PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.33
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.33
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
formidable / classes / helpers / FrmOnSubmitHelper.php

FrmOnSubmitHelper.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 6.33, at classes/helpers/FrmOnSubmitHelper.php

478 lines 14.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * On Submit action helper
4 *
5 * @package Formidable
6 *
7 * @since 6.0
8 */
9
10 if ( ! defined( 'ABSPATH' ) ) {
11 die( 'You are not allowed to call this page directly.' );
12 }
13
14 class FrmOnSubmitHelper {
15
16 /**
17 * Shows message settings.
18 *
19 * @param array $args {
20 * The args.
21 *
22 * @type object $form_action Form action post data.
23 * @type FrmFormAction $action_control Form action object.
24 * @type object $form Form data.
25 * @type string $action_key Action key.
26 * @type array $values Contains `fields` (form fields) and `id` (form ID).
27 * }
28 *
29 * @return void
30 */
31 public static function show_message_settings( $args ) {
32 $id_attr = $args['action_control']->get_field_id( 'success_msg' );
33 // phpcs:disable Generic.WhiteSpace.ScopeIndent
34 ?>
35 <div class="frm_form_field frm_has_shortcodes frm-mt-sm">
36 <label for="<?php echo esc_attr( $id_attr ); ?>" class="screen-reader-text">
37 <?php esc_html_e( 'Message on submit', 'formidable' ); ?>
38 </label>
39
40 <?php
41 wp_editor(
42 $args['form_action']->post_content['success_msg'],
43 $id_attr,
44 array(
45 'textarea_name' => $args['action_control']->get_field_name( 'success_msg' ),
46 'textarea_rows' => 4,
47 'editor_class' => 'frm_not_email_message',
48 )
49 );
50 ?>
51 </div>
52
53 <?php
54 $id_attr = $args['action_control']->get_field_id( 'show_form' );
55 $name_attr = $args['action_control']->get_field_name( 'show_form' );
56 ?>
57 <div class="frm_form_field frm-h-stack-xs">
58 <?php
59 FrmHtmlHelper::toggle(
60 $id_attr,
61 $name_attr,
62 array(
63 'div_class' => 'with_frm_style frm_toggle',
64 'checked' => ! empty( $args['form_action']->post_content['show_form'] ),
65 'echo' => true,
66 )
67 );
68 ?>
69 <label for="<?php echo esc_attr( $id_attr ); ?>">
70 <?php esc_html_e( 'Show the form with the confirmation message', 'formidable' ); ?>
71 </label>
72 </div>
73 <?php
74 // phpcs:enable Generic.WhiteSpace.ScopeIndent
75 }
76
77 /**
78 * Shows redirect settings.
79 *
80 * @param array $args {
81 * The args.
82 *
83 * @type object $form_action Form action post data.
84 * @type FrmFormAction $action_control Form action object.
85 * @type object $form Form data.
86 * @type string $action_key Action key.
87 * @type array $values Contains `fields` (form fields) and `id` (form ID).
88 * }
89 *
90 * @return void
91 */
92 public static function show_redirect_settings( $args ) {
93 include FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/on_submit_redirect_settings.php';
94 }
95
96 /**
97 * Shows page settings.
98 *
99 * @param array $args {
100 * The args.
101 *
102 * @type object $form_action Form action post data.
103 * @type FrmFormAction $action_control Form action object.
104 * @type object $form Form data.
105 * @type string $action_key Action key.
106 * @type array $values Contains `fields` (form fields) and `id` (form ID).
107 * }
108 *
109 * @return void
110 */
111 public static function show_page_settings( $args ) {
112 $name_attr = $args['action_control']->get_field_name( 'success_page_id' );
113 // phpcs:disable Generic.WhiteSpace.ScopeIndent
114 ?>
115 <div class="frm_form_field frm-mt-xs">
116 <div class="frm_note_style frm-mt-0 frm-mb-md">
117 <?php esc_html_e( 'NOTE: The selected page content will be displayed, but the full page will not be loaded. Traditional URL tracking in Google Analytics and similar tools won\'t register a page load event. If precise tracking is essential, consider using the \'Redirect to URL\' option.', 'formidable' ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong ?>
118 </div>
119 <label for="<?php echo esc_attr( $name_attr ); ?>" class="screen-reader-text">
120 <?php esc_html_e( 'Select a page', 'formidable' ); ?>
121 </label>
122 <?php
123 FrmAppHelper::maybe_autocomplete_pages_options(
124 array(
125 'field_name' => $name_attr,
126 'page_id' => $args['form_action']->post_content['success_page_id'],
127 'placeholder' => __( 'Select a Page', 'formidable' ),
128 )
129 );
130 ?>
131 </div>
132 <?php
133 // phpcs:enable Generic.WhiteSpace.ScopeIndent
134 }
135
136 /**
137 * Gets all active On Submit form actions for form.
138 * This checks and gets data from WordPress cache group `frm_actions` first. It prevents the cache issue if form
139 * action is created during run time. If you use another cache method, please remember to delete the cache in
140 * {@see FrmFormAction::save_settings()}.
141 *
142 * @param int $form_id Form ID.
143 *
144 * @return array
145 */
146 public static function get_actions( $form_id ) {
147 $cache_key = 'frm_on_submit_actions_' . $form_id;
148 $actions = wp_cache_get( $cache_key, 'frm_actions' );
149
150 if ( false !== $actions ) {
151 return $actions;
152 }
153
154 $actions = FrmFormAction::get_action_for_form( $form_id, FrmOnSubmitAction::$slug, array( 'post_status' => 'publish' ) );
155 wp_cache_set( $cache_key, 'frm_actions' );
156 return $actions;
157 }
158
159 /**
160 * Gets On Submit action type (message, redirect or page).
161 *
162 * @param object $action Form action object.
163 *
164 * @return string
165 */
166 public static function get_action_type( $action ) {
167 return $action->post_content['success_action'] ?? self::get_default_action_type();
168 }
169
170 /**
171 * @return string
172 */
173 public static function get_default_action_type() {
174 return 'message';
175 }
176
177 /**
178 * @return string
179 */
180 public static function get_default_msg() {
181 $msg = FrmAppHelper::get_settings()->success_msg;
182 return $msg ? $msg : __( 'Your responses were successfully submitted. Thank you!', 'formidable' );
183 }
184
185 /**
186 * @return string
187 */
188 public static function get_default_redirect_msg() {
189 return __( 'Please wait while you are redirected.', 'formidable' );
190 }
191
192 /**
193 * Gets the default open in new tab message.
194 *
195 * @since 6.3.1
196 *
197 * @return string
198 */
199 public static function get_default_new_tab_msg() {
200 return FrmAppHelper::get_settings()->new_tab_msg;
201 }
202
203 /**
204 * Adds the first On Submit action data to the form options to be saved.
205 *
206 * @param int $form_id Form ID.
207 *
208 * @return void
209 */
210 public static function save_on_submit_settings( $form_id ) {
211 $actions = self::get_actions( $form_id );
212 $first_create_action = null;
213 $first_edit_action = null;
214
215 foreach ( $actions as $action ) {
216 if ( ! $first_create_action && in_array( 'create', $action->post_content['event'], true ) ) {
217 $first_create_action = $action;
218 }
219
220 if ( ! $first_edit_action && in_array( 'update', $action->post_content['event'], true ) ) {
221 $first_edit_action = $action;
222 }
223 }
224
225 $form_options = array();
226 self::populate_on_submit_data( $form_options, $first_create_action );
227
228 if ( method_exists( 'FrmProFormActionsController', 'change_on_submit_action_ops' ) && FrmAppHelper::pro_is_connected() ) {
229 $form_editable = FrmDb::get_var( 'frm_forms', array( 'id' => $form_id ), 'editable' );
230
231 if ( $form_editable ) {
232 self::populate_on_submit_data( $form_options, $first_edit_action, 'update' );
233 }
234 }
235
236 if ( $form_options ) {
237 $_POST['options'] += $form_options;
238 }
239 }
240
241 /**
242 * Populates the On Submit data to form options.
243 *
244 * @param array $form_options Form options.
245 * @param object|null $action Optional. The On Submit action object.
246 * @param string $event Form event. Default is `create`.
247 *
248 * @return void
249 */
250 public static function populate_on_submit_data( &$form_options, $action = null, $event = 'create' ) {
251 $opt = 'update' === $event ? 'edit_' : 'success_';
252
253 if ( ! $action || ! is_object( $action ) ) {
254 $form_options[ $opt . 'action' ] = self::get_default_action_type();
255 $form_options[ $opt . 'msg' ] = self::get_default_msg();
256
257 return;
258 }
259
260 $form_options[ $opt . 'action' ] = $action->post_content['success_action'] ?? 'message';
261
262 switch ( $form_options[ $opt . 'action' ] ) {
263 case 'redirect':
264 $form_options[ $opt . 'url' ] = $action->post_content['success_url'] ?? '';
265 $form_options['open_in_new_tab'] = ! empty( $action->post_content['open_in_new_tab'] );
266 $form_options['redirect_delay'] = ! empty( $action->post_content['redirect_delay'] );
267 $form_options['redirect_delay_time'] = $action->post_content['redirect_delay_time'];
268 $form_options['redirect_delay_msg'] = $action->post_content['redirect_delay_msg'];
269 break;
270
271 case 'page':
272 $form_options[ $opt . 'page_id' ] = $action->post_content['success_page_id'] ?? '';
273 break;
274
275 default:
276 $form_options[ $opt . 'msg' ] = ! empty( $action->post_content['success_msg'] ) ? $action->post_content['success_msg'] : self::get_default_msg();
277 $form_options['show_form'] = ! empty( $action->post_content['show_form'] );
278 }
279 }
280
281 /**
282 * Maybe migrate submit settings from the form options to On Submit action.
283 * This is added after On Submit action is released. This might migrate the frontend editing submit settings too.
284 *
285 * @since 6.1.1
286 *
287 * @param int $form_id Form ID.
288 *
289 * @return void
290 */
291 public static function maybe_migrate_submit_settings_to_action( $form_id ) {
292 $form = FrmDb::get_row( 'frm_forms', array( 'id' => $form_id ), 'options,editable' );
293
294 if ( ! $form ) {
295 return;
296 }
297
298 FrmAppHelper::unserialize_or_decode( $form->options );
299
300 if ( self::form_has_migrated( $form ) ) {
301 return;
302 }
303
304 $form->id = $form_id;
305 $action_type = FrmOnSubmitAction::$slug;
306
307 // Check if form already has form actions to avoid creating duplicates.
308 $has_actions = FrmFormAction::form_has_action_type( $form_id, $action_type );
309
310 if ( $has_actions ) {
311 // Don't migrate again.
312 self::save_migrated_success_actions( $form );
313 return;
314 }
315
316 // Create On Submit action.
317 $base_action = array();
318
319 $base_action['post_type'] = FrmFormActionsController::$action_post_type;
320 $base_action['post_excerpt'] = $action_type;
321 $base_action['post_title'] = FrmOnSubmitAction::get_name();
322 $base_action['menu_order'] = $form_id;
323 $base_action['post_status'] = 'publish';
324 $base_action['post_content'] = array(
325 'event' => array( 'create' ),
326 );
327
328 $action_data = self::get_on_submit_action_data_from_form_options( $form->options );
329
330 // If frontend editing is enabled, migrate its settings too.
331 if ( method_exists( 'FrmProFormActionsController', 'change_on_submit_action_ops' ) && FrmAppHelper::pro_is_connected() && $form->editable ) {
332 $edit_data = self::get_on_submit_action_data_from_form_options( $form->options, 'update' );
333
334 if ( $action_data === $edit_data ) {
335 // Just create one action for both create and update if they are the same.
336 $base_action['post_content']['event'][] = 'update';
337 } else {
338 // Create a separate action for update.
339 $edit_action = $base_action;
340 $edit_action['post_content'] += $edit_data;
341 $edit_action['post_content']['event'] = array( 'update' );
342
343 $edit_action['post_content'] = FrmAppHelper::prepare_and_encode( $edit_action['post_content'] );
344 FrmDb::save_json_post( $edit_action );
345 }
346 }
347
348 $action = $base_action;
349 $action['post_content'] += $action_data;
350
351 $action['post_content'] = FrmAppHelper::prepare_and_encode( $action['post_content'] );
352 FrmDb::save_json_post( $action );
353
354 self::save_migrated_success_actions( $form );
355 }
356
357 /**
358 * Gets On Submit action data from form options to be used for the migration.
359 *
360 * @since 6.1.1
361 *
362 * @param array $form_options Form options.
363 * @param string $event Action event. Accepts `create` or `update`. Default is `create`.
364 *
365 * @return array
366 */
367 private static function get_on_submit_action_data_from_form_options( $form_options, $event = 'create' ) {
368 $opt = 'update' === $event ? 'edit_' : 'success_';
369 $data = array(
370 'success_action' => $form_options[ $opt . 'action' ] ?? self::get_default_action_type(),
371 );
372
373 switch ( $data['success_action'] ) {
374 case 'redirect':
375 $data['success_url'] = $form_options[ $opt . 'url' ] ?? '';
376 break;
377
378 case 'page':
379 $data['success_page_id'] = $form_options[ $opt . 'page_id' ] ?? '';
380 break;
381
382 default:
383 $data['success_msg'] = $form_options[ $opt . 'msg' ] ?? self::get_default_msg();
384 $data['show_form'] = ! empty( $form_options['show_form'] );
385 }
386
387 return $data;
388 }
389
390 /**
391 * Checks if On Submit settings are migrated.
392 *
393 * @since 6.1.1
394 *
395 * @param object $form Form object.
396 *
397 * @return bool
398 */
399 public static function form_has_migrated( $form ) {
400 return ! empty( $form->options['on_submit_migrated'] );
401 }
402
403 /**
404 * @since 6.1.1
405 *
406 * @param object $form Limited form object.
407 *
408 * @return void
409 */
410 private static function save_migrated_success_actions( $form ) {
411 // Options may be an empty string.
412 if ( ! is_array( $form->options ) ) {
413 $form->options = array();
414 }
415 $form->options['on_submit_migrated'] = 1;
416 FrmForm::update( $form->id, array( 'options' => $form->options ) );
417 }
418
419 /**
420 * Gets fallback action, used when no actions match.
421 *
422 * @since 6.1.1
423 *
424 * @param array|string $event Uses 'create' or 'update'.
425 *
426 * @return object
427 */
428 public static function get_fallback_action( $event = 'create' ) {
429 $action = new stdClass();
430 $default_msg = self::get_default_msg();
431
432 if ( current_user_can( 'frm_edit_forms' ) ) {
433 $default_msg .= '<br />';
434 $default_msg .= '<span style="font-weight: 600; font-style: italic;">';
435 $default_msg .= __( 'This is the fallback message. No confirmation actions match your conditional logic, or they are invalid.', 'formidable' );
436 $default_msg .= '</span>';
437 }
438
439 $action->post_content = array(
440 'event' => (array) $event,
441 'success_action' => 'message',
442 'success_msg' => $default_msg,
443 );
444
445 return $action;
446 }
447
448 /**
449 * Gets fallback action after opening the redirect URL in a new tab.
450 *
451 * @since 6.3.1
452 *
453 * @param array|string $event Uses 'create' or 'update'.
454 *
455 * @return object
456 */
457 public static function get_fallback_action_after_open_in_new_tab( $event ) {
458 $action = self::get_fallback_action( $event );
459
460 $action->post_content['success_msg'] = self::get_default_new_tab_msg();
461
462 return $action;
463 }
464
465 /**
466 * Check if the current event has been passed. If not, use create actions.
467 *
468 * @since 6.1.1
469 *
470 * @param array $atts
471 *
472 * @return string
473 */
474 public static function current_event( $atts ) {
475 return ! empty( $atts['action'] ) ? $atts['action'] : 'create';
476 }
477 }
478