Completed
Push — master ( 625fa5...d40073 )
by Stephanie
16s queued 11s
created

FrmFormAction::maybe_switch_field_ids()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
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
	public function get_switch_fields() {
54
		return array();
55
	}
56
57
	public function migrate_values( $action, $form ) {
58
		return $action;
59
	}
60
61
	// Functions you'll need to call.
62
63
	/**
64
	 * PHP5 constructor
65
	 *
66
	 * @param string $id_base Optional Base ID for the widget, lower case,
67
	 * if left empty a portion of the widget's class name will be used. Has to be unique.
68
	 * @param string $name Name for the widget displayed on the configuration page.
69
	 * @param array $action_options Optional Passed to wp_register_sidebar_widget()
70
	 *   - description: shown on the configuration page
71
	 *   - classname
72
	 * @param array $control_options Optional Passed to wp_register_widget_control()
73
	 *   - width: required if more than 250px
74
	 *   - height: currently not used but may be needed in the future
75
	 */
76
	public function __construct( $id_base, $name, $action_options = array(), $control_options = array() ) {
77
		if ( ! defined( 'ABSPATH' ) ) {
78
			die( 'You are not allowed to call this page directly.' );
79
		}
80
81
		$this->id_base     = strtolower( $id_base );
82
		$this->name        = $name;
83
		$this->option_name = 'frm_' . $this->id_base . '_action';
84
85
		$default_options = array(
86
			'classes'     => '',
87
			'active'      => true,
88
			'event'       => array( 'create' ),
89
			'limit'       => 1,
90
			'force_event' => false,
91
			'priority'    => 20,
92
			'ajax_load'   => true,
93
			'plugin'      => $this->id_base,
94
			'tooltip'     => $name,
95
			'group'       => $id_base,
96
			'color'       => '',
97
		);
98
99
		$action_options          = apply_filters( 'frm_' . $id_base . '_action_options', $action_options );
100
		$group                   = $this->get_group( $action_options );
101
		$action_options['group'] = $group['id'];
102
103
		if ( ! isset( $action_options['color'] ) ) {
104
			$colors = array( 'green', 'orange', 'purple' );
105
			shuffle( $colors );
106
			$action_options['color'] = 'var(--' . reset( $colors ) . ')';
107
		}
108
109
		$upgrade_class = $action_options['classes'] === 'frm_show_upgrade';
110
		if ( $action_options['group'] === $id_base ) {
111
			$upgrade_class = strpos( $action_options['classes'], 'frm_show_upgrade' ) !== false;
112
			$action_options['classes'] = $group['icon'];
113
		} elseif ( ! isset( $action_options['classes'] ) || empty( $action_options['classes'] ) || $upgrade_class ) {
114
			$action_options['classes'] = $group['icon'];
115
		}
116
117
		if ( $upgrade_class ) {
118
			$action_options['classes'] .= ' frm_show_upgrade';
119
		}
120
121
		$this->action_options  = wp_parse_args( $action_options, $default_options );
122
		$this->control_options = wp_parse_args( $control_options, array( 'id_base' => $this->id_base ) );
123
	}
124
125
	/**
126
	 * @param string $id_base
127
	 */
128
	public function FrmFormAction( $id_base, $name, $action_options = array(), $control_options = array() ) {
129
		self::__construct( $id_base, $name, $action_options, $control_options );
130
	}
131
132
	/**
133
	 * Help to switch old field id by new field id for duplicate form
134
	 *
135
	 * @param  string $action id of the field that needs to be switched
136
	 *
137
	 * @return string
138
	 */
139
	public function maybe_switch_field_ids( $action ) {
140
		$updated_action = apply_filters( 'frm_maybe_switch_field_ids', $action );
141
		if ( $updated_action === $action ) {
142
			$updated_action = FrmFieldsHelper::switch_field_ids( $action );
143
		}
144
		return $updated_action;
145
	}
146
147
	/**
148
	 * @since 4.0
149
	 */
