'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 '
';
}
// Render Disabled Features Section
if (!empty($disabled_features)) {
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('');
}
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_config_settings['code3'])){echo esc_textarea(stripslashes($this->aiautotool_config_settings['code3']));} ?>
render_account_info(); ?>
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 '
';
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 '
' . esc_html__('Copy', 'ai-auto-tool') . ' ';
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');