PluginProbe
The Innovative Form Builder – IvyForms / 0.8
The Innovative Form Builder – IvyForms v0.8
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 1.2 1.3
ivyforms / backend / src / Services / API / IvyFormsAPI.php

IvyFormsAPI.php in The Innovative Form Builder – IvyForms 0.8, at backend/src/Services/API/IvyFormsAPI.php

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