Completed
Push — master ( feb49b...2e7061 )
by Stephanie
06:17 queued 03:03
created

FrmFormAction::get_group()   B

Complexity

Conditions 7
Paths 5

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

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