Formidable Forms – Form Builder for WordPress - Version 2.05

Version Description

  • New: Add option to not save IP address with entries for GDPR compliant forms
  • New: Add a new label position option: Inside. This option automatically uses the field labels as placeholders.
  • Enhancement: Prevent jumping when selecting field to edit on form builder.
  • Enhancement: Trigger frm_after_entry_processed hook after save when the action is set to show a message. This affects deleting entries automatically.
  • Enhancement: Allow text colors like "red" in frm-show-entry.
  • Enhancement: Increase minimum WP version requirement to 4.0.
  • Enhancement: Add array_key option to entry shortcode to set whether an ID or key is used when an array is returned.
  • Fix: Restore Default Plain button for filling email content.
  • Fix: Set dependency on reCaptcha script to ensure it loads after the Formidable script when defer fails.
  • Fix: Add frm_entries_list_query hook to filter queries on the Formidable -> Entries page.
  • Fix: Improve field duplication on form builder.
  • Fix: Remove deprecated notification settings on import.
  • Fix: Allow multiple invisible recaptchas to work on the same page.
  • Fix: Make sure licenses tab loads if navigating to it directly.
  • Pro Version Forms
  • New: Add Repeat Limit option to Repeatable Sections.
  • New: Add target="blank" option to file upload shortcodes with newpage=1 param.
  • New: Add frm_before_entries_table hook to display extar content on the Formidable -> Entries page.
  • New: Add frm_lookup_is_current_user_filter_needed filter to allow the options in a lookup field to be conditionally limited.
  • Enhancement: Allow repeating fields to be excluded from show entry shortcode.
  • Enhancement: Improve calculated fields that include fields both inside and outside a repeating section
  • Enhancement: Add RTL form support for time fields.
  • Enhancement: Conditionally allow int, rather than string, comparison in Lookup fields.
  • Enhancement: Add frm_main_feedback hook to messages shown after draft and edit.
  • Enhancement: Display zip code on the same line with city and state when an address is displayed.
  • Enhancement: Improve searching Dynamic field values on Entries tab
  • Fix: Improve compatibiliy with page builders and membership plugins. Don't run the_content filter on the View content. Instead, filter the content by calling those functions directly.
  • Fix: Delete temporary files after no less than 3 hours, regardless of time zone.
  • Fix: Append the media meta_query rather than replacing it. This resolves a conflict with files in WooCommerce.
  • Fix: Trim logic and actual value in conditional logic comparison.
  • Fix: Improve layout of confirmation field with a left label.
  • Fix: Allow a default value for checkbox fields on any form page.
  • Fix: Prevent Hidden fields from retaining "Clear default value when typing" setting when the field type changes.
  • Fix: Prevent errors when searching Dynamic fields with frm-search bar.
  • Fix: Do not send update emails when a draft is converted to an entry.
  • Fix: Do not show editable entry after submitting a draft, even though users can save and continue partial submissions.
  • Fix: Ensure the setting to not save credit card values is respected for draft entries too.
  • Fix: Do not show full address if [x show="line_2"] is empty.
  • Fix: Fix undefined index error for section ID shortcode.
  • Fix: Prevent jQuery from being loaded an extra time with edit in-place.
  • Fix: Correctly validate required field in embedded form on multi-page form.
  • Fix: Error messages were appearing in some server configurations when credit card numbers includes spaces.
Download this release

Release Info

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

Code changes from version 2.04.01 to 2.05

Files changed (45) hide show
  1. classes/controllers/FrmAddonsController.php +5 -11
  2. classes/controllers/FrmEntriesController.php +10 -3
  3. classes/controllers/FrmFieldsController.php +68 -21
  4. classes/controllers/FrmFormsController.php +141 -62
  5. classes/factories/FrmEntryFactory.php +4 -4
  6. classes/helpers/FrmAppHelper.php +10 -1
  7. classes/helpers/FrmEntriesHelper.php +13 -7
  8. classes/helpers/FrmEntriesListHelper.php +2 -0
  9. classes/helpers/FrmFieldsHelper.php +64 -11
  10. classes/helpers/FrmStylesHelper.php +25 -0
  11. classes/helpers/FrmXMLHelper.php +21 -1
  12. classes/models/FrmDb.php +3 -2
  13. classes/models/FrmEmail.php +7 -1
  14. classes/models/FrmEntry.php +4 -0
  15. classes/models/FrmEntryFormatter.php +37 -3
  16. classes/models/FrmEntryShortcodeFormatter.php +127 -41
  17. classes/models/FrmEntryValues.php +1 -1
  18. classes/models/FrmField.php +22 -22
  19. classes/models/FrmFieldValue.php +9 -0
  20. classes/models/FrmFieldValueSelector.php +1 -1
  21. classes/models/FrmSettings.php +4 -0
  22. classes/models/FrmTableHTMLGenerator.php +42 -51
  23. classes/views/addons/upgrade_to_pro.php +1 -1
  24. classes/views/frm-entries/sidebar-shared.php +5 -3
  25. classes/views/frm-form-actions/_email_settings.php +7 -1
  26. classes/views/frm-forms/add_field.php +15 -12
  27. classes/views/frm-settings/form.php +10 -1
  28. classes/views/styles/_field-labels.php +1 -1
  29. css/_single_theme.css.php +13 -8
  30. css/custom_theme.css.php +15 -0
  31. css/frm_admin.css +0 -1
  32. formidable.php +1 -1
  33. js/formidable.js +125 -75
  34. js/formidable.min.js +102 -101
  35. js/formidable_admin.js +52 -20
  36. languages/formidable-az_AZ.mo +0 -0
  37. languages/formidable-az_AZ.po +775 -751
  38. languages/formidable-da_DK.mo +0 -0
  39. languages/formidable-de_DE.mo +0 -0
  40. languages/formidable-de_DE.po +778 -756
  41. languages/formidable-es_ES.mo +0 -0
  42. languages/formidable-es_ES.po +778 -756
  43. languages/formidable-fr_FR.mo +0 -0
  44. languages/formidable-hu_HU.mo +0 -0
  45. languages/{formidable-fr_FR.po → formidable-hu_HU.po} +7735 -8128
classes/controllers/FrmAddonsController.php CHANGED
@@ -139,10 +139,6 @@ class FrmAddonsController {
139
  'title' => 'Polylang',
140
  'excerpt' => 'Create bilingual or multilingual forms with help from Polylang.',
141
  ),
