loader = new Aivexa_Loader(); $this->define_admin_hooks(); $this->define_public_hooks(); $this->define_rest_hooks(); $this->define_privacy_hooks(); } /** * Register admin hooks. */ private function define_admin_hooks(): void { $admin = new Aivexa_Admin(); $this->loader->add_action( 'admin_menu', $admin, 'register_menus' ); $this->loader->add_action( 'admin_init', $admin, 'register_settings' ); $this->loader->add_action( 'admin_enqueue_scripts', $admin, 'enqueue_assets' ); $this->loader->add_action( 'wp_ajax_aivexa_test_connection', $admin, 'ajax_test_connection' ); $this->loader->add_action( 'wp_ajax_aivexa_test_agent', $admin, 'ajax_test_agent' ); } /** * Register public hooks. */ private function define_public_hooks(): void { $public = new Aivexa_Public(); $this->loader->add_action( 'init', $public, 'register_shortcode' ); $this->loader->add_action( 'wp_enqueue_scripts', $public, 'maybe_enqueue_assets' ); $this->loader->add_action( 'wp_footer', $public, 'maybe_render_floating_widget' ); } /** * Register REST hooks. */ private function define_rest_hooks(): void { $rest = new Aivexa_REST_API(); $this->loader->add_action( 'rest_api_init', $rest, 'register_routes' ); } /** * Register privacy hooks. */ private function define_privacy_hooks(): void { $this->loader->add_filter( 'wp_privacy_personal_data_exporters', $this, 'register_exporter', 10 ); $this->loader->add_filter( 'wp_privacy_personal_data_erasers', $this, 'register_eraser', 10 ); } /** * Register personal data exporter. * * @param array $exporters Exporters. * @return array */ public function register_exporter( array $exporters ): array { $exporters['aivexa'] = array( 'exporter_friendly_name' => __( 'Aivexa Conversations', 'aivexa' ), 'callback' => array( $this, 'export_personal_data' ), ); return $exporters; } /** * Register personal data eraser. * * @param array $erasers Erasers. * @return array */ public function register_eraser( array $erasers ): array { $erasers['aivexa'] = array( 'eraser_friendly_name' => __( 'Aivexa Conversations', 'aivexa' ), 'callback' => array( $this, 'erase_personal_data' ), ); return $erasers; } /** * Export conversation data for a user email. * * @param string $email_address Email. * @param int $page Page. * @return array */ public function export_personal_data( string $email_address, int $page = 1 ): array { unset( $page ); $user = get_user_by( 'email', $email_address ); if ( ! $user instanceof WP_User ) { return array( 'data' => array(), 'done' => true, ); } $memory = new Aivexa_Memory(); $conversations = $memory->get_conversations_for_session( 'user_' . $user->ID ); $data = array(); foreach ( $conversations as $conversation_id => $conversation ) { $messages = array(); if ( ! empty( $conversation['messages'] ) && is_array( $conversation['messages'] ) ) { foreach ( $conversation['messages'] as $message ) { if ( ! is_array( $message ) ) { continue; } $messages[] = sprintf( '%s: %s', isset( $message['role'] ) ? sanitize_text_field( (string) $message['role'] ) : '', isset( $message['content'] ) ? sanitize_textarea_field( (string) $message['content'] ) : '' ); } } $data[] = array( 'group_id' => 'aivexa', 'group_label' => __( 'Aivexa Conversations', 'aivexa' ), 'item_id' => 'aivexa-conversation-' . $conversation_id, 'data' => array( array( 'name' => __( 'Conversation ID', 'aivexa' ), 'value' => $conversation_id, ), array( 'name' => __( 'Messages', 'aivexa' ), 'value' => implode( "\n", $messages ), ), ), ); } return array( 'data' => $data, 'done' => true, ); } /** * Erase conversation data for a user email. * * @param string $email_address Email. * @param int $page Page. * @return array */ public function erase_personal_data( string $email_address, int $page = 1 ): array { unset( $page ); $user = get_user_by( 'email', $email_address ); if ( ! $user instanceof WP_User ) { return array( 'items_removed' => false, 'items_retained' => false, 'messages' => array(), 'done' => true, ); } $memory = new Aivexa_Memory(); $conversations = $memory->get_conversations_for_session( 'user_' . $user->ID ); $removed = false; foreach ( array_keys( $conversations ) as $conversation_id ) { $removed = $memory->clear_conversation( (string) $conversation_id ) || $removed; } return array( 'items_removed' => $removed, 'items_retained' => false, 'messages' => array(), 'done' => true, ); } /** * Run loader. */ public function run(): void { $this->loader->run(); } }