PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.26
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.26
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 / models / FrmFormAction.php

FrmFormAction.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 6.26, at classes/models/FrmFormAction.php

1,074 lines 26.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 die( 'You are not allowed to call this page directly.' );
4 }
5
6 class FrmFormAction {
7
8 /**
9 * Root id for all actions of this type.
10 *
11 * @var string
12 */
13 public $id_base;
14
15 /**
16 * Name for this action type.
17 *
18 * @var string
19 */
20 public $name;
21
22 /**
23 * Name of the option used to store the settings for this action type.
24 *
25 * @var string
26 */
27 public $option_name;
28
29 /**
30 * Option array passed to wp_register_sidebar_widget().
31 *
32 * @var array
33 */
34 public $action_options;
35
36 /**
37 * Option array passed to wp_register_widget_control().
38 *
39 * @var array
40 */
41 public $control_options;
42
43 /**
44 * The ID of the form to evaluate.
45 *
46 * @var int
47 */
48 public $form_id;
49
50 /**
51 * Unique ID number of the current instance.
52 *
53 * @var int
54 */
55 public $number = false;
56
57 /**
58 * Unique ID string of the current instance (id_base-number).
59 *
60 * @var string
61 */
62 public $id = '';
63
64 /**
65 * Set true when we update the data after a POST submit - makes sure we don't do it twice.
66 *
67 * @var bool
68 */
69 public $updated = false;
70
71 // Member functions that you must over-ride.
72
73 /**
74 * This function should check that $new_instance is set correctly.
75 * The newly calculated value of $instance should be returned.
76 * If "false" is returned, the instance won't be saved/updated.
77 *
78 * @param array $new_instance New settings for this instance as input by the user via form().
79 * @param array $old_instance Old settings for this instance.
80 *
81 * @return array Settings to save or bool false to cancel saving
82 */
83 public function update( $new_instance, $old_instance ) {
84 return $new_instance;
85 }
86
87 /**
88 * Echo the settings update form
89 *
90 * @param WP_Post $instance Current settings.
91 * @param array $args
92 *
93 * @return string
94 */
95 public function form( $instance, $args = array() ) {
96 echo '<p class="no-options-widget">' . esc_html__( 'There are no options for this action.', 'formidable' ) . '</p>';
97
98 return 'noform';
99 }
100
101 /**
102 * @return array of the default options
103 */
104 public function get_defaults() {
105 return array();
106 }
107
108 /**
109 * @return array
110 */
111 public function get_switch_fields() {
112 return array();
113 }
114
115 /**
116 * @param object $action
117 * @param object $form
118 *
119 * @return object
120 */
121 public function migrate_values( $action, $form ) {
122 return $action;
123 }
124
125 // Functions you'll need to call.
126
127 /**
128 * PHP5 constructor
129 *
130 * @param string $id_base Optional Base ID for the widget, lower case,
131 * if left empty a portion of the widget's class name will be used. Has to be unique.
132 * @param string $name Name for the widget displayed on the configuration page.
133 * @param array $action_options Optional Passed to wp_register_sidebar_widget().
134 * - description: shown on the configuration page.
135 * - classname.
136 * @param array $control_options Optional Passed to wp_register_widget_control().
137 * - width: required if more than 250px.
138 * - height: currently not used but may be needed in the future.
139 */
140 public function __construct( $id_base, $name, $action_options = array(), $control_options = array() ) {
141 if ( ! defined( 'ABSPATH' ) ) {
142 die( 'You are not allowed to call this page directly.' );
143 }
144
145 $this->id_base = strtolower( $id_base );
146 $this->name = $name;
147 $this->option_name = 'frm_' . $this->id_base . '_action';
148
149 $default_options = array(
150 'classes' => '',
151 'active' => true,
152 'event' => array( 'create' ),
153 'limit' => 1,
154 'force_event' => false,
155 'priority' => 20,
156 'ajax_load' => true,
157 'plugin' => $this->id_base,
158 'tooltip' => $name,
159 'group' => $id_base,
160 'color' => '',
161 'keywords' => '',
162 );
163
164 $action_options = apply_filters( 'frm_' . $id_base . '_action_options', $action_options );
165 $group = $this->get_group( $action_options );
166 $action_options['group'] = $group['id'];
167
168 if ( ! isset( $action_options['color'] ) ) {
169 $colors = array( 'green', 'orange', 'purple' );
170 shuffle( $colors );
171 $action_options['color'] = 'var(--' . reset( $colors ) . ')';
172 }
173
174 $upgrade_class = isset( $action_options['classes'] ) && $action_options['classes'] === 'frm_show_upgrade';
175
176 if ( $action_options['group'] === $id_base ) {
177 $upgrade_class = strpos( $action_options['classes'], 'frm_show_upgrade' ) !== false;
178 $action_options['classes'] = $group['icon'];
179 } elseif ( empty( $action_options['classes'] ) || $upgrade_class ) {
180 $action_options['classes'] = $group['icon'];
181 }
182
183 if ( $upgrade_class ) {
184 $action_options['classes'] .= ' frm_show_upgrade';
185 }
186
187 $this->action_options = wp_parse_args( $action_options, $default_options );
188 $this->control_options = wp_parse_args( $control_options, array( 'id_base' => $this->id_base ) );
189 }
190
191 /**
192 * @param string $id_base
193 * @param string $name
194 * @param array $action_options
195 * @param array $control_options
196 *
197 * @return void
198 */
199 public function FrmFormAction( $id_base, $name, $action_options = array(), $control_options = array() ) {
200 self::__construct( $id_base, $name, $action_options, $control_options );
201 }
202
203 /**
204 * Help to switch old field id by new field id for duplicate form
205 *
206 * @param string $action id of the field that needs to be switched.
207 *
208 * @return string
209 */
210 public function maybe_switch_field_ids( $action ) {
211 $updated_action = apply_filters( 'frm_maybe_switch_field_ids', $action );
212
213 if ( $updated_action === $action ) {
214 $updated_action = FrmFieldsHelper::switch_field_ids( $action );
215 }
216 return $updated_action;
217 }
218
219 /**
220 * @since 4.0
221 *
222 * @param array $action_options
223 *
224 * @return array
225 */
226 protected function get_group( $action_options ) {
227 $groups = FrmFormActionsController::form_action_groups();
228 $group = 'misc';
229
230 if ( isset( $action_options['group'] ) && isset( $groups[ $action_options['group'] ] ) ) {
231 $group = $action_options['group'];
232 } elseif ( isset( $groups[ $this->id_base ] ) ) {
233 $group = $this->id_base;
234 } else {
235 foreach ( $groups as $name => $check_group ) {
236 if ( isset( $check_group['actions'] ) && in_array( $this->id_base, $check_group['actions'] ) ) {
237 $group = $name;
238 break;
239 }
240 }
241 }
242
243 $groups[ $group ]['id'] = $group;
244 return $groups[ $group ];
245 }
246
247 /**
248 * Constructs name attributes for use in form() fields
249 *
250 * This function should be used in form() methods to create name attributes for fields to be saved by update()
251 *
252 * @param string $field_name Field name.
253 * @param string $post_field
254 *
255 * @return string Name attribute for $field_name
256 */
257 public function get_field_name( $field_name, $post_field = 'post_content' ) {
258 $name = $this->option_name . '[' . $this->number . ']';
259 $name .= ( empty( $post_field ) ? '' : '[' . $post_field . ']' );
260 $name .= '[' . $field_name . ']';
261
262 return $name;
263 }
264
265 /**
266 * Constructs id attributes for use in form() fields
267 *
268 * This function should be used in form() methods to create id attributes for fields to be saved by update()
269 *
270 * @param string $field_name Field name.
271 *
272 * @return string ID attribute for $field_name
273 */
274 public function get_field_id( $field_name ) {
275 return $field_name . '_' . $this->number;
276 }
277
278 /**
279 * @param int|string $number
280 *
281 * @return void
282 */
283 public function _set( $number ) {
284 $this->number = $number;
285 $this->id = $this->id_base . '-' . $number;
286 }
287
288 /**
289 * @param false|int|string $form_id
290 *
291 * @return object
292 */
293 public function prepare_new( $form_id = false ) {
294 if ( $form_id ) {
295 $this->form_id = $form_id;
296 }
297
298 $post_content = array();
299 $default_values = $this->get_global_defaults();
300
301 // fill default values
302 $post_content = wp_parse_args( $post_content, $default_values );
303
304 if ( ! isset( $post_content['event'] ) && ! $this->action_options['force_event'] ) {
305 $post_content['event'] = array( reset( $this->action_options['event'] ) );
306 }
307
308 $form_action = array(
309 'post_title' => $this->name,
310 'post_content' => $post_content,
311 'post_excerpt' => $this->id_base,
312 'ID' => '',
313 'post_status' => 'publish',
314 'post_type' => FrmFormActionsController::$action_post_type,
315 'post_name' => $this->form_id . '_' . $this->id_base . '_' . $this->number,
316 'menu_order' => $this->form_id,
317 );
318 unset( $post_content );
319
320 return (object) $form_action;
321 }
322
323 /**
324 * @param int|string $form_id
325 *
326 * @return int|WP_Error
327 */
328 public function create( $form_id ) {
329 $this->form_id = $form_id;
330
331 $action = $this->prepare_new();
332
333 return $this->save_settings( $action );
334 }
335
336 /**
337 * @param int|string $form_id
338 * @param int|string $old_id
339 *
340 * @return void
341 */
342 public function duplicate_form_actions( $form_id, $old_id ) {
343 if ( $form_id == $old_id ) {
344 // don't duplicate the actions if this is a template getting updated
345 return;
346 }
347
348 $this->form_id = $old_id;
349 $actions = $this->get_all( $old_id );
350
351 $this->form_id = $form_id;
352
353 foreach ( $actions as $action ) {
354 $this->duplicate_one( $action, $form_id );
355 unset( $action );
356 }
357 }
358
359 /**
360 * Check if imported action should be created or updated.
361 *
362 * @since 2.0
363 *
364 * @param array $action
365 * @param array $forms
366 *
367 * @return int $post_id
368 */
369 public function maybe_create_action( $action, $forms ) {
370 if ( isset( $action['ID'] ) && is_numeric( $action['ID'] ) && isset( $forms[ $action['menu_order'] ] ) && $forms[ $action['menu_order'] ] === 'updated' ) {
371 // Update action only
372 $action['post_content'] = FrmAppHelper::maybe_json_decode( $action['post_content'] );
373 $post_id = $this->save_settings( $action );
374 } else {
375 // Create action
376 $action['post_content'] = FrmAppHelper::maybe_json_decode( $action['post_content'] );
377 $post_id = $this->duplicate_one( (object) $action, $action['menu_order'] );
378 }
379
380 return $post_id;
381 }
382
383 /**
384 * @param object $action
385 * @param int|string $form_id
386 *
387 * @return int|WP_Error
388 */
389 public function duplicate_one( $action, $form_id ) {
390 global $frm_duplicate_ids;
391
392 $action->menu_order = $form_id;
393 $switch = $this->get_global_switch_fields();
394
395 foreach ( (array) $action->post_content as $key => $val ) {
396 if ( is_numeric( $val ) && isset( $frm_duplicate_ids[ $val ] ) ) {
397 $action->post_content[ $key ] = $frm_duplicate_ids[ $val ];
398 } elseif ( ! is_array( $val ) ) {
399 $action->post_content[ $key ] = FrmFieldsHelper::switch_field_ids( $val );
400 } elseif ( isset( $switch[ $key ] ) && is_array( $switch[ $key ] ) ) {
401 // loop through each value if empty
402 if ( empty( $switch[ $key ] ) ) {
403 $switch[ $key ] = array_keys( $val );
404 }
405
406 foreach ( $switch[ $key ] as $subkey ) {
407 $action->post_content[ $key ] = $this->duplicate_array_walk( $action->post_content[ $key ], $subkey, $val );
408 }
409 }
410
411 unset( $key, $val );
412 }
413 unset( $action->ID );
414
415 return $this->save_settings( $action );
416 }
417
418 /**
419 * @param array $action
420 * @param array|string $subkey
421 * @param mixed $val
422 *
423 * @return array
424 */
425 private function duplicate_array_walk( $action, $subkey, $val ) {
426 global $frm_duplicate_ids;
427
428 if ( is_array( $subkey ) ) {
429 foreach ( $subkey as $subkey2 ) {
430 foreach ( (array) $val as $ck => $cv ) {
431 if ( is_array( $cv ) ) {
432 $action[ $ck ] = $this->duplicate_array_walk( $action[ $ck ], $subkey2, $cv );
433 } elseif ( isset( $cv[ $subkey ] ) && is_numeric( $cv[ $subkey ] ) && isset( $frm_duplicate_ids[ $cv[ $subkey ] ] ) ) {
434 $action[ $ck ][ $subkey ] = $frm_duplicate_ids[ $cv[ $subkey ] ];
435 }
436 }
437 }
438 } else {
439 foreach ( (array) $val as $ck => $cv ) {
440 if ( is_array( $cv ) ) {
441 $action[ $ck ] = $this->duplicate_array_walk( $action[ $ck ], $subkey, $cv );
442 } elseif ( $ck == $subkey && isset( $frm_duplicate_ids[ $cv ] ) ) {
443 $action[ $ck ] = $frm_duplicate_ids[ $cv ];
444 } elseif ( $ck == $subkey ) {
445 $action[ $ck ] = $this->maybe_switch_field_ids( $action[ $ck ] );
446 }
447 }
448 }//end if
449
450 return $action;
451 }
452
453 /**
454 * Deal with changed settings.
455 *
456 * Do NOT over-ride this function
457 *
458 * @param int|string $form_id
459 *
460 * @return array|null
461 */
462 public function update_callback( $form_id ) {
463 $this->form_id = $form_id;
464
465 $all_instances = $this->get_settings();
466
467 // We need to update the data
468 if ( $this->updated ) {
469 return;
470 }
471
472 // phpcs:ignore WordPress.Security.NonceVerification.Missing
473 if ( isset( $_POST[ $this->option_name ] ) && is_array( $_POST[ $this->option_name ] ) ) {
474 // Sanitizing removes scripts and <email> type of values.
475 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
476 $settings = wp_unslash( $_POST[ $this->option_name ] );
477 } else {
478 return;
479 }
480
481 $action_ids = array();
482
483 foreach ( $settings as $number => $new_instance ) {
484 $this->_set( $number );
485
486 $old_instance = $all_instances[ $number ] ?? array();
487
488 if ( ! isset( $new_instance['post_status'] ) ) {
489 $new_instance['post_status'] = 'draft';
490 }
491
492 // settings were never opened, so don't update
493 if ( ! isset( $new_instance['post_title'] ) ) {
494 $this->maybe_update_status( $new_instance, $old_instance );
495 $action_ids[] = $new_instance['ID'];
496 $this->updated = true;
497 continue;
498 }
499
500 $new_instance['post_type'] = FrmFormActionsController::$action_post_type;
501 $new_instance['post_name'] = $this->form_id . '_' . $this->id_base . '_' . $this->number;
502 $new_instance['menu_order'] = $this->form_id;
503 $new_instance['post_date'] = $old_instance->post_date ?? '';
504 $instance = $this->update( $new_instance, $old_instance );
505
506 /**
507 * Filter an action's settings before saving.
508 *
509 * Returning false will effectively short-circuit the widget's ability
510 * to update settings.
511 *
512 * @since 2.0
513 *
514 * @param array $instance The current widget instance's settings.
515 * @param array $new_instance Array of new widget settings.
516 * @param array $old_instance Array of old widget settings.
517 * @param FrmFormAction $form_action FrmFormAction instance.
518 */
519 $instance = apply_filters( 'frm_action_update_callback', $instance, $new_instance, $old_instance, $this );
520
521 $instance['post_content'] = apply_filters( 'frm_before_save_action', $instance['post_content'], $instance, $new_instance, $old_instance, $this );
522 $instance['post_content'] = apply_filters( 'frm_before_save_' . $this->id_base . '_action', $instance['post_content'], $instance, $new_instance, $old_instance, $this );
523
524 if ( false !== $instance ) {
525 $all_instances[ $number ] = $instance;
526 }
527
528 $action_ids[] = $this->save_settings( $instance );
529
530 $this->updated = true;
531 }//end foreach
532
533 return $action_ids;
534 }
535
536 /**
537 * If the status of the action has changed, update it
538 *
539 * @since 3.04
540 *
541 * @param array $new_instance
542 * @param array|stdClass $old_instance
543 *
544 * @return void
545 */
546 protected function maybe_update_status( $new_instance, $old_instance ) {
547 if ( ! is_object( $old_instance ) || $new_instance['post_status'] === $old_instance->post_status ) {
548 return;
549 }
550
551 self::clear_cache();
552 wp_update_post(
553 array(
554 'ID' => $new_instance['ID'],
555 'post_status' => $new_instance['post_status'],
556 )
557 );
558 }
559
560 /**
561 * @param array $settings
562 *
563 * @return int|WP_Error
564 */
565 public function save_settings( $settings ) {
566 self::clear_cache();
567
568 return FrmDb::save_settings( $settings, 'frm_actions' );
569 }
570
571 /**
572 * @param int $id
573 *
574 * @return object|null
575 */
576 public function get_single_action( $id ) {
577 $action = get_post( $id );
578
579 if ( $action ) {
580 $action = $this->prepare_action( $action );
581 $this->_set( $id );
582 }
583
584 return $action;
585 }
586
587 /**
588 * @param int|string $form_id
589 *
590 * @return array
591 */
592 public function get_one( $form_id ) {
593 return $this->get_all( $form_id, 1 );
594 }
595
596 /**
597 * @param int|string $form_id
598 * @param string $type
599 * @param array $atts
600 *
601 * @return array
602 */
603 public static function get_action_for_form( $form_id, $type = 'all', $atts = array() ) {
604 $action_controls = FrmFormActionsController::get_form_actions( $type );
605
606 if ( empty( $action_controls ) ) {
607 // don't continue if there are no available actions
608 return array();
609 }
610
611 if ( 'all' !== $type ) {
612 if ( is_array( $action_controls ) ) {
613 return array();
614 }
615 return $action_controls->get_all( $form_id, $atts );
616 }
617
618 self::prepare_get_action( $atts );
619
620 $limit = self::get_action_limit( $form_id, $atts['limit'] );
621
622 $args = self::action_args( $form_id, $limit );
623 $args['post_status'] = $atts['post_status'];
624 $actions = FrmDb::check_cache( json_encode( $args ), 'frm_actions', $args, 'get_posts' );
625
626 if ( ! $actions ) {
627 return array();
628 }
629
630 $settings = array();
631
632 foreach ( $actions as $action ) {
633 // some plugins/themes are formatting the post_excerpt
634 $action->post_excerpt = sanitize_title( $action->post_excerpt );
635
636 if ( ! isset( $action_controls[ $action->post_excerpt ] ) ) {
637 continue;
638 }
639
640 $action = $action_controls[ $action->post_excerpt ]->prepare_action( $action );
641 $settings[ $action->ID ] = $action;
642
643 if ( count( $settings ) >= $limit ) {
644 break;
645 }
646 }
647
648 if ( 1 === $limit ) {
649 $settings = reset( $settings );
650 }
651
652 return $settings;
653 }
654
655 /**
656 * Get the limit for the number of actions for a single form. By default, this is 99, but
657 * it can be modified with a code snippet.
658 *
659 * @since 6.17 This logic from moved from FrmFormAction::get_action_for_form.
660 *
661 * @param int|string $form_id
662 * @param int|string $limit The unfiltered limit value.
663 *
664 * @return int The filtered limit value.
665 */
666 public static function get_action_limit( $form_id, $limit = 99 ) {
667 $type = 'all';
668 return (int) apply_filters( 'frm_form_action_limit', (int) $limit, compact( 'type', 'form_id' ) );
669 }
670
671 /**
672 * @since 3.04
673 *
674 * @param array $args
675 * @param string $default_status
676 *
677 * @return void
678 */
679 protected static function prepare_get_action( &$args, $default_status = 'publish' ) {
680 if ( is_numeric( $args ) ) {
681 // for reverse compatibility. $limit was changed to $args
682 $args = array(
683 'limit' => $args,
684 );
685 }
686
687 $defaults = array(
688 'limit' => 99,
689 'post_status' => $default_status,
690 );
691 $args = wp_parse_args( $args, $defaults );
692 }
693
694 /**
695 * @param int $action_id
696 * @param string $type
697 *
698 * @return bool|object
699 */
700 public static function get_single_action_type( $action_id, $type ) {
701 if ( ! $type ) {
702 return false;
703 }
704
705 /**
706 * @var FrmFormAction
707 */
708 $action_control = FrmFormActionsController::get_form_actions( $type );
709
710 return $action_control->get_single_action( $action_id );
711 }
712
713 /**
714 * @param int $form_id
715 * @param string $type
716 *
717 * @return bool
718 */
719 public static function form_has_action_type( $form_id, $type ) {
720 $actions = self::get_action_for_form( $form_id, $type );
721 return ! empty( $actions );
722 }
723
724 /**
725 * @param false|int|string $form_id
726 * @param array $atts
727 *
728 * @return array
729 */
730 public function get_all( $form_id = false, $atts = array() ) {
731 if ( is_array( $atts ) && ! isset( $atts['limit'] ) && $this->action_options['limit'] > 99 ) {
732 $atts['limit'] = $this->action_options['limit'];
733 }
734
735 self::prepare_get_action( $atts, 'any' );
736
737 $limit = $atts['limit'];
738
739 if ( $form_id ) {
740 $this->form_id = $form_id;
741 }
742
743 $type = $this->id_base;
744
745 global $frm_vars;
746 $frm_vars['action_type'] = $type;
747
748 add_filter( 'posts_where', 'FrmFormActionsController::limit_by_type' );
749 $query = self::action_args( $form_id, $limit );
750 $query['post_status'] = $atts['post_status'];
751 $query['suppress_filters'] = false;
752
753 $actions = FrmDb::check_cache( json_encode( $query ) . '_type_' . $type, 'frm_actions', $query, 'get_posts' );
754 unset( $query );
755
756 remove_filter( 'posts_where', 'FrmFormActionsController::limit_by_type' );
757
758 if ( empty( $actions ) ) {
759 return array();
760 }
761
762 $settings = array();
763
764 foreach ( $actions as $action ) {
765 if ( count( $settings ) >= $limit ) {
766 continue;
767 }
768
769 $action = $this->prepare_action( $action );
770
771 $settings[ $action->ID ] = $action;
772 }
773
774 if ( 1 === $limit ) {
775 $settings = reset( $settings );
776 }
777
778 return $settings;
779 }
780
781 /**
782 * @param int $form_id
783 * @param int $limit
784 *
785 * @return array
786 */
787 public static function action_args( $form_id = 0, $limit = 99 ) {
788 $args = array(
789 'post_type' => FrmFormActionsController::$action_post_type,
790 'post_status' => 'publish',
791 'numberposts' => $limit,
792 'orderby' => 'title',
793 'order' => 'ASC',
794 );
795
796 if ( $form_id && $form_id != 'all' ) {
797 $args['menu_order'] = $form_id;
798 }
799
800 return $args;
801 }
802
803 /**
804 * @param WP_Post $action
805 *
806 * @return WP_Post
807 */
808 public function prepare_action( $action ) {
809 $action->post_content = (array) FrmAppHelper::maybe_json_decode( $action->post_content );
810 $action->post_excerpt = sanitize_title( $action->post_excerpt );
811
812 $default_values = $this->get_global_defaults();
813
814 // fill default values
815 $action->post_content += $default_values;
816
817 foreach ( $default_values as $k => $vals ) {
818 if ( is_array( $vals ) && ! empty( $vals ) ) {
819 if ( 'event' === $k && ! $this->action_options['force_event'] && ! empty( $action->post_content[ $k ] ) ) {
820 continue;
821 }
822 $action->post_content[ $k ] = wp_parse_args( $action->post_content[ $k ], $vals );
823 }
824 }
825
826 if ( ! is_array( $action->post_content['event'] ) ) {
827 $action->post_content['event'] = explode( ',', $action->post_content['event'] );
828 }
829
830 return $action;
831 }
832
833 /**
834 * @param false|int|string $form_id
835 * @param string $type
836 *
837 * @return void
838 */
839 public function destroy( $form_id = false, $type = 'default' ) {
840 global $wpdb;
841
842 $this->form_id = $form_id;
843
844 $query = array( 'post_type' => FrmFormActionsController::$action_post_type );
845
846 if ( $form_id ) {
847 $query['menu_order'] = $form_id;
848 }
849
850 if ( 'all' != $type ) {
851 $query['post_excerpt'] = $this->id_base;
852 }
853
854 $post_ids = FrmDb::get_col( $wpdb->posts, $query, 'ID' );
855
856 foreach ( $post_ids as $id ) {
857 wp_delete_post( $id );
858 }
859 self::clear_cache();
860 }
861
862 /**
863 * Delete the action cache when a form action is created, deleted, or updated
864 *
865 * @since 2.0.5
866 *
867 * @return void
868 */
869 public static function clear_cache() {
870 FrmDb::cache_delete_group( 'frm_actions' );
871 }
872
873 /**
874 * @return array
875 */
876 public function get_settings() {
877 return self::get_action_for_form( $this->form_id, $this->id_base );
878 }
879
880 /**
881 * @return array
882 */
883 public function get_global_defaults() {
884 $defaults = $this->get_defaults();
885
886 if ( ! isset( $defaults['event'] ) ) {
887 $defaults['event'] = array( 'create' );
888 }
889
890 if ( ! isset( $defaults['conditions'] ) ) {
891 $defaults['conditions'] = array(
892 'send_stop' => '',
893 'any_all' => '',
894 );
895 }
896
897 return $defaults;
898 }
899
900 /**
901 * @return array
902 */
903 public function get_global_switch_fields() {
904 $switch = $this->get_switch_fields();
905 $switch['conditions'] = array( 'hide_field' );
906
907 $switch = apply_filters( 'frm_global_switch_fields', $switch );
908
909 return $switch;
910 }
911
912 /**
913 * Migrate settings from form->options into new action.
914 *
915 * @param object $form
916 * @param string $update
917 *
918 * @return int|WP_Error
919 */
920 public function migrate_to_2( $form, $update = 'update' ) {
921 $action = $this->prepare_new( $form->id );
922 FrmAppHelper::unserialize_or_decode( $form->options );
923
924 // fill with existing options
925 foreach ( $action->post_content as $name => $val ) {
926 if ( isset( $form->options[ $name ] ) ) {
927 $action->post_content[ $name ] = $form->options[ $name ];
928 unset( $form->options[ $name ] );
929 }
930 }
931
932 $action = $this->migrate_values( $action, $form );
933
934 // check if action already exists
935 $post_id = get_posts(
936 array(
937 'name' => $action->post_name,
938 'post_type' => FrmFormActionsController::$action_post_type,
939 'post_status' => $action->post_status,
940 'numberposts' => 1,
941 )
942 );
943
944 if ( empty( $post_id ) ) {
945 // create action now
946 $post_id = $this->save_settings( $action );
947 }
948
949 if ( $post_id && 'update' == $update ) {
950 global $wpdb;
951 $form->options = maybe_serialize( $form->options );
952
953 // update form options
954 $wpdb->update( $wpdb->prefix . 'frm_forms', array( 'options' => $form->options ), array( 'id' => $form->id ) );
955 FrmForm::clear_form_cache();
956 }
957
958 return $post_id;
959 }
960
961 /**
962 * @param WP_Post $action
963 * @param stdClass $entry
964 *
965 * @return bool
966 */
967 public static function action_conditions_met( $action, $entry ) {
968 if ( is_callable( 'FrmProFormActionsController::action_conditions_met' ) ) {
969 return FrmProFormActionsController::action_conditions_met( $action, $entry );
970 }
971
972 $stop = false;
973 return $stop;
974 }
975
976 /**
977 * Get the value from a specific field and entry
978 *
979 * @since 2.01.02
980 *
981 * @param object $entry
982 * @param int $field_id
983 *
984 * @return array|bool|mixed|string
985 */
986 private static function get_value_from_entry( $entry, $field_id ) {
987 $observed_value = '';
988
989 if ( isset( $entry->metas[ $field_id ] ) ) {
990 $observed_value = $entry->metas[ $field_id ];
991 } elseif ( $entry->post_id && FrmAppHelper::pro_is_installed() ) {
992 $field = FrmField::getOne( $field_id );
993 $observed_value = FrmProEntryMetaHelper::get_post_or_meta_value(
994 $entry,
995 $field,
996 array(
997 'links' => false,
998 'truncate' => false,
999 )
1000 );
1001 }
1002
1003 return $observed_value;
1004 }
1005
1006 /**
1007 * @param string $class
1008 *
1009 * @return array
1010 */
1011 public static function default_action_opts( $class = '' ) {
1012 return array(
1013 'classes' => 'frm_icon_font ' . $class,
1014 'active' => false,
1015 'limit' => 0,
1016 );
1017 }
1018
1019 /**
1020 * @return array
1021 */
1022 public static function trigger_labels() {
1023 $triggers = array(
1024 'draft' => __( 'Draft is saved', 'formidable' ),
1025 'create' => __( 'Entry is created', 'formidable' ),
1026 'update' => __( 'Entry is updated', 'formidable' ),
1027 'delete' => __( 'Entry is deleted', 'formidable' ),
1028 'import' => __( 'Entry is imported', 'formidable' ),
1029 );
1030
1031 return apply_filters( 'frm_action_triggers', $triggers );
1032 }
1033
1034 /**
1035 * @return void
1036 */
1037 public function render_conditional_logic_call_to_action() {
1038 ?>
1039 <h3>
1040 <a href="javascript:void(0)" class="frm_show_upgrade frm_noallow" data-upgrade="<?php echo esc_attr( $this->get_upgrade_text() ); ?>" data-medium="conditional-<?php echo esc_attr( $this->id_base ); ?>">
1041 <?php esc_html_e( 'Use Conditional Logic', 'formidable' ); ?>
1042 </a>
1043 </h3>
1044 <?php
1045 }
1046
1047 /**
1048 * @return string
1049 */
1050 protected function get_upgrade_text() {
1051 return __( 'Conditional form actions', 'formidable' );
1052 }
1053
1054 /**
1055 * Gets form fields for form action settings.
1056 *
1057 * @since 6.10
1058 *
1059 * @param int $form_id Form ID.
1060 *
1061 * @return object[]
1062 */
1063 protected function get_form_fields( $form_id ) {
1064 // Get form fields, include embedded and repeater child fields.
1065 $form_fields = FrmField::get_all_for_form( $form_id, '', 'include' );
1066 return array_filter(
1067 $form_fields,
1068 function ( $form_field ) {
1069 return ! FrmField::is_no_save_field( $form_field->type );
1070 }
1071 );
1072 }
1073 }
1074