Formidable Forms – Form Builder for WordPress - Version 5.0.04

Version Description

  • New: Custom HTML for errors is now also applied when validating with JavaScript.
  • New: Added a button to quickly save and reload after activating a new plugin from the settings page.
  • New: Added several new filters required to support the new new Formidable surveys add on.
Download this release

Release Info

Developer formidableforms
Plugin Icon 128x128 Formidable Forms – Form Builder for WordPress
Version 5.0.04
Comparing to
See all releases

Code changes from version 5.0.03 to 5.0.04

Files changed (37) hide show
  1. classes/controllers/FrmAddonsController.php +24 -4
  2. classes/controllers/FrmAppController.php +9 -3
  3. classes/controllers/FrmEntriesController.php +23 -2
  4. classes/controllers/FrmFieldsController.php +92 -0
  5. classes/controllers/FrmFormsController.php +48 -5
  6. classes/controllers/FrmHooksController.php +3 -1
  7. classes/helpers/FrmAppHelper.php +199 -2
  8. classes/helpers/FrmFieldsHelper.php +256 -33
  9. classes/helpers/FrmTipsHelper.php +0 -7
  10. classes/models/FrmEntry.php +22 -4
  11. classes/models/FrmEntryValidate.php +10 -1
  12. classes/models/FrmEntryValues.php +37 -0
  13. classes/models/FrmField.php +10 -0
  14. classes/models/FrmInbox.php +42 -2
  15. classes/models/fields/FrmFieldType.php +1 -2
  16. classes/views/frm-entries/form.php +10 -1
  17. classes/views/frm-fields/back-end/bulk-options-overlay.php +12 -3
  18. classes/views/frm-fields/back-end/radio-display-format.php +20 -0
  19. classes/views/frm-fields/back-end/radio-images.php +10 -7
  20. classes/views/frm-fields/back-end/settings.php +12 -2
  21. classes/views/frm-fields/front-end/checkbox-field.php +11 -1
  22. classes/views/frm-fields/front-end/radio-field.php +11 -1
  23. classes/views/frm-forms/settings-advanced.php +14 -1
  24. classes/views/frm-forms/settings-buttons.php +2 -2
  25. classes/views/inbox/banner.php +15 -0
  26. classes/views/shared/admin-header.php +1 -0
  27. classes/views/shared/images-dropdown.php +44 -0
  28. classes/views/shared/upgrade_overlay.php +1 -1
  29. css/font_icons.css +1 -1
  30. css/frm_admin.css +91 -1
  31. formidable.php +1 -1
  32. images/icons.svg +5 -0
  33. js/formidable.js +21 -3
  34. js/formidable.min.js +36 -35
  35. js/formidable_admin.js +201 -29
  36. languages/formidable.pot +563 -501
  37. readme.txt +9 -9
classes/controllers/FrmAddonsController.php CHANGED
@@ -964,11 +964,32 @@ class FrmAddonsController {
964
  $plugin = FrmAppHelper::get_param( 'plugin', '', 'post', 'sanitize_text_field' );
965
  self::maybe_activate_addon( $plugin );
966
 
967
- // Send back a response.
968
- echo json_encode( __( 'Your plugin has been activated. Please reload the page to see more options.', 'formidable' ) );
969
  wp_die();
970
  }
971
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
972
  /**
973
  * @since 3.04.02
974
  * @param string $installed The plugin folder name with file name
@@ -1163,8 +1184,7 @@ class FrmAddonsController {
1163
 
1164
  self::download_and_activate();
1165
 
1166
- // Send back a response.
1167
- echo json_encode( __( 'Your plugin has been installed. Please reload the page to see more options.', 'formidable' ) );
1168
  wp_die();
1169
  }
1170
 
964
  $plugin = FrmAppHelper::get_param( 'plugin', '', 'post', 'sanitize_text_field' );
965
  self::maybe_activate_addon( $plugin );
966
 
967
+ echo json_encode( self::get_addon_activation_response() );
 
968
  wp_die();
969
  }
970
 
971
+ /**
972
+ * @return array|string
973
+ */
974
+ private static function get_addon_activation_response() {
975
+ if ( self::activating_from_settings_page() ) {
976
+ $response = array(
977
+ 'message' => __( 'Your plugin has been activated. Would you like to save and reload the page now?', 'formidable' ),
978
+ 'saveAndReload' => 'settings',
979
+ );
980
+ } else {
981
+ $response = __( 'Your plugin has been activated. Please reload the page to see more options.', 'formidable' );
982
+ }
983
+ return $response;
984
+ }
985
+
986
+ /**
987
+ * @return bool
988
+ */
989
+ private static function activating_from_settings_page() {
990
+ return false !== strpos( FrmAppHelper::get_server_value( 'HTTP_REFERER' ), 'frm_action=settings' );
991
+ }
992
+
993
  /**
994
  * @since 3.04.02
995
  * @param string $installed The plugin folder name with file name
1184
 
1185
  self::download_and_activate();
1186
 
1187
+ echo json_encode( self::get_addon_activation_response() );
 
1188
  wp_die();
1189
  }
1190
 
classes/controllers/FrmAppController.php CHANGED
@@ -422,9 +422,15 @@ class FrmAppController {
422
  self::admin_js();
423
  }
424
 
425
- if ( FrmAppHelper::is_admin_page( 'formidable' ) && in_array( FrmAppHelper::get_param( 'frm_action' ), array( 'add_new', 'list_templates' ), true ) ) {
426
- wp_safe_redirect( admin_url( 'admin.php?page=formidable&triggerNewFormModal=1' ) );
427
- exit;
 
 
 
 
 
 
428
  }
429
  }
430
 
422
  self::admin_js();
423
  }
424
 
425
+ if ( FrmAppHelper::is_admin_page( 'formidable' ) ) {
426
+ $action = FrmAppHelper::get_param( 'frm_action' );
427
+
428
+ if ( in_array( $action, array( 'add_new', 'list_templates' ), true ) ) {
429
+ wp_safe_redirect( admin_url( 'admin.php?page=formidable&triggerNewFormModal=1' ) );
430
+ exit;
431
+ }
432
+
433
+ FrmInbox::maybe_disable_screen_options();
434
  }
435
  }
436
 
classes/controllers/FrmEntriesController.php CHANGED
@@ -110,6 +110,16 @@ class FrmEntriesController {
110
  private static function get_columns_for_form( $form_id, &$columns ) {
111
  $form_cols = FrmField::get_all_for_form( $form_id, '', 'include' );
112
 
 
 
 
 
 
 
 
 
 
 
113
  foreach ( $form_cols as $form_col ) {
114
  if ( FrmField::is_no_save_field( $form_col->type ) ) {
115
  continue;
@@ -276,8 +286,7 @@ class FrmEntriesController {
276
  );
277
 
278
  foreach ( $fields as $field ) {
279
- if ( $field->type != 'checkbox' && ( ! isset( $field->field_options['post_field'] ) || $field->field_options['post_field'] == '' ) ) {
280
- // Can't sort on checkboxes because they are stored serialized, or post fields
281
  $columns[ $form_id . '_' . $field->field_key ] = 'meta_' . $field->id;
282
  }
283
  }
@@ -285,6 +294,18 @@ class FrmEntriesController {
285
  return $columns;
286
  }
287
 
 
 
 
 
 
 
 
 
 
 
 
 
288
  public static function hidden_columns( $result ) {
289
  $form_id = FrmForm::get_current_form_id();
290
 
110
  private static function get_columns_for_form( $form_id, &$columns ) {
111
  $form_cols = FrmField::get_all_for_form( $form_id, '', 'include' );
112
 
113
+ /**
114
+ * Allows changing fields in the Entries list table heading.
115
+ *
116
+ * @since 5.0.04
117
+ *
118
+ * @param array $fields Array of fields.
119
+ * @param array $args The arguments. Contains `form_id`.
120
+ */
121
+ $form_cols = apply_filters( 'frm_fields_in_entries_list_table', $form_cols, compact( 'form_id' ) );
122
+
123
  foreach ( $form_cols as $form_col ) {
124
  if ( FrmField::is_no_save_field( $form_col->type ) ) {
125
  continue;
286
  );
287
 
288
  foreach ( $fields as $field ) {
289
+ if ( self::field_supports_sorting( $field ) ) {
 
290
  $columns[ $form_id . '_' . $field->field_key ] = 'meta_' . $field->id;
291
  }
292
  }
294
  return $columns;
295
  }
296
 
