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

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