PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 5.4.2
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v5.4.2
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 5.4.2, at classes/controllers/FrmFormActionsController.php

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