'15096', 'slug' => 'ai-auto-tool', 'premium_slug' => 'ai-auto-tool-pay', 'type' => 'plugin', 'public_key' => 'pk_a1bb06b76f38f9ff1132089d99b21', 'is_premium' => false, 'has_premium_version' => false, 'has_addons' => false, 'has_paid_plans' => true, 'has_affiliation' => 'all', 'menu' => array( 'slug' => 'ai_auto_tool', 'contact' => true, 'support' => false, 'network' => true, ), ) ); } return $aiautotool_premium; } aiautotool_premium(); do_action( 'aiautotool_premium_loaded' ); } aiautotool_premium()->add_filter( 'hide_freemius_powered_by', '__return_true' ); // Load New User Discount Code Handler require_once plugin_dir_path(__FILE__) . 'lib/new-user-discount.php'; // Add custom CSS for Freemius pricing page aiautotool_premium()->add_filter( 'pricing/css_path', function( $css_path ) { return plugin_dir_path(__FILE__) . 'css/freemius-pricing-custom.css'; }); // Configure checkout page parameters aiautotool_premium()->add_filter( 'checkout/parameters', function() { return array( 'show_refund_badge' => true, 'show_reviews' => true, 'billing_cycle_selector' => 'dropdown', 'annual_discount' => true, ); } ); // Ensure annual discount is shown in pricing config add_action( 'admin_init', function() { // Only on pricing page if ( isset( $_GET['page'] ) && strpos( $_GET['page'], 'pricing' ) !== false ) { // Add annual_discount to pricing config via filter aiautotool_premium()->add_filter( 'fs_pricing_query_params', function( $params ) { if ( ! isset( $params['annual_discount'] ) ) { $params['annual_discount'] = true; } return $params; }, 10, 1 ); } }, 1 ); // Enqueue custom CSS for pricing page add_action( 'admin_enqueue_scripts', function( $hook ) { // Only on pricing page if ( isset( $_GET['page'] ) && strpos( $_GET['page'], 'pricing' ) !== false ) { wp_enqueue_style( 'aiautotool-freemius-pricing-custom', plugin_dir_url(__FILE__) . 'css/freemius-pricing-custom.css', array(), defined('AIAUTOTOOL_VERSION_CACHE') ? AIAUTOTOOL_VERSION_CACHE : '1.0' ); } // Only on account page if ( isset( $_GET['page'] ) && strpos( $_GET['page'], 'account' ) !== false ) { wp_enqueue_style( 'aiautotool-freemius-account-custom', plugin_dir_url(__FILE__) . 'css/freemius-account-custom.css', array(), defined('AIAUTOTOOL_VERSION_CACHE') ? AIAUTOTOOL_VERSION_CACHE : '1.0' ); } }, 999 ); /* translators: %s là đường dẫn tới trang nâng cấp lên bản Pro của AI Auto Tool.*/ $Upgrade_notifice = sprintf('AI Auto Tool Limit Quota. Please Upgrade Pro', aiautotool_premium()->get_upgrade_url()); define('AIAUTOTOOL_TITLE_UPGRADE', $Upgrade_notifice); function aiautotool_activate() { require_once esc_html( plugin_dir_path( __FILE__ ) ) . 'vendor/aiautotool/class-ai-auto-tool-activator.php'; Ai_auto_tool_Activator::activate(); } function aiautotool_deactivate() { require_once esc_html( plugin_dir_path( __FILE__ ) ) . 'vendor/aiautotool/class-ai-auto-tool-deactivator.php'; Ai_auto_tool_Deactivator::deactivate(); } register_activation_hook( __FILE__, 'aiautotool_activate' ); register_deactivation_hook( __FILE__, 'aiautotool_deactivate' ); // Load textdomain immediately before loading any other files that might use translations // This must happen before bootstrap.php is loaded to prevent WordPress 6.7.0 warnings if (function_exists('load_plugin_textdomain')) { load_plugin_textdomain('ai-auto-tool', false, dirname(plugin_basename(__FILE__)) . '/languages/'); } // Load Extra Config Module (MANDATORY - always loads, not dependent on active/disable) // Must load BEFORE class instantiation to ensure class exists when registering $extra_config_bootstrap = plugin_dir_path(__FILE__) . 'inc/extra-config/bootstrap.php'; if (file_exists($extra_config_bootstrap)) { require_once $extra_config_bootstrap; } // Load Floating Robot Widget EARLY to ensure admin_enqueue_scripts hook is registered // This must be loaded before AI_Auto_Tool class is instantiated to catch admin_enqueue_scripts hook if( ! class_exists( 'AI_Auto_Tool' ) ) { class AI_Auto_Tool { protected $subclasses = []; private $aiautotool_config_settings; public function __construct() { // Initialize Professional Autoloader System $this->init_autoloader_system(); // Textdomain is now loaded early in the plugin file (line ~61) before any code runs // This prevents WordPress 6.7.0 translation loading warnings // Menu registration now handled by Menu Manager // add_action( 'admin_menu', array( $this, 'add_menu_page' ) , 10, 2); add_action( 'admin_init', array( $this, 'register_settings' ) ); add_action( 'rest_api_init', array($this,'create_post_route')); add_action('wp_ajax_aiautotool_insert_post', array( $this, 'aiautotool_insert_post_ajax' )); add_action( 'wp_ajax_aiautotool_get_cate', array( $this, 'aiautotool_get_cate' )); add_action( 'wp_ajax_get_all_media', array( $this, 'get_all_media_callback' )); add_action( 'wp_ajax_aiautotool_save_image', array( $this, 'aiautotool_save_image' )); // AJAX handlers for Bard API to avoid CORS issues add_action( 'wp_ajax_aiautotool_bard_contentmore', array( $this, 'aiautotool_bard_contentmore_callback' )); add_action( 'wp_ajax_aiautotool_bard_content', array( $this, 'aiautotool_bard_content_callback' )); add_action( 'wp_ajax_aiautotool_bard_rewrite', array( $this, 'aiautotool_bard_rewrite_callback' )); // Legacy loading methods (now handled by autoloader) // DEBUG MODE: Track memory during initialization if (defined('WP_DEBUG') && WP_DEBUG && (defined('AIAUTOTOOL_DEBUG_LOADING') && AIAUTOTOOL_DEBUG_LOADING)) { $init_memory = round(memory_get_usage(true) / 1024 / 1024, 2); error_log("AI Auto Tool DEBUG: [INIT] Starting plugin initialization - Memory: {$init_memory} MB"); } self::load_lib(); if (defined('WP_DEBUG') && WP_DEBUG && (defined('AIAUTOTOOL_DEBUG_LOADING') && AIAUTOTOOL_DEBUG_LOADING)) { $after_lib_memory = round(memory_get_usage(true) / 1024 / 1024, 2); error_log("AI Auto Tool DEBUG: [AFTER load_lib] Memory: {$after_lib_memory} MB"); } // self::load_inc(); self::aiautotool_new_object(); if (defined('WP_DEBUG') && WP_DEBUG && (defined('AIAUTOTOOL_DEBUG_LOADING') && AIAUTOTOOL_DEBUG_LOADING)) { $after_new_object_memory = round(memory_get_usage(true) / 1024 / 1024, 2); error_log("AI Auto Tool DEBUG: [AFTER aiautotool_new_object] Memory: {$after_new_object_memory} MB"); } // Assets are now managed by Asset Manager (inc/asset-manager.php) // Old method add_aiautotool_button_js() is kept for backward compatibility // but Asset Manager handles it more efficiently with conditional loading // Register AJAX handlers for all features add_action( 'init', array( $this, 'register_all_ajax_handlers' ) ); add_filter('plugin_action_links', array( $this, 'add_ai_auto_tool_settings_link' ), 10, 2); register_activation_hook(__FILE__, array($this, 'activate')); register_deactivation_hook(__FILE__, array($this, 'deactivate')); $aiautotool_Warning_Notice = new aiautotool_Warning_Notice(array( 'icon_url' => plugins_url('/images/logo.svg', __FILE__), 'title' => 'Aiautotool Plugin ', 'content' => 'The plugin is available for free so if it benefits you. Join the plugin support group here.', 'button_text' => 'Join group support Ai auto Tool Plugin', 'button_url' => 'https://t.me/aiautotoolchat', )); } public function init_settings() { } private function aiautotool_getdata() { return rendersetting::aiautotool_getdata(); } public function load_textdomain() { load_plugin_textdomain('ai-auto-tool', false, dirname(plugin_basename(__FILE__)) . '/languages/'); } public function activate() { if (class_exists('activeCallBack')) { $activeCallBack = new activeCallBack(); $activeCallBack->activate(); } } public function deactivate(){ $siteurl = get_option('siteurl'); $siteurl = str_replace('https://', 'http://', $siteurl); update_option('siteurl', $siteurl); // } $home = get_option('home'); $home = str_replace('https://', 'http://', $home); update_option('home', $home); if (class_exists('activeCallBack')) { $activeCallBack = new activeCallBack(); $activeCallBack->deactivate(); } global $wpdb; $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE 'aiautotool_%'" ); $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE 'fs_%'" ); } function add_ai_auto_tool_settings_link($links, $file) { if (false !== strpos($file, 'ai-auto-tool/Ai-Auto-Tool.php')) { $settings_link = 'Settings'; array_unshift($links, $settings_link); } return $links; } public function addSubclass($subclass) { // Prevent duplicate instances foreach ($this->subclasses as $existing) { if (get_class($existing) === get_class($subclass)) { return; // Already added, skip duplicate } } $this->subclasses[] = $subclass; } public function aiautotool_new_object(){ // Static flag to prevent multiple executions static $new_object_loaded = false; if ($new_object_loaded) { return; } // Use option cache helper if available $use_cache = class_exists('AIAutoTool_OptionCache'); $is_admin_page = is_admin(); // CRITICAL OPTIMIZATION: Only load essential classes immediately // Other features will be loaded on-demand when needed (lazy loading) // Extra Config - New Architecture (required for settings) if (class_exists('Aiautotool_Extra_Config_Manager')) { $extra_config_manager = Aiautotool_Extra_Config_Manager::instance(); $this->addSubclass($extra_config_manager); } // AI Provider Settings UI - Always loaded (mandatory) if (class_exists('AIAutotool_AI_Provider_Settings_UI')) { $ai_provider_settings_ui = new AIAutotool_AI_Provider_Settings_UI(); $this->addSubclass($ai_provider_settings_ui); } // OPTIMIZED: Only load features that are active OR needed for admin UI // Features are loaded on-demand when their settings page is accessed // Autoblogging - Only load if active $autoblogging_active = $use_cache ? AIAutoTool_OptionCache::is_active('AI_AutoTool_Autoblogging_active') : (get_option('AI_AutoTool_Autoblogging_active', 'false') === 'true'); if ($autoblogging_active) { $autoblogging_file = plugin_dir_path(__FILE__) . 'inc/features/autoblogging/autoblogging.php'; $file_exists = $use_cache ? AIAutoTool_OptionCache::file_exists($autoblogging_file) : file_exists($autoblogging_file); if ($file_exists) { require_once $autoblogging_file; if (class_exists('AIAutoTool\\Features\\Autoblogging\\Autoblogging')) { try { $autoblogging = new \AIAutoTool\Features\Autoblogging\Autoblogging(); $this->addSubclass($autoblogging); } catch (Exception $e) { if (defined('WP_DEBUG') && WP_DEBUG) { error_log('AI Auto Tool: Failed to load Autoblogging: ' . $e->getMessage()); } } } } } // Keyword Autopost - Load always (menu needs to be registered even if inactive) $keyword_autopost_file = plugin_dir_path(__FILE__) . 'inc/features/keyword-autopost/keyword-autopost.php'; $file_exists = $use_cache ? AIAutoTool_OptionCache::file_exists($keyword_autopost_file) : file_exists($keyword_autopost_file); if ($file_exists) { require_once $keyword_autopost_file; if (class_exists('AIAutoTool\\Features\\KeywordAutopost\\KeywordAutopost')) { try { $keyword_autopost = new \AIAutoTool\Features\KeywordAutopost\KeywordAutopost(); $this->addSubclass($keyword_autopost); } catch (Exception $e) { if (defined('WP_DEBUG') && WP_DEBUG) { error_log('AI Auto Tool: Failed to load Keyword Autopost: ' . $e->getMessage()); } } } } // OPTIMIZED: Batch load features only when active or needed for admin UI // Features are defined with their active option names for efficient checking $features_to_load = array( array( 'file' => 'inc/features/image-scanner/image-scanner.php', 'class' => 'AIAutoTool\\Features\\ImageScanner\\ImageScanner', 'option' => 'AIAutotool_Image404Scanner_active', 'load_on_admin' => true ), array( 'file' => 'inc/features/bot-security/bot-security.php', 'class' => 'AIAutoTool\\Features\\BotSecurity\\BotSecurity', 'option' => 'AIAutoToolSecurityBot_active', 'load_on_admin' => true ), array( 'file' => 'inc/features/auto-comment/auto-comment.php', 'class' => 'AIAutoTool\\Features\\AutoComment\\AutoComment', 'option' => 'AIautotool_autocomment_active', 'load_on_admin' => true ), array( 'file' => 'inc/features/auto-create-tags/auto-create-tags.php', 'class' => 'AIAutoTool\\Features\\AutoCreateTags\\AutoCreateTags', 'option' => 'AIautotool_autocreatetags_active', 'load_on_admin' => true ), array( 'file' => 'inc/features/canonical-manager/canonical-manager.php', 'class' => 'AIAutoTool\\Features\\CanonicalManager\\CanonicalManager', 'option' => 'Aiautotool_Canonical_active', 'load_on_admin' => true ), array( 'file' => 'inc/features/external-links/external-links.php', 'class' => 'AIAutoTool\\Features\\ExternalLinks\\ExternalLinks', 'option' => 'Aiautotool_exLink_backlink_active', 'load_on_admin' => true ), array( 'file' => 'inc/features/cloudflare-ai/cloudflare-ai.php', 'class' => 'AIAutoTool\\Features\\CloudflareAI\\CloudflareAI', 'option' => 'AI_AutoTool_cloudflareAI_active', 'load_on_admin' => true ), array( 'file' => 'inc/features/submit-index/submit-index.php', 'class' => 'AIAutoTool\\Features\\SubmitIndex\\SubmitIndex', 'option' => 'AIAutoTool_SubmitIndex_active', 'load_on_admin' => true ), array( 'file' => 'inc/features/suggest-auto/suggest-auto.php', 'class' => 'AIAutoTool\\Features\\SuggestAuto\\SuggestAuto', 'option' => 'AI_AutoTool_suggetauto_active', 'load_on_admin' => true ), array( 'file' => 'inc/features/username-generator/username-generator.php', 'class' => 'AIAutoTool\\Features\\UsernameGenerator\\UsernameGenerator', 'option' => 'aiautotool_AutoGenerateUsername_active', 'load_on_admin' => false ), array( 'file' => 'inc/features/web-stories/web-stories.php', 'class' => 'AIAutoTool\\Features\\WebStories\\WebStories', 'option' => 'AIautotool_Web_Stories_active', 'load_on_admin' => true ), array( 'file' => 'inc/features/footer-base/footer-base.php', 'class' => 'AIAutoTool\\Features\\FooterBase\\FooterBase', 'option' => 'Aiautotool_footer_base_active', 'load_on_admin' => true ), array( 'file' => 'inc/features/prompt-cpt/prompt-cpt.php', 'class' => 'AIAutoTool\\Features\\PromptCPT\\PromptCPT', 'option' => 'AIautotool_Prompt_CPT_active', 'load_on_admin' => true ), array( 'file' => 'inc/features/auto-create-categories/auto-create-categories.php', 'class' => 'AIAutoTool_AutoCreateCategories', 'option' => 'AIAutoTool_auto_create_categories_active', 'load_on_admin' => true ), array( 'file' => 'inc/features/crawlcampaign/crawlcampaign.php', 'class' => 'AIAutoTool\\Features\\CrawlCampaign\\CrawlCampaign', 'option' => 'aiautotool_crawlcampaign_active', 'load_on_admin' => true ), ); // Batch load features foreach ($features_to_load as $feature) { $is_active = $use_cache ? AIAutoTool_OptionCache::is_active($feature['option']) : (get_option($feature['option'], 'false') === 'true'); // Load if active OR if on admin page and feature should load on admin if ($is_active || ($is_admin_page && $feature['load_on_admin'])) { $file_path = plugin_dir_path(__FILE__) . $feature['file']; $file_exists = $use_cache ? AIAutoTool_OptionCache::file_exists($file_path) : file_exists($file_path); if ($file_exists) { // Ensure rendersetting is loaded for legacy features if ($feature['class'] === 'AIAutoTool_AutoCreateCategories' && !class_exists('rendersetting')) { $rendersetting_file = plugin_dir_path(__FILE__) . 'lib/setting.php'; if (file_exists($rendersetting_file)) { require_once $rendersetting_file; } } require_once $file_path; if (class_exists($feature['class'])) { try { $instance = new $feature['class'](); $this->addSubclass($instance); if (defined('WP_DEBUG') && WP_DEBUG && $feature['class'] === 'AIAutoTool_AutoCreateCategories') { error_log('AI Auto Tool: Successfully loaded AIAutoTool_AutoCreateCategories'); } } catch (Exception $e) { if (defined('WP_DEBUG') && WP_DEBUG) { error_log('AI Auto Tool: Failed to load ' . $feature['class'] . ': ' . $e->getMessage()); error_log('AI Auto Tool: Exception trace: ' . $e->getTraceAsString()); } } catch (Error $e) { if (defined('WP_DEBUG') && WP_DEBUG) { error_log('AI Auto Tool: Fatal error loading ' . $feature['class'] . ': ' . $e->getMessage()); error_log('AI Auto Tool: Error trace: ' . $e->getTraceAsString()); } } } else { if (defined('WP_DEBUG') && WP_DEBUG && $feature['class'] === 'AIAutoTool_AutoCreateCategories') { error_log('AI Auto Tool: Class AIAutoTool_AutoCreateCategories not found after requiring file: ' . $file_path); error_log('AI Auto Tool: rendersetting class exists: ' . (class_exists('rendersetting') ? 'YES' : 'NO')); } } } else { if (defined('WP_DEBUG') && WP_DEBUG && $feature['class'] === 'AIAutoTool_AutoCreateCategories') { error_log('AI Auto Tool: File not found: ' . $file_path); } } } else { if (defined('WP_DEBUG') && WP_DEBUG && $feature['class'] === 'AIAutoTool_AutoCreateCategories') { error_log('AI Auto Tool: Feature not loaded - is_active: ' . ($is_active ? 'YES' : 'NO') . ', is_admin_page: ' . ($is_admin_page ? 'YES' : 'NO') . ', load_on_admin: ' . ($feature['load_on_admin'] ? 'YES' : 'NO')); } } } // Prompt Customer - Load in admin to register AJAX actions if ($is_admin_page) { $prompt_customer_file = plugin_dir_path(__FILE__) . 'inc/features/prompt-customer/AI_AutoTool_Prompt_Customer.php'; if (file_exists($prompt_customer_file)) { require_once $prompt_customer_file; if (class_exists('AI_AutoTool_Prompt_Customer')) { $AI_AutoTool_Prompt_Customer = new AI_AutoTool_Prompt_Customer(); $this->addSubclass($AI_AutoTool_Prompt_Customer); } } } // Legacy class loading - only if classes already exist (loaded by features above) if (class_exists('URL_Scanner_Plugin')) { $url_scanner_plugin = new URL_Scanner_Plugin(); $this->addSubclass($url_scanner_plugin); } if (class_exists('AIAutoToolsinglepost')) { $AIAutoToolsinglepost = new AIAutoToolsinglepost(); $this->addSubclass($AIAutoToolsinglepost); } if (class_exists('AIautotool_autocomment')) { $AIautotool_autocomment = new AIautotool_autocomment(); $this->addSubclass($AIautotool_autocomment); } if (class_exists('AIautotool_autocreatetags')) { $AIautotool_autocreatetags = new AIautotool_autocreatetags(); $this->addSubclass($AIautotool_autocreatetags); } if (class_exists('AI_AutoTool_cloudflareAI')) { $AI_AutoTool_cloudflareAI = new AI_AutoTool_cloudflareAI(); $this->addSubclass($AI_AutoTool_cloudflareAI); } // Note: auto-create-categories feature is now loaded via $features_to_load array above if (class_exists('AI_AutoTool_suggetauto')) { $AI_AutoTool_suggetauto = new AI_AutoTool_suggetauto(); $this->addSubclass($AI_AutoTool_suggetauto); } if (class_exists('AIautotool_Prompt_CPT')) { $AIautotool_Prompt_CPT = new AIautotool_Prompt_CPT(); $this->addSubclass($AIautotool_Prompt_CPT); } if (class_exists('AIAutoTool_SubmitIndex')) { $AIAutoTool_SubmitIndex = new AIAutoTool_SubmitIndex(); $this->addSubclass($AIAutoTool_SubmitIndex); } if (class_exists('Aiautotool_exLink_backlink')) { $Aiautotool_exLink_backlink = new Aiautotool_exLink_backlink(); $this->addSubclass($Aiautotool_exLink_backlink); } if (class_exists('Aiautotool_Canonical')) { $Aiautotool_Canonical = new Aiautotool_Canonical(); $this->addSubclass($Aiautotool_Canonical); } if (class_exists('AIautotool_Web_Stories')) { $AIautotool_Web_Stories = new AIautotool_Web_Stories(); $this->addSubclass($AIautotool_Web_Stories); } // if (class_exists('AIAutoToolSecurityBot')) { // $AIAutoToolSecurityBot = new AIAutoToolSecurityBot(); // $this->addSubclass($AIAutoToolSecurityBot); // } // if (class_exists('AIAutotool_Image404Scanner')) { // $AIAutotool_Image404Scanner = new AIAutotool_Image404Scanner(); // $this->addSubclass($AIAutotool_Image404Scanner); // } // if (class_exists('aiautotool_AutoGenerateUsername')) { // $aiautotool_AutoGenerateUsername = new aiautotool_AutoGenerateUsername(); // $this->addSubclass($aiautotool_AutoGenerateUsername); // } // if (class_exists('Post_Exporter_Plugin')) { // $Post_Exporter_Plugin = new Post_Exporter_Plugin(); // $this->addSubclass($Post_Exporter_Plugin); // } // if (class_exists('Auto_Install_Plugins')) { // $Auto_Install_Plugins = new Auto_Install_Plugins(); // $this->addSubclass($Auto_Install_Plugins); // } // if (class_exists('Keyword_Autopost_Plugin')) { // $Keyword_Autopost_Plugin = new Keyword_Autopost_Plugin(); // $this->addSubclass($Keyword_Autopost_Plugin); // } // if (class_exists('Aiautotool_Footer_Base')) { // $Aiautotool_Footer_Base = new Aiautotool_Footer_Base(); // $this->addSubclass($Aiautotool_Footer_Base); // } // if (class_exists('activeCallBack')) { // $activeCallBack = new activeCallBack(); // } // if (class_exists('AI_AutoTool_Prompt_Customer')) { // $AI_AutoTool_Prompt_Customer = new AI_AutoTool_Prompt_Customer(); // } $new_object_loaded = true; } public function show_render_setting() { foreach ($this->subclasses as $subclass) { // Skip AI_AutoTool_Prompt_Customer as it's rendered separately in #set-prompt tab if (get_class($subclass) === 'AI_AutoTool_Prompt_Customer') { continue; } if (method_exists($subclass, 'render_setting')) { $subclass->render_setting(); } } } public function show_render_tab_setting() { foreach ($this->subclasses as $subclass) { if (method_exists($subclass, 'render_tab_setting')) { $subclass->render_tab_setting(); } } } public function render_list_feature(){ // Load only active features from inc directory $this->load_all_inc_features(); // Render all features (both active and inactive) using AutoToolBox $this->render_all_features(); } /** * Force load feature descriptions file */ private function ensure_feature_descriptions_loaded() { if (!class_exists('AiAutoTool_Feature_Descriptions')) { $file_path = plugin_dir_path(__FILE__) . 'lib/feature-descriptions.php'; if (file_exists($file_path)) { require_once $file_path; error_log('AI Auto Tool Debug: Force loaded feature-descriptions.php'); } else { error_log('AI Auto Tool Debug: feature-descriptions.php not found at: ' . $file_path); } } } /** * Get feature description with fallback * * @param string $feature_key Feature key * @param string $fallback_description Fallback description if class not available * @return string Description HTML */ private function get_feature_description($feature_key, $fallback_description = '') { // Ensure feature descriptions are loaded $this->ensure_feature_descriptions_loaded(); // Debug: Check if class exists if (!class_exists('AiAutoTool_Feature_Descriptions')) { error_log('AI Auto Tool Debug: AiAutoTool_Feature_Descriptions class not found for feature: ' . $feature_key); return $fallback_description; } $description = AiAutoTool_Feature_Descriptions::get_truncated_description($feature_key); if (empty($description)) { error_log('AI Auto Tool Debug: Empty description for feature: ' . $feature_key); return $fallback_description; } return $description; } /** * Render all features (active and inactive) using AutoToolBox * IMPORTANT FUNCTION: This method controls feature rendering in the main UI. */ private function render_all_features() { // Static flag to prevent multiple renders static $features_rendered = false; if ($features_rendered) { return; } // Cache for option values to prevent repeated database queries static $option_cache = array(); $inc_dir = plugin_dir_path(__FILE__) . 'inc/'; // Get feature registry from centralized method $feature_files = $this->get_feature_registry(); // Separate features into active and disabled arrays $active_features = array(); $disabled_features = array(); foreach ($feature_files as $file => $config) { $file_path = $inc_dir . $file; $class_name = $config['class']; $active_option = $config['active_option']; $title = $config['title']; $description = $config['description']; $icon = $config['icon']; // Check if file exists if (file_exists($file_path)) { // Check if feature is active - use cache to prevent repeated DB queries // Special handling: Cron Status Widget is always active if ($active_option === 'AIAutoTool_Cron_Status_Widget_active') { $is_active = 'true'; // Always active, cannot be disabled // Ensure option is set to true if (!isset($option_cache[$active_option])) { update_option($active_option, 'true'); $option_cache[$active_option] = 'true'; } } else { if (!isset($option_cache[$active_option])) { // Try to get option with original name first $is_active = get_option($active_option, false); // If not found, try normalized name (in case it was saved with normalized name) if ($is_active === false) { $normalized_option = $active_option; if (strpos($normalized_option, 'aiautotool_') !== 0) { $normalized_option = 'aiautotool_' . $normalized_option; } $is_active = get_option($normalized_option, false); // If found with normalized name, migrate it to original name for consistency if ($is_active !== false) { update_option($active_option, $is_active, false); delete_option($normalized_option); } } // Also try using FeatureOptions if available if ($is_active === false && class_exists('AIAutoTool_FeatureOptions')) { $is_active = AIAutoTool_FeatureOptions::get_option($active_option, false); } $option_cache[$active_option] = $is_active; } $is_active = $option_cache[$active_option]; } $active = ($is_active === 'true' || $is_active === true); // Store feature data for later rendering $feature_data = array( 'file' => $file, 'config' => $config, 'active' => $active, 'active_option' => $active_option ); // Categorize feature if ($active) { $active_features[] = $feature_data; } else { $disabled_features[] = $feature_data; } } } // Render Active Features Section if (!empty($active_features)) { echo '
'; echo '
'; echo '