297
+ /**
298
+ * Can't sort on checkboxes because they are sorted serialized.
299
+ * Some post content can be sorted but not everything.
300
+ *
301
+ * @param stdClass $field
302
+ * @return bool
303
+ */
304
+ private static function field_supports_sorting( $field ) {
305
+ $is_sortable = 'checkbox' !== $field->type && empty( $field->field_options['post_field'] );
306
+ return apply_filters( 'frm_field_column_is_sortable', $is_sortable, $field );
307
+ }
308
+
309
  public static function hidden_columns( $result ) {
310
  $form_id = FrmForm::get_current_form_id();
311
 
classes/controllers/FrmFieldsController.php CHANGED
@@ -127,6 +127,23 @@ class FrmFieldsController {
127
  $values = apply_filters( 'frm_prepare_single_field_for_duplication', $values );
128
 
129
  $field_id = FrmField::create( $values );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  if ( $field_id ) {
131
  self::load_single_field( $field_id, $values );
132
  }
@@ -695,6 +712,81 @@ class FrmFieldsController {
695
  $invalid_message = FrmFieldsHelper::get_error_msg( $field, 'invalid' );
696
  $add_html['data-invmsg'] = 'data-invmsg="' . esc_attr( $invalid_message ) . '"';
697
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
698
  }
699
 
700
  /**
127
  $values = apply_filters( 'frm_prepare_single_field_for_duplication', $values );
128
 
129
  $field_id = FrmField::create( $values );
130
+
131
+ /**
132
+ * Fires after duplicating a field.
133
+ *
134
+ * @since 5.0.04
135
+ *
136
+ * @param array $args {
137
+ * The arguments.
138
+ *
139
+ * @type int $field_id New field ID.
140
+ * @type array $values Values before inserting.
141
+ * @type object $copy_field Copy field data.
142
+ * @type int $form_id Form ID.
143
+ * }
144
+ */
145
+ do_action( 'frm_after_duplicate_field', compact( 'field_id', 'values', 'copy_field', 'form_id' ) );
146
+
147
  if ( $field_id ) {
148
  self::load_single_field( $field_id, $values );
149
  }
712
  $invalid_message = FrmFieldsHelper::get_error_msg( $field, 'invalid' );
713
  $add_html['data-invmsg'] = 'data-invmsg="' . esc_attr( $invalid_message ) . '"';
714
  }
715
+
716
+ if ( ! empty( $add_html['data-reqmsg'] ) || ! empty( $add_html['data-invmsg'] ) ) {
717
+ self::maybe_add_error_html_for_js_validation( $field, $add_html );
718
+ }
719
+ }
720
+
721
+ /**
722
+ * @since 5.0.03
723
+ *
724
+ * @param array $field
725
+ * @param array $add_html
726
+ */
727
+ private static function maybe_add_error_html_for_js_validation( $field, array &$add_html ) {
728
+ $form = self::get_form_for_js_validation( $field );
729
+ if ( false === $form ) {
730
+ return;
731
+ }
732
+
733
+ $error_body = self::pull_custom_error_body_from_custom_html( $form, $field );
734
+ if ( false !== $error_body ) {
735
+ $error_body = urlencode( $error_body );
736
+ $add_html['data-error-html'] = 'data-error-html="' . esc_attr( $error_body ) . '"';
737
+ }
738
+ }
739
+
740
+ /**
741
+ * @since 5.0.03
742
+ *
743
+ * @param array $field
744
+ * @return stdClass|false false if there is no form object found with JS validation active.
745
+ */
746
+ private static function get_form_for_js_validation( $field ) {
747
+ global $frm_vars;
748
+ if ( ! empty( $frm_vars['js_validate_forms'] ) ) {
749
+ if ( isset( $frm_vars['js_validate_forms'][ $field['form_id'] ] ) ) {
750
+ return $frm_vars['js_validate_forms'][ $field['form_id'] ];
751
+ }
752
+ if ( ! empty( $field['parent_form_id'] ) && isset( $frm_vars['js_validate_forms'][ $field['parent_form_id'] ] ) ) {
753
+ return $frm_vars['js_validate_forms'][ $field['parent_form_id'] ];
754
+ }
755
+ }
756
+ return false;
757
+ }
758
+
759
+ /**
760
+ * @param stdClass $form
761
+ * @param array $field
762
+ * @param array $errors
763
+ * @return string|false
764
+ */
765
+ public static function pull_custom_error_body_from_custom_html( $form, $field, $errors = array() ) {
766
+ if ( empty( $field['custom_html'] ) ) {
767
+ return false;
768
+ }
769
+
770
+ $custom_html = $field['custom_html'];
771
+ $custom_html = apply_filters( 'frm_before_replace_shortcodes', $custom_html, $field, $errors, $form );
772
+
773
+ $start = strpos( $custom_html, '[if error]' );
774
+ if ( false === $start ) {
775
+ return false;
776
+ }
777
+
778
+ $end = strpos( $custom_html, '[/if error]' );
779
+ if ( false === $end || $end < $start ) {
780
+ return false;
781
+ }
782
+
783
+ $error_body = substr( $custom_html, $start + 10, $end - $start - 10 );
784
+ if ( '<div class="frm_error" id="frm_error_field_[key]">[error]</div>' === $error_body ) {
785
+ // no custom HTML if the default is detected, so do nothing special.
786
+ return false;
787
+ }
788
+
789
+ return $error_body;
790
  }
791
 
792
  /**
classes/controllers/FrmFormsController.php CHANGED
@@ -975,9 +975,18 @@ class FrmFormsController {
975
 
976
  unset( $reset_fields );
977
 
978
- $args = array( 'parent_form_id' => $form->id );
979
- $values = FrmAppHelper::setup_edit_vars( $form, 'forms', '', true, array(), $args );
980
- $values['fields'] = $fields;
 
 
 
 
 
 
 
 
 
981
 
982
  $edit_message = __( 'Form was successfully updated.', 'formidable' );
983
  if ( $form->is_template && $message == $edit_message ) {
@@ -1018,6 +1027,16 @@ class FrmFormsController {
1018
  $fields = FrmField::get_all_for_form( $id );
1019
  $values = FrmAppHelper::setup_edit_vars( $form, 'forms', $fields, true );
1020
 
 
 
 
 
 
 
 
 
 
 
1021
  self::clean_submit_html( $values );
1022
 
1023
  $sections = self::get_settings_tabs( $values );
@@ -1183,7 +1202,17 @@ class FrmFormsController {
1183
  }
1184
 
1185
  public static function mb_tags_box( $form_id, $class = '' ) {
1186
- $fields = FrmField::get_all_for_form( $form_id, '', 'include' );
 
 
 
 
 
 
 
 
 
 
1187
  $linked_forms = array();
1188
  $col = 'one';
1189
  $settings_tab = FrmAppHelper::is_admin_page( 'formidable' ) ? true : false;
@@ -1325,9 +1354,23 @@ class FrmFormsController {
1325
  echo esc_attr( sanitize_text_field( $form->options['form_class'] ) );
1326
  }
1327
 
1328
- if ( isset( $form->options['js_validate'] ) && $form->options['js_validate'] ) {
1329
  echo ' frm_js_validate ';
 
 
 
 
 
 
 
 
 
 
 
 
 
1330
  }
 
1331
  }
1332
 
1333
  public static function get_email_html() {
975
 
976
  unset( $reset_fields );
977
 
978
+ $args = array( 'parent_form_id' => $form->id );
979
+ $values = FrmAppHelper::setup_edit_vars( $form, 'forms', '', true, array(), $args );
980
+
981
+ /**
982
+ * Allows modifying the list of fields in the form builder.
983
+ *
984
+ * @since 5.0.04
985
+ *
986
+ * @param object[] $fields Array of fields.
987
+ * @param array $args The arguments. Contains `form`.
988
+ */
989
+ $values['fields'] = apply_filters( 'frm_fields_in_form_builder', $fields, compact( 'form' ) );
990
 
991
  $edit_message = __( 'Form was successfully updated.', 'formidable' );
992
  if ( $form->is_template && $message == $edit_message ) {
1027
  $fields = FrmField::get_all_for_form( $id );
1028
  $values = FrmAppHelper::setup_edit_vars( $form, 'forms', $fields, true );
1029
 
1030
+ /**
1031
+ * Allows changing fields in the form settings.
1032
+ *
1033
+ * @since 5.0.04
1034
+ *
1035
+ * @param array $fields Array of fields.
1036
+ * @param array $args The arguments. Contains `form`.
1037
+ */
1038
+ $values['fields'] = apply_filters( 'frm_fields_in_settings', $values['fields'], compact( 'form' ) );
1039
+
1040
  self::clean_submit_html( $values );
1041
 
1042
  $sections = self::get_settings_tabs( $values );
1202
  }
1203
 
1204
  public static function mb_tags_box( $form_id, $class = '' ) {
1205
+ $fields = FrmField::get_all_for_form( $form_id, '', 'include' );
1206
+
1207
+ /**
1208
+ * Allows modifying the list of fields in the tags box.
1209
+ *
1210
+ * @since 5.0.04
1211
+ *
1212
+ * @param array $fields The list of fields.
1213
+ * @param array $args The arguments. Contains `form_id`.
1214
+ */
1215
+ $fields = apply_filters( 'frm_fields_in_tags_box', $fields, compact( 'form_id' ) );
1216
  $linked_forms = array();
1217
  $col = 'one';
1218
  $settings_tab = FrmAppHelper::is_admin_page( 'formidable' ) ? true : false;
1354
  echo esc_attr( sanitize_text_field( $form->options['form_class'] ) );
1355
  }
1356
 
1357
+ if ( ! empty( $form->options['js_validate'] ) ) {
1358
  echo ' frm_js_validate ';
1359
+ self::add_js_validate_form_to_global_vars( $form );
1360
+ }
1361
+ }
1362
+
1363
+ /**
1364
+ * @since 5.0.03
1365
+ *
1366
+ * @param stdClass $form
1367
+ */
1368
+ public static function add_js_validate_form_to_global_vars( $form ) {
1369
+ global $frm_vars;
1370
+ if ( ! isset( $frm_vars['js_validate_forms'] ) ) {
1371
+ $frm_vars['js_validate_forms'] = array();
1372
  }
1373
+ $frm_vars['js_validate_forms'][ $form->id ] = $form;
1374
  }
1375
 