150
	protected function get_group( $action_options ) {
151
		$groups = FrmFormActionsController::form_action_groups();
152
		$group  = 'misc';
153
154
		if ( isset( $action_options['group'] ) && isset( $groups[ $action_options['group'] ] ) ) {
155
			$group = $action_options['group'];
156
		} elseif ( isset( $groups[ $this->id_base ] ) ) {
157
			$group = $this->id_base;
158
		} else {
159
			foreach ( $groups as $name => $check_group ) {
160
				if ( isset( $check_group['actions'] ) && in_array( $this->id_base, $check_group['actions'] ) ) {
161
					$group = $name;
162
					break;
163
				}
164
			}
165
		}
166
167
		$groups[ $group ]['id'] = $group;
168
		return $groups[ $group ];
169
	}
170
171
	/**
172
	 * Constructs name attributes for use in form() fields
173
	 *
174
	 * This function should be used in form() methods to create name attributes for fields to be saved by update()
175
	 *
176
	 * @param string $field_name Field name
177
	 *
178
	 * @return string Name attribute for $field_name
179
	 */
180
	public function get_field_name( $field_name, $post_field = 'post_content' ) {
181
		$name = $this->option_name . '[' . $this->number . ']';
182
		$name .= ( empty( $post_field ) ? '' : '[' . $post_field . ']' );
183
		$name .= '[' . $field_name . ']';
184
185
		return $name;
186
	}
187
188
	/**
189
	 * Constructs id attributes for use in form() fields
190
	 *
191
	 * This function should be used in form() methods to create id attributes for fields to be saved by update()
192
	 *
193
	 * @param string $field_name Field name
194
	 *
195
	 * @return string ID attribute for $field_name
196
	 */
197
	public function get_field_id( $field_name ) {
198
		return $field_name . '_' . $this->number;
199
	}
200
201
	// Private Function. Don't worry about this.
202
203
	public function _set( $number ) {
204
		$this->number = $number;
205
		$this->id     = $this->id_base . '-' . $number;
206
	}
207
208
	public function prepare_new( $form_id = false ) {
209
		if ( $form_id ) {
210
			$this->form_id = $form_id;
211
		}
212
213
		$post_content   = array();
214
		$default_values = $this->get_global_defaults();
215
216
		// fill default values
217
		$post_content = wp_parse_args( $post_content, $default_values );
218
219
		if ( ! isset( $post_content['event'] ) && ! $this->action_options['force_event'] ) {
220
			$post_content['event'] = array( reset( $this->action_options['event'] ) );
221
		}
222
223
		$form_action = array(
224
			'post_title'   => $this->name,
225
			'post_content' => $post_content,
226
			'post_excerpt' => $this->id_base,
227
			'ID'           => '',
228
			'post_status'  => 'publish',
229
			'post_type'    => FrmFormActionsController::$action_post_type,
230
			'post_name'    => $this->form_id . '_' . $this->id_base . '_' . $this->number,
231
			'menu_order'   => $this->form_id,
232
		);
233
		unset( $post_content );
234
235
		return (object) $form_action;
236
	}
237
238
	public function create( $form_id ) {
239
		$this->form_id = $form_id;
240
241
		$action = $this->prepare_new();
242
243
		return $this->save_settings( $action );
244
	}
245
246
	public function duplicate_form_actions( $form_id, $old_id ) {
247
		if ( $form_id == $old_id ) {
248
			// don't duplicate the actions if this is a template getting updated
249
			return;
250
		}
251
252
		$this->form_id = $old_id;
253
		$actions       = $this->get_all( $old_id );
254
255
		$this->form_id = $form_id;
256
		foreach ( $actions as $action ) {
257
			$this->duplicate_one( $action, $form_id );
258
			unset( $action );
259
		}
260
	}
261
262
	/* Check if imported action should be created or updated
263
	 *
264
	 * @since 2.0
265
	 *
266
	 * @param array $action
267
	 * @return integer $post_id
268
	 */
269
	public function maybe_create_action( $action, $forms ) {
270
		if ( isset( $action['ID'] ) && is_numeric( $action['ID'] ) && isset( $forms[ $action['menu_order'] ] ) && $forms[ $action['menu_order'] ] == 'updated' ) {
271
			// Update action only
272
			$action['post_content'] = FrmAppHelper::maybe_json_decode( $action['post_content'] );
273
			$post_id                = $this->save_settings( $action );
274
		} else {
275
			// Create action
276
			$action['post_content'] = FrmAppHelper::maybe_json_decode( $action['post_content'] );
277
			$post_id                = $this->duplicate_one( (object) $action, $action['menu_order'] );
278
		}
279
280
		return $post_id;
281
	}
