init(); } /** * Initialize all plugin subsystems. * * @return void */ private function init(): void { add_action( 'ai_support_assistant_purge_history', array( \AISupportAssistant\Chat\ChatHistory::class, 'purge_expired' ) ); add_action( 'admin_notices', array( $this, 'index_upgrade_notice' ) ); // Load plugin textdomain for i18n translations. add_action( 'init', array( $this, 'load_textdomain' ) ); // Deferred upgrade check: runs only in admin context. add_action( 'admin_init', array( $this, 'maybe_upgrade' ) ); // Scaffolding settings register. \AISupportAssistant\Admin\Settings::get_instance(); // Scaffolding admin panels. if ( is_admin() ) { \AISupportAssistant\Admin\Menu::get_instance(); } // REST API controller. \AISupportAssistant\REST\RestController::get_instance(); // Background document indexing. \AISupportAssistant\Documents\DocumentManager::register_hooks(); // Shortcode and Frontend Widget. \AISupportAssistant\Frontend\Shortcode::get_instance(); \AISupportAssistant\Frontend\Block::get_instance(); } /** * Load translation textdomain. * * @return void */ public function load_textdomain(): void { // phpcs:ignore PluginCheck.CodeAnalysis.DiscouragedFunctions.load_plugin_textdomainFound load_plugin_textdomain( 'ai-support-assistant', false, dirname( plugin_basename( AI_SUPPORT_ASSISTANT_FILE ) ) . '/languages' ); } /** * Run one-time data/schema migrations. * * @return void */ public function maybe_upgrade(): void { if ( ! wp_next_scheduled( 'ai_support_assistant_purge_history' ) ) { wp_schedule_event( time() + HOUR_IN_SECONDS, 'daily', 'ai_support_assistant_purge_history' ); } $db_version = get_option( 'ai_support_assistant_db_version', '0' ); if ( version_compare( $db_version, AI_SUPPORT_ASSISTANT_VERSION, '<' ) ) { if ( \AISupportAssistant\Database\DatabaseManager::activate() ) { update_option( 'ai_support_assistant_db_version', AI_SUPPORT_ASSISTANT_VERSION ); } } } /** * Static Plugin Activation Callback. */ public static function activate(): void { if ( \AISupportAssistant\Database\DatabaseManager::activate() ) { update_option( 'ai_support_assistant_db_version', AI_SUPPORT_ASSISTANT_VERSION ); } } /** * Static Plugin Deactivation Callback. */ public static function deactivate(): void { wp_clear_scheduled_hook( 'ai_support_assistant_purge_history' ); wp_unschedule_hook( 'ai_support_assistant_index_document' ); } /** Explain why legacy embeddings need rebuilding after the schema upgrade. */ public function index_upgrade_notice(): void { if ( ! current_user_can( 'manage_options' ) ) { return; } global $wpdb; $table = \AISupportAssistant\Database\DatabaseManager::get_chunks_table(); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Indexed existence check reflects re-indexing immediately; a stale cache would retain the upgrade notice. $legacy = $wpdb->get_var( $wpdb->prepare( 'SELECT id FROM %i WHERE embedding_model = %s LIMIT 1', $table, '' ) ); if ( $legacy ) { echo '
' . esc_html__( 'AI Support Assistant: Re-index your documents to enable model-safe search. Legacy embeddings are excluded until rebuilt.', 'ai-support-assistant' ) . '