PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.26.1
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.26.1
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.26.1, at classes/helpers/FrmOnSubmitHelper.php

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