'; echo ''; echo __('Active Features', 'ai-auto-tool'); echo ' ' . count($active_features) . ''; echo '

'; echo '

' . __('These features are currently enabled and active on your site', 'ai-auto-tool') . '

'; echo '
'; echo '
'; foreach ($active_features as $feature_data) { $config = $feature_data['config']; $active = $feature_data['active']; $active_option = $feature_data['active_option']; // Create AutoToolBox for this feature $box = new AutoToolBox( $config['icon'] . ' ' . $config['title'], $config['description'], admin_url('admin.php?page=aiautotool_integrations'), $active_option, $active, '', false ); // Render the box echo $box->generateHTML(); } echo '
'; echo '
'; } // Render Disabled Features Section if (!empty($disabled_features)) { echo '
'; echo '
'; echo '

'; echo ''; echo __('Disabled Features', 'ai-auto-tool'); echo ' ' . count($disabled_features) . ''; echo '

'; echo '

' . __('These features are currently disabled and not active on your site', 'ai-auto-tool') . '

'; echo '
'; echo '
'; foreach ($disabled_features as $feature_data) { $config = $feature_data['config']; $active = $feature_data['active']; $active_option = $feature_data['active_option']; // Create AutoToolBox for this feature $box = new AutoToolBox( $config['icon'] . ' ' . $config['title'], $config['description'], admin_url('admin.php?page=aiautotool_integrations'), $active_option, $active, '', false ); // Render the box echo $box->generateHTML(); } echo '
'; echo '
'; } $features_rendered = true; } /** * Get feature registry - extracted from render_all_features for reuse * * @return array Feature registry with file paths and metadata */ private function get_feature_registry() { return array( 'features/canonical-manager/canonical-manager.php' => array( 'class' => 'AIAutoTool\Features\CanonicalManager\CanonicalManager', 'active_option' => 'Aiautotool_Canonical_active', 'title' => 'Canonical Manager', 'description' => $this->get_feature_description('canonical', 'Manage canonical URLs and redirects'), 'icon' => '' ), 'features/external-links/external-links.php' => array( 'class' => 'AIAutoTool\Features\ExternalLinks\ExternalLinks', 'active_option' => 'Aiautotool_exLink_backlink_active', 'title' => 'Auto External Links', 'description' => $this->get_feature_description('microsite_backlink', 'Automatically manage external links and backlinks'), 'icon' => '' ), 'features/submit-index/submit-index.php' => array( 'class' => 'AIAutoTool\Features\SubmitIndex\SubmitIndex', 'active_option' => 'AIAutoTool_SubmitIndex_active', 'title' => 'Submit Index', 'description' => $this->get_feature_description('google_index', 'Submit URLs to search engines for indexing'), 'icon' => '' ), 'features/post-exporter/post-exporter.php' => array( 'class' => 'AIAutoTool\Features\PostExporter\PostExporter', 'active_option' => 'Post_Exporter_Plugin_active', 'title' => 'Post Exporter', 'description' => $this->get_feature_description('post_exporter', 'Export posts and content to various formats'), 'icon' => '' ), 'features/keyword-autopost/keyword-autopost.php' => array( 'class' => 'AIAutoTool\Features\KeywordAutopost\KeywordAutopost', 'active_option' => 'aiautotool_keyword_autopost_active', 'title' => 'Keyword Autopost', 'description' => $this->get_feature_description('keyword_autopost', 'Automatically create posts based on keywords'), 'icon' => '' ), 'features/single-ai/single-ai.php' => array( 'class' => 'AIAutoTool\Features\SingleAI\SingleAI', 'active_option' => 'AIAutoToolsinglepost_active', 'title' => 'Single AI Post', 'description' => $this->get_feature_description('single_ai', 'Create individual AI-powered posts'), 'icon' => '' ), 'features/image-scanner/image-scanner.php' => array( 'class' => 'AIAutoTool\Features\ImageScanner\ImageScanner', 'active_option' => 'AIAutotool_Image404Scanner_active', 'title' => 'Image Scanner', 'description' => $this->get_feature_description('thumb_fix', 'Scan and manage images for 404 errors'), 'icon' => '' ), 'features/auto-comment/auto-comment.php' => array( 'class' => 'AIAutoTool\Features\AutoComment\AutoComment', 'active_option' => 'AIautotool_autocomment_active', 'title' => 'Auto Comment', 'description' => $this->get_feature_description('auto_comment', 'Automatically generate and post comments using AI'), 'icon' => '' ), 'features/auto-create-tags/auto-create-tags.php' => array( 'class' => 'AIAutoTool\Features\AutoCreateTags\AutoCreateTags', 'active_option' => 'AIautotool_autocreatetags_active', 'title' => 'Auto Create Tags', 'description' => $this->get_feature_description('auto_create_tag', 'Automatically create and assign tags to posts'), 'icon' => '' ), 'features/cloudflare-ai/cloudflare-ai.php' => array( 'class' => 'AIAutoTool\Features\CloudflareAI\CloudflareAI', 'active_option' => 'AI_AutoTool_cloudflareAI_active', 'title' => 'Cloudflare AI', 'description' => $this->get_feature_description('cloudflare_ai', 'Integrate with Cloudflare AI services'), 'icon' => '' ), 'features/suggest-auto/suggest-auto.php' => array( 'class' => 'AIAutoTool\Features\SuggestAuto\SuggestAuto', 'active_option' => 'AI_AutoTool_suggetauto_active', 'title' => 'Suggest Auto', 'description' => $this->get_feature_description('suggest_auto', 'Automatically suggest content improvements'), 'icon' => '' ), 'features/prompt-cpt/prompt-cpt.php' => array( 'class' => 'AIAutoTool\Features\PromptCPT\PromptCPT', 'active_option' => 'AIautotool_Prompt_CPT_active', 'title' => 'Prompt CPT', 'description' => $this->get_feature_description('prompt_manager', 'Manage custom post types for prompts'), 'icon' => '' ), 'features/prompt-customer/prompt-customer.php' => array( 'class' => 'AIAutoTool\Features\PromptCustomer\PromptCustomer', 'active_option' => 'AI_AutoTool_Prompt_Customer_active', 'title' => 'Prompt Customer', 'description' => $this->get_feature_description('prompt_customer', 'Customer prompt management and customization'), 'icon' => '' ), 'features/bot-security/bot-security.php' => array( 'class' => 'AIAutoTool\Features\BotSecurity\BotSecurity', 'active_option' => 'AIAutoToolSecurityBot_active', 'title' => 'Bot Security', 'description' => 'Security features for bot protection', 'icon' => '' ), 'features/web-stories/web-stories.php' => array( 'class' => 'AIAutoTool\Features\WebStories\WebStories', 'active_option' => 'AIautotool_Web_Stories_active', 'title' => 'Web Stories', 'description' => $this->get_feature_description('webstories', 'Create and manage web stories'), 'icon' => '' ), 'features/install-plugin/install-plugin.php' => array( 'class' => 'AIAutoTool\Features\InstallPlugin\InstallPlugin', 'active_option' => 'Aiautotool_Install_Plugin_active', 'title' => 'Install Plugin', 'description' => $this->get_feature_description('install_plugin', 'Install and manage plugins'), 'icon' => '' ), 'features/footer-base/footer-base.php' => array( 'class' => 'AIAutoTool\Features\FooterBase\FooterBase', 'active_option' => 'Aiautotool_footer_base_active', 'title' => 'Footer Base', 'description' => 'Manage footer content and base elements', 'icon' => '' ), 'features/username-generator/username-generator.php' => array( 'class' => 'AIAutoTool\Features\UsernameGenerator\UsernameGenerator', 'active_option' => 'aiautotool_AutoGenerateUsername_active', 'title' => 'Auto Generate Username', 'description' => 'Automatically generate usernames', 'icon' => '' ), 'features/autoblogging/autoblogging.php' => array( 'class' => 'AIAutoTool\Features\Autoblogging\Autoblogging', 'active_option' => 'AI_AutoTool_Autoblogging_active', 'title' => 'Autoblogging', 'description' => 'Automatically create blog posts from URLs using AI', 'icon' => '' ), 'features/auto-create-categories/auto-create-categories.php' => array( 'class' => 'AIAutoTool_AutoCreateCategories', 'active_option' => 'AIAutoTool_auto_create_categories_active', 'title' => 'Auto Create Categories', 'description' => $this->get_feature_description('auto_create_categories', 'Tự động tạo danh sách category dạng cây thư mục bằng AI, tối ưu SEO theo topic cluster'), 'icon' => '' ), 'features/crawlcampaign/crawlcampaign.php' => array( 'class' => 'AIAutoTool\Features\CrawlCampaign\CrawlCampaign', 'active_option' => 'aiautotool_crawlcampaign_active', 'title' => 'Crawl Campaign', 'description' => $this->get_feature_description('crawlcampaign', 'Tự động crawl và đăng bà i từ nhiều nguồn (RSS, YouTube, Amazon, Facebook, Instagram, Twitter, etc.)'), 'icon' => '' ), ); } /** * Register AJAX handlers for all features */ public function register_all_ajax_handlers() { $active_options = array( 'Aiautotool_Canonical_active', 'Aiautotool_exLink_backlink_active', 'AIAutoTool_SubmitIndex_active', 'Post_Exporter_Plugin_active', 'aiautotool_keyword_autopost_active', 'AIAutoToolsinglepost_active', 'AIAutotool_Image404Scanner_active', 'AIautotool_autocomment_active', 'AIautotool_autocreatetags_active', 'AI_AutoTool_cloudflareAI_active', 'AI_AutoTool_suggetauto_active', 'AIautotool_Prompt_CPT_active', 'AI_AutoTool_Prompt_Customer_active', // Add Prompt Customer // Temporarily disabled due to HTML output issues 'AIAutoToolSecurityBot_active', 'AIautotool_Web_Stories_active', 'Aiautotool_Install_Plugin_active', 'AI_AutoTool_Autoblogging_active', 'AIAutoTool_Cron_Status_Widget_active', 'aiautotool_AutoGenerateUsername_active', 'Aiautotool_footer_base_active', 'AIAutoTool_auto_create_categories_active', 'aiautotool_crawlcampaign_active', ); foreach ($active_options as $option) { // Register AJAX handler for this option (requires authentication - options modification) add_action('wp_ajax_update_active_option_canonical_' . $option, array($this, 'generic_update_active_option_callback')); } } /** * Generic AJAX callback for updating active options */ public function generic_update_active_option_callback() { check_ajax_referer('aiautotool_nonce', 'security'); if (!current_user_can('manage_options')) { wp_send_json_error(array('message' => __('Permission denied', 'ai-auto-tool')), 403); return; } if (isset($_POST['active'])) { $active = sanitize_text_field($_POST['active']); // Get the option name from the action hook $action = current_action(); $option_name = str_replace('wp_ajax_update_active_option_canonical_', '', $action); // Update the option update_option($option_name, $active, null, 'no'); // Return the new value wp_send_json_success(array('active' => $active, 'option' => $option_name)); } wp_send_json_error('Invalid request'); } /** * Tải tất cả các tính năng từ thư mục inc và thêm và o subclasses * Chỉ tải các tính năng đang được kích hoạt * CHẾ ĐỘ DEBUG: Bao gồm từng tệp một để theo dõi mức sử dụng bộ nhớ */ private function load_all_inc_features() { // Static flag to prevent multiple loads static $features_loaded = false; if ($features_loaded) { return; } // DEBUG MODE: Enable to track memory usage per file $debug_mode = defined('WP_DEBUG') && WP_DEBUG && (defined('AIAUTOTOOL_DEBUG_LOADING') && AIAUTOTOOL_DEBUG_LOADING); // Cache for option values to prevent repeated database queries static $option_cache = array(); $inc_dir = plugin_dir_path(__FILE__) . 'inc/'; // Define all feature files, their classes, and active option names $feature_files = array( 'features/canonical-manager/canonical-manager.php' => array( 'class' => 'AIAutoTool\Features\CanonicalManager\CanonicalManager', 'active_option' => 'Aiautotool_Canonical_active' ), 'features/external-links/external-links.php' => array( 'class' => 'AIAutoTool\Features\ExternalLinks\ExternalLinks', 'active_option' => 'Aiautotool_exLink_backlink_active' ), 'features/submit-index/submit-index.php' => array( 'class' => 'AIAutoTool\Features\SubmitIndex\SubmitIndex', 'active_option' => 'AIAutoTool_SubmitIndex_active' ), 'features/post-exporter/post-exporter.php' => array( 'class' => 'AIAutoTool\Features\PostExporter\PostExporter', 'active_option' => 'Post_Exporter_Plugin_active' ), 'features/keyword-autopost/keyword-autopost.php' => array( 'class' => 'AIAutoTool\Features\KeywordAutopost\KeywordAutopost', 'active_option' => 'aiautotool_keyword_autopost_active' ), 'features/single-ai/single-ai.php' => array( 'class' => 'AIAutoTool\Features\SingleAI\SingleAI', 'active_option' => 'AIAutoToolsinglepost_active' ), 'features/image-scanner/image-scanner.php' => array( 'class' => 'AIAutoTool\Features\ImageScanner\ImageScanner', 'active_option' => 'AIAutotool_Image404Scanner_active' ), 'features/auto-comment/auto-comment.php' => array( 'class' => 'AIAutoTool\Features\AutoComment\AutoComment', 'active_option' => 'AIautotool_autocomment_active' ), 'features/auto-create-tags/auto-create-tags.php' => array( 'class' => 'AIAutoTool\Features\AutoCreateTags\AutoCreateTags', 'active_option' => 'AIautotool_autocreatetags_active' ), 'features/cloudflare-ai/cloudflare-ai.php' => array( 'class' => 'AIAutoTool\Features\CloudflareAI\CloudflareAI', 'active_option' => 'AI_AutoTool_cloudflareAI_active' ), 'features/suggest-auto/suggest-auto.php' => array( 'class' => 'AIAutoTool\Features\SuggestAuto\SuggestAuto', 'active_option' => 'AI_AutoTool_suggetauto_active' ), 'features/prompt-cpt/prompt-cpt.php' => array( 'class' => 'AIAutoTool\Features\PromptCPT\PromptCPT', 'active_option' => 'AIautotool_Prompt_CPT_active' ), // Temporarily disabled due to HTML output issues 'features/bot-security/bot-security.php' => array( 'class' => 'AIAutoTool\Features\BotSecurity\BotSecurity', 'active_option' => 'AIAutoToolSecurityBot_active' ), 'features/web-stories/web-stories.php' => array( 'class' => 'AIAutoTool\Features\WebStories\WebStories', 'active_option' => 'AIautotool_Web_Stories_active' ), 'features/install-plugin/install-plugin.php' => array( 'class' => 'AIAutoTool\Features\InstallPlugin\InstallPlugin', 'active_option' => 'Aiautotool_Install_Plugin_active' ), 'features/footer-base/footer-base.php' => array( 'class' => 'AIAutoTool\Features\FooterBase\FooterBase', 'active_option' => 'Aiautotool_footer_base_active' ), 'features/username-generator/username-generator.php' => array( 'class' => 'AIAutoTool\Features\UsernameGenerator\UsernameGenerator', 'active_option' => 'aiautotool_AutoGenerateUsername_active' ), 'features/autoblogging/autoblogging.php' => array( 'class' => 'AIAutoTool\Features\Autoblogging\Autoblogging', 'active_option' => 'AI_AutoTool_Autoblogging_active' ), ); foreach ($feature_files as $file => $config) { $file_path = $inc_dir . $file; $class_name = $config['class']; $active_option = $config['active_option']; // Check if file exists and class is not already loaded if (file_exists($file_path) && !$this->is_class_loaded($class_name)) { // Check if feature is active - use cache to prevent repeated DB queries // Special handling: Cron Status Widget is always active if ($active_option === 'AIAutoTool_Cron_Status_Widget_active') { $is_active = 'true'; // Always active, cannot be disabled // Ensure option is set to true if (!isset($option_cache[$active_option])) { update_option($active_option, 'true'); $option_cache[$active_option] = 'true'; } } else { if (!isset($option_cache[$active_option])) { $option_cache[$active_option] = get_option($active_option, false); } $is_active = $option_cache[$active_option]; } // CRITICAL: Don't instantiate classes here to prevent memory exhaustion // Classes will be loaded on-demand when actually needed // Only require the file to ensure it's available if needed if (!class_exists($class_name)) { // DEBUG MODE: Track memory before and after loading each file if ($debug_mode) { $memory_before = memory_get_usage(true); $memory_before_mb = round($memory_before / 1024 / 1024, 2); error_log("AI Auto Tool DEBUG: [BEFORE] Loading {$file} - Memory: {$memory_before_mb} MB"); } try { require_once $file_path; if ($debug_mode) { $memory_after = memory_get_usage(true); $memory_after_mb = round($memory_after / 1024 / 1024, 2); $memory_diff = round(($memory_after - $memory_before) / 1024 / 1024, 2); $peak_memory = round(memory_get_peak_usage(true) / 1024 / 1024, 2); error_log("AI Auto Tool DEBUG: [AFTER] Loaded {$file} - Memory: {$memory_after_mb} MB (+{$memory_diff} MB) - Peak: {$peak_memory} MB"); // Warn if memory increase is significant if ($memory_diff > 5) { error_log("AI Auto Tool DEBUG: ⚠️ WARNING - {$file} increased memory by {$memory_diff} MB!"); } } } catch (Exception $e) { if ($debug_mode) { error_log("AI Auto Tool DEBUG: ❌ ERROR loading {$file}: " . $e->getMessage()); } // Continue with next file even if one fails continue; } catch (Error $e) { if ($debug_mode) { error_log("AI Auto Tool DEBUG: ❌ FATAL ERROR loading {$file}: " . $e->getMessage()); } // Continue with next file even if one fails continue; } } // DO NOT instantiate here - causes memory exhaustion // Instantiation will happen on-demand via render_all_features() or when feature is actually used /* // Check if class exists if (class_exists($class_name)) { try { $instance = new $class_name(); // Only add classes that have render_feature method if (method_exists($instance, 'render_feature')) { $this->addSubclass($instance); if (defined('WP_DEBUG') && WP_DEBUG) { error_log("AI Auto Tool: Loaded feature {$class_name} from {$file} (active: " . ($is_active ? 'yes' : 'no') . ")"); } } else { if (defined('WP_DEBUG') && WP_DEBUG) { error_log("AI Auto Tool: Skipped {$class_name} - no render_feature method"); } } } catch (Exception $e) { if (defined('WP_DEBUG') && WP_DEBUG) { error_log("AI Auto Tool: Failed to load {$class_name}: " . $e->getMessage()); } } } */ } } if ($debug_mode) { $final_memory = round(memory_get_usage(true) / 1024 / 1024, 2); $peak_memory = round(memory_get_peak_usage(true) / 1024 / 1024, 2); error_log("AI Auto Tool DEBUG: [COMPLETE] load_all_inc_features() finished - Final Memory: {$final_memory} MB - Peak: {$peak_memory} MB"); } $features_loaded = true; } /** * Check if a class is already loaded in subclasses */ private function is_class_loaded($class_name) { foreach ($this->subclasses as $subclass) { if (get_class($subclass) === $class_name) { return true; } } return false; } public function render_plan(){ // Track rendered features by active_option_name to prevent duplicates $rendered_features = array(); foreach ($this->subclasses as $subclass) { // Check if this feature has already been rendered if (isset($subclass->active_option_name)) { $option_name = $subclass->active_option_name; // Skip if already rendered if (isset($rendered_features[$option_name])) { continue; } // Mark as rendered $rendered_features[$option_name] = true; } // Only render if feature is active if (method_exists($subclass, 'render_plan')) { $subclass->render_plan(); } } } /** * Initialize Professional Autoloader System */ private function init_autoloader_system() { // Load Asset Manager FIRST (before other components that may need it) $asset_manager_file = plugin_dir_path(__FILE__) . 'inc/asset-manager.php'; if (file_exists($asset_manager_file)) { require_once $asset_manager_file; } // Load autoloader components $autoloader_files = array( 'inc/option-cache.php', // Load option cache FIRST for performance 'inc/autoloader.php', 'inc/class-mapper.php', 'inc/lazy-loader.php', 'inc/optimized-loader.php', 'inc/feature-options.php', 'inc/feature-manager.php', 'inc/migration.php', 'inc/menu-manager.php', // Add menu manager 'inc/class-duplicate-fixer.php', // Add duplicate fixer 'inc/menu-test.php', // Add menu test ); foreach ($autoloader_files as $file) { $file_path = plugin_dir_path(__FILE__) . $file; if (file_exists($file_path)) { require_once $file_path; } } // Initialize autoloader if (class_exists('AIAutoTool_Autoloader')) { AIAutoTool_Autoloader::init(); } // Initialize lazy loader if (class_exists('AIAutoTool_LazyLoader')) { AIAutoTool_LazyLoader::init(); } // Initialize menu manager if (class_exists('AIAutoTool_MenuManager')) { AIAutoTool_MenuManager::init($this); } // Initialize feature options if (class_exists('AIAutoTool_FeatureOptions')) { AIAutoTool_FeatureOptions::init_default_options(); } // Load AI Providers Module EARLY (MUST load before features that use AI) // This ensures AI Helper is always available when features need it $ai_providers_index = plugin_dir_path(__FILE__) . 'inc/ai-providers/index.php'; if (file_exists($ai_providers_index)) { require_once $ai_providers_index; if (defined('WP_DEBUG') && WP_DEBUG) { error_log('AI Auto Tool: AI Providers module loaded'); } } // CRITICAL FIX: Defer class map generation to avoid memory exhaustion // Only generate on-demand or via admin action, not during plugin initialization // This prevents recursive file scanning that can exhaust memory // The autoloader will work without the generated map using fallback methods /* if (class_exists('AIAutoTool_ClassMapper')) { AIAutoTool_ClassMapper::generateClassMap(); } */ if (defined('WP_DEBUG') && WP_DEBUG) { error_log('AI Auto Tool: Professional autoloader system initialized'); } } /** * Legacy load_inc method - now uses lazy loading * @deprecated Use AIAutoTool_LazyLoader instead */ public function load_inc() { // Load rendersetting class first (required by many inc classes) $rendersetting_file = plugin_dir_path(__FILE__) . 'lib/setting.php'; if (file_exists($rendersetting_file)) { require_once $rendersetting_file; } // Load essential library classes (required by many inc classes) $essential_lib_files = array( 'lib/aiautotool_notice_control.php', // aiautotool_Warning_Notice 'lib/boxf.php', // AutoToolBox 'lib/bard.php', // BardGenContent 'lib/AIautotool_logall.php', // AIautoTool_log 'lib/feature-descriptions.php', // AiAutoTool_Feature_Descriptions ); foreach ($essential_lib_files as $file) { $file_path = plugin_dir_path(__FILE__) . $file; if (file_exists($file_path)) { require_once $file_path; // Debug: Log when feature-descriptions.php is loaded if ($file === 'lib/feature-descriptions.php') { error_log('AI Auto Tool Debug: feature-descriptions.php loaded successfully'); if (class_exists('AiAutoTool_Feature_Descriptions')) { error_log('AI Auto Tool Debug: AiAutoTool_Feature_Descriptions class exists'); } else { error_log('AI Auto Tool Debug: AiAutoTool_Feature_Descriptions class NOT found after loading file'); } } } else { // Debug: Log if file doesn't exist if ($file === 'lib/feature-descriptions.php') { error_log('AI Auto Tool Debug: feature-descriptions.php file not found at: ' . $file_path); } } } // This method is now handled by the autoloader system // Only load core files immediately (excluding API manager - handled by autoloader) $core_files = array( 'inc/canonical.php', 'inc/ssl.php', ); foreach ($core_files as $file) { $file_path = plugin_dir_path(__FILE__) . $file; if (file_exists($file_path)) { require_once $file_path; } } // Load AI Providers Module (MUST load before features that use AI) $ai_providers_index = plugin_dir_path(__FILE__) . 'inc/ai-providers/index.php'; if (file_exists($ai_providers_index)) { require_once $ai_providers_index; } // Load new Extra Config architecture $extra_config_bootstrap = plugin_dir_path(__FILE__) . 'inc/extra-config/bootstrap.php'; if (file_exists($extra_config_bootstrap)) { require_once $extra_config_bootstrap; } } /** * Legacy load_lib method - now uses lazy loading * @deprecated Use AIAutoTool_LazyLoader instead * FIXED: Only load essential files, not all files in lib directory * This prevents memory exhaustion from loading unnecessary files */ public function load_lib() { // Static flag to prevent multiple loads static $lib_loaded = false; if ($lib_loaded) { return; } // Only load essential library files that are required immediately // Other files will be loaded on-demand by the autoloader $essential_files = array( 'lib/setting.php', // rendersetting class - required by many features 'lib/aiautotool_notice_control.php', // aiautotool_Warning_Notice ); foreach ($essential_files as $file) { $file_path = plugin_dir_path(__FILE__) . $file; if (file_exists($file_path)) { require_once $file_path; } } $lib_loaded = true; // Note: Other lib files will be loaded on-demand via autoloader // This prevents loading all files upfront which causes memory issues } /** * Get autoloader statistics */ public function get_autoloader_stats() { if (class_exists('AIAutoTool_Autoloader')) { return AIAutoTool_Autoloader::getStats(); } return array(); } /** * Get lazy loader statistics */ public function get_lazy_loader_stats() { if (class_exists('AIAutoTool_LazyLoader')) { return AIAutoTool_LazyLoader::getStats(); } return array(); } /** * Force load feature */ public function load_feature($feature_name) { if (class_exists('AIAutoTool_LazyLoader')) { return AIAutoTool_LazyLoader::loadFeature($feature_name); } return false; } /** * Check if feature is loaded */ public function is_feature_loaded($feature_name) { if (class_exists('AIAutoTool_LazyLoader')) { return AIAutoTool_LazyLoader::isFeatureLoaded($feature_name); } return false; } /** * Legacy method for backward compatibility * Assets are now managed by Asset Manager (inc/asset-manager.php) * This method is kept for any external code that might call it directly * * @deprecated Use AIAutoTool_Asset_Manager instead */ public function add_aiautotool_button_js() { // Asset Manager now handles this, but we keep this method for backward compatibility // Assets will be loaded automatically by Asset Manager on plugin pages if (defined('WP_DEBUG') && WP_DEBUG) { error_log('AI Auto Tool: add_aiautotool_button_js() called (deprecated - use Asset Manager)'); } } /** * Ensure scripts are loaded for integrations page * Assets are now handled by Asset Manager * * @deprecated Use AIAutoTool_Asset_Manager instead */ public function ensure_integrations_scripts($hook) { // Asset Manager now handles this automatically // This method is kept for backward compatibility } public function add_menu_page() { add_menu_page( ' Ai Auto Tool', ' Ai Auto Tool', 'manage_options', MENUSUBPARRENT, array( $this, 'menu_page' ), 'data:image/svg+xml;base64,' . base64_encode(file_get_contents(plugin_dir_path(__FILE__) . '/images/logo.svg')), 3 ); add_submenu_page( MENUSUBPARRENT, ' Integrations', ' Integrations', 'manage_options', 'aiautotool_integrations', array($this, 'aiautotool_integrations') ); } public function aiautotool_integrations(){ // JS settings are now loaded via admin_enqueue_scripts hook // No need to call enqueue_integrations_page_assets() here ?>

