PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.14
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.14
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.14, at app/Modules/Form/Form.php

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