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

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