PluginProbe
The Innovative Form Builder – IvyForms / 1.5
The Innovative Form Builder – IvyForms v1.5
1.5.1 1.5 1.4.1 1.4 trunk 0.1.2 0.2 0.2.1 0.3 0.3.1 0.4 0.5 0.6 0.6.1 0.6.1-backup 0.6.1.1 0.7 0.8 0.8.1 0.8.2 0.9 0.9.1 1.0 1.1 1.1.1 All 27 releases
← All changes | backend/src/Plugin/AdminHooks.php +56 -17 0.6 → 1.5 View file →
@@ -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,38 +55,81 @@
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 - IVYFORMS_URL . 'frontend/src/assets/js/admin/admin-deactivation-modal.js',
87 + IVYFORMS_URL . 'frontend/assets/js/admin-deactivation-modal.js',
76 88 [],
77 89 IVYFORMS_VERSION,
78 90 true
79 91 );
80 -
81 - // Localize script data for deactivation modal
82 92 wp_localize_script(
83 93 'ivyforms-deactivation-modal',
84 94 'ivyformsData',
85 95 [
86 - 'version' => IVYFORMS_VERSION,
96 + 'version' => IVYFORMS_VERSION,
97 + 'pluginUrl' => IVYFORMS_URL,
87 98 'restApiUrl' => rest_url('ivyforms/v1/deactivation-feedback'),
88 - 'restNonce' => wp_create_nonce('wp_rest'),
99 + 'restNonce' => wp_create_nonce('wp_rest'),
89 100 ]
90 101 );
91 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 + }
92 132 }
93 133
94 134 /**
95 135 * Check a plugin version and handle activation/deactivation if needed
@@ -98,9 +138,8 @@
98 138 */
99 139 private function checkVersionAndHandleActivation(): void
100 140 {
101 141 if (!function_exists('activate_plugin')) {
102 - // @phpstan-ignore requireOnce.fileNotFound
103 142 require_once ABSPATH . 'wp-admin/includes/plugin.php';
104 143 }
105 144
106 145 $settingsService = new SettingsService();
@@ -108,10 +147,10 @@
108 147 $currentVersion = IVYFORMS_VERSION;
109 148 $savedVersion = $settingsService->getSetting('general', 'version');
110 149
111 150 if ($savedVersion !== $currentVersion) {
112 - deactivate_plugins(IVYFORMS_PLUGIN_SLUG); // @phpstan-ignore argument.type
113 - activate_plugin(IVYFORMS_PLUGIN_SLUG); // @phpstan-ignore argument.type
151 + deactivate_plugins(IVYFORMS_PLUGIN_SLUG);
152 + activate_plugin(IVYFORMS_PLUGIN_SLUG);
114 153
115 154 $settingsService->setSetting('general', 'version', $currentVersion);
116 155 }
117 156 }
@@ -132,9 +171,9 @@
132 171 remove_all_actions('user_admin_notices');
133 172 remove_all_actions('network_admin_notices');
134 173 wp_register_style(
135 174 'ivyforms_admin_global',
136 - IVYFORMS_URL . 'frontend/css/global-admin.css',
175 + IVYFORMS_URL . 'frontend/assets/css/global-admin.css',
137 176 array(),
138 177 IVYFORMS_VERSION
139 178 );
140 179 wp_enqueue_style('ivyforms_admin_global');