config_page(); } /** * Get detailed plan status using Freemius SDK * Returns array with plan status information * * @return array Plan status information */ function get_plan_status() { $fs = aiautotool_premium(); $status_info = array( 'is_free' => false, 'is_trial' => false, 'is_paying' => false, 'is_cancelled' => false, 'is_expired' => false, 'is_trial_expired' => false, 'is_non_renewing' => false, 'plan_name' => 'free', 'plan_title' => 'Free', 'subscription_status' => null, 'status_label' => 'Free', 'status_color' => '#6c757d', 'trial_days_remaining' => null, 'trial_ends' => null, 'subscription_days_remaining' => null, 'subscription_expires' => null, ); try { // PRIORITY: Check trial FIRST before paying, because trial users should be shown as trial // Check if user is in trial - use multiple methods to ensure detection $is_trial_check = false; $trial_ends_date = null; // Method 1: Direct is_trial() check if (method_exists($fs, 'is_trial') && $fs->is_trial()) { $is_trial_check = true; } // Method 2: Check site trial_ends date if (!$is_trial_check) { try { $site = $fs->get_site(); if ($site && isset($site->trial_ends) && !empty($site->trial_ends)) { $trial_ends_timestamp = strtotime($site->trial_ends); $current_timestamp = time(); // If trial_ends is in the future, user is in trial if ($trial_ends_timestamp > $current_timestamp) { $is_trial_check = true; $trial_ends_date = $site->trial_ends; } } } catch (Exception $e) { if (defined('WP_DEBUG') && WP_DEBUG) { } } } // Method 3: Check if can_use_premium_code but not paying (likely trial) if (!$is_trial_check && method_exists($fs, 'can_use_premium_code') && $fs->can_use_premium_code()) { if (!method_exists($fs, 'is_paying') || !$fs->is_paying()) { // Has premium access but not paying = likely trial $is_trial_check = true; } } if ($is_trial_check) { $status_info['is_trial'] = true; $status_info['is_free'] = false; $status_info['plan_name'] = $fs->get_plan_name(); // For trial users, show "Trailer Pro" instead of just the plan title $plan_title_from_fs = $fs->get_plan_title(); $status_info['plan_title'] = ($plan_title_from_fs && $plan_title_from_fs !== 'Free') ? esc_html__('Trailer', 'ai-auto-tool') . ' ' . $plan_title_from_fs : esc_html__('Trailer Pro', 'ai-auto-tool'); $status_info['status_label'] = 'Trial'; $status_info['status_color'] = '#17a2b8'; $status_info['subscription_status'] = 'trialing'; // Calculate trial days remaining try { $site = $fs->get_site(); if ($site && isset($site->trial_ends) && !empty($site->trial_ends)) { $trial_ends_timestamp = strtotime($site->trial_ends); $current_timestamp = time(); $days_remaining = max(0, ceil(($trial_ends_timestamp - $current_timestamp) / 86400)); $status_info['trial_days_remaining'] = $days_remaining; $status_info['trial_ends'] = $site->trial_ends; } else if ($trial_ends_date) { $trial_ends_timestamp = strtotime($trial_ends_date); $current_timestamp = time(); $days_remaining = max(0, ceil(($trial_ends_timestamp - $current_timestamp) / 86400)); $status_info['trial_days_remaining'] = $days_remaining; $status_info['trial_ends'] = $trial_ends_date; } else { $status_info['trial_days_remaining'] = 0; } } catch (Exception $e) { if (defined('WP_DEBUG') && WP_DEBUG) { } $status_info['trial_days_remaining'] = 0; } } // Check if user is paying (Pro plan) - but only if NOT in trial else if ($fs->is_paying()) { $status_info['is_paying'] = true; $status_info['is_free'] = false; $status_info['plan_name'] = $fs->get_plan_name(); $status_info['plan_title'] = $fs->get_plan_title(); $status_info['status_label'] = 'Pro'; $status_info['status_color'] = '#28a745'; // Get subscription status try { $license = $fs->_get_license(); if ($license && isset($license->id)) { $subscription = $fs->_get_subscription($license->id); if ($subscription && method_exists($subscription, 'get_status')) { $subscription_status = $subscription->get_status(); $status_info['subscription_status'] = $subscription_status; // Calculate subscription days remaining if expiration date is available if (isset($license->expiration) && !empty($license->expiration)) { $expiration_timestamp = strtotime($license->expiration); $current_timestamp = time(); $days_remaining = max(0, ceil(($expiration_timestamp - $current_timestamp) / 86400)); $status_info['subscription_days_remaining'] = $days_remaining; $status_info['subscription_expires'] = $license->expiration; } // Check subscription status switch ($subscription_status) { case 'active': $status_info['status_label'] = 'Pro (Active)'; $status_info['status_color'] = '#28a745'; break; case 'canceled': $status_info['is_cancelled'] = true; $status_info['status_label'] = 'Pro (Cancelled)'; $status_info['status_color'] = '#ffc107'; break; case 'expired': $status_info['is_expired'] = true; $status_info['status_label'] = 'Pro (Expired)'; $status_info['status_color'] = '#dc3545'; break; case 'non_renewing': $status_info['is_non_renewing'] = true; $status_info['status_label'] = 'Pro (Non-Renewing)'; $status_info['status_color'] = '#ff9800'; break; } } } } catch (Exception $e) { if (defined('WP_DEBUG') && WP_DEBUG) { } } } // Check if trial has expired else if (method_exists($fs, 'has_trial_expired') && $fs->has_trial_expired()) { $status_info['is_trial_expired'] = true; $status_info['is_free'] = true; $status_info['status_label'] = 'Trial Expired'; $status_info['status_color'] = '#dc3545'; } // Check if free plan else if ($fs->is_free_plan()) { $status_info['is_free'] = true; $status_info['plan_name'] = 'free'; $status_info['plan_title'] = 'Free'; $status_info['status_label'] = 'Free'; $status_info['status_color'] = '#6c757d'; } // Fallback: check plan name else { $plan_name = $fs->get_plan_name(); $status_info['plan_name'] = $plan_name; $status_info['plan_title'] = $fs->get_plan_title(); if ($plan_name === 'free') { $status_info['is_free'] = true; $status_info['status_label'] = 'Free'; } else { $status_info['status_label'] = ucfirst($plan_name); $status_info['status_color'] = '#28a745'; } } // Debug logging if (defined('WP_DEBUG') && WP_DEBUG) { if (isset($status_info['trial_days_remaining']) && $status_info['trial_days_remaining'] !== null) { } if (isset($status_info['trial_ends']) && $status_info['trial_ends']) { } // Also log plan and subscription objects if available try { $plan = $fs->get_plan(); if ($plan) { } $license = $fs->_get_license(); if ($license && isset($license->id)) { $subscription = $fs->_get_subscription($license->id); if ($subscription) { if (method_exists($subscription, 'get_status')) { } } } } catch (Exception $e) { } } } catch (Exception $e) { if (defined('WP_DEBUG') && WP_DEBUG) { } } return $status_info; } function is_free_plan() { // Premium checks removed - always return false (always premium) return false; } // function is_free_plan() { // if ( ! aiautotool_premium()->is_registered() ) { // return true; // } // if ( ! aiautotool_premium()->has_paid_plan() ) { // return true; // } // return ( // 'free' === aiautotool_premium()->get_plan_name() || // ! aiautotool_premium()->has_features_enabled_license() // ); // } public function config_page() { if (!current_user_can('manage_options')) { wp_die(esc_html__('You do not have sufficient permissions to access this page.','ai-auto-tool')); } $api_key_list = get_option('aiautotool_api_key_list', array()); $config_img = get_option('aiautotool_config_img', false); $aiautotool_images_list = get_option('aiautotool_images_list', []); $users = get_users(); if (isset($_POST['aiautotool_add_key'])) { $new_key = 'KCT-'.uniqid(); $user_id = sanitize_text_field($_POST['aiautotool_user']); $api_key_list = get_option('aiautotool_api_key_list', array()); $api_key_list[] = array( 'key' => $new_key, 'user_id' => $user_id, ); update_option('aiautotool_api_key_list', $api_key_list,null, 'no'); echo esc_html('

New API key added.

'); } if (isset($_POST['aiautotool_save_config'])) { if(isset($_POST['aiautotool_config_img'])){ $config_img = sanitize_text_field($_POST['aiautotool_config_img']); update_option('aiautotool_config_img', $config_img,null, 'no'); } } if (isset($_POST['aiautotool_remove_api_key'])) { $remove_key = sanitize_text_field($_POST['aiautotool_remove_api_key']); unset($api_key_list[$remove_key]); update_option('aiautotool_api_key_list', $api_key_list,null, 'no'); } if (isset($_POST['aiautotool_remove_log_img'])) { update_option('aiautotool_images_list', [],null, 'no'); $aiautotool_images_list = get_option('aiautotool_images_list', []); echo esc_html('

Reset log Images Success!!!!.

'); } if (isset($_POST['aiautotool_remove_img_log_item'])) { $remove_key = sanitize_text_field($_POST['aiautotool_remove_img_log_item']); unset($aiautotool_images_list[$remove_key]); update_option('aiautotool_images_list', $aiautotool_images_list,null, 'no'); echo esc_html('

Remove log item image Success!!!!.

'); } $this->aiautotool_config_settings = get_option('aiautotool_code_settings',array()); if(isset($_POST['aiautotool_code_settings'])){ foreach($_POST['aiautotool_code_settings'] as $key => $value){ if($key!='btnall'){ $this->aiautotool_config_settings[$key] = $value; } } $result = update_option('aiautotool_code_settings',(array )$this->aiautotool_config_settings,null, 'no'); $this->aiautotool_config_settings = get_option('aiautotool_code_settings',array()); } ?>

render_subscription_info(); ?>
subclasses as $subclass) { if (get_class($subclass) === 'AI_AutoTool_Prompt_Customer') { $AI_AutoTool_Prompt_Customer = $subclass; break; } } // If not found, create new instance (shouldn't happen if aiautotool_new_object ran) if (!$AI_AutoTool_Prompt_Customer && class_exists('AI_AutoTool_Prompt_Customer')) { $AI_AutoTool_Prompt_Customer = new AI_AutoTool_Prompt_Customer(); $this->addSubclass($AI_AutoTool_Prompt_Customer); } if ($AI_AutoTool_Prompt_Customer) { $AI_AutoTool_Prompt_Customer->render_setting(); } ?>
aiautotool_getdata(); // Get expiration data $expiration_data = isset($dt['expiration']) && is_array($dt['expiration']) ? $dt['expiration'] : array(); $start_date = isset($expiration_data['start_date']) ? $expiration_data['start_date'] : date('Y-m-d'); $expiration_date = isset($expiration_data['expiration']) ? $expiration_data['expiration'] : date('Y-m-d', strtotime('+1 month')); // Calculate days until reset $current_date = date('Y-m-d'); $expiration_timestamp = strtotime($expiration_date); $current_timestamp = strtotime($current_date); $days_until_reset = max(0, ceil(($expiration_timestamp - $current_timestamp) / 86400)); // Calculate usage breakdown percentages $total_usage = max(1, $dt['usage']); // Avoid division by zero $post_usage_pct = $total_usage > 0 ? round(($dt['AI_post_usage'] / $total_usage) * 100, 1) : 0; $comment_usage_pct = $total_usage > 0 ? round(($dt['Commentauto_AI_usage'] / $total_usage) * 100, 1) : 0; $tag_usage_pct = $total_usage > 0 ? round(($dt['Autocreatetag_AI_usage'] / $total_usage) * 100, 1) : 0; $schedule_usage_pct = $total_usage > 0 ? round(($dt['Schedule_AI_usage'] / $total_usage) * 100, 1) : 0; // Get plan status FIRST to accurately determine if user is free or premium/trial $plan_status_check = $this->get_plan_status(); $is_free = $plan_status_check['is_free']; // Double-check: If has active license, trial, or license object, force is_free to false // This ensures premium features are shown even if plan_name hasn't updated yet $fs_debug = aiautotool_premium(); $has_license_debug = $fs_debug->has_active_valid_license(); $has_features_debug = $fs_debug->has_features_enabled_license(); $is_trial_debug = method_exists($fs_debug, 'is_trial') ? $fs_debug->is_trial() : false; $is_paying_debug = method_exists($fs_debug, 'is_paying') ? $fs_debug->is_paying() : false; $license_obj_debug = $fs_debug->_get_license(); // If has active license, features enabled, trial, paying, or license object exists, force NOT free if ($has_license_debug || $has_features_debug || $is_trial_debug || $is_paying_debug || (is_object($license_obj_debug) && isset($license_obj_debug->id))) { $is_free = false; // Definitely NOT free if license exists, trial, or paying } $plan_limit = $is_free ? AIAUTOTOOL_FREE : ($dt['quota'] == -1 ? -1 : 5000); $remaining = $plan_limit == -1 ? -1 : max(0, $plan_limit - $dt['usage']); $usage_percentage = $plan_limit == -1 ? 0 : min(100, ($dt['usage'] / $plan_limit) * 100); // Show premium activation notice if premium is activated if (!$is_free && (aiautotool_premium()->has_active_valid_license() || (is_object($license_obj_debug) && isset($license_obj_debug->id)))) { $fs = rendersetting::is_premium(); $plan_title = $fs->get_plan_title(); echo '
'; echo '
'; echo '
'; echo ''; echo '
'; echo '
'; echo '

' . esc_html__('Premium Activated', 'ai-auto-tool') . '

'; echo '

' . sprintf(esc_html__('Your %s plan is active and all premium features are unlocked!', 'ai-auto-tool'), '' . esc_html($plan_title) . '') . '

'; echo '
'; echo '
'; echo '
'; } echo '
'; // Header Section - Modern Design echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '

' . esc_html__('Plan & Quota Overview', 'ai-auto-tool') . '

'; echo '

' . esc_html($domain) . ' | v' . esc_html(AIAUTOTOOL_VS) . '

'; echo '
'; if (!$is_free) { // Get plan status for accurate display $plan_status = $this->get_plan_status(); $accountType = $plan_status['plan_title']; $status_color = $plan_status['status_color']; echo '
'; echo '
'; echo '
' . esc_html__('Current Plan', 'ai-auto-tool') . '
'; echo '
' . esc_html($accountType) . '
'; if ($plan_status['subscription_status']) { echo '
' . esc_html(ucfirst($plan_status['subscription_status'])) . '
'; } echo '
'; echo '
'; } echo '
'; echo '
'; if ($is_free) { echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo ''; echo '
'; echo '

' . esc_html__('Upgrade to Premium', 'ai-auto-tool') . '

'; echo '
'; echo '

' . esc_html__('Unlock unlimited requests and access to all premium features!', 'ai-auto-tool') . '

'; // Check if user is eligible for new user discount $is_new_user = false; $discount_code = 'NEWKCT50'; if ( class_exists( 'AIAutoTool_NewUserDiscount' ) ) { $discount_handler = new AIAutoTool_NewUserDiscount(); $is_new_user = $discount_handler->is_new_user(); $discount_code = apply_filters( 'aiautotool_new_user_discount_code', AIAutoTool_NewUserDiscount::NEW_USER_DISCOUNT_CODE ); } // Display discount notice for new users if ( $is_new_user ) { $upgrade_url = aiautotool_premium()->get_upgrade_url(); $upgrade_url_with_coupon = add_query_arg( 'coupon', $discount_code, $upgrade_url ); echo '
'; echo '

'; echo '🎉 ' . esc_html__('Special Offer for New Users!', 'ai-auto-tool') . '
'; printf( esc_html__('Use code %s to get 50%% off on your first purchase!', 'ai-auto-tool'), '' . esc_html( $discount_code ) . '' ); echo '

'; echo '
'; } echo '
'; // Check if trial is available $fs_trial = aiautotool_premium(); $has_trial_plan = method_exists($fs_trial, 'has_trial_plan') ? $fs_trial->has_trial_plan() : true; $is_trial_utilized = method_exists($fs_trial, 'is_trial_utilized') ? $fs_trial->is_trial_utilized() : false; $can_start_trial = $has_trial_plan && !$is_trial_utilized; // Show "Start Trial" button if trial is available $trial_url = method_exists($fs_trial, 'get_trial_url') ? $fs_trial->get_trial_url() : $fs_trial->get_upgrade_url() . '&trial=true'; echo ''; echo ' ' . esc_html__('Start Free Trial', 'ai-auto-tool'); echo ''; $upgrade_url_final = $is_new_user ? add_query_arg( 'coupon', $discount_code, aiautotool_premium()->get_upgrade_url() ) : aiautotool_premium()->get_upgrade_url(); echo ''; echo ' ' . esc_html__('Upgrade to Pro', 'ai-auto-tool'); echo ''; $fs_unique_affix = aiautotool_premium()->get_unique_affix(); echo ''; echo ' ' . esc_html__( 'Activate License', 'ai-auto-tool' ); echo ''; echo '
'; echo '
'; echo '
'; // Ensure the activation modal and trial modal are available on this page if ( function_exists( 'fs_require_once_template' ) ) { $vars = array( 'id' => aiautotool_premium()->get_id() ); fs_require_once_template( 'forms/license-activation.php', $vars ); // Load trial start template if trial is available if ($can_start_trial) { fs_require_once_template( 'forms/trial-start.php', $vars ); } } } else { // Get detailed plan status $plan_status = $this->get_plan_status(); $fs = rendersetting::is_premium(); $accountType = $plan_status['plan_title']; // Determine background color and style based on status $bg_gradient = 'linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%)'; $icon_bg = 'linear-gradient(135deg, #28a745 0%, #20c997 100%)'; $text_color = '#155724'; if ($plan_status['is_trial']) { $bg_gradient = 'linear-gradient(135deg, #d1ecf1 0%, #bee5eb 100%)'; $icon_bg = 'linear-gradient(135deg, #17a2b8 0%, #138496 100%)'; $text_color = '#0c5460'; } else if ($plan_status['is_cancelled']) { $bg_gradient = 'linear-gradient(135deg, #fff3cd 0%, #ffeaa7 100%)'; $icon_bg = 'linear-gradient(135deg, #ffc107 0%, #ff9800 100%)'; $text_color = '#856404'; } else if ($plan_status['is_expired'] || $plan_status['is_trial_expired']) { $bg_gradient = 'linear-gradient(135deg, #f8d7da 0%, #f5c6cb 100%)'; $icon_bg = 'linear-gradient(135deg, #dc3545 0%, #c82333 100%)'; $text_color = '#721c24'; } else if ($plan_status['is_non_renewing']) { $bg_gradient = 'linear-gradient(135deg, #ffe0b2 0%, #ffcc80 100%)'; $icon_bg = 'linear-gradient(135deg, #ff9800 0%, #f57c00 100%)'; $text_color = '#e65100'; } // Safely get plan_id with null checks $plan_id = null; try { $license = aiautotool_premium()->_get_license(); if ($license && isset($license->id)) { $subscription = aiautotool_premium()->_get_subscription($license->id); if ($subscription && isset($subscription->plan_id)) { $plan_id = $subscription->plan_id; } } } catch (Exception $e) { if (defined('WP_DEBUG') && WP_DEBUG) { } } echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo ''; echo '
'; echo '
'; echo '

' . esc_html__('Premium Plan Benefits', 'ai-auto-tool') . '

'; echo '

' . sprintf(esc_html__('Status: %s', 'ai-auto-tool'), '' . esc_html($plan_status['status_label']) . '') . '

'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
' . esc_html__('Unlimited Requests', 'ai-auto-tool') . '
'; echo '
' . esc_html__('All Premium Features', 'ai-auto-tool') . '
'; echo '
' . esc_html__('Priority Support', 'ai-auto-tool') . '
'; echo '
' . esc_html__('Regular Updates', 'ai-auto-tool') . '
'; // Trailer/Trial display with days remaining $trailer_text = esc_html__('Trial', 'ai-auto-tool'); $days_remaining = null; // Check for trial days remaining if ($plan_status['is_trial'] && isset($plan_status['trial_days_remaining']) && $plan_status['trial_days_remaining'] !== null) { $days_remaining = intval($plan_status['trial_days_remaining']); } // Check for subscription days remaining (for paying users) else if ($plan_status['is_paying'] && isset($plan_status['subscription_days_remaining']) && $plan_status['subscription_days_remaining'] !== null) { $days_remaining = intval($plan_status['subscription_days_remaining']); } // Display days remaining if available if ($days_remaining !== null) { if ($days_remaining > 0) { $trailer_text = esc_html__('Trailer', 'ai-auto-tool') . ' (' . sprintf(esc_html__('%d days remaining', 'ai-auto-tool'), $days_remaining) . ')'; } else { $trailer_text = esc_html__('Trailer', 'ai-auto-tool') . ' (' . esc_html__('Expiring soon', 'ai-auto-tool') . ')'; } } echo '
' . $trailer_text . '
'; echo '
'; // Show warning messages for cancelled, expired, or non-renewing plans if ($plan_status['is_cancelled']) { echo '
'; echo '

'; echo ''; echo '' . esc_html__('Subscription Cancelled', 'ai-auto-tool') . ' - ' . esc_html__('Your subscription has been cancelled but you can still use premium features until the end of your billing period.', 'ai-auto-tool'); echo '

'; echo '
'; } else if ($plan_status['is_expired'] || $plan_status['is_trial_expired']) { echo '
'; echo '

'; echo ''; echo '' . esc_html__('Subscription Expired', 'ai-auto-tool') . ' - ' . esc_html__('Your subscription has expired. Please renew to continue using premium features.', 'ai-auto-tool'); echo '

'; echo '
'; } else if ($plan_status['is_non_renewing']) { echo '
'; echo '

'; echo ''; echo '' . esc_html__('Non-Renewing', 'ai-auto-tool') . ' - ' . esc_html__('Your subscription will not automatically renew. Premium features will remain active until the end of your billing period.', 'ai-auto-tool'); echo '

'; echo '
'; } else if ($plan_status['is_trial']) { echo '
'; echo '

'; echo ''; echo '' . esc_html__('Trial Period', 'ai-auto-tool') . ' - ' . esc_html__('You are currently in your trial period. Enjoy all premium features!', 'ai-auto-tool'); echo '

'; echo '
'; } echo '
'; echo '
'; } // Main Statistics Cards - Modern Design echo '
'; // Total Usage Card echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo ''; echo '
'; echo '

' . esc_html__('Total Usage', 'ai-auto-tool') . '

'; echo '
'; echo '
' . esc_html(number_format($dt['usage'])) . '
'; if ($plan_limit != -1) { echo '
'; echo '
'; echo '' . esc_html__('of', 'ai-auto-tool') . ' ' . esc_html(number_format($plan_limit)) . ' ' . esc_html__('requests', 'ai-auto-tool') . ''; echo '' . esc_html(number_format($usage_percentage, 1)) . '%'; echo '
'; echo '
'; $progress_color = $usage_percentage > 80 ? '#dc3545' : ($usage_percentage > 60 ? '#ffc107' : '#28a745'); echo '
'; echo '
'; echo '
'; } else { echo '
' . esc_html__('Unlimited', 'ai-auto-tool') . '
'; } echo '
'; echo '
'; // Remaining Quota Card if ($plan_limit != -1) { echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo ''; echo '
'; echo '

' . esc_html__('Remaining', 'ai-auto-tool') . '

'; echo '
'; echo '
' . esc_html(number_format($remaining)) . '
'; echo '
' . esc_html__('requests available', 'ai-auto-tool') . '
'; if ($remaining < ($plan_limit * 0.2) && $remaining > 0) { echo '
'; echo '' . esc_html__('Low quota remaining', 'ai-auto-tool'); echo '
'; } echo '
'; echo '
'; } // Monthly Reset Card echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo ''; echo '
'; echo '

' . esc_html__('Monthly Reset', 'ai-auto-tool') . '

'; echo '
'; echo '
' . esc_html($days_until_reset) . '
'; echo '
' . esc_html__('days until reset', 'ai-auto-tool') . '
'; echo '
'; echo '
' . esc_html__('Reset date', 'ai-auto-tool') . '
'; echo '
' . esc_html(date_i18n(get_option('date_format'), strtotime($expiration_date))) . '
'; echo '
'; echo '
'; echo '
'; // License Status Card (for premium) if (!$is_free) { $license = aiautotool_premium()->_get_license(); $license_status = $license ? 'active' : 'inactive'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo ''; echo '
'; echo '

' . esc_html__('License Status', 'ai-auto-tool') . '

'; echo '
'; echo '
'; if ($license_status == 'active') { echo ''; echo '' . esc_html__('Active', 'ai-auto-tool'); echo ''; } else { echo ''; echo '' . esc_html__('Inactive', 'ai-auto-tool'); echo ''; } echo '
'; if ($license && isset($license->secret_key)) { $license_key = $license->secret_key; $license_key_id = 'license-key-' . uniqid(); $license_key_escaped = esc_js($license_key); echo '
'; echo '
'; echo '
' . esc_html__('License Key', 'ai-auto-tool') . '
'; echo ''; echo '
'; echo '
'; echo '' . esc_html($license_key) . ''; echo '
'; echo '
'; echo ''; } echo '
'; echo '
'; } echo '
'; // Usage Breakdown Section - Modern Design echo '
'; echo '
'; echo '
'; echo ''; echo '
'; echo '

' . esc_html__('Usage Breakdown by Feature', 'ai-auto-tool') . '

'; echo '
'; echo '
'; // AI Post Usage echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo ''; echo '
'; echo '
' . esc_html__('AI Posts', 'ai-auto-tool') . '
' . esc_html($post_usage_pct) . '% ' . esc_html__('of total', 'ai-auto-tool') . '
'; echo '
'; echo '
' . esc_html(number_format($dt['AI_post_usage'])) . '
'; echo '
'; echo '
'; echo '
'; // Auto Comment Usage echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo ''; echo '
'; echo '
' . esc_html__('Auto Comments', 'ai-auto-tool') . '
' . esc_html($comment_usage_pct) . '% ' . esc_html__('of total', 'ai-auto-tool') . '
'; echo '
'; echo '
' . esc_html(number_format($dt['Commentauto_AI_usage'])) . '
'; echo '
'; echo '
'; echo '
'; // Auto Tag Usage echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo ''; echo '
'; echo '
' . esc_html__('Auto Tags', 'ai-auto-tool') . '
' . esc_html($tag_usage_pct) . '% ' . esc_html__('of total', 'ai-auto-tool') . '
'; echo '
'; echo '
' . esc_html(number_format($dt['Autocreatetag_AI_usage'])) . '
'; echo '
'; echo '
'; echo '
'; // Schedule Usage echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo ''; echo '
'; echo '
' . esc_html__('Scheduled Posts', 'ai-auto-tool') . '
' . esc_html($schedule_usage_pct) . '% ' . esc_html__('of total', 'ai-auto-tool') . '
'; echo '
'; echo '
' . esc_html(number_format($dt['Schedule_AI_usage'])) . '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; // Plan Information & Actions // Features Section echo '
'; echo '
'; echo '
'; echo ''; echo '
'; echo '

' . esc_html__('Active Features & Quotas', 'ai-auto-tool') . '

'; echo '
'; echo '
'; echo ''; self::render_plan(); echo '
'; echo '
'; // Additional Information echo '
'; echo '
'; echo '
'; echo ''; echo '
'; echo '

' . esc_html__('Information', 'ai-auto-tool') . '

'; echo '
'; echo '
    '; echo '
  • ' . esc_html__('Usage is reset monthly on the reset date shown above.', 'ai-auto-tool') . '
  • '; echo '
  • ' . esc_html__('All AI-powered features (Posts, Comments, Tags, Scheduled) count towards your quota.', 'ai-auto-tool') . '
  • '; if ($is_free) { echo '
  • ' . esc_html__('Free plan includes ' . AIAUTOTOOL_FREE . ' requests per month.', 'ai-auto-tool') . '
  • '; } else { echo '
  • ' . esc_html__('Premium plans include unlimited requests.', 'ai-auto-tool') . '
  • '; } echo '
  • ' . esc_html__('For questions or support, please contact our support team.', 'ai-auto-tool') . '
  • '; echo '
'; echo '
'; echo '
'; } /** * Render account information from Freemius get_site() * Displays install_id, site_id, plan_id, license_id, trial info, etc. */ public function render_account_info() { try { $fs = aiautotool_premium(); $is_registered = $fs->is_registered(); if (!$is_registered) { echo '
'; echo ''; echo '

' . esc_html__('Account Not Registered', 'ai-auto-tool') . '

'; echo '

' . esc_html__('Please register your account to view account information.', 'ai-auto-tool') . '

'; echo '
'; return; } $site = $fs->get_site(); $license = $fs->_get_license(); $plan_status = $this->get_plan_status(); echo '
'; // Header echo '
'; echo '

' . esc_html__('Account Information', 'ai-auto-tool') . '

'; echo '

' . esc_html__('Detailed account information from Freemius', 'ai-auto-tool') . '

'; echo '
'; // Site Information Card echo '
'; echo '

' . esc_html__('Site Information', 'ai-auto-tool') . '

'; if ($site) { $info_items = array( 'install_id' => array('label' => __('Install ID', 'ai-auto-tool'), 'value' => isset($site->id) ? $site->id : 'N/A', 'icon' => 'fa-hashtag', 'color' => '#667eea'), 'site_id' => array('label' => __('Site ID', 'ai-auto-tool'), 'value' => isset($site->site_id) ? $site->site_id : 'N/A', 'icon' => 'fa-globe', 'color' => '#28a745'), 'blog_id' => array('label' => __('Blog ID', 'ai-auto-tool'), 'value' => isset($site->blog_id) ? $site->blog_id : 'N/A', 'icon' => 'fa-blog', 'color' => '#17a2b8'), 'plugin_id' => array('label' => __('Plugin ID', 'ai-auto-tool'), 'value' => isset($site->plugin_id) ? $site->plugin_id : 'N/A', 'icon' => 'fa-puzzle-piece', 'color' => '#ff9800'), 'user_id' => array('label' => __('User ID', 'ai-auto-tool'), 'value' => isset($site->user_id) ? $site->user_id : 'N/A', 'icon' => 'fa-user', 'color' => '#9c27b0'), 'url' => array('label' => __('Site URL', 'ai-auto-tool'), 'value' => isset($site->url) ? esc_html($site->url) : 'N/A', 'icon' => 'fa-link', 'color' => '#2196f3'), 'title' => array('label' => __('Site Title', 'ai-auto-tool'), 'value' => isset($site->title) ? esc_html($site->title) : 'N/A', 'icon' => 'fa-heading', 'color' => '#607d8b'), 'version' => array('label' => __('Plugin Version', 'ai-auto-tool'), 'value' => isset($site->version) ? esc_html($site->version) : 'N/A', 'icon' => 'fa-code-branch', 'color' => '#795548'), 'language' => array('label' => __('Language', 'ai-auto-tool'), 'value' => isset($site->language) ? esc_html($site->language) : 'N/A', 'icon' => 'fa-language', 'color' => '#e91e63'), 'platform_version' => array('label' => __('WordPress Version', 'ai-auto-tool'), 'value' => isset($site->platform_version) ? esc_html($site->platform_version) : 'N/A', 'icon' => 'fa-wordpress', 'color' => '#00a0d2'), ); echo '
'; foreach ($info_items as $key => $item) { echo '
'; echo '
'; echo '
'; echo ''; echo '
'; echo '
'; echo '
' . esc_html($item['label']) . '
'; echo '
' . esc_html($item['value']) . '
'; echo '
'; echo '
'; echo '
'; } echo '
'; } else { echo '

' . esc_html__('Site information not available', 'ai-auto-tool') . '

'; } echo '
'; // Plan & License Information Card echo '
'; echo '

' . esc_html__('Plan & License Information', 'ai-auto-tool') . '

'; $plan_items = array(); if ($site) { if (isset($site->plan_id)) { $plan_items['plan_id'] = array('label' => __('Plan ID', 'ai-auto-tool'), 'value' => $site->plan_id, 'icon' => 'fa-tag', 'color' => '#667eea'); } if (isset($site->license_id)) { $plan_items['license_id'] = array('label' => __('License ID', 'ai-auto-tool'), 'value' => $site->license_id, 'icon' => 'fa-key', 'color' => '#28a745'); } if (isset($site->trial_plan_id)) { $plan_items['trial_plan_id'] = array('label' => __('Trial Plan ID', 'ai-auto-tool'), 'value' => $site->trial_plan_id, 'icon' => 'fa-clock', 'color' => '#17a2b8'); } if (isset($site->trial_ends)) { $trial_ends_date = date('Y-m-d H:i:s', strtotime($site->trial_ends)); $plan_items['trial_ends'] = array('label' => __('Trial Ends', 'ai-auto-tool'), 'value' => $trial_ends_date, 'icon' => 'fa-calendar-times', 'color' => '#ff9800'); } if (isset($site->is_premium)) { $plan_items['is_premium'] = array('label' => __('Is Premium', 'ai-auto-tool'), 'value' => $site->is_premium ? __('Yes', 'ai-auto-tool') : __('No', 'ai-auto-tool'), 'icon' => 'fa-star', 'color' => $site->is_premium ? '#ffc107' : '#6c757d'); } } // Add plan status info $plan_items['plan_title'] = array('label' => __('Current Plan', 'ai-auto-tool'), 'value' => isset($plan_status['plan_title']) ? $plan_status['plan_title'] : 'N/A', 'icon' => 'fa-crown', 'color' => '#ffc107'); $plan_items['status_label'] = array('label' => __('Status', 'ai-auto-tool'), 'value' => isset($plan_status['status_label']) ? $plan_status['status_label'] : 'N/A', 'icon' => 'fa-info-circle', 'color' => isset($plan_status['status_color']) ? $plan_status['status_color'] : '#6c757d'); if ($license && is_object($license)) { if (isset($license->id)) { $plan_items['license_object_id'] = array('label' => __('License Object ID', 'ai-auto-tool'), 'value' => $license->id, 'icon' => 'fa-id-card', 'color' => '#9c27b0'); } if (isset($license->expiration)) { $expiration_date = date('Y-m-d H:i:s', strtotime($license->expiration)); $plan_items['license_expiration'] = array('label' => __('License Expiration', 'ai-auto-tool'), 'value' => $expiration_date, 'icon' => 'fa-calendar-check', 'color' => '#f44336'); } } if (!empty($plan_items)) { echo '
'; foreach ($plan_items as $key => $item) { echo '
'; echo '
'; echo '
'; echo ''; echo '
'; echo '
'; echo '
' . esc_html($item['label']) . '
'; echo '
' . esc_html($item['value']) . '
'; echo '
'; echo '
'; echo '
'; } echo '
'; } else { echo '

' . esc_html__('Plan information not available', 'ai-auto-tool') . '

'; } echo '
'; // Secret Key Information (if available) if ($site && isset($site->secret_key) && !empty($site->secret_key)) { echo '
'; echo '

' . esc_html__('Security Information', 'ai-auto-tool') . '

'; echo '
'; echo '
' . esc_html__('Secret Key', 'ai-auto-tool') . '
'; echo '
' . esc_html($site->secret_key) . '
'; echo '

' . esc_html__('Keep this key secure and do not share it publicly.', 'ai-auto-tool') . '

'; echo '
'; echo '
'; } // Debug Information (if WP_DEBUG is enabled) if (defined('WP_DEBUG') && WP_DEBUG) { echo '
'; echo '

' . esc_html__('Debug Information', 'ai-auto-tool') . '

'; echo '
'; echo '
';
                    echo esc_html(print_r($site, true));
                    echo '
'; echo '
'; echo '
'; } echo '
'; } catch (Exception $e) { echo '
'; echo ''; echo '

' . esc_html__('Error Loading Account Information', 'ai-auto-tool') . '

'; echo '

' . esc_html($e->getMessage()) . '

'; echo '
'; if (defined('WP_DEBUG') && WP_DEBUG) { } } } public function create_post_route() { register_rest_route( 'aiautotool', '/createpost', array( 'methods' => 'POST', 'callback' => array($this,'aiautotool_insert_post_ajax'), 'permission_callback' => array($this, 'rest_api_permission_check') ) ); register_rest_route( 'aiautotool', '/get_cate', array( 'methods' => 'GET', 'callback' => array($this,'aiautotool_get_cate'), 'permission_callback' => array($this, 'rest_api_permission_check') )); register_rest_route( 'aiautotool', '/media', array( 'methods' => 'GET', 'callback' => array($this,'get_all_media_callback'), 'permission_callback' => array($this, 'rest_api_permission_check') )); } /** * REST API permission callback - check API key or user capability */ public function rest_api_permission_check($request) { // Check if API key is provided $api_key = $request->get_param('key') ?: $request->get_header('X-API-Key'); if (!empty($api_key)) { // Validate API key $api_key_list = get_option('aiautotool_api_key_list', array()); foreach ($api_key_list as $stored_key) { if ($api_key == $stored_key['key']) { return true; } } return false; } // Fallback: require user to be logged in with edit_posts capability return is_user_logged_in() && current_user_can('edit_posts'); } public function register_settings() { register_setting( 'ai_auto_tool_api_keys', 'ai_auto_tool_api_keys', array( 'type' => 'array', 'sanitize_callback' => array( $this, 'sanitize_array_setting' ), ) ); register_setting( 'ai_auto_tool_log', 'ai_auto_tool_log', array( 'type' => 'array', 'sanitize_callback' => array( $this, 'sanitize_array_setting' ), ) ); } /** * Sanitize array settings * * @param mixed $value Input value * @return array Sanitized array */ public function sanitize_array_setting( $value ) { if ( ! is_array( $value ) ) { return array(); } return map_deep( $value, 'sanitize_text_field' ); } public function aiautotool_insert_post_ajax() { // Check permissions for AJAX requests if (defined('DOING_AJAX') && DOING_AJAX) { check_ajax_referer('aiautotool_nonce', 'security'); if (!current_user_can('edit_posts')) { wp_send_json_error(array('message' => __('Permission denied', 'ai-auto-tool'))); } } else { // For REST API requests, check API key and permissions // The API key validation below will handle REST API permissions } // Lấy dữ liệu POST hoặc từ REST API request $request_data = $_POST; if (empty($request_data) && isset($_REQUEST)) { $request_data = $_REQUEST; } $name = isset($request_data['name']) ? sanitize_text_field($request_data['name']) : ''; $detail = isset($request_data['detail']) ? wp_kses_post($request_data['detail']) : ''; $category_name = isset($request_data['category']) ? sanitize_text_field($request_data['category']) : ''; $tags = isset($request_data['tags']) ? sanitize_text_field($request_data['tags']) : ''; $date = isset($request_data['date']) ? sanitize_text_field($request_data['date']) : ''; $key = isset($request_data['key']) ? sanitize_text_field($request_data['key']) : ''; // For REST API requests, validate API key first if (!defined('DOING_AJAX') || !DOING_AJAX) { if (empty($key)) { return new WP_Error('missing_api_key', __('API key is required', 'ai-auto-tool'), array('status' => 403)); } // Validate API key exists $api_key_list = get_option('aiautotool_api_key_list', array()); $valid_key = false; foreach ($api_key_list as $api_key) { if ($key == $api_key['key']) { $valid_key = true; break; } } if (!$valid_key) { return new WP_Error('invalid_api_key', __('Invalid API key', 'ai-auto-tool'), array('status' => 403)); } } $postname = AIAutoTool_Utilities::sanitize_title($name); $user_id = ''; $user_ids = get_users( array( 'fields' => 'ID', ) ); $random_user_id = $user_ids[array_rand($user_ids)]; $api_key_list = get_option('aiautotool_api_key_list', array()); if (count($api_key_list)>0) { foreach ($api_key_list as $k=>$api_key){ if ($key==$api_key['key']) { $user_id = $random_user_id;//rand(1, 11);//$api_key['user_id']; $config_img = get_option('aiautotool_config_img', false); if($config_img){ $aiautotool_images_list = get_option('aiautotool_images_list', []); $html = str_replace('\"', '"', $detail); $arrayImageUpload = preg_match_all('/]+src\s*=\s*["\']([^"\']+)["\']/i', stripslashes($html), $matches) ? $matches[1] : []; $attachThumbnail = 0; if (!empty($arrayImageUpload)){ foreach ($arrayImageUpload as $post_image_url){ $image_item = null; foreach ($aiautotool_images_list as $item) { if ($item['url_remote'] === $post_image_url) { $image_item = $item; break; } } if ($image_item !== null) { $image_url_new = $image_item['url_image_new']['url_out']; $detail = str_replace($post_image_url, $image_url_new, $detail); if ($attachThumbnail == 0) { $attachThumbnail = $image_item['url_image_new']['attach_id']; } }else{ try { $image_url_new = AIAutoTool_Utilities::save_image($post_image_url,$postname); if (!empty($image_url_new)){ $imgUploaded[] = $image_url_new; if ($attachThumbnail == 0) { $attachThumbnail = $image_url_new['attach_id']; } $aiautotool_images_list[] = [ 'url_remote' => $post_image_url, 'url_image_new' => $image_url_new, ]; update_option('aiautotool_images_list', $aiautotool_images_list,null, 'no'); } }catch (Exception $e) { } } } } foreach ($imgUploaded as $img){ $detail = str_replace($img['url'],$img['baseurl'],$detail); } } $category = get_category_by_slug($category_name); $category_id = $category->term_id; // Insert the post $post_id = wp_insert_post(array( 'post_title' => $name, 'post_content' => $detail, 'post_category' => array($category_id), 'tags_input' => $tags, 'post_status' => 'publish', 'post_author'=>$user_id, 'post_date' => $date, 'meta_input' => array( 'key' => $key, ), 'post_type' => 'post', )); // Return the URL of the new post if ($post_id) { if ($attachThumbnail != 0) { set_post_thumbnail($post_id, $attachThumbnail); } $post_url = get_permalink($post_id); echo json_encode(array('url' => $post_url)); } else { echo json_encode(array('error' => 'Failed to insert post.')); } } } } wp_die(); } public function aiautotool_get_cate() { header('Content-Type: application/json; charset=utf-8'); // Check permissions for AJAX requests if (defined('DOING_AJAX') && DOING_AJAX) { check_ajax_referer('aiautotool_nonce', 'security'); if (!current_user_can('edit_posts')) { wp_send_json_error(array('message' => __('Permission denied', 'ai-auto-tool'))); } } if ( isset( $_GET['key'] ) || isset( $_REQUEST['key'] ) ) { $key = isset($_GET['key']) ? sanitize_text_field($_GET['key']) : sanitize_text_field($_REQUEST['key']); $api_key_list = get_option('aiautotool_api_key_list', array()); if (count($api_key_list)>0) { foreach ($api_key_list as $k=>$api_key){ if ($key==$api_key['key']) { $categories = get_categories(); $categories_array = array(); foreach ( $categories as $category ) { $categories_array[] = array( 'id' => $category->cat_ID, 'name' => $category->name, 'slug' => $category->slug ); } echo json_encode( $categories_array ); die(); } } } } else { wp_send_json_error( ' key not in AJAX.' ); } die(); } public function get_all_media_callback() { // Check permissions for AJAX requests if (defined('DOING_AJAX') && DOING_AJAX) { check_ajax_referer('aiautotool_nonce', 'security'); if (!current_user_can('upload_files')) { wp_send_json_error(array('message' => __('Permission denied', 'ai-auto-tool'))); } } $key = isset($_GET['key']) ? sanitize_text_field($_GET['key']) : (isset($_REQUEST['key']) ? sanitize_text_field($_REQUEST['key']) : ''); $api_key_list = get_option('aiautotool_api_key_list', array()); if (count($api_key_list)>0) { foreach ($api_key_list as $k=>$api_key){ if ($key==$api_key['key']) { $args = array( 'post_type' => 'attachment', 'post_mime_type' => 'image', 'post_status' => 'inherit', 'posts_per_page' => - 1, ); $media_query = new WP_Query( $args ); $media = array(); if ( $media_query->have_posts() ) { while ( $media_query->have_posts() ) { $media_query->the_post(); $media[] = array( 'id' => get_the_ID(), 'title'=> get_the_title(), 'url' => wp_get_attachment_url(), 'type' => get_post_mime_type(), ); } wp_reset_postdata(); wp_send_json( $media ); die(); }else{ $arr = array('ok'=>'notfindimg'); wp_send_json( $arr ); die(); } } } } die(); } public function aiautotool_save_image(){ // Check permissions if (defined('DOING_AJAX') && DOING_AJAX) { check_ajax_referer('aiautotool_nonce', 'security'); if (!current_user_can('edit_posts')) { wp_send_json_error(array('message' => __('Permission denied', 'ai-auto-tool'))); } } $reponse = array(); if(!empty($_POST['link_img'])){ $link_img = sanitize_text_field($_POST['link_img']); $postId = sanitize_text_field($_POST['postId']); $postTitle = sanitize_text_field($_POST['postTitle']); $i = sanitize_text_field($_POST['i']); if(strpos( $link_img,$_SERVER['HTTP_HOST']) !== false){ //echo $link_img; $av = array( 'stt'=>'ok', 'linkedit'=>$link_img ); }else{ // $imagenew = upload_image($postTitle,$link_img,$postId,$i); $imagenews = AIAutoTool_Utilities::save_image($link_img,$postTitle); $imagenew = $imagenews['url_out']; $av = array( 'stt'=>'ok', 'linkedit'=>$imagenew ); } }else{ $av = array( 'stt'=>'notok', 'linkedit'=>'' ); } header( "Content-Type: application/json" ); echo json_encode($av); exit(); } /** * AJAX callback for bardcontentmore endpoint - avoids CORS issues */ public function aiautotool_bard_contentmore_callback() { // Verify nonce for AJAX requests if (defined('DOING_AJAX') && DOING_AJAX) { // Use wp_verify_nonce instead of check_ajax_referer to avoid 403 die if (!isset($_POST['security']) || !wp_verify_nonce($_POST['security'], 'aiautotool_nonce')) { wp_send_json(array( 'code' => '403', 'msg' => __('Security check failed. Please refresh the page and try again.', 'ai-auto-tool'), 'result' => '' )); wp_die(); } if (!current_user_can('edit_posts')) { wp_send_json(array( 'code' => '403', 'msg' => __('Permission denied', 'ai-auto-tool'), 'result' => '' )); wp_die(); } } // Get data from WordPress AJAX (can be in 'data' field or raw POST) $data = array(); // Try to get from 'data' field (sent as JSON string) if (isset($_POST['data']) && is_string($_POST['data'])) { $data = json_decode(stripslashes($_POST['data']), true); } else { // Try raw POST data $raw_data = file_get_contents('php://input'); $data = json_decode($raw_data, true); } if (!$data || !is_array($data)) { wp_send_json(array( 'code' => '400', 'msg' => 'Invalid JSON data', 'result' => '' )); wp_die(); } // Extract parameters $question = isset($data['question']) ? sanitize_textarea_field($data['question']) : ''; $lang = isset($data['lang']) ? sanitize_text_field($data['lang']) : 'Vietnamese'; $domain = isset($data['domain']) ? sanitize_text_field($data['domain']) : ''; $model = isset($data['model']) ? sanitize_text_field($data['model']) : 'gemini'; $info = isset($data['info']) ? $data['info'] : array(); if (empty($question)) { wp_send_json(array( 'code' => '400', 'msg' => 'Question parameter is required', 'result' => '' )); wp_die(); } // Use BardGenContent class to make server-side request require_once plugin_dir_path(__FILE__) . 'lib/bard.php'; $bardGenContent = new BardGenContent(); try { // Debug log request info if (defined('WP_DEBUG') && WP_DEBUG) { error_log('=== aiautotool_bard_contentmore_callback() DEBUG ==='); error_log('Question: ' . $question); error_log('Language: ' . $lang); error_log('Domain: ' . $domain); error_log('Model: ' . $model); } // Call the bardcontentmore method which handles the API call $result = $bardGenContent->bardcontentmore($question, $lang, $model); // Check if result is an array with error code (from API server) if (is_array($result) && isset($result['code']) && isset($result['msg'])) { // API returned error response (code 201-207, etc.) if (defined('WP_DEBUG') && WP_DEBUG) { error_log('API returned error code: ' . $result['code']); error_log('API error message: ' . $result['msg']); } wp_send_json(array( 'code' => $result['code'], 'msg' => $result['msg'], 'result' => isset($result['result']) ? $result['result'] : false )); wp_die(); } // Debug log result info if (defined('WP_DEBUG') && WP_DEBUG) { error_log('API Result Type: ' . gettype($result)); error_log('API Result Length: ' . (is_string($result) ? strlen($result) : 'N/A')); error_log('API Result Preview: ' . (is_string($result) ? substr($result, 0, 200) : json_encode($result))); } if ($result !== null && $result !== '' && $result !== false) { $response = array( 'code' => '200', 'msg' => 'Success', 'result' => $result ); // Add debug info if WP_DEBUG is enabled if (defined('WP_DEBUG') && WP_DEBUG) { $response['debug'] = array( 'question' => $question, 'lang' => $lang, 'result_length' => is_string($result) ? strlen($result) : 0, 'result_type' => gettype($result), 'timestamp' => current_time('mysql') ); } wp_send_json($response); } else { $error_response = array( 'code' => '500', 'msg' => 'Failed to generate content - API returned empty result', 'result' => '' ); if (defined('WP_DEBUG') && WP_DEBUG) { error_log('API returned empty/null result'); $error_response['debug'] = array( 'question' => $question, 'lang' => $lang, 'error' => 'Empty result from API' ); } wp_send_json($error_response); } } catch (Exception $e) { $error_msg = 'Error: ' . $e->getMessage(); if (defined('WP_DEBUG') && WP_DEBUG) { error_log('Exception in aiautotool_bard_contentmore_callback: ' . $e->getMessage()); error_log('Stack trace: ' . $e->getTraceAsString()); } $error_response = array( 'code' => '500', 'msg' => $error_msg, 'result' => '' ); if (defined('WP_DEBUG') && WP_DEBUG) { $error_response['debug'] = array( 'exception' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine() ); } wp_send_json($error_response); } wp_die(); } /** * AJAX callback for bardcontent endpoint - avoids CORS issues */ public function aiautotool_bard_content_callback() { // Verify nonce for AJAX requests if (defined('DOING_AJAX') && DOING_AJAX) { // Use wp_verify_nonce instead of check_ajax_referer to avoid 403 die if (!isset($_POST['security']) || !wp_verify_nonce($_POST['security'], 'aiautotool_nonce')) { wp_send_json(array( 'code' => '403', 'msg' => __('Security check failed. Please refresh the page and try again.', 'ai-auto-tool'), 'result' => '' )); wp_die(); } if (!current_user_can('edit_posts')) { wp_send_json(array( 'code' => '403', 'msg' => __('Permission denied', 'ai-auto-tool'), 'result' => '' )); wp_die(); } } // Get data from WordPress AJAX (can be in 'data' field or raw POST) $data = array(); // Try to get from 'data' field (sent as JSON string) if (isset($_POST['data']) && is_string($_POST['data'])) { $data = json_decode(stripslashes($_POST['data']), true); } else { // Try raw POST data $raw_data = file_get_contents('php://input'); $data = json_decode($raw_data, true); } if (!$data || !is_array($data)) { wp_send_json(array( 'code' => '400', 'msg' => 'Invalid JSON data', 'result' => '' )); wp_die(); } // Extract parameters $question = isset($data['question']) ? sanitize_textarea_field($data['question']) : ''; $lang = isset($data['lang']) ? sanitize_text_field($data['lang']) : 'Vietnamese'; $model = isset($data['model']) ? sanitize_text_field($data['model']) : 'gpt-4.1-nano-2025-04-14'; if (empty($question)) { wp_send_json(array( 'code' => '400', 'msg' => 'Question parameter is required', 'result' => '' )); wp_die(); } // Use BardGenContent class to make server-side request require_once plugin_dir_path(__FILE__) . 'lib/bard.php'; $bardGenContent = new BardGenContent(); try { // Debug log request info if (defined('WP_DEBUG') && WP_DEBUG) { error_log('=== aiautotool_bard_content_callback() DEBUG ==='); error_log('Question: ' . $question); error_log('Language: ' . $lang); error_log('Model: ' . $model); } // Call the bardcontent method $result = $bardGenContent->bardcontent($question, $lang, $model); // Check if result is an array with error code (from API server) if (is_array($result) && isset($result['code']) && isset($result['msg'])) { // API returned error response (code 201-207, etc.) if (defined('WP_DEBUG') && WP_DEBUG) { error_log('API returned error code: ' . $result['code']); error_log('API error message: ' . $result['msg']); } wp_send_json(array( 'code' => $result['code'], 'msg' => $result['msg'], 'result' => isset($result['result']) ? $result['result'] : false )); wp_die(); } // Debug log result info if (defined('WP_DEBUG') && WP_DEBUG) { error_log('API Result Type: ' . gettype($result)); error_log('API Result Length: ' . (is_string($result) ? strlen($result) : 'N/A')); error_log('API Result Preview: ' . (is_string($result) ? substr($result, 0, 200) : json_encode($result))); } if ($result !== null && $result !== '' && $result !== false) { $response = array( 'code' => '200', 'msg' => 'Success', 'result' => $result ); // Add debug info if WP_DEBUG is enabled if (defined('WP_DEBUG') && WP_DEBUG) { $response['debug'] = array( 'question' => $question, 'lang' => $lang, 'result_length' => is_string($result) ? strlen($result) : 0, 'result_type' => gettype($result), 'timestamp' => current_time('mysql') ); } wp_send_json($response); } else { $error_response = array( 'code' => '500', 'msg' => 'Failed to generate content - API returned empty result', 'result' => '' ); if (defined('WP_DEBUG') && WP_DEBUG) { error_log('API returned empty/null result'); $error_response['debug'] = array( 'question' => $question, 'lang' => $lang, 'error' => 'Empty result from API' ); } wp_send_json($error_response); } } catch (Exception $e) { $error_msg = 'Error: ' . $e->getMessage(); if (defined('WP_DEBUG') && WP_DEBUG) { error_log('Exception in aiautotool_bard_content_callback: ' . $e->getMessage()); error_log('Stack trace: ' . $e->getTraceAsString()); } $error_response = array( 'code' => '500', 'msg' => $error_msg, 'result' => '' ); if (defined('WP_DEBUG') && WP_DEBUG) { $error_response['debug'] = array( 'exception' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine() ); } wp_send_json($error_response); } wp_die(); } /** * AJAX callback for bardrewrite endpoint - avoids CORS issues */ public function aiautotool_bard_rewrite_callback() { // Verify nonce for AJAX requests if (defined('DOING_AJAX') && DOING_AJAX) { // Use wp_verify_nonce instead of check_ajax_referer to avoid 403 die if (!isset($_POST['security']) || !wp_verify_nonce($_POST['security'], 'aiautotool_nonce')) { wp_send_json(array( 'code' => '403', 'msg' => __('Security check failed. Please refresh the page and try again.', 'ai-auto-tool'), 'result' => '' )); wp_die(); } if (!current_user_can('edit_posts')) { wp_send_json(array( 'code' => '403', 'msg' => __('Permission denied', 'ai-auto-tool'), 'result' => '' )); wp_die(); } } // Get data from WordPress AJAX (can be in 'data' field or raw POST) $data = array(); // Try to get from 'data' field (sent as JSON string) if (isset($_POST['data']) && is_string($_POST['data'])) { $data = json_decode(stripslashes($_POST['data']), true); } else { // Try raw POST data $raw_data = file_get_contents('php://input'); $data = json_decode($raw_data, true); } if (!$data || !is_array($data)) { wp_send_json(array( 'code' => '400', 'msg' => 'Invalid JSON data', 'result' => '' )); wp_die(); } // Extract parameters $question = isset($data['question']) ? sanitize_textarea_field($data['question']) : ''; $lang = isset($data['lang']) ? sanitize_text_field($data['lang']) : 'Vietnamese'; $toneOfVoice = isset($data['toneOfVoice']) ? sanitize_text_field($data['toneOfVoice']) : ''; $model = isset($data['model']) ? sanitize_text_field($data['model']) : 'gpt-4.1-nano-2025-04-14'; if (empty($question)) { wp_send_json(array( 'code' => '400', 'msg' => 'Question parameter is required', 'result' => '' )); wp_die(); } // Use BardGenContent class to make server-side request require_once plugin_dir_path(__FILE__) . 'lib/bard.php'; $bardGenContent = new BardGenContent(); try { // Debug log request info if (defined('WP_DEBUG') && WP_DEBUG) { error_log('=== aiautotool_bard_rewrite_callback() DEBUG ==='); error_log('Question: ' . $question); error_log('Language: ' . $lang); error_log('Tone of Voice: ' . $toneOfVoice); error_log('Model: ' . $model); } // Call the bardrewrite method $result = $bardGenContent->bardrewrite($question, $lang, $toneOfVoice, $model); // Check if result is an array with error code (from API server) if (is_array($result) && isset($result['code']) && isset($result['msg'])) { // API returned error response (code 201-207, etc.) if (defined('WP_DEBUG') && WP_DEBUG) { error_log('API returned error code: ' . $result['code']); error_log('API error message: ' . $result['msg']); } wp_send_json(array( 'code' => $result['code'], 'msg' => $result['msg'], 'result' => isset($result['result']) ? $result['result'] : false )); wp_die(); } // Debug log result info if (defined('WP_DEBUG') && WP_DEBUG) { error_log('API Result Type: ' . gettype($result)); error_log('API Result Length: ' . (is_string($result) ? strlen($result) : 'N/A')); error_log('API Result Preview: ' . (is_string($result) ? substr($result, 0, 200) : json_encode($result))); } if ($result !== null && $result !== '' && $result !== false) { $response = array( 'code' => '200', 'msg' => 'Success', 'result' => $result ); // Add debug info if WP_DEBUG is enabled if (defined('WP_DEBUG') && WP_DEBUG) { $response['debug'] = array( 'question' => $question, 'lang' => $lang, 'toneOfVoice' => $toneOfVoice, 'result_length' => is_string($result) ? strlen($result) : 0, 'result_type' => gettype($result), 'timestamp' => current_time('mysql') ); } wp_send_json($response); } else { $error_response = array( 'code' => '500', 'msg' => 'Failed to rewrite content - API returned empty result', 'result' => '' ); if (defined('WP_DEBUG') && WP_DEBUG) { error_log('API returned empty/null result'); $error_response['debug'] = array( 'question' => $question, 'lang' => $lang, 'toneOfVoice' => $toneOfVoice, 'error' => 'Empty result from API' ); } wp_send_json($error_response); } } catch (Exception $e) { $error_msg = 'Error: ' . $e->getMessage(); if (defined('WP_DEBUG') && WP_DEBUG) { error_log('Exception in aiautotool_bard_rewrite_callback: ' . $e->getMessage()); error_log('Stack trace: ' . $e->getTraceAsString()); } $error_response = array( 'code' => '500', 'msg' => $error_msg, 'result' => '' ); if (defined('WP_DEBUG') && WP_DEBUG) { $error_response['debug'] = array( 'exception' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine() ); } wp_send_json($error_response); } wp_die(); } } new AI_Auto_Tool(); function aiautotool_load_func() { $inc_directory = plugin_dir_path(__FILE__) . 'func'; $inc_files = glob($inc_directory . '/*.php'); // print_r($inc_files); if ($inc_files) { foreach ($inc_files as $file) { if (is_file($file)) { include $file; } } } } aiautotool_load_func(); } add_filter('auto_update_plugin_ai-auto-tool', '__return_true');