includes(); // Initialize components $this->init_components(); // Initialize hooks $this->init_hooks(); // Initialize settings hooks Aiflab_Chatweb_Config::init_settings_hooks(); } /** * Define constants */ private function define_constants() { // Constants are already defined in the main plugin file // This method is kept for compatibility } /** * Include required files */ private function includes() { // Load i18n first (needed by other classes) require_once AIFLAB_CHATWEB_PLUGIN_PATH . 'includes/class-chatweb-i18n.php'; require_once AIFLAB_CHATWEB_PLUGIN_PATH . 'includes/class-chatweb-config.php'; require_once AIFLAB_CHATWEB_PLUGIN_PATH . 'includes/class-chatweb-api.php'; require_once AIFLAB_CHATWEB_PLUGIN_PATH . 'includes/class-chatweb-posts.php'; require_once AIFLAB_CHATWEB_PLUGIN_PATH . 'includes/class-chatweb-debug-logger.php'; // Load WooCommerce integration if WooCommerce is active if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) { require_once AIFLAB_CHATWEB_PLUGIN_PATH . 'includes/class-chatweb-woocommerce.php'; } // Always load admin class - it's needed for AJAX calls // is_admin() can return false in AJAX context, so we load it unconditionally require_once AIFLAB_CHATWEB_PLUGIN_PATH . 'admin/class-chatweb-admin.php'; } /** * Add hooks */ private function add_hooks() { // This method is an alias for init_hooks $this->init_hooks(); } /** * Initialize WordPress hooks */ private function init_hooks() { // JSON i18n is loaded via Aiflab_Chatweb_i18n class add_action('admin_enqueue_scripts', array($this, 'admin_scripts')); add_action('wp_footer', array($this, 'add_embed_code')); // Activation and deactivation hooks register_activation_hook(__FILE__, array($this, 'activate')); register_deactivation_hook(__FILE__, array($this, 'deactivate')); } /** * Load plugin dependencies */ private function load_dependencies() { require_once AIFLAB_CHATWEB_PLUGIN_PATH . 'includes/class-chatweb-config.php'; require_once AIFLAB_CHATWEB_PLUGIN_PATH . 'includes/class-chatweb-api.php'; // Load WooCommerce integration if WooCommerce is active if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) { require_once AIFLAB_CHATWEB_PLUGIN_PATH . 'includes/class-chatweb-woocommerce.php'; } // Always load admin class - needed for AJAX calls require_once AIFLAB_CHATWEB_PLUGIN_PATH . 'admin/class-chatweb-admin.php'; } /** * Initialize plugin components */ private function init_components() { $this->api = new Aiflab_Chatweb_API(); // Initialize WooCommerce integration if WooCommerce is active if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) { $this->woocommerce = new Aiflab_Chatweb_WooCommerce(); } // Always initialize admin class - needed for AJAX calls $this->admin = new Aiflab_Chatweb_Admin(); } // load_textdomain() removed - using JSON-based i18n via Aiflab_Chatweb_i18n class /** * Fallback to English for untranslated strings */ public function fallback_to_english($translation, $text, $domain) { if ($domain !== 'aifusionlab-chatbot-for-chatweb') { return $translation; } // If translation is the same as original text (meaning no translation found) // OR if current locale is not English, force English translations $current_locale = get_locale(); $force_english = ($current_locale !== 'en_US' && $current_locale !== 'en'); if ($force_english || $translation === $text) { // Define English fallbacks for ALL Vietnamese strings $english_strings = array( 'ChatWeb Cài đặt' => 'Chatweb Settings', 'ChatWeb' => 'Chatweb', 'Dashboard' => 'Dashboard', 'ChatWeb Logo' => 'Chatweb Logo', 'Cấu hình API Key' => 'API Key Configuration', 'API Key' => 'API Key', 'Nhập API Key của bạn...' => 'Enter your API Key...', 'API Key được cung cấp bởi ChatWeb để kết nối với dịch vụ.' => 'API Key provided by Chatweb to connect to the service.', 'Lưu API Key' => 'Save API Key', 'Test Kết nối' => 'Test Connection', 'Trạng thái:' => 'Status:', 'Đã cấu hình API Key' => 'API Key Configured', 'Embed Code' => 'Embed Code', 'Embed code được tự động lấy từ API khi lưu API Key. Bạn có thể copy code bên dưới để sử dụng thủ công nếu cần.' => 'Embed code is automatically retrieved from API when saving API Key. You can copy the code below for manual use if needed.', 'Embed Code:' => 'Embed Code:', 'Embed code sẽ hiển thị ở đây sau khi lưu API Key...' => 'Embed code will be displayed here after saving API Key...', 'Code này chỉ để xem và copy. Không thể chỉnh sửa vì được lấy trực tiếp từ ChatWeb API khi lưu API Key.' => 'This code is for viewing and copying only. Cannot be edited as it is retrieved directly from Chatweb API when saving API Key.', 'Copy Embed Code' => 'Copy Embed Code', 'Làm mới Embed Code' => 'Refresh Embed Code', 'Vui lòng cấu hình API Key trước. Embed code sẽ được tự động lấy khi lưu API Key.' => 'Please configure API Key first. Embed code will be automatically retrieved when saving API Key.', 'Cài đặt Embed' => 'Embed Settings', 'Bật/Tắt Embed' => 'Enable/Disable Embed', 'Bật để tự động chèn embed code vào footer website.' => 'Enable to automatically insert embed code into website footer.', 'Khi bật, embed code sẽ được tự động chèn vào footer của tất cả các trang.' => 'When enabled, embed code will be automatically inserted into the footer of all pages.', 'Lưu Cài đặt' => 'Save Settings', 'Cài đặt WooCommerce' => 'WooCommerce Settings', 'Đồng bộ sản phẩm' => 'Product Sync', 'Bật để tự động đồng bộ sản phẩm WooCommerce với ChatWeb.' => 'Enable to automatically sync WooCommerce products with Chatweb.', 'Khi bật, sản phẩm sẽ được tự động đồng bộ khi tạo mới, cập nhật hoặc xóa.' => 'When enabled, products will be automatically synced when created, updated, or deleted.', 'Đồng bộ sản phẩm thủ công' => 'Manual Product Sync', 'Bạn có thể đồng bộ thủ công tất cả sản phẩm WooCommerce với ChatWeb.' => 'You can manually sync all WooCommerce products with Chatweb.', 'Đồng bộ tất cả sản phẩm' => 'Sync All Products', 'Thông tin Plugin' => 'Plugin Information', 'Phiên bản:' => 'Version:', 'Website:' => 'Website:', 'Hỗ trợ' => 'Support', 'Nếu bạn cần hỗ trợ, vui lòng liên hệ:' => 'If you need support, please contact:', 'Địa chỉ:' => 'Address:', 'Liên hệ:' => 'Contact:', 'Đang tải...' => 'Loading...', 'Có lỗi xảy ra' => 'An error occurred', 'Thành công' => 'Success', 'Chọn ngày' => 'Select Date', 'Bạn không có quyền thực hiện hành động này.' => 'You do not have permission to perform this action.', 'API Key không được để trống.' => 'API Key cannot be empty.', 'API Key đã được lưu thành công và embed code đã được tự động lấy từ API. Tính năng embed đã được tự động bật.' => 'API Key has been saved successfully and embed code has been automatically retrieved from API. Embed feature has been automatically enabled.', 'API Key không hợp lệ hoặc không có quyền truy cập.' => 'API Key is invalid or does not have access permission.', 'API Key chưa được cấu hình. Vui lòng cấu hình API Key trước.' => 'API Key has not been configured. Please configure API Key first.', 'Embed code đã được làm mới thành công từ API.' => 'Embed code has been successfully refreshed from API.', 'Không thể lấy embed code từ API.' => 'Unable to retrieve embed code from API.', 'WooCommerce không được kích hoạt.' => 'WooCommerce is not activated.', 'Không tìm thấy sản phẩm nào để đồng bộ.' => 'No products found to sync.', 'Cài đặt embed đã được lưu thành công.' => 'Embed settings have been saved successfully.', 'Có lỗi xảy ra khi lưu cài đặt.' => 'An error occurred while saving settings.', 'Cài đặt WooCommerce đã được lưu thành công.' => 'WooCommerce settings have been saved successfully.' ); if (isset($english_strings[$text])) { return $english_strings[$text]; } } return $translation; } /** * Fallback to English for untranslated strings with context */ public function fallback_to_english_with_context($translation, $text, $context, $domain) { if ($domain !== 'aifusionlab-chatbot-for-chatweb' || $translation !== $text) { return $translation; } return $this->fallback_to_english($translation, $text, 'aifusionlab-chatbot-for-chatweb'); } /** * Enqueue admin scripts and styles */ public function admin_scripts($hook) { // Only load on our plugin pages if (strpos($hook, 'aiflab') === false && strpos($hook, 'aifusionlab') === false) { return; } wp_enqueue_style( 'aiflab-chatweb-admin-style', AIFLAB_CHATWEB_PLUGIN_URL . 'assets/css/admin.css', array(), AIFLAB_CHATWEB_PLUGIN_VERSION ); wp_enqueue_script( 'aiflab-chatweb-admin-script', AIFLAB_CHATWEB_PLUGIN_URL . 'assets/js/admin.js', array('jquery'), AIFLAB_CHATWEB_PLUGIN_VERSION, true ); // Get i18n instance and pass translations to JS $i18n = Aiflab_Chatweb_i18n::get_instance(); // Localize script for AJAX and i18n wp_localize_script('aiflab-chatweb-admin-script', 'aiflab_chatweb_ajax', array( 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('aiflab_chatweb_nonce'), 'locale' => $i18n->get_locale() )); // Pass all translations to JS wp_localize_script('aiflab-chatweb-admin-script', 'aiflab_chatweb_i18n', $i18n->get_js_translations()); } /** * Add embed code to footer */ public function add_embed_code() { // Only add on frontend if (is_admin()) { return; } // Check if embed is enabled $enable_embed = Aiflab_Chatweb_Config::get_setting('enable_embed', false); if (!$enable_embed) { return; } // Check if API key is configured $api_key = Aiflab_Chatweb_Config::get_setting('api_key', ''); if (empty($api_key)) { return; } // Get embed code from database $embed_code = Aiflab_Chatweb_Config::get_embed_code(); // Log for debugging // Output embed code if not empty if (!empty($embed_code)) { echo "\n\n"; // Allow all data-* attributes for embed code $allowed_html = array( 'script' => array( 'src' => true, 'async' => true, 'defer' => true, 'type' => true, 'charset' => true, 'crossorigin' => true, 'integrity' => true, 'nomodule' => true, ), 'div' => array( 'id' => true, 'class' => true, 'style' => true, ), 'span' => array( 'id' => true, 'class' => true, 'style' => true, ), 'noscript' => true, 'link' => array( 'rel' => true, 'href' => true, 'type' => true, 'as' => true, 'crossorigin' => true, ), ); // Add common data-* attributes used by Chatweb embed foreach (array('id', 'website-id', 'position', 'bot-id', 'theme', 'language', 'token') as $data_attr) { if (isset($allowed_html['div'])) { $allowed_html['div']['data-' . $data_attr] = true; } } echo wp_kses($embed_code, $allowed_html); echo "\n\n"; } } /** * Plugin activation */ public function activate() { // Set default options $this->set_default_options(); // Create debug logger table Aiflab_Chatweb_Debug_Logger::create_table(); // Flush rewrite rules flush_rewrite_rules(); // Clear caches $this->clear_caches(); } /** * Plugin deactivation */ public function deactivate() { // Flush rewrite rules flush_rewrite_rules(); // Clear caches $this->clear_caches(); } /** * Set default plugin options */ private function set_default_options() { if (class_exists('Aiflab_Chatweb_Config')) { Aiflab_Chatweb_Config::reset_settings(); } else { // Fallback nếu class chưa được load $default_options = array( 'api_key' => '', 'enable_embed' => false, 'embed_code' => '', 'enable_woocommerce_sync' => false ); foreach ($default_options as $key => $value) { $option_name = 'aiflab_chatweb_' . $key; add_option($option_name, $value); } } } /** * Clear all caches */ private function clear_caches() { // Clear WordPress object cache if (function_exists('wp_cache_flush')) { wp_cache_flush(); } // Call the static method to clear plugin caches if (class_exists('Aiflab_Chatweb_Config')) { Aiflab_Chatweb_Config::clear_plugin_caches(); } } } /** * Initialize the plugin */ function aiflab_chatweb_extension_init() { return Aiflab_Chatweb_Extension::get_instance(); } // Start the plugin aiflab_chatweb_extension_init();