PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / trunk
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More vtrunk
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/models/FrmFormAction.php +94 -62 6.27 → trunk View file →
@@ -140,9 +140,17 @@
140 140 if ( ! defined( 'ABSPATH' ) ) {
141 141 die( 'You are not allowed to call this page directly.' );
142 142 }
143 143
144 - $this->id_base = strtolower( $id_base );
144 + $this->id_base = strtolower( $id_base );
145 +
146 + /**
147 + * @since 6.31
148 + *
149 + * @param string $name
150 + */
151 + $name = apply_filters( 'frm_' . $id_base . '_action_name', $name );
152 +
145 153 $this->name = $name;
146 154 $this->option_name = 'frm_' . $this->id_base . '_action';
147 155
148 156 $default_options = array(
@@ -157,8 +165,11 @@
157 165 'tooltip' => $name,
158 166 'group' => $id_base,
159 167 'color' => '',
160 168 'keywords' => '',
169 + 'description' => '',
170 + 'is_new' => false,
171 + 'is_beta' => false,
161 172 );
162 173
163 174 $action_options = apply_filters( 'frm_' . $id_base . '_action_options', $action_options );
164 175 $group = $this->get_group( $action_options );
@@ -164,11 +175,12 @@
164 175 $group = $this->get_group( $action_options );
165 176 $action_options['group'] = $group['id'];
166 177
167 178 if ( ! isset( $action_options['color'] ) ) {
168 - $colors = array( 'green', 'orange', 'purple' );
169 - shuffle( $colors );
170 - $action_options['color'] = 'var(--' . reset( $colors ) . ')';
179 + // Deterministic fallback so all instances of the same action type render with the same color across requests.
180 + $colors = array( 'green', 'orange', 'purple' );
181 + $index = abs( crc32( $id_base ) ) % count( $colors );
182 + $action_options['color'] = 'var(--' . $colors[ $index ] . ')';
171 183 }
172 184
173 185 $upgrade_class = isset( $action_options['classes'] ) && $action_options['classes'] === 'frm_show_upgrade';
174 186
@@ -209,9 +221,9 @@
209 221 public function maybe_switch_field_ids( $action ) {
210 222 $updated_action = apply_filters( 'frm_maybe_switch_field_ids', $action );
211 223
212 224 if ( $updated_action === $action ) {
213 - $updated_action = FrmFieldsHelper::switch_field_ids( $action );
225 + return FrmFieldsHelper::switch_field_ids( $action );
214 226 }
215 227
216 228 return $updated_action;
217 229 }
@@ -255,9 +267,9 @@
255 267 * @return string Name attribute for $field_name
256 268 */
257 269 public function get_field_name( $field_name, $post_field = 'post_content' ) {
258 270 $name = $this->option_name . '[' . $this->number . ']';
259 - $name .= empty( $post_field ) ? '' : '[' . $post_field . ']';
271 + $name .= $post_field ? '[' . $post_field . ']' : '';
260 272
261 273 return $name . ( '[' . $field_name . ']' );
262 274 }
263 275
@@ -296,9 +308,9 @@
296 308
297 309 $post_content = array();
298 310 $default_values = $this->get_global_defaults();
299 311
300 - // fill default values
312 + // Fill default values
301 313 $post_content = wp_parse_args( $post_content, $default_values );
302 314
303 315 if ( ! isset( $post_content['event'] ) && ! $this->action_options['force_event'] ) {
304 316 $post_content['event'] = array( reset( $this->action_options['event'] ) );
@@ -313,9 +325,8 @@
313 325 'post_type' => FrmFormActionsController::$action_post_type,
314 326 'post_name' => $this->form_id . '_' . $this->id_base . '_' . $this->number,
315 327 'menu_order' => $this->form_id,
316 328 );
317 - unset( $post_content );
318 329
319 330 return (object) $form_action;
320 331 }
321 332
@@ -340,9 +351,9 @@
340 351 */
341 352 public function duplicate_form_actions( $form_id, $old_id ) {
342 353 // phpcs:ignore Universal.Operators.StrictComparisons
343 354 if ( $form_id == $old_id ) {
344 - // don't duplicate the actions if this is a template getting updated
355 + // Don't duplicate the actions if this is a template getting updated
345 356 return;
346 357 }
347 358
348 359 $this->form_id = $old_id;
@@ -363,9 +374,9 @@
363 374 *
364 375 * @param array $action
365 376 * @param array $forms
366 377 *
367 - * @return int $post_id
378 + * @return int Post ID.
368 379 */
369 380 public function maybe_create_action( $action, $forms ) {
370 381 if ( isset( $action['ID'] ) && is_numeric( $action['ID'] ) && isset( $forms[ $action['menu_order'] ] ) && $forms[ $action['menu_order'] ] === 'updated' ) {
371 382 // Update action only
@@ -394,9 +405,9 @@
394 405 $action->post_content[ $key ] = $frm_duplicate_ids[ $val ];
395 406 } elseif ( ! is_array( $val ) ) {
396 407 $action->post_content[ $key ] = FrmFieldsHelper::switch_field_ids( $val );
397 408 } elseif ( isset( $switch[ $key ] ) && is_array( $switch[ $key ] ) ) {
398 - // loop through each value if empty
409 + // Loop through each value if empty
399 410 if ( empty( $switch[ $key ] ) ) {
400 411 $switch[ $key ] = array_keys( $val );
401 412 }
402 413
@@ -466,16 +477,16 @@
466 477 return null;
467 478 }
468 479
469 480 // phpcs:ignore WordPress.Security.NonceVerification.Missing
470 - if ( isset( $_POST[ $this->option_name ] ) && is_array( $_POST[ $this->option_name ] ) ) {
471 - // Sanitizing removes scripts and <email> type of values.
472 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
473 - $settings = wp_unslash( $_POST[ $this->option_name ] );
474 - } else {
481 + if ( ! isset( $_POST[ $this->option_name ] ) || ! is_array( $_POST[ $this->option_name ] ) ) {
475 482 return null;
476 483 }
477 484
485 + // Sanitizing removes scripts and <email> type of values.
486 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
487 + $settings = wp_unslash( $_POST[ $this->option_name ] );
488 +
478 489 $action_ids = array();
479 490
480 491 foreach ( $settings as $number => $new_instance ) {
481 492 $this->_set( $number );
@@ -485,9 +496,9 @@
485 496 if ( ! isset( $new_instance['post_status'] ) ) {
486 497 $new_instance['post_status'] = 'draft';
487 498 }
488 499
489 - // settings were never opened, so don't update
500 + // Settings were never opened, so don't update
490 501 if ( ! isset( $new_instance['post_title'] ) ) {
491 502 $this->maybe_update_status( $new_instance, $old_instance );
492 503 $action_ids[] = $new_instance['ID'];
493 504 $this->updated = true;
@@ -599,9 +610,9 @@
599 610 public static function get_action_for_form( $form_id, $type = 'all', $atts = array() ) {
600 611 $action_controls = FrmFormActionsController::get_form_actions( $type );
601 612
602 613 if ( ! $action_controls ) {
603 - // don't continue if there are no available actions
614 + // Don't continue if there are no available actions
604 615 return array();
605 616 }
606 617
607 618 if ( 'all' !== $type ) {
@@ -625,9 +636,9 @@
625 636
626 637 $settings = array();
627 638
628 639 foreach ( $actions as $action ) {
629 - // some plugins/themes are formatting the post_excerpt
640 + // Some plugins/themes are formatting the post_excerpt
630 641 $action->post_excerpt = sanitize_title( $action->post_excerpt );
631 642
632 643 if ( ! isset( $action_controls[ $action->post_excerpt ] ) ) {
633 644 continue;
@@ -640,13 +651,9 @@
640 651 break;
641 652 }
642 653 }
643 654
644 - if ( 1 === $limit ) {
645 - $settings = reset( $settings );
646 - }
647 -
648 - return $settings;
655 + return 1 === $limit ? reset( $settings ) : $settings;
649 656 }
650 657
651 658 /**
652 659 * Get the limit for the number of actions for a single form. By default, this is 99, but
@@ -666,16 +673,16 @@
666 673
667 674 /**
668 675 * @since 3.04
669 676 *
670 - * @param array $args
671 - * @param string $default_status
677 + * @param array|string $args
678 + * @param string $default_status
672 679 *
673 680 * @return void
674 681 */
675 682 protected static function prepare_get_action( &$args, $default_status = 'publish' ) {
676 683 if ( is_numeric( $args ) ) {
677 - // for reverse compatibility. $limit was changed to $args
684 + // For reverse compatibility. $limit was changed to $args
678 685 $args = array(
679 686 'limit' => $args,
680 687 );
681 688 }
@@ -765,18 +772,14 @@
765 772 $action = $this->prepare_action( $action );
766 773 $settings[ $action->ID ] = $action;
767 774 }
768 775
769 - if ( 1 === $limit ) {
770 - $settings = reset( $settings );
771 - }
772 -
773 - return $settings;
776 + return 1 === $limit ? reset( $settings ) : $settings;
774 777 }
775 778
776 779 /**
777 - * @param int $form_id
778 - * @param int $limit
780 + * @param int|string $form_id
781 + * @param int $limit
779 782 *
780 783 * @return array
781 784 */
782 785 public static function action_args( $form_id = 0, $limit = 99 ) {
@@ -805,18 +808,20 @@
805 808 $action->post_excerpt = sanitize_title( $action->post_excerpt );
806 809
807 810 $default_values = $this->get_global_defaults();
808 811
809 - // fill default values
812 + // Fill default values
810 813 $action->post_content += $default_values;
811 814
812 815 foreach ( $default_values as $k => $vals ) {
813 - if ( is_array( $vals ) && $vals ) {
814 - if ( 'event' === $k && ! $this->action_options['force_event'] && ! empty( $action->post_content[ $k ] ) ) {
815 - continue;
816 - }
817 - $action->post_content[ $k ] = wp_parse_args( $action->post_content[ $k ], $vals );
816 + if ( ! is_array( $vals ) || ! $vals ) {
817 + continue;
818 818 }
819 +
820 + if ( 'event' === $k && ! $this->action_options['force_event'] && ! empty( $action->post_content[ $k ] ) ) {
821 + continue;
822 + }
823 + $action->post_content[ $k ] = wp_parse_args( $action->post_content[ $k ], $vals );
819 824 }
820 825
821 826 if ( ! is_array( $action->post_content['event'] ) ) {
822 827 $action->post_content['event'] = explode( ',', $action->post_content['event'] );
@@ -913,19 +918,21 @@
913 918 public function migrate_to_2( $form, $update = 'update' ) {
914 919 $action = $this->prepare_new( $form->id );
915 920 FrmAppHelper::unserialize_or_decode( $form->options );
916 921
917 - // fill with existing options
922 + // Fill with existing options
918 923 foreach ( $action->post_content as $name => $val ) {
919 - if ( isset( $form->options[ $name ] ) ) {
920 - $action->post_content[ $name ] = $form->options[ $name ];
921 - unset( $form->options[ $name ] );
924 + if ( ! isset( $form->options[ $name ] ) ) {
925 + continue;
922 926 }
927 +
928 + $action->post_content[ $name ] = $form->options[ $name ];
929 + unset( $form->options[ $name ] );
923 930 }
924 931
925 932 $action = $this->migrate_values( $action, $form );
926 933
927 - // check if action already exists
934 + // Check if action already exists
928 935 $post_id = get_posts(
929 936 array(
930 937 'name' => $action->post_name,
931 938 'post_type' => FrmFormActionsController::$action_post_type,
@@ -934,21 +941,23 @@
934 941 )
935 942 );
936 943
937 944 if ( ! $post_id ) {
938 - // create action now
945 + // Create action now
939 946 $post_id = $this->save_settings( $action );
940 947 }
941 948
942 - if ( $post_id && 'update' === $update ) {
943 - global $wpdb;
944 - $form->options = maybe_serialize( $form->options );
949 + if ( ! $post_id || 'update' !== $update ) {
950 + return $post_id;
951 + }
945 952
946 - // update form options
947 - $wpdb->update( $wpdb->prefix . 'frm_forms', array( 'options' => $form->options ), array( 'id' => $form->id ) );
948 - FrmForm::clear_form_cache();
949 - }
953 + global $wpdb;
954 + $form->options = maybe_serialize( $form->options );
950 955
956 + // Update form options
957 + $wpdb->update( $wpdb->prefix . 'frm_forms', array( 'options' => $form->options ), array( 'id' => $form->id ) );
958 + FrmForm::clear_form_cache();
959 +
951 960 return $post_id;
952 961 }
953 962
954 963 /**
@@ -970,11 +979,12 @@
970 979 * @return array
971 980 */
972 981 public static function default_action_opts( $class = '' ) {
973 982 return array(
974 - 'classes' => 'frmfont ' . $class,
975 - 'active' => false,
976 - 'limit' => 0,
983 + 'classes' => 'frmfont ' . $class,
984 + 'active' => false,
985 + 'limit' => 0,
986 + 'description' => '',
977 987 );
978 988 }
979 989
980 990 /**
@@ -992,18 +1002,40 @@
992 1002 return apply_filters( 'frm_action_triggers', $triggers );
993 1003 }
994 1004
995 1005 /**
1006 + * @param string $action_key The unique key for this action instance.
1007 + *
996 1008 * @return void
997 1009 */
998 - public function render_conditional_logic_call_to_action() {
1010 + public function render_conditional_logic_call_to_action( $action_key = '' ) {
1011 + $params = array(
1012 + 'class' => 'frm-h-stack-xs frm-bt-200 frm-py-md frm_show_upgrade',
1013 + 'data-upgrade' => $this->get_upgrade_text(),
1014 + 'data-medium' => 'conditional-' . $this->id_base,
1015 + 'data-content' => 'conditional-logic',
1016 + );
1017 + // phpcs:disable Generic.WhiteSpace.ScopeIndent
999 1018 ?>
1000 - <h3>
1001 - <a href="javascript:void(0)" class="frm_show_upgrade frm_noallow" data-upgrade="<?php echo esc_attr( $this->get_upgrade_text() ); ?>" data-medium="conditional-<?php echo esc_attr( $this->id_base ); ?>"><?php // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong ?>
1002 - <?php esc_html_e( 'Use Conditional Logic', 'formidable' ); ?>
1003 - </a>
1004 - </h3>
1019 + <div <?php FrmAppHelper::array_to_html_params( $params, true ); ?>>
1020 + <?php
1021 + FrmHtmlHelper::toggle(
1022 + 'frm_logic_cta_' . $action_key,
1023 + 'frm_logic_cta_' . $action_key,
1024 + array(
1025 + 'div_class' => 'with_frm_style frm_toggle',
1026 + 'checked' => false,
1027 + 'echo' => true,
1028 + 'disabled' => true,
1029 + )
1030 + );
1031 + ?>
1032 + <label for="frm_logic_cta_<?php echo esc_attr( $action_key ); ?>" class="frm_noallow">
1033 + <?php esc_html_e( 'Use Conditional Logic', 'formidable' ); ?>
1034 + </label>
1035 + </div>
1005 1036 <?php
1037 + // phpcs:enable Generic.WhiteSpace.ScopeIndent
1006 1038 }
1007 1039
1008 1040 /**
1009 1041 * @return string