PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.11
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.11
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 / Hooks / actions.php

actions.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 6.2.11, at app/Hooks/actions.php

1,269 lines 44.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 defined('ABSPATH') || die;
4
5 use FluentForm\App\Modules\Component\Component;
6 use FluentForm\App\Modules\Acl\Acl;
7 use FluentForm\App\Helpers\Helper;
8 use FluentForm\Framework\Helpers\ArrayHelper;
9
10 /**
11 * All registered action's handlers should be in app\Hooks\Handlers,
12 * addAction is similar to add_action and addCustomAction is just a
13 * wrapper over add_action which will add a prefix to the hook name
14 * using the plugin slug to make it unique in all WordPress plugins,
15 * ex: $app->addCustomAction('foo', ['FooHandler', 'handleFoo']) is
16 * equivalent to add_action('slug-foo', ['FooHandler', 'handleFoo']).
17 */
18
19 /**
20 * Application instance.
21 *
22 * @var $app FluentForm\Framework\Foundation\Application
23 */
24
25 // From MenuProvider.php
26 $app->addAction(
27 'admin_menu',
28 function () use ($app) {
29 (new \FluentForm\App\Modules\Registerer\Menu($app))->register();
30 }
31 );
32
33 $app->addAction(
34 'fluentform/form_application_view_editor',
35 function ($formId) use ($app) {
36 (new \FluentForm\App\Modules\Registerer\Menu($app))->renderEditor($formId);
37 }
38 );
39
40 $app->addAction(
41 'fluentform/form_application_view_settings',
42 function ($formId) use ($app) {
43 (new \FluentForm\App\Modules\Registerer\Menu($app))->renderSettings($formId);
44 }
45 );
46
47 $app->addAction(
48 'fluentform/form_settings_container_form_settings',
49 function ($formId) use ($app) {
50 (new \FluentForm\App\Modules\Registerer\Menu($app))->renderFormSettings($formId);
51 }
52 );
53
54 $app->addAction(
55 'fluentform/global_settings_component_settings',
56 function () use ($app) {
57 (new \FluentForm\App\Modules\Renderer\GlobalSettings\Settings($app))->render();
58 }
59 );
60
61 $app->addAction(
62 'fluentform/global_settings_component_reCaptcha',
63 function () use ($app) {
64 (new \FluentForm\App\Modules\Renderer\GlobalSettings\Settings($app))->render();
65 }
66 );
67
68 $app->addAction(
69 'fluentform/global_settings_component_hCaptcha',
70 function () use ($app) {
71 (new \FluentForm\App\Modules\Renderer\GlobalSettings\Settings($app))->render();
72 }
73 );
74
75 // Register DefaultStyleApplicator on init so it works for REST API requests too
76 add_action('init', function () {
77 new \FluentForm\App\Modules\Form\DefaultStyleApplicator();
78 }, 9);
79
80 // From Backend.php
81 add_action('admin_init', function () use ($app) {
82 (new \FluentForm\App\Modules\Registerer\Menu($app))->reisterScripts();
83 (new \FluentForm\App\Modules\Registerer\AdminBar())->register();
84 (new \FluentForm\App\Modules\Ai\AiController())->boot();
85 (new \FluentForm\App\Modules\Report\ReportHandler())->register($app);
86 }, 9);
87
88 add_action('admin_enqueue_scripts', function () use ($app) {
89 (new \FluentForm\App\Modules\Registerer\Menu($app))->enqueuePageScripts();
90 }, 10);
91
92 // Add Entries Menu
93 $app->addAction('fluentform/form_application_view_entries', function ($form_id) {
94 (new \FluentForm\App\Modules\Entries\EntryViewRenderer())->renderEntries($form_id);
95 });
96
97 $app->addAction('fluentform/after_form_navigation', function ($form_id) use ($app) {
98 (new \FluentForm\App\Modules\Registerer\Menu($app))->addCopyShortcodeButton($form_id);
99 (new \FluentForm\App\Modules\Registerer\Menu($app))->addPreviewButton($form_id);
100 });
101
102 $app->addAction('media_buttons', function () {
103 (new \FluentForm\App\Modules\EditorButtonModule())->addButton();
104 });
105
106 /*
107 * Addons Page
108 */
109 $app->addAction('fluentform/addons_page_render_fluentform_add_ons', function () {
110 (new \FluentForm\App\Modules\AddOnModule())->showFluentAddOns();
111 });
112
113 $app->addAction('fluentform/addons_page_render_suggested_plugins', function () {
114 (new \FluentForm\App\Modules\AddOnModule())->showSuggestedPlugins();
115 });
116
117 $app->addAction('fluentform/global_menu', function () use ($app) {
118 $menu = new \FluentForm\App\Modules\Registerer\Menu($app);
119 $menu->renderGlobalMenu();
120 if ('yes' != get_option('fluentform_scheduled_actions_migrated')) {
121 \FluentForm\Database\Migrations\ScheduledActions::migrate();
122 }
123
124 $hookName = 'fluentform_do_scheduled_tasks';
125 if (!wp_next_scheduled($hookName)) {
126 wp_schedule_event(time(), 'ff_every_five_minutes', $hookName);
127 }
128
129 $emailReportHookName = 'fluentform_do_email_report_scheduled_tasks';
130 if (!wp_next_scheduled($emailReportHookName)) {
131 wp_schedule_event(time(), 'daily', $emailReportHookName);
132 }
133 });
134
135 $app->addAction('wp_dashboard_setup', function () {
136 $acl = new \FluentForm\App\Modules\Acl\Acl();
137
138 if (!$acl::getCurrentUserCapability()) {
139 return;
140 }
141 wp_add_dashboard_widget('fluentform_stat_widget', __('Fluent Forms Latest Form Submissions', 'fluentform'), function () {
142 (new \FluentForm\App\Modules\DashboardWidgetModule())->showStat();
143 }, 10, 1);
144 });
145
146 add_action('admin_init', function () {
147 $disablePages = [
148 'fluent_forms',
149 'fluent_forms_transfer',
150 'fluent_forms_settings',
151 'fluent_forms_add_ons',
152 'fluent_forms_docs',
153 'fluent_forms_all_entries',
154 'msformentries',
155 'fluent_forms_payment_entries',
156 'fluent_forms_reports',
157 ];
158
159 $page = wpFluentForm('request')->get('page');
160
161 if ($page && in_array($page, $disablePages)) {
162 remove_all_actions('admin_notices');
163 \FluentForm\App\Modules\Registerer\ReviewQuery::register();
164 \FluentForm\App\Modules\Registerer\MigrationNotice::register();
165 \FluentForm\App\Modules\Registerer\StripeKeyNotice::register();
166 }
167 });
168
169 add_action('wp_print_scripts', function () {
170 if (is_admin()) {
171 if (\FluentForm\App\Helpers\Helper::isFluentAdminPage()) {
172 $option = get_option('_fluentform_global_form_settings');
173 $isSkip = 'no' == \FluentForm\Framework\Helpers\ArrayHelper::get($option, 'misc.noConflictStatus');
174
175 $isSkip = apply_filters_deprecated(
176 'fluentform_skip_no_conflict',
177 [
178 $isSkip,
179 ],
180 FLUENTFORM_FRAMEWORK_UPGRADE,
181 'fluentform/skip_no_conflict',
182 'Use fluentform/skip_no_conflict instead of fluentform_skip_no_conflict.'
183 );
184
185 $isSkip = apply_filters('fluentform/skip_no_conflict', $isSkip);
186
187 if ($isSkip) {
188 return;
189 }
190
191 global $wp_scripts;
192 if (!$wp_scripts) {
193 return;
194 }
195
196 $pluginUrl = plugins_url();
197 // Get an array of slugs to exclude from dequeue
198 $excludeSlugs = apply_filters('fluentform/exclude_js_slugs_from_dequeue', ['fluentform']);
199
200 foreach ($wp_scripts->queue as $script) {
201 if (!isset($wp_scripts->registered[$script])) {
202 continue;
203 }
204
205 $src = $wp_scripts->registered[$script]->src;
206
207 // Check if the script is in the plugins directory
208 if (false !== strpos($src, $pluginUrl)) {
209 // Only dequeue if none of the exclude slugs are in the script src
210 $shouldDequeue = true;
211 foreach ($excludeSlugs as $slug) {
212 if (false !== strpos($src, $slug)) {
213 $shouldDequeue = false;
214 break;
215 }
216 }
217
218 if ($shouldDequeue) {
219 wp_dequeue_script($wp_scripts->registered[$script]->handle);
220 }
221 }
222 }
223 }
224 }
225 }, 1);
226
227 $app->addAction('fluentform/loading_editor_assets', function ($form) {
228 add_filter('fluentform/editor_init_element_input_name', function ($field) {
229 if (empty($field['settings']['label_placement'])) {
230 $field['settings']['label_placement'] = '';
231 }
232 return $field;
233 });
234
235 add_filter('fluentform/editor_init_element_step_start', function ($item) {
236 if (!isset($item['settings']['progress_layout'])) {
237 $item['settings']['progress_layout'] = 'top';
238 }
239
240 if (!isset($item['settings']['tabs_show_progress_bar'])) {
241 $item['settings']['tabs_show_progress_bar'] = 'no';
242 }
243
244 return $item;
245 });
246
247 $upgradableCheckInputs = [
248 'input_radio',
249 'select',
250 'select_country',
251 'input_checkbox',
252 ];
253 foreach ($upgradableCheckInputs as $upgradeElement) {
254 add_filter('fluentform/editor_init_element_' . $upgradeElement, function ($element) use ($upgradeElement, $form) {
255
256 if (!\FluentForm\Framework\Helpers\ArrayHelper::get($element, 'settings.advanced_options')) {
257 $formattedOptions = [];
258 $oldOptions = \FluentForm\Framework\Helpers\ArrayHelper::get($element, 'options', []);
259 foreach ($oldOptions as $value => $label) {
260 $formattedOptions[] = [
261 'label' => $label,
262 'value' => $value,
263 'calc_value' => '',
264 'image' => '',
265 ];
266 }
267 $element['settings']['advanced_options'] = $formattedOptions;
268 $element['settings']['enable_image_input'] = false;
269 $element['settings']['calc_value_status'] = false;
270 unset($element['options']);
271
272 if ('input_radio' == $upgradeElement || 'input_checkbox' == $upgradeElement) {
273 $element['editor_options']['template'] = 'inputCheckable';
274 }
275 }
276
277 if (!isset($element['settings']['layout_class']) && in_array($upgradeElement, ['input_radio', 'input_checkbox'])) {
278 $element['settings']['layout_class'] = '';
279 }
280
281 if (!isset($element['settings']['dynamic_default_value'])) {
282 $element['settings']['dynamic_default_value'] = '';
283 }
284
285 if ('select_country' != $upgradeElement && !isset($element['settings']['randomize_options'])) {
286 $element['settings']['randomize_options'] = 'no';
287 }
288
289 if ('select' == $upgradeElement && \FluentForm\Framework\Helpers\ArrayHelper::get($element, 'attributes.multiple')) {
290 if (empty($element['settings']['max_selection'])) {
291 $element['settings']['max_selection'] = '';
292 }
293 if (isset($element['settings']['enable_select_2'])) {
294 \FluentForm\Framework\Helpers\ArrayHelper::forget($element, 'settings.enable_select_2');
295 }
296 }
297
298 if (
299 (
300 (
301 'select' == $upgradeElement &&
302 !\FluentForm\Framework\Helpers\ArrayHelper::get($element, 'attributes.multiple')
303 ) ||
304 'select_country' == $upgradeElement
305 ) &&
306 !isset($element['settings']['enable_select_2'])
307 ) {
308 $element['settings']['enable_select_2'] = 'no';
309 }
310
311 if ('select_country' != $upgradeElement && !isset($element['settings']['values_visible'])) {
312 $element['settings']['values_visible'] = false;
313 }
314
315 if ('select' == $upgradeElement && !isset($element['settings']['enable_option_groups'])) {
316 $element['settings']['enable_option_groups'] = 'no';
317 }
318
319 return $element;
320 });
321 }
322
323 $upgradableFileInputs = [
324 'input_file',
325 'input_image',
326 ];
327 foreach ($upgradableFileInputs as $upgradeElement) {
328 add_filter('fluentform/editor_init_element_' . $upgradeElement, function ($element) {
329 if (!isset($element['settings']['upload_file_location'])) {
330 $element['settings']['upload_file_location'] = 'default';
331 }
332 if (!isset($element['settings']['file_location_type'])) {
333 $element['settings']['file_location_type'] = 'follow_global_settings';
334 }
335 if ('input_image' === $element['element']) {
336 if (!isset($element['settings']['enable_crop'])) {
337 $element['settings']['enable_crop'] = 'no';
338 }
339 if (!isset($element['settings']['crop_mode'])) {
340 $element['settings']['crop_mode'] = (
341 isset($element['settings']['enforce_image_dimensions']) &&
342 'yes' === $element['settings']['enforce_image_dimensions']
343 ) ? 'dimensions' : 'ratio';
344 }
345 if (!isset($element['settings']['crop_ratio'])) {
346 $element['settings']['crop_ratio'] = 'free';
347 }
348 if (!isset($element['settings']['enforce_image_dimensions'])) {
349 $element['settings']['enforce_image_dimensions'] = 'no';
350 }
351 if (!isset($element['settings']['crop_width'])) {
352 $element['settings']['crop_width'] = '';
353 }
354 if (!isset($element['settings']['crop_height'])) {
355 $element['settings']['crop_height'] = '';
356 }
357 }
358 return $element;
359 });
360 }
361
362 $prefixSuffixInputs = [
363 'textarea',
364 'input_url',
365 'input_password',
366 ];
367
368 foreach ($prefixSuffixInputs as $inputType) {
369 add_filter('fluentform/editor_init_element_' . $inputType, function ($item) {
370 if (!isset($item['settings']['prefix_label'])) {
371 $item['settings']['prefix_label'] = '';
372 }
373 if (!isset($item['settings']['suffix_label'])) {
374 $item['settings']['suffix_label'] = '';
375 }
376 return $item;
377 });
378 }
379
380 add_filter('fluentform/editor_init_element_gdpr_agreement', function ($element) {
381 if (!isset($element['settings']['required_field_message'])) {
382 $element['settings']['required_field_message'] = '';
383 }
384 return $element;
385 });
386
387 add_filter('fluentform/editor_init_element_input_text', function ($element) {
388 if (!isset($element['attributes']['maxlength'])) {
389 $element['attributes']['maxlength'] = '';
390 }
391 return $element;
392 });
393
394 add_filter('fluentform/editor_init_element_textarea', function ($element) {
395 if (!isset($element['attributes']['maxlength'])) {
396 $element['attributes']['maxlength'] = '';
397 }
398 return $element;
399 });
400
401 add_filter('fluentform/editor_init_element_input_date', function ($item) {
402 if (!isset($item['settings']['date_config'])) {
403 $item['settings']['date_config'] = '';
404 }
405 return $item;
406 });
407
408 add_filter('fluentform/editor_init_element_ratings', function ($item) {
409 if (!isset($item['settings']['icon_source'])) {
410 $item['settings']['icon_source'] = 'preset';
411 }
412
413 if (!isset($item['settings']['icon_type'])) {
414 $item['settings']['icon_type'] = \FluentForm\App\Services\FormBuilder\RatingIcon::DEFAULT_ICON;
415 }
416
417 if (!isset($item['settings']['custom_icon_svg'])) {
418 $item['settings']['custom_icon_svg'] = '';
419 }
420
421 if (!isset($item['settings']['inactive_color'])) {
422 $item['settings']['inactive_color'] = \FluentForm\App\Services\FormBuilder\RatingIcon::DEFAULT_INACTIVE_COLOR;
423 }
424
425 if (!isset($item['settings']['active_color'])) {
426 $item['settings']['active_color'] = \FluentForm\App\Services\FormBuilder\RatingIcon::DEFAULT_ACTIVE_COLOR;
427 }
428
429 return $item;
430 });
431
432 add_filter('fluentform/editor_init_element_container', function ($item) {
433 if (!isset($item['settings']['conditional_logics'])) {
434 $item['settings']['conditional_logics'] = [];
435 }
436
437 if (!isset($item['settings']['container_width'])) {
438 $item['settings']['container_width'] = '';
439 }
440
441 if (!isset($item['settings']['is_width_auto_calc'])) {
442 $item['settings']['is_width_auto_calc'] = true;
443 }
444
445 if (!isset($item['settings']['render_recaptcha_v3_badge'])) {
446 $item['settings']['render_recaptcha_v3_badge'] = false;
447 }
448
449 $shouldSetWidth = !empty($item['columns']) && (!isset($item['columns'][0]['width']) || !$item['columns'][0]['width']);
450
451 if ($shouldSetWidth) {
452 $perColumn = round(100 / count($item['columns']), 2);
453
454 foreach ($item['columns'] as &$column) {
455 $column['width'] = $perColumn;
456 }
457 }
458
459 return $item;
460 });
461
462 add_filter('fluentform/editor_init_element_input_number', function ($item) {
463 if (!isset($item['settings']['number_step'])) {
464 $item['settings']['number_step'] = '';
465 }
466 if (!isset($item['settings']['numeric_formatter'])) {
467 $item['settings']['numeric_formatter'] = '';
468 }
469 if (!isset($item['settings']['prefix_label'])) {
470 $item['settings']['prefix_label'] = '';
471 }
472 if (!isset($item['settings']['suffix_label'])) {
473 $item['settings']['suffix_label'] = '';
474 }
475 if (!isset($item['settings']['mobile_keyboard_type_number'])) {
476 $item['settings']['mobile_keyboard_type_number'] = '';
477 }
478
479 return $item;
480 });
481
482 add_filter('fluentform/editor_init_element_input_mask', function ($item) {
483 if (!isset($item['settings']['mobile_keyboard_type'])) {
484 $item['settings']['mobile_keyboard_type'] = '';
485 }
486 return $item;
487 });
488
489 add_filter('fluentform/editor_init_element_input_email', function ($item) {
490 if (!isset($item['settings']['is_unique'])) {
491 $item['settings']['is_unique'] = 'no';
492 }
493 if (!isset($item['settings']['unique_validation_message'])) {
494 $item['settings']['unique_validation_message'] = __('Email address need to be unique.', 'fluentform');
495 }
496 if (!isset($item['settings']['prefix_label'])) {
497 $item['settings']['prefix_label'] = '';
498 }
499 if (!isset($item['settings']['suffix_label'])) {
500 $item['settings']['suffix_label'] = '';
501 }
502 return $item;
503 });
504
505 add_filter('fluentform/editor_init_element_input_text', function ($item) {
506 if (isset($item['attributes']['data-mask'])) {
507 if (!isset($item['settings']['data-mask-reverse'])) {
508 $item['settings']['data-mask-reverse'] = 'no';
509 }
510 if (!isset($item['settings']['data-clear-if-not-match'])) {
511 $item['settings']['data-clear-if-not-match'] = 'no';
512 }
513 } else {
514 if (!isset($item['settings']['is_unique'])) {
515 $item['settings']['is_unique'] = 'no';
516 }
517 if (!isset($item['settings']['unique_validation_message'])) {
518 $item['settings']['unique_validation_message'] = __('This field value need to be unique.', 'fluentform');
519 }
520 }
521
522 if (!isset($item['settings']['prefix_label'])) {
523 $item['settings']['prefix_label'] = '';
524 }
525 if (!isset($item['settings']['suffix_label'])) {
526 $item['settings']['suffix_label'] = '';
527 }
528 return $item;
529 });
530
531 if ($inputs = \FluentForm\App\Modules\Form\FormFieldsParser::getInputs($form, ['element'])) {
532 foreach ($inputs as $input) {
533 add_filter('fluentform/editor_init_element_' . $input['element'], function ($field) {
534 Helper::resolveValidationRulesGlobalOption($field);
535 return $field;
536 });
537 }
538 }
539
540 add_filter('fluentform/editor_init_element_recaptcha', function ($item, $form) {
541 $item['attributes']['name'] = 'g-recaptcha-response';
542 return $item;
543 }, 10, 2);
544
545 add_filter('fluentform/editor_init_element_hcaptcha', function ($item, $form) {
546 $item['attributes']['name'] = 'h-captcha-response';
547 return $item;
548 }, 10, 2);
549
550 add_filter('fluentform/editor_init_element_turnstile', function ($item, $form) {
551 $item['attributes']['name'] = 'cf-turnstile-response';
552 return $item;
553 }, 10, 2);
554
555 add_filter('fluentform/editor_init_element_address', function ($item) {
556 // Initialize autocomplete provider settings
557 if (!isset($item['settings']['autocomplete_provider'])) {
558 // If google autocomplete setting is enabled, set provider to google
559 if (ArrayHelper::get($item, 'settings.enable_g_autocomplete') === 'yes') {
560 $item['settings']['autocomplete_provider'] = 'google';
561 } else {
562 $item['settings']['autocomplete_provider'] = 'none';
563 }
564 }
565 if (!isset($item['settings']['enable_auto_locate'])) {
566 $item['settings']['enable_auto_locate'] = 'on_click'; // on_load, on_click, no
567 }
568 if (!isset($item['settings']['save_coordinates'])) {
569 $item['settings']['save_coordinates'] = 'no';
570 }
571
572 foreach ($item['fields'] as &$addressField) {
573 if (
574 !isset($addressField['settings']['label_placement']) &&
575 !isset($addressField['settings']['label_placement_options'])
576 ) {
577 $addressField['settings']['label_placement'] = '';
578 $addressField['settings']['label_placement_options'] = [
579 [
580 'value' => '',
581 'label' => __('Default', 'fluentform'),
582 ],
583 [
584 'value' => 'top',
585 'label' => __('Top', 'fluentform'),
586 ],
587 [
588 'value' => 'right',
589 'label' => __('Right', 'fluentform'),
590 ],
591 [
592 'value' => 'bottom',
593 'label' => __('Bottom', 'fluentform'),
594 ],
595 [
596 'value' => 'left',
597 'label' => __('Left', 'fluentform'),
598 ],
599 [
600 'value' => 'hide_label',
601 'label' => __('Hidden', 'fluentform'),
602 ],
603 ];
604 }
605 }
606 return $item;
607 });
608
609 add_filter('fluentform/editor_init_element_gdpr_agreement', function ($item, $form) {
610 $isConversationalForm = Helper::isConversionForm($form->id);
611
612 if ($isConversationalForm) {
613 $item['settings']['tc_agree_text'] = __('I accept', 'fluentform');
614 }
615
616 return $item;
617 }, 10, 2);
618
619 add_filter('fluentform/editor_init_element_terms_and_condition', function ($item, $form) {
620 $isConversationalForm = Helper::isConversionForm($form->id);
621
622 if ($isConversationalForm) {
623 $item['settings']['hide_disagree'] = false;
624 }
625
626 return $item;
627 }, 10, 2);
628 }, 10);
629
630 $app->addAction('fluentform/addons_page_render_fluentform_pdf', function () use ($app) {
631 $url = '';
632 if (!defined('FLUENTFORM_PDF_VERSION')) {
633 $url = wp_nonce_url(
634 self_admin_url('update.php?action=install-plugin&plugin=fluentforms-pdf'),
635 'install-plugin_fluentforms-pdf'
636 );
637 }
638
639 $app->view->render('admin.addons.pdf_promo', [
640 'public_url' => fluentFormMix(),
641 'install_url' => $url,
642 'is_installed' => defined('FLUENTFORM_PDF_VERSION'),
643 ]);
644 });
645
646 $app->addAction('fluentform/installed_by', function ($by) {
647 if (is_string($by) && !get_option('_ff_ins_by')) {
648 update_option('_ff_ins_by', sanitize_text_field($by), 'no');
649 }
650 });
651
652 // from Frontend.php
653 if (defined('WP_ROCKET_VERSION')) {
654 add_filter('rocket_excluded_inline_js_content', function ($lines) {
655 $lines[] = 'fluent_form_ff_form_instance';
656 $lines[] = 'fluentFormVars';
657 $lines[] = 'fluentform_payment';
658
659 return $lines;
660 });
661 }
662
663 // from Common.php
664 add_action('save_post', function ($post_id) use ($app) {
665
666 if (!is_post_type_viewable(get_post_type($post_id))) {
667 return;
668 }
669
670 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verified by WordPress save_post action
671 $post_content = isset($_REQUEST['post_content']) ? wp_kses_post(wp_unslash($_REQUEST['post_content'])) : false;
672 if (!$post_content || !is_string($post_content)) {
673 $post = get_post($post_id);
674 $post_content = $post->post_content;
675 }
676
677 $shortcodeIds = Helper::getShortCodeIds(
678 $post_content,
679 'fluentform',
680 'id'
681 );
682
683 $attributes = ArrayHelper::get($shortcodeIds, 'attributes', []);
684 ArrayHelper::forget($shortcodeIds, 'attributes');
685
686 $shortcodeModalIds = Helper::getShortCodeIds(
687 $post_content,
688 'fluentform_modal',
689 'form_id'
690 );
691
692 $gutenbergIds = Helper::getFormsIdsFromBlocks($post_content);
693
694 if ($shortcodeModalIds) {
695 $modalAttributes = ArrayHelper::get($shortcodeModalIds, 'attributes', []);
696 ArrayHelper::forget($shortcodeModalIds, 'attributes');
697
698 $shortcodeIds = array_merge($shortcodeIds, $shortcodeModalIds);
699
700 if ($modalAttributes) {
701 $attributes = array_merge($attributes, $modalAttributes);
702 }
703 }
704
705 if ($gutenbergIds) {
706 $blockAttributes = ArrayHelper::get($gutenbergIds, 'attributes', []);
707 ArrayHelper::forget($gutenbergIds, 'attributes');
708
709 $shortcodeIds = array_merge($shortcodeIds, $gutenbergIds);
710
711 if ($blockAttributes) {
712 $attributes = array_merge($attributes, $blockAttributes);
713 }
714 }
715
716 $shortcodeIds = array_unique($shortcodeIds);
717
718 if ($attributes) {
719 $data = [];
720
721 foreach ($attributes as $attribute) {
722 $data[$attribute['formId']]['themes'][] = $attribute['theme'];
723 }
724
725 $shortcodeIds['attributes'] = $data;
726 }
727
728 if ($shortcodeIds) {
729 update_post_meta($post_id, '_has_fluentform', $shortcodeIds);
730 } elseif (get_post_meta($post_id, '_has_fluentform', true)) {
731 update_post_meta($post_id, '_has_fluentform', []);
732 }
733 });
734
735 $fluentformComponent = new Component($app);
736 $fluentformComponent->addRendererActions();
737 $fluentformComponent->addFluentFormShortCode();
738 $fluentformComponent->addFluentFormDefaultValueParser();
739 $fluentformComponent->addFluentformSubmissionInsertedFilter();
740 $fluentformComponent->addIsRenderableFilter();
741 $fluentformComponent->registerInputSanitizers();
742
743 add_action('wp', function () use ($app) {
744 // @todo: We will remove the fluentform_pages check from April 2021
745 $fluentFormPages = $app->request->get('fluent_forms_pages') || $app->request->get('fluentform_pages');
746
747 if ($fluentFormPages) {
748 add_action('wp_enqueue_scripts', function () use ($app) {
749 wp_enqueue_script('jquery');
750 wp_enqueue_script(
751 'fluent_forms_global',
752 fluentFormMix('js/fluent_forms_global.js'),
753 ['jquery'],
754 FLUENTFORM_VERSION,
755 true
756 );
757 $globalVars = [
758 'ajaxurl' => Helper::getAjaxUrl(),
759 'global_search_active' => apply_filters('fluentform/global_search_active', 'yes'),
760 'rest' => Helper::getRestInfo(),
761 ];
762 if (Acl::hasAnyFormPermission()) {
763 $globalVars['fluent_forms_admin_nonce'] = wp_create_nonce('fluent_forms_admin_nonce');
764 }
765 wp_localize_script('fluent_forms_global', 'fluent_forms_global_var', $globalVars);
766 wp_enqueue_style('fluent-form-styles');
767 $form = wpFluent()->table('fluentform_forms')->find(intval($app->request->get('preview_id')));
768 $postId = get_the_ID() ? get_the_ID() : 0;
769
770 $loadPublicStyle = apply_filters_deprecated(
771 'fluentform_load_default_public',
772 [
773 true,
774 $form,
775 $postId,
776 ],
777 FLUENTFORM_FRAMEWORK_UPGRADE,
778 'fluentform/load_default_public',
779 'Use fluentform/load_default_public instead of fluentform_load_default_public.'
780 );
781
782 if (apply_filters('fluentform/load_default_public', $loadPublicStyle, $form, $postId)) {
783 wp_enqueue_style('fluentform-public-default');
784 }
785 wp_enqueue_script('fluent-form-submission');
786 wp_enqueue_style('fluent-form-preview', fluentFormMix('css/preview.css'), [], FLUENTFORM_VERSION);
787 if (!defined('FLUENTFORMPRO')) {
788 wp_enqueue_script(
789 'fluentform-preview_app',
790 fluentFormMix('js/form_preview_app.js'),
791 ['jquery'],
792 FLUENTFORM_VERSION,
793 true
794 );
795
796 wp_localize_script('fluentform-preview_app', 'fluent_preview_var', [
797 'i18n' => \FluentForm\App\Modules\Registerer\TranslationString::getPreviewI18n(),
798 ]);
799 }
800 });
801
802 (new \FluentForm\App\Modules\ProcessExteriorModule())->handleExteriorPages();
803 }
804 }, 1);
805
806 // Register api response log hooks
807 $app->addAction(
808 'fluentform/after_submission_api_response_success',
809 function ($form, $entryId, $data, $feed, $res, $msg = '') {
810 fluentform_after_submission_api_response_success($form, $entryId, $data, $feed, $res, $msg = '');
811 },
812 10,
813 6
814 );
815
816 $app->addAction(
817 'fluentform/after_submission_api_response_failed',
818 function ($form, $entryId, $data, $feed, $res, $msg = '') {
819 fluentform_after_submission_api_response_failed($form, $entryId, $data, $feed, $res, $msg = '');
820 },
821 10,
822 6
823 );
824
825 function fluentform_after_submission_api_response_success($form, $entryId, $data, $feed, $res, $msg = '')
826 {
827 try {
828 $isDev = 'production' != wpFluentForm()->getEnv();
829
830 $isDev = apply_filters_deprecated(
831 'fluentform_api_success_log',
832 [
833 $isDev,
834 $form,
835 $feed,
836 ],
837 FLUENTFORM_FRAMEWORK_UPGRADE,
838 'fluentform/api_success_log',
839 'Use fluentform/api_success_log instead of fluentform_api_success_log.'
840 );
841
842 if (!apply_filters('fluentform/api_success_log', $isDev, $form, $feed)) {
843 return;
844 }
845
846 wpFluent()->table('fluentform_submission_meta')->insert([
847 'response_id' => $entryId,
848 'form_id' => $form->id,
849 'meta_key' => 'api_log',
850 'value' => $msg,
851 'name' => $feed->formattedValue['name'],
852 'status' => 'success',
853 'created_at' => current_time('mysql'),
854 'updated_at' => current_time('mysql'),
855 ]);
856 } catch (Exception $e) {
857 if (defined('WP_DEBUG') && WP_DEBUG) {
858 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Debug logging only when WP_DEBUG is enabled, helps developers troubleshoot shortcode parsing issues
859 error_log($e->getMessage());
860 }
861 return '';
862 }
863 }
864
865 function fluentform_after_submission_api_response_failed($form, $entryId, $data, $feed, $res, $msg = '')
866 {
867 try {
868 $isDev = 'production' != wpFluentForm()->getEnv();
869
870 $isDev = apply_filters_deprecated(
871 'fluentform_api_failed_log',
872 [
873 $isDev,
874 $form,
875 $feed,
876 ],
877 FLUENTFORM_FRAMEWORK_UPGRADE,
878 'fluentform/api_failed_log',
879 'Use fluentform/api_failed_log instead of fluentform_api_failed_log.'
880 );
881
882 if (!apply_filters('fluentform/api_failed_log', $isDev, $form, $feed)) {
883 return;
884 }
885
886 wpFluent()->table('fluentform_submission_meta')->insert([
887 'response_id' => $entryId,
888 'form_id' => $form->id,
889 'meta_key' => 'api_log',
890 'value' => json_encode($res),
891 'name' => $feed->formattedValue['name'],
892 'status' => 'failed',
893 'created_at' => current_time('mysql'),
894 'updated_at' => current_time('mysql'),
895 ]);
896 } catch (Exception $e) {
897 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Intentional logging for debugging
898 error_log($e->getMessage());
899 }
900 }
901
902 $app->addAction('fluentform/before_form_render', function ($form, $atts) {
903 $theme = ArrayHelper::get($atts, 'theme');
904
905 $styles = $theme ? [$theme] : [];
906
907 do_action(
908 'fluentform/load_form_assets',
909 $form->id,
910 $styles
911 );
912 }, 10, 2);
913
914 add_action('fluentform/load_form_assets', function ($formId, $styles = []) {
915 $formAssetLoader = (new \FluentForm\App\Modules\Form\Settings\FormCssJs());
916
917 $formAssetLoader->addCustomCssJs($formId);
918
919 $notLoadedStyles = [];
920
921 foreach ($styles as $style) {
922 if (!did_action('fluent_form/loaded_styler_' . $formId . '_' . $style)) {
923 $notLoadedStyles[] = $style;
924 }
925 }
926
927 // check if already loaded
928 if ($notLoadedStyles) {
929 $formAssetLoader->addStylerCSS($formId, $notLoadedStyles);
930 }
931 }, 10, 2);
932
933 $app->addAction('fluentform/submission_inserted', function ($insertId, $formData, $form) use ($app) {
934 $notificationManager = new \FluentForm\App\Hooks\Handlers\GlobalNotificationHandler($app);
935 $notificationManager->globalNotify($insertId, $formData, $form);
936 }, 10, 3);
937
938 $app->addAction('fluentform/schedule_feed', function ($queueId) use ($app) {
939 $scheduler = $app['fluentFormAsyncRequest'];
940
941 $scheduler->process($queueId);
942 });
943
944 $app->addAction('init', function () use ($app) {
945 new \FluentForm\App\Services\Integrations\MailChimp\MailChimpIntegration($app);
946 new \FluentForm\App\Modules\Form\TokenBasedSpamProtection($app);
947 // Load payment module
948 if (Helper::isPaymentCompatible()) {
949 (new FluentForm\App\Modules\Payments\PaymentHandler())->init();
950 }
951 });
952
953 $app->addAction('fluentform/form_element_start', function ($form) use ($app) {
954 $honeyPot = new \FluentForm\App\Modules\Form\HoneyPot($app);
955 $honeyPot->renderHoneyPot($form);
956
957 $tokenBasedSpamProtection = new \FluentForm\App\Modules\Form\TokenBasedSpamProtection($app);
958 $tokenBasedSpamProtection->renderTokenField($form);
959
960 $cleanTalk = new \FluentForm\App\Modules\Form\CleanTalkHandler();
961 $cleanTalk->setCleanTalkScript();
962 });
963
964 $app->addAction('fluentform/before_insert_submission', function ($insertData, $requestData, $form) use ($app) {
965 $honeyPot = new \FluentForm\App\Modules\Form\HoneyPot($app);
966 $honeyPot->verify($insertData, $requestData, $form->id);
967
968 $tokenBasedSpamProtection = new \FluentForm\App\Modules\Form\TokenBasedSpamProtection($app);
969 $tokenBasedSpamProtection->verify($insertData, $requestData, $form->id);
970 }, 9, 3);
971
972 // Maybe update current user allowed form ids,
973 // if current user has specific form permission and capable to create form
974 $app->addAction('fluentform/inserted_new_form', function ($formId) {
975 \FluentForm\App\Services\Manager\FormManagerService::maybeAddUserAllowedFormIds($formId);
976 });
977
978 add_action('fluentform/log_data', function ($data) use ($app) {
979 $dataLogger = new \FluentForm\App\Modules\Logger\DataLogger($app);
980 $dataLogger->log($data);
981 });
982
983 // Support for third party plugin who do_action this hook on previous way (before 5.0.0 way)
984 // In Fluent Forms 5.0.0 'ff_log_data' add_action replaced with action named 'fluentform/log_data'.
985 // @todo - notify them for updating do_action name 'fluentform/log_data'.
986 // @todo - We will remove bellow add_action after 2 or more version release latter.
987 add_action('ff_log_data', function ($data) use ($app) {
988 $dataLogger = new \FluentForm\App\Modules\Logger\DataLogger($app);
989 $dataLogger->log($data);
990 });
991
992 // widgets
993 add_action('widgets_init', function () {
994 register_widget('FluentForm\App\Modules\Widgets\SidebarWidgets');
995 });
996
997 add_action('wp', function () {
998 global $post;
999
1000 if (!is_a($post, 'WP_Post')) {
1001 return;
1002 }
1003
1004 $fluentFormIds = get_post_meta($post->ID, '_has_fluentform', true);
1005 $attributes = ArrayHelper::get($fluentFormIds, 'attributes', []);
1006
1007 if (isset($fluentFormIds['attributes'])) {
1008 unset($fluentFormIds['attributes']);
1009 }
1010
1011 if ($fluentFormIds && is_array($fluentFormIds)) {
1012 foreach ($fluentFormIds as $formId) {
1013 do_action(
1014 'fluentform/load_form_assets',
1015 $formId,
1016 array_unique(ArrayHelper::get($attributes, $formId . '.themes', []))
1017 );
1018 }
1019 }
1020 });
1021
1022 add_filter('cron_schedules', function ($schedules) {
1023 $schedules['ff_every_five_minutes'] = [
1024 'interval' => 300,
1025 'display' => 'Every 5 minutes (FluentForm)',
1026 ];
1027
1028 return $schedules;
1029 }, 10, 1);
1030
1031 add_action('fluentform_do_scheduled_tasks', 'fluentFormHandleScheduledTasks');
1032 add_action('fluentform_do_email_report_scheduled_tasks', 'fluentFormHandleScheduledEmailReport');
1033
1034 add_action('fluentform/integration_action_result', function ($feed, $status, $note = '') {
1035 if (!isset($feed['scheduled_action_id']) || !$status) {
1036 return;
1037 }
1038 if (!$note) {
1039 $note = $status;
1040 }
1041
1042 if (strlen($note) > 255) {
1043 if (function_exists('mb_substr')) {
1044 $note = mb_substr($note, 0, 251) . '...';
1045 } else {
1046 $note = substr($note, 0, 251) . '...';
1047 }
1048 }
1049
1050 $actionId = intval($feed['scheduled_action_id']);
1051 wpFluent()->table('ff_scheduled_actions')
1052 ->where('id', $actionId)
1053 ->update([
1054 'status' => $status,
1055 'note' => $note,
1056 'updated_at' => current_time('mysql'),
1057 ]);
1058 }, 10, 3);
1059
1060
1061 // Support for third party plugin who do_action this hook on previous way (before 5.0.0 way)
1062 // In Fluent Forms 5.0.0 'ff_integration_action_result' add_action replaced in above action named 'fluentform/integration_action_result'.
1063 // @todo - notify them for updating do_action name 'fluentform/integration_action_result'.
1064 // @todo - We will remove bellow add_action after 2 or more version release latter.
1065 add_action('ff_integration_action_result', function ($feed, $status, $note = '') {
1066 if (!isset($feed['scheduled_action_id']) || !$status) {
1067 return;
1068 }
1069 if (!$note) {
1070 $note = $status;
1071 }
1072
1073 if (strlen($note) > 255) {
1074 if (function_exists('mb_substr')) {
1075 $note = mb_substr($note, 0, 251) . '...';
1076 } else {
1077 $note = substr($note, 0, 251) . '...';
1078 }
1079 }
1080
1081 $actionId = intval($feed['scheduled_action_id']);
1082 wpFluent()->table('ff_scheduled_actions')
1083 ->where('id', $actionId)
1084 ->update([
1085 'status' => $status,
1086 'note' => $note,
1087 ]);
1088 }, 10, 3);
1089
1090 add_action('fluentform/global_notify_completed', function ($insertId, $form) use ($app) {
1091 $isTruncate = apply_filters_deprecated(
1092 'fluentform_truncate_password_values',
1093 [
1094 true,
1095 $form->id,
1096 ],
1097 FLUENTFORM_FRAMEWORK_UPGRADE,
1098 'fluentform/truncate_password_values',
1099 'Use fluentform/truncate_password_values instead of fluentform_truncate_password_values.'
1100 );
1101
1102 if (strpos($form->form_fields, '"element":"input_password"') && apply_filters('fluentform/truncate_password_values', $isTruncate, $form->id)) {
1103 // we have password
1104 (new \FluentForm\App\Services\Integrations\GlobalNotificationService())->cleanUpPassword($insertId, $form);
1105 }
1106 }, 10, 2);
1107
1108 /*
1109 * Elementor Block Init
1110 */
1111
1112 if (defined('ELEMENTOR_VERSION')) {
1113 new \FluentForm\App\Modules\Widgets\ElementorWidget($app);
1114 }
1115 /*
1116 * Oxygen Widget Init
1117 */
1118
1119 add_action('init', function () {
1120 if (class_exists('OxyEl')) {
1121 if (file_exists(FLUENTFORM_DIR_PATH . 'app/Modules/Widgets/OxygenWidget.php')) {
1122 new FluentForm\App\Modules\Widgets\OxygenWidget();
1123 }
1124 }
1125 });
1126
1127 (new FluentForm\App\Services\Integrations\Slack\SlackNotificationActions($app))->register();
1128
1129 /*
1130 * Smartcode parser shortcodes
1131 */
1132
1133 new \FluentForm\App\Services\FormBuilder\Components\CustomSubmitButton();
1134
1135 add_action('enqueue_block_editor_assets', function () {
1136
1137 wp_enqueue_script(
1138 'fluentform-gutenberg-block',
1139 fluentFormMix('js/fluent_gutenblock.js'),
1140 ['wp-element', 'wp-polyfill', 'wp-i18n', 'wp-blocks', 'wp-components','wp-server-side-render', 'wp-block-editor'],
1141 FLUENTFORM_VERSION,
1142 true
1143 );
1144 wp_enqueue_style(
1145 'fluentform-gutenberg-block',
1146 fluentFormMix('css/fluent_gutenblock.css'),
1147 ['wp-edit-blocks'],
1148 FLUENTFORM_VERSION
1149 );
1150
1151 $forms = wpFluent()->table('fluentform_forms')
1152 ->select(['id', 'title'])
1153 ->orderBy('id', 'DESC')
1154 ->get()
1155 ->toArray();
1156
1157 array_unshift($forms, (object) [
1158 'id' => '',
1159 'title' => __('-- Select a form --', 'fluentform'),
1160 ]);
1161
1162 $presets = [
1163 [
1164 'label' => __('Default (Form Styler)', 'fluentform'),
1165 'value' => '',
1166 ],
1167 [
1168 'label' => __('Inherit Theme Style', 'fluentform'),
1169 'value' => 'ffs_inherit_theme',
1170 ],
1171 ];
1172
1173 $presets = apply_filters('fluentform/block_editor_style_presets', $presets);
1174
1175 wp_localize_script('fluentform-gutenberg-block', 'fluentform_block_vars', [
1176 'logo' => fluentFormMix('img/fluent_icon.svg'),
1177 'forms' => $forms,
1178 'style_presets' => $presets,
1179 'theme_style' => apply_filters('fluentform/load_theme_style', false) ? 'ffs_inherit_theme' : '',
1180 'conversational_demo_img' => fluentFormMix('img/conversational-form-demo.png'),
1181 'rest' => Helper::getRestInfo(),
1182 ]);
1183
1184 wp_enqueue_style(
1185 'fluentform-gutenberg-block',
1186 fluentFormMix('css/fluent_gutenblock.css'),
1187 ['wp-edit-blocks'],
1188 FLUENTFORM_VERSION
1189 );
1190 $fluentFormPublicCss = fluentFormMix('css/fluent-forms-public.css');
1191 $fluentFormPublicDefaultCss = fluentFormMix('css/fluentform-public-default.css');
1192
1193 if (is_rtl()) {
1194 $fluentFormPublicCss = fluentFormMix('css/fluent-forms-public-rtl.css');
1195 $fluentFormPublicDefaultCss = fluentFormMix('css/fluentform-public-default-rtl.css');
1196 }
1197
1198 wp_enqueue_style(
1199 'fluent-form-styles',
1200 $fluentFormPublicCss,
1201 [],
1202 FLUENTFORM_VERSION
1203 );
1204
1205 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Checking post ID in admin context
1206 $post_id = isset($_GET['post']) ? (int) $_GET['post'] : 0;
1207 $loadPublicStyle = apply_filters_deprecated(
1208 'fluentform_load_default_public',
1209 [
1210 true,
1211 (object) [],
1212 $post_id,
1213 ],
1214 FLUENTFORM_FRAMEWORK_UPGRADE,
1215 'fluentform/load_default_public',
1216 'Use fluentform/load_default_public instead of fluentform_load_default_public.'
1217 );
1218
1219 if (apply_filters('fluentform/load_default_public', $loadPublicStyle, (object) [], $post_id)) {
1220 wp_enqueue_style(
1221 'fluentform-public-default',
1222 $fluentFormPublicDefaultCss,
1223 [],
1224 FLUENTFORM_VERSION
1225 );
1226 }
1227 });
1228
1229
1230 if (function_exists('register_block_type')) {
1231 add_action('init', function () {
1232 // Use the dedicated GutenbergBlock class for block registration and rendering
1233 \FluentForm\App\Services\Blocks\GutenbergBlock::register();
1234 });
1235 }
1236
1237
1238 add_action('fluentform/before_updating_form', function ($form, $postData) {
1239 (new FluentForm\App\Services\Form\HistoryService())->init($form, $postData);
1240 }, 10, 2);
1241
1242
1243 // WordPress 6.3+ uses iframes for block editor preview
1244 // Official WordPress solution: Use enqueue_block_assets with proper context checking
1245 // See: https://make.wordpress.org/core/2023/07/18/miscellaneous-editor-changes-in-wordpress-6-3/
1246 add_action('enqueue_block_assets', function () {
1247 // enqueue_block_assets also fires on the front end, where wp_enqueue_scripts already loads these conditionally.
1248 if (!is_admin()) {
1249 return;
1250 }
1251
1252 $current_screen = function_exists('get_current_screen') ? get_current_screen() : null;
1253 if ($current_screen && !$current_screen->is_block_editor()) {
1254 return;
1255 }
1256
1257 // Enqueue Fluent Forms CSS for block editor iframe preview
1258 // These styles are necessary for the live form preview in the block editor
1259 wp_enqueue_style('fluent-forms-public', fluentFormMix('css/fluent-forms-public.css'), [], FLUENTFORM_VERSION);
1260 wp_enqueue_style('fluentform-public-default', fluentFormMix('css/fluentform-public-default.css'), [], FLUENTFORM_VERSION);
1261 });
1262
1263
1264
1265 // require the CLI
1266 if (defined('WP_CLI') && WP_CLI) {
1267 \WP_CLI::add_command('fluentform', '\FluentForm\App\Modules\CLI\Commands');
1268 }
1269