PluginProbe
The Innovative Form Builder – IvyForms / 1.4.1
The Innovative Form Builder – IvyForms v1.4.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
ivyforms / backend / src / Plugin / Plugin.php

Plugin.php in The Innovative Form Builder – IvyForms 1.4.1, at backend/src/Plugin/Plugin.php

286 lines 7.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Plugin Loader.
5 *
6 * @package IvyForms
7 * @since 0.1.0
8 */
9
10 namespace IvyForms\Plugin;
11
12 use Exception;
13 use IvyForms\Common\Exceptions\InvalidArgumentException;
14 use IvyForms\Common\Exceptions\ValidationException;
15 use IvyForms\Routes\Routes;
16 use IvyForms\Services\InstallActions\ActivationDatabaseHook;
17 use IvyForms\Services\Integrations\Elementor\IvyFormsElementorLoader;
18 use IvyForms\Services\Integrations\Gutenberg\Blocks\GutenbergBlock;
19 use IvyForms\Services\Integrations\IntegrationService;
20 use IvyForms\Services\Menu\MenuManager;
21 use IvyForms\Services\Preview\PreviewService;
22 use IvyForms\Services\Settings\SettingsService;
23 use IvyForms\Services\Shortcode\Helpers\ShortcodeHelper;
24 use IvyForms\Services\Shortcode\ShortcodeService;
25 use IvyForms\Services\Usage\UsageTrackingService;
26 use IvyForms\Vendor\DI\Container;
27 use IvyForms\Vendor\DI\ContainerBuilder;
28 use IvyForms\Vendor\DI\DependencyException;
29 use IvyForms\Vendor\DI\NotFoundException;
30
31 /**
32 * Plugin
33 */
34 class Plugin
35 {
36 /**
37 * Instance
38 */
39 private static ?object $instance = null;
40
41 private ContainerBuilder $builder;
42 /**
43 * Container
44 */
45 public ?Container $container = null;
46
47 /**
48 * Settings Service
49 */
50 private ?SettingsService $settingsService = null;
51
52 /**
53 * Load plugin
54 *
55 * @return object initialized object of class.
56 * @throws Exception
57 */
58 public static function getInstance(): ?object
59 {
60 if (null === self::$instance) {
61 self::$instance = new self();
62 }
63 return self::$instance;
64 }
65
66 /**
67 * Constructor
68 *
69 * @throws Exception
70 * @since 0.1.0
71 */
72 public function __construct()
73 {
74 $this->builder = new ContainerBuilder();
75 $this->builder->addDefinitions(IVYFORMS_PATH . '/backend/src/Config/repository.php');
76 $this->builder->addDefinitions(IVYFORMS_PATH . '/backend/src/Config/services.php');
77
78 /**
79 * Allow to hook into container before build
80 * @since 0.1.0
81 *
82 * Arguments:
83 * - ContainerBuilder $builder The IvyForms DI container builder (base)
84 */
85 do_action('ivyforms/boot/extend_container_builder', $this->builder);
86
87 $this->container = $this->builder->build();
88
89 $this->settingsService = $this->container->get(SettingsService::class);
90
91 /**
92 * The code that runs during plugin activation
93 */
94 register_activation_hook(
95 IVYFORMS_FILE,
96 [ PluginInstallLifecycle::class, 'activation' ]
97 );
98 register_activation_hook(
99 IVYFORMS_FILE,
100 [ PluginInstallLifecycle::class, 'activationSettings' ]
101 );
102
103 /**
104 * The code that runs during plugin deactivation
105 */
106 register_deactivation_hook(
107 IVYFORMS_FILE,
108 [ PluginInstallLifecycle::class, 'deactivation' ]
109 );
110
111 /**
112 * The code that runs when plugin is deleted
113 */
114 register_uninstall_hook(
115 IVYFORMS_FILE,
116 [ PluginInstallLifecycle::class, 'deletion']
117 );
118
119 /** Init load */
120 add_action('plugins_loaded', [ $this, 'init' ]);
121
122 add_action('init', [PluginInstallLifecycle::class, 'maybeEnsureAdministratorCapabilities'], 0);
123
124 /** Load translations at init action (WordPress 6.7+ requirement) */
125 add_action('init', [ $this, 'loadTranslations' ]);
126
127 /** Register API calls */
128 add_action('rest_api_init', [$this, 'registerRoutes']);
129
130 /** Isolate API calls */
131 add_action('wp_ajax_ivyforms_api', [ $this, 'registerRoutes' ]);
132 add_action('wp_ajax_nopriv_ivyforms_api', [ $this, 'registerRoutes' ]);
133
134 /** Activation hook for new site on multisite setup */
135 add_action('wpmu_new_blog', [ PluginInstallLifecycle::class, 'initNewSite' ]);
136
137 add_filter('wp_script_attributes', ['IvyForms\Services\Shortcode\ShortcodeService', 'addScriptAttribute']);
138
139 // Register admin hooks via AdminHooks class
140 $adminHooks = new AdminHooks($this->settingsService);
141 $adminHooks->register();
142 }
143
144 /**
145 * @throws DependencyException
146 * @throws NotFoundException
147 */
148 public function registerRoutes(): void
149 {
150 // Register REST API routes after the container is built
151 Routes::registerRoutes($this->container);
152 }
153
154 /**
155 * Init
156 * @return void
157 * @throws ValidationException|InvalidArgumentException
158 */
159 public function init(): void
160 {
161 new PreviewService();
162 $this->initIntegrationService();
163 $this->initMenuManager();
164 $this->registerShortcode();
165 $this->registerGutenbergBlock();
166 $this->registerElementorWidget();
167 $this->initUsageTrackingService();
168 }
169
170 /**
171 * Initialize integration service
172 *
173 * @return void
174 */
175 private function initIntegrationService(): void
176 {
177 try {
178 /** @var IntegrationService $integrationService */
179 $integrationService = $this->container->get(IntegrationService::class);
180 $integrationService->init();
181 } catch (DependencyException |NotFoundException $e) {
182 if (defined('WP_DEBUG') && WP_DEBUG) {
183 error_log('Integration service error: ' . $e->getMessage());
184 }
185 }
186 }
187
188 /**
189 * Initialize usage tracking service
190 *
191 * @return void
192 */
193 private function initUsageTrackingService(): void
194 {
195 try {
196 /** @var UsageTrackingService $usageTrackingService */
197 $usageTrackingService = $this->container->get(UsageTrackingService::class);
198 $usageTrackingService->init();
199 } catch (DependencyException |NotFoundException $e) {
200 if (defined('WP_DEBUG') && WP_DEBUG) {
201 error_log('Usage tracking service error: ' . $e->getMessage());
202 }
203 }
204 }
205
206 /**
207 * Initialize menu manager
208 *
209 * @return void
210 */
211 private function initMenuManager(): void
212 {
213 try {
214 /** @var MenuManager $menuManager*/
215 $menuManager = $this->container->get(MenuManager::class);
216 // Register the admin menus and submenus using the 'admin_menu' hook
217 $menuManager->registerMenus();
218 } catch (DependencyException |NotFoundException $e) {
219 if (defined('WP_DEBUG') && WP_DEBUG) {
220 error_log('Menu error: ' . $e->getMessage());
221 }
222 }
223 }
224
225 /**
226 * Register shortcode
227 *
228 * @return void
229 */
230 private function registerShortcode(): void
231 {
232 if (is_admin()) {
233 return;
234 }
235
236 add_action('wp_enqueue_scripts', [ShortcodeHelper::class, 'registerFrontendStyleHandles'], 1);
237
238 add_shortcode('ivyforms', function ($atts = []) {
239 return ShortcodeService::shortcodeHandler($atts);
240 });
241 }
242
243 /**
244 * Register Gutenberg block
245 *
246 * @return void
247 */
248 private function registerGutenbergBlock(): void
249 {
250 if (!function_exists('register_block_type')) {
251 return;
252 }
253
254 add_action('init', [GutenbergBlock::class, 'register']);
255 }
256
257 /**
258 * Register Elementor widget
259 *
260 * @return void
261 */
262 private function registerElementorWidget(): void
263 {
264 if (!defined('ELEMENTOR_VERSION')) {
265 return;
266 }
267
268 IvyFormsElementorLoader::instance();
269 }
270
271 /**
272 * Load plugin translations
273 * Called on 'init' action to comply with WordPress 6.7+ requirements
274 *
275 * @return void
276 */
277 public function loadTranslations(): void
278 {
279 load_plugin_textdomain(
280 'ivyforms',
281 false,
282 dirname(plugin_basename(IVYFORMS_FILE)) . '/languages/' . get_locale() . '/'
283 );
284 }
285 }
286