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 / Services / API / IvyFormsAPI.php

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

454 lines 14.8 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 use Exception;
6 use IvyForms\Factory\Form\FormFactory;
7 use IvyForms\Services\Confirmation\ConfirmationService;
8 use IvyForms\Services\Entry\EntryService;
9 use IvyForms\Services\FieldOptions\FieldOptionsService;
10 use IvyForms\Services\Form\FormService;
11 use IvyForms\Services\Field\FieldService;
12 use IvyForms\Common\Exceptions\NotFoundException;
13 use IvyForms\Common\Exceptions\InvalidArgumentException;
14 use IvyForms\Common\Exceptions\QueryExecutionException;
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;
20 use WP_Error;
21 use IvyForms\Services\API\IvyFormsAPIHelpers;
22
23 /**
24 * Class IvyFormsAPI
25 *
26 * @package IvyForms\Services\API
27 *
28 * This class provides a singleton instance to interact with the IvyForms plugin.
29 * It includes methods to manage forms and fields, including creating, updating,
30 * deleting, and retrieving forms and fields.
31 */
32 class IvyFormsAPI
33 {
34 use IvyFormsAPIHelpers;
35
36 private static ?self $instance = null;
37 private FormService $formService;
38 private FieldService $fieldService;
39 private FieldOptionsService $fieldOptionsService;
40 private NotificationService $notificationService;
41 private ConfirmationService $confirmationService;
42 private EntryService $entryService;
43 private SettingsService $settingsService;
44 private function __construct(
45 FormService $formService,
46 FieldService $fieldService,
47 FieldOptionsService $fieldOptionsService,
48 NotificationService $notificationService,
49 ConfirmationService $confirmationService,
50 EntryService $entryService,
51 SettingsService $settingsService
52 ) {
53 $this->formService = $formService;
54 $this->fieldService = $fieldService;
55 $this->fieldOptionsService = $fieldOptionsService;
56 $this->notificationService = $notificationService;
57 $this->confirmationService = $confirmationService;
58 $this->entryService = $entryService;
59 $this->settingsService = $settingsService;
60 }
61
62 /**
63 * Check if IvyForms plugin is installed and activated
64 *
65 * @return bool
66 */
67 public static function isPluginActive(): bool
68 {
69 if (!function_exists('is_plugin_active')) {
70 require_once ABSPATH . 'wp-admin/includes/plugin.php';
71 }
72 return is_plugin_active('ivyforms/ivyforms.php');
73 }
74
75 /**
76 * Check if Pro plugin is installed and activated
77 *
78 * @return bool
79 */
80 public static function isProPluginActive(): bool
81 {
82 // Check if Pro plugin constant is defined
83 if (defined('IVYFORMS_PRO_VERSION')) {
84 return true;
85 }
86
87 // Alternative check: see if Pro plugin class exists
88 return class_exists('IvyFormsPro\\Plugin\\Plugin', false);
89 }
90
91 /**
92 * Get instance with error handling
93 *
94 * @return self|WP_Error Returns an instance of IvyFormsAPI or WP_Error on failure
95 */
96 public static function getInstance()
97 {
98 if (self::$instance === null) {
99 return self::handleErrors(function () {
100 if (!self::isPluginActive()) {
101 throw new Exception(
102 BackendStrings::getExceptionStrings()['ivyforms_not_installed']
103 );
104 }
105 if (!file_exists(IVYFORMS_PATH . '/backend/vendor/autoload.php')) {
106 throw new Exception(
107 BackendStrings::getExceptionStrings()['autoload_not_found']
108 );
109 }
110 if (!file_exists(IVYFORMS_PATH . '/backend/src/Config/container.php')) {
111 throw new Exception(
112 BackendStrings::getExceptionStrings()['container_not_found']
113 );
114 }
115
116 $builder = new ContainerBuilder();
117 $builder->addDefinitions(IVYFORMS_PATH . '/backend/src/Config/repository.php');
118 $builder->addDefinitions(IVYFORMS_PATH . '/backend/src/Config/services.php');
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
131 $formService = $container->get(FormService::class);
132 $fieldService = $container->get(FieldService::class);
133 $fieldOptionsService = $container->get(FieldOptionsService::class);
134 $notificationService = $container->get(NotificationService::class);
135 $confirmationService = $container->get(ConfirmationService::class);
136 $entryService = $container->get(EntryService::class);
137 $settingsService = $container->get(SettingsService::class);
138
139 self::$instance = new self(
140 $formService,
141 $fieldService,
142 $fieldOptionsService,
143 $notificationService,
144 $confirmationService,
145 $entryService,
146 $settingsService
147 );
148 return self::$instance;
149 });
150 }
151 return self::$instance;
152 }
153
154 /**
155 * Get a single form by ID
156 *
157 * @param int $formId
158 * @return object|WP_Error
159 */
160 public static function getForm(int $formId)
161 {
162 return self::handleErrors(function () use ($formId) {
163 if ($formId <= 0) {
164 throw new InvalidArgumentException(
165 BackendStrings::getExceptionStrings()['invalid_form_id']
166 );
167 }
168 return self::getInstance()->formService->getFormById($formId);
169 });
170 }
171
172 /**
173 * Get all forms
174 *
175 * @return mixed[] | WP_Error
176 */
177 public static function getForms()
178 {
179 return self::handleErrors(function () {
180 return self::getInstance()->formService->getAllForms();
181 });
182 }
183
184 /**
185 * Create a new form
186 *
187 * @param mixed[] $formData
188 * @return int|WP_Error
189 */
190 public static function createForm(array $formData)
191 {
192 return self::handleErrors(function () use ($formData) {
193 if (empty($formData)) {
194 throw new InvalidArgumentException(
195 BackendStrings::getExceptionStrings()['invalid_form_data']
196 );
197 }
198 $formData = FormFactory::create($formData);
199 return self::getInstance()->formService->createForm($formData);
200 });
201 }
202
203 /**
204 * Update an existing form
205 *
206 * @param int $formId
207 * @param mixed[] $formData
208 * @return bool|WP_Error
209 */
210 public static function updateForm(int $formId, array $formData)
211 {
212 return self::handleErrors(function () use ($formId, $formData) {
213 if ($formId <= 0) {
214 throw new InvalidArgumentException(
215 BackendStrings::getExceptionStrings()['invalid_form_id']
216 );
217 }
218 if (empty($formData)) {
219 throw new InvalidArgumentException(
220 BackendStrings::getExceptionStrings()['invalid_form_data']
221 );
222 }
223 $formData = FormFactory::create($formData);
224 return self::getInstance()->formService->updateForm($formId, $formData);
225 });
226 }
227
228 /**
229 * Delete a form
230 *
231 * @param int $formId
232 * @return bool | WP_Error
233 */
234 public static function deleteForm(int $formId)
235 {
236 return self::handleErrors(function () use ($formId) {
237 if ($formId <= 0) {
238 throw new InvalidArgumentException(
239 BackendStrings::getExceptionStrings()['invalid_form_id']
240 );
241 }
242 self::getInstance()->formService->deleteForm($formId);
243 self::getInstance()->fieldService->deleteFieldsByFormId($formId);
244 return true;
245 });
246 }
247
248 /**
249 * Check if a form exists
250 *
251 * @param int $formId
252 * @return bool | WP_Error
253 */
254 public static function formExists(int $formId)
255 {
256 return self::handleErrors(function () use ($formId) {
257 if ($formId <= 0) {
258 throw new InvalidArgumentException(
259 BackendStrings::getExceptionStrings()['invalid_form_id']
260 );
261 }
262 return self::getInstance()->formService->formExists($formId);
263 });
264 }
265
266 /**
267 * Get all fields for a form
268 *
269 * @param int $formId
270 * @return mixed[] | WP_Error
271 */
272 public static function getFields(int $formId)
273 {
274 return self::handleErrors(function () use ($formId) {
275 if ($formId <= 0) {
276 throw new InvalidArgumentException(
277 BackendStrings::getExceptionStrings()['invalid_form_id']
278 );
279 }
280 return self::getInstance()->fieldService->getAllFields($formId);
281 });
282 }
283
284 /**
285 * Delete fields by form ID
286 *
287 * @param int $formId
288 * @return bool | WP_Error
289 */
290 public static function deleteFields(int $formId)
291 {
292 return self::handleErrors(function () use ($formId) {
293 if ($formId <= 0) {
294 throw new InvalidArgumentException(
295 BackendStrings::getExceptionStrings()['invalid_form_id']
296 );
297 }
298 self::getInstance()->fieldService->deleteFieldsByFormId($formId);
299 return true;
300 });
301 }
302 /**
303 * Get all fields for a form
304 *
305 * @param int $formId
306 * @return mixed[] | WP_Error
307 */
308 public static function getConfirmations(int $formId)
309 {
310 return self::handleErrors(function () use ($formId) {
311 if ($formId <= 0) {
312 throw new InvalidArgumentException(
313 BackendStrings::getExceptionStrings()['invalid_form_id']
314 );
315 }
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;
451 });
452 }
453 }
454