PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.2
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.2
6.2.14 6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 3.6.65 All 196 releases
fluentform / app / Modules / Form / Form.php

Form.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 6.2.2, at app/Modules/Form/Form.php

865 lines 28.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentForm\App\Modules\Form;
4
5 use FluentForm\App\Helpers\Helper;
6 use FluentForm\App\Modules\Acl\Acl;
7 use FluentForm\App\Modules\Payments\PaymentHelper;
8 use FluentForm\Framework\Foundation\Application;
9 use FluentForm\Framework\Helpers\ArrayHelper;
10
11 class Form
12 {
13 /**
14 * Request object
15 *
16 * @var \FluentForm\Framework\Request\Request $request
17 */
18 protected $request;
19
20 /**
21 * Set this value when we need predefined default settings.
22 *
23 * @var array $defaultSettings
24 */
25 protected $defaultSettings;
26
27 /**
28 * Set this value when we need predefined default notifications.
29 *
30 * @var array $defaultNotifications
31 */
32 protected $defaultNotifications;
33
34 /**
35 * Set this value when we need predefined form fields.
36 *
37 * @var array $formFields
38 */
39 protected $formFields;
40
41 protected $metas = [];
42
43 protected $formType = 'form';
44
45 protected $hasPayment = 0;
46 /**
47 * @var \FluentForm\Framework\Database\Query\Builder
48 */
49 protected $model = null;
50
51 /**
52 * Form constructor.
53 *
54 * @param \FluentForm\Framework\Foundation\Application $application
55 */
56 public function __construct(Application $application)
57 {
58 $this->request = $application->request;
59 $this->model = wpFluent()->table('fluentform_forms');
60 }
61
62 /**
63 * Get all forms from database
64 */
65 public function index()
66 {
67 $forms = fluentFormApi('forms')->forms([
68 'search' => $this->request->get('search'),
69 'status' => $this->request->get('status'),
70 'filter_by' => $this->request->get('filter_by', 'all'),
71 'date_range' => $this->request->get('date_range', []),
72 'sort_column' => $this->request->get('sort_column', 'id'),
73 'sort_by' => $this->request->get('sort_by', 'DESC'),
74 'per_page' => $this->request->get('per_page', 10),
75 'page' => $this->request->get('page', 1),
76 ]);
77
78 wp_send_json($forms, 200);
79 }
80
81 /**
82 * Create a form from backend/editor
83 *
84 * @return void|array
85 */
86 public function store($returnJSON = true)
87 {
88 $type = $this->request->get('type', $this->formType);
89 $title = $this->request->get('title', 'My New Form');
90 $status = $this->request->get('status', 'published');
91 $createdBy = get_current_user_id();
92
93 $now = current_time('mysql');
94
95 $insertData = [
96 'title' => $title,
97 'type' => $type,
98 'status' => $status,
99 'created_by' => $createdBy,
100 'created_at' => $now,
101 'updated_at' => $now,
102 ];
103
104 if ($this->formFields) {
105 $insertData['form_fields'] = $this->formFields;
106 }
107
108 if ($this->hasPayment) {
109 $insertData['has_payment'] = $this->hasPayment;
110 }
111
112 $formId = $this->model->insertGetId($insertData);
113
114 // Rename the form name here
115 wpFluent()->table('fluentform_forms')->where('id', $formId)->update([
116 'title' => $title . ' (#' . $formId . ')',
117 ]);
118
119 if ($this->metas && is_array($this->metas)) {
120 foreach ($this->metas as $meta) {
121 $meta['value'] = trim(preg_replace('/\s+/', ' ', $meta['value']));
122
123 wpFluent()->table('fluentform_form_meta')
124 ->insert([
125 'form_id' => $formId,
126 'meta_key' => $meta['meta_key'],
127 'value' => $meta['value'],
128 ]);
129 }
130 } else {
131 // add default form settings now
132 $defaultSettings = $this->defaultSettings ?: $this->getFormsDefaultSettings($formId);
133
134 $defaultSettings = apply_filters_deprecated(
135 'fluentform_create_default_settings',
136 [
137 $defaultSettings
138 ],
139 FLUENTFORM_FRAMEWORK_UPGRADE,
140 'fluentform/create_default_settings',
141 'Use fluentform/create_default_settings instead of fluentform_create_default_settings.'
142 );
143
144 $defaultSettings = apply_filters('fluentform/create_default_settings', $defaultSettings);
145
146 wpFluent()->table('fluentform_form_meta')
147 ->insert([
148 'form_id' => $formId,
149 'meta_key' => 'formSettings',
150 'value' => json_encode($defaultSettings),
151 ]);
152
153 if ($this->defaultNotifications) {
154 wpFluent()->table('fluentform_form_meta')
155 ->insert([
156 'form_id' => $formId,
157 'meta_key' => 'notifications',
158 'value' => json_encode($this->defaultNotifications),
159 ]);
160 }
161 }
162
163 do_action_deprecated(
164 'fluentform_inserted_new_form',
165 [
166 $formId,
167 $insertData
168 ],
169 FLUENTFORM_FRAMEWORK_UPGRADE,
170 'fluentform/inserted_new_form',
171 'Use fluentform/inserted_new_form instead of fluentform_inserted_new_form.'
172 );
173
174 do_action('fluentform/inserted_new_form', $formId, $insertData);
175
176 $data = [
177 'formId' => $formId,
178 'redirect_url' => admin_url('admin.php?page=fluent_forms&form_id=' . $formId . '&route=editor'),
179 'message' => __('Successfully created a form.', 'fluentform'),
180 ];
181
182 if ($returnJSON) {
183 wp_send_json_success($data, 200);
184 }
185
186 return $data;
187 }
188
189 public function getFormsDefaultSettings($formId = false)
190 {
191 $defaultSettings = [
192 'confirmation' => [
193 'redirectTo' => 'samePage',
194 'messageToShow' => __('Thank you for your message. We will get in touch with you shortly.', 'fluentform'),
195 'customPage' => null,
196 'samePageFormBehavior' => 'hide_form',
197 'customUrl' => null,
198 ],
199 'restrictions' => [
200 'limitNumberOfEntries' => [
201 'enabled' => false,
202 'numberOfEntries' => null,
203 'period' => 'total',
204 'limitReachedMsg' => 'Maximum number of entries exceeded.',
205 ],
206 'scheduleForm' => [
207 'enabled' => false,
208 'start' => null,
209 'end' => null,
210 'selectedDays' => null,
211 'pendingMsg' => __('Form submission is not started yet.', 'fluentform'),
212 'expiredMsg' => __('Form submission is now closed.', 'fluentform'),
213 ],
214 'requireLogin' => [
215 'enabled' => false,
216 'requireLoginMsg' => 'You must be logged in to submit the form.',
217 ],
218 'denyEmptySubmission' => [
219 'enabled' => false,
220 'message' => __('Sorry, you cannot submit an empty form. Let\'s hear what you wanna say.', 'fluentform'),
221 ],
222 ],
223 'layout' => [
224 'labelPlacement' => 'top',
225 'helpMessagePlacement' => 'with_label',
226 'errorMessagePlacement' => 'inline',
227 'cssClassName' => '',
228 'asteriskPlacement' => 'asterisk-right'
229 ],
230 'delete_entry_on_submission' => 'no',
231 ];
232
233 if ($formId) {
234 $value = $this->getMeta($formId, 'formSettings', true);
235 if ($value) {
236 $defaultSettings = wp_parse_args($value, $defaultSettings);
237 }
238 } else {
239 $globalSettings = get_option('_fluentform_global_form_settings');
240 if (isset($globalSettings['layout'])) {
241 $defaultSettings['layout'] = $globalSettings['layout'];
242 }
243 }
244
245 return $defaultSettings;
246 }
247
248 public function getAdvancedValidationSettings($formId)
249 {
250 $settings = [
251 'status' => false,
252 'type' => 'all',
253 'conditions' => [
254 [
255 'field' => '',
256 'operator' => '=',
257 'value' => '',
258 ],
259 ],
260 'error_message' => '',
261 'validation_type' => 'fail_on_condition_met',
262 ];
263
264 $metaSettings = $this->getMeta($formId, 'advancedValidationSettings', true);
265
266 if ($metaSettings && is_array($metaSettings)) {
267 $settings = wp_parse_args($metaSettings, $settings);
268 }
269
270 return $settings;
271 }
272
273 public function getMeta($formId, $metaKey, $isJson = true)
274 {
275 $settingsMeta = wpFluent()->table('fluentform_form_meta')
276 ->where('form_id', $formId)
277 ->where('meta_key', $metaKey)
278 ->first();
279 if ($settingsMeta) {
280 if ($isJson) {
281 return \json_decode($settingsMeta->value, true);
282 } else {
283 return $settingsMeta->value;
284 }
285 }
286 return false;
287 }
288
289 public function updateMeta($formId, $metaKey, $metaValue)
290 {
291 $exist = wpFluent()->table('fluentform_form_meta')
292 ->where('form_id', $formId)
293 ->where('meta_key', $metaKey)
294 ->first();
295
296 if (is_array($metaValue) || is_object($metaValue)) {
297 $metaValue = \json_encode($metaValue);
298 }
299
300 if ($exist) {
301 return wpFluent()->table('fluentform_form_meta')
302 ->where('id', $exist->id)
303 ->update([
304 'value' => $metaValue,
305 ]);
306 }
307
308 return wpFluent()->table('fluentform_form_meta')->insertGetId([
309 'form_id' => $formId,
310 'meta_key' => $metaKey,
311 'value' => $metaValue,
312 ]);
313 }
314
315 public function deleteMeta($formId, $metaKey)
316 {
317 return wpFluent()->table('fluentform_form_meta')
318 ->where('form_id', $formId)
319 ->where('meta_key', $metaKey)
320 ->delete();
321 }
322
323 /**
324 * Find/Read a from from the database
325 */
326 public function find()
327 {
328 $form = $this->fetchForm($this->request->get('formId'));
329 wp_send_json(['form' => $form, 'metas' => []], 200);
330 }
331
332 /**
333 * Fetch a from from the database
334 * Note: required for ninja-tables
335 *
336 * @return mixed
337 */
338 public function fetchForm($formId)
339 {
340 return $this->model->find($formId);
341 }
342
343 /**
344 * Save/update a form from backend/editor
345 */
346 public function update()
347 {
348 $formId = $this->request->get('formId');
349 $title = sanitize_text_field($this->request->get('title'));
350 $status = $this->request->get('status', 'published');
351
352 $this->validate();
353
354 $data = [
355 'title' => $title,
356 'status' => $status,
357 'updated_at' => current_time('mysql'),
358 ];
359
360 if ($formFields = $this->request->get('formFields')) {
361 $formFields = apply_filters_deprecated(
362 'fluentform_form_fields_update',
363 [
364 $formFields,
365 $formId
366 ],
367 FLUENTFORM_FRAMEWORK_UPGRADE,
368 'fluentform/form_fields_update',
369 'Use fluentform/form_fields_update instead of fluentform_form_fields_update.'
370 );
371 $formFields = apply_filters('fluentform/form_fields_update', $formFields, $formId);
372 $formFields = $this->sanitizeFields($formFields);
373 $data['form_fields'] = $formFields;
374 }
375
376 $this->model->where('id', $formId)->update($data);
377
378 $form = $this->fetchForm($formId);
379
380 if (FormFieldsParser::hasPaymentFields($form)) {
381 $this->model->where('id', $formId)->update([
382 'has_payment' => 1,
383 ]);
384 } elseif ($form->has_payment) {
385 $this->model->where('id', $formId)->update([
386 'has_payment' => 0,
387 ]);
388 }
389
390 $emailInputs = FormFieldsParser::getElement($form, ['input_email'], ['element', 'attributes']);
391 if ($emailInputs) {
392 $emailInput = array_shift($emailInputs);
393 $emailInputName = ArrayHelper::get($emailInput, 'attributes.name');
394 $this->updateMeta($formId, '_primary_email_field', $emailInputName);
395 } else {
396 $this->updateMeta($formId, '_primary_email_field', '');
397 }
398
399 wp_send_json([
400 'message' => __('The form is successfully updated.', 'fluentform'),
401 ], 200);
402 }
403
404 private function sanitizeFields($formFields)
405 {
406 if (fluentformCanUnfilteredHTML()) {
407 return $formFields;
408 }
409
410 $fieldsArray = json_decode($formFields, true);
411
412 if (isset($fieldsArray['submitButton'])) {
413 $fieldsArray['submitButton']['settings']['button_ui']['text'] = fluentform_sanitize_html($fieldsArray['submitButton']['settings']['button_ui']['text']);
414 if (!empty($fieldsArray['submitButton']['settings']['button_ui']['img_url'])) {
415 $fieldsArray['submitButton']['settings']['button_ui']['img_url'] = sanitize_url($fieldsArray['submitButton']['settings']['button_ui']['img_url']);
416 }
417 }
418
419 $fieldsArray['fields'] = $this->sanitizeFieldMaps($fieldsArray['fields']);
420
421 return json_encode($fieldsArray);
422 }
423
424 private function sanitizeFieldMaps($fields)
425 {
426 if (!is_array($fields)) {
427 return $fields;
428 }
429
430 $attributesMap = [
431 'name' => 'sanitize_key',
432 'value' => 'sanitize_textarea_field',
433 'id' => 'sanitize_key',
434 'class' => 'sanitize_text_field',
435 'placeholder' => 'sanitize_text_field',
436 ];
437 $attributesKeys = array_keys($attributesMap);
438 $settingsMap = [
439 'container_class' => 'sanitize_text_field',
440 'label' => 'wp_kses_post',
441 'label_placement' => 'sanitize_text_field',
442 'help_message' => 'wp_kses_post',
443 'admin_field_label' => 'sanitize_text_field',
444 'prefix_label' => 'sanitize_text_field',
445 'suffix_label' => 'sanitize_text_field',
446 'unique_validation_message' => 'sanitize_text_field',
447 'advanced_options' => 'fluentform_options_sanitize',
448 'html_codes' => 'fluentform_sanitize_html',
449 ];
450 $settingsKeys = array_keys($settingsMap);
451 $stylePrefMap = [
452 'layout' => 'sanitize_key',
453 'media' => 'sanitize_url',
454 'alt_text' => 'sanitize_text_field',
455 ];
456 $stylePrefKeys = array_keys($stylePrefMap);
457
458 foreach ($fields as $fieldIndex => $field) {
459 $element = ArrayHelper::get($field, 'element');
460
461 if ('container' == $element) {
462 $columns = $field['columns'];
463 foreach ($columns as $columnIndex => $column) {
464 $fields[$fieldIndex]['columns'][$columnIndex]['fields'] = $this->sanitizeFieldMaps($column['fields']);
465 }
466 return $fields;
467 }
468
469 /*
470 * Handle Name or address fields
471 */
472 if (!empty($field['fields'])) {
473 $fields[$fieldIndex]['fields'] = $this->sanitizeFieldMaps($field['fields']);
474 return $fields;
475 }
476
477 if (!empty($field['attributes'])) {
478 $attributes = array_filter(ArrayHelper::only($field['attributes'], $attributesKeys));
479 foreach ($attributes as $key => $value) {
480 $fields[$fieldIndex]['attributes'][$key] = call_user_func($attributesMap[$key], $value);
481 }
482 }
483
484 if (!empty($field['settings'])) {
485 $settings = array_filter(ArrayHelper::only($field['settings'], $settingsKeys));
486 foreach ($settings as $key => $value) {
487 $fields[$fieldIndex]['settings'][$key] = call_user_func($settingsMap[$key], $value);
488 }
489 }
490
491 if (!empty($field['style_pref'])) {
492 $settings = array_filter(ArrayHelper::only($field['style_pref'], $stylePrefKeys));
493 foreach ($settings as $key => $value) {
494 $fields[$fieldIndex]['style_pref'][$key] = call_user_func($stylePrefMap[$key], $value);
495 }
496 }
497 }
498
499 return $fields;
500 }
501
502 /**
503 * Delete a from from database
504 */
505 public function delete()
506 {
507 $formId = $this->request->get('formId');
508
509 $this->model->where('id', $formId)->delete();
510
511 $maybeErrors = $this->deleteFormAssests($formId);
512
513 wp_send_json([
514 'message' => __('Successfully deleted the form.', 'fluentform'),
515 'errors' => $maybeErrors,
516 ], 200);
517 }
518
519 protected function deleteFormAssests($formId)
520 {
521 // Now Let's delete associate items
522 wpFluent()->table('fluentform_submissions')
523 ->where('form_id', $formId)
524 ->delete();
525
526 wpFluent()->table('fluentform_submission_meta')
527 ->where('form_id', $formId)
528 ->delete();
529
530 wpFluent()->table('fluentform_entry_details')
531 ->where('form_id', $formId)
532 ->delete();
533
534 wpFluent()->table('fluentform_form_meta')
535 ->where('form_id', $formId)
536 ->delete();
537
538 wpFluent()->table('fluentform_form_analytics')
539 ->where('form_id', $formId)
540 ->delete();
541
542 wpFluent()->table('fluentform_logs')
543 ->where('parent_source_id', $formId)
544 ->whereIn('source_type', ['submission_item', 'form_item', 'draft_submission_meta'])
545 ->delete();
546
547 ob_start();
548 if (PaymentHelper::hasPaymentSettings()) {
549 try {
550 \FluentForm\App\Models\OrderItem::where('form_id', $formId)->delete();
551 \FluentForm\App\Models\Transaction::where('form_id', $formId)->delete();
552 } catch (\Exception $exception) {
553 }
554 }
555
556 $errors = ob_get_clean();
557 return $errors;
558 }
559
560 /**
561 * Duplicate a from
562 */
563 public function duplicate()
564 {
565 $formId = absint($this->request->get('formId'));
566 $form = $this->model->where('id', $formId)->first();
567
568 $data = [
569 'title' => $form->title,
570 'status' => $form->status,
571 'appearance_settings' => $form->appearance_settings,
572 'form_fields' => $form->form_fields,
573 'type' => $form->type,
574 'has_payment' => $form->has_payment,
575 'conditions' => $form->conditions,
576 'created_by' => get_current_user_id(),
577 'created_at' => current_time('mysql'),
578 'updated_at' => current_time('mysql'),
579 ];
580
581 $newFormId = $this->model->insertGetId($data);
582
583 // Rename the form name here
584 wpFluent()->table('fluentform_forms')
585 ->where('id', $newFormId)
586 ->update([
587 'title' => $form->title . ' (#' . $newFormId . ')',
588 ]);
589
590 $formMetas = wpFluent()->table('fluentform_form_meta')
591 ->where('form_id', $formId)
592 ->whereNot('meta_key', ['_total_views'])
593 ->get();
594
595 // Required for duplicating PDF feeds
596 $extras = [];
597
598 foreach ($formMetas as $meta) {
599 if ('notifications' == $meta->meta_key || '_pdf_feeds' == $meta->meta_key) {
600 $extras[$meta->meta_key][] = $meta;
601 continue;
602 }
603 if ("ffc_form_settings_generated_css" == $meta->meta_key || "ffc_form_settings_meta" == $meta->meta_key) {
604 $meta->value = str_replace('ff_conv_app_' . $formId, 'ff_conv_app_' . $newFormId, $meta->value);
605 }
606 $metaData = [
607 'meta_key' => $meta->meta_key,
608 'value' => $meta->value,
609 'form_id' => $newFormId,
610 ];
611
612 wpFluent()->table('fluentform_form_meta')->insert($metaData);
613 }
614
615 $pdfFeedMap = $this->getPdfFeedMap($extras, $newFormId);
616 if (array_key_exists('notifications', $extras)) {
617 $extras = $this->notificationWithPdfMap($extras, $pdfFeedMap);
618 foreach ($extras['notifications'] as $notify) {
619 $notifyData = [
620 'meta_key' => $notify->meta_key,
621 'value' => $notify->value,
622 'form_id' => $newFormId,
623 ];
624 wpFluent()->table('fluentform_form_meta')->insert($notifyData);
625 }
626 }
627
628 do_action_deprecated(
629 'flentform_form_duplicated',
630 [
631 $newFormId
632 ],
633 FLUENTFORM_FRAMEWORK_UPGRADE,
634 'fluentform/form_duplicated',
635 'Use fluentform/form_duplicated instead of flentform_form_duplicated.'
636 );
637
638 do_action('fluentform/form_duplicated', $newFormId);
639
640 wp_send_json([
641 'message' => __('Form has been successfully duplicated.', 'fluentform'),
642 'form_id' => $newFormId,
643 'redirect' => admin_url('admin.php?page=fluent_forms&route=editor&form_id=' . $newFormId),
644 ], 200);
645 }
646
647 /**
648 * Validate a form by form title & for duplicate name attributes
649 */
650 private function validate()
651 {
652 $fields = $this->request->get('formFields');
653 if ($fields) {
654 $duplicates = Helper::getDuplicateFieldNames($fields);
655 if ($duplicates) {
656 $duplicateString = implode(', ', $duplicates);
657 wp_send_json([
658 'title' => sprintf('Name attribute %s has duplicate value.', $duplicateString),
659 ], 422);
660 }
661 }
662
663 if (!sanitize_text_field($this->request->get('title'))) {
664 wp_send_json([
665 'title' => 'The title field is required.',
666 ], 422);
667 }
668 }
669
670 public function convertToConversational()
671 {
672 $formId = $this->request->get('form_id');
673 $form = $this->fetchForm($formId);
674
675 if (!$form) {
676 wp_send_json([
677 'message' => __('Form Not Found! Try Again.', 'fluentform'),
678 ], 422);
679 }
680
681 $conversationalMeta = $this->getMeta($formId, 'is_conversion_form', false);
682
683 $shouldConvert = in_array($conversationalMeta, [false, 'no']);
684
685 if ($shouldConvert) {
686 $formConverted['form_fields'] = \FluentForm\App\Services\FluentConversational\Classes\Converter\Converter::convertExistingForm($form);
687
688 $this->model->where('id', $formId)->update($formConverted);
689
690 $conversationalMetaValue = 'yes';
691 } else {
692 $conversationalMetaValue = 'no';
693 }
694
695 $this->updateMeta($formId, 'is_conversion_form', $conversationalMetaValue);
696
697 wp_send_json_success([
698 'message' => __('Form has been successfully converted.', 'fluentform'),
699 ], 200);
700 }
701
702 private function getAdminPermalink($route, $form)
703 {
704 $baseUrl = admin_url('admin.php?page=fluent_forms');
705 return $baseUrl . '&route=' . $route . '&form_id=' . $form->id;
706 }
707
708 private function getSettingsUrl($form)
709 {
710 $baseUrl = admin_url('admin.php?page=fluent_forms');
711 return $baseUrl . '&form_id=' . $form->id . '&route=settings&sub_route=form_settings#basic_settings';
712 }
713
714
715 /**
716 * Map pdf feed ID to replace with duplicated PDF feed ID when duplicating form
717 *
718 * @param array $extras
719 * @param array $newFormId
720 *
721 * @return array
722 */
723 private function getPdfFeedMap($extras, $newFormId)
724 {
725 $pdfFeedMap = [];
726 if (array_key_exists('_pdf_feeds', $extras)) {
727 foreach ($extras['_pdf_feeds'] as $pdf_feed) {
728 $pdfData = [
729 'meta_key' => $pdf_feed->meta_key,
730 'value' => $pdf_feed->value,
731 'form_id' => $newFormId,
732 ];
733 $pdfFeedMap[$pdf_feed->id] = wpFluent()->table('fluentform_form_meta')->insertGetId($pdfData);
734 }
735 }
736 return $pdfFeedMap;
737 }
738
739 /**
740 * Map notification data with PDF feed map
741 *
742 * @param array $extras
743 * @param array $pdfFeedMap
744 *
745 * @return array
746 */
747 private function notificationWithPdfMap($extras, $pdfFeedMap)
748 {
749 foreach ($extras['notifications'] as $key => $notification) {
750 $notificationValue = json_decode($notification->value);
751 $pdf_attachments = [];
752 if (isset($notificationValue->pdf_attachments) && count($notificationValue->pdf_attachments)) {
753 foreach ($notificationValue->pdf_attachments as $attachment) {
754 $pdf_attachments[] = json_encode($pdfFeedMap[$attachment]);
755 }
756 }
757 $notificationValue->pdf_attachments = $pdf_attachments;
758 $notification->value = json_encode($notificationValue);
759
760 $extras['notifications'][$key] = $notification;
761 }
762 return $extras;
763 }
764
765 public function findFormLocations()
766 {
767 $formId = intval($this->request->get('form_id'));
768
769 $excluded = ['attachment'];
770 $post_types = get_post_types(['show_in_menu' => true], 'objects', 'or');
771 $postTypes = [];
772 foreach($post_types as $post_type) {
773 $postTypeName = $post_type->name;
774 if (in_array($postTypeName, $excluded)) {
775 continue;
776 }
777 $postTypes[] = $postTypeName;
778 }
779
780 $params = array(
781 'post_type' => $postTypes,
782 'posts_per_page' => -1
783 );
784
785 $params = apply_filters_deprecated(
786 'fluentform_find_shortcode_params',
787 [
788 $params
789 ],
790 FLUENTFORM_FRAMEWORK_UPGRADE,
791 'fluentform/find_shortcode_params',
792 'Use fluentform/find_shortcode_params instead of fluentform_find_shortcode_params.'
793 );
794
795 $params = apply_filters('fluentform/find_shortcode_params', $params);
796
797 $formLocations = [];
798 $posts = get_posts($params);
799 foreach($posts as $post) {
800
801 $formIds = self::getShortCodeIds($post->post_content);
802 if(!empty($formIds) && in_array($formId,$formIds)) {
803
804 $postType = get_post_type_object($post->post_type);
805 $formLocations[] = [
806 'id' => $post->ID,
807 'name' => $postType->labels->singular_name,
808 'title' => (empty($post->post_title) ? $post->ID : $post->post_title),
809 'edit_link' => sprintf("%spost.php?post=%s&action=edit", admin_url(), $post->ID),
810 ];
811 }
812 }
813 $data = [
814 'locations' => $formLocations,
815 'status' => !empty($formLocations),
816 ];
817 wp_send_json($data, 200);
818
819 }
820
821 public static function getShortCodeIds($content)
822 {
823 $ids = [];
824 $tag = 'fluentform';
825 $selector = 'id';
826
827 if (function_exists('parse_blocks')) {
828 $parsedBlocks = parse_blocks($content);
829 foreach ($parsedBlocks as $block) {
830 if (!ArrayHelper::exists($block, 'blockName') || ArrayHelper::exists($block, 'attrs.formId')) {
831 continue;
832 }
833 $hasBlock = strpos($block['blockName'], 'fluentfom/guten-block') === 0;
834 if ($hasBlock) {
835 $ids[] = intval($block['attrs']['formId']);
836 }
837 }
838 }
839
840 $hasShortCode = has_shortcode($content, $tag);
841 if(!$hasShortCode){
842 return $ids;
843 }
844
845 preg_match_all('/' . get_shortcode_regex() . '/', $content, $matches, PREG_SET_ORDER);
846 if (empty($matches)) {
847 return $ids;
848 }
849
850
851 foreach ($matches as $shortcode) {
852 if (count($shortcode) >= 2 && $tag === $shortcode[2]) {
853 $parsedCode = str_replace(['[', ']', '&#91;', '&#93;'], '', $shortcode[0]);
854
855 $result = shortcode_parse_atts($parsedCode);
856
857 if (!empty($result[$selector])) {
858 $ids[] = $result[$selector];
859 }
860 }
861 }
862 return $ids;
863 }
864 }
865