load_dependencies(); $this->init_hooks(); } /** * Load required files */ private function load_dependencies() { require_once AICP_BRIDGE_PLUGIN_DIR . 'includes/class-aicp-api.php'; require_once AICP_BRIDGE_PLUGIN_DIR . 'includes/class-aicp-settings.php'; require_once AICP_BRIDGE_PLUGIN_DIR . 'includes/class-aicp-validator.php'; require_once AICP_BRIDGE_PLUGIN_DIR . 'includes/class-aicp-wizard.php'; require_once AICP_BRIDGE_PLUGIN_DIR . 'includes/class-aicp-statistics.php'; require_once AICP_BRIDGE_PLUGIN_DIR . 'includes/class-aicp-rest-api.php'; if (is_admin()) { require_once AICP_BRIDGE_PLUGIN_DIR . 'admin/class-aicp-admin.php'; } // WooCommerce integration is loaded in init() on plugins_loaded hook // to ensure WooCommerce is available regardless of plugin load order } /** * Initialize hooks */ private function init_hooks() { // Plugin activation/deactivation register_activation_hook(AICP_BRIDGE_PLUGIN_FILE, array($this, 'activate')); register_deactivation_hook(AICP_BRIDGE_PLUGIN_FILE, array($this, 'deactivate')); // Initialize components after plugins loaded add_action('plugins_loaded', array($this, 'init')); // Load translations add_action('init', array($this, 'load_textdomain')); } /** * Initialize plugin components */ public function init() { // Ensure admin capability exists (for existing installs) $this->ensure_admin_capability(); $this->settings = AICP_Settings::get_instance(); $this->api = new AICP_API($this->settings); $this->wizard = new AICP_Wizard($this->api, $this->settings); $this->statistics = new AICP_Statistics($this->api); // Register REST API endpoints for SaaS-to-WordPress communication $this->rest_api = new AICP_REST_API(); $this->rest_api->init(); // Override "Uploaded by" display for media uploaded by AICP add_filter('the_author', array($this, 'filter_aicp_attachment_author')); add_filter('wp_prepare_attachment_for_js', array($this, 'filter_aicp_attachment_for_js'), 10, 2); if (is_admin()) { $this->admin = new AICP_Admin($this->api, $this->settings, $this->wizard, $this->statistics); } if ($this->is_woocommerce_active()) { require_once AICP_BRIDGE_PLUGIN_DIR . 'includes/class-aicp-woocommerce.php'; $this->woocommerce = new AICP_WooCommerce($this->api, $this->settings); } } /** * Filter the author display name for attachments uploaded by AICP. * This makes the Media Library "Uploaded by" column show "aicontentplan.com". */ public function filter_aicp_attachment_author($author) { global $post; if ($post && $post->post_type === 'attachment') { $uploaded_by = get_post_meta($post->ID, '_aicp_uploaded_by', true); if (!empty($uploaded_by)) { return $uploaded_by; } } return $author; } /** * Filter attachment data for the media grid view (modal/grid uses JS). * Sets authorName so the grid view also shows "aicontentplan.com". */ public function filter_aicp_attachment_for_js($response, $attachment) { $uploaded_by = get_post_meta($attachment->ID, '_aicp_uploaded_by', true); if (!empty($uploaded_by)) { $response['authorName'] = $uploaded_by; } return $response; } /** * Ensure admin capability exists */ private function ensure_admin_capability() { $aicp_admin = get_role('administrator'); if ($aicp_admin && !$aicp_admin->has_cap('manage_aicp_settings')) { $aicp_admin->add_cap('manage_aicp_settings'); } } /** * Plugin activation */ public function activate() { // Set default options $aicp_defaults = array( 'aicp_api_key' => '', 'aicp_api_secret' => '', 'aicp_connection_status' => 'disconnected', 'aicp_organization_name' => '', 'aicp_subscription_tier' => '', 'aicp_publishing_defaults' => wp_json_encode(array( 'post_status' => 'draft', 'category' => 0, 'author' => 0 )), 'aicp_woocommerce_enabled' => false, 'aicp_woocommerce_categories' => array(), 'aicp_setup_complete' => false ); foreach ($aicp_defaults as $aicp_key => $aicp_value) { if (get_option($aicp_key) === false) { add_option($aicp_key, $aicp_value); } } // Create capability for managing AICP settings $aicp_admin = get_role('administrator'); if ($aicp_admin) { $aicp_admin->add_cap('manage_aicp_settings'); } // Flush rewrite rules flush_rewrite_rules(); } /** * Plugin deactivation */ public function deactivate() { // Clean up transients delete_transient('aicp_connection_info'); delete_transient('aicp_statistics'); // Flush rewrite rules flush_rewrite_rules(); } /** * Load plugin text domain. * * Since WordPress 4.6, translations are automatically loaded from * wp-content/languages/plugins/aicp-{locale}.mo. This method provides * fallback support for bundled translations in the plugin's languages directory. */ public function load_textdomain() { // phpcs:ignore PluginCheck.CodeAnalysis.DiscouragedFunctions.load_plugin_textdomainFound -- Fallback for bundled translations load_plugin_textdomain( 'aicp', false, dirname(AICP_BRIDGE_PLUGIN_BASENAME) . '/languages/' ); } /** * Check if WooCommerce is active * * @return bool */ public function is_woocommerce_active() { return class_exists('WooCommerce'); } /** * Get API URL * * @return string */ public function get_api_url() { // Allow override via settings $aicp_custom_url = $this->settings ? $this->settings->get_api_url() : ''; $aicp_api_url = !empty($aicp_custom_url) ? $aicp_custom_url : AICP_API_URL; return apply_filters('aicp_api_url', $aicp_api_url); } } /** * Get main plugin instance * * @return AICP_Bridge */ function aicp_bridge() { return AICP_Bridge::get_instance(); } // Initialize the plugin aicp_bridge();