Completed
Push — master ( fec4f5...5e053d )
by Stephanie
02:54
created

FrmFormActionsController::actions_init()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
class FrmFormActionsController {
4
    public static $action_post_type = 'frm_form_actions';
5
    public static $registered_actions;
6
7
    public static function register_post_types() {
8
		register_post_type(
9
			self::$action_post_type,
10
			array(
11
				'label'       => __( 'Form Actions', 'formidable' ),
12
				'description' => '',
13
				'public'      => false,
14
				'show_ui'     => false,
15
				'exclude_from_search' => true,
16
				'show_in_nav_menus' => false,
17
				'show_in_menu' => true,
18
				'capability_type' => 'page',
19
				'supports'     => array( 'title', 'editor', 'excerpt', 'custom-fields', 'page-attributes' ),
20
				'has_archive'  => false,
21
			)
22
		);
23
24
        /**
25
         * post_content: json settings
26
         * menu_order: form id
27
         * post_excerpt: action type
28
         */
29
30
        self::actions_init();
31
    }
32
33
    public static function actions_init() {
34
        self::$registered_actions = new Frm_Form_Action_Factory();
35
        self::register_actions();
36
        do_action( 'frm_form_actions_init' );
37
    }
38
39
    public static function register_actions() {
40
		$action_classes = array(
41
            'email'     => 'FrmEmailAction',
42
            'wppost'    => 'FrmDefPostAction',
43
            'register'  => 'FrmDefRegAction',
44
            'paypal'    => 'FrmDefPayPalAction',
45
            //'aweber'    => 'FrmDefAweberAction',
46
            'mailchimp' => 'FrmDefMlcmpAction',
47
            'twilio'    => 'FrmDefTwilioAction',
48
            'highrise'  => 'FrmDefHrsAction',
49
        );
50
		$action_classes = apply_filters( 'frm_registered_form_actions', $action_classes );
51
52
		include_once( FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/email_action.php' );
53
		include_once( FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/default_actions.php' );
54
55
        foreach ( $action_classes as $action_class ) {
56
			self::$registered_actions->register( $action_class );
57
        }
58
    }
59
60
	public static function get_form_actions( $action = 'all' ) {
61
        $temp_actions = self::$registered_actions;
62
		if ( empty( $temp_actions ) ) {
63
            self::actions_init();
64
            $temp_actions = self::$registered_actions->actions;
65
        } else {
66
            $temp_actions = $temp_actions->actions;
67
        }
68
69
        $actions = array();
70
71
        foreach ( $temp_actions as $a ) {
72
            if ( 'all' != $action && $a->id_base == $action ) {
73
                return $a;
74
            }
75
76
			$actions[ $a->id_base ] = $a;
77
        }
78
        unset( $temp_actions, $a );
79
80
        $action_limit = 10;
81
        if ( count( $actions ) <= $action_limit ) {
82
            return $actions;
83
        }
84
85
        // remove the last few inactive icons if there are too many
86
        $temp_actions = $actions;
87
        arsort( $temp_actions );
88
        foreach ( $temp_actions as $type => $a ) {
89
            if ( ! isset( $a->action_options['active'] ) || empty( $a->action_options['active'] ) ) {
90
				unset( $actions[ $type ] );
91
                if ( count( $actions ) <= $action_limit ) {
92
                    break;
93
                }
94
            }
95
            unset( $type, $a );
96
        }
97
98
        return $actions;
99
    }
100
101
	/**
102
	 * @since 2.0
103
	 */
104
    public static function list_actions( $form, $values ) {
105
        if ( empty( $form ) ) {
106
            return;
107
        }
108
109
		/**
110
		 * use this hook to migrate old settings into a new action
111
		 * @since 2.0
112
		 */
113
		do_action( 'frm_before_list_actions', $form );
114
115
		$form_actions = FrmFormAction::get_action_for_form( $form->id );
116
117
        $action_controls = self::get_form_actions();
118
119
        $action_map = array();
120
121
		foreach ( $action_controls as $key => $control ) {
122
            $action_map[ $control->id_base ] = $key;
123
        }
124
125
    	foreach ( $form_actions as $action ) {
126
    	    if ( ! isset( $action_map[ $action->post_excerpt ] ) ) {
127
    	        // don't try and show settings if action no longer exists
128
    	        continue;
129
    	    }
130
131
    		self::action_control( $action, $form, $action->ID, $action_controls[ $action_map[ $action->post_excerpt ] ], $values );
132
    	}
133
    }
134
135
	public static function action_control( $form_action, $form, $action_key, $action_control, $values ) {
136
		$action_control->_set( $action_key );
137
		include( FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/form_action.php' );
138
    }
139
140
    public static function add_form_action() {
141
		FrmAppHelper::permission_check( 'frm_edit_forms' );
142
        check_ajax_referer( 'frm_ajax', 'nonce' );
143
144
        global $frm_vars;
145
146
		$action_key = absint( $_POST['list_id'] );
147
        $action_type = sanitize_text_field( $_POST['type'] );
148
149
        $action_control = self::get_form_actions( $action_type );
150
		$action_control->_set( $action_key );
151
152
        $form_id = absint( $_POST['form_id'] );
153
154
		$form_action = $action_control->prepare_new( $form_id );
155
156
        $values = array();
157
		$form = self::fields_to_values( $form_id, $values );
158
159
		include( FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/form_action.php' );
160
        wp_die();
161
    }
162
163
    public static function fill_action() {
164
		FrmAppHelper::permission_check( 'frm_edit_forms' );
165
        check_ajax_referer( 'frm_ajax', 'nonce' );
166
167
        $action_key = absint( $_POST['action_id'] );
168
        $action_type = sanitize_text_field( $_POST['action_type'] );
169
170
        $action_control = self::get_form_actions( $action_type );
171
		if ( empty( $action_control ) ) {
172
            wp_die();
173
        }
174
175
        $form_action = $action_control->get_single_action( $action_key );
176
177
        $values = array();
178
		$form = self::fields_to_values( $form_action->menu_order, $values );
179
180
		include( FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/_action_inside.php' );
181
        wp_die();
182
    }
183
184
	private static function fields_to_values( $form_id, array &$values ) {
185
		$form = FrmForm::getOne( $form_id );
186
187
		$values = array(
188
			'fields' => array(),
189
			'id'     => $form->id,
190
		);
191
192
		$fields = FrmField::get_all_for_form( $form->id );
193
        foreach ( $fields as $k => $f ) {
194
            $f = (array) $f;
195
            $opts = (array) $f['field_options'];
196
			$f = array_merge( $opts, $f );
197
            if ( ! isset( $f['post_field'] ) ) {
198
                $f['post_field'] = '';
199
            }
200
            $values['fields'][] = $f;
201
			unset( $k, $f );
202
        }
203
204
        return $form;
205
    }
206
207
	public static function update_settings( $form_id ) {
208
		$process_form = FrmAppHelper::get_post_param( 'process_form', '', 'sanitize_text_field' );
209
		if ( ! wp_verify_nonce( $process_form, 'process_form_nonce' ) ) {
210
			wp_die( esc_html__( 'You do not have permission to do that', 'formidable' ) );
211
		}
212
213
        global $wpdb;
214
215
        $registered_actions = self::$registered_actions->actions;
216
217
		$old_actions = FrmDb::get_col(
218
			$wpdb->posts,
219
			array(
220
				'post_type'  => self::$action_post_type,
221
				'menu_order' => $form_id,
222
			),
223
			'ID'
224
		);
225
        $new_actions = array();
226
227
        foreach ( $registered_actions as $registered_action ) {
228
			$action_ids = $registered_action->update_callback( $form_id );
229
            if ( ! empty( $action_ids ) ) {
230
                $new_actions[] = $action_ids;
231
            }
232
        }
233
234
        //Only use array_merge if there are new actions
235
        if ( ! empty( $new_actions ) ) {
236
            $new_actions = call_user_func_array( 'array_merge', $new_actions );
237
        }
238
        $old_actions = array_diff( $old_actions, $new_actions );
239
240
		self::delete_missing_actions( $old_actions );
241
    }
242
243
	public static function delete_missing_actions( $old_actions ) {
244
		if ( ! empty( $old_actions ) ) {
245
			foreach ( $old_actions as $old_id ) {
246
				wp_delete_post( $old_id );
247
			}
248
			FrmDb::cache_delete_group( 'frm_actions' );
249
		}
250
	}
251
252
	public static function trigger_create_actions( $entry_id, $form_id, $args = array() ) {
253
		$filter_args = $args;
254
		$filter_args['entry_id'] = $entry_id;
255
		$filter_args['form_id']  = $form_id;
256
		$event = apply_filters( 'frm_trigger_create_action', 'create', $args );
257
258
		self::trigger_actions( $event, $form_id, $entry_id, 'all', $args );
259
	}
260
261
    /**
262
     * @param string $event
263
     */
264
	public static function trigger_actions( $event, $form, $entry, $type = 'all', $args = array() ) {
265
		$form_actions = FrmFormAction::get_action_for_form( ( is_object( $form ) ? $form->id : $form ), $type );
266
267
		if ( empty( $form_actions ) ) {
268
            return;
269
        }
270
271
		FrmForm::maybe_get_form( $form );
272
273
        $link_settings = self::get_form_actions( $type );
274
        if ( 'all' != $type ) {
275
            $link_settings = array( $type => $link_settings );
276
        }
277
278
		$stored_actions = array();
279
		$action_priority = array();
280
281
		if ( in_array( $event, array( 'create', 'update' ) ) && defined( 'WP_IMPORTING' ) && WP_IMPORTING ) {
282
			$this_event = 'import';
283
		} else {
284
			$this_event = $event;
285
		}
286
287
        foreach ( $form_actions as $action ) {
288
289
			$skip_this_action = ( ! in_array( $this_event, $action->post_content['event'] ) );
290
			$skip_this_action = apply_filters( 'frm_skip_form_action', $skip_this_action, compact( 'action', 'entry', 'form', 'event' ) );
291
			if ( $skip_this_action ) {
292
                continue;
293
            }
294
295
            if ( ! is_object( $entry ) ) {
296
                $entry = FrmEntry::getOne( $entry, true );
297
            }
298
299
			if ( empty( $entry ) || ( $entry->is_draft && $event != 'draft' ) ) {
300
				continue;
301
			}
302
303
			$child_entry = ( ( $form && is_numeric( $form->parent_form_id ) && $form->parent_form_id ) || ( $entry && ( $entry->form_id != $form->id || $entry->parent_item_id ) ) || ( isset( $args['is_child'] ) && $args['is_child'] ) );
304
305
			if ( $child_entry ) {
306
				// maybe trigger actions for sub forms
307
				$trigger_children = apply_filters( 'frm_use_embedded_form_actions', false, compact( 'form', 'entry' ) );
308
				if ( ! $trigger_children ) {
309
					continue;
310
				}
311
            }
312
313
            // check conditional logic
314
			$stop = FrmFormAction::action_conditions_met( $action, $entry );
315
            if ( $stop ) {
316
                continue;
317
            }
318
319
            // store actions so they can be triggered with the correct priority
320
            $stored_actions[ $action->ID ] = $action;
321
            $action_priority[ $action->ID ] = $link_settings[ $action->post_excerpt ]->action_options['priority'];
322
323
			unset( $action );
324
        }
325
326
        if ( ! empty( $stored_actions ) ) {
327
			asort( $action_priority );
328
329
            // make sure hooks are loaded
330
            new FrmNotification();
331
332
            foreach ( $action_priority as $action_id => $priority ) {
333
                $action = $stored_actions[ $action_id ];
334
				do_action( 'frm_trigger_' . $action->post_excerpt . '_action', $action, $entry, $form, $event );
335
				do_action( 'frm_trigger_' . $action->post_excerpt . '_' . $event . '_action', $action, $entry, $form );
336
337
                // If post is created, get updated $entry object
338
                if ( $action->post_excerpt == 'wppost' && $event == 'create' ) {
339
					$entry = FrmEntry::getOne( $entry->id, true );
340
                }
341
            }
342
        }
343
    }
344
345
	public static function duplicate_form_actions( $form_id, $values, $args = array() ) {
346
		if ( ! isset( $args['old_id'] ) || empty( $args['old_id'] ) ) {
347
            // continue if we know which actions to copy
348
            return;
349
        }
350
351
		$action_controls = self::get_form_actions();
352
353
        foreach ( $action_controls as $action_control ) {
354
            $action_control->duplicate_form_actions( $form_id, $args['old_id'] );
355
            unset( $action_control );
356
        }
357
    }
358
359
    public static function limit_by_type( $where ) {
360
        global $frm_vars, $wpdb;
361
362
        if ( ! isset( $frm_vars['action_type'] ) ) {
363
            return $where;
364
        }
365
366
        $where .= $wpdb->prepare( ' AND post_excerpt = %s ', $frm_vars['action_type'] );
367
        return $where;
368
    }
369
}
370
371
372
class Frm_Form_Action_Factory {
373
	public $actions = array();
374
375
	public function __construct() {
376
		add_action( 'frm_form_actions_init', array( $this, '_register_actions' ), 100 );
377
	}
378
379
	public function register( $action_class ) {
380
		$this->actions[ $action_class ] = new $action_class();
381
	}
382
383
	public function unregister( $action_class ) {
384
		if ( isset( $this->actions[ $action_class ] ) ) {
385
			unset( $this->actions[ $action_class ] );
386
		}
387
	}
388
389
	public function _register_actions() {
390
		$keys = array_keys( $this->actions );
391
392
		foreach ( $keys as $key ) {
393
			// don't register new action if old action with the same id is already registered
394
			if ( ! isset( $this->actions[ $key ] ) ) {
395
			    $this->actions[ $key ]->_register();
396
			}
397
		}
398
	}
399
}
400