282
283
	public function duplicate_one( $action, $form_id ) {
284
		global $frm_duplicate_ids;
285
286
		$action->menu_order = $form_id;
287
		$switch             = $this->get_global_switch_fields();
288
289
		foreach ( (array) $action->post_content as $key => $val ) {
290
			if ( is_numeric( $val ) && isset( $frm_duplicate_ids[ $val ] ) ) {
291
				$action->post_content[ $key ] = $frm_duplicate_ids[ $val ];
292
			} elseif ( ! is_array( $val ) ) {
293
				$action->post_content[ $key ] = FrmFieldsHelper::switch_field_ids( $val );
294
			} elseif ( isset( $switch[ $key ] ) && is_array( $switch[ $key ] ) ) {
295
				// loop through each value if empty
296
				if ( empty( $switch[ $key ] ) ) {
297
					$switch[ $key ] = array_keys( $val );
298
				}
299
300
				foreach ( $switch[ $key ] as $subkey ) {
301
					$action->post_content[ $key ] = $this->duplicate_array_walk( $action->post_content[ $key ], $subkey, $val );
302
				}
303
			}
304
305
			unset( $key, $val );
306
		}
307
		unset( $action->ID );
308
309
		return $this->save_settings( $action );
310
	}
311
312
	private function duplicate_array_walk( $action, $subkey, $val ) {
313
		global $frm_duplicate_ids;
314
315
		if ( is_array( $subkey ) ) {
316
			foreach ( $subkey as $subkey2 ) {
317
				foreach ( (array) $val as $ck => $cv ) {
318
					if ( is_array( $cv ) ) {
319
						$action[ $ck ] = $this->duplicate_array_walk( $action[ $ck ], $subkey2, $cv );
320
					} elseif ( isset( $cv[ $subkey ] ) && is_numeric( $cv[ $subkey ] ) && isset( $frm_duplicate_ids[ $cv[ $subkey ] ] ) ) {
321
						$action[ $ck ][ $subkey ] = $frm_duplicate_ids[ $cv[ $subkey ] ];
322
					}
323
				}
324
			}
325
		} else {
326
			foreach ( (array) $val as $ck => $cv ) {
327
				if ( is_array( $cv ) ) {
328
					$action[ $ck ] = $this->duplicate_array_walk( $action[ $ck ], $subkey, $cv );
329
				} elseif ( $ck == $subkey && isset( $frm_duplicate_ids[ $cv ] ) ) {
330
					$action[ $ck ] = $frm_duplicate_ids[ $cv ];
331
				} elseif ( $ck == $subkey ) {
332
					$action[ $ck ] = $this->maybe_switch_field_ids( $action[ $ck ] );
333
				}
334
			}
335
		}
336
337
		return $action;
338
	}
339
340
	/**
341
	 * Deal with changed settings.
342
	 *
343
	 * Do NOT over-ride this function
344
	 */