1376
  public static function get_email_html() {
classes/controllers/FrmHooksController.php CHANGED
@@ -35,7 +35,9 @@ class FrmHooksController {
35
  // Instansiate Controllers.
36
  foreach ( $controllers as $c ) {
37
  foreach ( $hooks as $hook ) {
38
- call_user_func( array( $c, $hook ) );
 
 
39
  unset( $hook );
40
  }
41
  unset( $c );
35
  // Instansiate Controllers.
36
  foreach ( $controllers as $c ) {
37
  foreach ( $hooks as $hook ) {
38
+ if ( is_callable( array( $c, $hook ) ) ) {
39
+ call_user_func( array( $c, $hook ) );
40
+ }
41
  unset( $hook );
42
  }
43
  unset( $c );
classes/helpers/FrmAppHelper.php CHANGED
@@ -11,7 +11,7 @@ class FrmAppHelper {
11
  /**
12
  * @since 2.0
13
  */
14
- public static $plug_version = '5.0.03';
15
 
16
  /**
17
  * @since 1.07.02
@@ -2710,7 +2710,7 @@ class FrmAppHelper {
2710
  'ta' => __( 'Tamil', 'formidable' ),
2711
  'th' => __( 'Thai', 'formidable' ),
2712
  'tr' => __( 'Turkish', 'formidable' ),
2713
- 'uk' => __( 'Ukranian', 'formidable' ),
2714
  'vi' => __( 'Vietnamese', 'formidable' ),
2715
  );
2716
 
@@ -2745,6 +2745,203 @@ class FrmAppHelper {
2745
  return 'frmfont frm_logo_icon';
2746
  }
2747
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2748
  /**
2749
  * @since 4.07
2750
  * @deprecated 4.09.01
11
  /**
12
  * @since 2.0
13
  */
14
+ public static $plug_version = '5.0.04';
15
 
16
  /**
17
  * @since 1.07.02
2710
  'ta' => __( 'Tamil', 'formidable' ),
2711
  'th' => __( 'Thai', 'formidable' ),
2712
  'tr' => __( 'Turkish', 'formidable' ),
2713
+ 'uk' => __( 'Ukrainian', 'formidable' ),
2714
  'vi' => __( 'Vietnamese', 'formidable' ),
2715
  );
2716
 
2745
  return 'frmfont frm_logo_icon';
2746
  }
2747
 
2748
+ /**
2749
+ * Shows the images dropdown.
2750
+ *
2751
+ * @since 5.0.04
2752
+ *
2753
+ * @param array $args {
2754
+ * Arguments.
2755
+ *
2756
+ * @type string $selected Selected value.
2757
+ * @type array[] $options Array of options with keys are option values and values are array.
2758
+ * The option array contains `text`, `svg` and `custom_atts`.
2759
+ * @type string $classes Custom CSS classes for the wrapper element.
2760
+ * @type array $input_attrs Attributes of value input.
2761
+ * }
2762
+ */
2763
+ public static function images_dropdown( $args ) {
2764
+ $args = self::fill_default_images_dropdown_args( $args );
2765
+
2766
+ $input_attrs_str = self::get_images_dropdown_input_attrs( $args );
2767
+ ob_start();
2768
+ include self::plugin_path() . '/classes/views/shared/images-dropdown.php';
2769
+ $output = ob_get_clean();
2770
+
2771
+ /**
2772
+ * Allows modifying the output of FrmAppHelper::images_dropdown() method.
2773
+ *
2774
+ * @since 5.0.04
2775
+ *
2776
+ * @param string $output The output.
2777
+ * @param array $args Passed arguments.
2778
+ */
2779
+ echo apply_filters( 'frm_images_dropdown_output', $output, $args ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2780
+ }
2781
+
2782
+ /**
2783
+ * Fills the default images_dropdown() arguments.
2784
+ *
2785
+ * @since 5.0.04
2786
+ *
2787
+ * @param array $args The arguments.
2788
+ * @return array
2789
+ */
2790
+ private static function fill_default_images_dropdown_args( $args ) {
2791
+ $defaults = array(
2792
+ 'selected' => '',
2793
+ 'options' => array(),
2794
+ 'classes' => '',
2795
+ 'input_attrs' => array(),
2796
+ );
2797
+ $new_args = wp_parse_args( $args, $defaults );
2798
+
2799
+ $new_args['options'] = (array) $new_args['options'];
2800
+ $new_args['input_attrs'] = (array) $new_args['input_attrs'];
2801
+
2802
+ // Set the number of columns.
2803
+ $new_args['col_class'] = ceil( 12 / count( $new_args['options'] ) );
2804
+ if ( $new_args['col_class'] > 6 ) {
2805
+ $new_args['col_class'] = ceil( $new_args['col_class'] / 2 );
2806
+ }
2807
+
2808
+ /**
2809
+ * Allows modifying the arguments of images_dropdown() method.
2810
+ *
2811
+ * @since 5.0.04
2812
+ *
2813
+ * @param array $new_args Arguments after filling the defaults.
2814
+ * @param array $args Arguments passed to the method, before filling the defaults.
2815
+ */
2816
+ return apply_filters( 'frm_images_dropdown_args', $new_args, $args );
2817
+ }
2818
+
2819
+ /**
2820
+ * Gets HTML attributes of the input in images_dropdown() method.
2821
+ *
2822
+ * @since 5.0.04
2823
+ *
2824
+ * @param array $args The arguments.
2825
+ * @return string
2826
+ */
2827
+ private static function get_images_dropdown_input_attrs( $args ) {
2828
+ $input_attrs = $args['input_attrs'];
2829
+ $input_attrs['type'] = 'radio';
2830
+ $input_attrs['name'] = $args['name'];
2831
+
2832
+ $input_attrs_str = '';
2833
+ foreach ( $input_attrs as $key => $input_attr ) {
2834
+ $input_attrs_str .= ' ' . sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $input_attr ) );
2835
+ }
2836
+
2837
+ /**
2838
+ * Allows modifying the HTML attributes of the input in images_dropdown() method.
2839
+ *
2840
+ * @since 5.0.04
2841
+ *
2842
+ * @param string $input_attrs_str HTML attributes string.
2843
+ * @param array $args The arguments of images_dropdown() method.
2844
+ */
2845
+ return apply_filters( 'frm_images_dropdown_input_attrs', $input_attrs_str, $args );
2846
+ }
2847
+
2848
+ /**
2849
+ * Gets the image of each option in images_dropdown() method.
2850
+ *
2851
+ * @since 5.0.04
2852
+ *
2853
+ * @param array $option Option data.
2854
+ * @param array $args The arguments of images_dropdown() method.
2855
+ * @return string
2856
+ */
2857
+ private static function get_images_dropdown_option_image( $option, $args ) {
2858
+ $image = self::icon_by_class(
2859
+ 'frmfont ' . $option['svg'],
2860
+ array(
2861
+ 'echo' => false,
2862
+ )
2863
+ );
2864
+
2865
+ $args['option'] = $option;
2866
+
2867
+ /**
2868
+ * Allows modifying the image of each option in images_dropdown() method.
2869
+ *
2870
+ * @since 5.0.04
2871
+ *
2872
+ * @param string $image The image HTML.
2873
+ * @param array $args The arguments of images_dropdown() method, with `option` array is added.
2874
+ */
2875
+ return apply_filters( 'frm_images_dropdown_option_image', $image, $args );
2876
+ }
2877
+
2878
+ /**
2879
+ * Gets the HTML classes of each option in images_dropdown() method.
2880
+ *
2881
+ * @since 5.0.04
2882
+ *
2883
+ * @param array $option Option data.
2884
+ * @param array $args The arguments of images_dropdown() method.
2885
+ * @return string
2886
+ */
2887
+ private static function get_images_dropdown_option_classes( $option, $args ) {
2888
+ $classes = '';
2889
+
2890
+ if ( ! empty( $option['custom_attrs']['class'] ) ) {
2891
+ $classes .= ' ' . $option['custom_attrs']['class'];
2892
+ }
2893
+
2894
+ $args['option'] = $option;
2895
+
2896
+ /**
2897
+ * Allows modifying the CSS classes of each option in images_dropdown() method.
2898
+ *
2899
+ * @since 5.0.04
2900
+ *
2901
+ * @param string $classes CSS classes.
2902
+ * @param array $args The arguments of images_dropdown() method, with `option` array is added.
2903
+ */
2904
+ return apply_filters( 'frm_images_dropdown_option_classes', $classes, $args );
2905
+ }
2906
+
2907
+ /**
2908
+ * Gets the custom HTML attributes of each option in images_dropdown() method.
2909
+ *
2910
+ * @since 5.0.04
2911
+ *
2912
+ * @param array $option Option data.
2913
+ * @param array $args The arguments of images_dropdown() method.
2914
+ * @return string
2915
+ */
2916
+ private static function get_images_dropdown_option_html_attrs( $option, $args ) {
2917
+ $html_attrs = '';
2918
+ if ( ! empty( $option['custom_attrs'] ) && is_array( $option['custom_attrs'] ) ) {
2919
+ $html_attrs_arr = array();
2920
+
2921
+ foreach ( $option['custom_attrs'] as $key => $value ) {
2922
+ if ( in_array( $key, array( 'type', 'class', 'data-value' ) ) ) {
2923
+ continue;
2924
+ }
2925
+
2926
+ $html_attrs_arr[] = sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $value ) );
2927
+ }
2928
+
2929
+ $html_attrs = implode( ' ', $html_attrs_arr );
2930
+ }
2931
+
2932
+ $args['option'] = $option;
2933
+
2934
+ /**
2935
+ * Allows modifying the custom HTML attributes of each option in images_dropdown() method.
2936
+ *
2937
+ * @since 5.0.04
2938
+ *
2939
+ * @param string $html_attrs The HTML attributes string.
2940
+ * @param array $args The arguments of images_dropdown() method, with `option` array is added.
2941
+ */
2942
+ return apply_filters( 'frm_images_dropdown_option_html_attrs', $html_attrs, $args );
2943
+ }
2944
+
2945
  /**
2946
  * @since 4.07
2947
  * @deprecated 4.09.01
classes/helpers/FrmFieldsHelper.php CHANGED
@@ -571,25 +571,35 @@ class FrmFieldsHelper {
571
  }
572
 
573
  $m = false;
574
- if ( $cond == '==' ) {
575
  $m = $observed_value == $hide_opt;
576
- } elseif ( $cond == '!=' ) {
577
  $m = $observed_value != $hide_opt;
578
- } elseif ( $cond == '>' ) {
579
  $m = $observed_value > $hide_opt;
580
- } elseif ( $cond == '>=' ) {
581
  $m = $observed_value >= $hide_opt;
582
- } elseif ( $cond == '<' ) {
583
  $m = $observed_value < $hide_opt;
584
- } elseif ( $cond == '<=' ) {
585
  $m = $observed_value <= $hide_opt;
586
- } elseif ( $cond == 'LIKE' || $cond == 'not LIKE' ) {
587
  $m = stripos( $observed_value, $hide_opt );
588
- if ( $cond == 'not LIKE' ) {
589
  $m = ( $m === false ) ? true : false;
590
  } else {
591
  $m = ( $m === false ) ? false : true;
592
  }
 
 
 
 
 
 
 
 
 
 
593
  }
594
 
595
  return $m;
@@ -613,22 +623,22 @@ class FrmFieldsHelper {
613
 
614
  public static function array_value_condition( $observed_value, $cond, $hide_opt ) {
615
  $m = false;
616
- if ( $cond == '==' ) {
617
  if ( is_array( $hide_opt ) ) {
618
  $m = array_intersect( $hide_opt, $observed_value );
619
  $m = empty( $m ) ? false : true;
620
  } else {
621
  $m = in_array( $hide_opt, $observed_value );
622
  }
623
- } elseif ( $cond == '!=' ) {
624
  $m = ! in_array( $hide_opt, $observed_value );
625
- } elseif ( $cond == '>' ) {
626
  $min = min( $observed_value );
627
  $m = $min > $hide_opt;
628
- } elseif ( $cond == '<' ) {
629
  $max = max( $observed_value );
630
  $m = $max < $hide_opt;
631
- } elseif ( $cond == 'LIKE' || $cond == 'not LIKE' ) {
632
  foreach ( $observed_value as $ob ) {
633
  $m = strpos( $ob, $hide_opt );
634
  if ( $m !== false ) {
@@ -637,9 +647,25 @@ class FrmFieldsHelper {
637
  }
638
  }
639
 
640
- if ( $cond == 'not LIKE' ) {
641
  $m = ( $m === false ) ? true : false;
642
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
643
  }
644
 
645
  return $m;
@@ -982,7 +1008,7 @@ class FrmFieldsHelper {
982
  $field_types[ $type ] = $field_selection[ $type ];
983
  }
984
 
985
- $field_types = apply_filters( 'frm_switch_field_types', $field_types, compact( 'type' ) );
986
 
987
  return $field_types;
988
  }
@@ -1307,7 +1333,7 @@ class FrmFieldsHelper {
1307
  */
1308
  public static function bulk_options_overlay() {
1309
  $prepop = array();
1310
- self::get_bulk_prefilled_opts( $prepop );
1311
 
1312
  include( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/bulk-options-overlay.php' );
1313
  }
@@ -1629,20 +1655,45 @@ class FrmFieldsHelper {
1629
  return apply_filters( 'frm_countries', $countries );
1630
  }
1631
 
1632
- public static function get_bulk_prefilled_opts( array &$prepop ) {
1633
- $prepop[ __( 'Countries', 'formidable' ) ] = self::get_countries();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1634
 
 
1635
  $states = self::get_us_states();
1636
  $state_abv = array_keys( $states );
1637
  sort( $state_abv );
 
 
 
 
1638
  $prepop[ __( 'U.S. State Abbreviations', 'formidable' ) ] = $state_abv;
1639
 
 
1640
  $states = array_values( $states );
1641
  sort( $states );
 
 
 
 
1642
  $prepop[ __( 'U.S. States', 'formidable' ) ] = $states;
1643
  unset( $state_abv, $states );
1644
 
1645
- $prepop[ __( 'Age', 'formidable' ) ] = array(
 
1646
  __( 'Under 18', 'formidable' ),
1647
  __( '18-24', 'formidable' ),
1648
  __( '25-34', 'formidable' ),
@@ -1652,33 +1703,71 @@ class FrmFieldsHelper {
1652
  __( '65 or Above', 'formidable' ),
1653
  __( 'Prefer Not to Answer', 'formidable' ),
1654
  );
 
 
 
1655
 
1656
- $prepop[ __( 'Satisfaction', 'formidable' ) ] = array(
1657
- __( 'Very Satisfied', 'formidable' ),
1658
- __( 'Satisfied', 'formidable' ),
1659
- __( 'Neutral', 'formidable' ),
1660
- __( 'Unsatisfied', 'formidable' ),
1661
  __( 'Very Unsatisfied', 'formidable' ),
 
 
 
 
1662
  __( 'N/A', 'formidable' ),
1663
  );
 
 
 
1664
 
1665
- $prepop[ __( 'Importance', 'formidable' ) ] = array(
1666
- __( 'Very Important', 'formidable' ),
1667
- __( 'Important', 'formidable' ),
1668
- __( 'Neutral', 'formidable' ),
1669
- __( 'Somewhat Important', 'formidable' ),
1670
  __( 'Not at all Important', 'formidable' ),
 
 
 
 
1671
  __( 'N/A', 'formidable' ),
1672
  );
 
 
 
1673
 
1674
- $prepop[ __( 'Agreement', 'formidable' ) ] = array(
1675
- __( 'Strongly Agree', 'formidable' ),
 
 
 
 
 
1676
  __( 'Agree', 'formidable' ),
 
 
 
 
 
 
 
 
 
 
 
 
 
1677
  __( 'Neutral', 'formidable' ),
1678
- __( 'Disagree', 'formidable' ),
1679
- __( 'Strongly Disagree', 'formidable' ),
1680
  __( 'N/A', 'formidable' ),
1681
  );
 
 
 
 
 
1682
 
1683
  $prepop = apply_filters( 'frm_bulk_field_choices', $prepop );
1684
  }
@@ -1771,6 +1860,140 @@ class FrmFieldsHelper {
1771
  <?php
1772
  }
1773
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1774
  /**
1775
  * @deprecated 4.0
1776
  */
571
  }
572
 
573
  $m = false;
574
+ if ( $cond === '==' ) {
575
  $m = $observed_value == $hide_opt;
576
+ } elseif ( $cond === '!=' ) {
577
  $m = $observed_value != $hide_opt;
578
+ } elseif ( $cond === '>' ) {
579
  $m = $observed_value > $hide_opt;
580
+ } elseif ( $cond === '>=' ) {
581
  $m = $observed_value >= $hide_opt;
582
+ } elseif ( $cond === '<' ) {
583
  $m = $observed_value < $hide_opt;
584
+ } elseif ( $cond === '<=' ) {
585
  $m = $observed_value <= $hide_opt;
586
+ } elseif ( $cond === 'LIKE' || $cond === 'not LIKE' ) {
587
  $m = stripos( $observed_value, $hide_opt );
588
+ if ( $cond === 'not LIKE' ) {
589
  $m = ( $m === false ) ? true : false;
590
  } else {
591
  $m = ( $m === false ) ? false : true;
592
  }
593
+ } elseif ( $cond === '%LIKE' ) {
594
+ // ends with
595
+ $length = strlen( $hide_opt );
596
+ $substr = substr( $observed_value, strlen( $observed_value ) - $length );
597
+ $m = 0 === strcasecmp( $substr, $hide_opt );
598
+ } elseif ( 'LIKE%' === $cond ) {
599
+ // starts with
600
+ $length = strlen( $hide_opt );
601
+ $substr = substr( $observed_value, 0, $length );
602
+ $m = 0 === strcasecmp( $substr, $hide_opt );
603
  }
604
 
605
  return $m;
623
 
624
  public static function array_value_condition( $observed_value, $cond, $hide_opt ) {
625
  $m = false;
626
+ if ( $cond === '==' ) {
627
  if ( is_array( $hide_opt ) ) {
628
  $m = array_intersect( $hide_opt, $observed_value );
629
  $m = empty( $m ) ? false : true;
630
  } else {
631
  $m = in_array( $hide_opt, $observed_value );
632
  }
633
+ } elseif ( $cond === '!=' ) {
634
  $m = ! in_array( $hide_opt, $observed_value );
635
+ } elseif ( $cond === '>' ) {
636
  $min = min( $observed_value );
637
  $m = $min > $hide_opt;
638
+ } elseif ( $cond === '<' ) {
639
  $max = max( $observed_value );
640
  $m = $max < $hide_opt;
641
+ } elseif ( $cond === 'LIKE' || $cond === 'not LIKE' ) {
642
  foreach ( $observed_value as $ob ) {
643
  $m = strpos( $ob, $hide_opt );
644
  if ( $m !== false ) {
647
  }
648
  }
649
 
650
+ if ( $cond === 'not LIKE' ) {
651
  $m = ( $m === false ) ? true : false;
652
  }
653
+ } elseif ( $cond === '%LIKE' ) {
654
+ // ends with
655
+ foreach ( $observed_value as $ob ) {
656
+ if ( $hide_opt === substr( $ob, strlen( $ob ) - strlen( $hide_opt ) ) ) {
657
+ $m = true;
658
+ break;
659
+ }
660
+ }
661
+ } elseif ( $cond === 'LIKE%' ) {
662
+ // starts with
663
+ foreach ( $observed_value as $ob ) {
664
+ if ( $hide_opt === substr( $ob, 0, strlen( $hide_opt ) ) ) {
665
+ $m = true;
666
+ break;
667
+ }
668
+ }
669
  }
670
 
671
  return $m;
1008
  $field_types[ $type ] = $field_selection[ $type ];
1009
  }
1010
 
1011
+ $field_types = apply_filters( 'frm_switch_field_types', $field_types, compact( 'type', 'field_selection' ) );
1012
 
1013
  return $field_types;
1014
  }
1333
  */
1334
  public static function bulk_options_overlay() {
1335
  $prepop = array();
1336
+ self::get_bulk_prefilled_opts( $prepop, true );
1337
 
1338
  include( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/bulk-options-overlay.php' );
1339
  }
1655
  return apply_filters( 'frm_countries', $countries );
1656
  }
1657
 
1658
+ /**
1659
+ * Gets bulk prefilled options.
1660
+ *
1661
+ * @since 5.0.04 Add `$include_class` param.
1662
+ *
1663
+ * @param array $prepop Bulk options.
1664
+ * @param array $include_class Include the class in the bulk options.
1665
+ */
1666
+ public static function get_bulk_prefilled_opts( array &$prepop, $include_class = false ) {
1667
+ // Countries.
1668
+ $countries = self::get_countries();
1669
+ if ( $include_class ) {
1670
+ $countries['class'] = 'frm-countries-opts';
1671
+ }
1672
+
1673
+ $prepop[ __( 'Countries', 'formidable' ) ] = $countries;
1674
 
1675
+ // State abv.
1676
  $states = self::get_us_states();
1677
  $state_abv = array_keys( $states );
1678
  sort( $state_abv );
1679
+ if ( $include_class ) {
1680
+ $state_abv['class'] = 'frm-state-abv-opts';
1681
+ }
1682
+
1683
  $prepop[ __( 'U.S. State Abbreviations', 'formidable' ) ] = $state_abv;
1684
 
1685
+ // States.
1686
  $states = array_values( $states );
1687
  sort( $states );
1688
+ if ( $include_class ) {
1689
+ $states['class'] = 'frm-states-opts';
1690
+ }
1691
+
1692
  $prepop[ __( 'U.S. States', 'formidable' ) ] = $states;
1693
  unset( $state_abv, $states );
1694
 
1695
+ // Age.
1696
+ $ages = array(
1697
  __( 'Under 18', 'formidable' ),
1698
  __( '18-24', 'formidable' ),
1699
  __( '25-34', 'formidable' ),
1703
  __( '65 or Above', 'formidable' ),
1704
  __( 'Prefer Not to Answer', 'formidable' ),
1705
  );
1706
+ if ( $include_class ) {
1707
+ $ages['class'] = 'frm-age-opts';
1708
+ }
1709
 
1710
+ $prepop[ __( 'Age', 'formidable' ) ] = $ages;
1711
+
1712
+ // Satisfaction.
1713
+ $satisfaction = array(
 
1714
  __( 'Very Unsatisfied', 'formidable' ),
1715
+ __( 'Unsatisfied', 'formidable' ),
1716
+ __( 'Neutral', 'formidable' ),
1717
+ __( 'Satisfied', 'formidable' ),
1718
+ __( 'Very Satisfied', 'formidable' ),
1719
  __( 'N/A', 'formidable' ),
1720
  );
1721
+ if ( $include_class ) {
1722
+ $satisfaction['class'] = 'frm-satisfaction-opts';
1723
+ }
1724
 
1725
+ $prepop[ __( 'Satisfaction', 'formidable' ) ] = $satisfaction;
1726
+
1727
+ // Importance.
1728
+ $importance = array(
 
1729
  __( 'Not at all Important', 'formidable' ),
1730
+ __( 'Somewhat Important', 'formidable' ),
1731
+ __( 'Neutral', 'formidable' ),
1732
+ __( 'Important', 'formidable' ),
1733
+ __( 'Very Important', 'formidable' ),
1734
  __( 'N/A', 'formidable' ),
1735
  );
1736
+ if ( $include_class ) {
1737
+ $importance['class'] = 'frm-importance-opts';
1738
+ }
1739
 
1740
+ $prepop[ __( 'Importance', 'formidable' ) ] = $importance;
1741
+
1742
+ // Agreement.
1743
+ $agreement = array(
1744
+ __( 'Strongly Disagree', 'formidable' ),
1745
+ __( 'Disagree', 'formidable' ),
1746
+ __( 'Neutral', 'formidable' ),
1747
  __( 'Agree', 'formidable' ),
1748
+ __( 'Strongly Agree', 'formidable' ),
1749
+ __( 'N/A', 'formidable' ),
1750
+ );
1751
+ if ( $include_class ) {
1752
+ $agreement['class'] = 'frm-agreement-opts';
1753
+ }
1754
+
1755
+ $prepop[ __( 'Agreement', 'formidable' ) ] = $agreement;
1756
+
1757
+ // Likely.
1758
+ $likely = array(
1759
+ __( 'Extremely Unlikely', 'formidable' ),
1760
+ __( 'Unlikely', 'formidable' ),
1761
  __( 'Neutral', 'formidable' ),
1762
+ __( 'Likely', 'formidable' ),
1763
+ __( 'Extremely Likely', 'formidable' ),
1764
  __( 'N/A', 'formidable' ),
1765
  );
1766
+ if ( $include_class ) {
1767
+ $likely['class'] = 'frm-likely-opts';
1768
+ }
1769
+
1770
+ $prepop[ __( 'Likely', 'formidable' ) ] = $likely;
1771
 
1772
  $prepop = apply_filters( 'frm_bulk_field_choices', $prepop );
1773
  }
1860
  <?php
1861
  }
1862
 
1863
+ /**
1864
+ * Shows Display format option.
1865
+ *
1866
+ * @since 5.0.04
1867
+ *
1868
+ * @param array $field Field data.
1869
+ */
1870
+ public static function show_radio_display_format( $field ) {
1871
+ $options = array(
1872
+ '0' => array(
1873
+ 'text' => __( 'Simple', 'formidable' ),
1874
+ 'svg' => 'frm_simple_radio',
1875
+ ),
1876
+ '1' => array(
1877
+ 'text' => __( 'Images', 'formidable' ),
1878
+ 'svg' => 'frm_image_as_option',
1879
+ 'addon' => 'pro',
1880
+ 'upgrade' => __( 'Image Options', 'formidable' ),
1881
+ 'message' => __( 'Show images instead of radio buttons or check boxes. This is ideal for polls, surveys, segmenting questionnaires and more.', 'formidable' ) . '<img src="' . esc_url( FrmAppHelper::plugin_url() ) . '/images/image-options.png" />',
1882
+ 'content' => 'image-options',
1883
+ ),
1884
+ 'buttons' => array(
1885
+ 'text' => __( 'Buttons', 'formidable' ),
1886
+ 'svg' => 'frm_button_as_option',
1887
+ 'addon' => 'surveys',
1888
+ 'upgrade' => __( 'Button Options', 'formidable' ),
1889
+ 'message' => __( 'Show buttons for radio buttons or check boxes. This is ideal for polls, surveys, segmenting questionnaires and more.', 'formidable' ),
1890
+ 'content' => 'button-options',
1891
+ ),
1892
+ );
1893
+
1894
+ /**
1895
+ * Allows modifying the options of Display format setting of Radio field.
1896
+ *
1897
+ * @since 5.0.04
1898
+ *
1899
+ * @param array $options Options.
1900
+ */
1901
+ $options = apply_filters( 'frm_radio_display_format_options', $options );
1902
+
1903
+ $args = self::get_display_format_args( $field, $options );
1904
+
1905
+ include FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/radio-display-format.php';
1906
+ }
1907
+
1908
+ /**
1909
+ * Gets display format arguments to pass to the images_dropdown() method.
1910
+ *
1911
+ * @since 5.0.04
1912
+ *
1913
+ * @param array $field Field data.
1914
+ * @param array $options Options array.
1915
+ * @return array
1916
+ */
1917
+ private static function get_display_format_args( $field, $options ) {
1918
+ $args = array(
1919
+ 'selected' => '0',
1920
+ 'options' => array(),
1921
+ 'name' => 'field_options[image_options_' . $field['id'] . ']',
1922
+ 'input_attrs' => array(
1923
+ 'class' => 'frm_toggle_image_options',
1924
+ ),
1925
+ );
1926
+
1927
+ self::fill_image_setting_options( $options, $args );
1928
+
1929
+ /**
1930
+ * Allows modifying the arguments of Display format setting of Radio field.
1931
+ *
1932
+ * @since 5.0.04
1933
+ *
1934
+ * @param array $args Arguments.
1935
+ * @param array $method_args The arguments from the method. Contains `field`, `options`.
1936
+ */
1937
+ return apply_filters( 'frm_radio_display_format_args', $args, compact( 'field', 'options' ) );
1938
+ }
1939
+
1940
+ /**
1941
+ * @since 5.0.04
1942
+ */
1943
+ private static function fill_image_setting_options( $options, &$args ) {
1944
+ foreach ( $options as $key => $option ) {
1945
+ $args['options'][ $key ] = $option;
1946
+
1947
+ if ( ! empty( $option['addon'] ) ) {
1948
+ $args['options'][ $key ]['custom_attrs'] = self::fill_image_setting_addon_link( $option );
1949
+ }
1950
+
1951
+ unset( $args['options'][ $key ]['addon'] );
1952
+ $fill = array( 'upgrade', 'message', 'content' );
1953
+ foreach ( $fill as $f ) {
1954
+ unset( $args['options'][ $key ][ $f ], $f );
1955
+ }
1956
+ }
1957
+ }
1958
+
1959
+ /**
1960
+ * @since 5.0.04
1961
+ *
1962
+ * @return array
1963
+ */
1964
+ private static function fill_image_setting_addon_link( $option ) {
1965
+ $custom_attrs = array(
1966
+ 'class' => 'frm_noallow frm_show_upgrade',
1967
+ 'data-medium' => 'builder',
1968
+ );
1969
+
1970
+ // translators: Add-on name.
1971
+ $custom_attrs['data-upgrade'] = sprintf( __( 'Formidable %s', 'formidable' ), ucwords( $option['addon'] ) );
1972
+
1973
+ $fill = array( 'upgrade', 'message', 'content' );
1974
+ foreach ( $fill as $f ) {
1975
+ if ( isset( $option[ $f ] ) ) {
1976
+ $custom_attrs[ 'data-' . $f ] = $option[ $f ];
1977
+ }
1978
+ }
1979
+
1980
+ if ( 'pro' === $option['addon'] ) {
1981
+ return $custom_attrs;
1982
+ }
1983
+
1984
+ $upgrading = FrmAddonsController::install_link( $option['addon'] );
1985
+ if ( isset( $upgrading['url'] ) ) {
1986
+ $install_data = wp_json_encode( $upgrading );
1987
+ } else {
1988
+ $install_data = '';
1989
+ }
1990
+
1991
+ $custom_attrs['data-oneclick'] = $install_data;
1992
+ $custom_attrs['data-requires'] = FrmFormsHelper::get_plan_required( $upgrading );
1993
+
1994
+ return $custom_attrs;
1995
+ }
1996
+
1997
  /**
1998
  * @deprecated 4.0
1999
  */
classes/helpers/FrmTipsHelper.php CHANGED
@@ -122,13 +122,6 @@ class FrmTipsHelper {
122
  'tip' => __( 'Have long forms?', 'formidable' ),
123
  'call' => __( 'Let users save drafts and return later!', 'formidable' ),
124
  ),
125
- array(
126
- 'link' => array(
127
- 'content' => 'ajax',
128
- ),
129
- 'tip' => __( 'Want to submit forms without reloading the page?', 'formidable' ),
130
- 'call' => __( 'Get ajax form submit.', 'formidable' ),
131
- ),
132
  array(
133
  'link' => array(
134
  'content' => 'form-scheduling',
122
  'tip' => __( 'Have long forms?', 'formidable' ),
123
  'call' => __( 'Let users save drafts and return later!', 'formidable' ),
124
  ),
 
 
 
 
 
 
 
125
  array(
126
  'link' => array(
127
  'content' => 'form-scheduling',
classes/models/FrmEntry.php CHANGED
@@ -461,10 +461,8 @@ class FrmEntry {
461
  }
462
 
463
  if ( preg_match( '/ meta_([0-9]+)/', $order_by, $order_matches ) ) {
464
- // sort by a requested field
465
- $field_id = (int) $order_matches[1];
466
- $fields .= ', (SELECT meta_value FROM ' . $wpdb->prefix . 'frm_item_metas WHERE field_id = ' . $field_id . ' AND item_id = it.id) as meta_' . $field_id;
467
- unset( $order_matches, $field_id );
468
  }
469
 
470
  // prepare the query
@@ -527,6 +525,26 @@ class FrmEntry {
527
  return $entries;
528
  }
529
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
530
  // Pagination Methods
531
  /**
532
  * @param int|array|string If int, use the form id.
461
  }
462
 
463
  if ( preg_match( '/ meta_([0-9]+)/', $order_by, $order_matches ) ) {
464
+ $fields .= self::sort_by_field( $order_matches[1] );
465
+ unset( $order_matches );
 
 
466
  }
467
 
468
  // prepare the query
525
  return $entries;
526
  }
527
 
528
+ /**
529
+ * @param int $field_id
530
+ * @return string
531
+ */
532
+ private static function sort_by_field( $field_id ) {
533
+ global $wpdb;
534
+ $field_id = (int) $field_id;
535
+
536
+ $field_options = FrmDb::get_var( 'frm_fields', array( 'id' => $field_id ), 'field_options' );
537
+ FrmAppHelper::unserialize_or_decode( $field_options );
538
+
539
+ if ( empty( $field_options['post_field'] ) ) {
540
+ $sort = ', (SELECT meta_value FROM ' . $wpdb->prefix . 'frm_item_metas WHERE field_id = ' . $field_id . ' AND item_id = it.id) as meta_' . $field_id;
541
+ } else {
542
+ $sort = '';
543
+ }
544
+
545
+ return apply_filters( 'frm_handle_field_column_sort', $sort, $field_id, $field_options );
546
+ }
547
+
548
  // Pagination Methods
549
  /**
550
  * @param int|array|string If int, use the form id.
classes/models/FrmEntryValidate.php CHANGED
@@ -34,7 +34,16 @@ class FrmEntryValidate {
34
  self::spam_check( $exclude, $values, $errors );
35
  }
36
 
37
- $errors = apply_filters( 'frm_validate_entry', $errors, $values, compact( 'exclude' ) );
 
 
 
 
 
 
 
 
 
38
 
39
  return $errors;
40
  }
34
  self::spam_check( $exclude, $values, $errors );
35
  }
36
 
37
+ /**
38
+ * Allows modifying the validation errors after validating all fields.
39
+ *
40
+ * @since 5.0.04 Added `posted_fields` to the third param.
41
+ *
42
+ * @param array $errors Errors data.
43
+ * @param array $values Value data of the form.
44
+ * @param array $args Custom arguments. Contains `exclude` and `posted_fields`.
45
+ */
46
+ $errors = apply_filters( 'frm_validate_entry', $errors, $values, compact( 'exclude', 'posted_fields' ) );
47
 
48
  return $errors;
49
  }
classes/models/FrmEntryValues.php CHANGED
@@ -119,6 +119,16 @@ class FrmEntryValues {
119
  }
120
 
121
  $this->include_fields = $this->prepare_array_property( 'include_fields', $atts );
 
 
 
 
 
 
 
 
 
 
122
  }
123
 
124
  /**
@@ -130,6 +140,16 @@ class FrmEntryValues {
130
  */
131
  protected function init_exclude_fields( $atts ) {
132
  $this->exclude_fields = $this->prepare_array_property( 'exclude_fields', $atts );
 
 
 
 
 
 
 
 
 
 
133
  }
134
 
135
  /**
@@ -164,6 +184,23 @@ class FrmEntryValues {
164
  */
165
  protected function init_fields() {
166
  $this->fields = FrmField::get_all_for_form( $this->form_id, '', 'exclude', 'exclude' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
  }
168
 
169
  /**
119
  }
120
 
121
  $this->include_fields = $this->prepare_array_property( 'include_fields', $atts );
122
+
123
+ /**
124
+ * Allows modifying the IDs of include_fields used in the entry values.
125
+ *
126
+ * @since 5.0.04
127
+ *
128
+ * @param array $field_ids The list of field IDs.
129
+ * @param array $atts The arguments. See {@see FrmEntriesController::show_entry_shortcode()}.
130
+ */
131
+ $this->include_fields = apply_filters( 'frm_entry_values_include_fields', $this->include_fields, $atts );
132
  }
133
 
134
  /**
140
  */
141
  protected function init_exclude_fields( $atts ) {
142
  $this->exclude_fields = $this->prepare_array_property( 'exclude_fields', $atts );
143
+
144
+ /**
145
+ * Allows modifying the IDs of exclude_fields used in the entry values.
146
+ *
147
+ * @since 5.0.04
148
+ *
149
+ * @param array $field_ids The list of field IDs.
150
+ * @param array $atts The arguments. See {@see FrmEntriesController::show_entry_shortcode()}.
151
+ */
152
+ $this->exclude_fields = apply_filters( 'frm_entry_values_exclude_fields', $this->exclude_fields, $atts );
153
  }
154
 
155
  /**
184
  */
185
  protected function init_fields() {
186
  $this->fields = FrmField::get_all_for_form( $this->form_id, '', 'exclude', 'exclude' );
187
+
188
+ /**
189
+ * Allows modifying the list of all field in the form that is used in the entry values.
190
+ *
191
+ * @since 5.0.04
192
+ *
193
+ * @param array $fields The list of fields.
194
+ * @param array $args The arguments. Contains `form_id`, `entry`.
195
+ */
196
+ $this->fields = apply_filters(
197
+ 'frm_entry_values_fields',
198
+ $this->fields,
199
+ array(
200
+ 'form_id' => $this->form_id,
201
+ 'entry' => $this->entry,
202
+ )
203
+ );
204
  }
205
 
206
  /**
classes/models/FrmField.php CHANGED
@@ -139,6 +139,16 @@ class FrmField {
139
  'name' => __( 'Embed Form', 'formidable' ),
140
  'icon' => 'frm_icon_font frm_file_text_icon',
141
  ),
 
 
 
 
 
 
 
 
 
 
142
  'password' => array(
143
  'name' => __( 'Password', 'formidable' ),
144
  'icon' => 'frm_icon_font frm_lock_open_icon',
139
  'name' => __( 'Embed Form', 'formidable' ),
140
  'icon' => 'frm_icon_font frm_file_text_icon',
141
  ),
142
+ 'likert' => array(
143
+ 'name' => __( 'Likert Scale', 'formidable' ),
144
+ 'icon' => 'frm_icon_font frm_likert_scale frm_show_upgrade',
145
+ 'addon' => 'surveys',
146
+ ),
147
+ 'nps' => array(
148
+ 'name' => __( 'NPS', 'formidable' ),
149
+ 'icon' => 'frm_icon_font frm_nps frm_show_upgrade',
150
+ 'addon' => 'surveys',
151
+ ),
152
  'password' => array(
153
  'name' => __( 'Password', 'formidable' ),
154
  'icon' => 'frm_icon_font frm_lock_open_icon',
classes/models/FrmInbox.php CHANGED
@@ -14,6 +14,11 @@ class FrmInbox extends FrmFormApi {
14
 
15
  private $messages = false;
16
 
 
 
 
 
 
17
  public function __construct( $for_parent = null ) {
18
  $this->set_cache_key();
19
  $this->set_messages();
@@ -160,13 +165,19 @@ class FrmInbox extends FrmFormApi {
160
 
161
  /**
162
  * Show different messages for different accounts.
 
 
 
163
  */
164
  private function is_for_user( $message ) {
165
  if ( ! isset( $message['who'] ) || $message['who'] === 'all' ) {
166
  return true;
167
  }
168
-
169
- return in_array( $this->get_user_type(), (array) $message['who'] );
 
 
 
170
  }
171
 
172
  private function get_user_type() {
@@ -282,4 +293,33 @@ class FrmInbox extends FrmFormApi {
282
  private function update_list() {
283
  update_option( $this->option, $this->messages, 'no' );
284
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
  }
14
 
15
  private $messages = false;
16
 
17
+ /**
18
+ * @param array
19
+ */
20
+ private static $banner_messages;
21
+
22
  public function __construct( $for_parent = null ) {
23
  $this->set_cache_key();
24
  $this->set_messages();
165
 
166
  /**
167
  * Show different messages for different accounts.
168
+ *
169
+ * @param array $message
170
+ * @return bool
171
  */
172
  private function is_for_user( $message ) {
173
  if ( ! isset( $message['who'] ) || $message['who'] === 'all' ) {
174
  return true;
175
  }
176
+ $who = (array) $message['who'];
177
+ if ( in_array( 'all', $who, true ) || in_array( 'everyone', $who, true ) ) {
178
+ return true;
179
+ }
180
+ return in_array( $this->get_user_type(), $who, true );
181
  }
182
 
183
  private function get_user_type() {
293
  private function update_list() {
294
  update_option( $this->option, $this->messages, 'no' );
295
  }
296
+
297
+ public static function maybe_show_banner() {
298
+ if ( empty( self::$banner_messages ) ) {
299
+ return;
300
+ }
301
+ $message = end( self::$banner_messages );
302
+ require FrmAppHelper::plugin_path() . '/classes/views/inbox/banner.php';
303
+ }
304
+
305
+ public static function maybe_disable_screen_options() {
306
+ self::$banner_messages = self::get_banner_messages();
307
+ if ( self::$banner_messages ) {
308
+ // disable screen options tab when displaying banner messages because it gets in the way of the banner.
309
+ add_filter( 'screen_options_show_screen', '__return_false' );
310
+ }
311
+ }
312
+
313
+ /**
314
+ * @return array
315
+ */
316
+ private static function get_banner_messages() {
317
+ $inbox = new self();
318
+ return array_filter(
319
+ $inbox->get_messages( 'filter' ),
320
+ function( $message ) {
321
+ return ! empty( $message['banner'] );
322
+ }
323
+ );
324
+ }
325
  }
classes/models/fields/FrmFieldType.php CHANGED
@@ -700,9 +700,8 @@ DEFAULT_HTML;
700
  */
701
  public function prepare_field_html( $args ) {
702
  $args = $this->fill_display_field_values( $args );
703
-
704
  if ( $this->has_html ) {
705
- $args['html'] = $this->before_replace_html_shortcodes( $args, $this->field['custom_html'] );
706
  $args['errors'] = is_array( $args['errors'] ) ? $args['errors'] : array();
707
  $args['field_obj'] = $this;
708
 
700
  */
701
  public function prepare_field_html( $args ) {
702
  $args = $this->fill_display_field_values( $args );
 
703
  if ( $this->has_html ) {
704
+ $args['html'] = $this->before_replace_html_shortcodes( $args, FrmField::get_option( $this->field, 'custom_html' ) );
705
  $args['errors'] = is_array( $args['errors'] ) ? $args['errors'] : array();
706
  $args['field_obj'] = $this;
707
 
classes/views/frm-entries/form.php CHANGED
@@ -44,7 +44,16 @@ $frm_hide_fields = FrmAppHelper::get_post_param( 'frm_hide_fields_' . $form->id,
44
  <?php } ?>
45
  <?php
46
  if ( $values['fields'] ) {
47
- FrmFieldsHelper::show_fields( $values['fields'], $errors, $form, $form_action );
 
 
 
 
 
 
 
 
 
48
  }
49
 
50
  $frm_settings = FrmAppHelper::get_settings();
44
  <?php } ?>
45
  <?php
46
  if ( $values['fields'] ) {
47
+ /**
48
+ * Allows modifying the list of fields in the frontend form.
49
+ *
50
+ * @since 5.0.04
51
+ *
52
+ * @param array $fields Array of fields.
53
+ * @param array $args The arguments. Contains `form`.
54
+ */
55
+ $fields_to_show = apply_filters( 'frm_fields_in_form', $values['fields'], compact( 'form' ) );
56
+ FrmFieldsHelper::show_fields( $fields_to_show, $errors, $form, $form_action );
57
  }
58
 
59
  $frm_settings = FrmAppHelper::get_settings();
classes/views/frm-fields/back-end/bulk-options-overlay.php CHANGED
@@ -17,7 +17,8 @@ if ( ! defined( 'ABSPATH' ) ) {
17
  </p>
18
  <textarea name="frm_bulk_options" id="frm_bulk_options"></textarea>
19
  <input type="hidden" value="" id="bulk-field-id" />
20
-
 
21
  <button class="button-primary frm-button-primary" id="frm-update-bulk-opts">
22
  <?php esc_attr_e( 'Update Options', 'formidable' ); ?>
23
  </button>
@@ -27,8 +28,16 @@ if ( ! defined( 'ABSPATH' ) ) {
27
  <?php esc_html_e( 'Insert Presets', 'formidable' ); ?>
28
  </h3>
29
  <ul class="frm_prepop">
30
- <?php foreach ( $prepop as $label => $pop ) { ?>
31
- <li>
 
 
 
 
 
 
 
 
32
  <a href="#" class="frm-insert-preset" data-opts="<?php echo esc_attr( json_encode( $pop ) ); ?>">
33
  <?php echo esc_html( $label ); ?>
34
  </a>
17
  </p>
18
  <textarea name="frm_bulk_options" id="frm_bulk_options"></textarea>
19
  <input type="hidden" value="" id="bulk-field-id" />
20
+ <input type="hidden" value="" id="bulk-option-type" />
21
+
22
  <button class="button-primary frm-button-primary" id="frm-update-bulk-opts">
23
  <?php esc_attr_e( 'Update Options', 'formidable' ); ?>
24
  </button>
28
  <?php esc_html_e( 'Insert Presets', 'formidable' ); ?>
29
  </h3>
30
  <ul class="frm_prepop">
31
+ <?php
32
+ foreach ( $prepop as $label => $pop ) {
33
+ if ( isset( $pop['class'] ) ) {
34
+ $class = $pop['class'];
35
+ unset( $pop['class'] );
36
+ } else {
37
+ $class = '';
38
+ }
39
+ ?>
40
+ <li class="<?php echo esc_attr( $class ); ?>">
41
  <a href="#" class="frm-insert-preset" data-opts="<?php echo esc_attr( json_encode( $pop ) ); ?>">
42
  <?php echo esc_html( $label ); ?>
43
  </a>
classes/views/frm-fields/back-end/radio-display-format.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Display format option
4
+ *
5
+ * @since 5.0.04
6
+ * @package Formidable
7
+ *
8
+ * @var array $field Field data.
9
+ * @var array $options Options array.
10
+ * @var array $args The arguments.
11
+ */
12
+
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ die( 'You are not allowed to call this page directly.' );
15
+ }
16
+ ?>
17
+ <div id="frm_display_format_<?php echo intval( $field['id'] ); ?>_container" class="frm_form_field">
18
+ <label for="frm_image_options_<?php echo intval( $field['id'] ); ?>"><?php esc_html_e( 'Display format', 'formidable' ); ?></label>
19
+ <?php FrmAppHelper::images_dropdown( $args ); ?>
20
+ </div>
classes/views/frm-fields/back-end/radio-images.php CHANGED
@@ -1,7 +1,17 @@
1
  <?php
 
 
 
 
 
 
 
 
2
  if ( ! defined( 'ABSPATH' ) ) {
3
  die( 'You are not allowed to call this page directly.' );
4
  }
 
 
5
  ?>
6
  <p class="frm6 frm_form_field frm_noallow frm_show_upgrade" data-upgrade="<?php esc_attr_e( 'Separate Values', 'formidable' ); ?>" data-message="<?php esc_attr_e( 'Add a separate value to use for calculations, email routing, saving to the database, and many other uses. The option values are saved while the option labels are shown in the form.', 'formidable' ); ?>" data-medium="builder" data-content="separate-values">
7
  <label>
@@ -9,10 +19,3 @@ if ( ! defined( 'ABSPATH' ) ) {
9
  <?php esc_html_e( 'Use separate values', 'formidable' ); ?>
10
  </label>
11
  </p>
12
-
13
- <p class="frm6 frm_form_field frm_image_options_radio frm_noallow frm_show_upgrade" data-upgrade="<?php esc_attr_e( 'Image Options', 'formidable' ); ?>" data-message="<?php echo esc_attr( __( 'Show images instead of radio buttons or check boxes. This is ideal for polls, surveys, segmenting questionnaires and more.', 'formidable' ) . '<img src="' . FrmAppHelper::plugin_url() . '/images/image-options.png" />' ); ?>" data-medium="builder" data-content="image-options">
14
- <label>
15
- <input type="checkbox" value="1" disabled="disabled" />
16
- <?php esc_html_e( 'Use images for options', 'formidable' ); ?>
17
- </label>
18
- </p>
1
  <?php
2
+ /**
3
+ * View file for image options of Radio or Checkbox field.
4
+ *
5
+ * @package Formidable
6
+ *
7
+ * @var array $args Arguments. Contains `field`, `display` and `values`.
8
+ */
9
+
10
  if ( ! defined( 'ABSPATH' ) ) {
11
  die( 'You are not allowed to call this page directly.' );
12
  }
13
+
14
+ FrmFieldsHelper::show_radio_display_format( $args['field'] );
15
  ?>
16
  <p class="frm6 frm_form_field frm_noallow frm_show_upgrade" data-upgrade="<?php esc_attr_e( 'Separate Values', 'formidable' ); ?>" data-message="<?php esc_attr_e( 'Add a separate value to use for calculations, email routing, saving to the database, and many other uses. The option values are saved while the option labels are shown in the form.', 'formidable' ); ?>" data-medium="builder" data-content="separate-values">
17
  <label>
19
  <?php esc_html_e( 'Use separate values', 'formidable' ); ?>
20
  </label>
21
  </p>
 
 
 
 
 
 
 
classes/views/frm-fields/back-end/settings.php CHANGED
@@ -100,7 +100,17 @@ if ( $display['clear_on_focus'] ) {
100
  do_action( 'frm_extra_field_display_options', $field );
101
  }
102
 
103
- do_action( 'frm_before_field_options', $field );
 
 
 
 
 
 
 
 
 
 
104
 
105
  ?>
106
 
@@ -304,7 +314,7 @@ do_action( 'frm_before_field_options', $field );
304
  <select name="field_options[type_<?php echo esc_attr( $field['id'] ); ?>]" id="field_options_type_<?php echo esc_attr( $field['id'] ); ?>">
305
  <?php foreach ( $field_types as $fkey => $ftype ) { ?>
306
  <option value="<?php echo esc_attr( $fkey ); ?>" <?php echo ( $fkey === $field['type'] ) ? ' selected="selected"' : ''; ?> <?php echo array_key_exists( $fkey, $disabled_fields ) ? 'disabled="disabled"' : ''; ?>>
307
- <?php echo esc_html( is_array( $ftype ) ? $ftype['name'] : $ftype ); ?>
308
  </option>
309
  <?php
310
  unset( $fkey, $ftype );
100
  do_action( 'frm_extra_field_display_options', $field );
101
  }
102
 
103
+ /**
104
+ * Fires after printing the primary options section of field.
105
+ *
106
+ * @since 5.0.04 Added `$display` and `$values`.
107
+ *
108
+ * @param array $field Field data.
109
+ * @param FrmFieldType $field_obj Field type object.
110
+ * @param array $display Display data.
111
+ * @param array $values Field values.
112
+ */
113
+ do_action( 'frm_before_field_options', $field, compact( 'field_obj', 'display', 'values' ) );
114
 
115
  ?>
116
 
314
  <select name="field_options[type_<?php echo esc_attr( $field['id'] ); ?>]" id="field_options_type_<?php echo esc_attr( $field['id'] ); ?>">
315
  <?php foreach ( $field_types as $fkey => $ftype ) { ?>
316
  <option value="<?php echo esc_attr( $fkey ); ?>" <?php echo ( $fkey === $field['type'] ) ? ' selected="selected"' : ''; ?> <?php echo array_key_exists( $fkey, $disabled_fields ) ? 'disabled="disabled"' : ''; ?>>
317
+ <?php echo esc_html( is_array( $ftype ) ? $ftype['name'] : $ftype ); ?>
318
  </option>
319
  <?php
320
  unset( $fkey, $ftype );
classes/views/frm-fields/front-end/checkbox-field.php CHANGED
@@ -23,6 +23,16 @@ if ( isset( $field['post_field'] ) && $field['post_field'] == 'post_category' )
23
  $field_val = FrmFieldsHelper::get_value_from_array( $opt, $opt_key, $field );
24
  $opt = FrmFieldsHelper::get_label_from_array( $opt, $opt_key, $field );
25
 
 
 
 
 
 
 
 
 
 
 
26
  $checked = ''; // init
27
  if ( ! FrmFieldsHelper::is_other_opt( $opt_key ) ) {
28
  // Let the checked state of 'Other' fields be determined solely by FrmFieldsHelper::prepare_other_input as below.
@@ -48,7 +58,7 @@ if ( isset( $field['post_field'] ) && $field['post_field'] == 'post_category' )
48
  ?> /><?php
49
 
50
  if ( ! isset( $shortcode_atts ) || ! isset( $shortcode_atts['label'] ) || $shortcode_atts['label'] ) {
51
- echo ' ' . FrmAppHelper::kses( $opt, 'all' ) . '</label>'; // WPCS: XSS ok.
52
  }
53
 
54
  $other_args = array(
23
  $field_val = FrmFieldsHelper::get_value_from_array( $opt, $opt_key, $field );
24
  $opt = FrmFieldsHelper::get_label_from_array( $opt, $opt_key, $field );
25
 
26
+ /**
27
+ * Allows changing the HTML of option label in choice field (radio, checkbox,...).
28
+ *
29
+ * @since 5.0.04
30
+ *
31
+ * @param string $label Label HTML.
32
+ * @param array $args The arguments. Contains `field`.
33
+ */
34
+ $label = apply_filters( 'frm_choice_field_option_label', $opt, compact( 'field' ) );
35
+
36
  $checked = ''; // init
37
  if ( ! FrmFieldsHelper::is_other_opt( $opt_key ) ) {
38
  // Let the checked state of 'Other' fields be determined solely by FrmFieldsHelper::prepare_other_input as below.
58
  ?> /><?php
59
 
60
  if ( ! isset( $shortcode_atts ) || ! isset( $shortcode_atts['label'] ) || $shortcode_atts['label'] ) {
61
+ echo ' ' . FrmAppHelper::kses( $label, 'all' ) . '</label>'; // WPCS: XSS ok.
62
  }
63
 
64
  $other_args = array(
classes/views/frm-fields/front-end/radio-field.php CHANGED
@@ -22,6 +22,16 @@ if ( isset( $field['post_field'] ) && $field['post_field'] == 'post_category' )
22
 
23
  $field_val = FrmFieldsHelper::get_value_from_array( $opt, $opt_key, $field );
24
  $opt = FrmFieldsHelper::get_label_from_array( $opt, $opt_key, $field );
 
 
 
 
 
 
 
 
 
 
25
  ?>
26
  <div class="<?php echo esc_attr( apply_filters( 'frm_radio_class', 'frm_radio', $field, $field_val ) ); ?>" id="<?php echo esc_attr( FrmFieldsHelper::get_checkbox_id( $field, $opt_key, 'radio' ) ); ?>"><?php
27
 
@@ -40,7 +50,7 @@ if ( isset( $field['post_field'] ) && $field['post_field'] == 'post_category' )
40
  ?>/><?php
41
 
42
  if ( ! isset( $shortcode_atts ) || ! isset( $shortcode_atts['label'] ) || $shortcode_atts['label'] ) {
43
- echo ' ' . FrmAppHelper::kses( $opt, 'all' ) . '</label>'; // WPCS: XSS ok.
44
  }
45
 
46
  $other_args = array(
22
 
23
  $field_val = FrmFieldsHelper::get_value_from_array( $opt, $opt_key, $field );
24
  $opt = FrmFieldsHelper::get_label_from_array( $opt, $opt_key, $field );
25
+
26
+ /**
27
+ * Allows changing the HTML of option label in choice field (radio, checkbox,...).
28
+ *
29
+ * @since 5.0.04
30
+ *
31
+ * @param string $label Label HTML.
32
+ * @param array $args The arguments. Contains `field`.
33
+ */
34
+ $label = apply_filters( 'frm_choice_field_option_label', $opt, compact( 'field' ) );
35
  ?>
36
  <div class="<?php echo esc_attr( apply_filters( 'frm_radio_class', 'frm_radio', $field, $field_val ) ); ?>" id="<?php echo esc_attr( FrmFieldsHelper::get_checkbox_id( $field, $opt_key, 'radio' ) ); ?>"><?php
37
 
50
  ?>/><?php
51
 
52
  if ( ! isset( $shortcode_atts ) || ! isset( $shortcode_atts['label'] ) || $shortcode_atts['label'] ) {
53
+ echo ' ' . FrmAppHelper::kses( $label, 'all' ) . '</label>'; // WPCS: XSS ok.
54
  }
55
 
56
  $other_args = array(
classes/views/frm-forms/settings-advanced.php CHANGED
@@ -121,11 +121,13 @@ if ( ! defined( 'ABSPATH' ) ) {
121
  <?php is_callable( 'self::render_spam_settings' ) && self::render_spam_settings( $values ); ?>
122
  </table>
123
 
 
 
124
  <!--AJAX Section-->
125
  <h3><?php esc_html_e( 'AJAX', 'formidable' ); ?>
126
  <span class="frm_help frm_icon_font frm_tooltip_icon" data-placement="right" title="<?php esc_attr_e( 'Make stuff happen in the background without a page refresh', 'formidable' ); ?>" ></span>
127
  </h3>
128
- <?php FrmTipsHelper::pro_tip( 'get_form_settings_tip', 'p' ); ?>
129
  <table class="form-table">
130
  <tr>
131
  <td>
@@ -136,6 +138,17 @@ if ( ! defined( 'ABSPATH' ) ) {
136
  </td>
137
  </tr>
138
  <?php do_action( 'frm_add_form_ajax_options', $values ); ?>
 
 
 
 
 
 
 
 
 
 
 
139
  <tr>
140
  <td>
141
  <label for="js_validate" class="frm_inline_block">
121
  <?php is_callable( 'self::render_spam_settings' ) && self::render_spam_settings( $values ); ?>
122
  </table>
123
 
124
+ <?php FrmTipsHelper::pro_tip( 'get_form_settings_tip', 'p' ); ?>
125
+
126
  <!--AJAX Section-->
127
  <h3><?php esc_html_e( 'AJAX', 'formidable' ); ?>
128
  <span class="frm_help frm_icon_font frm_tooltip_icon" data-placement="right" title="<?php esc_attr_e( 'Make stuff happen in the background without a page refresh', 'formidable' ); ?>" ></span>
129
  </h3>
130
+
131
  <table class="form-table">
132
  <tr>
133
  <td>
138
  </td>
139
  </tr>
140
  <?php do_action( 'frm_add_form_ajax_options', $values ); ?>
141
+ <?php if ( ! FrmAppHelper::pro_is_installed() ) { ?>
142
+ <tr>
143
+ <td>
144
+ <label data-upgrade="<?php esc_attr_e( 'AJAX Form Submissions', 'formidable' ); ?>" data-medium="ajax" data-message="<?php esc_attr_e( 'Want to submit forms without reloading the page?', 'formidable' ); ?>">
145
+ <input type="checkbox" disabled="disabled" />
146
+ <span class="frm_noallow"><?php esc_html_e( 'Submit this form with AJAX', 'formidable' ); ?></span>
147
+ <span class="frm_help frm_icon_font frm_tooltip_icon" title="<?php esc_attr_e( 'Submit the form without refreshing the page.', 'formidable' ); ?>"></span>
148
+ </label>
149
+ </td>
150
+ </tr>
151
+ <?php } ?>
152
  <tr>
153
  <td>
154
  <label for="js_validate" class="frm_inline_block">
classes/views/frm-forms/settings-buttons.php CHANGED
@@ -47,9 +47,9 @@ if ( ! defined( 'ABSPATH' ) ) {
47
  </td>
48
  </tr>
49
  <tr>
50
- <td><label><?php esc_html_e( 'Submit Button Text', 'formidable' ); ?></label></td>
51
  <td>
52
- <input type="text" name="options[submit_value]" value="<?php echo esc_attr( $values['submit_value'] ); ?>" />
53
  </td>
54
  </tr>
55
  <?php do_action( 'frm_add_form_button_options', $values ); ?>
47
  </td>
48
  </tr>
49
  <tr>
50
+ <td><label for="frm_submit_button_text"><?php esc_html_e( 'Submit Button Text', 'formidable' ); ?></label></td>
51
  <td>
52
+ <input id="frm_submit_button_text" type="text" name="options[submit_value]" value="<?php echo esc_attr( $values['submit_value'] ); ?>" />
53
  </td>
54
  </tr>
55
  <?php do_action( 'frm_add_form_button_options', $values ); ?>
classes/views/inbox/banner.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ die( 'You are not allowed to call this page directly.' );
4
+ }
5
+ $cta = str_replace( 'button-secondary', 'button-primary', $message['cta'] );
6
+ ?>
7
+ <div id="frm_banner" data-key="<?php echo esc_attr( $message['key'] ); ?>">
8
+ <?php if ( ! empty( $message['emoji'] ) ) { ?>
9
+ <span class="frm-banner-emoji"><?php echo esc_html( $message['emoji'] ); ?></span>
10
+ <?php } ?>
11
+ <strong class="frm-banner-title"><?php echo esc_html( $message['subject'] ); ?></strong>
12
+ <span class="frm-banner-content"><?php echo esc_html( $message['banner'] ); ?></span>
13
+ <span class="frm-banner-cta"><?php echo FrmAppHelper::kses( $cta, 'all' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></span>
14
+ <span class="frm-banner-dismiss frmsvg"><?php FrmAppHelper::icon_by_class( 'frmfont frm_close_icon', array( 'aria-label' => 'Dismiss' ) ); ?></span>
15
+ </div>
classes/views/shared/admin-header.php CHANGED
@@ -11,6 +11,7 @@ if ( current_user_can( 'administrator' ) && ! FrmAppHelper::pro_is_installed() &
11
  </div>
12
  <?php
13
  }
 
14
  ?>
15
  <div id="frm_top_bar">
16
  <?php if ( FrmAppHelper::is_full_screen() ) { ?>
11
  </div>
12
  <?php
13
  }
14
+ FrmInbox::maybe_show_banner();
15
  ?>
16
  <div id="frm_top_bar">
17
  <?php if ( FrmAppHelper::is_full_screen() ) { ?>
classes/views/shared/images-dropdown.php ADDED
@@ -0,0 +1,44 @@