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/Plugin.php +117 -144 0.5 → 1.5 View file →
@@ -8,30 +8,27 @@
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 -
17 -use IvyForms\Vendor\DI\Container;
18 -use IvyForms\Vendor\DI\ContainerBuilder;
19 -use IvyForms\Vendor\DI\DependencyException;
20 -use IvyForms\Vendor\DI\NotFoundException;
21 12 use Exception;
22 13 use IvyForms\Common\Exceptions\InvalidArgumentException;
14 +use IvyForms\Common\Exceptions\ValidationException;
23 15 use IvyForms\Routes\Routes;
24 16 use IvyForms\Services\InstallActions\ActivationDatabaseHook;
25 -use IvyForms\Services\InstallActions\ActivationMultisite;
26 -use IvyForms\Services\InstallActions\ActivationNewSiteMultisite;
27 -use IvyForms\Services\InstallActions\ActivationSettingsHook;
28 -use IvyForms\Services\InstallActions\DeleteDatabaseHook;
29 -use IvyForms\Services\InstallActions\DeletionMultisite;
17 +use IvyForms\Services\Integrations\Elementor\IvyFormsElementorLoader;
18 +use IvyForms\Services\Integrations\Gutenberg\Blocks\GutenbergBlock;
19 +use IvyForms\Services\Integrations\IntegrationService;
30 20 use IvyForms\Services\Menu\MenuManager;
21 +use IvyForms\Services\Payment\PaymentCspHeaders;
31 22 use IvyForms\Services\Preview\PreviewService;
32 23 use IvyForms\Services\Settings\SettingsService;
24 +use IvyForms\Services\Shortcode\Helpers\ShortcodeHelper;
33 25 use IvyForms\Services\Shortcode\ShortcodeService;
26 +use IvyForms\Services\Usage\UsageTrackingService;
27 +use IvyForms\Vendor\DI\Container;
28 +use IvyForms\Vendor\DI\ContainerBuilder;
29 +use IvyForms\Vendor\DI\DependencyException;
30 +use IvyForms\Vendor\DI\NotFoundException;
34 31
35 32 /**
36 33 * Plugin
37 34 */
@@ -96,26 +93,39 @@
96 93 * The code that runs during plugin activation
97 94 */
98 95 register_activation_hook(
99 96 IVYFORMS_FILE,
100 - [ self::class, 'activation' ]
97 + [ PluginInstallLifecycle::class, 'activation' ]
101 98 );
102 99 register_activation_hook(
103 100 IVYFORMS_FILE,
104 - [ self::class, 'activationSettings' ]
101 + [ PluginInstallLifecycle::class, 'activationSettings' ]
105 102 );
106 103
107 104 /**
108 105 * The code that runs during plugin deactivation
109 106 */
107 + register_deactivation_hook(
108 + IVYFORMS_FILE,
109 + [ PluginInstallLifecycle::class, 'deactivation' ]
110 + );
111 +
112 + /**
113 + * The code that runs when plugin is deleted
114 + */
110 115 register_uninstall_hook(
111 116 IVYFORMS_FILE,
112 - [ self::class, 'deletion']
117 + [ PluginInstallLifecycle::class, 'deletion']
113 118 );
114 119
115 120 /** Init load */
116 121 add_action('plugins_loaded', [ $this, 'init' ]);
117 122
123 + add_action('init', [PluginInstallLifecycle::class, 'maybeEnsureAdministratorCapabilities'], 0);
124 +
125 + /** Load translations at init action (WordPress 6.7+ requirement) */
126 + add_action('init', [ $this, 'loadTranslations' ]);
127 +
118 128 /** Register API calls */
119 129 add_action('rest_api_init', [$this, 'registerRoutes']);
120 130
121 131 /** Isolate API calls */
@@ -122,54 +132,18 @@
122 132 add_action('wp_ajax_ivyforms_api', [ $this, 'registerRoutes' ]);
123 133 add_action('wp_ajax_nopriv_ivyforms_api', [ $this, 'registerRoutes' ]);
124 134
125 135 /** Activation hook for new site on multisite setup */
126 - add_action('wpmu_new_blog', [ $this, 'initNewSite' ]);
136 + add_action('wpmu_new_blog', [ PluginInstallLifecycle::class, 'initNewSite' ]);
127 137
128 138 add_filter('wp_script_attributes', ['IvyForms\Services\Shortcode\ShortcodeService', 'addScriptAttribute']);
129 139
130 - add_action('admin_init', [$this, 'adminInit']);
131 - add_filter('admin_body_class', [$this, 'addAdminBodyClass']);
140 + // Register admin hooks via AdminHooks class
141 + $adminHooks = new AdminHooks($this->settingsService);
142 + $adminHooks->register();
132 143 }
133 144
134 145 /**
135 - * Handle admin initialization tasks
136 - *
137 - * @return void
138 - */
139 - public function adminInit(): void
140 - {
141 - $this->checkVersionAndHandleActivation();
142 -
143 - $this->removeAdminNotices();
144 - }
145 -
146 - /**
147 - * Check a plugin version and handle activation/deactivation if needed
148 - *
149 - * @return void
150 - */
151 - private function checkVersionAndHandleActivation(): void
152 - {
153 - if (!function_exists('activate_plugin')) {
154 - // @phpstan-ignore requireOnce.fileNotFound
155 - require_once ABSPATH . 'wp-admin/includes/plugin.php';
156 - }
157 -
158 - $settingsService = new SettingsService();
159 -
160 - $currentVersion = IVYFORMS_VERSION;
161 - $savedVersion = $settingsService->getSetting('general', 'version');
162 -
163 - if ($savedVersion !== $currentVersion) {
164 - deactivate_plugins(IVYFORMS_PLUGIN_SLUG); // @phpstan-ignore argument.type
165 - activate_plugin(IVYFORMS_PLUGIN_SLUG); // @phpstan-ignore argument.type
166 -
167 - $settingsService->setSetting('general', 'version', $currentVersion);
168 - }
169 - }
170 -
171 - /**
172 146 * @throws DependencyException
173 147 * @throws NotFoundException
174 148 */
175 149 public function registerRoutes(): void
@@ -178,137 +152,136 @@
178 152 Routes::registerRoutes($this->container);
179 153 }
180 154
181 155 /**
182 - * Remove admin notices on IvyForms admin pages
156 + * Init
157 + * @return void
158 + * @throws ValidationException|InvalidArgumentException
183 159 */
184 - public function removeAdminNotices(): void
160 + public function init(): void
185 161 {
186 - // Check if we're on an IvyForms admin page
187 - if ($this->isIvyFormsAdminPage()) {
188 - // Remove all admin notices
189 - remove_all_actions('admin_notices');
190 - remove_all_actions('all_admin_notices');
191 - // For plugins using user_admin_notices or network_admin_notices
192 - remove_all_actions('user_admin_notices');
193 - remove_all_actions('network_admin_notices');
194 - wp_register_style(
195 - 'ivyforms_admin_global',
196 - IVYFORMS_URL . 'frontend/css/global-admin.css',
197 - array(),
198 - IVYFORMS_VERSION
199 - );
200 - wp_enqueue_style('ivyforms_admin_global');
201 - }
162 + new PreviewService();
163 + $this->initIntegrationService();
164 + $this->initMenuManager();
165 + $this->registerShortcode();
166 + PaymentCspHeaders::register();
167 + $this->registerGutenbergBlock();
168 + $this->registerElementorWidget();
169 + $this->initUsageTrackingService();
202 170 }
203 171
204 172 /**
205 - * Check if current page is an IvyForms admin page
173 + * Initialize integration service
206 174 *
207 - * @SuppressWarnings(PHPMD)
208 - *
209 - * @return bool
175 + * @return void
210 176 */
211 - private function isIvyFormsAdminPage(): bool
177 + private function initIntegrationService(): void
212 178 {
213 - if (!is_admin()) {
214 - return false;
179 + try {
180 + /** @var IntegrationService $integrationService */
181 + $integrationService = $this->container->get(IntegrationService::class);
182 + $integrationService->init();
183 + } catch (DependencyException | NotFoundException $e) {
184 + if (defined('WP_DEBUG') && WP_DEBUG) {
185 + error_log('Integration service error: ' . $e->getMessage());
186 + }
215 187 }
216 - // Adjust this based on your page's actual slug/identifier
217 - return (isset($_GET['page']) && strpos($_GET['page'], 'ivyforms') !== false);
218 188 }
219 189
220 190 /**
221 - * @param bool $networkWide
191 + * Initialize usage tracking service
192 + *
193 + * @return void
222 194 */
223 - public static function activation(bool $networkWide): void
195 + private function initUsageTrackingService(): void
224 196 {
225 - //Network activation
226 - if ($networkWide && function_exists('is_multisite') && is_multisite()) {
227 - ActivationMultisite::init();
197 + try {
198 + /** @var UsageTrackingService $usageTrackingService */
199 + $usageTrackingService = $this->container->get(UsageTrackingService::class);
200 + $usageTrackingService->init();
201 + } catch (DependencyException | NotFoundException $e) {
202 + if (defined('WP_DEBUG') && WP_DEBUG) {
203 + error_log('Usage tracking service error: ' . $e->getMessage());
204 + }
228 205 }
229 -
230 - ActivationDatabaseHook::init();
231 206 }
232 207
233 208 /**
234 - * @param int $siteId
209 + * Initialize menu manager
210 + *
211 + * @return void
235 212 */
236 - public static function initNewSite(int $siteId): void
213 + private function initMenuManager(): void
237 214 {
238 - ActivationNewSiteMultisite::init($siteId);
215 + try {
216 + /** @var MenuManager $menuManager*/
217 + $menuManager = $this->container->get(MenuManager::class);
218 + // Register the admin menus and submenus using the 'admin_menu' hook
219 + $menuManager->registerMenus();
220 + } catch (DependencyException | NotFoundException $e) {
221 + if (defined('WP_DEBUG') && WP_DEBUG) {
222 + error_log('Menu error: ' . $e->getMessage());
223 + }
224 + }
239 225 }
240 226
241 227 /**
242 - * @throws Exception
228 + * Register shortcode
229 + *
230 + * @return void
243 231 */
244 - public static function activationSettings(): void
232 + private function registerShortcode(): void
245 233 {
246 - ActivationSettingsHook::init();
234 + if (is_admin()) {
235 + return;
236 + }
237 +
238 + add_action('wp_enqueue_scripts', [ShortcodeHelper::class, 'registerFrontendStyleHandles'], 1);
239 +
240 + add_shortcode('ivyforms', function ($atts = []) {
241 + return ShortcodeService::shortcodeHandler($atts);
242 + });
247 243 }
248 244
249 245 /**
250 - * Uninstall function when plugin is deleted
251 - * @throws InvalidArgumentException
246 + * Register Gutenberg block
247 + *
248 + * @return void
252 249 */
253 - public static function deletion(): void
250 + private function registerGutenbergBlock(): void
254 251 {
255 - $settingsService = new SettingsService();
252 + if (!function_exists('register_block_type')) {
253 + return;
254 + }
256 255
257 - if ($settingsService->getSetting('activation', 'deleteTables')) {
258 - //Network deletion
259 - if (
260 - function_exists('is_multisite') &&
261 - is_multisite()
262 - ) {
263 - DeletionMultisite::delete();
264 - }
265 -
266 - DeleteDatabaseHook::delete();
267 - }
256 + add_action('init', [GutenbergBlock::class, 'register']);
268 257 }
269 258
270 259 /**
271 - * Init
260 + * Register Elementor widget
261 + *
272 262 * @return void
273 263 */
274 - public function init(): void
264 + private function registerElementorWidget(): void
275 265 {
276 -
277 - new PreviewService();
278 -
279 - try {
280 - /** @var MenuManager $menuManager*/
281 - $menuManager = $this->container->get(MenuManager::class);
282 - // Register the admin menus and submenus using the 'admin_menu' hook
283 - $menuManager->registerMenus();
284 - } catch (DependencyException | NotFoundException $e) {
285 - if (defined('WP_DEBUG') && WP_DEBUG) {
286 - error_log('Menu error: ' . $e->getMessage());
287 - }
266 + if (!defined('ELEMENTOR_VERSION')) {
267 + return;
288 268 }
289 269
290 - if (!is_admin()) {
291 - add_shortcode('ivyforms', function ($atts = []) {
292 - return ShortcodeService::shortcodeHandler($atts);
293 - });
294 - }
270 + IvyFormsElementorLoader::instance();
295 271 }
272 +
296 273 /**
297 - * Add admin body class
274 + * Load plugin translations
275 + * Called on 'init' action to comply with WordPress 6.7+ requirements
298 276 *
299 - * @param string $classes
300 - * @return string
277 + * @return void
301 278 */
302 - public function addAdminBodyClass(string $classes): string
279 + public function loadTranslations(): void
303 280 {
304 - if ($this->settingsService === null) {
305 - return $classes;
306 - }
307 -
308 - if ($this->settingsService->getSetting('general', 'fullscreen')) {
309 - $classes .= ' ivyforms-fullscreen-mode ';
310 - }
311 -
312 - return $classes;
281 + load_plugin_textdomain(
282 + 'ivyforms',
283 + false,
284 + dirname(plugin_basename(IVYFORMS_FILE)) . '/languages/' . get_locale() . '/'
285 + );
313 286 }
314 287 }