PluginProbe
The Innovative Form Builder – IvyForms / 1.5.1
The Innovative Form Builder – IvyForms v1.5.1
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 +217 -0 0.6.1 → 1.5.1 View file →
@@ -1,0 +1,217 @@
1 +<?php
2 +
3 +/**
4 + * Admin Hooks Handler
5 + *
6 + * @package IvyForms
7 + * @since 0.5.0
8 + */
9 +
10 +namespace IvyForms\Plugin;
11 +
12 +use IvyForms\Infrastructure\WP\MCP\McpFeatureGate;
13 +use IvyForms\Services\Ai\AiAvailability;
14 +use IvyForms\Services\Settings\SettingsService;
15 +
16 +/**
17 + * AdminHooks
18 + *
19 + * Handles all admin-related hooks and functionality
20 + */
21 +class AdminHooks
22 +{
23 + /**
24 + * Settings Service
25 + */
26 + private ?SettingsService $settingsService = null;
27 +
28 + /**
29 + * Constructor
30 + *
31 + * @param SettingsService|null $settingsService
32 + */
33 + public function __construct(?SettingsService $settingsService = null)
34 + {
35 + $this->settingsService = $settingsService;
36 + }
37 +
38 + /**
39 + * Register admin hooks
40 + *
41 + * @return void
42 + */
43 + public function register(): void
44 + {
45 + add_action('admin_init', [$this, 'adminInit']);
46 + add_filter('admin_body_class', [$this, 'addAdminBodyClass']);
47 + add_action('admin_enqueue_scripts', [$this, 'adminScripts']);
48 + }
49 +
50 + /**
51 + * Handle admin initialization tasks
52 + *
53 + * @return void
54 + */
55 + public function adminInit(): void
56 + {
57 + $this->checkVersionAndHandleActivation();
58 + $this->removeAdminNotices();
59 + $this->maybeWarmAiAvailabilityCache();
60 + }
61 +
62 + /**
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)
77 + *
78 + * @param string $hook Current admin page hook
79 + * @return void
80 + */
81 + public function adminScripts(string $hook): void
82 + {
83 + // Deactivation modal on plugins page
84 + if ($hook === 'plugins.php') {
85 + wp_enqueue_script(
86 + 'ivyforms-deactivation-modal',
87 + IVYFORMS_URL . 'frontend/assets/js/admin-deactivation-modal.js',
88 + [],
89 + IVYFORMS_VERSION,
90 + true
91 + );
92 + wp_localize_script(
93 + 'ivyforms-deactivation-modal',
94 + 'ivyformsData',
95 + [
96 + 'version' => IVYFORMS_VERSION,
97 + 'pluginUrl' => IVYFORMS_URL,
98 + 'restApiUrl' => rest_url('ivyforms/v1/deactivation-feedback'),
99 + 'restNonce' => wp_create_nonce('wp_rest'),
100 + ]
101 + );
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 + }
132 + }
133 +
134 + /**
135 + * Check a plugin version and handle activation/deactivation if needed
136 + *
137 + * @return void
138 + */
139 + private function checkVersionAndHandleActivation(): void
140 + {
141 + if (!function_exists('activate_plugin')) {
142 + require_once ABSPATH . 'wp-admin/includes/plugin.php';
143 + }
144 +
145 + $settingsService = new SettingsService();
146 +
147 + $currentVersion = IVYFORMS_VERSION;
148 + $savedVersion = $settingsService->getSetting('general', 'version');
149 +
150 + if ($savedVersion !== $currentVersion) {
151 + deactivate_plugins(IVYFORMS_PLUGIN_SLUG);
152 + activate_plugin(IVYFORMS_PLUGIN_SLUG);
153 +
154 + $settingsService->setSetting('general', 'version', $currentVersion);
155 + }
156 + }
157 +
158 + /**
159 + * Remove admin notices on IvyForms admin pages
160 + *
161 + * @return void
162 + */
163 + public function removeAdminNotices(): void
164 + {
165 + // Check if we're on an IvyForms admin page
166 + if ($this->isIvyFormsAdminPage()) {
167 + // Remove all admin notices
168 + remove_all_actions('admin_notices');
169 + remove_all_actions('all_admin_notices');
170 + // For plugins using user_admin_notices or network_admin_notices
171 + remove_all_actions('user_admin_notices');
172 + remove_all_actions('network_admin_notices');
173 + wp_register_style(
174 + 'ivyforms_admin_global',
175 + IVYFORMS_URL . 'frontend/assets/css/global-admin.css',
176 + array(),
177 + IVYFORMS_VERSION
178 + );
179 + wp_enqueue_style('ivyforms_admin_global');
180 + }
181 + }
182 +
183 + /**
184 + * Check if current page is an IvyForms admin page
185 + *
186 + * @SuppressWarnings(PHPMD)
187 + *
188 + * @return bool
189 + */
190 + private function isIvyFormsAdminPage(): bool
191 + {
192 + if (!is_admin()) {
193 + return false;
194 + }
195 + // Adjust this based on your page's actual slug/identifier
196 + return (isset($_GET['page']) && strpos($_GET['page'], 'ivyforms') !== false);
197 + }
198 +
199 + /**
200 + * Add admin body class
201 + *
202 + * @param string $classes
203 + * @return string
204 + */
205 + public function addAdminBodyClass(string $classes): string
206 + {
207 + if ($this->settingsService === null) {
208 + return $classes;
209 + }
210 +
211 + if ($this->settingsService->getSetting('general', 'fullscreen')) {
212 + $classes .= ' ivyforms-fullscreen-mode ';
213 + }
214 +
215 + return $classes;
216 + }
217 +}