PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 4.08
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v4.08
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 / controllers / FrmFormActionsController.php

FrmFormActionsController.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 4.08, at classes/controllers/FrmFormActionsController.php

585 lines 16.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 FrmFormActionsController {
7 public static $action_post_type = 'frm_form_actions';
8 public static $registered_actions;
9
10 /**
11 * Variables saved in the post:
12 * post_content: json settings
13 * menu_order: form id
14 * post_excerpt: action type
15 */
16 public static function register_post_types() {
17 register_post_type(
18 self::$action_post_type,
19 array(
20 'label' => __( 'Form Actions', 'formidable' ),
21 'description' => '',
22 'public' => false,
23 'show_ui' => false,
24 'exclude_from_search' => true,
25 'show_in_nav_menus' => false,
26 'show_in_menu' => true,
27 'capability_type' => 'page',
28 'supports' => array( 'title', 'editor', 'excerpt', 'custom-fields', 'page-attributes' ),
29 'has_archive' => false,
30 )
31 );
32
33 self::actions_init();
34 }
35
36 public static function actions_init() {
37 self::$registered_actions = new Frm_Form_Action_Factory();
38 self::register_actions();
39 do_action( 'frm_form_actions_init' );
40 }
41
42 public static function register_actions() {
43 $action_classes = array(
44 'email' => 'FrmEmailAction',
45 'wppost' => 'FrmDefPostAction',
46 'register' => 'FrmDefRegAction',
47 'paypal' => 'FrmDefPayPalAction',
48 'payment' => 'FrmDefHrsAction',
49 'mailchimp' => 'FrmDefMlcmpAction',
50 'api' => 'FrmDefApiAction',
51
52 'salesforce' => 'FrmDefSalesforceAction',
53 'activecampaign' => 'FrmDefActiveCampaignAction',
54 'constantcontact' => 'FrmDefConstContactAction',
55 'getresponse' => 'FrmDefGetResponseAction',
56 'hubspot' => 'FrmDefHubspotAction',
57 'zapier' => 'FrmDefZapierAction',
58 'twilio' => 'FrmDefTwilioAction',
59 'highrise' => 'FrmDefHighriseAction',
60 'mailpoet' => 'FrmDefMailpoetAction',
61 'aweber' => 'FrmDefAweberAction',
62 );
63
64 $action_classes = apply_filters( 'frm_registered_form_actions', $action_classes );
65
66 include_once( FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/email_action.php' );
67 include_once( FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/default_actions.php' );
68
69 foreach ( $action_classes as $action_class ) {
70 self::$registered_actions->register( $action_class );
71 }
72 }
73
74 /**
75 * @since 4.0
76 *
77 * @param array $values
78 */
79 public static function email_settings( $values ) {
80 $form = FrmForm::getOne( $values['id'] );
81 $groups = self::form_action_groups();
82
83 $action_controls = self::get_form_actions();
84 self::maybe_add_action_to_group( $action_controls, $groups );
85
86 $allowed = self::active_actions( $action_controls );
87
88 include( FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/settings.php' );
89 }
90
91 /**
92 * Add unknown actions to a group.
93 *
94 * @since 4.0
95 */
96 private static function maybe_add_action_to_group( $action_controls, &$groups ) {
97 $grouped = array();
98 foreach ( $groups as $group ) {
99 if ( isset( $group['actions'] ) ) {
100 $grouped = array_merge( $grouped, $group['actions'] );
101 }
102 }
103
104 foreach ( $action_controls as $action ) {
105 if ( isset( $groups[ $action->id_base ] ) || in_array( $action->id_base, $grouped ) ) {
106 continue;
107 }
108
109 $this_group = $action->action_options['group'];
110 if ( ! isset( $groups[ $this_group ] ) ) {
111 $this_group = 'misc';
112 }
113
114 if ( ! isset( $groups[ $this_group ]['actions'] ) ) {
115 $groups[ $this_group ]['actions'] = array();
116 }
117 $groups[ $this_group ]['actions'][] = $action->id_base;
118
119 unset( $action );
120 }
121 }
122
123 /**
124 * @since 4.0
125 *
126 * @return array
127 */
128 public static function form_action_groups() {
129 $groups = array(
130 'misc' => array(
131 'name' => '',
132 'icon' => 'frm_icon_font frm_shuffle_icon',
133 'actions' => array(
134 'email',
135 'wppost',
136 'register',
137 'twilio',
138 ),
139 ),
140 'payment' => array(
141 'name' => __( 'eCommerce', 'formidable' ),
142 'icon' => 'frm_icon_font frm_credit_card_alt_icon',
143 'actions' => array(
144 'paypal',
145 'payment',
146 ),
147 ),
148 'marketing' => array(
149 'name' => __( 'Email Marketing', 'formidable' ),
150 'icon' => 'frm_icon_font frm_mail_bulk_icon',
151 'actions' => array(
152 'mailchimp',
153 'activecampaign',
154 'constantcontact',
155 'getresponse',
156 'aweber',
157 'mailpoet',
158 ),
159 ),
160 'crm' => array(
161 'name' => __( 'CRM', 'formidable' ),
162 'icon' => 'frm_icon_font frm_address_card_icon',
163 'actions' => array(
164 'salesforce',
165 'hubspot',
166 'highrise',
167 ),
168 ),
169 );
170
171 return apply_filters( 'frm_action_groups', $groups );
172 }
173
174 /**
175 * Get the number of currently active form actions.
176 *
177 * @since 4.0
178 *
179 * @return array
180 */
181 private static function active_actions( $action_controls ) {
182 $allowed = array();
183 foreach ( $action_controls as $action_control ) {
184 if ( isset( $action_control->action_options['active'] ) && $action_control->action_options['active'] ) {
185 $allowed[] = $action_control->id_base;
186 }
187 }
188 return $allowed;
189 }
190
191 /**
192 * For each add-on, add an li, class, and javascript function. If active, add an additional class.
193 *
194 * @since 4.0
195 * @param object $action_control
196 * @param array $allowed
197 */
198 public static function show_action_icon_link( $action_control, $allowed ) {
199 $data = array();
200 $classes = ' frm_' . $action_control->id_base . '_action frm_single_action';
201
202 $group_class = ' frm-group-' . $action_control->action_options['group'];
203
204 /* translators: %s: Name of form action */
205 $upgrade_label = sprintf( esc_html__( '%s form actions', 'formidable' ), $action_control->action_options['tooltip'] );
206
207 $default_shown = array( 'wppost', 'register', 'paypal', 'payment', 'mailchimp' );
208 $default_shown = array_values( array_diff( $default_shown, $allowed ) );
209 $default_position = array_search( $action_control->id_base, $default_shown );
210 $allowed_count = count( $allowed );
211
212 if ( isset( $action_control->action_options['active'] ) && $action_control->action_options['active'] ) {
213 $classes .= ' frm_active_action';
214 } else {
215 $classes .= ' frm_inactive_action';
216 if ( $default_position !== false && ( $allowed_count + $default_position ) < 6 ) {
217 $group_class .= ' frm-default-show';
218 }
219
220 $data['data-upgrade'] = $upgrade_label;
221 $data['data-medium'] = 'settings-' . $action_control->id_base;
222
223 $upgrading = FrmAddonsController::install_link( $action_control->action_options['plugin'] );
224 if ( isset( $upgrading['url'] ) ) {
225 $data['data-oneclick'] = json_encode( $upgrading );
226 }
227 }
228
229 // HTML to include on the icon.
230 $icon_atts = array();
231 if ( $action_control->action_options['color'] !== 'var(--primary-hover)' ) {
232 $icon_atts = array(
233 'style' => '--primary-hover:' . $action_control->action_options['color'],
234 );
235 }
236
237 include( FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/_action_icon.php' );
238 }
239
240 public static function get_form_actions( $action = 'all' ) {
241 $temp_actions = self::$registered_actions;
242 if ( empty( $temp_actions ) ) {
243 self::actions_init();
244 $temp_actions = self::$registered_actions->actions;
245 } else {
246 $temp_actions = $temp_actions->actions;
247 }
248
249 $actions = array();
250
251 foreach ( $temp_actions as $a ) {
252 if ( 'all' != $action && $a->id_base == $action ) {
253 return $a;
254 }
255
256 $actions[ $a->id_base ] = $a;
257 }
258
259 return $actions;
260 }
261
262 /**
263 * @since 2.0
264 */
265 public static function list_actions( $form, $values ) {
266 if ( empty( $form ) ) {
267 return;
268 }
269
270 /**
271 * Use this hook to migrate old settings into a new action
272 *
273 * @since 2.0
274 */
275 do_action( 'frm_before_list_actions', $form );
276
277 $filters = array(
278 'post_status' => 'all',
279 );
280 $form_actions = FrmFormAction::get_action_for_form( $form->id, 'all', $filters );
281
282 $action_controls = self::get_form_actions();
283
284 $action_map = array();
285
286 foreach ( $action_controls as $key => $control ) {
287 $action_map[ $control->id_base ] = $key;
288 }
289
290 foreach ( $form_actions as $action ) {
291 if ( ! isset( $action_map[ $action->post_excerpt ] ) ) {
292 // don't try and show settings if action no longer exists
293 continue;
294 }
295
296 self::action_control( $action, $form, $action->ID, $action_controls[ $action_map[ $action->post_excerpt ] ], $values );
297 }
298 }
299
300 public static function action_control( $form_action, $form, $action_key, $action_control, $values ) {
301 $action_control->_set( $action_key );
302
303 $use_logging = self::should_show_log_message( $form_action->post_excerpt );
304
305 include( FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/form_action.php' );
306 }
307
308 public static function add_form_action() {
309 FrmAppHelper::permission_check( 'frm_edit_forms' );
310 check_ajax_referer( 'frm_ajax', 'nonce' );
311
312 global $frm_vars;
313
314 $action_key = FrmAppHelper::get_param( 'list_id', '', 'post', 'absint' );
315 $action_type = FrmAppHelper::get_param( 'type', '', 'post', 'sanitize_text_field' );
316
317 $action_control = self::get_form_actions( $action_type );
318 $action_control->_set( $action_key );
319
320 $form_id = FrmAppHelper::get_param( 'form_id', '', 'post', 'absint' );
321
322 $form_action = $action_control->prepare_new( $form_id );
323 $use_logging = self::should_show_log_message( $action_type );
324
325 $values = array();
326 $form = self::fields_to_values( $form_id, $values );
327
328 include( FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/form_action.php' );
329 wp_die();
330 }
331
332 public static function fill_action() {
333 FrmAppHelper::permission_check( 'frm_edit_forms' );
334 check_ajax_referer( 'frm_ajax', 'nonce' );
335
336 $action_key = FrmAppHelper::get_param( 'action_id', '', 'post', 'absint' );
337 $action_type = FrmAppHelper::get_param( 'action_type', '', 'post', 'sanitize_text_field' );
338
339 $action_control = self::get_form_actions( $action_type );
340 if ( empty( $action_control ) ) {
341 wp_die();
342 }
343
344 $form_action = $action_control->get_single_action( $action_key );
345
346 $values = array();
347 $form = self::fields_to_values( $form_action->menu_order, $values );
348
349 $use_logging = self::should_show_log_message( $action_type );
350
351 include( FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/_action_inside.php' );
352 wp_die();
353 }
354
355 /**
356 * @since 3.06.04
357 * @return bool
358 */
359 private static function should_show_log_message( $action_type ) {
360 $logging = array( 'api', 'salesforce', 'constantcontact', 'activecampaign' );
361 return in_array( $action_type, $logging ) && ! function_exists( 'frm_log_autoloader' );
362 }
363
364 private static function fields_to_values( $form_id, array &$values ) {
365 $form = FrmForm::getOne( $form_id );
366
367 $values = array(
368 'fields' => array(),
369 'id' => $form->id,
370 );
371
372 $fields = FrmField::get_all_for_form( $form->id );
373 foreach ( $fields as $k => $f ) {
374 $f = (array) $f;
375 $opts = (array) $f['field_options'];
376 $f = array_merge( $opts, $f );
377 if ( ! isset( $f['post_field'] ) ) {
378 $f['post_field'] = '';
379 }
380 $values['fields'][] = $f;
381 unset( $k, $f );
382 }
383
384 return $form;
385 }
386
387 public static function update_settings( $form_id ) {
388 FrmAppHelper::permission_check( 'frm_edit_forms' );
389 $process_form = FrmAppHelper::get_post_param( 'process_form', '', 'sanitize_text_field' );
390 if ( ! wp_verify_nonce( $process_form, 'process_form_nonce' ) ) {
391 wp_die( esc_html__( 'You do not have permission to do that', 'formidable' ) );
392 }
393
394 global $wpdb;
395
396 $registered_actions = self::$registered_actions->actions;
397
398 $old_actions = FrmDb::get_col(
399 $wpdb->posts,
400 array(
401 'post_type' => self::$action_post_type,
402 'menu_order' => $form_id,
403 ),
404 'ID'
405 );
406 $new_actions = array();
407
408 foreach ( $registered_actions as $registered_action ) {
409 $action_ids = $registered_action->update_callback( $form_id );
410 if ( ! empty( $action_ids ) ) {
411 $new_actions[] = $action_ids;
412 }
413 }
414
415 // Only use array_merge if there are new actions.
416 if ( ! empty( $new_actions ) ) {
417 $new_actions = call_user_func_array( 'array_merge', $new_actions );
418 }
419 $old_actions = array_diff( $old_actions, $new_actions );
420
421 self::delete_missing_actions( $old_actions );
422 }
423
424 public static function delete_missing_actions( $old_actions ) {
425 if ( ! empty( $old_actions ) ) {
426 foreach ( $old_actions as $old_id ) {
427 wp_delete_post( $old_id );
428 }
429 FrmDb::cache_delete_group( 'frm_actions' );
430 }
431 }
432
433 public static function trigger_create_actions( $entry_id, $form_id, $args = array() ) {
434 $filter_args = $args;
435 $filter_args['entry_id'] = $entry_id;
436 $filter_args['form_id'] = $form_id;
437
438 $event = apply_filters( 'frm_trigger_create_action', 'create', $args );
439
440 self::trigger_actions( $event, $form_id, $entry_id, 'all', $args );
441 }
442
443 /**
444 * @param string $event
445 */
446 public static function trigger_actions( $event, $form, $entry, $type = 'all', $args = array() ) {
447 $action_status = array(
448 'post_status' => 'publish',
449 );
450 $form_actions = FrmFormAction::get_action_for_form( ( is_object( $form ) ? $form->id : $form ), $type, $action_status );
451
452 if ( empty( $form_actions ) ) {
453 return;
454 }
455
456 FrmForm::maybe_get_form( $form );
457
458 $link_settings = self::get_form_actions( $type );
459 if ( 'all' != $type ) {
460 $link_settings = array( $type => $link_settings );
461 }
462
463 $stored_actions = array();
464 $action_priority = array();
465
466 if ( in_array( $event, array( 'create', 'update' ) ) && defined( 'WP_IMPORTING' ) && WP_IMPORTING ) {
467 $this_event = 'import';
468 } else {
469 $this_event = $event;
470 }
471
472 foreach ( $form_actions as $action ) {
473
474 $skip_this_action = ( ! in_array( $this_event, $action->post_content['event'] ) );
475 $skip_this_action = apply_filters( 'frm_skip_form_action', $skip_this_action, compact( 'action', 'entry', 'form', 'event' ) );
476 if ( $skip_this_action ) {
477 continue;
478 }
479
480 if ( ! is_object( $entry ) ) {
481 $entry = FrmEntry::getOne( $entry, true );
482 }
483
484 if ( empty( $entry ) || ( $entry->is_draft && $event != 'draft' ) ) {
485 continue;
486 }
487
488 $child_entry = ( ( is_object( $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'] ) );
489
490 if ( $child_entry ) {
491 // maybe trigger actions for sub forms
492 $trigger_children = apply_filters( 'frm_use_embedded_form_actions', false, compact( 'form', 'entry' ) );
493 if ( ! $trigger_children ) {
494 continue;
495 }
496 }
497
498 // Check conditional logic.
499 $stop = FrmFormAction::action_conditions_met( $action, $entry );
500 if ( $stop ) {
501 continue;
502 }
503
504 // Store actions so they can be triggered with the correct priority.
505 $stored_actions[ $action->ID ] = $action;
506 $action_priority[ $action->ID ] = $link_settings[ $action->post_excerpt ]->action_options['priority'];
507
508 unset( $action );
509 }
510
511 if ( ! empty( $stored_actions ) ) {
512 asort( $action_priority );
513
514 // Make sure hooks are loaded.
515 new FrmNotification();
516
517 foreach ( $action_priority as $action_id => $priority ) {
518 $action = $stored_actions[ $action_id ];
519 do_action( 'frm_trigger_' . $action->post_excerpt . '_action', $action, $entry, $form, $event );
520 do_action( 'frm_trigger_' . $action->post_excerpt . '_' . $event . '_action', $action, $entry, $form );
521
522 // If post is created, get updated $entry object.
523 if ( $action->post_excerpt == 'wppost' && $event == 'create' ) {
524 $entry = FrmEntry::getOne( $entry->id, true );
525 }
526 }
527 }
528 }
529
530 public static function duplicate_form_actions( $form_id, $values, $args = array() ) {
531 if ( ! isset( $args['old_id'] ) || empty( $args['old_id'] ) ) {
532 // Continue if we know which actions to copy.
533 return;
534 }
535
536 $action_controls = self::get_form_actions();
537
538 foreach ( $action_controls as $action_control ) {
539 $action_control->duplicate_form_actions( $form_id, $args['old_id'] );
540 unset( $action_control );
541 }
542 }
543
544 public static function limit_by_type( $where ) {
545 global $frm_vars, $wpdb;
546
547 if ( ! isset( $frm_vars['action_type'] ) ) {
548 return $where;
549 }
550
551 $where .= $wpdb->prepare( ' AND post_excerpt = %s ', $frm_vars['action_type'] );
552
553 return $where;
554 }
555 }
556
557 class Frm_Form_Action_Factory {
558 public $actions = array();
559
560 public function __construct() {
561 add_action( 'frm_form_actions_init', array( $this, '_register_actions' ), 100 );
562 }
563
564 public function register( $action_class ) {
565 $this->actions[ $action_class ] = new $action_class();
566 }
567
568 public function unregister( $action_class ) {
569 if ( isset( $this->actions[ $action_class ] ) ) {
570 unset( $this->actions[ $action_class ] );
571 }
572 }
573
574 public function _register_actions() {
575 $keys = array_keys( $this->actions );
576
577 foreach ( $keys as $key ) {
578 // don't register new action if old action with the same id is already registered
579 if ( ! isset( $this->actions[ $key ] ) ) {
580 $this->actions[ $key ]->_register();
581 }
582 }
583 }
584 }
585