init_components(); $this->init_hooks(); } private function init_components() { $this->encryption_manager = AIVectorSearch_Encryption_Manager::instance(); $this->connection_manager = AIVectorSearch_Connection_Manager::instance(); $this->supabase_client = AIVectorSearch_Supabase_Client::instance(); $this->api_client = AIVectorSearch_API_Client::instance(); $this->openai_client = AIVectorSearch_OpenAI_Client::instance(); $this->analytics = AIVectorSearch_Analytics::instance(); $this->product_sync = AIVectorSearch_Product_Sync::instance(); $this->search_handler = AIVectorSearch_Search_Handler::instance(); $this->recommendations = AIVectorSearch_Recommendations::instance(); $this->recommendations_integrations = AIVectorSearch_Recommendations_Integrations::instance(); $this->admin_interface = AIVectorSearch_Admin_Interface::instance(); } private function init_hooks() { add_action('plugins_loaded', [$this, 'ensure_store_id'], 11); // Plugin lifecycle hooks - must use main plugin file path, not this class file if (defined('AIVESESE_PLUGIN_PATH')) { register_activation_hook(AIVESESE_PLUGIN_PATH . 'ai-supabase-search.php', [$this, 'on_activation']); register_deactivation_hook(AIVESESE_PLUGIN_PATH . 'ai-supabase-search.php', [$this, 'on_deactivation']); } // Add admin notices for mode switching add_action('admin_notices', [$this, 'show_mode_switch_notices']); add_action('admin_notices', [$this, 'show_analytics_notices']); add_action('admin_enqueue_scripts', [$this, 'enqueue_analytics_notice_script']); } public function ensure_store_id() { $store = get_option('aivesese_store', ''); // Basic UUID v4 format check $is_uuid = preg_match( '/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i', (string) $store ); if (!$is_uuid) { $new = function_exists('wp_generate_uuid4') ? wp_generate_uuid4() : wp_generate_password(36, false); // fallback update_option('aivesese_store', $new, false); // autoload = false } } public function on_activation() { // Ensure store ID is generated on activation $this->ensure_store_id(); // Set default options $defaults = [ 'aivesese_connection_mode' => 'lite', // Default to lite mode for instant search 'aivesese_enable_search' => '1', 'aivesese_semantic_toggle' => '0', 'aivesese_auto_sync' => '0', 'aivesese_enable_pdp_similar' => '0', 'aivesese_enable_cart_below' => '0', 'aivesese_enable_woodmart_integration' => '0', ]; foreach ($defaults as $option => $default_value) { if (get_option($option) === false) { update_option($option, $default_value); } } $this->analytics->create_table(); // Clear any existing caches $this->clear_plugin_caches(); // Show welcome notice update_option('aivesese_show_welcome_notice', '1'); } public function on_deactivation() { // Clear plugin caches $this->clear_plugin_caches(); wp_clear_scheduled_hook('aivs_cleanup_analytics'); } private function clear_plugin_caches() { global $wpdb; // Delete all transients that start with our prefixes $prefixes = ['fts_', 'sem_', 'recs_', 'aivesese_sim_']; foreach ($prefixes as $prefix) { $escaped_prefix = $wpdb->esc_like($prefix) . '%'; $wpdb->query($wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s", '_transient_' . $escaped_prefix )); $wpdb->query($wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s", '_transient_timeout_' . $escaped_prefix )); } } /** * Show admin notices for mode switching and welcome */ public function show_mode_switch_notices() { if (!current_user_can('manage_options')) { return; } // Welcome notice for new installs if (get_option('aivesese_show_welcome_notice') === '1') { $this->show_welcome_notice(); } // Connection mode notices $connection_mode = get_option('aivesese_connection_mode', 'lite'); if ($connection_mode === 'api' && empty(get_option('aivesese_license_key'))) { $this->show_api_setup_notice(); } if ($connection_mode === 'self_hosted' && (!get_option('aivesese_url') || !get_option('aivesese_key'))) { $this->show_self_hosted_setup_notice(); } } /** * Show analytics-related notices */ public function show_analytics_notices() { if (!current_user_can('manage_options')) { return; } $screen = get_current_screen(); if (!$screen || !in_array($screen->id, ['dashboard', 'edit-product'], true)) { return; } // Check if analytics has interesting data to show $stats = $this->analytics->get_search_stats(7); // Last 7 days // Show analytics discovery notice if they have search activity if ($stats['total_searches'] >= 10 && !get_option('aivesese_analytics_discovered', false)) { echo '
'; echo '

🔍 Search Analytics Available!

'; echo '

Great news! Your store has ' . $stats['total_searches'] . ' searches this week. '; echo 'We\'ve been collecting analytics data that can help you boost sales!

'; echo '

'; echo 'View Analytics Dashboard '; echo 'Maybe Later'; echo '

'; echo '
'; } // Show opportunity notice for zero-result searches $opportunities = $this->analytics->get_zero_result_searches(1, 7); if (!empty($opportunities) && $opportunities[0]->search_count >= 5 && !get_option('aivesese_opportunity_shown_' . md5($opportunities[0]->search_term), false)) { $term = $opportunities[0]->search_term; $count = $opportunities[0]->search_count; echo '
'; echo '

💰 Revenue Opportunity Detected!

'; echo '

Customers searched for "' . esc_html($term) . '" ' . $count . ' times this week but found no products. '; echo 'This could be a significant sales opportunity!

'; echo '

'; echo 'Add Product for "' . esc_html($term) . '" '; echo 'View All Opportunities'; echo '

'; echo '
'; } } public function enqueue_analytics_notice_script($hook) { if (!current_user_can('manage_options')) { return; } $screen = function_exists('get_current_screen') ? get_current_screen() : null; if (!$screen || !in_array($screen->id, ['dashboard', 'edit-product'], true)) { return; } wp_localize_script('jquery', 'aivesese_analytics_notice', [ 'nonce' => wp_create_nonce('aivs_analytics_nonce'), ]); wp_add_inline_script( 'jquery', "jQuery(document).on('click', '.aivs-dismiss-notice', function(e) {\n" . " e.preventDefault();\n" . " const key = jQuery(this).data('key');\n" . " const notice = jQuery(this).closest('.notice');\n" . "\n" . " jQuery.post(ajaxurl, {\n" . " action: 'aivs_dismiss_analytics_notice',\n" . " key: key,\n" . " nonce: window.aivesese_analytics_notice ? window.aivesese_analytics_notice.nonce : ''\n" . " }, function() {\n" . " notice.fadeOut();\n" . " });\n" . "});\n" . "\n" . "jQuery(document).on('click', '.notice[data-dismiss-key] .notice-dismiss', function() {\n" . " const key = jQuery(this).parent().data('dismiss-key');\n" . " jQuery.post(ajaxurl, {\n" . " action: 'aivs_dismiss_analytics_notice',\n" . " key: key,\n" . " nonce: window.aivesese_analytics_notice ? window.aivesese_analytics_notice.nonce : ''\n" . " });\n" . "});" ); } private function show_welcome_notice() { $dismiss_url = wp_nonce_url( add_query_arg('aivesese_dismiss_welcome', '1'), 'aivesese_welcome_nonce' ); echo '
'; echo '

🎉 Welcome to AI Vector Search!

'; echo '

Thank you for installing AI Vector Search. You have two ways to get started:

'; echo '
'; // API Option echo '
'; echo '

🚀 Managed API Service (Coming Soon)

'; echo '

We\'re working on a hosted service that will eliminate setup complexity.

'; echo '
'; // Self-hosted Option echo '
'; echo '

⚙️ Self-Hosted (DIY)

'; echo '
    '; echo '
  • 🔧 Requires Supabase setup
  • '; echo '
  • 🔧 Manual configuration
  • '; echo '
  • 💰 Pay only API usage
  • '; echo '
  • 📊 Basic analytics included
  • '; echo '
'; echo '

Configure Now

'; echo '
'; echo '
'; echo '

Dismiss this notice

'; echo '
'; // Handle dismissal if (isset($_GET['aivesese_dismiss_welcome']) && check_admin_referer('aivesese_welcome_nonce')) { update_option('aivesese_show_welcome_notice', '0'); wp_safe_redirect(remove_query_arg(['aivesese_dismiss_welcome', '_wpnonce'])); exit; } } private function show_api_setup_notice() { echo '
'; echo '

AI Vector Search: API mode is selected but no license key is configured. '; echo 'Configure your license key or '; echo 'get a license.

'; echo '
'; } private function show_self_hosted_setup_notice() { echo '
'; echo '

AI Vector Search: Self-hosted mode requires Supabase configuration. '; echo 'Complete your setup.

'; echo '
'; } // Getter methods for accessing components public function get_encryption_manager() { return $this->encryption_manager; } public function get_connection_manager() { return $this->connection_manager; } public function get_supabase_client() { return $this->supabase_client; } public function get_api_client() { return $this->api_client; } public function get_openai_client() { return $this->openai_client; } public function get_analytics() { return $this->analytics; } public function get_product_sync() { return $this->product_sync; } public function get_search_handler() { return $this->search_handler; } public function get_recommendations() { return $this->recommendations; } public function get_admin_interface() { return $this->admin_interface; } // Utility methods public function is_woocommerce_active(): bool { return class_exists('WooCommerce'); } public function get_plugin_version(): string { return AIVESESE_PLUGIN_VERSION; } public function get_plugin_path(): string { return AIVESESE_PLUGIN_PATH; } public function get_plugin_url(): string { return AIVESESE_PLUGIN_URL; } /** * Check if the plugin is properly configured */ public function is_configured(): bool { $connection_mode = get_option('aivesese_connection_mode', 'lite'); if ($connection_mode === 'api') { return !empty(get_option('aivesese_license_key')) && get_option('aivesese_api_activated') === '1'; } if ($connection_mode === 'lite') { return true; } return !empty(get_option('aivesese_url')) && !empty(get_option('aivesese_key')) && !empty(get_option('aivesese_store')); } /** * Get current connection mode */ public function get_connection_mode(): string { return get_option('aivesese_connection_mode', 'lite'); } /** * Check if semantic search is available in current mode */ public function is_semantic_search_available(): bool { return $this->connection_manager->is_semantic_search_available(); } } add_action('wp_ajax_aivs_dismiss_analytics_notice', function() { check_ajax_referer('aivs_analytics_nonce', 'nonce'); if (!current_user_can('manage_options')) { wp_die('Unauthorized'); } $key = sanitize_text_field(wp_unslash($_POST['key'] ?? '')); update_option("aivesese_{$key}", true, false); wp_die('OK'); });