345
	public function update_callback( $form_id ) {
346
		$this->form_id = $form_id;
347
348
		$all_instances = $this->get_settings();
349
350
		// We need to update the data
351
		if ( $this->updated ) {
352
			return;
353
		}
354
355
		if ( isset( $_POST[ $this->option_name ] ) && is_array( $_POST[ $this->option_name ] ) ) {
356
			// Sanitizing removes scripts and <email> type of values.
357
			// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
358
			$settings = wp_unslash( $_POST[ $this->option_name ] );
359
		} else {
360
			return;
361
		}
362
363
		$action_ids = array();
364
365
		foreach ( $settings as $number => $new_instance ) {
366
			$this->_set( $number );
367
368
			$old_instance = isset( $all_instances[ $number ] ) ? $all_instances[ $number ] : array();
369
370
			if ( ! isset( $new_instance['post_status'] ) ) {
371
				$new_instance['post_status'] = 'draft';
372
			}
373
374
			// settings were never opened, so don't update
375
			if ( ! isset( $new_instance['post_title'] ) ) {
376
				$this->maybe_update_status( $new_instance, $old_instance );
377
				$action_ids[]  = $new_instance['ID'];
378
				$this->updated = true;
379
				continue;
380
			}
381
382
			$new_instance['post_type']  = FrmFormActionsController::$action_post_type;
383
			$new_instance['post_name']  = $this->form_id . '_' . $this->id_base . '_' . $this->number;
384
			$new_instance['menu_order'] = $this->form_id;
385
			$new_instance['post_date']  = isset( $old_instance->post_date ) ? $old_instance->post_date : '';
386
387
			$instance = $this->update( $new_instance, $old_instance );
388
389
			/**
390
			 * Filter an action's settings before saving.
391
			 *
392
			 * Returning false will effectively short-circuit the widget's ability
393
			 * to update settings.
394
			 *
395
			 * @since 2.0
396
			 *
397
			 * @param array $instance The current widget instance's settings.
398
			 * @param array $new_instance Array of new widget settings.
399
			 * @param array $old_instance Array of old widget settings.
400
			 * @param WP_Widget $this The current widget instance.
401
			 */
402
			$instance = apply_filters( 'frm_action_update_callback', $instance, $new_instance, $old_instance, $this );
403
404
			$instance['post_content'] = apply_filters( 'frm_before_save_action', $instance['post_content'], $instance, $new_instance, $old_instance, $this );
405
			$instance['post_content'] = apply_filters( 'frm_before_save_' . $this->id_base . '_action', $new_instance['post_content'], $instance, $new_instance, $old_instance, $this );
406
407
			if ( false !== $instance ) {
408
				$all_instances[ $number ] = $instance;
409
			}
410
411
			$action_ids[] = $this->save_settings( $instance );
412
413
			$this->updated = true;
414
		}
415
416
		return $action_ids;
417
	}
418
419
	/**
420
	 * If the status of the action has changed, update it
421
	 *
422
	 * @since 3.04
423
	 */
424
	protected function maybe_update_status( $new_instance, $old_instance ) {
425
		if ( $new_instance['post_status'] !== $old_instance->post_status ) {
426
			self::clear_cache();
427
			wp_update_post(
428
				array(
429
					'ID'          => $new_instance['ID'],
430
					'post_status' => $new_instance['post_status'],
431
				)
432
			);
433
		}
434
	}
435
436
	public function save_settings( $settings ) {
437
		self::clear_cache();
438
439
		return FrmDb::save_settings( $settings, 'frm_actions' );
440
	}
441
442
	public function get_single_action( $id ) {
443
		$action = get_post( $id );
444
		if ( $action ) {
445
			$action = $this->prepare_action( $action );
446
			$this->_set( $id );
447
		}
448
449
		return $action;
450
	}
451
452
	public function get_one( $form_id ) {
453
		return $this->get_all( $form_id, 1 );
454
	}
455
456
	public static function get_action_for_form( $form_id, $type = 'all', $atts = array() ) {
457
		$action_controls = FrmFormActionsController::get_form_actions( $type );
458
		if ( empty( $action_controls ) ) {
459
			// don't continue if there are no available actions
460
			return array();
461
		}
462
463
		if ( 'all' != $type ) {
464
			return $action_controls->get_all( $form_id, $atts );
465
		}
466
467
		self::prepare_get_action( $atts );
468
469
		$limit = apply_filters( 'frm_form_action_limit', $atts['limit'], compact( 'type', 'form_id' ) );
470
471
		$args                = self::action_args( $form_id, $limit );
472
		$args['post_status'] = $atts['post_status'];
473
		$actions             = FrmDb::check_cache( json_encode( $args ), 'frm_actions', $args, 'get_posts' );
474
475
		if ( ! $actions ) {
476
			return array();
477
		}
478
479
		$settings = array();
480
		foreach ( $actions as $action ) {
481
			// some plugins/themes are formatting the post_excerpt
482
			$action->post_excerpt = sanitize_title( $action->post_excerpt );
483
484
			if ( ! isset( $action_controls[ $action->post_excerpt ] ) ) {
485
				continue;
486
			}
487
488
			$action                  = $action_controls[ $action->post_excerpt ]->prepare_action( $action );
489
			$settings[ $action->ID ] = $action;
490
491
			if ( count( $settings ) >= $limit ) {
492
				break;
493
			}
494
		}
495
496
		if ( 1 === $limit ) {
497
			$settings = reset( $settings );
498
		}
499
500
		return $settings;
501
	}
