| @@ -8,13 +8,10 @@ | ||
| 8 | 8 | */ |
| 9 | 9 | |
| 10 | 10 | namespace IvyForms\Plugin; |
| 11 | 11 | |
| 12 | -// phpcs:disable PSR1.Files.SideEffects | |
| 13 | -if (!defined('ABSPATH')) { | |
| 14 | - exit; // Exit if accessed directly | |
| 15 | -} | |
| 16 | - | |
| 12 | +use IvyForms\Infrastructure\WP\MCP\McpFeatureGate; | |
| 13 | +use IvyForms\Services\Ai\AiAvailability; | |
| 17 | 14 | use IvyForms\Services\Settings\SettingsService; |
| 18 | 15 | |
| 19 | 16 | /** |
| 20 | 17 | * AdminHooks |
| @@ -46,9 +43,9 @@ | ||
| 46 | 43 | public function register(): void |
| 47 | 44 | { |
| 48 | 45 | add_action('admin_init', [$this, 'adminInit']); |
| 49 | 46 | add_filter('admin_body_class', [$this, 'addAdminBodyClass']); |
| 50 | - add_action('admin_enqueue_scripts', [$this, 'enqueueDeactivationModal']); | |
| 47 | + add_action('admin_enqueue_scripts', [$this, 'adminScripts']); | |
| 51 | 48 | } |
| 52 | 49 | |
| 53 | 50 | /** |
| 54 | 51 | * Handle admin initialization tasks |
| @@ -58,18 +55,33 @@ | ||
| 58 | 55 | public function adminInit(): void |
| 59 | 56 | { |
| 60 | 57 | $this->checkVersionAndHandleActivation(); |
| 61 | 58 | $this->removeAdminNotices(); |
| 59 | + $this->maybeWarmAiAvailabilityCache(); | |
| 62 | 60 | } |
| 63 | 61 | |
| 64 | 62 | /** |
| 65 | - * Enqueue deactivation modal script on plugins page | |
| 63 | + * Warm AI capability cache outside MenuService::render() so admin UI never | |
| 64 | + * triggers provider probes while localizing scripts. | |
| 65 | + */ | |
| 66 | + private function maybeWarmAiAvailabilityCache(): void | |
| 67 | + { | |
| 68 | + if (!$this->isIvyFormsAdminPage()) { | |
| 69 | + return; | |
| 70 | + } | |
| 71 | + | |
| 72 | + AiAvailability::maybeRefreshTextGenerationSupport(); | |
| 73 | + } | |
| 74 | + | |
| 75 | + /** | |
| 76 | + * Enqueue admin scripts (deactivation modal and Angie MCP server for Elementor AI integration) | |
| 66 | 77 | * |
| 67 | 78 | * @param string $hook Current admin page hook |
| 68 | 79 | * @return void |
| 69 | 80 | */ |
| 70 | - public function enqueueDeactivationModal(string $hook): void | |
| 81 | + public function adminScripts(string $hook): void | |
| 71 | 82 | { |
| 83 | + // Deactivation modal on plugins page | |
| 72 | 84 | if ($hook === 'plugins.php') { |
| 73 | 85 | wp_enqueue_script( |
| 74 | 86 | 'ivyforms-deactivation-modal', |
| 75 | 87 | IVYFORMS_URL . 'frontend/assets/js/admin-deactivation-modal.js', |
| @@ -76,12 +88,8 @@ | ||
| 76 | 88 | [], |
| 77 | 89 | IVYFORMS_VERSION, |
| 78 | 90 | true |
| 79 | 91 | ); |
| 80 | - | |
| 81 | - $settingsService = new SettingsService(); | |
| 82 | - $deleteOnUninstall = $settingsService->getSetting('general', 'delete_on_uninstall'); | |
| 83 | - | |
| 84 | 92 | wp_localize_script( |
| 85 | 93 | 'ivyforms-deactivation-modal', |
| 86 | 94 | 'ivyformsData', |
| 87 | 95 | [ |
| @@ -88,21 +96,40 @@ | ||
| 88 | 96 | 'version' => IVYFORMS_VERSION, |
| 89 | 97 | 'pluginUrl' => IVYFORMS_URL, |
| 90 | 98 | 'restApiUrl' => rest_url('ivyforms/v1/deactivation-feedback'), |
| 91 | 99 | 'restNonce' => wp_create_nonce('wp_rest'), |
| 92 | - 'deleteOnUninstall' => $deleteOnUninstall, | |
| 93 | - 'i18n' => [ | |
| 94 | - 'warningTitle' => __('Warning', 'ivyforms'), | |
| 95 | - 'warningMessage' => __( | |
| 96 | - 'All IvyForms database tables and settings will be deleted when ' | |
| 97 | - . 'this plugin is deactivated. To prevent this,', | |
| 98 | - 'ivyforms' | |
| 99 | - ), | |
| 100 | - 'warningLinkText' => __('disable this option in settings', 'ivyforms'), | |
| 101 | - ] | |
| 102 | 100 | ] |
| 103 | 101 | ); |
| 104 | 102 | } |
| 103 | + | |
| 104 | + // Angie MCP client — proxy JS talks to the PHP MCP REST route. | |
| 105 | + // Only load when Angie is active and IvyForms MCP itself is enabled. | |
| 106 | + if ( | |
| 107 | + function_exists('is_plugin_active') | |
| 108 | + && is_plugin_active('angie/angie.php') | |
| 109 | + && McpFeatureGate::isEnabled() | |
| 110 | + ) { | |
| 111 | + $wpVersion = get_bloginfo('version'); | |
| 112 | + if (version_compare($wpVersion, '6.5', '<')) { | |
| 113 | + return; | |
| 114 | + } | |
| 115 | + $mcpServerPath = IVYFORMS_PATH . '/frontend/dist/ivyforms-angie.js'; | |
| 116 | + if (!file_exists($mcpServerPath)) { | |
| 117 | + return; | |
| 118 | + } | |
| 119 | + | |
| 120 | + // Script modules cannot use wp_localize_script(); ensure core wpApiSettings | |
| 121 | + // (root + nonce) exists on every admin page where Angie loads this module. | |
| 122 | + wp_enqueue_script('wp-api-request'); | |
| 123 | + | |
| 124 | + // @phpstan-ignore-next-line | |
| 125 | + wp_enqueue_script_module( | |
| 126 | + 'ivyforms-angie-mcp', | |
| 127 | + IVYFORMS_URL . 'frontend/dist/ivyforms-angie.js', | |
| 128 | + array(), | |
| 129 | + IVYFORMS_VERSION | |
| 130 | + ); | |
| 131 | + } | |
| 105 | 132 | } |
| 106 | 133 | |
| 107 | 134 | /** |
| 108 | 135 | * Check a plugin version and handle activation/deactivation if needed |
| @@ -120,10 +147,10 @@ | ||
| 120 | 147 | $currentVersion = IVYFORMS_VERSION; |
| 121 | 148 | $savedVersion = $settingsService->getSetting('general', 'version'); |
| 122 | 149 | |
| 123 | 150 | if ($savedVersion !== $currentVersion) { |
| 124 | - deactivate_plugins(IVYFORMS_PLUGIN_SLUG); // @phpstan-ignore argument.type | |
| 125 | - activate_plugin(IVYFORMS_PLUGIN_SLUG); // @phpstan-ignore argument.type | |
| 151 | + deactivate_plugins(IVYFORMS_PLUGIN_SLUG); | |
| 152 | + activate_plugin(IVYFORMS_PLUGIN_SLUG); | |
| 126 | 153 | |
| 127 | 154 | $settingsService->setSetting('general', 'version', $currentVersion); |
| 128 | 155 | } |
| 129 | 156 | } |