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

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

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