502
503
	/**
504
	 * @since 3.04
505
	 * @param array  $args
506
	 * @param string $default_status
507
	 */
508
	protected static function prepare_get_action( &$args, $default_status = 'publish' ) {
509
		if ( is_numeric( $args ) ) {
510
			// for reverse compatibility. $limit was changed to $args
511
			$args = array(
512
				'limit' => $args,
513
			);
514
		}
515
		$defaults = array(
516
			'limit'       => 99,
517
			'post_status' => $default_status,
518
		);
519
		$args     = wp_parse_args( $args, $defaults );
520
	}
521
522
	/**
523
	 * @param int $action_id
524
	 */
525
	public static function get_single_action_type( $action_id, $type ) {
526
		if ( ! $type ) {
527
			return false;
528
		}
529
		$action_control = FrmFormActionsController::get_form_actions( $type );
530
531
		return $action_control->get_single_action( $action_id );
532
	}
533
534
	/**
535
	 * @param int $form_id
536
	 *
537
	 * @return bool
538
	 */
539
	public static function form_has_action_type( $form_id, $type ) {
540
		$payment_actions = self::get_action_for_form( $form_id, $type );
541
542
		return ! empty( $payment_actions );
543
	}
544
545
	public function get_all( $form_id = false, $atts = array() ) {
546
		self::prepare_get_action( $atts, 'any' );
547
		$limit = $atts['limit'];
548
549
		if ( $form_id ) {
550
			$this->form_id = $form_id;
551
		}
552
553
		$type = $this->id_base;
554
555
		global $frm_vars;
556
		$frm_vars['action_type'] = $type;
557
558
		add_filter( 'posts_where', 'FrmFormActionsController::limit_by_type' );
559
		$query = self::action_args( $form_id, $limit );
560
		$query['post_status'] = $atts['post_status'];
561
		$query['suppress_filters'] = false;
562
563
		$actions = FrmDb::check_cache( json_encode( $query ) . '_type_' . $type, 'frm_actions', $query, 'get_posts' );
564
		unset( $query );
565
566
		remove_filter( 'posts_where', 'FrmFormActionsController::limit_by_type' );
567
568
		if ( empty( $actions ) ) {
569
			return array();
570
		}
571
572
		$settings = array();
573
		foreach ( $actions as $action ) {
574
			if ( count( $settings ) >= $limit ) {
575
				continue;
576
			}
577
578
			$action = $this->prepare_action( $action );
579
580
			$settings[ $action->ID ] = $action;
581
		}
582
583
		if ( 1 === $limit ) {
584
			$settings = reset( $settings );
585
		}
586
587
		return $settings;
588
	}
589
590
	public static function action_args( $form_id = 0, $limit = 99 ) {
591
		$args = array(
592
			'post_type'   => FrmFormActionsController::$action_post_type,
593
			'post_status' => 'publish',
594
			'numberposts' => $limit,
595
			'orderby'     => 'title',
596
			'order'       => 'ASC',
597
		);
598
599
		if ( $form_id && $form_id != 'all' ) {
600
			$args['menu_order'] = $form_id;
601
		}
602
603
		return $args;
604
	}
605
606
	public function prepare_action( $action ) {
607
		$action->post_content = (array) FrmAppHelper::maybe_json_decode( $action->post_content );
608
		$action->post_excerpt = sanitize_title( $action->post_excerpt );
609
610
		$default_values = $this->get_global_defaults();
611
612
		// fill default values
613
		$action->post_content += $default_values;
614
615
		foreach ( $default_values as $k => $vals ) {
616
			if ( is_array( $vals ) && ! empty( $vals ) ) {
617
				if ( 'event' == $k && ! $this->action_options['force_event'] && ! empty( $action->post_content[ $k ] ) ) {
618
					continue;
619
				}
620
				$action->post_content[ $k ] = wp_parse_args( $action->post_content[ $k ], $vals );
621
			}
622
		}
623
624
		if ( ! is_array( $action->post_content['event'] ) ) {
625
			$action->post_content['event'] = explode( ',', $action->post_content['event'] );
626
		}
627
628
		return $action;
629
	}
