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

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