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

861 lines 22.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
8 /**
9 * @var string
10 */
11 public static $action_post_type = 'frm_form_actions';
12
13 /**
14 * @var array|null
15 */
16 public static $registered_actions;
17
18 /**
19 * Variables saved in the post:
20 * post_content: json settings
21 * menu_order: form id
22 * post_excerpt: action type
23 */
24 public static function register_post_types() {
25 register_post_type(
26 self::$action_post_type,
27 array(
28 'label' => __( 'Form Actions', 'formidable' ),
29 'description' => '',
30 'public' => false,
31 'show_ui' => false,
32 'exclude_from_search' => true,
33 'show_in_nav_menus' => false,
34 'show_in_menu' => true,
35 'capability_type' => 'page',
36 'supports' => array( 'title', 'editor', 'excerpt', 'custom-fields', 'page-attributes' ),
37 'has_archive' => false,
38 )
39 );
40
41 self::actions_init();
42 }
43
44 public static function actions_init() {
45 self::$registered_actions = new Frm_Form_Action_Factory();
46 self::register_actions();
47 do_action( 'frm_form_actions_init' );
48 }
49
50 /**
51 * @return void
52 */
53 public static function register_actions() {
54 $action_classes = array(
55 'on_submit' => 'FrmOnSubmitAction',
56 'email' => 'FrmEmailAction',
57 'wppost' => 'FrmDefPostAction',
58 'register' => 'FrmDefRegAction',
59 'paypal' => 'FrmDefPayPalAction',
60 'payment' => 'FrmTransLiteAction',
61 'quiz' => 'FrmDefQuizAction',
62 'quiz_outcome' => 'FrmDefQuizOutcomeAction',
63 'mailchimp' => 'FrmDefMlcmpAction',
64 'api' => 'FrmDefApiAction',
65 'salesforce' => 'FrmDefSalesforceAction',
66 'activecampaign' => 'FrmDefActiveCampaignAction',
67 'constantcontact' => 'FrmDefConstContactAction',
68 'getresponse' => 'FrmDefGetResponseAction',
69 'hubspot' => 'FrmDefHubspotAction',
70 'zapier' => 'FrmDefZapierAction',
71 'n8n' => 'FrmDefN8NAction',
72 'twilio' => 'FrmDefTwilioAction',
73 'highrise' => 'FrmDefHighriseAction',
74 'mailpoet' => 'FrmDefMailpoetAction',
75 'aweber' => 'FrmDefAweberAction',
76 'convertkit' => 'FrmDefConvertKitAction',
77 'googlespreadsheet' => 'FrmDefGoogleSpreadsheetAction',
78 );
79
80 if ( ! FrmAppHelper::show_new_feature( 'n8n' ) ) {
81 unset( $action_classes['n8n'] );
82 }
83
84 $action_classes = apply_filters( 'frm_registered_form_actions', $action_classes );
85 $action_classes = self::maybe_unset_highrise( $action_classes );
86
87 include_once FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/email_action.php';
88 include_once FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/default_actions.php';
89
90 foreach ( $action_classes as $action_class ) {
91 self::$registered_actions->register( $action_class );
92 }
93 }
94
95 /**
96 * Remove the Highrise action if it is not registered.
97 *
98 * @since 6.23
99 *
100 * @param array $action_classes
101 *
102 * @return array
103 */
104 private static function maybe_unset_highrise( $action_classes ) {
105 if ( 'FrmDefHighriseAction' === ( $action_classes['highrise'] ?? '' ) ) {
106 unset( $action_classes['highrise'] );
107 }
108 return $action_classes;
109 }
110
111 /**
112 * @since 4.0
113 *
114 * @param array $values
115 */
116 public static function email_settings( $values ) {
117 $form = FrmForm::getOne( $values['id'] );
118 $groups = self::form_action_groups();
119
120 $action_controls = self::get_form_actions();
121 self::maybe_add_action_to_group( $action_controls, $groups );
122
123 $allowed = self::active_actions( $action_controls );
124
125 include FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/settings.php';
126 }
127
128 /**
129 * Add unknown actions to a group.
130 *
131 * @since 4.0
132 *
133 * @param array $action_controls
134 * @param array $groups
135 *
136 * @return void
137 */
138 private static function maybe_add_action_to_group( $action_controls, &$groups ) {
139 $grouped = array();
140
141 foreach ( $groups as $group ) {
142 if ( isset( $group['actions'] ) ) {
143 $grouped = array_merge( $grouped, $group['actions'] );
144 }
145 }
146
147 foreach ( $action_controls as $action ) {
148 if ( isset( $groups[ $action->id_base ] ) || in_array( $action->id_base, $grouped ) ) {
149 continue;
150 }
151
152 $this_group = $action->action_options['group'];
153
154 if ( ! isset( $groups[ $this_group ] ) ) {
155 $this_group = 'misc';
156 }
157
158 if ( ! isset( $groups[ $this_group ]['actions'] ) ) {
159 $groups[ $this_group ]['actions'] = array();
160 }
161 $groups[ $this_group ]['actions'][] = $action->id_base;
162
163 unset( $action );
164 }
165 }
166
167 /**
168 * @since 4.0
169 *
170 * @return array
171 */
172 public static function form_action_groups() {
173 $groups = array(
174 'misc' => array(
175 'name' => '',
176 'icon' => 'frm_icon_font frm_shuffle_icon',
177 'actions' => array(
178 'email',
179 'wppost',
180 'register',
181 'quiz',
182 'quiz_outcome',
183 'twilio',
184 ),
185 ),
186 'payment' => array(
187 'name' => __( 'eCommerce', 'formidable' ),
188 'icon' => 'frm_icon_font frm_credit_card_alt_icon',
189 'actions' => array(
190 'paypal',
191 'payment',
192 ),
193 ),
194 'marketing' => array(
195 'name' => __( 'Email Marketing', 'formidable' ),
196 'icon' => 'frm_icon_font frm_mail_bulk_icon',
197 'actions' => array(
198 'mailchimp',
199 'activecampaign',
200 'constantcontact',
201 'getresponse',
202 'aweber',
203 'mailpoet',
204 'convertkit',
205 ),
206 ),
207 'crm' => array(
208 'name' => __( 'CRM', 'formidable' ),
209 'icon' => 'frm_icon_font frm_address_card_icon',
210 'actions' => self::get_crm_actions(),
211 ),
212 );
213
214 return apply_filters( 'frm_action_groups', $groups );
215 }
216
217 /**
218 * Get the actions to include in the CRM section.
219 *
220 * @since 6.23
221 *
222 * @return array
223 */
224 private static function get_crm_actions() {
225 $crm_actions = array(
226 'salesforce',
227 'hubspot',
228 );
229
230 // Only include Highrise when the add-on is active.
231 // This is because Highrise is deprecated. We don't want to show it in Lite.
232 if ( class_exists( 'FrmHrsSettings' ) ) {
233 $crm_actions[] = 'highrise';
234 }
235
236 return $crm_actions;
237 }
238
239 /**
240 * Get the number of currently active form actions.
241 *
242 * @since 4.0
243 *
244 * @param array $action_controls
245 *
246 * @return array
247 */
248 private static function active_actions( $action_controls ) {
249 $allowed = array();
250
251 foreach ( $action_controls as $action_control ) {
252 if ( isset( $action_control->action_options['active'] ) && $action_control->action_options['active'] ) {
253 $allowed[] = $action_control->id_base;
254 }
255 }
256 return $allowed;
257 }
258
259 /**
260 * For each add-on, add an li, class, and javascript function. If active, add an additional class.
261 *
262 * @since 4.0
263 *
264 * @param object $action_control
265 * @param array $allowed
266 */
267 public static function show_action_icon_link( $action_control, $allowed ) {
268 $data = array();
269 $classes = ' frm_' . $action_control->id_base . '_action frm_single_action';
270
271 $group_class = ' frm-group-' . $action_control->action_options['group'];
272
273 /* translators: %s: Name of form action */
274 $upgrade_label = sprintf( esc_html__( '%s form actions', 'formidable' ), $action_control->action_options['tooltip'] );
275
276 $default_shown = array( 'wppost', 'register', 'payment', 'quiz', 'hubspot' );
277 $default_shown = array_values( array_diff( $default_shown, $allowed ) );
278 $default_position = array_search( $action_control->id_base, $default_shown );
279 $allowed_count = count( $allowed );
280
281 if ( isset( $action_control->action_options['active'] ) && $action_control->action_options['active'] ) {
282 $classes .= ' frm_active_action';
283 } else {
284 $classes .= ' frm_inactive_action';
285
286 if ( $default_position !== false && ( $allowed_count + $default_position ) < 6 ) {
287 $group_class .= ' frm-default-show';
288 }
289
290 $data['data-upgrade'] = $upgrade_label;
291 $data['data-medium'] = 'settings-' . $action_control->id_base;
292
293 $upgrading = FrmAddonsController::install_link( $action_control->action_options['plugin'] );
294
295 if ( isset( $upgrading['url'] ) ) {
296 $data['data-oneclick'] = json_encode( $upgrading );
297 }
298
299 if ( isset( $action_control->action_options['message'] ) ) {
300 $data['data-message'] = $action_control->action_options['message'];
301 }
302
303 $requires = FrmFormsHelper::get_plan_required( $upgrading );
304
305 if ( $requires && 'free' !== $requires ) {
306 $data['data-requires'] = $requires;
307 }
308 }//end if
309
310 // HTML to include on the icon.
311 $icon_atts = array();
312
313 if ( $action_control->action_options['color'] !== 'var(--primary-700)' ) {
314 $icon_atts = array(
315 'style' => '--primary-700:' . $action_control->action_options['color'],
316 );
317 }
318
319 include FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/_action_icon.php';
320 }
321
322 /**
323 * @param string $action
324 *
325 * @return array|FrmFormAction A single form action is returned when a specific $action value is requested.
326 */
327 public static function get_form_actions( $action = 'all' ) {
328 $temp_actions = self::$registered_actions;
329
330 if ( empty( $temp_actions ) ) {
331 self::actions_init();
332 $temp_actions = self::$registered_actions->actions;
333 } else {
334 $temp_actions = $temp_actions->actions;
335 }
336
337 $actions = array();
338
339 foreach ( $temp_actions as $a ) {
340 if ( 'all' !== $action && $a->id_base == $action ) {
341 return $a;
342 }
343
344 $actions[ $a->id_base ] = $a;
345 }
346
347 return $actions;
348 }
349
350 /**
351 * @since 2.0
352 *
353 * @param object $form
354 * @param array $values
355 *
356 * @return void
357 */
358 public static function list_actions( $form, $values ) {
359 if ( empty( $form ) ) {
360 return;
361 }
362
363 /**
364 * Use this hook to migrate old settings into a new action
365 *
366 * @since 2.0
367 */
368 do_action( 'frm_before_list_actions', $form );
369
370 $filters = array(
371 'post_status' => 'all',
372 );
373 $form_actions = FrmFormAction::get_action_for_form( $form->id, 'all', $filters );
374
375 /**
376 * @var array
377 */
378 $action_controls = self::get_form_actions();
379
380 $action_map = array();
381
382 foreach ( $action_controls as $key => $control ) {
383 $action_map[ $control->id_base ] = $key;
384 }
385
386 self::maybe_show_limit_warning( $form->id, $form_actions );
387
388 foreach ( $form_actions as $action ) {
389 if ( ! isset( $action_map[ $action->post_excerpt ] ) ) {
390 // don't try and show settings if action no longer exists
391 continue;
392 }
393
394 self::action_control( $action, $form, $action->ID, $action_controls[ $action_map[ $action->post_excerpt ] ], $values );
395 }
396 }
397
398 /**
399 * Show a warning before the form actions list if there are 99 actions, and the limit is set to 99.
400 * If it is filtered, the warning is still shown when applicable, just using the new limit.
401 *
402 * @since 6.17
403 *
404 * @param int|string $form_id
405 * @param array $form_actions
406 *
407 * @return void
408 */
409 private static function maybe_show_limit_warning( $form_id, $form_actions ) {
410 $count = count( $form_actions );
411
412 if ( $count < 99 ) {
413 return;
414 }
415
416 $limit = FrmFormAction::get_action_limit( $form_id );
417
418 if ( $limit < 99 || $count < $limit ) {
419 return;
420 }
421
422 $documentation_url = 'https://formidableforms.com/knowledgebase/frm_form_action_limit/#kb-increase-limit-of-form-actions';
423
424 echo '<div class="frm_warning_style">';
425 FrmAppHelper::icon_by_class( 'frm_icon_font frm_alert_icon' );
426 echo '&nbsp;';
427 printf(
428 // translators: %s: URL to documentation
429 esc_html__( 'You have reached your form action limit. To increase this limit, you will require additional code. Visit our documentation at %s.', 'formidable' ),
430 '<a href="' . esc_url( $documentation_url ) . '" target="_blank">' . esc_html( $documentation_url ) . '</a>'
431 );
432 echo '</div>';
433 }
434
435 /**
436 * @param WP_Post $form_action
437 * @param object $form
438 * @param int $action_key Action ID.
439 * @param FrmFormAction $action_control
440 * @param array $values
441 *
442 * @return void
443 */
444 public static function action_control( $form_action, $form, $action_key, $action_control, $values ) {
445 $action_control->_set( $action_key );
446
447 $use_logging = self::should_show_log_message( $form_action->post_excerpt );
448
449 include FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/form_action.php';
450 }
451
452 public static function add_form_action() {
453 FrmAppHelper::permission_check( 'frm_edit_forms' );
454 check_ajax_referer( 'frm_ajax', 'nonce' );
455
456 global $frm_vars;
457
458 $action_key = FrmAppHelper::get_param( 'list_id', '', 'post', 'absint' );
459 $action_type = FrmAppHelper::get_param( 'type', '', 'post', 'sanitize_text_field' );
460
461 /**
462 * @var FrmFormAction
463 */
464 $action_control = self::get_form_actions( $action_type );
465 $action_control->_set( $action_key );
466
467 $form_id = FrmAppHelper::get_param( 'form_id', '', 'post', 'absint' );
468
469 $form_action = $action_control->prepare_new( $form_id );
470 $use_logging = self::should_show_log_message( $action_type );
471
472 $values = array();
473 $form = self::fields_to_values( $form_id, $values );
474
475 include FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/form_action.php';
476 wp_die();
477 }
478
479 public static function fill_action() {
480 FrmAppHelper::permission_check( 'frm_edit_forms' );
481 check_ajax_referer( 'frm_ajax', 'nonce' );
482
483 $action_key = FrmAppHelper::get_param( 'action_id', '', 'post', 'absint' );
484 $action_type = FrmAppHelper::get_param( 'action_type', '', 'post', 'sanitize_text_field' );
485
486 $action_control = self::get_form_actions( $action_type );
487
488 if ( empty( $action_control ) ) {
489 wp_die();
490 }
491
492 $form_action = $action_control->get_single_action( $action_key );
493
494 $values = array();
495 $form = self::fields_to_values( $form_action->menu_order, $values );
496
497 $use_logging = self::should_show_log_message( $action_type );
498
499 include FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/_action_inside.php';
500 wp_die();
501 }
502
503 /**
504 * @since 3.06.04
505 *
506 * @param string $action_type
507 *
508 * @return bool
509 */
510 private static function should_show_log_message( $action_type ) {
511 $logging = array( 'api', 'salesforce', 'constantcontact', 'activecampaign' );
512 return in_array( $action_type, $logging, true ) && ! function_exists( 'frm_log_autoloader' );
513 }
514
515 /**
516 * @param int|string $form_id
517 * @param array $values
518 *
519 * @return object
520 */
521 private static function fields_to_values( $form_id, array &$values ) {
522 $form = FrmForm::getOne( $form_id );
523
524 $values = array(
525 'fields' => array(),
526 'id' => $form->id,
527 );
528
529 $fields = FrmField::get_all_for_form( $form->id );
530
531 foreach ( $fields as $k => $f ) {
532 $f = (array) $f;
533 $opts = (array) $f['field_options'];
534 $f = array_merge( $opts, $f );
535
536 if ( ! isset( $f['post_field'] ) ) {
537 $f['post_field'] = '';
538 }
539 $values['fields'][] = $f;
540 unset( $k, $f );
541 }
542
543 return $form;
544 }
545
546 /**
547 * @param int $form_id
548 *
549 * @return void
550 */
551 public static function update_settings( $form_id ) {
552 FrmAppHelper::permission_check( 'frm_edit_forms' );
553 $process_form = FrmAppHelper::get_post_param( 'process_form', '', 'sanitize_text_field' );
554
555 if ( ! wp_verify_nonce( $process_form, 'process_form_nonce' ) ) {
556 $frm_settings = FrmAppHelper::get_settings();
557 $error_args = array(
558 'title' => __( 'Verification failed', 'formidable' ),
559 'body' => $frm_settings->admin_permission,
560 'cancel_url' => add_query_arg(
561 array(
562 'page' => 'formidable',
563 'frm_action' => 'settings',
564 'id' => $form_id,
565 ),
566 admin_url( 'admin.php?' )
567 ),
568 );
569 FrmAppController::show_error_modal( $error_args );
570 return;
571 }
572
573 global $wpdb;
574
575 $registered_actions = self::$registered_actions->actions;
576
577 $old_actions = FrmDb::get_col(
578 $wpdb->posts,
579 array(
580 'post_type' => self::$action_post_type,
581 'menu_order' => $form_id,
582 ),
583 'ID'
584 );
585 $new_actions = array();
586
587 foreach ( $registered_actions as $registered_action ) {
588 $action_ids = $registered_action->update_callback( $form_id );
589
590 if ( ! empty( $action_ids ) ) {
591 $new_actions[] = $action_ids;
592 }
593 }
594
595 // Only use array_merge if there are new actions.
596 if ( ! empty( $new_actions ) ) {
597 $new_actions = call_user_func_array( 'array_merge', $new_actions );
598 }
599
600 $old_actions = array_diff( $old_actions, $new_actions );
601
602 self::delete_missing_actions( $old_actions );
603
604 FrmOnSubmitHelper::save_on_submit_settings( $form_id );
605 }
606
607 /**
608 * @param array $old_actions
609 *
610 * @return void
611 */
612 public static function delete_missing_actions( $old_actions ) {
613 if ( ! empty( $old_actions ) ) {
614 foreach ( $old_actions as $old_id ) {
615 wp_delete_post( $old_id );
616 }
617 FrmDb::cache_delete_group( 'frm_actions' );
618 }
619 }
620
621 /**
622 * @param int|string $entry_id
623 * @param int|string $form_id
624 * @param array $args
625 *
626 * @return void
627 */
628 public static function trigger_create_actions( $entry_id, $form_id, $args = array() ) {
629 $filter_args = $args;
630 $filter_args['entry_id'] = $entry_id;
631 $filter_args['form_id'] = $form_id;
632
633 /**
634 * @since 2.0.23
635 * @since 6.11.2 $filter_args is now passed instead of $args. It includes additional ID data.
636 *
637 * @param string $event 'create' by default. Pro may filter this value to 'draft' instead.
638 * @param array $filter_args
639 */
640 $event = apply_filters( 'frm_trigger_create_action', 'create', $filter_args );
641
642 self::trigger_actions( $event, $form_id, $entry_id, 'all', $args );
643 }
644
645 /**
646 * @param string $event
647 * @param int|object|string $form
648 * @param int|string $entry
649 * @param string $type
650 * @param array $args
651 *
652 * @return void
653 */
654 public static function trigger_actions( $event, $form, $entry, $type = 'all', $args = array() ) {
655 $action_status = array(
656 'post_status' => 'publish',
657 );
658 $form_actions = FrmFormAction::get_action_for_form( ( is_object( $form ) ? $form->id : $form ), $type, $action_status );
659
660 if ( empty( $form_actions ) ) {
661 return;
662 }
663
664 FrmForm::maybe_get_form( $form );
665
666 if ( ! is_object( $form ) ) {
667 return;
668 }
669
670 $link_settings = self::get_form_actions( $type );
671
672 if ( 'all' !== $type ) {
673 $link_settings = array( $type => $link_settings );
674 }
675
676 $stored_actions = array();
677 $action_priority = array();
678
679 if ( in_array( $event, array( 'create', 'update' ), true ) && defined( 'WP_IMPORTING' ) && WP_IMPORTING ) {
680 $this_event = 'import';
681 } else {
682 $this_event = $event;
683 }
684
685 foreach ( $form_actions as $action ) {
686
687 $skip_this_action = ! in_array( $this_event, $action->post_content['event'], true ) || FrmOnSubmitAction::$slug === $action->post_excerpt;
688 $skip_this_action = apply_filters( 'frm_skip_form_action', $skip_this_action, compact( 'action', 'entry', 'form', 'event' ) );
689
690 if ( $skip_this_action ) {
691 continue;
692 }
693
694 if ( ! is_object( $entry ) ) {
695 $entry = FrmEntry::getOne( $entry, true );
696 }
697
698 if ( empty( $entry ) || ( FrmEntriesHelper::DRAFT_ENTRY_STATUS === (int) $entry->is_draft && 'draft' !== $event ) ) {
699 continue;
700 }
701
702 $child_entry = ( is_numeric( $form->parent_form_id ) && $form->parent_form_id ) || ( $entry && ( $entry->form_id != $form->id || $entry->parent_item_id ) ) || ! empty( $args['is_child'] );
703
704 if ( $child_entry ) {
705 // maybe trigger actions for sub forms
706 $trigger_children = apply_filters( 'frm_use_embedded_form_actions', false, compact( 'form', 'entry' ) );
707
708 if ( ! $trigger_children ) {
709 continue;
710 }
711 }
712
713 // Check conditional logic.
714 $stop = FrmFormAction::action_conditions_met( $action, $entry );
715
716 if ( $stop ) {
717 continue;
718 }
719
720 // Store actions so they can be triggered with the correct priority.
721 $stored_actions[ $action->ID ] = $action;
722 $action_priority[ $action->ID ] = $link_settings[ $action->post_excerpt ]->action_options['priority'];
723
724 unset( $action );
725 }//end foreach
726
727 if ( ! empty( $stored_actions ) ) {
728 asort( $action_priority );
729
730 // Make sure hooks are loaded.
731 new FrmNotification();
732
733 foreach ( $action_priority as $action_id => $priority ) {
734 $action = $stored_actions[ $action_id ];
735
736 /**
737 * Allows custom form action trigger.
738 *
739 * @since 6.10
740 *
741 * @param bool $skip Skip default trigger.
742 * @param object $action Action object.
743 * @param object $entry Entry object.
744 * @param object $form Form object.
745 * @param string $event Event ('create' or 'update').
746 */
747 if ( false === apply_filters( 'frm_custom_trigger_action', false, $action, $entry, $form, $event ) ) {
748 do_action( 'frm_trigger_' . $action->post_excerpt . '_action', $action, $entry, $form, $event );
749 do_action( 'frm_trigger_' . $action->post_excerpt . '_' . $event . '_action', $action, $entry, $form );
750 }
751
752 // If post is created, get updated $entry object.
753 if ( $action->post_excerpt === 'wppost' && $event === 'create' ) {
754 $entry = FrmEntry::getOne( $entry->id, true );
755 }
756 }//end foreach
757 }//end if
758 }
759
760 /**
761 * @param int|string $form_id
762 * @param array $values
763 * @param array $args
764 *
765 * @return void
766 */
767 public static function duplicate_form_actions( $form_id, $values, $args = array() ) {
768 if ( empty( $args['old_id'] ) ) {
769 // Continue if we know which actions to copy.
770 return;
771 }
772
773 /**
774 * @var array
775 */
776 $action_controls = self::get_form_actions();
777
778 foreach ( $action_controls as $action_control ) {
779 $action_control->duplicate_form_actions( $form_id, $args['old_id'] );
780 unset( $action_control );
781 }
782 }
783
784 /**
785 * @param string $where
786 *
787 * @return string
788 */
789 public static function limit_by_type( $where ) {
790 global $frm_vars, $wpdb;
791
792 if ( ! isset( $frm_vars['action_type'] ) ) {
793 return $where;
794 }
795
796 $where .= $wpdb->prepare( ' AND post_excerpt = %s ', $frm_vars['action_type'] );
797
798 return $where;
799 }
800
801 /**
802 * Prevent WPML from filtering form actions based on the active language.
803 *
804 * @since 6.20
805 *
806 * @param bool|null $null
807 * @param string $post_type
808 *
809 * @return bool|null
810 */
811 public static function prevent_wpml_translations( $null, $post_type ) {
812 if ( self::$action_post_type === $post_type ) {
813 return false;
814 }
815 return $null;
816 }
817 }
818
819 class Frm_Form_Action_Factory {
820
821 /**
822 * @var array
823 */
824 public $actions = array();
825
826 public function __construct() {
827 add_action( 'frm_form_actions_init', array( $this, '_register_actions' ), 100 );
828 }
829
830 /**
831 * @param string $action_class
832 *
833 * @return void
834 */
835 public function register( $action_class ) {
836 $this->actions[ $action_class ] = new $action_class();
837 }
838
839 /**
840 * @param string $action_class
841 *
842 * @return void
843 */
844 public function unregister( $action_class ) {
845 if ( isset( $this->actions[ $action_class ] ) ) {
846 unset( $this->actions[ $action_class ] );
847 }
848 }
849
850 public function _register_actions() {
851 $keys = array_keys( $this->actions );
852
853 foreach ( $keys as $key ) {
854 // don't register new action if old action with the same id is already registered
855 if ( ! isset( $this->actions[ $key ] ) ) {
856 $this->actions[ $key ]->_register();
857 }
858 }
859 }
860 }
861