630
631
	public function destroy( $form_id = false, $type = 'default' ) {
632
		global $wpdb;
633
634
		$this->form_id = $form_id;
635
636
		$query = array( 'post_type' => FrmFormActionsController::$action_post_type );
637
		if ( $form_id ) {
638
			$query['menu_order'] = $form_id;
639
		}
640
		if ( 'all' != $type ) {
641
			$query['post_excerpt'] = $this->id_base;
642
		}
643
644
		$post_ids = FrmDb::get_col( $wpdb->posts, $query, 'ID' );
645
646
		foreach ( $post_ids as $id ) {
0 ignored issues
show
Bug introduced by
The expression $post_ids of type array|null|string|object is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
647
			wp_delete_post( $id );
648
		}
649
		self::clear_cache();
650
	}
651
652
	/**
653
	 * Delete the action cache when a form action is created, deleted, or updated
654
	 *
655
	 * @since 2.0.5
656
	 */
657
	public static function clear_cache() {
658
		FrmDb::cache_delete_group( 'frm_actions' );
659
	}
660
661
	public function get_settings() {
662
		return self::get_action_for_form( $this->form_id, $this->id_base );
663
	}
664
665
	public function get_global_defaults() {
666
		$defaults = $this->get_defaults();
667
668
		if ( ! isset( $defaults['event'] ) ) {
669
			$defaults['event'] = array( 'create' );
670
		}
671
672
		if ( ! isset( $defaults['conditions'] ) ) {
673
			$defaults['conditions'] = array(
674
				'send_stop' => '',
675
				'any_all'   => '',
676
			);
677
		}
678
679
		return $defaults;
680
	}
681
682
	public function get_global_switch_fields() {
683
		$switch               = $this->get_switch_fields();
684
		$switch['conditions'] = array( 'hide_field' );
685
686
		$switch = apply_filters( 'frm_global_switch_fields', $switch );
687
688
		return $switch;
689
	}
690
691
	/**
692
	 * Migrate settings from form->options into new action.
693
	 */
694
	public function migrate_to_2( $form, $update = 'update' ) {
695
		$action        = $this->prepare_new( $form->id );
696
		FrmAppHelper::unserialize_or_decode( $form->options );
697
698
		// fill with existing options
699
		foreach ( $action->post_content as $name => $val ) {
700
			if ( isset( $form->options[ $name ] ) ) {
701
				$action->post_content[ $name ] = $form->options[ $name ];
702
				unset( $form->options[ $name ] );
703
			}
704
		}
705
706
		$action = $this->migrate_values( $action, $form );
707
708
		// check if action already exists
709
		$post_id = get_posts(
710
			array(
711
				'name'        => $action->post_name,
712
				'post_type'   => FrmFormActionsController::$action_post_type,
713
				'post_status' => $action->post_status,
714
				'numberposts' => 1,
715
			)
716
		);
717
718
		if ( empty( $post_id ) ) {
719
			// create action now
720
			$post_id = $this->save_settings( $action );
721
		}
722
723
		if ( $post_id && 'update' == $update ) {
724
			global $wpdb;
725
			$form->options = maybe_serialize( $form->options );
726
727
			// update form options
728
			$wpdb->update( $wpdb->prefix . 'frm_forms', array( 'options' => $form->options ), array( 'id' => $form->id ) );
729
			FrmForm::clear_form_cache();
730
		}
731
732
		return $post_id;
733
	}
