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

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