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/Services/API/IvyFormsAPI.php +233 -43 0.2 → 1.5.1 View file →
@@ -1,16 +1,13 @@
1 1 <?php
2 2
3 3 namespace IvyForms\Services\API;
4 4
5 -// phpcs:disable PSR1.Files.SideEffects
6 -if (!defined('ABSPATH')) {
7 - exit; // Exit if accessed directly
8 -}
9 -
10 5 use Exception;
11 6 use IvyForms\Factory\Form\FormFactory;
12 7 use IvyForms\Services\Confirmation\ConfirmationService;
8 +use IvyForms\Services\Entry\EntryService;
9 +use IvyForms\Services\FieldOptions\FieldOptionsService;
13 10 use IvyForms\Services\Form\FormService;
14 11 use IvyForms\Services\Field\FieldService;
15 12 use IvyForms\Common\Exceptions\NotFoundException;
16 13 use IvyForms\Common\Exceptions\InvalidArgumentException;
@@ -15,9 +12,14 @@
15 12 use IvyForms\Common\Exceptions\NotFoundException;
16 13 use IvyForms\Common\Exceptions\InvalidArgumentException;
17 14 use IvyForms\Common\Exceptions\QueryExecutionException;
18 15 use IvyForms\Common\Exceptions\ValidationException;
16 +use IvyForms\Services\Notification\NotificationService;
17 +use IvyForms\Services\Settings\SettingsService;
18 +use IvyForms\Services\Translations\BackendStrings;
19 +use IvyForms\Vendor\DI\ContainerBuilder;
19 20 use WP_Error;
21 +use IvyForms\Services\API\IvyFormsAPIHelpers;
20 22
21 23 /**
22 24 * Class IvyFormsAPI
23 25 *
@@ -28,57 +30,63 @@
28 30 * deleting, and retrieving forms and fields.
29 31 */
30 32 class IvyFormsAPI
31 33 {
34 + use IvyFormsAPIHelpers;
35 +
32 36 private static ?self $instance = null;
33 37 private FormService $formService;
34 38 private FieldService $fieldService;
39 + private FieldOptionsService $fieldOptionsService;
40 + private NotificationService $notificationService;
35 41 private ConfirmationService $confirmationService;
36 -
42 + private EntryService $entryService;
43 + private SettingsService $settingsService;
37 44 private function __construct(
38 45 FormService $formService,
39 46 FieldService $fieldService,
40 - ConfirmationService $confirmationService
47 + FieldOptionsService $fieldOptionsService,
48 + NotificationService $notificationService,
49 + ConfirmationService $confirmationService,
50 + EntryService $entryService,
51 + SettingsService $settingsService
41 52 ) {
42 53 $this->formService = $formService;
43 54 $this->fieldService = $fieldService;
55 + $this->fieldOptionsService = $fieldOptionsService;
56 + $this->notificationService = $notificationService;
44 57 $this->confirmationService = $confirmationService;
58 + $this->entryService = $entryService;
59 + $this->settingsService = $settingsService;
45 60 }
46 61
47 62 /**
48 - * Protected method to handle errors uniformly across all API methods
63 + * Check if IvyForms plugin is installed and activated
49 64 *
50 - * @param callable $callback The function to execute
51 - * @return mixed The result of the callback or WP_Error on failure
65 + * @return bool
52 66 */
53 - protected static function handleErrors(callable $callback)
67 + public static function isPluginActive(): bool
54 68 {
55 - try {
56 - return $callback();
57 - } catch (InvalidArgumentException $e) {
58 - return new WP_Error('invalid_argument', $e->getMessage(), ['status' => 400]);
59 - } catch (NotFoundException $e) {
60 - return new WP_Error('not_found', $e->getMessage(), ['status' => 404]);
61 - } catch (QueryExecutionException $e) {
62 - return new WP_Error('query_execution_error', $e->getMessage(), ['status' => 500]);
63 - } catch (ValidationException $e) {
64 - return new WP_Error('validation_error', $e->getMessage(), ['status' => 422]);
65 - } catch (Exception $e) {
66 - return new WP_Error('unknown_error', $e->getMessage(), ['status' => 500]);
69 + if (!function_exists('is_plugin_active')) {
70 + require_once ABSPATH . 'wp-admin/includes/plugin.php';
67 71 }
72 + return is_plugin_active('ivyforms/ivyforms.php');
68 73 }
69 74
70 75 /**
71 - * Check if IvyForms plugin is installed and activated
76 + * Check if Pro plugin is installed and activated
72 77 *
73 78 * @return bool
74 79 */
75 - public static function isPluginActive(): bool
80 + public static function isProPluginActive(): bool
76 81 {
77 - if (!function_exists('is_plugin_active')) {
78 - require_once ABSPATH . 'wp-admin/includes/plugin.php';
82 + // Check if Pro plugin constant is defined
83 + if (defined('IVYFORMS_PRO_VERSION')) {
84 + return true;
79 85 }
80 - return is_plugin_active('ivyforms/ivyforms.php');
86 +
87 + // Alternative check: see if Pro plugin class exists
88 + return class_exists('IvyFormsPro\\Plugin\\Plugin', false);
81 89 }
82 90
83 91 /**
84 92 * Get instance with error handling
@@ -89,25 +97,55 @@
89 97 {
90 98 if (self::$instance === null) {
91 99 return self::handleErrors(function () {
92 100 if (!self::isPluginActive()) {
93 - throw new Exception('IvyForms plugin is not installed or activated');
101 + throw new Exception(
102 + BackendStrings::getExceptionStrings()['ivyforms_not_installed']
103 + );
94 104 }
95 105 if (!file_exists(IVYFORMS_PATH . '/backend/vendor/autoload.php')) {
96 - throw new Exception('Autoload file not found');
106 + throw new Exception(
107 + BackendStrings::getExceptionStrings()['autoload_not_found']
108 + );
97 109 }
98 110 if (!file_exists(IVYFORMS_PATH . '/backend/src/Config/container.php')) {
99 - throw new Exception('Container file not found');
111 + throw new Exception(
112 + BackendStrings::getExceptionStrings()['container_not_found']
113 + );
100 114 }
101 115
102 - require_once IVYFORMS_PATH . '/backend/vendor/autoload.php';
103 - $container = require IVYFORMS_PATH . '/backend/src/Config/container.php';
116 + $builder = new ContainerBuilder();
117 + $builder->addDefinitions(IVYFORMS_PATH . '/backend/src/Config/repository.php');
118 + $builder->addDefinitions(IVYFORMS_PATH . '/backend/src/Config/services.php');
104 119
120 + /**
121 + * Allow to hook into container before build
122 + * @since 0.1.0
123 + *
124 + * Arguments:
125 + * - ContainerBuilder $builder The container builder instance
126 + */
127 + do_action('ivyforms/boot/extend_container_builder', $builder);
128 +
129 + $container = $builder->build();
130 +
105 131 $formService = $container->get(FormService::class);
106 132 $fieldService = $container->get(FieldService::class);
133 + $fieldOptionsService = $container->get(FieldOptionsService::class);
134 + $notificationService = $container->get(NotificationService::class);
107 135 $confirmationService = $container->get(ConfirmationService::class);
136 + $entryService = $container->get(EntryService::class);
137 + $settingsService = $container->get(SettingsService::class);
108 138
109 - self::$instance = new self($formService, $fieldService, $confirmationService);
139 + self::$instance = new self(
140 + $formService,
141 + $fieldService,
142 + $fieldOptionsService,
143 + $notificationService,
144 + $confirmationService,
145 + $entryService,
146 + $settingsService
147 + );
110 148 return self::$instance;
111 149 });
112 150 }
113 151 return self::$instance;
@@ -122,9 +160,11 @@
122 160 public static function getForm(int $formId)
123 161 {
124 162 return self::handleErrors(function () use ($formId) {
125 163 if ($formId <= 0) {
126 - throw new InvalidArgumentException('Invalid form ID');
164 + throw new InvalidArgumentException(
165 + BackendStrings::getExceptionStrings()['invalid_form_id']
166 + );
127 167 }
128 168 return self::getInstance()->formService->getFormById($formId);
129 169 });
130 170 }
@@ -150,9 +190,11 @@
150 190 public static function createForm(array $formData)
151 191 {
152 192 return self::handleErrors(function () use ($formData) {
153 193 if (empty($formData)) {
154 - throw new InvalidArgumentException('Invalid form data');
194 + throw new InvalidArgumentException(
195 + BackendStrings::getExceptionStrings()['invalid_form_data']
196 + );
155 197 }
156 198 $formData = FormFactory::create($formData);
157 199 return self::getInstance()->formService->createForm($formData);
158 200 });
@@ -168,12 +210,16 @@
168 210 public static function updateForm(int $formId, array $formData)
169 211 {
170 212 return self::handleErrors(function () use ($formId, $formData) {
171 213 if ($formId <= 0) {
172 - throw new InvalidArgumentException('Invalid form ID');
214 + throw new InvalidArgumentException(
215 + BackendStrings::getExceptionStrings()['invalid_form_id']
216 + );
173 217 }
174 218 if (empty($formData)) {
175 - throw new InvalidArgumentException('Invalid form data');
219 + throw new InvalidArgumentException(
220 + BackendStrings::getExceptionStrings()['invalid_form_data']
221 + );
176 222 }
177 223 $formData = FormFactory::create($formData);
178 224 return self::getInstance()->formService->updateForm($formId, $formData);
179 225 });
@@ -188,9 +234,11 @@
188 234 public static function deleteForm(int $formId)
189 235 {
190 236 return self::handleErrors(function () use ($formId) {
191 237 if ($formId <= 0) {
192 - throw new InvalidArgumentException('Invalid form ID');
238 + throw new InvalidArgumentException(
239 + BackendStrings::getExceptionStrings()['invalid_form_id']
240 + );
193 241 }
194 242 self::getInstance()->formService->deleteForm($formId);
195 243 self::getInstance()->fieldService->deleteFieldsByFormId($formId);
196 244 return true;
@@ -206,9 +254,11 @@
206 254 public static function formExists(int $formId)
207 255 {
208 256 return self::handleErrors(function () use ($formId) {
209 257 if ($formId <= 0) {
210 - throw new InvalidArgumentException('Invalid form ID');
258 + throw new InvalidArgumentException(
259 + BackendStrings::getExceptionStrings()['invalid_form_id']
260 + );
211 261 }
212 262 return self::getInstance()->formService->formExists($formId);
213 263 });
214 264 }
@@ -222,9 +272,11 @@
222 272 public static function getFields(int $formId)
223 273 {
224 274 return self::handleErrors(function () use ($formId) {
225 275 if ($formId <= 0) {
226 - throw new InvalidArgumentException('Invalid form ID');
276 + throw new InvalidArgumentException(
277 + BackendStrings::getExceptionStrings()['invalid_form_id']
278 + );
227 279 }
228 280 return self::getInstance()->fieldService->getAllFields($formId);
229 281 });
230 282 }
@@ -238,9 +290,11 @@
238 290 public static function deleteFields(int $formId)
239 291 {
240 292 return self::handleErrors(function () use ($formId) {
241 293 if ($formId <= 0) {
242 - throw new InvalidArgumentException('Invalid form ID');
294 + throw new InvalidArgumentException(
295 + BackendStrings::getExceptionStrings()['invalid_form_id']
296 + );
243 297 }
244 298 self::getInstance()->fieldService->deleteFieldsByFormId($formId);
245 299 return true;
246 300 });
@@ -254,10 +308,146 @@
254 308 public static function getConfirmations(int $formId)
255 309 {
256 310 return self::handleErrors(function () use ($formId) {
257 311 if ($formId <= 0) {
258 - throw new InvalidArgumentException('Invalid form ID');
312 + throw new InvalidArgumentException(
313 + BackendStrings::getExceptionStrings()['invalid_form_id']
314 + );
259 315 }
260 316 return self::getInstance()->confirmationService->getConfirmationsById($formId);
317 + });
318 + }
319 +
320 + /**
321 + * Get all notifications for a form
322 + *
323 + * @param int $formId
324 + * @return mixed[] | WP_Error
325 + */
326 + public static function getNotifications(int $formId)
327 + {
328 + return self::handleErrors(function () use ($formId) {
329 + if ($formId <= 0) {
330 + throw new InvalidArgumentException(
331 + BackendStrings::getExceptionStrings()['invalid_form_id']
332 + );
333 + }
334 + return self::getInstance()->notificationService->getNotificationsByFormId($formId);
335 + });
336 + }
337 + /**
338 + * Get all field options for a field
339 + *
340 + * @param int $fieldId
341 + * @return mixed[] | WP_Error
342 + */
343 + public static function getFieldOptions(int $fieldId)
344 + {
345 + return self::handleErrors(function () use ($fieldId) {
346 + if ($fieldId <= 0) {
347 + throw new InvalidArgumentException(
348 + BackendStrings::getExceptionStrings()['invalid_field_id']
349 + );
350 + }
351 + $instance = self::getInstance();
352 + if ($instance instanceof WP_Error) {
353 + return $instance;
354 + }
355 + return $instance->fieldOptionsService->getByFieldId($fieldId);
356 + });
357 + }
358 +
359 + /**
360 + * Get entries for a specific form, with optional filters
361 + * @param int $formId
362 + * @param array<string, mixed> $params
363 + * @return array<int, mixed>|WP_Error
364 + */
365 + public static function getFormEntries(int $formId, array $params = [])
366 + {
367 + return self::handleErrors(function () use ($formId, $params) {
368 + if ($formId <= 0) {
369 + throw new InvalidArgumentException(
370 + BackendStrings::getExceptionStrings()['invalid_form_id']
371 + );
372 + }
373 + // Merge formId into filters
374 + $params['filters']['formId'] = $formId;
375 + $result = self::getInstance()->entryService->getEntryManager()->searchEntries($params);
376 + return $result['data'] ?? [];
377 + });
378 + }
379 +
380 + /**
381 + * Get entry fields for given entries
382 + *
383 + * @param array<int, mixed> $entries
384 + * @return array<int, mixed>|WP_Error
385 + */
386 + public static function getEntryFields(array $entries)
387 + {
388 + return self::handleErrors(function () use ($entries) {
389 + if (empty($entries)) {
390 + throw new InvalidArgumentException(
391 + BackendStrings::getExceptionStrings()['invalid_form_id']
392 + );
393 + }
394 + return self::getInstance()->entryService->getEntryFieldManager()->getEntryFields($entries);
395 + });
396 + }
397 +
398 + /**
399 + * Check if an integration is enabled
400 + *
401 + * @param string $integration
402 + * @return bool
403 + */
404 + public static function isIntegrationEnabled(string $integration): bool
405 + {
406 + $result = self::handleErrors(function () use ($integration) {
407 + $instance = self::getInstance();
408 + if ($instance instanceof WP_Error) {
409 + return false;
410 + }
411 + return self::checkIntegrationEnabled($instance, $integration);
412 + });
413 + return $result === true;
414 + }
415 +
416 + /**
417 + * Get forms with an integration enabled
418 + *
419 + * @param string $integration
420 + * @return array<int, mixed>|WP_Error Array of forms with an integration enabled
421 + */
422 + public static function getFormsWithIntegrationEnabled(string $integration)
423 + {
424 + return self::handleErrors(function () use ($integration) {
425 + $allForms = self::getInstance()->formService->getAllForms();
426 + return self::filterFormsWithIntegration($allForms, $integration);
427 + });
428 + }
429 + /**
430 + * Check if a specific form has an integration enabled
431 + *
432 + * @param int $formId
433 + * @param string $integration
434 + * @return bool|WP_Error
435 + */
436 + public static function isIntegrationEnabledForForm(int $formId, string $integration)
437 + {
438 + return self::handleErrors(function () use ($integration, $formId) {
439 + if ($formId <= 0) {
440 + throw new InvalidArgumentException(
441 + BackendStrings::getExceptionStrings()['invalid_form_id']
442 + );
443 + }
444 + $form = self::getInstance()->formService->getFormById($formId);
445 + if (method_exists($form, 'getIntegrationSettings')) {
446 + $integrationSettings = $form->getIntegrationSettings();
447 + return $integrationSettings->isIntegrationEnabled($integration)
448 + || empty($integrationSettings->toArray());
449 + }
450 + return false;
261 451 });
262 452 }
263 453 }