734
735
	public static function action_conditions_met( $action, $entry ) {
736
		if ( is_callable( 'FrmProFormActionsController::action_conditions_met' ) ) {
737
			return FrmProFormActionsController::action_conditions_met( $action, $entry );
738
		}
739
740
		// This is here for reverse compatibility.
741
		$notification = $action->post_content;
742
		$stop         = false;
743
		$met          = array();
744
745
		if ( ! isset( $notification['conditions'] ) || empty( $notification['conditions'] ) ) {
746
			return $stop;
747
		}
748
749
		foreach ( $notification['conditions'] as $k => $condition ) {
750
			if ( ! is_numeric( $k ) ) {
751
				continue;
752
			}
753
754
			if ( $stop && 'any' == $notification['conditions']['any_all'] && 'stop' == $notification['conditions']['send_stop'] ) {
755
				continue;
756
			}
757
758
			self::prepare_logic_value( $condition['hide_opt'], $action, $entry );
0 ignored issues
show
Deprecated Code introduced by
The method FrmFormAction::prepare_logic_value() has been deprecated with message: 4.06.02

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
759
760
			$observed_value = self::get_value_from_entry( $entry, $condition['hide_field'] );
0 ignored issues
show
Deprecated Code introduced by
The method FrmFormAction::get_value_from_entry() has been deprecated with message: 4.06.02

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
761
762
			$stop = FrmFieldsHelper::value_meets_condition( $observed_value, $condition['hide_field_cond'], $condition['hide_opt'] );
763
764
			if ( $notification['conditions']['send_stop'] == 'send' ) {
765
				$stop = $stop ? false : true;
766
			}
767
768
			$met[ $stop ] = $stop;
769
		}
770
771
		if ( $notification['conditions']['any_all'] == 'all' && ! empty( $met ) && isset( $met[0] ) && isset( $met[1] ) ) {
772
			$stop = ( $notification['conditions']['send_stop'] == 'send' );
773
		} elseif ( $notification['conditions']['any_all'] == 'any' && $notification['conditions']['send_stop'] == 'send' && isset( $met[0] ) ) {
774
			$stop = false;
775
		}
776
777
		return $stop;
778
	}
779
780
	/**
781
	 * Prepare the logic value for comparison against the entered value
782
	 *
783
	 * @since 2.01.02
784
	 * @deprecated 4.06.02
785
	 *
786
	 * @param array|string $logic_value
787
	 */
788
	private static function prepare_logic_value( &$logic_value, $action, $entry ) {
789
		if ( is_array( $logic_value ) ) {
790
			$logic_value = reset( $logic_value );
791
		}
792
793
		if ( $logic_value == 'current_user' ) {
794
			$logic_value = get_current_user_id();
795
		}
796
797
		$logic_value = apply_filters( 'frm_content', $logic_value, $action->menu_order, $entry );
798
799
		/**
800
		 * @since 4.04.05
801
		 */
802
		$logic_value = apply_filters( 'frm_action_logic_value', $logic_value );
803
	}
804
805
	/**
806
	 * Get the value from a specific field and entry
807
	 *
808
	 * @since 2.01.02
809
	 * @deprecated 4.06.02
810
	 *
811
	 * @param object $entry
812
	 * @param int $field_id
813
	 *
814
	 * @return array|bool|mixed|string
815
	 */
816
	private static function get_value_from_entry( $entry, $field_id ) {
817
		$observed_value = '';
818
819
		if ( isset( $entry->metas[ $field_id ] ) ) {
820
			$observed_value = $entry->metas[ $field_id ];
821
		} elseif ( $entry->post_id && FrmAppHelper::pro_is_installed() ) {
822
			$field          = FrmField::getOne( $field_id );
823
			$observed_value = FrmProEntryMetaHelper::get_post_or_meta_value(
824
				$entry,
825
				$field,
826
				array(
827
					'links'    => false,
828
					'truncate' => false,
829
				)
830
			);
831
		}
832
833
		return $observed_value;
834
	}
835
836
	public static function default_action_opts( $class = '' ) {
837
		return array(
838
			'classes' => 'frm_icon_font ' . $class,
839
			'active'  => false,
840
			'limit'   => 0,
841
		);
842
	}
843
844
	public static function trigger_labels() {
845
		$triggers = array(
846
			'draft'  => __( 'Draft is saved', 'formidable' ),
847
			'create' => __( 'Entry is created', 'formidable' ),
848
			'update' => __( 'Entry is updated', 'formidable' ),
849
			'delete' => __( 'Entry is deleted', 'formidable' ),
850
			'import' => __( 'Entry is imported', 'formidable' ),
851
		);
852
853
		return apply_filters( 'frm_action_triggers', $triggers );
854
	}
855
856
	public function render_conditional_logic_call_to_action() {
857
		?>
858
			<h3>
859
				<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 ); ?>">
860
					<?php esc_html_e( 'Use Conditional Logic', 'formidable' ); ?>
861
				</a>
862
			</h3>
863
		<?php
864
	}
865
866
	protected function get_upgrade_text() {
867
		return __( 'Conditional form actions', 'formidable' );
868
	}
869
}
870