up(); } catch (Exception $e) { contai_log("ContaiCreateKeywordsTable migration error: " . $e->getMessage()); } try { $api_logs_migration = new ContaiCreateAPILogsTable(); $api_logs_migration->up(); } catch (Exception $e) { contai_log("ContaiCreateAPILogsTable migration error: " . $e->getMessage()); } try { $jobs_migration = new ContaiCreateJobsTable(); $jobs_migration->up(); } catch (Exception $e) { contai_log("ContaiCreateJobsTable migration error: " . $e->getMessage()); } try { $update_keywords_status = new ContaiUpdateKeywordsTableStatus(); $update_keywords_status->up(); } catch (Exception $e) { contai_log("ContaiUpdateKeywordsTableStatus migration error: " . $e->getMessage()); } try { $internal_links_migration = new ContaiCreateInternalLinksTable(); $internal_links_migration->up(); } catch (Exception $e) { contai_log("ContaiCreateInternalLinksTable migration error: " . $e->getMessage()); } try { contai_register_job_processor_cron(); } catch (Exception $e) { contai_log("Cron registration error: " . $e->getMessage()); } try { contai_register_agent_actions_cron(); } catch (Exception $e) { contai_log("Agent cron registration error: " . $e->getMessage()); } // Set site hardening defaults for existing installs (opt-in for new installs) add_option('contai_disable_feeds', '1'); add_option('contai_disable_author_pages', '1'); add_option('contai_redirect_404', '1'); } register_activation_hook(__FILE__, 'contai_activate_plugin'); register_deactivation_hook(__FILE__, 'contai_unregister_job_processor_cron'); register_deactivation_hook( __FILE__, 'contai_unregister_agent_actions_cron' ); $toc_integration = ContaiTocFactory::create(); $toc_integration->register(); add_action('plugins_loaded', function() { $internal_links_integration = new ContaiInternalLinksWordPressIntegration(); $internal_links_integration->register(); }); /** * Check if the license key option exists and is valid * * @return bool True if license key is present and non-empty, false otherwise */ function contai_has_license_key() { $license_key = get_option('contai_api_key', ''); if (empty($license_key)) { return false; } if (is_string($license_key)) { $trimmed = trim($license_key); return !empty($trimmed); } return false; } /** * Register all admin menus unconditionally. * * All menus are always accessible regardless of API key status. * When the API key is not configured, SaaS-dependent pages display * a connection CTA instead of blocking access. * Local features (TOC, Internal Links) work without any API key. * This satisfies WordPress.org Guideline 5 (no trialware hard-gating). */ function contai_register_admin_menus() { add_menu_page( '1Platform Content AI', '1Platform Content AI', 'manage_options', 'contai-website-settings', 'contai_website_settings_page', 'dashicons-admin-comments', 90 ); add_submenu_page( 'contai-website-settings', 'Settings', 'Settings', 'manage_options', 'contai-website-settings', 'contai_website_settings_page' ); add_submenu_page( 'contai-website-settings', 'Content', 'Content', 'manage_options', 'contai-content-generator', 'contai_content_generator_page' ); add_submenu_page( 'contai-website-settings', 'Tools', 'Tools', 'manage_options', 'contai-apps', 'contai_apps_page' ); add_submenu_page( 'contai-website-settings', 'Site Wizard', 'Site Wizard', 'manage_options', 'contai-ai-site-generator', 'contai_ai_site_generator_page' ); add_submenu_page( 'contai-website-settings', 'Jobs', 'Jobs', 'manage_options', 'contai-job-monitor', 'contai_render_job_monitor_page' ); add_submenu_page( 'contai-website-settings', 'Billing', 'Billing', 'manage_options', 'contai-billing', 'contai_billing_page' ); add_submenu_page( 'contai-website-settings', 'Logs', 'Logs', 'manage_options', 'contai-logs', 'contai_logs_page' ); add_submenu_page( 'contai-website-settings', 'Agents', 'Agents', 'manage_options', 'contai-agents', 'contai_agents_page' ); add_submenu_page( 'contai-website-settings', 'License', 'License', 'manage_options', 'contai-licenses', 'contai_licenses_page' ); } add_action( 'admin_menu', 'contai_register_admin_menus' ); add_action( 'rest_api_init', function() { $controller = new ContaiAgentRestController(); $controller->register_routes(); } ); /** * Render the Agents admin page. */ function contai_agents_page() { ContaiAgentsAdminPage::render(); } add_action( 'admin_enqueue_scripts', function( $hook ) { if ( strpos( $hook, 'contai-agents' ) === false ) { return; } wp_enqueue_style( 'contai-agents-admin', plugin_dir_url( __FILE__ ) . 'includes/admin/agents/contai-agents-admin.css', array(), '2.3.6' ); wp_enqueue_script( 'contai-agents-admin', plugin_dir_url( __FILE__ ) . 'includes/admin/agents/contai-agents-admin.js', array(), '2.3.6', true ); wp_localize_script( 'contai-agents-admin', 'contaiAgents', array( 'restUrl' => rest_url( 'contai/v1/' ), 'nonce' => wp_create_nonce( 'wp_rest' ), 'settings' => ContaiAgentSettingsService::getAllSettings(), 'adminUrl' => admin_url( 'admin.php?page=contai-agents' ), ) ); } ); /** * Render a connection-required notice when the API key is not configured. * * SaaS-dependent pages call this function to display a CTA instead of * blocking access with redirects. Returns true if notice was rendered * (caller should skip page content). * * @return bool True if the notice was rendered. */ function contai_render_connection_required_notice() { if ( contai_has_license_key() ) { return false; } $license_url = admin_url( 'admin.php?page=contai-licenses' ); ?>
render(); } /** * Sync buffered client logs to the API on shutdown. */ add_action('shutdown', function() { if (is_admin() && ContaiClientLogReporter::getBufferCount() > 0) { ContaiClientLogReporter::syncBuffer(); } }); /** * Display admin notices for authentication token errors on plugin pages. */ function contai_display_auth_error_notices(): void { if (!current_user_can('manage_options')) { return; } $screen = get_current_screen(); if (!$screen || strpos($screen->id, 'contai') === false) { return; } require_once plugin_dir_path(__FILE__) . 'includes/services/api/OnePlatformAuthService.php'; $app_error = ContaiOnePlatformAuthService::getAppTokenError(); if ($app_error !== null) { printf( '%s %s
%s %s %s