PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.20
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.20
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
← All changes | classes/controllers/FrmFormActionsController.php +98 -606 6.326.20 View file →
@@ -3,16 +3,12 @@
3 3 die( 'You are not allowed to call this page directly.' );
4 4 }
5 5
6 6 class FrmFormActionsController {
7 -
8 - /**
9 - * @var string
10 - */
11 7 public static $action_post_type = 'frm_form_actions';
12 8
13 9 /**
14 - * @var Frm_Form_Action_Factory|null
10 + * @var array|null
15 11 */
16 12 public static $registered_actions;
17 13
18 14 /**
@@ -37,9 +33,8 @@
37 33 'has_archive' => false,
38 34 )
39 35 );
40 36
41 - self::maybe_setup_unlicensed_action_gate();
42 37 self::actions_init();
43 38 }
44 39
45 40 public static function actions_init() {
@@ -56,118 +51,47 @@
56 51 'on_submit' => 'FrmOnSubmitAction',
57 52 'email' => 'FrmEmailAction',
58 53 'wppost' => 'FrmDefPostAction',
59 54 'register' => 'FrmDefRegAction',
60 - 'stripe' => 'FrmStripeLiteAction',
61 - 'square' => 'FrmSquareAction',
62 - 'paypal' => 'FrmPayPalLiteAction',
63 - 'paypal-legacy' => 'FrmDefPayPalLegacyAction',
55 + 'paypal' => 'FrmDefPayPalAction',
64 56 'payment' => 'FrmTransLiteAction',
65 57 'quiz' => 'FrmDefQuizAction',
66 58 'quiz_outcome' => 'FrmDefQuizOutcomeAction',
59 + 'mailchimp' => 'FrmDefMlcmpAction',
67 60 'api' => 'FrmDefApiAction',
68 - 'mailchimp' => 'FrmDefMlcmpAction',
61 + 'salesforce' => 'FrmDefSalesforceAction',
69 62 'activecampaign' => 'FrmDefActiveCampaignAction',
70 63 'constantcontact' => 'FrmDefConstContactAction',
71 64 'getresponse' => 'FrmDefGetResponseAction',
65 + 'hubspot' => 'FrmDefHubspotAction',
66 + 'zapier' => 'FrmDefZapierAction',
67 + 'twilio' => 'FrmDefTwilioAction',
68 + 'highrise' => 'FrmDefHighriseAction',
72 69 'mailpoet' => 'FrmDefMailpoetAction',
70 + 'aweber' => 'FrmDefAweberAction',
73 71 'convertkit' => 'FrmDefConvertKitAction',
74 - 'aweber' => 'FrmDefAweberAction',
75 - 'twilio' => 'FrmDefTwilioAction',
76 - 'salesforce' => 'FrmDefSalesforceAction',
77 - 'hubspot' => 'FrmDefHubspotAction',
78 - 'highrise' => 'FrmDefHighriseAction',
79 - 'zapier' => 'FrmDefZapierAction',
80 72 'googlespreadsheet' => 'FrmDefGoogleSpreadsheetAction',
81 - 'n8n' => 'FrmDefN8NAction',
82 73 );
83 74
84 75 $action_classes = apply_filters( 'frm_registered_form_actions', $action_classes );
85 - $action_classes = self::maybe_unset_highrise( $action_classes );
86 76
87 77 include_once FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/email_action.php';
88 78 include_once FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/default_actions.php';
89 79
90 - // This needs to be called after we include default_actions.php or FrmDefPayPalLegacyAction will never exist.
91 - if ( 'FrmPayPalLiteAction' === $action_classes['paypal'] || ! class_exists( 'FrmPaymentAction' ) || ! class_exists( 'FrmDefPayPalLegacyAction' ) ) {
92 - unset( $action_classes['paypal-legacy'] );
93 - }
94 -
95 80 foreach ( $action_classes as $action_class ) {
96 81 self::$registered_actions->register( $action_class );
97 82 }
98 -
99 - self::apply_default_action_descriptions();
100 83 }
101 84
102 85 /**
103 - * Sets default descriptions on registered actions from a central list.
104 - *
105 - * Keeps the description when an add-on replaces a base action class without its own.
106 - *
107 - * @since 6.31
108 - *
109 - * @return void
110 - */
111 - private static function apply_default_action_descriptions() {
112 - $descriptions = array(
113 - 'on_submit' => __( 'Success messages', 'formidable' ),
114 - 'email' => __( 'Autoresponder alerts', 'formidable' ),
115 - 'wppost' => __( 'Content publishing', 'formidable' ),
116 - 'register' => __( 'Account creation', 'formidable' ),
117 - 'payment' => __( 'Transaction alerts', 'formidable' ),
118 - 'stripe' => __( 'Payment gateway', 'formidable' ),
119 - 'square' => __( 'Payment gateway', 'formidable' ),
120 - 'paypal' => __( 'Payment gateway', 'formidable' ),
121 - 'quiz' => __( 'Automated grading', 'formidable' ),
122 - 'quiz_outcome' => __( 'Result logic', 'formidable' ),
123 - 'aweber' => __( 'List triggers', 'formidable' ),
124 - 'mailchimp' => __( 'Subscription confirmation', 'formidable' ),
125 - 'zapier' => __( 'App automation', 'formidable' ),
126 - 'n8n' => __( 'Workflow automation', 'formidable' ),
127 - 'twilio' => __( 'Text notifications', 'formidable' ),
128 - 'activecampaign' => __( 'Contact automation', 'formidable' ),
129 - 'salesforce' => __( 'Lead automation', 'formidable' ),
130 - 'constantcontact' => __( 'Content distribution', 'formidable' ),
131 - 'getresponse' => __( 'Success notifications', 'formidable' ),
132 - 'hubspot' => __( 'CRM alerts', 'formidable' ),
133 - 'mailpoet' => __( 'Plugin automation', 'formidable' ),
134 - 'api' => __( 'System integration', 'formidable' ),
135 - 'googlespreadsheet' => __( 'Spreadsheet sync', 'formidable' ),
136 - 'convertkit' => __( 'Broadcast publishing', 'formidable' ),
137 - );
138 -
139 - foreach ( self::$registered_actions->actions as $action ) {
140 - if ( $action->action_options['description'] === '' && isset( $descriptions[ $action->id_base ] ) ) {
141 - $action->action_options['description'] = $descriptions[ $action->id_base ];
142 - }
143 - }
144 - }
145 -
146 - /**
147 - * Remove the Highrise action if it is not registered.
148 - *
149 - * @since 6.23
150 - *
151 - * @param array $action_classes
152 - *
153 - * @return array
154 - */
155 - private static function maybe_unset_highrise( $action_classes ) {
156 - if ( 'FrmDefHighriseAction' === ( $action_classes['highrise'] ?? '' ) ) {
157 - unset( $action_classes['highrise'] );
158 - }
159 - return $action_classes;
160 - }
161 -
162 - /**
163 86 * @since 4.0
164 87 *
165 88 * @param array $values
166 89 */
167 90 public static function email_settings( $values ) {
168 - $form = FrmForm::getOne( $values['id'] );
169 - $groups = self::form_action_groups();
91 + $form = FrmForm::getOne( $values['id'] );
92 + $groups = self::form_action_groups();
93 +
170 94 $action_controls = self::get_form_actions();
171 95 self::maybe_add_action_to_group( $action_controls, $groups );
172 96
173 97 $allowed = self::active_actions( $action_controls );
@@ -178,41 +102,23 @@
178 102 /**
179 103 * Add unknown actions to a group.
180 104 *
181 105 * @since 4.0
182 - *
183 - * @param array $action_controls
184 - * @param array $groups
185 - *
186 - * @return void
187 106 */
188 107 private static function maybe_add_action_to_group( $action_controls, &$groups ) {
189 108 $grouped = array();
190 -
191 109 foreach ( $groups as $group ) {
192 110 if ( isset( $group['actions'] ) ) {
193 111 $grouped = array_merge( $grouped, $group['actions'] );
194 112 }
195 -
196 - // Also collect actions from sections
197 - if ( ! isset( $group['sections'] ) ) {
198 - continue;
199 - }
200 -
201 - foreach ( $group['sections'] as $section ) {
202 - if ( isset( $section['actions'] ) ) {
203 - $grouped = array_merge( $grouped, $section['actions'] );
204 - }
205 - }
206 113 }
207 114
208 115 foreach ( $action_controls as $action ) {
209 - if ( isset( $groups[ $action->id_base ] ) || in_array( $action->id_base, $grouped, true ) ) {
116 + if ( isset( $groups[ $action->id_base ] ) || in_array( $action->id_base, $grouped ) ) {
210 117 continue;
211 118 }
212 119
213 120 $this_group = $action->action_options['group'];
214 -
215 121 if ( ! isset( $groups[ $this_group ] ) ) {
216 122 $this_group = 'misc';
217 123 }
218 124
@@ -230,48 +136,32 @@
230 136 *
231 137 * @return array
232 138 */
233 139 public static function form_action_groups() {
234 - // Get all action controls to check which are active
235 - $action_controls = self::get_form_actions();
236 -
237 - // Determine which actions are currently available
238 - $available_actions = self::get_available_my_actions( $action_controls );
239 -
240 - // Featured actions are add-ons that are NOT currently available
241 - $all_addon_actions = array(
242 - 'api',
243 - 'register',
244 - 'n8n',
245 - 'quiz',
246 - 'quiz_outcome',
247 - 'googlespreadsheet',
248 - );
249 - $featured_actions = array_diff( $all_addon_actions, $available_actions );
250 -
251 140 $groups = array(
252 - 'my_actions' => array(
253 - 'name' => __( 'My Actions', 'formidable' ),
254 - 'icon' => 'frmfont frm_shuffle_icon',
255 - 'sections' => array(
256 - 'active' => array(
257 - 'name' => '',
258 - 'actions' => $available_actions,
259 - ),
260 - 'featured' => array(
261 - 'name' => __( 'Featured', 'formidable' ),
262 - 'actions' => array_values( $featured_actions ),
263 - ),
141 + 'misc' => array(
142 + 'name' => '',
143 + 'icon' => 'frm_icon_font frm_shuffle_icon',
144 + 'actions' => array(
145 + 'email',
146 + 'wppost',
147 + 'register',
148 + 'quiz',
149 + 'quiz_outcome',
150 + 'twilio',
264 151 ),
265 152 ),
266 - 'payment' => array(
267 - 'name' => __( 'E-Commerce', 'formidable' ),
268 - 'icon' => 'frmfont frm_credit_card_alt_icon',
269 - 'actions' => self::get_payment_actions( $action_controls ),
153 + 'payment' => array(
154 + 'name' => __( 'eCommerce', 'formidable' ),
155 + 'icon' => 'frm_icon_font frm_credit_card_alt_icon',
156 + 'actions' => array(
157 + 'paypal',
158 + 'payment',
159 + ),
270 160 ),
271 - 'marketing' => array(
272 - 'name' => __( 'Marketing', 'formidable' ),
273 - 'icon' => 'frmfont frm_mail_bulk_icon',
161 + 'marketing' => array(
162 + 'name' => __( 'Email Marketing', 'formidable' ),
163 + 'icon' => 'frm_icon_font frm_mail_bulk_icon',
274 164 'actions' => array(
275 165 'mailchimp',
276 166 'activecampaign',
277 167 'constantcontact',
@@ -277,22 +167,19 @@
277 167 'constantcontact',
278 168 'getresponse',
279 169 'aweber',
280 170 'mailpoet',
281 - 'convertkit',
282 - 'twilio',
283 171 ),
284 172 ),
285 - 'crm' => array(
173 + 'crm' => array(
286 174 'name' => __( 'CRM', 'formidable' ),
287 - 'icon' => 'frmfont frm_address_card_icon',
288 - 'actions' => self::get_crm_actions(),
175 + 'icon' => 'frm_icon_font frm_address_card_icon',
176 + 'actions' => array(
177 + 'salesforce',
178 + 'hubspot',
179 + 'highrise',
180 + ),
289 181 ),
290 - 'misc' => array(
291 - 'name' => __( 'Misc', 'formidable' ),
292 - 'icon' => 'frmfont frm_shuffle_icon',
293 - 'actions' => self::get_misc_actions( $action_controls ),
294 - ),
295 182 );
296 183
297 184 return apply_filters( 'frm_action_groups', $groups );
298 185 }
@@ -297,142 +184,21 @@
297 184 return apply_filters( 'frm_action_groups', $groups );
298 185 }
299 186
300 187 /**
301 - * Get the actions that are currently available (active) for My Actions section.
302 - *
303 - * @since 6.31
304 - *
305 - * @param array $action_controls The registered action controls.
306 - *
307 - * @return array
308 - */
309 - private static function get_available_my_actions( $action_controls ) {
310 - $available = array(
311 - 'on_submit',
312 - 'email',
313 - 'stripe',
314 - 'square',
315 - 'paypal',
316 - );
317 -
318 - // Include all actions that are marked as active, including custom actions.
319 - // This ensures custom actions appear in "My Actions" when enabled.
320 - foreach ( $action_controls as $action_id => $action_control ) {
321 - if ( ! in_array( $action_id, $available, true ) && ! empty( $action_control->action_options['active'] ) ) {
322 - $available[] = $action_id;
323 - }
324 - }
325 -
326 - return $available;
327 - }
328 -
329 - /**
330 - * Get the actions to include in the Misc section.
331 - *
332 - * @since 6.31
333 - *
334 - * @param array $action_controls The registered action controls.
335 - *
336 - * @return array
337 - */
338 - private static function get_misc_actions( $action_controls ) {
339 - $misc_actions = array(
340 - 'on_submit',
341 - 'email',
342 - 'wppost',
343 - 'register',
344 - 'api',
345 - 'n8n',
346 - 'quiz',
347 - 'quiz_outcome',
348 - 'googlespreadsheet',
349 - );
350 -
351 - // Include all active actions that aren't in specific groups (payment, marketing, crm).
352 - // This ensures custom actions appear in "Misc" when enabled.
353 - $payment_actions = self::get_payment_actions( $action_controls );
354 - $marketing_actions = array( 'mailchimp', 'activecampaign', 'constantcontact', 'getresponse', 'aweber', 'mailpoet', 'convertkit', 'twilio' );
355 -
356 - $excluded_actions = array_merge( $payment_actions, $marketing_actions, self::get_crm_actions() );
357 -
358 - foreach ( $action_controls as $action_id => $action_control ) {
359 - if ( ! in_array( $action_id, $misc_actions, true ) && ! in_array( $action_id, $excluded_actions, true ) && ! empty( $action_control->action_options['active'] ) ) {
360 - $misc_actions[] = $action_id;
361 - }
362 - }
363 -
364 - return $misc_actions;
365 - }
366 -
367 - /**
368 - * Get the actions to include in the E-Commerce section.
369 - *
370 - * @since 6.33
371 - *
372 - * @param array $action_controls
373 - *
374 - * @return array
375 - */
376 - private static function get_payment_actions( $action_controls ) {
377 - $payment_actions = array(
378 - 'paypal',
379 - 'stripe',
380 - 'square',
381 - );
382 -
383 - if ( isset( $action_controls['paypal-legacy'] ) ) {
384 - $payment_actions[] = 'paypal-legacy';
385 - }
386 -
387 - if ( isset( $action_controls['payment'] ) ) {
388 - $payment_actions[] = 'payment';
389 - }
390 -
391 - return $payment_actions;
392 - }
393 -
394 - /**
395 - * Get the actions to include in the CRM section.
396 - *
397 - * @since 6.23
398 - *
399 - * @return array
400 - */
401 - private static function get_crm_actions() {
402 - $crm_actions = array(
403 - 'salesforce',
404 - 'hubspot',
405 - 'zapier',
406 - );
407 -
408 - // Only include Highrise when the add-on is active.
409 - // This is because Highrise is deprecated. We don't want to show it in Lite.
410 - if ( class_exists( 'FrmHrsSettings' ) ) {
411 - $crm_actions[] = 'highrise';
412 - }
413 -
414 - return $crm_actions;
415 - }
416 -
417 - /**
418 188 * Get the number of currently active form actions.
419 189 *
420 190 * @since 4.0
421 191 *
422 - * @param array $action_controls
423 - *
424 192 * @return array
425 193 */
426 194 private static function active_actions( $action_controls ) {
427 195 $allowed = array();
428 -
429 196 foreach ( $action_controls as $action_control ) {
430 - if ( ! empty( $action_control->action_options['active'] ) ) {
197 + if ( isset( $action_control->action_options['active'] ) && $action_control->action_options['active'] ) {
431 198 $allowed[] = $action_control->id_base;
432 199 }
433 200 }
434 -
435 201 return $allowed;
436 202 }
437 203
438 204 /**
@@ -438,15 +204,15 @@
438 204 /**
439 205 * For each add-on, add an li, class, and javascript function. If active, add an additional class.
440 206 *
441 207 * @since 4.0
442 - *
443 208 * @param object $action_control
444 209 * @param array $allowed
445 210 */
446 211 public static function show_action_icon_link( $action_control, $allowed ) {
447 - $data = array();
448 - $classes = ' frm_' . $action_control->id_base . '_action frm_single_action';
212 + $data = array();
213 + $classes = ' frm_' . $action_control->id_base . '_action frm_single_action';
214 +
449 215 $group_class = ' frm-group-' . $action_control->action_options['group'];
450 216
451 217 /* translators: %s: Name of form action */
452 218 $upgrade_label = sprintf( esc_html__( '%s form actions', 'formidable' ), $action_control->action_options['tooltip'] );
@@ -452,20 +218,15 @@
452 218 $upgrade_label = sprintf( esc_html__( '%s form actions', 'formidable' ), $action_control->action_options['tooltip'] );
453 219
454 220 $default_shown = array( 'wppost', 'register', 'payment', 'quiz', 'hubspot' );
455 221 $default_shown = array_values( array_diff( $default_shown, $allowed ) );
456 - $default_position = array_search( $action_control->id_base, $default_shown, true );
222 + $default_position = array_search( $action_control->id_base, $default_shown );
457 223 $allowed_count = count( $allowed );
458 224
459 - if ( ! empty( $action_control->action_options['active'] ) ) {
225 + if ( isset( $action_control->action_options['active'] ) && $action_control->action_options['active'] ) {
460 226 $classes .= ' frm_active_action';
461 227 } else {
462 228 $classes .= ' frm_inactive_action';
463 -
464 - if ( str_contains( $action_control->action_options['classes'], 'frm_show_expired_modal' ) ) {
465 - $classes .= ' frm_show_expired_modal';
466 - }
467 -
468 229 if ( $default_position !== false && ( $allowed_count + $default_position ) < 6 ) {
469 230 $group_class .= ' frm-default-show';
470 231 }
471 232
@@ -472,9 +233,8 @@
472 233 $data['data-upgrade'] = $upgrade_label;
473 234 $data['data-medium'] = 'settings-' . $action_control->id_base;
474 235
475 236 $upgrading = FrmAddonsController::install_link( $action_control->action_options['plugin'] );
476 -
477 237 if ( isset( $upgrading['url'] ) ) {
478 238 $data['data-oneclick'] = json_encode( $upgrading );
479 239 }
480 240
@@ -482,67 +242,41 @@
482 242 $data['data-message'] = $action_control->action_options['message'];
483 243 }
484 244
485 245 $requires = FrmFormsHelper::get_plan_required( $upgrading );
486 -
487 246 if ( $requires && 'free' !== $requires ) {
488 247 $data['data-requires'] = $requires;
489 248 }
490 -
491 - $learn_more_slug = ! empty( $action_control->action_options['learn-more'] )
492 - ? $action_control->action_options['learn-more']
493 - : self::get_learn_more_slug( $action_control->id_base );
494 -
495 - if ( $learn_more_slug ) {
496 - $data['data-learn-more'] = FrmAppHelper::get_doc_url(
497 - $learn_more_slug,
498 - 'settings-' . $action_control->id_base,
499 - ! str_contains( $learn_more_slug, '/' )
500 - );
501 - }
502 249 }//end if
503 250
504 - include FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/_action_icon.php';
505 - }
506 -
507 - /**
508 - * Get the HTML attributes for the action icon.
509 - *
510 - * @since 6.31
511 - *
512 - * @param object $action_control
513 - *
514 - * @return array
515 - */
516 - public static function get_action_icon_atts( $action_control ) {
517 - if ( 'var(--primary-700)' !== $action_control->action_options['color'] ) {
518 - return array(
251 + // HTML to include on the icon.
252 + $icon_atts = array();
253 + if ( $action_control->action_options['color'] !== 'var(--primary-700)' ) {
254 + $icon_atts = array(
519 255 'style' => '--primary-700:' . $action_control->action_options['color'],
520 256 );
521 257 }
522 258
523 - return array();
259 + include FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/_action_icon.php';
524 260 }
525 261
526 262 /**
527 263 * @param string $action
528 - *
529 264 * @return array|FrmFormAction A single form action is returned when a specific $action value is requested.
530 265 */
531 266 public static function get_form_actions( $action = 'all' ) {
532 267 $temp_actions = self::$registered_actions;
533 -
534 - if ( $temp_actions ) {
535 - $temp_actions = $temp_actions->actions;
536 - } else {
268 + if ( empty( $temp_actions ) ) {
537 269 self::actions_init();
538 270 $temp_actions = self::$registered_actions->actions;
271 + } else {
272 + $temp_actions = $temp_actions->actions;
539 273 }
540 274
541 275 $actions = array();
542 276
543 277 foreach ( $temp_actions as $a ) {
544 - if ( 'all' !== $action && $a->id_base === $action ) {
278 + if ( 'all' !== $action && $a->id_base == $action ) {
545 279 return $a;
546 280 }
547 281
548 282 $actions[ $a->id_base ] = $a;
@@ -552,16 +286,11 @@
552 286 }
553 287
554 288 /**
555 289 * @since 2.0
556 - *
557 - * @param object $form
558 - * @param array $values
559 - *
560 - * @return void
561 290 */
562 291 public static function list_actions( $form, $values ) {
563 - if ( ! $form ) {
292 + if ( empty( $form ) ) {
564 293 return;
565 294 }
566 295
567 296 /**
@@ -588,15 +317,11 @@
588 317 }
589 318
590 319 self::maybe_show_limit_warning( $form->id, $form_actions );
591 320
592 - echo '<p class="frm-mb-lg frm-no-actions-message' . ( $form_actions ? ' frm_hidden' : '' ) . '"> '
593 - . esc_html__( 'No actions have been added yet. Select an action above to get started.', 'formidable' )
594 - . '</p>';
595 -
596 321 foreach ( $form_actions as $action ) {
597 322 if ( ! isset( $action_map[ $action->post_excerpt ] ) ) {
598 - // Don't try and show settings if action no longer exists
323 + // don't try and show settings if action no longer exists
599 324 continue;
600 325 }
601 326
602 327 self::action_control( $action, $form, $action->ID, $action_controls[ $action_map[ $action->post_excerpt ] ], $values );
@@ -610,20 +335,17 @@
610 335 * @since 6.17
611 336 *
612 337 * @param int|string $form_id
613 338 * @param array $form_actions
614 - *
615 339 * @return void
616 340 */
617 341 private static function maybe_show_limit_warning( $form_id, $form_actions ) {
618 342 $count = count( $form_actions );
619 -
620 343 if ( $count < 99 ) {
621 344 return;
622 345 }
623 346
624 347 $limit = FrmFormAction::get_action_limit( $form_id );
625 -
626 348 if ( $limit < 99 || $count < $limit ) {
627 349 return;
628 350 }
629 351
@@ -629,9 +351,9 @@
629 351
630 352 $documentation_url = 'https://formidableforms.com/knowledgebase/frm_form_action_limit/#kb-increase-limit-of-form-actions';
631 353
632 354 echo '<div class="frm_warning_style">';
633 - FrmAppHelper::icon_by_class( 'frmfont frm_alert_icon' );
355 + FrmAppHelper::icon_by_class( 'frm_icon_font frm_alert_icon' );
634 356 echo '&nbsp;';
635 357 printf(
636 358 // translators: %s: URL to documentation
637 359 esc_html__( 'You have reached your form action limit. To increase this limit, you will require additional code. Visit our documentation at %s.', 'formidable' ),
@@ -639,17 +361,8 @@
639 361 );
640 362 echo '</div>';
641 363 }
642 364
643 - /**
644 - * @param WP_Post $form_action
645 - * @param object $form
646 - * @param int $action_key Action ID.
647 - * @param FrmFormAction $action_control
648 - * @param array $values
649 - *
650 - * @return void
651 - */
652 365 public static function action_control( $form_action, $form, $action_key, $action_control, $values ) {
653 366 $action_control->_set( $action_key );
654 367
655 368 $use_logging = self::should_show_log_message( $form_action->post_excerpt );
@@ -660,18 +373,13 @@
660 373 public static function add_form_action() {
661 374 FrmAppHelper::permission_check( 'frm_edit_forms' );
662 375 check_ajax_referer( 'frm_ajax', 'nonce' );
663 376
664 - $action_key = FrmAppHelper::get_param( 'list_id', '', 'post', 'absint' );
665 - $action_type = FrmAppHelper::get_param( 'type', '', 'post', 'sanitize_text_field' );
666 - $lite_actions = array_fill_keys( self::get_lite_actions(), true );
377 + global $frm_vars;
667 378
668 - if ( ! FrmAppHelper::pro_is_connected() && ! isset( $lite_actions[ $action_type ] ) ) {
669 - wp_die();
670 - }
379 + $action_key = FrmAppHelper::get_param( 'list_id', '', 'post', 'absint' );
380 + $action_type = FrmAppHelper::get_param( 'type', '', 'post', 'sanitize_text_field' );
671 381
672 - global $frm_vars;
673 -
674 382 /**
675 383 * @var FrmFormAction
676 384 */
677 385 $action_control = self::get_form_actions( $action_type );
@@ -676,60 +384,37 @@
676 384 */
677 385 $action_control = self::get_form_actions( $action_type );
678 386 $action_control->_set( $action_key );
679 387
680 - $form_id = FrmAppHelper::get_param( 'form_id', '', 'post', 'absint' );
681 - $form_action = $action_control->prepare_new( $form_id );
682 - $existing_titles = (array) FrmAppHelper::get_post_param( 'existing_titles', array(), 'sanitize_text_field' );
388 + $form_id = FrmAppHelper::get_param( 'form_id', '', 'post', 'absint' );
683 389
684 - if ( $existing_titles ) {
685 - $form_action->post_title = self::get_unique_action_title( $form_action->post_title, $existing_titles );
686 - }
390 + $form_action = $action_control->prepare_new( $form_id );
391 + $use_logging = self::should_show_log_message( $action_type );
687 392
688 - $use_logging = self::should_show_log_message( $action_type );
689 - $values = array();
690 - $form = self::fields_to_values( $form_id, $values );
393 + $values = array();
394 + $form = self::fields_to_values( $form_id, $values );
691 395
692 396 include FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/form_action.php';
693 397 wp_die();
694 398 }
695 399
696 - /**
697 - * Returns the first available title not in $existing_titles, appending " (2)", " (3)", etc. if needed.
698 - *
699 - * @since 6.31
700 - *
701 - * @param string $base_title Default action title from the action type.
702 - * @param string[] $existing_titles Titles currently visible in the form editor.
703 - *
704 - * @return string
705 - */
706 - private static function get_unique_action_title( $base_title, array $existing_titles ) {
707 - $taken = array_flip( $existing_titles );
708 - $title = $base_title;
709 -
710 - for ( $n = 2; isset( $taken[ $title ] ); $n++ ) {
711 - $title = $base_title . ' (' . $n . ')';
712 - }
713 -
714 - return $title;
715 - }
716 -
717 400 public static function fill_action() {
718 401 FrmAppHelper::permission_check( 'frm_edit_forms' );
719 402 check_ajax_referer( 'frm_ajax', 'nonce' );
720 403
721 - $action_key = FrmAppHelper::get_param( 'action_id', '', 'post', 'absint' );
722 - $action_type = FrmAppHelper::get_param( 'action_type', '', 'post', 'sanitize_text_field' );
404 + $action_key = FrmAppHelper::get_param( 'action_id', '', 'post', 'absint' );
405 + $action_type = FrmAppHelper::get_param( 'action_type', '', 'post', 'sanitize_text_field' );
406 +
723 407 $action_control = self::get_form_actions( $action_type );
724 -
725 - if ( ! $action_control ) {
408 + if ( empty( $action_control ) ) {
726 409 wp_die();
727 410 }
728 411
729 412 $form_action = $action_control->get_single_action( $action_key );
730 - $values = array();
731 - $form = self::fields_to_values( $form_action->menu_order, $values );
413 +
414 + $values = array();
415 + $form = self::fields_to_values( $form_action->menu_order, $values );
416 +
732 417 $use_logging = self::should_show_log_message( $action_type );
733 418
734 419 include FrmAppHelper::plugin_path() . '/classes/views/frm-form-actions/_action_inside.php';
735 420 wp_die();
@@ -736,40 +421,15 @@
736 421 }
737 422
738 423 /**
739 424 * @since 3.06.04
740 - *
741 - * @param string $action_type
742 - *
743 425 * @return bool
744 426 */
745 427 private static function should_show_log_message( $action_type ) {
746 - $logging = array(
747 - 'activecampaign',
748 - 'api',
749 - 'aweber',
750 - 'campaignmonitor',
751 - 'constantcontact',
752 - 'convertkit',
753 - 'getresponse',
754 - 'googlespreadsheet',
755 - 'hubspot',
756 - 'mailchimp',
757 - 'mailpoet',
758 - 'n8n',
759 - 'salesforce',
760 - 'twilio',
761 - 'zapier',
762 - );
428 + $logging = array( 'api', 'salesforce', 'constantcontact', 'activecampaign' );
763 429 return in_array( $action_type, $logging, true ) && ! function_exists( 'frm_log_autoloader' );
764 430 }
765 431
766 - /**
767 - * @param int|string $form_id
768 - * @param array $values
769 - *
770 - * @return object
771 - */
772 432 private static function fields_to_values( $form_id, array &$values ) {
773 433 $form = FrmForm::getOne( $form_id );
774 434
775 435 $values = array(
@@ -777,14 +437,12 @@
777 437 'id' => $form->id,
778 438 );
779 439
780 440 $fields = FrmField::get_all_for_form( $form->id );
781 -
782 441 foreach ( $fields as $k => $f ) {
783 442 $f = (array) $f;
784 443 $opts = (array) $f['field_options'];
785 444 $f = array_merge( $opts, $f );
786 -
787 445 if ( ! isset( $f['post_field'] ) ) {
788 446 $f['post_field'] = '';
789 447 }
790 448 $values['fields'][] = $f;
@@ -795,15 +453,13 @@
795 453 }
796 454
797 455 /**
798 456 * @param int $form_id
799 - *
800 457 * @return void
801 458 */
802 459 public static function update_settings( $form_id ) {
803 460 FrmAppHelper::permission_check( 'frm_edit_forms' );
804 461 $process_form = FrmAppHelper::get_post_param( 'process_form', '', 'sanitize_text_field' );
805 -
806 462 if ( ! wp_verify_nonce( $process_form, 'process_form_nonce' ) ) {
807 463 $frm_settings = FrmAppHelper::get_settings();
808 464 $error_args = array(
809 465 'title' => __( 'Verification failed', 'formidable' ),
@@ -836,19 +492,17 @@
836 492 $new_actions = array();
837 493
838 494 foreach ( $registered_actions as $registered_action ) {
839 495 $action_ids = $registered_action->update_callback( $form_id );
840 -
841 - if ( $action_ids ) {
496 + if ( ! empty( $action_ids ) ) {
842 497 $new_actions[] = $action_ids;
843 498 }
844 499 }
845 500
846 501 // Only use array_merge if there are new actions.
847 - if ( $new_actions ) {
502 + if ( ! empty( $new_actions ) ) {
848 503 $new_actions = call_user_func_array( 'array_merge', $new_actions );
849 504 }
850 -
851 505 $old_actions = array_diff( $old_actions, $new_actions );
852 506
853 507 self::delete_missing_actions( $old_actions );
854 508
@@ -854,32 +508,17 @@
854 508
855 509 FrmOnSubmitHelper::save_on_submit_settings( $form_id );
856 510 }
857 511
858 - /**
859 - * @param array $old_actions
860 - *
861 - * @return void
862 - */
863 512 public static function delete_missing_actions( $old_actions ) {
864 - if ( ! $old_actions ) {
865 - return;
513 + if ( ! empty( $old_actions ) ) {
514 + foreach ( $old_actions as $old_id ) {
515 + wp_delete_post( $old_id );
516 + }
517 + FrmDb::cache_delete_group( 'frm_actions' );
866 518 }
867 -
868 - foreach ( $old_actions as $old_id ) {
869 - wp_delete_post( $old_id );
870 - }
871 -
872 - FrmDb::cache_delete_group( 'frm_actions' );
873 519 }
874 520
875 - /**
876 - * @param int|string $entry_id
877 - * @param int|string $form_id
878 - * @param array $args
879 - *
880 - * @return void
881 - */
882 521 public static function trigger_create_actions( $entry_id, $form_id, $args = array() ) {
883 522 $filter_args = $args;
884 523 $filter_args['entry_id'] = $entry_id;
885 524 $filter_args['form_id'] = $form_id;
@@ -896,34 +535,26 @@
896 535 self::trigger_actions( $event, $form_id, $entry_id, 'all', $args );
897 536 }
898 537
899 538 /**
900 - * @param string $event
901 - * @param int|object|string $form
902 - * @param int|object|string $entry
903 - * @param string $type
904 - * @param array $args
905 - *
906 - * @return void
539 + * @param string $event
907 540 */
908 - public static function trigger_actions( $event, $form, $entry, $type = 'all', $args = array() ) { // phpcs:ignore SlevomatCodingStandard.Complexity.Cognitive.ComplexityTooHigh
541 + public static function trigger_actions( $event, $form, $entry, $type = 'all', $args = array() ) {
909 542 $action_status = array(
910 543 'post_status' => 'publish',
911 544 );
912 - $form_actions = FrmFormAction::get_action_for_form( is_object( $form ) ? $form->id : $form, $type, $action_status );
545 + $form_actions = FrmFormAction::get_action_for_form( ( is_object( $form ) ? $form->id : $form ), $type, $action_status );
913 546
914 - if ( ! $form_actions ) {
547 + if ( empty( $form_actions ) ) {
915 548 return;
916 549 }
917 550
918 551 FrmForm::maybe_get_form( $form );
919 -
920 552 if ( ! is_object( $form ) ) {
921 553 return;
922 554 }
923 555
924 556 $link_settings = self::get_form_actions( $type );
925 -
926 557 if ( 'all' !== $type ) {
927 558 $link_settings = array( $type => $link_settings );
928 559 }
929 560
@@ -936,11 +567,11 @@
936 567 $this_event = $event;
937 568 }
938 569
939 570 foreach ( $form_actions as $action ) {
571 +
940 572 $skip_this_action = ! in_array( $this_event, $action->post_content['event'], true ) || FrmOnSubmitAction::$slug === $action->post_excerpt;
941 573 $skip_this_action = apply_filters( 'frm_skip_form_action', $skip_this_action, compact( 'action', 'entry', 'form', 'event' ) );
942 -
943 574 if ( $skip_this_action ) {
944 575 continue;
945 576 }
946 577
@@ -947,18 +578,17 @@
947 578 if ( ! is_object( $entry ) ) {
948 579 $entry = FrmEntry::getOne( $entry, true );
949 580 }
950 581
951 - if ( ! $entry || ( FrmEntriesHelper::DRAFT_ENTRY_STATUS === (int) $entry->is_draft && 'draft' !== $event ) ) {
582 + if ( empty( $entry ) || ( FrmEntriesHelper::DRAFT_ENTRY_STATUS === (int) $entry->is_draft && 'draft' !== $event ) ) {
952 583 continue;
953 584 }
954 585
955 - $child_entry = ( is_numeric( $form->parent_form_id ) && $form->parent_form_id ) || ( $entry && ( (int) $entry->form_id !== (int) $form->id || $entry->parent_item_id ) ) || ! empty( $args['is_child'] ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
586 + $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'] );
956 587
957 588 if ( $child_entry ) {
958 - // Maybe trigger actions for sub forms
589 + // maybe trigger actions for sub forms
959 590 $trigger_children = apply_filters( 'frm_use_embedded_form_actions', false, compact( 'form', 'entry' ) );
960 -
961 591 if ( ! $trigger_children ) {
962 592 continue;
963 593 }
964 594 }
@@ -964,9 +594,8 @@
964 594 }
965 595
966 596 // Check conditional logic.
967 597 $stop = FrmFormAction::action_conditions_met( $action, $entry );
968 -
969 598 if ( $stop ) {
970 599 continue;
971 600 }
972 601
@@ -976,9 +605,9 @@
976 605
977 606 unset( $action );
978 607 }//end foreach
979 608
980 - if ( $stored_actions ) {
609 + if ( ! empty( $stored_actions ) ) {
981 610 asort( $action_priority );
982 611
983 612 // Make sure hooks are loaded.
984 613 new FrmNotification();
@@ -1009,15 +638,8 @@
1009 638 }//end foreach
1010 639 }//end if
1011 640 }
1012 641
1013 - /**
1014 - * @param int|string $form_id
1015 - * @param array $values
1016 - * @param array $args
1017 - *
1018 - * @return void
1019 - */
1020 642 public static function duplicate_form_actions( $form_id, $values, $args = array() ) {
1021 643 if ( empty( $args['old_id'] ) ) {
1022 644 // Continue if we know which actions to copy.
1023 645 return;
@@ -1033,13 +655,8 @@
1033 655 unset( $action_control );
1034 656 }
1035 657 }
1036 658
1037 - /**
1038 - * @param string $where
1039 - *
1040 - * @return string
1041 - */
1042 659 public static function limit_by_type( $where ) {
1043 660 global $frm_vars, $wpdb;
1044 661
1045 662 if ( ! isset( $frm_vars['action_type'] ) ) {
@@ -1045,9 +662,11 @@
1045 662 if ( ! isset( $frm_vars['action_type'] ) ) {
1046 663 return $where;
1047 664 }
1048 665
1049 - return $where . $wpdb->prepare( ' AND post_excerpt = %s ', $frm_vars['action_type'] );
666 + $where .= $wpdb->prepare( ' AND post_excerpt = %s ', $frm_vars['action_type'] );
667 +
668 + return $where;
1050 669 }
1051 670
1052 671 /**
1053 672 * Prevent WPML from filtering form actions based on the active language.
@@ -1055,136 +674,19 @@
1055 674 * @since 6.20
1056 675 *
1057 676 * @param bool|null $null
1058 677 * @param string $post_type
1059 - *
1060 678 * @return bool|null
1061 679 */
1062 680 public static function prevent_wpml_translations( $null, $post_type ) {
1063 - return self::$action_post_type === $post_type ? false : $null;
1064 - }
1065 -
1066 - /**
1067 - * If Pro is not connected, hook a filter that will force all non-Lite
1068 - * actions to inactive so the upgrade popup is shown instead.
1069 - *
1070 - * @since 6.31
1071 - *
1072 - * @return void
1073 - */
1074 - private static function maybe_setup_unlicensed_action_gate() {
1075 - if ( FrmAppHelper::pro_is_connected() ) {
1076 - return;
681 + if ( self::$action_post_type === $post_type ) {
682 + return false;
1077 683 }
1078 -
1079 - add_filter( 'frm_registered_form_actions', array( self::class, 'disable_unlicensed_actions' ), 100 );
684 + return $null;
1080 685 }
1081 -
1082 - /**
1083 - * For every registered action that is not a Lite action, add a per-action
1084 - * options filter that forces it to inactive with the upgrade class.
1085 - *
1086 - * Runs inside apply_filters('frm_registered_form_actions') at priority 100,
1087 - * so the per-key option filters are in place before the class constructors
1088 - * run in the foreach loop that follows.
1089 - *
1090 - * @since 6.31
1091 - *
1092 - * @param array $actions Map of action_key => class_name.
1093 - *
1094 - * @return array
1095 - */
1096 - public static function disable_unlicensed_actions( $actions ) {
1097 - $lite_actions = array_fill_keys( self::get_lite_actions(), true );
1098 -
1099 - foreach ( array_keys( $actions ) as $key ) {
1100 - if ( isset( $lite_actions[ $key ] ) ) {
1101 - continue;
1102 - }
1103 -
1104 - add_filter(
1105 - 'frm_' . $key . '_action_options',
1106 - function ( $options ) {
1107 - $options['active'] = false;
1108 -
1109 - if ( ! str_contains( $options['classes'], 'frm_show_upgrade' ) ) {
1110 - $options['classes'] .= ' frm_show_upgrade';
1111 - }
1112 -
1113 - return $options;
1114 - }
1115 - );
1116 - }//end foreach
1117 -
1118 - return $actions;
1119 - }
1120 -
1121 - /**
1122 - * Get action keys that are available in Lite without a Pro license.
1123 - *
1124 - * @since 6.31
1125 - *
1126 - * @return string[]
1127 - */
1128 - public static function get_lite_actions() {
1129 - return apply_filters( 'frm_lite_form_actions', array( 'on_submit', 'email', 'payment', 'stripe', 'square', 'paypal' ) );
1130 - }
1131 -
1132 - /**
1133 - * Single source of truth for learn-more URL slugs used in
1134 - * upgrade modals for non-Lite form actions.
1135 - *
1136 - * Slugs without '/' are KB doc slugs (knowledgebase/ prefix is added).
1137 - * Slugs with '/' are direct paths (e.g. features/) used as-is.
1138 - *
1139 - * @since 6.31
1140 - *
1141 - * @return array<string,string> Map of action_key => URL slug.
1142 - */
1143 - public static function get_action_learn_more_links() {
1144 - return array(
1145 - 'wppost' => 'features/user-submitted-posts-wordpress-forms',
1146 - 'register' => 'user-registration',
1147 - 'paypal' => 'features/paypal-wordpress-payments',
1148 - 'quiz' => 'quiz-maker-forms',
1149 - 'quiz_outcome' => 'quiz-maker-forms',
1150 - 'aweber' => 'features/aweber-addon',
1151 - 'mailchimp' => 'features/mailchimp-addon',
1152 - 'zapier' => 'features/form-entry-routing-with-zapier',
1153 - 'twilio' => 'features/twilio-sms-form-notifications',
1154 - 'activecampaign' => 'features/entries-to-activecampaign',
1155 - 'salesforce' => 'features/form-entries-to-salesforce',
1156 - 'constantcontact' => 'features/entries-to-constant-contact',
1157 - 'getresponse' => 'features/form-entries-to-getresponse',
1158 - 'hubspot' => 'features/form-entries-to-hubspot',
1159 - 'mailpoet' => 'features/mailpoet-newsletters-addon',
1160 - 'api' => 'features/wordpress-form-api',
1161 - 'googlespreadsheet' => 'features/google-sheets',
1162 - 'n8n' => 'features/connect-your-forms-to-any-app-with-n8n',
1163 - 'convertkit' => 'features/convertkit',
1164 - );
1165 - }
1166 -
1167 - /**
1168 - * Look up the learn-more doc slug for a given action key.
1169 - *
1170 - * @since 6.31
1171 - *
1172 - * @param string $action_key Action identifier (e.g. 'register').
1173 - *
1174 - * @return string Doc slug or empty string.
1175 - */
1176 - private static function get_learn_more_slug( $action_key ) {
1177 - $links = self::get_action_learn_more_links();
1178 - return $links[ $action_key ] ?? '';
1179 - }
1180 686 }
1181 687
1182 688 class Frm_Form_Action_Factory {
1183 -
1184 - /**
1185 - * @var array
1186 - */
1187 689 public $actions = array();
1188 690
1189 691 public function __construct() {
1190 692 add_action( 'frm_form_actions_init', array( $this, '_register_actions' ), 100 );
@@ -1189,22 +691,12 @@
1189 691 public function __construct() {
1190 692 add_action( 'frm_form_actions_init', array( $this, '_register_actions' ), 100 );
1191 693 }
1192 694
1193 - /**
1194 - * @param string $action_class
1195 - *
1196 - * @return void
1197 - */
1198 695 public function register( $action_class ) {
1199 696 $this->actions[ $action_class ] = new $action_class();
1200 697 }
1201 698
1202 - /**
1203 - * @param string $action_class
1204 - *
1205 - * @return void
1206 - */
1207 699 public function unregister( $action_class ) {
1208 700 if ( isset( $this->actions[ $action_class ] ) ) {
1209 701 unset( $this->actions[ $action_class ] );
1210 702 }
@@ -1213,9 +705,9 @@
1213 705 public function _register_actions() {
1214 706 $keys = array_keys( $this->actions );
1215 707
1216 708 foreach ( $keys as $key ) {
1217 - // Don't register new action if old action with the same id is already registered
709 + // don't register new action if old action with the same id is already registered
1218 710 if ( ! isset( $this->actions[ $key ] ) ) {
1219 711 $this->actions[ $key ]->_register();
1220 712 }
1221 713 }