142
- 'math-captcha' => array(
143
- 'title' => 'Math Captcha',
144
- 'excerpt' => 'Require users to perform a simple calculation before submitting a form to prevent spam. This add-on extends BestWebSoft\'s Captcha plugin.',
145
- ),
146
  'locations' => array(
147
  'title' => 'Locations',
148
  'excerpt' => 'Populate fields with Countries, States/Provinces, U.S. Counties, and U.S. Cities. This data can then be used in dependent Data from Entries fields.',
@@ -252,14 +248,12 @@ class FrmAddonsController {
252
  }
253
 
254
  private static function prepare_pro_info() {
255
- $pro_pricing = array(
256
- 'personal' => array( 'id' => 5, 'price' => '49.00', 'name' => 'Personal' ),
257
- 'professional' => array( 'id' => 6, 'price' => '99.00', 'name' => 'Professional' ),
258
- 'smallbusiness' => array( 'id' => 3, 'price' => '199.00', 'name' => 'Small Business' ),
259
- 'enterprise' => array( 'id' => 4, 'price' => '399.00', 'name' => 'Enterprise' ),
260
  );
261
-
262
- return $pro_pricing;
263
  }
264
 
265
  /**
139
  'title' => 'Polylang',
140
  'excerpt' => 'Create bilingual or multilingual forms with help from Polylang.',
141
  ),
 
 
 
 
142
  'locations' => array(
143
  'title' => 'Locations',
144
  'excerpt' => 'Populate fields with Countries, States/Provinces, U.S. Counties, and U.S. Cities. This data can then be used in dependent Data from Entries fields.',
248
  }
249
 
250
  private static function prepare_pro_info() {
251
+ return array(
252
+ 'personal' => array( 'id' => 2, 'download' => 19367654, 'price' => '49.00', 'name' => 'Personal' ),
253
+ 'professional' => array( 'id' => 0, 'download' => 19367001, 'price' => '99.00', 'name' => 'Professional' ),
254
+ 'smallbusiness' => array( 'id' => 0, 'download' => 19366995, 'price' => '199.00', 'name' => 'Small Business' ),
255
+ 'enterprise' => array( 'id' => 0, 'download' => 19366992, 'price' => '399.00', 'name' => 'Enterprise' ),
256
  );
 
 
257
  }
258
 
259
  /**
classes/controllers/FrmEntriesController.php CHANGED
@@ -81,7 +81,7 @@ class FrmEntriesController {
81
 
82
  $columns[ $form_id . '_created_at' ] = __( 'Entry creation date', 'formidable' );
83
  $columns[ $form_id . '_updated_at' ] = __( 'Entry update date', 'formidable' );
84
- $columns[ $form_id . '_ip' ] = 'IP';
85
 
86
  $frm_vars['cols'] = $columns;
87
 
@@ -131,6 +131,12 @@ class FrmEntriesController {
131
  }
132
  }
133
 
 
 
 
 
 
 
134
  public static function check_hidden_cols( $check, $object_id, $meta_key, $meta_value, $prev_value ) {
135
  $menu_name = FrmAppHelper::get_menu_name();
136
  $this_page_name = 'manage' . sanitize_title( $menu_name ) . '_page_formidable-entriescolumnshidden';
@@ -523,6 +529,7 @@ class FrmEntriesController {
523
  'default_email' => false,
524
  'form_id' => false,
525
  'format' => 'text',
 
526
  'direction' => 'ltr',
527
  'font_size' => '',
528
  'text_color' => '',
@@ -540,8 +547,8 @@ class FrmEntriesController {
540
  $atts = shortcode_atts( $defaults, $atts );
541
 
542
  if ( $atts['default_email'] ) {
543
-
544
- $entry_shortcode_formatter = FrmEntryFactory::entry_shortcode_formatter_instance( $atts['form_id'], $atts['format'] );
545
  $formatted_entry = $entry_shortcode_formatter->content();
546
 
547
  } else {
81
 
82
  $columns[ $form_id . '_created_at' ] = __( 'Entry creation date', 'formidable' );
83
  $columns[ $form_id . '_updated_at' ] = __( 'Entry update date', 'formidable' );
84
+ self::maybe_add_ip_col( $form_id, $columns );
85
 
86
  $frm_vars['cols'] = $columns;
87
 
131
  }
132
  }
133
 
134
+ private static function maybe_add_ip_col( $form_id, &$columns ) {
135
+ if ( FrmAppHelper::ips_saved() ) {
136
+ $columns[ $form_id . '_ip' ] = 'IP';
137
+ }
138
+ }
139
+
140
  public static function check_hidden_cols( $check, $object_id, $meta_key, $meta_value, $prev_value ) {
141
  $menu_name = FrmAppHelper::get_menu_name();
142
  $this_page_name = 'manage' . sanitize_title( $menu_name ) . '_page_formidable-entriescolumnshidden';
529
  'default_email' => false,
530
  'form_id' => false,
531
  'format' => 'text',
532
+ 'array_key' => 'key',
533
  'direction' => 'ltr',
534
  'font_size' => '',
535
  'text_color' => '',
547
  $atts = shortcode_atts( $defaults, $atts );
548
 
549
  if ( $atts['default_email'] ) {
550
+ $shortcode_atts = array( 'format' => $atts['format'], 'plain_text' => $atts['plain_text'] );
551
+ $entry_shortcode_formatter = FrmEntryFactory::entry_shortcode_formatter_instance( $atts['form_id'], $shortcode_atts );
552
  $formatted_entry = $entry_shortcode_formatter->content();
553
 
554
  } else {
classes/controllers/FrmFieldsController.php CHANGED
@@ -520,40 +520,87 @@ class FrmFieldsController {
520
  }
521
 
522
  private static function add_html_placeholder( $field, array &$add_html, array &$class ) {
523
- if ( empty( $field['default_value'] ) || FrmAppHelper::is_admin_page( 'formidable' ) ) {
524
  return;
525
  }
526
 
527
- $default_value_array = is_array( $field['default_value'] );
528
- if ( ! FrmField::is_option_true( $field, 'clear_on_focus' ) ) {
529
- if ( $default_value_array ) {
530
  $field['default_value'] = json_encode( $field['default_value'] );
 
 
 
531
  }
532
- $add_html['data-frmval'] = 'data-frmval="' . esc_attr( $field['default_value'] ) . '"';
533
- return;
534
- }
535
 
536
- if ( $default_value_array ) {
 
537
  // don't include a json placeholder
538
  return;
539
  }
540
 
541
- $frm_settings = FrmAppHelper::get_settings();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
542
 
543
- if ( $frm_settings->use_html && ! in_array( $field['type'], array( 'select', 'radio', 'checkbox', 'hidden' ) ) ) {
544
- // use HMTL5 placeholder with js fallback
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
545
  $add_html['placeholder'] = 'placeholder="' . esc_attr( $field['default_value'] ) . '"';
546
- wp_enqueue_script('jquery-placeholder');
547
- } else if ( ! $frm_settings->use_html ) {
548
- $val = str_replace( array( "\r\n", "\n" ), '\r', addslashes( str_replace( ''', "'", esc_attr( $field['default_value'] ) ) ) );
549
- $add_html['data-frmval'] = 'data-frmval="' . esc_attr( $val ) . '"';
550
- $class[] = 'frm_toggle_default';
551
 
552
- if ( $field['value'] == $field['default_value'] ) {
553
- $class[] = 'frm_default';
554
- }
555
- }
556
- }
 
557
 
558
  private static function add_validation_messages( $field, array &$add_html ) {
559
  if ( FrmField::is_required( $field ) ) {
520
  }
521
 
522
  private static function add_html_placeholder( $field, array &$add_html, array &$class ) {
523
+ if ( FrmAppHelper::is_admin_page( 'formidable' ) ) {
524
  return;
525
  }
526
 
527
+ if ( $field['default_value'] != '' && ! FrmField::is_option_true( $field, 'clear_on_focus' ) ) {
528
+ if ( is_array( $field['default_value'] ) ) {
 
529
  $field['default_value'] = json_encode( $field['default_value'] );
530
+ $add_html['data-frmval'] = 'data-frmval="' . esc_attr( $field['default_value'] ) . '"';
531
+ } else {
532
+ self::add_frmval_to_input( $field, $add_html );
533
  }
534
+ $field['default_value'] = '';
535
+ }
 
536
 
537
+ $field['default_value'] = self::prepare_default_value( $field );
538
+ if ( $field['default_value'] == '' || is_array( $field['default_value'] ) ) {
539
  // don't include a json placeholder
540
  return;
541
  }
542
 
543
+ $frm_settings = FrmAppHelper::get_settings();
544
+
545
+ if ( $frm_settings->use_html ) {
546
+ self::add_placeholder_to_input( $field, $add_html );
547
+ } else {
548
+ self::add_frmval_to_input( $field, $add_html );
549
+
550
+ $class[] = 'frm_toggle_default';
551
+
552
+ if ( $field['value'] == $field['default_value'] ) {
553
+ $class[] = 'frm_default';
554
+ }
555
+ }
556
+ }
557
+
558
+ private static function prepare_default_value( $field ) {
559
+ $is_placeholder_field = FrmFieldsHelper::is_placeholder_field_type( $field['type'] );
560
+ $is_combo_field = in_array( $field['type'], array( 'address', 'credit_card' ) );
561
+
562
+ $default_value = $field['default_value'];
563
+ if ( empty( $default_value ) ) {
564
+ if ( $is_placeholder_field && ! $is_combo_field ) {
565
+ $default_value = self::get_default_value_from_name( $field );
566
+ }
567
+ }
568
+
569
+ return $default_value;
570
+ }
571
 
572
+ /**
573
+ * If the label position is "inside",
574
+ * get the label to use as the placeholder
575
+ *
576
+ * @since 2.05
577
+ */
578
+ public static function get_default_value_from_name( $field ) {
579
+ $position = FrmStylesController::get_style_val( 'position', $field['form_id'] );
580
+ if ( $position == 'inside' ) {
581
+ $default_value = $field['name'];
582
+ } else {
583
+ $default_value = '';
584
+ }
585
+ return $default_value;
586
+ }
587
+
588
+ /**
589
+ * use HMTL5 placeholder with js fallback
590
+ */
591
+ private static function add_placeholder_to_input( $field, &$add_html ) {
592
+ if ( FrmFieldsHelper::is_placeholder_field_type( $field['type'] ) ) {
593
  $add_html['placeholder'] = 'placeholder="' . esc_attr( $field['default_value'] ) . '"';
594
+ wp_enqueue_script('jquery-placeholder');
595
+ }
596
+ }
 
 
597
 
598
+ private static function add_frmval_to_input( $field, &$add_html ) {
599
+ $val = str_replace( array( "\r\n", "\n" ), '\r', addslashes( str_replace( ''', "'", esc_attr( $field['default_value'] ) ) ) );
600
+ if ( $val != '' ) {
601
+ $add_html['data-frmval'] = 'data-frmval="' . esc_attr( $val ) . '"';
602
+ }
603
+ }
604
 
605
  private static function add_validation_messages( $field, array &$add_html ) {
606
  if ( FrmField::is_required( $field ) ) {
classes/controllers/FrmFormsController.php CHANGED
@@ -1139,87 +1139,166 @@ class FrmFormsController {
1139
  }
1140
 
1141
  public static function get_form_contents( $form, $title, $description, $atts ) {
1142
- global $frm_vars;
 
 
 
 
1143
 
1144
- $frm_settings = FrmAppHelper::get_settings();
1145
 
1146
- $submit = isset($form->options['submit_value']) ? $form->options['submit_value'] : $frm_settings->submit_value;
 
 
 
 
 
 
1147
 
1148
- $user_ID = get_current_user_id();
1149
- $params = FrmForm::get_params( $form );
1150
- $message = '';
1151
- $errors = array();
1152
 
1153
- if ( $params['posted_form_id'] == $form->id && $_POST ) {
1154
- $errors = isset( $frm_vars['created_entries'][ $form->id ] ) ? $frm_vars['created_entries'][ $form->id ]['errors'] : array();
1155
- }
1156
 
1157
- $include_form_tag = apply_filters( 'frm_include_form_tag', true, $form );
1158
- $fields = FrmFieldsHelper::get_form_fields( $form->id, $errors );
1159
 
1160
- if ( $params['action'] != 'create' || $params['posted_form_id'] != $form->id || ! $_POST ) {
1161
- do_action('frm_display_form_action', $params, $fields, $form, $title, $description);
1162
- if ( apply_filters('frm_continue_to_new', true, $form->id, $params['action']) ) {
1163
- $values = FrmEntriesHelper::setup_new_vars($fields, $form);
1164
- include( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/new.php' );
1165
- }
1166
- return;
1167
- }
 
 
 
 
1168
 
1169
- if ( ! empty($errors) ) {
1170
- $values = $fields ? FrmEntriesHelper::setup_new_vars($fields, $form) : array();
1171
- include( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/new.php' );
1172
- return;
1173
- }
 
1174
 
1175
- do_action('frm_validate_form_creation', $params, $fields, $form, $title, $description);
1176
- if ( ! apply_filters('frm_continue_to_create', true, $form->id) ) {
1177
- return;
1178
- }
 
 
 
1179
 
1180
- $values = FrmEntriesHelper::setup_new_vars($fields, $form, true);
1181
- $created = self::just_created_entry( $form->id );
1182
- $conf_method = apply_filters('frm_success_filter', 'message', $form, 'create');
 
 
 
 
1183
 
1184
- if ( $created && is_numeric($created) && $conf_method != 'message' ) {
1185
- do_action('frm_success_action', $conf_method, $form, $form->options, $created);
1186
- do_action( 'frm_after_entry_processed', array( 'entry_id' => $created, 'form' => $form ) );
1187
- return;
1188
- }
 
 
1189
 
1190
- if ( $created && is_numeric($created) ) {
1191
- $message = isset($form->options['success_msg']) ? $form->options['success_msg'] : $frm_settings->success_msg;
1192
- $class = 'frm_message';
1193
- } else {
1194
- $message = $frm_settings->failed_msg;
1195
- $class = FrmFormsHelper::form_error_class();
1196
- }
1197
 
1198
- $message = FrmFormsHelper::get_success_message( array(
1199
- 'message' => $message, 'form' => $form,
1200
- 'entry_id' => $created, 'class' => $class,
1201
- ) );
1202
- $message = apply_filters('frm_main_feedback', $message, $form, $created);
 
1203
 
1204
- if ( ! isset($form->options['show_form']) || $form->options['show_form'] ) {
1205
- require( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/new.php' );
1206
- } else {
1207
- global $frm_vars;
1208
- self::maybe_load_css( $form, $values['custom_style'], $frm_vars['load_css'] );
 
1209
 
1210
- $include_extra_container = 'frm_forms' . FrmFormsHelper::get_form_style_class( $values );
1211
- include( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/errors.php' );
1212
- }
 
 
1213
 
1214
- do_action( 'frm_after_entry_processed', array( 'entry_id' => $created, 'form' => $form ) );
1215
- }
 
 
 
 
 
 
 
 
 
 
 
 
1216
 
1217
  /**
1218
- * @since 2.2.7
 
1219
  */
1220
- public static function just_created_entry( $form_id ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1221
  global $frm_vars;
1222
- return ( isset( $frm_vars['created_entries'] ) && isset( $frm_vars['created_entries'][ $form_id ] ) && isset( $frm_vars['created_entries'][ $form_id ]['entry_id'] ) ) ? $frm_vars['created_entries'][ $form_id ]['entry_id'] : 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1223
  }
1224
 
1225
  public static function front_head() {
1139
  }
1140
 
1141
  public static function get_form_contents( $form, $title, $description, $atts ) {
1142
+ $params = FrmForm::get_params( $form );
1143
+ $errors = self::get_saved_errors( $form, $params );
1144
+ $fields = FrmFieldsHelper::get_form_fields( $form->id, $errors );
1145
+ $reset = false;
1146
+ $pass_args = compact( 'form', 'fields', 'errors', 'title', 'description', 'reset' );
1147
 
1148
+ $handle_process_here = $params['action'] == 'create' && $params['posted_form_id'] == $form->id && $_POST;
1149
 
1150
+ if ( ! $handle_process_here ) {
1151
+ do_action( 'frm_display_form_action', $params, $fields, $form, $title, $description );
1152
+ if ( apply_filters( 'frm_continue_to_new', true, $form->id, $params['action'] ) ) {
1153
+ self::show_form_after_submit( $pass_args );
1154
+ }
1155
+ } elseif ( ! empty( $errors ) ) {
1156
+ self::show_form_after_submit( $pass_args );
1157
 
1158
+ } else {
 
 
 
1159
 
1160
+ do_action( 'frm_validate_form_creation', $params, $fields, $form, $title, $description );
 
 
1161
 
1162
+ if ( apply_filters( 'frm_continue_to_create', true, $form->id ) ) {
1163
+ $entry_id = self::just_created_entry( $form->id );
1164
 
1165
+ $conf_method = apply_filters( 'frm_success_filter', 'message', $form, 'create' );
1166
+ if ( $entry_id && is_numeric( $entry_id ) && $conf_method != 'message' ) {
1167
+ self::run_success_action( compact( 'entry_id', 'form', 'conf_method' ) );
1168
+ } else {
1169
+ $pass_args['reset'] = true;
1170
+ $pass_args['entry_id'] = $entry_id;
1171
+ self::show_message_after_save( $pass_args );
1172
+ }
1173
+ do_action( 'frm_after_entry_processed', array( 'entry_id' => $entry_id, 'form' => $form ) );
1174
+ }
1175
+ }
1176
+ }
1177
 
1178
+ /**
1179
+ * If the form was processed earlier (init), get the generated errors
1180
+ * @since 2.05
1181
+ */
1182
+ private static function get_saved_errors( $form, $params ) {
1183
+ global $frm_vars;
1184
 
1185
+ if ( $params['posted_form_id'] == $form->id && $_POST && isset( $frm_vars['created_entries'][ $form->id ] ) ) {
1186
+ $errors = $frm_vars['created_entries'][ $form->id ]['errors'];
1187
+ } else {
1188
+ $errors = array();
1189
+ }
1190
+ return $errors;
1191
+ }
1192
 
1193
+ /**
1194
+ * @since 2.2.7
1195
+ */
1196
+ public static function just_created_entry( $form_id ) {
1197
+ global $frm_vars;
1198
+ return ( isset( $frm_vars['created_entries'] ) && isset( $frm_vars['created_entries'][ $form_id ] ) && isset( $frm_vars['created_entries'][ $form_id ]['entry_id'] ) ) ? $frm_vars['created_entries'][ $form_id ]['entry_id'] : 0;
1199
+ }
1200
 
1201
+ /**
1202
+ * Used when the success action is not 'message'
1203
+ * @since 2.05
1204
+ */
1205
+ public static function run_success_action( $args ) {
1206
+ do_action( 'frm_success_action', $args['conf_method'], $args['form'], $args['form']->options, $args['entry_id'] );
1207
+ }
1208
 
1209
+ /**
1210
+ * Prepare to show the success message and empty form after submit
1211
+ * @since 2.05
1212
+ */
1213
+ public static function show_message_after_save( $atts ) {
1214
+ $atts['message'] = self::prepare_submit_message( $atts['form'], $atts['entry_id'] );
 
1215
 
1216
+ if ( ! isset( $atts['form']->options['show_form'] ) || $atts['form']->options['show_form'] ) {
1217
+ self::show_form_after_submit( $atts );
1218
+ } else {
1219
+ self::show_lone_success_messsage( $atts );
1220
+ }
1221
+ }
1222
 
1223
+ /**
1224
+ * Show an empty form
1225
+ * @since 2.05
1226
+ */
1227
+ private static function show_form_after_submit( $args ) {
1228
+ self::fill_atts_for_form_display( $args );
1229
 
1230
+ $errors = $args['errors'];
1231
+ $message = $args['message'];
1232
+ $form = $args['form'];
1233
+ $title = $args['title'];
1234
+ $description = $args['description'];
1235
 
1236
+ if ( empty( $args['fields'] ) ) {
1237
+ $values = array();
1238
+ } else {
1239
+ $values = FrmEntriesHelper::setup_new_vars( $args['fields'], $form, $args['reset'] );
1240
+ }
1241
+ unset( $args );
1242
+
1243
+ $include_form_tag = apply_filters( 'frm_include_form_tag', true, $form );
1244
+
1245
+ $frm_settings = FrmAppHelper::get_settings();
1246
+ $submit = isset( $form->options['submit_value'] ) ? $form->options['submit_value'] : $frm_settings->submit_value;
1247
+
1248
+ include( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/new.php' );
1249
+ }
1250
 
1251
  /**
1252
+ * Get all the values needed on the new.php entry page
1253
+ * @since 2.05
1254
  */
1255
+ private static function fill_atts_for_form_display( &$args ) {
1256
+ $defaults = array(
1257
+ 'errors' => array(),
1258
+ 'message' => '',
1259
+ 'fields' => array(),
1260
+ 'form' => array(),
1261
+ 'title' => true,
1262
+ 'description' => false,
1263
+ 'reset' => false,
1264
+ );
1265
+ $args = wp_parse_args( $args, $defaults );
1266
+ }
1267
+
1268
+ /**
1269
+ * Show the success message without the form
1270
+ * @since 2.05
1271
+ */
1272
+ private static function show_lone_success_messsage( $atts ) {
1273
  global $frm_vars;
1274
+ $values = FrmEntriesHelper::setup_new_vars( $atts['fields'], $atts['form'], true );
1275
+ self::maybe_load_css( $atts['form'], $values['custom_style'], $frm_vars['load_css'] );
1276
+
1277
+ $include_extra_container = 'frm_forms' . FrmFormsHelper::get_form_style_class( $values );
1278
+ $errors = array();
1279
+ $form = $atts['form'];
1280
+ $message = $atts['message'];
1281
+
1282
+ include( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/errors.php' );
1283
+ }
1284
+
1285
+ /**
1286
+ * Prepare the success message before it's shown
1287
+ * @since 2.05
1288
+ */
1289
+ private static function prepare_submit_message( $form, $entry_id ) {
1290
+ $frm_settings = FrmAppHelper::get_settings();
1291
+
1292
+ if ( $entry_id && is_numeric( $entry_id ) ) {
1293
+ $message = isset( $form->options['success_msg'] ) ? $form->options['success_msg'] : $frm_settings->success_msg;
1294
+ $class = 'frm_message';
1295
+ } else {
1296
+ $message = $frm_settings->failed_msg;
1297
+ $class = FrmFormsHelper::form_error_class();
1298
+ }
1299
+
1300
+ $message = FrmFormsHelper::get_success_message( compact( 'message', 'form', 'entry_id', 'class' ) );
1301
+ return apply_filters( 'frm_main_feedback', $message, $form, $entry_id );
1302
  }
1303
 
1304
  public static function front_head() {
classes/factories/FrmEntryFactory.php CHANGED
@@ -30,15 +30,15 @@ class FrmEntryFactory {
30
  * @since 2.04
31
  *
32
  * @param int|string $form_id
33
- * @param string $format
34
  *
35
  * @return FrmEntryShortcodeFormatter|FrmProEntryShortcodeFormatter
36
  */
37
- public static function entry_shortcode_formatter_instance( $form_id, $format ) {
38
  if ( FrmAppHelper::pro_is_installed() ) {
39
- $shortcode_formatter = new FrmProEntryShortcodeFormatter( $form_id, $format );
40
  } else {
41
- $shortcode_formatter = new FrmEntryShortcodeFormatter( $form_id, $format );
42
  }
43
 
44
  return $shortcode_formatter;
30
  * @since 2.04
31
  *
32
  * @param int|string $form_id
33
+ * @param array $atts
34
  *
35
  * @return FrmEntryShortcodeFormatter|FrmProEntryShortcodeFormatter
36
  */
37
+ public static function entry_shortcode_formatter_instance( $form_id, $atts ) {
38
  if ( FrmAppHelper::pro_is_installed() ) {
39
+ $shortcode_formatter = new FrmProEntryShortcodeFormatter( $form_id, $atts );
40
  } else {
41
+ $shortcode_formatter = new FrmEntryShortcodeFormatter( $form_id, $atts );
42
  }
43
 
44
  return $shortcode_formatter;
classes/helpers/FrmAppHelper.php CHANGED
@@ -10,7 +10,7 @@ class FrmAppHelper {
10
  /**
11
  * @since 2.0
12
  */
13
- public static $plug_version = '2.04.01';
14
 
15
  /**
16
  * @since 1.07.02
@@ -90,6 +90,14 @@ class FrmAppHelper {
90
  return $frm_settings->menu;
91
  }
92
 
 
 
 
 
 
 
 
 
93
  /**
94
  * Show a message in place of pro features
95
  *
@@ -1781,6 +1789,7 @@ class FrmAppHelper {
1781
  'private' => __( 'Private' ),
1782
  'jquery_ui_url' => self::jquery_ui_base_url(),
1783
  'no_licenses' => __( 'No new licenses were found', 'formidable' ),
 
1784
  ) );
1785
  }
1786
  }
10
  /**
11
  * @since 2.0
12
  */
13
+ public static $plug_version = '2.05';
14
 
15
  /**
16
  * @since 1.07.02
90
  return $frm_settings->menu;
91
  }
92
 
93
+ /**
94
+ * @since 2.02.04
95
+ */
96
+ public static function ips_saved() {
97
+ $frm_settings = self::get_settings();
98
+ return ! $frm_settings->no_ips;
99
+ }
100
+
101
  /**
102
  * Show a message in place of pro features
103
  *
1789
  'private' => __( 'Private' ),
1790
  'jquery_ui_url' => self::jquery_ui_base_url(),
1791
  'no_licenses' => __( 'No new licenses were found', 'formidable' ),
1792
+ 'repeat_limit_min' => __( 'Please enter a Repeat Limit that is greater than 1.', 'formidable' ),
1793
  ) );
1794
  }
1795
  }
classes/helpers/FrmEntriesHelper.php CHANGED
@@ -17,6 +17,7 @@ class FrmEntriesHelper {
17
  }
18
 
19
  foreach ( (array) $fields as $field ) {
 
20
  $new_value = self::get_field_value_for_new_entry( $field, $reset, $args );
21
 
22
  $field_array = array(
@@ -79,6 +80,18 @@ class FrmEntriesHelper {
79
  return apply_filters( 'frm_setup_new_entry', $values );
80
  }
81
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  /**
83
  * Set the value for each field
84
  * This function is used when the form is first loaded and on all page turns *for a new entry*
@@ -91,13 +104,6 @@ class FrmEntriesHelper {
91
  * @return string|array $new_value
92
  */
93
  private static function get_field_value_for_new_entry( $field, $reset, $args ) {
94
- //If checkbox, multi-select dropdown, or checkbox data from entries field, the value should be an array
95
- $return_array = FrmField::is_field_with_multiple_values( $field );
96
-
97
- // Do any shortcodes in default value and allow customization of default value
98
- $field->default_value = apply_filters('frm_get_default_value', $field->default_value, $field, true, $return_array);
99
- // Calls FrmProFieldsHelper::get_default_value
100
-
101
  $new_value = $field->default_value;
102
 
103
  if ( ! $reset && self::value_is_posted( $field, $args ) ) {
17
  }
18
 
19
  foreach ( (array) $fields as $field ) {
20
+ self::prepare_field_default_value( $field );
21
  $new_value = self::get_field_value_for_new_entry( $field, $reset, $args );
22
 
23
  $field_array = array(
80
  return apply_filters( 'frm_setup_new_entry', $values );
81
  }
82
 
83
+ /**
84
+ * @since 2.05
85
+ */
86
+ private static function prepare_field_default_value( &$field ) {
87
+ //If checkbox, multi-select dropdown, or checkbox data from entries field, the value should be an array
88
+ $return_array = FrmField::is_field_with_multiple_values( $field );
89
+
90
+ // Do any shortcodes in default value and allow customization of default value
91
+ $field->default_value = apply_filters( 'frm_get_default_value', $field->default_value, $field, true, $return_array );
92
+ // Calls FrmProFieldsHelper::get_default_value
93
+ }
94
+
95
  /**
96
  * Set the value for each field
97
  * This function is used when the form is first loaded and on all page turns *for a new entry*
104
  * @return string|array $new_value
105
  */
106
  private static function get_field_value_for_new_entry( $field, $reset, $args ) {
 
 
 
 
 
 
 
107
  $new_value = $field->default_value;
108
 
109
  if ( ! $reset && self::value_is_posted( $field, $args ) ) {
classes/helpers/FrmEntriesListHelper.php CHANGED
@@ -30,6 +30,8 @@ class FrmEntriesListHelper extends FrmListHelper {
30
  $s_query = FrmProEntriesHelper::get_search_str( $s_query, $s, $form_id, $fid );
31
  }
32
 
 
 
33
  $orderby = isset( $_REQUEST['orderby'] ) ? sanitize_title( $_REQUEST['orderby'] ) : $default_orderby;
34
  if ( strpos($orderby, 'meta') !== false ) {
35
  $order_field_type = FrmField::get_type( str_replace( 'meta_', '', $orderby ) );
30
  $s_query = FrmProEntriesHelper::get_search_str( $s_query, $s, $form_id, $fid );
31
  }
32
 
33
+ $s_query = apply_filters( 'frm_entries_list_query', $s_query, compact( 'form_id' ) );
34
+
35
  $orderby = isset( $_REQUEST['orderby'] ) ? sanitize_title( $_REQUEST['orderby'] ) : $default_orderby;
36
  if ( strpos($orderby, 'meta') !== false ) {
37
  $order_field_type = FrmField::get_type( str_replace( 'meta_', '', $orderby ) );
classes/helpers/FrmFieldsHelper.php CHANGED
@@ -272,9 +272,8 @@ DEFAULT_HTML;
272
  $html = str_replace('[required_class]', $required_class, $html);
273
 
274
  //replace [label_position]
275
- $field['label'] = apply_filters('frm_html_label_position', $field['label'], $field, $form);
276
- $field['label'] = ( $field['label'] && $field['label'] != '' ) ? $field['label'] : 'top';
277
- $html = str_replace( '[label_position]', ( ( in_array( $field['type'], array( 'divider', 'end_divider', 'break' ) ) ) ? $field['label'] : ' frm_primary_label' ), $html );
278
 
279
  //replace [field_name]
280
  $html = str_replace('[field_name]', $field['name'], $html);
@@ -349,6 +348,52 @@ DEFAULT_HTML;
349
  return $html;
350
  }
351
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
352
  /**
353
  * This filters shortcodes in the field HTML
354
  *
@@ -489,7 +534,7 @@ DEFAULT_HTML;
489
  }
490
  $api_js_url = apply_filters( 'frm_recaptcha_js_url', $api_js_url );
491
 
492
- wp_register_script( 'recaptcha-api', $api_js_url, '', true );
493
  wp_enqueue_script( 'recaptcha-api' );
494
 
495
  // for reverse compatibility
@@ -539,13 +584,8 @@ DEFAULT_HTML;
539
  }
540
 
541
  public static function value_meets_condition( $observed_value, $cond, $hide_opt ) {
542
- // Remove white space from hide_opt
543
- if ( ! is_array( $hide_opt ) ) {
544
- $hide_opt = rtrim( $hide_opt );
545
- }
546
-
547
- $observed_value = wp_kses_post( $observed_value );
548
- $hide_opt = wp_kses_post( $hide_opt );
549
 
550
  if ( is_array($observed_value) ) {
551
  return self::array_value_condition($observed_value, $cond, $hide_opt);
@@ -571,6 +611,19 @@ DEFAULT_HTML;
571
  return $m;
572
  }
573
 
 
 
 
 
 
 
 
 
 
 
 
 
 
574
  public static function array_value_condition( $observed_value, $cond, $hide_opt ) {
575
  $m = false;
576
  if ( $cond == '==' ) {
272
  $html = str_replace('[required_class]', $required_class, $html);
273
 
274
  //replace [label_position]
275
+ $field['label'] = self::label_position( $field['label'], $field, $form );
276
+ self::add_class_to_label( $field, $html );
 
277
 
278
  //replace [field_name]
279
  $html = str_replace('[field_name]', $field['name'], $html);
348
  return $html;
349
  }
350
 
351
+ /**
352
+ * Get the class to use for the label position
353
+ * @since 2.05
354
+ */
355
+ private static function &label_position( $position, $field, $form ) {
356
+ if ( $position && $position != '' ) {
357
+ return $position;
358
+ }
359
+
360
+ $position = FrmStylesController::get_style_val( 'position', $form );
361
+ if ( $position == 'none' ) {
362
+ $position = 'top';
363
+ } elseif ( $position == 'no_label' ) {
364
+ $position = 'none';
365
+ } elseif ( $position == 'inside' && ! self::is_placeholder_field_type( $field['type'] ) ) {
366
+ $position = 'top';
367
+ }
368
+
369
+ $position = apply_filters( 'frm_html_label_position', $position, $field, $form );
370
+ $position = ( ! empty( $position ) ) ? $position : 'top';
371
+
372
+ return $position;
373
+ }
374
+
375
+ /**
376
+ * Check if this field type allows placeholders
377
+ * @since 2.05
378
+ */
379
+ public static function is_placeholder_field_type( $type ) {
380
+ return ! in_array( $type, array( 'select', 'radio', 'checkbox', 'hidden' ) );
381
+ }
382
+
383
+ /**
384
+ * Add the label position class into the HTML
385
+ * If the label position is inside, add a class to show the label if the field has a value.
386
+ *
387
+ * @since 2.05
388
+ */
389
+ private static function add_class_to_label( $field, &$html ) {
390
+ $label_class = in_array( $field['type'], array( 'divider', 'end_divider', 'break' ) ) ? $field['label'] : ' frm_primary_label';
391
+ $html = str_replace( '[label_position]', $label_class, $html );
392
+ if ( $field['label'] == 'inside' && $field['value'] != '' ) {
393
+ $html = str_replace( 'frm_primary_label', 'frm_primary_label frm_visible', $html );
394
+ }
395
+ }
396
+
397
  /**
398
  * This filters shortcodes in the field HTML
399
  *
534
  }
535
  $api_js_url = apply_filters( 'frm_recaptcha_js_url', $api_js_url );
536
 
537
+ wp_register_script( 'recaptcha-api', $api_js_url, array( 'formidable' ), true );
538
  wp_enqueue_script( 'recaptcha-api' );
539
 
540
  // for reverse compatibility
584
  }
585
 
586
  public static function value_meets_condition( $observed_value, $cond, $hide_opt ) {
587
+ $hide_opt = self::get_value_for_comparision( $hide_opt );
588
+ $observed_value = self::get_value_for_comparision( $observed_value );
 
 
 
 
 
589
 
590
  if ( is_array($observed_value) ) {
591
  return self::array_value_condition($observed_value, $cond, $hide_opt);
611
  return $m;
612
  }
613
 
614
+ /**
615
+ * Trim and sanitize the values
616
+ * @since 2.05
617
+ */
618
+ private static function get_value_for_comparision( $value ) {
619
+ // Remove white space from hide_opt
620
+ if ( ! is_array( $value ) ) {
621
+ $value = trim( $value );
622
+ }
623
+
624
+ return wp_kses_post( $value );
625
+ }
626
+
627
  public static function array_value_condition( $observed_value, $cond, $hide_opt ) {
628
  $m = false;
629
  if ( $cond == '==' ) {
classes/helpers/FrmStylesHelper.php CHANGED
@@ -96,6 +96,31 @@ class FrmStylesHelper {
96
  <?php
97
  }
98
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  public static function minus_icons() {
100
  return array(
101
  0 => array( '-' => '62e', '+' => '62f' ),
96
  <?php
97
  }
98
 
99
+ /**
100
+ * @since 2.05
101
+ */
102
+ public static function get_css_label_positions() {
103
+ return array(
104
+ 'none' => __( 'top', 'formidable' ),
105
+ 'left' => __( 'left', 'formidable' ),
106
+ 'right' => __( 'right', 'formidable' ),
107
+ 'no_label' => __( 'none', 'formidable' ),
108
+ 'inside' => __( 'inside', 'formidable' ),
109
+ );
110
+ }
111
+
112
+ public static function get_sigle_label_postitions() {
113
+ return array(
114
+ 'top' => __( 'Top', 'formidable' ),
115
+ 'left' => __( 'Left', 'formidable' ),
116
+ 'right' => __( 'Right', 'formidable' ),
117
+ 'inline' => __( 'Inline (left without a set width)', 'formidable' ),
118
+ 'none' => __( 'None', 'formidable' ),
119
+ 'hidden' => __( 'Hidden (but leave the space)', 'formidable' ),
120
+ 'inside' => __( 'Placeholder inside the field', 'formidable' ),
121
+ );
122
+ }
123
+
124
  public static function minus_icons() {
125
  return array(
126
  0 => array( '-' => '62e', '+' => '62f' ),
classes/helpers/FrmXMLHelper.php CHANGED
@@ -409,7 +409,7 @@ class FrmXMLHelper {
409
 
410
  if ( $f['type'] == 'form' || ( $f['type'] == 'divider' && FrmField::is_option_true( $f['field_options'], 'repeat' ) ) ) {
411
  if ( FrmField::is_option_true( $f['field_options'], 'form_select' ) ) {
412
- $form_select = $f['field_options']['form_select'];
413
  if ( isset( $imported['forms'][ $form_select ] ) ) {
414
  $f['field_options']['form_select'] = $imported['forms'][ $form_select ];
415
  }
@@ -1078,8 +1078,28 @@ class FrmXMLHelper {
1078
  }
1079
  unset($new_notification);
1080
  }
 
 
1081
  }
1082
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1083
  private static function migrate_notifications_to_action( $form_options, $form_id, &$notifications ) {
1084
  if ( ! isset( $form_options['notification'] ) && isset( $form_options['email_to'] ) && ! empty( $form_options['email_to'] ) ) {
1085
  // add old settings into notification array
409
 
410
  if ( $f['type'] == 'form' || ( $f['type'] == 'divider' && FrmField::is_option_true( $f['field_options'], 'repeat' ) ) ) {
411
  if ( FrmField::is_option_true( $f['field_options'], 'form_select' ) ) {
412
+ $form_select = (int) $f['field_options']['form_select'];
413
  if ( isset( $imported['forms'][ $form_select ] ) ) {
414
  $f['field_options']['form_select'] = $imported['forms'][ $form_select ];
415
  }
1078
  }
1079
  unset($new_notification);
1080
  }
1081
+
1082
+ self::remove_deprecated_notification_settings( $form_id, $form_options );
1083
  }
1084
 
1085
+ /**
1086
+ * Remove deprecated notification settings after migration
1087
+ *
1088
+ * @since 2.05
1089
+ *
1090
+ * @param int|string $form_id
1091
+ * @param array $form_options
1092
+ */
1093
+ private static function remove_deprecated_notification_settings( $form_id, $form_options ) {
1094
+ $delete_settings = array( 'notification', 'autoresponder', 'email_to' );
1095
+ foreach ( $delete_settings as $index ) {
1096
+ if ( isset( $form_options[ $index ] ) ) {
1097
+ unset( $form_options[ $index ] );
1098
+ }
1099
+ }
1100
+ FrmForm::update( $form_id, array( 'options' => $form_options ) );
1101
+ }
1102
+
1103
  private static function migrate_notifications_to_action( $form_options, $form_id, &$notifications ) {
1104
  if ( ! isset( $form_options['notification'] ) && isset( $form_options['email_to'] ) && ! empty( $form_options['email_to'] ) ) {
1105
  // add old settings into notification array
classes/models/FrmDb.php CHANGED
@@ -333,7 +333,7 @@ class FrmDb {
333
  * @param string $where
334
  */
335
  private static function add_query_placeholder( $key, $value, &$where ) {
336
- if ( is_numeric( $value ) && strpos( $key, 'meta_value' ) === false ) {
337
  $where .= '%d';
338
  } else {
339
  $where .= '%s';
@@ -838,7 +838,8 @@ DEFAULT_HTML;
838
  $new_default_html = FrmFieldsHelper::get_default_html('text');
839
  foreach ( $fields as $field ) {
840
  $field->field_options = maybe_unserialize($field->field_options);
841
- if ( ! FrmField::is_option_empty( $field, 'custom_html' ) || $field->field_options['custom_html'] == $default_html || $field->field_options['custom_html'] == $old_default_html ) {
 
842
  $field->field_options['custom_html'] = $new_default_html;
843
  $wpdb->update( $this->fields, array( 'field_options' => maybe_serialize( $field->field_options ) ), array( 'id' => $field->id ) );
844
  }
333
  * @param string $where
334
  */
335
  private static function add_query_placeholder( $key, $value, &$where ) {
336
+ if ( is_numeric( $value ) && ( strpos( $key, 'meta_value' ) === false || strpos( $key, '+0' ) !== false ) ) {
337
  $where .= '%d';
338
  } else {
339
  $where .= '%s';
838
  $new_default_html = FrmFieldsHelper::get_default_html('text');
839
  foreach ( $fields as $field ) {
840
  $field->field_options = maybe_unserialize($field->field_options);
841
+ $html = FrmField::get_option( $field, 'custom_html' );
842
+ if ( $html == $default_html || $html == $old_default_html ) {
843
  $field->field_options['custom_html'] = $new_default_html;
844
  $wpdb->update( $this->fields, array( 'field_options' => maybe_serialize( $field->field_options ) ), array( 'id' => $field->id ) );
845
  }
classes/models/FrmEmail.php CHANGED
@@ -296,7 +296,7 @@ class FrmEmail {
296
  if ( $this->include_user_info && $prev_mail_body == $mail_body ) {
297
  $data = maybe_unserialize( $this->entry->description );
298
  $mail_body .= "\r\n\r\n" . __( 'User Information', 'formidable' ) . "\r\n";
299
- $mail_body .= __( 'IP Address', 'formidable' ) . ': ' . $this->entry->ip . "\r\n";
300
  $mail_body .= __( 'User-Agent (Browser/OS)', 'formidable' ) . ': ' . FrmEntriesHelper::get_browser( $data['browser'] ) . "\r\n";
301
  $mail_body .= __( 'Referrer', 'formidable' ) . ': ' . $data['referrer'] . "\r\n";
302
  }
@@ -312,6 +312,12 @@ class FrmEmail {
312
  $this->message = apply_filters( 'frm_email_message', $this->message, $this->package_atts() );
313
  }
314
 
 
 
 
 
 
 
315
  /**
316
  * Set the attachments for an email message
317
  *
296
  if ( $this->include_user_info && $prev_mail_body == $mail_body ) {
297
  $data = maybe_unserialize( $this->entry->description );
298
  $mail_body .= "\r\n\r\n" . __( 'User Information', 'formidable' ) . "\r\n";
299
+ $this->maybe_add_ip( $mail_body );
300
  $mail_body .= __( 'User-Agent (Browser/OS)', 'formidable' ) . ': ' . FrmEntriesHelper::get_browser( $data['browser'] ) . "\r\n";
301
  $mail_body .= __( 'Referrer', 'formidable' ) . ': ' . $data['referrer'] . "\r\n";
302
  }
312
  $this->message = apply_filters( 'frm_email_message', $this->message, $this->package_atts() );
313
  }
314
 
315
+ private function maybe_add_ip( &$mail_body ) {
316
+ if ( ! empty( $this->entry->ip ) ) {
317
+ $mail_body .= __( 'IP Address', 'formidable' ) . ': ' . $this->entry->ip . "\r\n";
318
+ }
319
+ }
320
+
321
  /**
322
  * Set the attachments for an email message
323
  *
classes/models/FrmEntry.php CHANGED
@@ -576,6 +576,10 @@ class FrmEntry {
576
  * @return string
577
  */
578
  private static function get_ip( $values ) {
 
 
 
 
579
  $ip = FrmAppHelper::get_ip_address();
580
  if ( defined('WP_IMPORTING') && WP_IMPORTING ) {
581
  $ip = self::get_entry_value( $values, 'ip', $ip );
576
  * @return string
577
  */
578
  private static function get_ip( $values ) {
579
+ if ( ! FrmAppHelper::ips_saved() ) {
580
+ return '';
581
+ }
582
+
583
  $ip = FrmAppHelper::get_ip_address();
584
  if ( defined('WP_IMPORTING') && WP_IMPORTING ) {
585
  $ip = self::get_entry_value( $values, 'ip', $ip );
classes/models/FrmEntryFormatter.php CHANGED
@@ -41,6 +41,12 @@ class FrmEntryFormatter {
41
  */
42
  protected $format = 'text';
43
 
 
 
 
 
 
 
44
  /**
45
  * @var string
46
  * @since 2.04
@@ -69,7 +75,7 @@ class FrmEntryFormatter {
69
  * @var array
70
  * @since 2.04
71
  */
72
- protected $skip_fields = array( 'captcha' );
73
 
74
  /**
75
  * FrmEntryFormat constructor
@@ -87,6 +93,7 @@ class FrmEntryFormatter {
87
 
88
  $this->init_is_plain_text( $atts );
89
  $this->init_format( $atts );
 
90
  $this->init_include_blank( $atts );
91
  $this->init_direction( $atts );
92
  $this->init_include_user_info( $atts );
@@ -156,6 +163,20 @@ class FrmEntryFormatter {
156
  }
157
  }
158
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  /**
160
  * Set the is_plain_text property
161
  *
@@ -234,6 +255,19 @@ class FrmEntryFormatter {
234
  }
235
  }
236
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
  /**
238
  * Package and return the formatted entry values
239
  *
@@ -350,10 +384,10 @@ class FrmEntryFormatter {
350
  if ( $this->include_field_in_content( $field_value ) ) {
351
 
352
  $displayed_value = $this->prepare_display_value_for_array( $field_value->get_displayed_value() );
353
- $output[ $field_value->get_field_key() ] = $displayed_value;
354
 
355
  if ( $displayed_value !== $field_value->get_saved_value() ) {
356
- $output[ $field_value->get_field_key() . '-value' ] = $field_value->get_saved_value();
357
  }
358
  }
359
  }
41
  */
42
  protected $format = 'text';
43
 
44
+ /**
45
+ * @var string
46
+ * @since 2.05
47
+ */
48
+ protected $array_key = 'key';
49
+
50
  /**
51
  * @var string
52
  * @since 2.04
75
  * @var array
76
  * @since 2.04
77
  */
78
+ protected $skip_fields = array( 'captcha', 'html' );
79
 
80
  /**
81
  * FrmEntryFormat constructor
93
 
94
  $this->init_is_plain_text( $atts );
95
  $this->init_format( $atts );
96
+ $this->init_array_key( $atts );
97
  $this->init_include_blank( $atts );
98
  $this->init_direction( $atts );
99
  $this->init_include_user_info( $atts );
163
  }
164
  }
165
 
166
+ /**
167
+ * Set the array_key property that sets whether the keys in the
168
+ * returned array are field keys or ids
169
+ *
170
+ * @since 2.05
171
+ *
172
+ * @param array $atts
173
+ */
174
+ protected function init_array_key( $atts ) {
175
+ if ( isset( $atts['array_key'] ) && $atts['array_key'] == 'id' ) {
176
+ $this->array_key = 'id';
177
+ }
178
+ }
179
+
180
  /**
181
  * Set the is_plain_text property
182
  *
255
  }
256
  }
257
 
258
+ /**
259
+ * Get the field key or ID, depending on array_key property
260
+ *
261
+ * @since 2.05
262
+ *
263
+ * @param FrmFieldValue $field_value
264
+ *
265
+ * @return string|int
266
+ */
267
+ protected function get_key_or_id( $field_value ) {
268
+ return $this->array_key == 'key' ? $field_value->get_field_key() : $field_value->get_field_id();
269
+ }
270
+
271
  /**
272
  * Package and return the formatted entry values
273
  *
384
  if ( $this->include_field_in_content( $field_value ) ) {
385
 
386
  $displayed_value = $this->prepare_display_value_for_array( $field_value->get_displayed_value() );
387
+ $output[ $this->get_key_or_id( $field_value ) ] = $displayed_value;
388
 
389
  if ( $displayed_value !== $field_value->get_saved_value() ) {
390
+ $output[ $this->get_key_or_id( $field_value ) . '-value' ] = $field_value->get_saved_value();
391
  }
392
  }
393
  }
classes/models/FrmEntryShortcodeFormatter.php CHANGED
@@ -15,7 +15,7 @@ class FrmEntryShortcodeFormatter {
15
  * @var array
16
  * @since 2.04
17
  */
18
- protected $skip_fields = array( 'captcha' );
19
 
20
  /**
21
  * @var array
@@ -23,6 +23,12 @@ class FrmEntryShortcodeFormatter {
23
  */
24
  protected $fields = array();
25
 
 
 
 
 
 
 
26
  /**
27
  * @var string
28
  * @since 2.04
@@ -34,64 +40,88 @@ class FrmEntryShortcodeFormatter {
34
  * @since 2.04
35
  */
36
  protected $table_generator = null;
 
37
  /**
38
  * @var array
39
  * @since 2.04
40
  */
41
  protected $array_content = array();
42
 
43
- public function __construct( $form_id, $format ) {
 
 
 
 
 
 
44
  if ( ! $form_id ) {
45
  return;
46
  }
47
 
48
  $this->init_form_id( $form_id );
49
  $this->init_fields();
50
- $this->init_format( $format );
51
 
52
  if ( empty( $this->fields ) ) {
53
  return;
54
  }
55
 
56
- if ( $this->format == 'text' ) {
 
 
 
57
  $this->init_table_generator();
58
  }
59
  }
60
 
61
  /**
62
- * Set the form_id property
63
  *
64
  * @since 2.04
65
  * @param $form_id
66
  */
67
- private function init_form_id( $form_id ) {
68
  $this->form_id = (int) $form_id;
69
  }
70
 
71
  /**
72
- * Set the fields property
73
  *
74
  * @since 2.04
75
  */
76
- private function init_fields() {
77
  $this->fields = FrmField::get_all_for_form( $this->form_id, '', 'exclude', 'exclude' );
78
  }
79
 
80
  /**
81
- * Set the format property
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  *
83
  * @since 2.04
84
  *
85
- * @param string|mixed $format
86
  */
87
- private function init_format( $format ) {
88
- if ( is_string( $format ) && $format !== '' ) {
89
- $this->format = $format;
 
 
90
  }
91
  }
92
 
93
  /**
94
- * Set the table_generator property
95
  *
96
  * @since 2.04
97
  */
@@ -105,12 +135,16 @@ class FrmEntryShortcodeFormatter {
105
  * @since 2.04
106
  */
107
  public function content() {
108
- if ( $this->form_id === 0 ) {
109
- $content = '';
110
- } else if ( $this->format == 'array' ) {
 
 
111
  $content = $this->get_array();
 
 
112
  } else {
113
- $content = $this->text();
114
  }
115
 
116
  return $content;
@@ -121,11 +155,7 @@ class FrmEntryShortcodeFormatter {
121
  *
122
  * @since 2.04
123
  */
124
- private function get_array() {
125
- if ( ! $this->form_id || empty( $this->fields ) ) {
126
- return '';
127
- }
128
-
129
  foreach ( $this->fields as $field ) {
130
  $this->add_field_array( $field );
131
  }
@@ -134,28 +164,46 @@ class FrmEntryShortcodeFormatter {
134
  }
135
 
136
  /**
137
- * Return the default HTML for an email message
138
  *
139
  * @since 2.04
140
  */
141
- private function text() {
142
- if ( ! $this->form_id || empty( $this->fields ) ) {
143
- return '';
144
- }
145
 
 
 
 
 
 
 
146
  $content = $this->table_generator->generate_table_header();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
 
148
  foreach ( $this->fields as $field ) {
149
- $content .= $this->generate_field_html( $field );
150
  }
151
 
152
- $content .= $this->table_generator->generate_table_footer();
153
-
154
  return $content;
155
  }
156
 
157
  /**
158
- * Generate a field's HTML for the default HTML
159
  *
160
  * @since 2.04
161
  *
@@ -163,28 +211,48 @@ class FrmEntryShortcodeFormatter {
163
  *
164
  * @return string
165
  */
166
- protected function generate_field_html( $field ) {
167
  if ( in_array( $field->type, $this->skip_fields ) ) {
168
  return '';
169
  }
170
 
171
- $row = $this->generate_single_row( $field );
172
 
173
  return $row;
174
  }
175
 
176
  /**
177
- * Generate a single table row
178
  *
179
  * @since 2.04
180
  *
181
  * @param stdClass $field
182
- * @param null|string $value
183
  *
184
  * @return string
185
  */
186
- protected function generate_single_row( $field, $value = null ) {
187
- return $this->table_generator->generate_two_cell_shortcode_row( $field, $value );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  }
189
 
190
  /**
@@ -209,8 +277,6 @@ class FrmEntryShortcodeFormatter {
209
  *
210
  * @param stdClass $field
211
  * @param string $value
212
- *
213
- * @return array
214
  */
215
  protected function add_single_field_array( $field, $value ) {
216
  $array = array(
@@ -220,8 +286,28 @@ class FrmEntryShortcodeFormatter {
220
  );
221
 
222
  $this->array_content[ $field->id ] = apply_filters( 'frm_field_shortcodes_for_default_html_email', $array, $field );
 
223
 
224
- return $array;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
  }
226
 
227
  }
15
  * @var array
16
  * @since 2.04
17
  */
18
+ protected $skip_fields = array( 'captcha', 'html' );
19
 
20
  /**
21
  * @var array
23
  */
24
  protected $fields = array();
25
 
26
+ /**
27
+ * @var bool
28
+ * @since 2.05
29
+ */
30
+ protected $is_plain_text = false;
31
+
32
  /**
33
  * @var string
34
  * @since 2.04
40
  * @since 2.04
41
  */
42
  protected $table_generator = null;
43
+
44
  /**
45
  * @var array
46
  * @since 2.04
47
  */
48
  protected $array_content = array();
49
 
50
+ /**
51
+ * FrmEntryShortcodeFormatter constructor
52
+ *
53
+ * @param int|string $form_id
54
+ * @param array $atts
55
+ */
56
+ public function __construct( $form_id, $atts ) {
57
  if ( ! $form_id ) {
58
  return;
59
  }
60
 
61
  $this->init_form_id( $form_id );
62
  $this->init_fields();
 
63
 
64
  if ( empty( $this->fields ) ) {
65
  return;
66
  }
67
 
68
+ $this->init_plain_text( $atts );
69
+ $this->init_format( $atts );
70
+
71
+ if ( $this->is_table_format() ) {
72
  $this->init_table_generator();
73
  }
74
  }
75
 
76
  /**
77
+ * Initialize the form_id property
78
  *
79
  * @since 2.04
80
  * @param $form_id
81
  */
82
+ protected function init_form_id( $form_id ) {
83
  $this->form_id = (int) $form_id;
84
  }
85
 
86
  /**
87
+ * Initialize the fields property
88
  *
89
  * @since 2.04
90
  */
91
+ protected function init_fields() {
92
  $this->fields = FrmField::get_all_for_form( $this->form_id, '', 'exclude', 'exclude' );
93
  }
94
 
95
  /**
96
+ * Initialize the is_plain_text property
97
+ *
98
+ * @since 2.05
99
+ *
100
+ * @param array $atts
101
+ */
102
+ protected function init_plain_text( $atts ) {
103
+ if ( isset( $atts['plain_text'] ) && $atts['plain_text'] ) {
104
+ $this->is_plain_text = true;
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Initialize the format property
110
  *
111
  * @since 2.04
112
  *
113
+ * @param array $atts
114
  */
115
+ protected function init_format( $atts ) {
116
+ if ( isset( $atts['format'] ) && is_string( $atts['format'] ) && $atts['format'] !== '' ) {
117
+ $this->format = $atts['format'];
118
+ } else {
119
+ $this->format = 'text';
120
  }
121
  }
122
 
123
  /**
124
+ * Initialize the table_generator property
125
  *
126
  * @since 2.04
127
  */
135
  * @since 2.04
136
  */
137
  public function content() {
138
+ if ( ! $this->form_id || empty( $this->fields ) ) {
139
+ return '';
140
+ }
141
+
142
+ if ( $this->format == 'array' ) {
143
  $content = $this->get_array();
144
+ } else if ( $this->is_plain_text_format() ) {
145
+ $content = $this->get_plain_text();
146
  } else {
147
+ $content = $this->get_table();
148
  }
149
 
150
  return $content;
155
  *
156
  * @since 2.04
157
  */
158
+ protected function get_array() {
 
 
 
 
159
  foreach ( $this->fields as $field ) {
160
  $this->add_field_array( $field );
161
  }
164
  }
165
 
166
  /**
167
+ * Return the default plain text for an email message
168
  *
169
  * @since 2.04
170
  */
171
+ protected function get_plain_text() {
172
+ return $this->generate_content_for_all_fields();
173
+ }
 
174
 
175
+ /**
176
+ * Return the default HTML for an email message
177
+ *
178
+ * @since 2.04
179
+ */
180
+ protected function get_table() {
181
  $content = $this->table_generator->generate_table_header();
182
+ $content .= $this->generate_content_for_all_fields();
183
+ $content .= $this->table_generator->generate_table_footer();
184
+
185
+ return $content;
186
+ }
187
+
188
+ /**
189
+ * Generate the content for all fields
190
+ *
191
+ * @since 2.05
192
+ *
193
+ * @return string
194
+ */
195
+ protected function generate_content_for_all_fields() {
196
+ $content = '';
197
 
198
  foreach ( $this->fields as $field ) {
199
+ $content .= $this->generate_field_content( $field );
200
  }
201
 
 
 
202
  return $content;
203
  }
204
 
205
  /**
206
+ * Generate a field's HTML or plain text shortcodes
207
  *
208
  * @since 2.04
209
  *
211
  *
212
  * @return string
213
  */
214
+ protected function generate_field_content( $field ) {
215
  if ( in_array( $field->type, $this->skip_fields ) ) {
216
  return '';
217
  }
218
 
219
+ $row = $this->generate_two_cell_shortcode_row( $field );
220
 
221
  return $row;
222
  }
223
 
224
  /**
225
+ * Generate a two cell row of shortcodes for an HTML or plain text table
226
  *
227
  * @since 2.04
228
  *
229
  * @param stdClass $field
230
+ * @param mixed $value
231
  *
232
  * @return string
233
  */
234
+ protected function generate_two_cell_shortcode_row( $field, $value = null ) {
235
+ $row = '[if ' . $field->id . ']';
236
+
237
+ $label = '[' . $field->id . ' show=field_label]';
238
+
239
+ if ( $value === null ) {
240
+ $value = '[' . $field->id . ']';
241
+ }
242
+
243
+ if ( $this->is_plain_text_format() ) {
244
+ $row .= $label . ': ' . $value . "\r\n";
245
+ } else {
246
+ $row .= $this->table_generator->generate_two_cell_table_row( $label, $value );
247
+ }
248
+
249
+ $row .= '[/if ' . $field->id . ']';
250
+
251
+ if ( $this->is_table_format() ) {
252
+ $row .= "\r\n";
253
+ }
254
+
255
+ return $row;
256
  }
257
 
258
  /**
277
  *
278
  * @param stdClass $field
279
  * @param string $value
 
 
280
  */
281
  protected function add_single_field_array( $field, $value ) {
282
  $array = array(
286
  );
287
 
288
  $this->array_content[ $field->id ] = apply_filters( 'frm_field_shortcodes_for_default_html_email', $array, $field );
289
+ }
290
 
291
+ /**
292
+ * Check if the format is default plain text
293
+ *
294
+ * @since 2.05
295
+ *
296
+ * @return bool
297
+ */
298
+ protected function is_plain_text_format() {
299
+ return ( $this->format === 'text' && $this->is_plain_text === true );
300
+ }
301
+
302
+ /**
303
+ * Check if the format is default HTML
304
+ *
305
+ * @since 2.05
306
+ *
307
+ * @return bool
308
+ */
309
+ protected function is_table_format() {
310
+ return ( $this->format === 'text' && $this->is_plain_text === false );
311
  }
312
 
313
  }
classes/models/FrmEntryValues.php CHANGED
@@ -262,7 +262,7 @@ class FrmEntryValues {
262
  if ( ! empty( $this->include_fields ) ) {
263
  $is_included = $this->is_field_in_array( $field, $this->include_fields );
264
  } else if ( ! empty( $this->exclude_fields ) ) {
265
- $is_included = ! $this->is_field_in_array( $field, $this->include_fields );
266
  } else {
267
  $is_included = true;
268
  }
262
  if ( ! empty( $this->include_fields ) ) {
263
  $is_included = $this->is_field_in_array( $field, $this->include_fields );
264
  } else if ( ! empty( $this->exclude_fields ) ) {
265
+ $is_included = ! $this->is_field_in_array( $field, $this->exclude_fields );
266
  } else {
267
  $is_included = true;
268
  }
classes/models/FrmField.php CHANGED
@@ -164,6 +164,11 @@ class FrmField {
164
 
165
  if ( isset( $values['type'] ) ) {
166
  $values = apply_filters( 'frm_clean_' . $values['type'] . '_field_options_before_update', $values );
 
 
 
 
 
167
  }
168
 
169
  // serialize array values
@@ -581,26 +586,22 @@ class FrmField {
581
  return false;
582
  }
583
 
584
- if ( is_array( $field ) ) {
 
 
585
 
586
- $is_multi_value_field = (
587
- $field['type'] == 'checkbox' ||
588
- $field['type'] == 'address' ||
589
- ( $field['type'] == 'data' && isset($field['data_type']) && $field['data_type'] == 'checkbox' ) ||
590
- ( $field['type'] == 'lookup' && isset($field['data_type']) && $field['data_type'] == 'checkbox' ) ||
591
- self::is_multiple_select( $field )
592
- );
593
-
594
- } else {
595
- $is_multi_value_field = (
596
- $field->type == 'checkbox' ||
597
- $field->type == 'address' ||
598
- ( $field->type == 'data' && isset( $field->field_options['data_type'] ) && $field->field_options['data_type'] == 'checkbox' ) ||
599
- ( $field->type == 'lookup' && isset( $field->field_options['data_type'] ) && $field->field_options['data_type'] == 'checkbox' ) ||
600
- self::is_multiple_select( $field )
601
- );
602
  }
603
 
 
 
 
 
 
 
 
 
604
  return $is_multi_value_field;
605
  }
606
 
@@ -611,11 +612,10 @@ class FrmField {
611
  * @return boolean
612
  */
613
  public static function is_multiple_select( $field ) {
614
- if ( is_array( $field ) ) {
615
- return self::is_option_true( $field, 'multiple' ) && ( ( $field['type'] == 'select' || ( $field['type'] == 'data' && isset( $field['data_type'] ) && $field['data_type'] == 'select') ) );
616
- } else {
617
- return self::is_option_true( $field, 'multiple' ) && ( ( $field->type == 'select' || ( $field->type == 'data' && isset($field->field_options['data_type'] ) && $field->field_options['data_type'] == 'select') ) );
618
- }
619
  }
620
 
621
  /**
164
 
165
  if ( isset( $values['type'] ) ) {
166
  $values = apply_filters( 'frm_clean_' . $values['type'] . '_field_options_before_update', $values );
167
+
168
+ if ( $values['type'] == 'hidden' && isset( $values['field_options'] ) && isset( $values['field_options']['clear_on_focus'] ) ) {
169
+ // don't keep the old placeholder setting for hidden fields
170
+ $values['field_options']['clear_on_focus'] = 0;
171
+ }
172
  }
173
 
174
  // serialize array values
586
  return false;
587
  }
588
 
589
+ $field_type = is_array( $field ) ? $field['type'] : $field->type;
590
+ $data_type = self::get_option( $field, 'data_type' );
591
+ $original_type = self::get_option( $field, 'original_type' );
592
 
593
+ if ( ! empty( $original_type ) && $original_type != $field_type ) {
594
+ $field_type = $original_type; // check the original type for arrays
 
 
 
 
 
 
 
 
 
 
 
 
 
 
595
  }
596
 
597
+ $is_multi_value_field = (
598
+ $field_type == 'checkbox' ||
599
+ $field_type == 'address' ||
600
+ ( $field_type == 'data' && $data_type == 'checkbox' ) ||
601
+ ( $field_type == 'lookup' && $data_type == 'checkbox' ) ||
602
+ self::is_multiple_select( $field )
603
+ );
604
+
605
  return $is_multi_value_field;
606
  }
607
 
612
  * @return boolean
613
  */
614
  public static function is_multiple_select( $field ) {
615
+ $field_type = is_array( $field ) ? $field['type'] : $field->type;
616
+ $data_type = self::get_option( $field, 'data_type' );
617
+
618
+ return self::is_option_true( $field, 'multiple' ) && ( ( $field_type == 'select' || ( $field_type == 'data' && $data_type == 'select') ) );
 
619
  }
620
 
621
  /**
classes/models/FrmFieldValue.php CHANGED
@@ -118,6 +118,15 @@ class FrmFieldValue {
118
  return $this->field->name;
119
  }
120
 
 
 
 
 
 
 
 
 
 
121
  /**
122
  * Get the field property's key
123
  *
118
  return $this->field->name;
119
  }
120
 
121
+ /**
122
+ * Get the field property's id
123
+ *
124
+ * @since 2.05
125
+ */
126
+ public function get_field_id() {
127
+ return $this->field->id;
128
+ }
129
+
130
  /**
131
  * Get the field property's key
132
  *
classes/models/FrmFieldValueSelector.php CHANGED
@@ -220,7 +220,7 @@ class FrmFieldValueSelector {
220
  * @since 2.03.05
221
  */
222
  public function display_text_box() {
223
- echo '<input type="text" name="' . esc_attr( $this->html_name ) . '" value="' . esc_attr( $this->value ) . '" />';
224
  }
225
 
226
  /**
220
  * @since 2.03.05
221
  */
222
  public function display_text_box() {
223
+ echo '<input type="text" name="' . esc_attr( $this->html_name ) . '" value="' . esc_attr( trim( $this->value ) ) . '" />';
224
  }
225
 
226
  /**
classes/models/FrmSettings.php CHANGED
@@ -30,6 +30,8 @@ class FrmSettings {
30
  public $re_msg;
31
  public $re_multi;
32
 
 
 
33
  public function __construct() {
34
  if ( ! defined('ABSPATH') ) {
35
  die('You are not allowed to call this page directly.');
@@ -98,6 +100,7 @@ class FrmSettings {
98
  'admin_permission' => __( 'You do not have permission to do that', 'formidable' ),
99
 
100
  'email_to' => '[admin_email]',
 
101
  );
102
  }
103
 
@@ -212,6 +215,7 @@ class FrmSettings {
212
  $this->jquery_css = isset( $params['frm_jquery_css'] ) ? absint( $params['frm_jquery_css'] ) : 0;
213
  $this->accordion_js = isset( $params['frm_accordion_js'] ) ? absint( $params['frm_accordion_js'] ) : 0;
214
  $this->fade_form = isset( $params['frm_fade_form'] ) ? absint( $params['frm_fade_form'] ) : 0;
 
215
  }
216
 
217
  private function update_roles( $params ) {
30
  public $re_msg;
31
  public $re_multi;
32
 
33
+ public $no_ips;
34
+
35
  public function __construct() {
36
  if ( ! defined('ABSPATH') ) {
37
  die('You are not allowed to call this page directly.');
100
  'admin_permission' => __( 'You do not have permission to do that', 'formidable' ),
101
 
102
  'email_to' => '[admin_email]',
103
+ 'no_ips' => 0,
104
  );
105
  }
106
 
215
  $this->jquery_css = isset( $params['frm_jquery_css'] ) ? absint( $params['frm_jquery_css'] ) : 0;
216
  $this->accordion_js = isset( $params['frm_accordion_js'] ) ? absint( $params['frm_accordion_js'] ) : 0;
217
  $this->fade_form = isset( $params['frm_fade_form'] ) ? absint( $params['frm_fade_form'] ) : 0;
218
+ $this->no_ips = isset( $params['frm_no_ips'] ) ? absint( $params['frm_no_ips'] ) : 0;
219
  }
220
 
221
  private function update_roles( $params ) {
classes/models/FrmTableHTMLGenerator.php CHANGED
@@ -84,7 +84,11 @@ class FrmTableHTMLGenerator {
84
 
85
  foreach ( $this->style_settings as $key => $setting ) {
86
  if ( isset( $atts[ $key ] ) && $atts[ $key ] !== '' ) {
87
- $this->style_settings[ $key ] = str_replace( '#', '', $atts[ $key ] );
 
 
 
 
88
  }
89
  }
90
  }
@@ -124,7 +128,7 @@ class FrmTableHTMLGenerator {
124
  if ( $this->use_inline_style === true ) {
125
 
126
  $this->table_style = ' style="' . esc_attr( 'font-size:' . $this->style_settings['font_size'] . ';line-height:135%;' );
127
- $this->table_style .= esc_attr( 'border-bottom:' . $this->style_settings['border_width'] . ' solid #' . $this->style_settings['border_color'] . ';' ) . '"';
128
 
129
  }
130
  }
@@ -138,13 +142,46 @@ class FrmTableHTMLGenerator {
138
  if ( $this->use_inline_style === true ) {
139
 
140
  $td_style_attributes = 'text-align:' . ( $this->direction == 'rtl' ? 'right' : 'left' ) . ';';
141
- $td_style_attributes .= 'color:#' . $this->style_settings['text_color'] . ';padding:7px 9px;vertical-align:top;';
142
- $td_style_attributes .= 'border-top:' . $this->style_settings['border_width'] . ' solid #' . $this->style_settings[ 'border_color' ] . ';';
143
 
144
  $this->td_style = ' style="' . $td_style_attributes . '"';
145
  }
146
  }
147
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  /**
149
  * Get the table row background color
150
  *
@@ -168,7 +205,7 @@ class FrmTableHTMLGenerator {
168
  if ( $this->type === 'shortcode' ) {
169
  $tr_style = ' style="[frm-alt-color]"';
170
  } else if ( $this->use_inline_style ) {
171
- $tr_style = ' style="background-color:#' . $this->table_row_background_color() . ';"';
172
  } else {
173
  $tr_style = '';
174
  }
@@ -258,50 +295,4 @@ class FrmTableHTMLGenerator {
258
 
259
  return $row;
260
  }
261
-
262
-
263
- /**
264
- * Generate a two cell row of shortcodes for an HTML table
265
- *
266
- * @since 2.04
267
- *
268
- * @param stdClass $field
269
- * @param mixed $value
270
- *
271
- * @return string
272
- */
273
- public function generate_two_cell_shortcode_row( $field, $value = null ) {
274
- $row = '[if ' . $field->id . ']';
275
-
276
- $label = '[' . $field->id . ' show=field_label]';
277
-
278
- if ( $value === null ) {
279
- $value = '[' . $field->id . ']';
280
- }
281
-
282
- $row .= $this->generate_two_cell_table_row( $label, $value );
283
-
284
- $row .= '[/if ' . $field->id . ']' . "\r\n";
285
-
286
- return $row;
287
- }
288
-
289
- /**
290
- * Generate a sinle cell row of shortcodes for an HTML table
291
- *
292
- * @since 2.04
293
- *
294
- * @param stdClass $field
295
- * @param mixed $value
296
- *
297
- * @return string
298
- */
299
- public function generate_single_cell_shortcode_row( $field, $value ) {
300
- $row = '[if ' . $field->id . ']';
301
- $row .= $this->generate_single_cell_table_row( $value );
302
- $row .= '[/if ' . $field->id . ']' . "\r\n";
303
-
304
- return $row;
305
- }
306
-
307
  }
84
 
85
  foreach ( $this->style_settings as $key => $setting ) {
86
  if ( isset( $atts[ $key ] ) && $atts[ $key ] !== '' ) {
87
+ $this->style_settings[ $key ] = $atts[ $key ];
88
+ }
89
+
90
+ if ( $this->is_color_setting( $key ) ) {
91
+ $this->style_settings[ $key ] = $this->get_color_markup( $this->style_settings[ $key ] );
92
  }
93
  }
94
  }
128
  if ( $this->use_inline_style === true ) {
129
 
130
  $this->table_style = ' style="' . esc_attr( 'font-size:' . $this->style_settings['font_size'] . ';line-height:135%;' );
131
+ $this->table_style .= esc_attr( 'border-bottom:' . $this->style_settings['border_width'] . ' solid ' . $this->style_settings['border_color'] . ';' ) . '"';
132
 
133
  }
134
  }
142
  if ( $this->use_inline_style === true ) {
143
 
144
  $td_style_attributes = 'text-align:' . ( $this->direction == 'rtl' ? 'right' : 'left' ) . ';';
145
+ $td_style_attributes .= 'color:' . $this->style_settings['text_color'] . ';padding:7px 9px;vertical-align:top;';
146
+ $td_style_attributes .= 'border-top:' . $this->style_settings['border_width'] . ' solid ' . $this->style_settings['border_color'] . ';';
147
 
148
  $this->td_style = ' style="' . $td_style_attributes . '"';
149
  }
150
  }
151
 
152
+ /**
153
+ * Determine if setting is for a color, e.g. text color, background color, or border color
154
+ *
155
+ * @param string $setting_key name of setting
156
+ *
157
+ * @since 2.05
158
+ *
159
+ * @return boolean
160
+ */
161
+ private function is_color_setting ( $setting_key ) {
162
+ return strpos( $setting_key, 'color' ) !== false;
163
+ }
164
+
165
+ /**
166
+ * Get color markup from color setting value
167
+ *
168
+ * @param string $color_markup value of a color setting, with format #FFFFF, FFFFFF, or white.
169
+ *
170
+ * @since 2.05
171
+ *
172
+ * @return string
173
+ */
174
+ private function get_color_markup( $color_markup ) {
175
+ $color_markup = trim( $color_markup );
176
+
177
+ //check if each character in string is valid hex digit
178
+ if ( ctype_xdigit( $color_markup ) ) {
179
+ $color_markup = '#' . $color_markup;
180
+ }
181
+
182
+ return $color_markup;
183
+ }
184
+
185
  /**
186
  * Get the table row background color
187
  *
205
  if ( $this->type === 'shortcode' ) {
206
  $tr_style = ' style="[frm-alt-color]"';
207
  } else if ( $this->use_inline_style ) {
208
+ $tr_style = ' style="background-color:' . $this->table_row_background_color() . ';"';
209
  } else {
210
  $tr_style = '';
211
  }
295
 
296
  return $row;
297
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298
  }
classes/views/addons/upgrade_to_pro.php CHANGED
@@ -19,7 +19,7 @@
19
  <th>
20
  <h3><?php echo esc_attr( ucfirst( $price_info['name'] ) ) ?></h3>
21
  <h4>$<?php echo esc_attr( $price_info['price'] ) ?></h4>
22
- <a href="<?php echo esc_url( FrmAppHelper::make_affiliate_url( 'https://formidableforms.com/checkout?edd_action=add_to_cart&download_id=93790' ) ) ?>&amp;edd_options[price_id]=<?php echo absint( $price_info['id'] ) ?>" class="button-primary" target="_blank">
23
  <?php _e( 'Get Started', 'formidable' ) ?>
24
  </a>
25
  </th>
19
  <th>
20
  <h3><?php echo esc_attr( ucfirst( $price_info['name'] ) ) ?></h3>
21
  <h4>$<?php echo esc_attr( $price_info['price'] ) ?></h4>
22
+ <a href="<?php echo esc_url( FrmAppHelper::make_affiliate_url( 'https://formidableforms.com/checkout?edd_action=add_to_cart' ) ) ?>&amp;download_id=<?php echo absint( $price_info['download'] ) ?>&amp;edd_options[price_id]=<?php echo absint( $price_info['id'] ) ?>" class="button-primary" target="_blank">
23
  <?php _e( 'Get Started', 'formidable' ) ?>
24
  </a>
25
  </th>
classes/views/frm-entries/sidebar-shared.php CHANGED
@@ -52,10 +52,12 @@
52
  <div class="postbox">
53
  <h3 class="hndle"><span><?php _e( 'User Information', 'formidable' ) ?></span></h3>
54
  <div class="inside">
55
- <div class="misc-pub-section">
56
- <?php _e( 'IP Address', 'formidable' ) ?>:
 
57
  <b><?php echo sanitize_text_field( $entry->ip ); ?></b>
58
- </div>
 
59
 
60
  <?php if ( isset( $browser ) ) { ?>
61
  <div class="misc-pub-section">
52
  <div class="postbox">
53
  <h3 class="hndle"><span><?php _e( 'User Information', 'formidable' ) ?></span></h3>
54
  <div class="inside">
55
+ <?php if ( ! empty( $entry->ip ) ) { ?>
56
+ <div class="misc-pub-section">
57
+ <?php _e( 'IP Address', 'formidable' ) ?>:
58
  <b><?php echo sanitize_text_field( $entry->ip ); ?></b>
59
+ </div>
60
+ <?php } ?>
61
 
62
  <?php if ( isset( $browser ) ) { ?>
63
  <div class="misc-pub-section">
classes/views/frm-form-actions/_email_settings.php CHANGED
@@ -55,7 +55,13 @@
55
  <textarea name="<?php echo esc_attr( $this->get_field_name('email_message') ) ?>" class="frm_not_email_message large-text" id="<?php echo esc_attr( $this->get_field_id('email_message') ) ?>" cols="50" rows="5"><?php echo FrmAppHelper::esc_textarea($form_action->post_content['email_message']) ?></textarea></p>
56
 
57
  <h4><?php _e( 'Options', 'formidable' ) ?> </h4>
58
- <label for="<?php echo esc_attr( $this->get_field_id('inc_user_info') ) ?>"><input type="checkbox" name="<?php echo esc_attr( $this->get_field_name('inc_user_info') ) ?>" class="frm_not_inc_user_info" id="<?php echo esc_attr( $this->get_field_id('inc_user_info') ) ?>" value="1" <?php checked( $form_action->post_content['inc_user_info'], 1 ); ?> /> <?php _e( 'Append IP Address, Browser, and Referring URL to message', 'formidable' ) ?></label>
 
 
 
 
 
 
59
 
60
  <p><label for="<?php echo esc_attr( $this->get_field_id('plain_text') ) ?>"><input type="checkbox" name="<?php echo esc_attr( $this->get_field_name('plain_text') ) ?>" id="<?php echo esc_attr( $this->get_field_id('plain_text') ) ?>" value="1" <?php checked( $form_action->post_content['plain_text'], 1 ); ?> /> <?php _e( 'Send Emails in Plain Text', 'formidable' ) ?></label></p>
61
  </td>
55
  <textarea name="<?php echo esc_attr( $this->get_field_name('email_message') ) ?>" class="frm_not_email_message large-text" id="<?php echo esc_attr( $this->get_field_id('email_message') ) ?>" cols="50" rows="5"><?php echo FrmAppHelper::esc_textarea($form_action->post_content['email_message']) ?></textarea></p>
56
 
57
  <h4><?php _e( 'Options', 'formidable' ) ?> </h4>
58
+ <label for="<?php echo esc_attr( $this->get_field_id('inc_user_info') ) ?>"><input type="checkbox" name="<?php echo esc_attr( $this->get_field_name('inc_user_info') ) ?>" class="frm_not_inc_user_info" id="<?php echo esc_attr( $this->get_field_id('inc_user_info') ) ?>" value="1" <?php checked( $form_action->post_content['inc_user_info'], 1 ); ?> />
59
+ <?php if ( FrmAppHelper::ips_saved() ) { ?>
60
+ <?php _e( 'Append IP Address, Browser, and Referring URL to message', 'formidable' ) ?>
61
+ <?php } else { ?>
62
+ <?php _e( 'Append Browser and Referring URL to message', 'formidable' ) ?>
63
+ <?php } ?>
64
+ </label>
65
 
66
  <p><label for="<?php echo esc_attr( $this->get_field_id('plain_text') ) ?>"><input type="checkbox" name="<?php echo esc_attr( $this->get_field_name('plain_text') ) ?>" id="<?php echo esc_attr( $this->get_field_id('plain_text') ) ?>" value="1" <?php checked( $form_action->post_content['plain_text'], 1 ); ?> /> <?php _e( 'Send Emails in Plain Text', 'formidable' ) ?></label></p>
67
  </td>
classes/views/frm-forms/add_field.php CHANGED
@@ -219,18 +219,21 @@ if ( $display['options'] ) { ?>
219
  }
220
 
221
  if ( $display['label_position'] ) { ?>
222
- <tr><td class="frm_150_width"><label><?php _e( 'Label Position', 'formidable' ) ?></label></td>
223
- <td><select name="field_options[label_<?php echo esc_attr( $field['id'] ) ?>]">
224
- <option value=""<?php selected($field['label'], ''); ?>><?php _e( 'Default', 'formidable' ) ?></option>
225
- <option value="top"<?php selected($field['label'], 'top'); ?>><?php _e( 'Top', 'formidable' ) ?></option>
226
- <option value="left"<?php selected($field['label'], 'left'); ?>><?php _e( 'Left', 'formidable' ) ?></option>
227
- <option value="right"<?php selected($field['label'], 'right'); ?>><?php _e( 'Right', 'formidable' ) ?></option>
228
- <option value="inline"<?php selected($field['label'], 'inline'); ?>><?php _e( 'Inline (left without a set width)', 'formidable' ) ?></option>
229
- <option value="none"<?php selected($field['label'], 'none'); ?>><?php _e( 'None', 'formidable' ) ?></option>
230
- <option value="hidden"<?php selected($field['label'], 'hidden'); ?>><?php _e( 'Hidden (but leave the space)', 'formidable' ) ?></option>
231
- </select>
232
- </td>
233
- </tr>
 
 
 
234
  <?php }
235
 
236
  // Field Size
219
  }
220
 
221
  if ( $display['label_position'] ) { ?>
222
+ <tr>
223
+ <td class="frm_150_width"><label><?php _e( 'Label Position', 'formidable' ) ?></label></td>
224
+ <td>
225
+ <select name="field_options[label_<?php echo esc_attr( $field['id'] ) ?>]">
226
+ <option value=""<?php selected($field['label'], ''); ?>>
227
+ <?php _e( 'Default', 'formidable' ) ?>
228
+ </option>
229
+ <?php foreach ( FrmStylesHelper::get_sigle_label_postitions() as $pos => $pos_label ) { ?>
230
+ <option value="<?php echo esc_attr( $pos ) ?>"<?php selected( $field['label'], $pos ); ?>>
231
+ <?php echo esc_html( $pos_label ) ?>
232
+ </option>
233
+ <?php } ?>
234
+ </select>
235
+ </td>
236
+ </tr>
237
  <?php }
238
 
239
  // Field Size
classes/views/frm-settings/form.php CHANGED
@@ -18,7 +18,7 @@
18
  <a href="#general_settings" class="frm_cursor_pointer"><?php _e( 'General', 'formidable' ) ?></a>
19
  </li>
20
  <?php foreach ( $sections as $sec_name => $section ) { ?>
21
- <li <?php echo ( $a == $sec_name . '_settings' ) ? 'class="tabs active"' : '' ?>>
22
  <a href="#<?php echo esc_attr( $sec_name ) ?>_settings" data-frmajax="<?php echo esc_attr( isset( $section['ajax'] ) ? $section['ajax'] : '' ) ?>">
23
  <?php echo isset( $section['name'] ) ? $section['name'] : ucfirst( $sec_name ) ?>
24
  </a>
@@ -173,6 +173,15 @@
173
  <?php FrmAppHelper::wp_pages_dropdown('frm-preview-page-id', $frm_settings->preview_page_id ) ?>
174
  </p>
175
 
 
 
 
 
 
 
 
 
 
176
  </div>
177
 
178
  <?php
18
  <a href="#general_settings" class="frm_cursor_pointer"><?php _e( 'General', 'formidable' ) ?></a>
19
  </li>
20
  <?php foreach ( $sections as $sec_name => $section ) { ?>
21
+ <li <?php echo ( $a == $sec_name . '_settings' ) ? 'class="tabs active starttab"' : '' ?>>
22
  <a href="#<?php echo esc_attr( $sec_name ) ?>_settings" data-frmajax="<?php echo esc_attr( isset( $section['ajax'] ) ? $section['ajax'] : '' ) ?>">
23
  <?php echo isset( $section['name'] ) ? $section['name'] : ucfirst( $sec_name ) ?>
24
  </a>
173
  <?php FrmAppHelper::wp_pages_dropdown('frm-preview-page-id', $frm_settings->preview_page_id ) ?>
174
  </p>
175
 
176
+ <p>
177
+ <label class="frm_left_label"><?php _e( 'IP storage', 'formidable' ); ?></label>
178
+ <label for="frm_no_ips">
179
+ <input type="checkbox" name="frm_no_ips" id="frm_no_ips" value="1" <?php checked( $frm_settings->no_ips, 1 ) ?> />
180
+ <?php _e( 'Do not store IPs with form submissions. Check this box if you are in the UK.', 'formidable' ) ?>
181
+ </label>
182
+
183
+ </p>
184
+
185
  </div>
186
 
187
  <?php
classes/views/styles/_field-labels.php CHANGED
@@ -18,7 +18,7 @@
18
  <div class="field-group clearfix frm_clear">
19
  <label><?php _e( 'Position', 'formidable' ) ?></label>
20
  <select name="<?php echo esc_attr( $frm_style->get_field_name('position') ) ?>" id="frm_position">
21
- <?php foreach ( array( 'none' => __( 'top', 'formidable' ), 'left' => __( 'left', 'formidable' ), 'right' => __( 'right', 'formidable' ), 'no_label' => __( 'none', 'formidable' ) ) as $pos => $pos_label ) { ?>
22
  <option value="<?php echo esc_attr( $pos ) ?>" <?php selected($style->post_content['position'], $pos) ?>><?php echo esc_html( $pos_label ) ?></option>
23
  <?php } ?>
24
  </select>
18
  <div class="field-group clearfix frm_clear">
19
  <label><?php _e( 'Position', 'formidable' ) ?></label>
20
  <select name="<?php echo esc_attr( $frm_style->get_field_name('position') ) ?>" id="frm_position">
21
+ <?php foreach ( FrmStylesHelper::get_css_label_positions() as $pos => $pos_label ) { ?>
22
  <option value="<?php echo esc_attr( $pos ) ?>" <?php selected($style->post_content['position'], $pos) ?>><?php echo esc_html( $pos_label ) ?></option>
23
  <?php } ?>
24
  </select>
css/_single_theme.css.php CHANGED
@@ -384,14 +384,6 @@ $arrow_icons = FrmStylesHelper::arrow_icons();
384
  color:transparent<?php echo esc_html( $important ) ?>;
385
  }
386
 
387
- .<?php echo esc_html( $style_class ) ?> .frm_default,
388
- .<?php echo esc_html( $style_class ) ?> .placeholder,
389
- .<?php echo esc_html( $style_class ) ?> .chosen-container-multi .chosen-choices li.search-field .default,
390
- .<?php echo esc_html( $style_class ) ?> .chosen-container-single .chosen-default{
391
- color: <?php echo esc_html( $text_color . $important ) ?>;
392
- font-style:italic;
393
- }
394
-
395
  .<?php echo esc_html( $style_class ) ?> select{
396
  width:<?php echo esc_html( ( $auto_width ? 'auto' : $field_width ) . $important ) ?>;
397
  max-width:100%;
@@ -468,6 +460,15 @@ $arrow_icons = FrmStylesHelper::arrow_icons();
468
  color: <?php echo esc_html( $text_color_disabled . $important ) ?>;
469
  }
470
 
 
 
 
 
 
 
 
 
 
471
 
472
  .<?php echo esc_html( $style_class ) ?> .form-field input:not([type=file]):focus,
473