Formidable Forms – Form Builder for WordPress - Version 3.0

Version Description

  • Move features into the free form builder: redirect and show page after save, javascript validation, field format options with HTML5 pattern validation, and phone number, number, user ID, hidden field, and HTML fields
  • Possibly breaking change: Remove code that has been deprecated since before v2.02
  • Save a combined js file to use on the front-end with a fallback if the file fails to generate. This file is updated when the plugin is activated or updated.
  • A UI pick-me-up in preparation of things to come in 4.0.
  • New: Use CSS grids for better layouts. If you would like your column layouts to show in Internet Explorer, you'll need to turn on the old styling in the Formidable -> Global settings. The grids use a 12-column layout with classes that range from frm1 (1 column of 12) to frm12 (span all 12 columns). (Thanks for the feedback from our feedback group!)
  • New: Search for fields by name, id, and key in the customization panel
  • Improved RTL styling in backend
  • Enhancement: Add frm_rtl class to forms with styles set to RTL for easier styling.
  • Enhancement: Customize the invalid message when a custom format is set on text fields
  • Better a11y/WCAG support: hidden labels where required, "for" tag on most labels, and link the field to its description for screenreaders.
  • Move form shortcodes from the sidebar to the form settings page
  • Change "field options" to "field settings" on the form builder page
  • Update the Print styling for the entries page
  • Remove frm_text_block class and do it by default. Radio buttons and checkboxes with wrapping text should look good by default.
  • Add a link in the footer to review Formidable
  • New: field object class to make it easy to make new field types. We don't have docs yet, but developers can take a look at the FrmFieldType class. But we've gone to great efforts to make sure fields done the old way will continue to function.
  • New hook: Add frm_output_single_style hook to add extra css into the generated stylesheet
  • New hook: Add frm_before_get_form hook for enqueueing form scripts
  • New hook: Add frm_enqueue_builder_scripts hook to load extra scripts on the form builder page
  • New hook: Add frm_show_entry_defaults hook to add extra atts to the frm_show_entry shortcode
  • Tweak: Include 'original_default' in the field array for new entries so we can compare and prevent double processing later
  • Fix: quotation marks were being escaped in frm_form_attributes and frm_form_div_attributes hooks
  • Removed: The preview page option in the global settings is no longer used. The form preview page is now generated.
  • Removed: The placeholder fallback javascript for old versions of IE is gone. No need to give everyone extra scripts to load.
  • Deprecated the accordion javascript checkbox in global settings since it isn't used by the plugin. If you had this box checked, you'll still see it. Once you uncheck it the option will no longer appear.
  • Pro Version Forms
  • New: Move Formidable Pro to its own plugin during update or install. Wahoo!
  • New: If the Pro version is installed without the lite forms, install it automatically. Prevent errors if pro is running alone or is also nested inside of lite.
  • Add range slider and toggle fields
  • Add visibility option to HTML and section fields
  • Move repeater field to its own field button
  • Combine image and URL fields
  • Add readonly option to time fields
  • Star rating fields: Separate from scale fields and remove the jquery rating js and replace with mostly html and css
  • Show frm-stats as stars with straight html/css (no more js)
  • New: Make it easier to show star values. Show the stars by default on the View entry page and show stars in a view with [25 html=1].
  • New: Added param checking to inline conditionals: [if 25 equals='param' param='set-name-here'] and [if get param="level" equals="gold"]
  • New: Add entry_position shortcode for incremental content in views. For example, this gives the option to show more or different information for the first entry in the view or insert ads after the third entry.
  • New: Automatically adjust fields to fit equally in an inline form
  • Separate Pro and Lite translations
  • Enhancement: If a form creates posts and is set to not save entries, save the created post.
  • Enhancement: Run form install on an API route instead of the admin ajax route and make sure there won't be multiple instances of the install running at once.
  • Enhancement: Use the options instead of transients for checking for updates. Some types of caching store transients indefinitely.
  • Enhancement: Get the shortcodes for a view more concisely. Check for any numeric shortcode instead of checking the database for the field ids
  • Tweak: Open files in the form upload field in a new tab
  • Tweak: Don't show the reports nav if the form has no entries
  • Tweak: Add .do-calculation class on a form to run calculations even if they are not on the current page of the form
  • Tweak: Add $atts with $atts['view'] to all pagination hooks
  • Fix: calculations in hidden fields inside of sections were not calculating
  • Fix: Add validation for the year range in date fields
  • Fix: Don't use conditional logic in form actions when the field isn't selected
  • Fix: Show address fields without
    in dynamic fields
  • Fix: Require the credit card field when editing a draft
  • Fix: Only show the user login for a user id field when the display name is empty. Don't show it as a fallback for other user values.
  • Fix: Return 403 instead of 401 when a file type isn't allowed to be uploaded.
  • Fix: Install the wp_frm_copies table during the first multisite installation, and prevent it from checking tables before they exist.
  • Fix: Do not process a shortcode that is inserted into a field.
  • Fix: Conditionals that check user meta were always returning true
  • Fix: Autocomplete for dynamic fields was too small
  • Fix: If a field includes regex, keep the slashes when the field is duplicated
  • Fix: Correctly check conditional logic when comparing 0 to blank.
  • Fix: Prevent double filtering shortcodes in a nested view
  • Fix: Allow a view to not be filtered on the same page as a filtered view
  • Fix: Searching dynamic fields were returning extra, incorrect results
  • Fix: Searching for a decimal value was dropping the value after the decimal
  • Fix: Searching for a number with post entries and frm-search wasn't correctly checking the posts
  • Fix: datepicker settings weren't loading correctly in an ajax form with date fields that aren't on the first form page
  • Fix: Correctly hide and show fields in embedded forms with the frm-show-entry shortcode
  • Fix: When a field immediately follows an embedded form, it was showing up when include_fields included the embedded form
  • Removed the option to bulk create templates from forms
  • Removed the list of users on the reports page for quicker report loading.
Download this release

Release Info

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

Code changes from version 2.05.09 to 3.0

Files changed (120) hide show
  1. classes/controllers/FrmAddonsController.php +16 -17
  2. classes/controllers/FrmAppController.php +97 -38
  3. classes/controllers/FrmEntriesController.php +53 -46
  4. classes/controllers/FrmFieldsController.php +169 -98
  5. classes/controllers/FrmFormsController.php +302 -73
  6. classes/controllers/FrmHooksController.php +4 -13
  7. classes/controllers/FrmStylesController.php +21 -1
  8. classes/controllers/FrmXMLController.php +6 -31
  9. classes/factories/FrmFieldFactory.php +88 -0
  10. classes/helpers/FrmAppHelper.php +110 -118
  11. classes/helpers/FrmEntriesHelper.php +59 -88
  12. classes/helpers/FrmEntriesListHelper.php +2 -2
  13. classes/helpers/FrmFieldsHelper.php +476 -629
  14. classes/helpers/FrmFormActionsHelper.php +0 -10
  15. classes/helpers/FrmFormsHelper.php +291 -47
  16. classes/helpers/FrmFormsListHelper.php +14 -33
  17. classes/helpers/FrmListHelper.php +89 -59
  18. classes/helpers/FrmShortcodeHelper.php +55 -0
  19. classes/helpers/FrmStylesHelper.php +5 -13
  20. classes/helpers/FrmTipsHelper.php +2 -2
  21. classes/helpers/FrmXMLHelper.php +3 -2
  22. classes/models/FrmAddon.php +32 -16
  23. classes/models/FrmCreateFile.php +100 -15
  24. classes/models/FrmDb.php +3 -2
  25. classes/models/FrmEDD_SL_Plugin_Updater.php +107 -34
  26. classes/models/FrmEntry.php +7 -45
  27. classes/models/FrmEntryFormatter.php +258 -25
  28. classes/models/FrmEntryMeta.php +38 -5
  29. classes/models/FrmEntryShortcodeFormatter.php +6 -0
  30. classes/models/FrmEntryValidate.php +35 -49
  31. classes/models/FrmEntryValues.php +11 -29
  32. classes/models/FrmField.php +215 -40
  33. classes/models/FrmFieldFormHtml.php +406 -0
  34. classes/models/FrmFieldValue.php +61 -55
  35. classes/models/FrmFieldValueSelector.php +2 -1
  36. classes/models/FrmForm.php +54 -26
  37. classes/models/FrmFormDeprecated.php +3 -3
  38. classes/models/FrmMigrate.php +9 -4
  39. classes/models/FrmSettings.php +3 -3
  40. classes/models/fields/FrmFieldCaptcha.php +198 -0
  41. classes/models/fields/FrmFieldCheckbox.php +63 -0
  42. classes/models/fields/FrmFieldDefault.php +53 -0
  43. classes/models/fields/FrmFieldEmail.php +43 -0
  44. classes/models/fields/FrmFieldHTML.php +46 -0
  45. classes/models/fields/FrmFieldHidden.php +45 -0
  46. classes/models/fields/FrmFieldNumber.php +91 -0
  47. classes/models/fields/FrmFieldPhone.php +34 -0
  48. classes/models/fields/FrmFieldRadio.php +59 -0
  49. classes/models/fields/FrmFieldSelect.php +53 -0
  50. classes/models/fields/FrmFieldText.php +28 -0
  51. classes/models/fields/FrmFieldTextarea.php +68 -0
  52. classes/models/fields/FrmFieldType.php +834 -0
  53. classes/models/fields/FrmFieldUrl.php +83 -0
  54. classes/models/fields/FrmFieldUserID.php +108 -0
  55. classes/views/addons/upgrade_to_pro.php +94 -21
  56. classes/views/frm-entries/_sidebar-shared-pub.php +7 -1
  57. classes/views/frm-entries/errors.php +1 -1
  58. classes/views/frm-entries/form.php +5 -10
  59. classes/views/frm-entries/list.php +21 -29
  60. classes/views/frm-entries/new.php +2 -2
  61. classes/views/frm-entries/show.php +74 -69
  62. classes/views/frm-entries/sidebar-shared.php +14 -5
  63. classes/views/frm-entries/sidebar-show.php +18 -34
  64. classes/views/frm-fields/back-end/ajax-field-placeholder.php +4 -0
  65. classes/views/frm-fields/back-end/dropdown-field.php +1 -1
  66. classes/views/frm-fields/back-end/field-captcha.php +7 -0
  67. classes/views/frm-fields/back-end/field-hidden.php +4 -0
  68. classes/views/frm-fields/back-end/field-html.php +6 -0
  69. classes/views/frm-fields/back-end/field-multiple.php +15 -0
  70. classes/views/frm-fields/back-end/field-user-id.php +3 -0
  71. classes/views/frm-fields/back-end/html-content.php +7 -0
  72. classes/views/frm-fields/back-end/number-range.php +15 -0
  73. classes/views/frm-fields/back-end/pixels-wide.php +7 -3
  74. classes/views/frm-fields/back-end/value-format.php +7 -0
  75. classes/views/frm-fields/front-end/checkbox-field.php +54 -0
  76. classes/views/frm-fields/front-end/dropdown-field.php +4 -7
  77. classes/views/frm-fields/front-end/radio-field.php +53 -0
  78. classes/views/frm-fields/input.php +3 -147
  79. classes/views/frm-fields/radio.php +2 -21
  80. classes/views/frm-fields/show-build.php +4 -35
  81. classes/views/frm-form-actions/form_action.php +1 -1
  82. classes/views/frm-forms/_publish_box.php +43 -88
  83. classes/views/frm-forms/actions-dropdown.php +19 -0
  84. classes/views/frm-forms/add_field.php +42 -72
  85. classes/views/frm-forms/add_field_links.php +113 -157
  86. classes/views/frm-forms/edit.php +13 -20
  87. classes/views/frm-forms/form.php +17 -21
  88. classes/views/frm-forms/insert_form_popup.php +45 -49
  89. classes/views/frm-forms/list.php +9 -10
  90. classes/views/frm-forms/mb_html_tab.php +4 -0
  91. classes/views/frm-forms/new.php +14 -15
  92. classes/views/frm-forms/settings.php +93 -57
  93. classes/views/frm-forms/sidebar-settings.php +11 -4
  94. classes/views/frm-settings/form.php +9 -6
  95. classes/views/frm-settings/license_box.php +1 -1
  96. classes/views/shared/admin-header.php +32 -0
  97. classes/views/shared/errors.php +15 -15
  98. classes/views/shared/form-nav.php +6 -7
  99. classes/views/shared/head.php +0 -2
  100. classes/views/shared/mb_adv_info.php +21 -9
  101. classes/views/styles/_sample_form.php +10 -8
  102. classes/views/styles/show.php +5 -5
  103. classes/views/xml/xml.php +2 -2
  104. css/_single_theme.css.php +62 -504
  105. css/custom_theme.css.php +107 -176
  106. css/font_icons.css +261 -6
  107. css/frm_admin.css +1240 -335
  108. css/frm_fonts.css +3 -2
  109. css/frm_grids.css +223 -108
  110. css/frm_old_grids.css +643 -0
  111. deprecated.php +0 -5
  112. fonts/s11-fp.eot +0 -0
  113. fonts/s11-fp.svg +151 -67
  114. fonts/s11-fp.ttf +0 -0
  115. fonts/s11-fp.woff +0 -0
  116. formidable.php +47 -40
  117. images/rte.png +0 -0
  118. js/formidable.js +196 -4073
  119. js/formidable.min.js +35 -105
  120. js/formidable_admin.js +274 -117
classes/controllers/FrmAddonsController.php CHANGED
@@ -57,36 +57,35 @@ class FrmAddonsController {
57
  'title' => 'Formidable Pro',
58
  'link' => 'pricing/',
59
  'docs' => '',
60
- 'file' => 'formidable/pro',
61
  'excerpt' => 'Enhance your basic Formidable forms with a plethora of Pro field types and features. Create advanced forms and data-driven applications in minutes.',
62
  ),
63
  'mailchimp' => array(
64
- 'title' => 'MailChimp',
65
  'excerpt' => 'Get on the path to more sales and leads in a matter of minutes. Add leads to a MailChimp mailing list when they submit forms and update their information along with the entry.',
66
  ),
67
  'registration' => array(
68
- 'title' => 'User Registration',
69
  'link' => 'downloads/user-registration/',
70
  'excerpt' => 'Give new users access to your site as quickly and painlessly as possible. Allow users to register, edit and be able to login to their profiles on your site from the front end in a clean, customized registration form.',
71
  ),
72
  'paypal' => array(
73
- 'title' => 'PayPal Standard',
74
  'link' => 'downloads/paypal-standard/',
75
  'excerpt' => 'Automate your business by collecting instant payments from your clients. Collect information, calculate a total, and send them on to PayPal. Require a payment before publishing content on your site.',
76
  ),
77
  'stripe' => array(
78
- 'title' => 'Stripe',
79
  'docs' => 'stripe/',
80
  'excerpt' => 'Any Formidable forms on your site can accept credit card payments without users ever leaving your site.',
81
  ),
82
  'authorize-net' => array(
83
- 'title' => 'Authorize.net AIM',
84
  'link' => 'downloads/authorize-net-aim/',
85
  'docs' => 'authorize-net-aim/',
86
  'excerpt' => 'Accept one-time payments directly on your site, using Authorize.net AIM.',
87
  ),
88
  'woocommerce' => array(
89
- 'title' => 'WooCommerce',
90
  'excerpt' => 'Use a Formidable form on your WooCommerce product pages.',
91
  ),
92
  'autoresponder' => array(
@@ -95,49 +94,49 @@ class FrmAddonsController {
95
  'excerpt' => 'Schedule email notifications, SMS messages, and API actions.',
96
  ),
97
  'modal' => array(
98
- 'title' => 'Bootstrap Modal',
99
  'link' => 'downloads/bootstrap-modal/',
100
  'docs' => 'bootstrap-modal/',
101
  'excerpt' => 'Open a view or form in a Bootstrap popup.',
102
  ),
103
  'bootstrap' => array(
104
- 'title' => 'Bootstrap',
105
  'excerpt' => 'Instantly add Bootstrap styling to all your Formidable forms.',
106
  ),
107
  'zapier' => array(
108
- 'title' => 'Zapier',
109
  'excerpt' => 'Connect with hundreds of different applications through Zapier. Insert a new row in a Google docs spreadsheet, post on Twitter, or add a new Dropbox file with your form.',
110
  ),
111
  'signature' => array(
112
- 'title' => 'Signature',
113
  'excerpt' => 'Add a signature field to your form. The user may write their signature with a trackpad/mouse or just type it.',
114
  ),
115
  'api' => array(
116
- 'title' => 'Formidable API',
117
  'link' => 'downloads/formidable-api/',
118
  'excerpt' => 'Send entry results to any other site that has a Rest API. This includes the option of sending entries from one Formidable site to another.',
119
  ),
120
  'twilio' => array(
121
- 'title' => 'Twilio',
122
  'docs' => 'twilio-add-on/',
123
  'excerpt' => 'Allow users to text their votes for polls created by Formidable Forms, or send SMS notifications when entries are submitted or updated.',
124
  ),
125
  'aweber' => array(
126
- 'title' => 'AWeber',
127
  'excerpt' => 'Subscribe users to an AWeber mailing list when they submit a form. AWeber is a powerful email marketing service.',
128
  ),
129
  'highrise' => array(
130
- 'title' => 'Highrise',
131
  'excerpt' => 'Add your leads to your Highrise CRM account any time a Formidable form is submitted.',
132
  ),
133
  'wpml' => array(
134
- 'title' => 'WP Multilingual',
135
  'link' => 'downloads/wp-multilingual/',
136
  'docs' => 'formidable-multi-language/',
137
  'excerpt' => 'Translate your forms into multiple languages using the Formidable-integrated WPML plugin.',
138
  ),
139
  'polylang' => array(
140
- 'title' => 'Polylang',
141
  'excerpt' => 'Create bilingual or multilingual forms with help from Polylang.',
142
  ),
143
  'locations' => array(
57
  'title' => 'Formidable Pro',
58
  'link' => 'pricing/',
59
  'docs' => '',
 
60
  'excerpt' => 'Enhance your basic Formidable forms with a plethora of Pro field types and features. Create advanced forms and data-driven applications in minutes.',
61
  ),
62
  'mailchimp' => array(
63
+ 'title' => 'MailChimp Forms',
64
  'excerpt' => 'Get on the path to more sales and leads in a matter of minutes. Add leads to a MailChimp mailing list when they submit forms and update their information along with the entry.',
65
  ),
66
  'registration' => array(
67
+ 'title' => 'User Registration Forms',
68
  'link' => 'downloads/user-registration/',
69
  'excerpt' => 'Give new users access to your site as quickly and painlessly as possible. Allow users to register, edit and be able to login to their profiles on your site from the front end in a clean, customized registration form.',
70
  ),
71
  'paypal' => array(
72
+ 'title' => 'PayPal Standard Forms',
73
  'link' => 'downloads/paypal-standard/',
74
  'excerpt' => 'Automate your business by collecting instant payments from your clients. Collect information, calculate a total, and send them on to PayPal. Require a payment before publishing content on your site.',
75
  ),
76
  'stripe' => array(
77
+ 'title' => 'Stripe Forms',
78
  'docs' => 'stripe/',
79
  'excerpt' => 'Any Formidable forms on your site can accept credit card payments without users ever leaving your site.',
80
  ),
81
  'authorize-net' => array(
82
+ 'title' => 'Authorize.net AIM Forms',
83
  'link' => 'downloads/authorize-net-aim/',
84
  'docs' => 'authorize-net-aim/',
85
  'excerpt' => 'Accept one-time payments directly on your site, using Authorize.net AIM.',
86
  ),
87
  'woocommerce' => array(
88
+ 'title' => 'WooCommerce Forms',
89
  'excerpt' => 'Use a Formidable form on your WooCommerce product pages.',
90
  ),
91
  'autoresponder' => array(
94
  'excerpt' => 'Schedule email notifications, SMS messages, and API actions.',
95
  ),
96
  'modal' => array(
97
+ 'title' => 'Bootstrap Modal Forms',
98
  'link' => 'downloads/bootstrap-modal/',
99
  'docs' => 'bootstrap-modal/',
100
  'excerpt' => 'Open a view or form in a Bootstrap popup.',
101
  ),
102
  'bootstrap' => array(
103
+ 'title' => 'Bootstrap Style Forms',
104
  'excerpt' => 'Instantly add Bootstrap styling to all your Formidable forms.',
105
  ),
106
  'zapier' => array(
107
+ 'title' => 'Zapier Forms',
108
  'excerpt' => 'Connect with hundreds of different applications through Zapier. Insert a new row in a Google docs spreadsheet, post on Twitter, or add a new Dropbox file with your form.',
109
  ),
110
  'signature' => array(
111
+ 'title' => 'Digital Signature Forms',
112
  'excerpt' => 'Add a signature field to your form. The user may write their signature with a trackpad/mouse or just type it.',
113
  ),
114
  'api' => array(
115
+ 'title' => 'Formidable Forms API',
116
  'link' => 'downloads/formidable-api/',
117
  'excerpt' => 'Send entry results to any other site that has a Rest API. This includes the option of sending entries from one Formidable site to another.',
118
  ),
119
  'twilio' => array(
120
+ 'title' => 'Twilio SMS Forms',
121
  'docs' => 'twilio-add-on/',
122
  'excerpt' => 'Allow users to text their votes for polls created by Formidable Forms, or send SMS notifications when entries are submitted or updated.',
123
  ),
124
  'aweber' => array(
125
+ 'title' => 'AWeber Forms',
126
  'excerpt' => 'Subscribe users to an AWeber mailing list when they submit a form. AWeber is a powerful email marketing service.',
127
  ),
128
  'highrise' => array(
129
+ 'title' => 'Highrise Forms',
130
  'excerpt' => 'Add your leads to your Highrise CRM account any time a Formidable form is submitted.',
131
  ),
132
  'wpml' => array(
133
+ 'title' => 'WP Multilingual Forms',
134
  'link' => 'downloads/wp-multilingual/',
135
  'docs' => 'formidable-multi-language/',
136
  'excerpt' => 'Translate your forms into multiple languages using the Formidable-integrated WPML plugin.',
137
  ),
138
  'polylang' => array(
139
+ 'title' => 'Polylang Forms',
140
  'excerpt' => 'Create bilingual or multilingual forms with help from Polylang.',
141
  ),
142
  'locations' => array(
classes/controllers/FrmAppController.php CHANGED
@@ -23,6 +23,29 @@ class FrmAppController {
23
  return $pos;
24
  }
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  public static function load_wp_admin_style() {
27
  FrmAppHelper::load_font_style();
28
  }
@@ -94,7 +117,7 @@ class FrmAppController {
94
 
95
  // Adds a settings link to the plugins page
96
  public static function settings_link( $links ) {
97
- $settings = '<a href="' . esc_url( admin_url( 'admin.php?page=formidable-settings' ) ) . '">' . __( 'Settings', 'formidable' ) . '</a>';
98
  array_unshift( $links, $settings );
99
 
100
  return $links;
@@ -108,21 +131,29 @@ class FrmAppController {
108
  return;
109
  }
110
 
111
- if ( get_site_option( 'frmpro-authorized' ) && ! file_exists( FrmAppHelper::plugin_path() . '/pro/formidable-pro.php' ) ) {
112
- FrmAppHelper::load_admin_wide_js();
 
 
 
 
113
 
114
- // user is authorized, but running free version
115
- $inst_install_url = 'https://formidableforms.com/knowledgebase/install-formidable-forms/';
 
 
 
 
116
  ?>
117
  <div class="error" class="frm_previous_install">
118
  <?php
119
- echo wp_kses_post( apply_filters( 'frm_pro_update_msg',
120
  sprintf(
121
- __( 'This site has been previously authorized to run Formidable Forms.<br/>%1$sInstall Formidable Pro%2$s or %3$sdeauthorize%4$s this site to continue running the free version and remove this message.', 'formidable' ),
122
- '<a href="' . esc_url( $inst_install_url ) . '" target="_blank">', '</a>',
123
  '<a href="#" class="frm_deauthorize_link">', '</a>'
124
  ), esc_url( $inst_install_url )
125
- ) );
126
  ?>
127
  </div>
128
  <?php
@@ -272,6 +303,7 @@ class FrmAppController {
272
 
273
  wp_register_script( 'formidable-editinplace', FrmAppHelper::plugin_url() . '/js/jquery/jquery.editinplace.packed.js', array( 'jquery' ), '2.3.0' );
274
 
 
275
  } else if ( $pagenow == 'post.php' || ( $pagenow == 'post-new.php' && $post_type == 'frm_display' ) ) {
276
  if ( isset( $_REQUEST['post_type'] ) ) {
277
  $post_type = sanitize_title( $_REQUEST['post_type'] );
@@ -319,19 +351,14 @@ class FrmAppController {
319
  }
320
  }
321
 
322
- public static function localize_script( $location ) {
323
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmAppHelper::localize_script' );
324
- return FrmAppHelper::localize_script( $location );
325
- }
326
-
327
- public static function custom_stylesheet() {
328
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmStylesController::custom_stylesheet' );
329
- return FrmStylesController::custom_stylesheet();
330
- }
331
-
332
- public static function load_css() {
333
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmStylesController::load_saved_css' );
334
- return FrmStylesController::load_saved_css();
335
  }
336
 
337
  /**
@@ -343,22 +370,38 @@ class FrmAppController {
343
  * @param int $blog_id Blog ID.
344
  */
345
  public static function network_upgrade_site( $blog_id = 0 ) {
 
 
 
346
  if ( $blog_id ) {
347
  switch_to_blog( $blog_id );
348
- $upgrade_url = admin_url( 'admin-ajax.php' );
349
  restore_current_blog();
350
  } else {
351
- $upgrade_url = admin_url( 'admin-ajax.php' );
352
  }
353
 
354
- $upgrade_url = add_query_arg( array( 'action' => 'frm_silent_upgrade' ), $upgrade_url );
355
- $r = wp_remote_get( esc_url_raw( $upgrade_url ) );
356
- if ( is_wp_error( $r ) || ! is_array( $r ) || ! empty( $r['body'] ) ) {
357
  // if the remove post fails, use javascript instead
358
  add_action( 'admin_notices', 'FrmAppController::install_js_fallback' );
359
  }
360
  }
361
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
362
  /**
363
  * Silent database upgrade (no redirect).
364
  * Called via ajax request during network upgrade process.
@@ -366,15 +409,16 @@ class FrmAppController {
366
  * @since 2.0.1
367
  */
368
  public static function ajax_install() {
369
- if ( self::needs_update() ) {
370
- self::install();
371
- }
372
  wp_die();
373
  }
374
 
375
  public static function activation_install() {
376
  FrmDb::delete_cache_and_transient( 'frm_plugin_version' );
377
  FrmFormActionsController::actions_init();
 
 
 
378
  self::install();
379
  }
380
 
@@ -407,16 +451,16 @@ class FrmAppController {
407
  }
408
 
409
  // Routes for wordpress pages -- we're just replacing content here folks.
410
- public static function page_route( $content ) {
411
- global $post;
 
412
 
413
- $frm_settings = FrmAppHelper::get_settings();
414
- if ( $post && $post->ID == $frm_settings->preview_page_id && isset( $_GET['form'] ) ) {
415
- $content = FrmFormsController::page_preview();
416
- }
417
 
418
- return $content;
419
- }
420
 
421
  public static function deauthorize() {
422
  FrmAppHelper::permission_check('frm_change_settings');
@@ -429,6 +473,21 @@ class FrmAppController {
429
  wp_die();
430
  }
431
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
432
  public static function get_form_shortcode( $atts ) {
433
  _deprecated_function( __FUNCTION__, '1.07.05', 'FrmFormsController::get_form_shortcode()' );
434
  return FrmFormsController::get_form_shortcode( $atts );
23
  return $pos;
24
  }
25
 
26
+ /**
27
+ * @since 3.0
28
+ */
29
+ public static function add_admin_class( $classes ) {
30
+ if ( self::is_white_page() ) {
31
+ $classes .= ' frm-white-body ';
32
+ }
33
+ return $classes;
34
+ }
35
+
36
+ /**
37
+ * @since 3.0
38
+ */
39
+ private static function is_white_page() {
40
+ $is_white_page = ( FrmAppHelper::is_admin_page( 'formidable' ) || FrmAppHelper::is_admin_page( 'formidable-entries' ) || FrmAppHelper::is_admin_page( 'formidable-pro-upgrade' ) );
41
+ if ( ! $is_white_page ) {
42
+ $screen = get_current_screen();
43
+ $is_white_page = ( $screen && $screen->id === 'edit-frm_display' );
44
+ }
45
+
46
+ return $is_white_page;
47
+ }
48
+
49
  public static function load_wp_admin_style() {
50
  FrmAppHelper::load_font_style();
51
  }
117
 
118
  // Adds a settings link to the plugins page
119
  public static function settings_link( $links ) {
120
+ $settings = '<a href="' . esc_url( admin_url( 'admin.php?page=formidable' ) ) . '">' . __( 'Build a Form', 'formidable' ) . '</a>';
121
  array_unshift( $links, $settings );
122
 
123
  return $links;
131
  return;
132
  }
133
 
134
+ $pro_installed = is_dir( WP_PLUGIN_DIR . '/formidable-pro' );
135
+
136
+ if ( get_site_option( 'frmpro-authorized' ) && ! is_callable( 'load_formidable_pro' ) ) {
137
+ FrmAppHelper::load_admin_wide_js();
138
+
139
+ // user is authorized, but running free version
140
 
141
+ if ( $pro_installed ) {
142
+ // if pro version is installed, include link to activate it
143
+ $inst_install_url = wp_nonce_url( self_admin_url( 'plugins.php?action=activate&plugin=formidable-pro/formidable-pro.php' ), 'activate-plugin_formidable-pro/formidable-pro.php' );
144
+ } else {
145
+ $inst_install_url = 'https://formidableforms.com/knowledgebase/install-formidable-forms/';
146
+ }
147
  ?>
148
  <div class="error" class="frm_previous_install">
149
  <?php
150
+ echo apply_filters( 'frm_pro_update_msg',
151
  sprintf(
152
+ esc_html__( 'This site has been previously authorized to run Formidable Forms. %1$sInstall Formidable Pro%2$s or %3$sdeauthorize%4$s this site to continue running the free version and remove this message.', 'formidable' ),
153
+ '<br/><a href="' . esc_url( $inst_install_url ) . '" target="_blank">', '</a>',
154
  '<a href="#" class="frm_deauthorize_link">', '</a>'
155
  ), esc_url( $inst_install_url )
156
+ );
157
  ?>
158
  </div>
159
  <?php
303
 
304
  wp_register_script( 'formidable-editinplace', FrmAppHelper::plugin_url() . '/js/jquery/jquery.editinplace.packed.js', array( 'jquery' ), '2.3.0' );
305
 
306
+ do_action( 'frm_enqueue_builder_scripts' );
307
  } else if ( $pagenow == 'post.php' || ( $pagenow == 'post-new.php' && $post_type == 'frm_display' ) ) {
308
  if ( isset( $_REQUEST['post_type'] ) ) {
309
  $post_type = sanitize_title( $_REQUEST['post_type'] );
351
  }
352
  }
353
 
354
+ /**
355
+ * @since 3.0
356
+ */
357
+ public static function create_rest_routes() {
358
+ register_rest_route( 'frm-admin/v1', '/install', array(
359
+ 'methods' => 'GET',
360
+ 'callback' => 'FrmAppController::api_install',
361
+ ) );
 
 
 
 
 
362
  }
363
 
364
  /**
370
  * @param int $blog_id Blog ID.
371
  */
372
  public static function network_upgrade_site( $blog_id = 0 ) {
373
+
374
+ $request = new WP_REST_Request( 'GET', '/frm-admin/v1/install' );
375
+
376
  if ( $blog_id ) {
377
  switch_to_blog( $blog_id );
378
+ $response = rest_do_request( $request );
379
  restore_current_blog();
380
  } else {
381
+ $response = rest_do_request( $request );
382
  }
383
 
384
+ if ( $response->is_error() ) {
 
 
385
  // if the remove post fails, use javascript instead
386
  add_action( 'admin_notices', 'FrmAppController::install_js_fallback' );
387
  }
388
  }
389
 
390
+ /**
391
+ * @since 3.0
392
+ */
393
+ public static function api_install() {
394
+ if ( self::needs_update() ) {
395
+ $running = get_option( 'frm_install_running' );
396
+ if ( false === $running ) {
397
+ update_option( 'frm_install_running', true );
398
+ self::install();
399
+ delete_option( 'frm_install_running' );
400
+ }
401
+ }
402
+ return true;
403
+ }
404
+
405
  /**
406
  * Silent database upgrade (no redirect).
407
  * Called via ajax request during network upgrade process.
409
  * @since 2.0.1
410
  */
411
  public static function ajax_install() {
412
+ self::api_install();
 
 
413
  wp_die();
414
  }
415
 
416
  public static function activation_install() {
417
  FrmDb::delete_cache_and_transient( 'frm_plugin_version' );
418
  FrmFormActionsController::actions_init();
419
+ if ( ! self::needs_update() ) {
420
+ FrmAppHelper::save_combined_js();
421
+ }
422
  self::install();
423
  }
424
 
451
  }
452
 
453
  // Routes for wordpress pages -- we're just replacing content here folks.
454
+ public static function page_route( $content ) {
455
+ _deprecated_function( __METHOD__, '3.0' );
456
+ global $post;
457
 
458
+ if ( $post && isset( $_GET['form'] ) ) {
459
+ $content = FrmFormsController::page_preview();
460
+ }
 
461
 
462
+ return $content;
463
+ }
464
 
465
  public static function deauthorize() {
466
  FrmAppHelper::permission_check('frm_change_settings');
473
  wp_die();
474
  }
475
 
476
+ public static function set_footer_text( $text ) {
477
+ if ( FrmAppHelper::is_formidable_admin() ) {
478
+ $text = sprintf(
479
+ __( 'Help us spread the %1$sFormidable Forms%2$s love with %3$s %5$s on WordPress.org%4$s. Thank you heaps!', 'formidable' ),
480
+ '<a href="' . esc_url( FrmAppHelper::make_affiliate_url( 'https://formidableforms.com' ) ) . '" target="_blank">',
481
+ '</a>',
482
+ '<a href="https://wordpress.org/support/plugin/formidable/reviews/?filter=5#new-post" target="_blank">',
483
+ '</a>',
484
+ '&#9733;&#9733;&#9733;&#9733;&#9733;'
485
+ );
486
+ $text = '<span id="footer-thankyou">' . $text . '</span>';
487
+ }
488
+ return $text;
489
+ }
490
+
491
  public static function get_form_shortcode( $atts ) {
492
  _deprecated_function( __FUNCTION__, '1.07.05', 'FrmFormsController::get_form_shortcode()' );
493
  return FrmFormsController::get_form_shortcode( $atts );
classes/controllers/FrmEntriesController.php CHANGED
@@ -14,13 +14,15 @@ class FrmEntriesController {
14
  * @since 2.05.07
15
  */
16
  private static function load_manage_entries_hooks() {
17
- if ( ! in_array( FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' ), array( 'edit', 'show' ) ) ) {
18
  $menu_name = FrmAppHelper::get_menu_name();
19
  $base = self::base_column_key( $menu_name );
20
 
21
  add_filter( 'manage_' . $base . '_columns', 'FrmEntriesController::manage_columns' );
22
  add_filter( 'get_user_option_' . self::hidden_column_key( $menu_name ), 'FrmEntriesController::hidden_columns' );
23
  add_filter( 'manage_' . $base . '_sortable_columns', 'FrmEntriesController::sortable_columns' );
 
 
24
  }
25
  }
26
 
@@ -52,7 +54,8 @@ class FrmEntriesController {
52
 
53
  $action = FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' );
54
  $page = FrmAppHelper::simple_get( 'page', 'sanitize_title' );
55
- if ( $page != 'formidable-entries' || ( ! empty( $action ) && $action != 'list' ) ) {
 
56
  return $help;
57
  }
58
 
@@ -73,6 +76,21 @@ class FrmEntriesController {
73
  return $help;
74
  }
75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  public static function manage_columns( $columns ) {
77
  global $frm_vars;
78
  $form_id = FrmForm::get_current_form_id();
@@ -411,6 +429,7 @@ class FrmEntriesController {
411
 
412
  $fields = FrmField::get_all_for_form( $entry->form_id, '', 'include' );
413
  $to_emails = array();
 
414
 
415
  include( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/show.php' );
416
  }
@@ -421,9 +440,7 @@ class FrmEntriesController {
421
  $params = FrmForm::get_admin_params();
422
 
423
  if ( isset( $params['keep_post'] ) && $params['keep_post'] ) {
424
- //unlink entry from post
425
- global $wpdb;
426
- $wpdb->update( $wpdb->prefix . 'frm_items', array( 'post_id' => '' ), array( 'id' => $params['id'] ) );
427
  }
428
 
429
  $message = '';
@@ -520,17 +537,35 @@ class FrmEntriesController {
520
 
521
  if ( empty( $errors ) ) {
522
  $_POST['frm_skip_cookie'] = 1;
 
523
  if ( $params['action'] == 'create' ) {
524
  if ( apply_filters( 'frm_continue_to_create', true, $form_id ) && ! isset( $frm_vars['created_entries'][ $form_id ]['entry_id'] ) ) {
525
  $frm_vars['created_entries'][ $form_id ]['entry_id'] = FrmEntry::create( $_POST );
 
 
526
  }
527
  }
528
 
529
  do_action( 'frm_process_entry', $params, $errors, $form, array( 'ajax' => $ajax ) );
 
 
 
530
  unset( $_POST['frm_skip_cookie'] );
531
  }
532
  }
533
 
 
 
 
 
 
 
 
 
 
 
 
 
534
  public static function delete_entry_before_redirect( $url, $form, $atts ) {
535
  self::_delete_entry( $atts['id'], $form );
536
  return $url;
@@ -548,17 +583,27 @@ class FrmEntriesController {
548
 
549
  $form->options = maybe_unserialize( $form->options );
550
  if ( isset( $form->options['no_save'] ) && $form->options['no_save'] ) {
 
551
  FrmEntry::destroy( $entry_id );
552
  }
553
  }
554
 
 
 
 
 
 
 
 
 
 
555
  /**
556
  * @param $atts
557
  *
558
  * @return array|string
559
  */
560
  public static function show_entry_shortcode( $atts ) {
561
- $defaults = array(
562
  'id' => false,
563
  'entry' => false,
564
  'fields' => false,
@@ -581,7 +626,8 @@ class FrmEntriesController {
581
  'include_fields' => '',
582
  'include_extras' => '',
583
  'inline_style' => 1,
584
- );
 
585
 
586
  $atts = shortcode_atts( $defaults, $atts );
587
 
@@ -603,11 +649,6 @@ class FrmEntriesController {
603
  return $formatted_entry;
604
  }
605
 
606
- public static function get_params( $form = null ) {
607
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmForm::get_params' );
608
- return FrmForm::get_params( $form );
609
- }
610
-
611
  public static function entry_sidebar( $entry ) {
612
  $data = maybe_unserialize( $entry->description );
613
  $date_format = get_option( 'date_format' );
@@ -618,38 +659,4 @@ class FrmEntriesController {
618
 
619
  include( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/sidebar-shared.php' );
620
  }
621
-
622
- /***********************************************************************
623
- * Deprecated Functions
624
- ************************************************************************/
625
-
626
- /**
627
- * @deprecated 2.02.14
628
- *
629
- * @return mixed
630
- */
631
- public static function filter_email_value( $value ) {
632
- _deprecated_function( __FUNCTION__, '2.02.14', 'FrmProEntriesController::filter_value_in_single_entry_table' );
633
- return $value;
634
- }
635
-
636
- /**
637
- * @deprecated 2.02.14
638
- *
639
- * @return mixed
640
- */
641
- public static function filter_display_value( $value ) {
642
- _deprecated_function( __FUNCTION__, '2.02.14', 'FrmProEntriesController::filter_display_value' );
643
- return $value;
644
- }
645
-
646
- /**
647
- * @deprecated 2.03.04
648
- *
649
- * @return mixed
650
- */
651
- public static function filter_shortcode_value( $value ) {
652
- _deprecated_function( __FUNCTION__, '2.03.04', 'custom code' );
653
- return $value;
654
- }
655
  }
14
  * @since 2.05.07
15
  */
16
  private static function load_manage_entries_hooks() {
17
+ if ( ! in_array( FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' ), array( 'edit', 'show', 'new' ) ) ) {
18
  $menu_name = FrmAppHelper::get_menu_name();
19
  $base = self::base_column_key( $menu_name );
20
 
21
  add_filter( 'manage_' . $base . '_columns', 'FrmEntriesController::manage_columns' );
22
  add_filter( 'get_user_option_' . self::hidden_column_key( $menu_name ), 'FrmEntriesController::hidden_columns' );
23
  add_filter( 'manage_' . $base . '_sortable_columns', 'FrmEntriesController::sortable_columns' );
24
+ } else {
25
+ add_filter( 'screen_options_show_screen', __CLASS__ . '::remove_screen_options', 10, 2 );
26
  }
27
  }
28
 
54
 
55
  $action = FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' );
56
  $page = FrmAppHelper::simple_get( 'page', 'sanitize_title' );
57
+ $show_help = ( $page == 'formidable-entries' && ( empty( $action ) || $action == 'list' ) );
58
+ if ( ! $show_help ) {
59
  return $help;
60
  }
61
 
76
  return $help;
77
  }
78
 
79
+ /**
80
+ * Prevent the "screen options" tab from showing when
81
+ * editing or creating an entry
82
+ *
83
+ * @since 3.0
84
+ */
85
+ public static function remove_screen_options( $show_screen, $screen ) {
86
+ $menu_name = sanitize_title( FrmAppHelper::get_menu_name() );
87
+ if ( $screen->id == $menu_name . '_page_formidable-entries' ) {
88
+ $show_screen = false;
89
+ }
90
+
91
+ return $show_screen;
92
+ }
93
+
94
  public static function manage_columns( $columns ) {
95
  global $frm_vars;
96
  $form_id = FrmForm::get_current_form_id();
429
 
430
  $fields = FrmField::get_all_for_form( $entry->form_id, '', 'include' );
431
  $to_emails = array();
432
+ $form = FrmForm::getOne( $entry->form_id );
433
 
434
  include( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/show.php' );
435
  }
440
  $params = FrmForm::get_admin_params();
441
 
442
  if ( isset( $params['keep_post'] ) && $params['keep_post'] ) {
443
+ self::unlink_post( $params['id'] );
 
 
444
  }
445
 
446
  $message = '';
537
 
538
  if ( empty( $errors ) ) {
539
  $_POST['frm_skip_cookie'] = 1;
540
+ $do_success = false;
541
  if ( $params['action'] == 'create' ) {
542
  if ( apply_filters( 'frm_continue_to_create', true, $form_id ) && ! isset( $frm_vars['created_entries'][ $form_id ]['entry_id'] ) ) {
543
  $frm_vars['created_entries'][ $form_id ]['entry_id'] = FrmEntry::create( $_POST );
544
+ $params['id'] = $frm_vars['created_entries'][ $form_id ]['entry_id'];
545
+ $do_success = true;
546
  }
547
  }
548
 
549
  do_action( 'frm_process_entry', $params, $errors, $form, array( 'ajax' => $ajax ) );
550
+ if ( $do_success ) {
551
+ FrmFormsController::maybe_trigger_redirect( $form, $params, array( 'ajax' => $ajax ) );
552
+ }
553
  unset( $_POST['frm_skip_cookie'] );
554
  }
555
  }
556
 
557
+ /**
558
+ * Escape url entities before redirect
559
+ *
560
+ * @since 3.0
561
+ *
562
+ * @param string $url
563
+ * @return string
564
+ */
565
+ public static function prepare_redirect_url( $url ) {
566
+ return str_replace( array( ' ', '[', ']', '|', '@' ), array( '%20', '%5B', '%5D', '%7C', '%40' ), $url );
567
+ }
568
+
569
  public static function delete_entry_before_redirect( $url, $form, $atts ) {
570
  self::_delete_entry( $atts['id'], $form );
571
  return $url;
583
 
584
  $form->options = maybe_unserialize( $form->options );
585
  if ( isset( $form->options['no_save'] ) && $form->options['no_save'] ) {
586
+ self::unlink_post( $entry_id );
587
  FrmEntry::destroy( $entry_id );
588
  }
589
  }
590
 
591
+ /**
592
+ * unlink entry from post
593
+ */
594
+ private static function unlink_post( $entry_id ) {
595
+ global $wpdb;
596
+ $wpdb->update( $wpdb->prefix . 'frm_items', array( 'post_id' => '' ), array( 'id' => $entry_id ) );
597
+ FrmEntry::clear_cache();
598
+ }
599
+
600
  /**
601
  * @param $atts
602
  *
603
  * @return array|string
604
  */
605
  public static function show_entry_shortcode( $atts ) {
606
+ $defaults = apply_filters( 'frm_show_entry_defaults', array(
607
  'id' => false,
608
  'entry' => false,
609
  'fields' => false,
626
  'include_fields' => '',
627
  'include_extras' => '',
628
  'inline_style' => 1,
629
+ 'child_array' => false, // return embedded fields as nested array
630
+ ) );
631
 
632
  $atts = shortcode_atts( $defaults, $atts );
633
 
649
  return $formatted_entry;
650
  }
651
 
 
 
 
 
 
652
  public static function entry_sidebar( $entry ) {
653
  $data = maybe_unserialize( $entry->description );
654
  $date_format = get_option( 'date_format' );
659
 
660
  include( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/sidebar-shared.php' );
661
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
662
  }
classes/controllers/FrmFieldsController.php CHANGED
@@ -14,36 +14,32 @@ class FrmFieldsController {
14
  $_GET['page'] = 'formidable';
15
  $fields = stripslashes_deep( $fields );
16
 
17
- $ajax = true;
18
- $values = array( 'id' => FrmAppHelper::get_post_param( 'form_id', '', 'absint' ) );
19
- $path = FrmAppHelper::plugin_path();
 
20
  $field_html = array();
21
 
22
  foreach ( $fields as $field ) {
23
- $field = htmlspecialchars_decode( nl2br( $field ) );
24
- $field = json_decode( $field, true );
25
- if ( ! isset( $field['id'] ) ) {
26
- // this field may have already been loaded
27
- continue;
28
- }
29
-
30
- $field_id = absint( $field['id'] );
31
-
32
- if ( ! isset( $field['value'] ) ) {
33
- $field['value'] = '';
34
- }
35
 
36
- $field_name = 'item_meta[' . $field_id . ']';
37
- $html_id = FrmFieldsHelper::get_html_id( $field );
 
 
 
38
 
39
- ob_start();
40
- include( $path . '/classes/views/frm-forms/add_field.php' );
41
- $field_html[ $field_id ] = ob_get_contents();
42
- ob_end_clean();
43
  }
44
 
45
- unset( $path );
46
-
47
  echo json_encode( $field_html );
48
 
49
  wp_die();
@@ -89,12 +85,15 @@ class FrmFieldsController {
89
  return false;
90
  }
91
 
92
- $field = self::include_single_field( $field_id, $values, $form_id );
 
93
 
94
  return $field;
95
  }
96
 
97
  public static function edit_name( $field = 'name', $id = '' ) {
 
 
98
  FrmAppHelper::permission_check( 'frm_edit_forms' );
99
  check_ajax_referer( 'frm_ajax', 'nonce' );
100
 
@@ -150,8 +149,6 @@ class FrmFieldsController {
150
  FrmAppHelper::permission_check( 'frm_edit_forms' );
151
  check_ajax_referer( 'frm_ajax', 'nonce' );
152
 
153
- global $wpdb;
154
-
155
  $field_id = FrmAppHelper::get_post_param( 'field_id', 0, 'absint' );
156
  $form_id = FrmAppHelper::get_post_param( 'form_id', 0, 'absint' );
157
 
@@ -168,31 +165,95 @@ class FrmFieldsController {
168
  $values = apply_filters( 'frm_prepare_single_field_for_duplication', $values );
169
 
170
  $field_id = FrmField::create( $values );
171
- if ( ! $field_id ) {
172
- wp_die();
173
  }
174
 
175
- self::include_single_field( $field_id, $values );
176
-
177
  wp_die();
178
  }
179
 
180
- /**
181
- * Load a single field in the form builder along with all needed variables
182
- */
183
- public static function include_single_field( $field_id, $values, $form_id = 0 ) {
 
 
 
 
 
 
 
 
184
  $field = FrmFieldsHelper::setup_edit_vars( FrmField::getOne( $field_id ) );
185
- $field_name = 'item_meta[' . $field_id . ']';
186
- $html_id = FrmFieldsHelper::get_html_id( $field );
187
- $id = $form_id ? $form_id : $field['form_id'];
188
- if ( $field['type'] == 'html' ) {
189
- $field['stop_filter'] = true;
190
- }
191
 
192
- require( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/add_field.php' );
 
193
 
194
- return $field;
195
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
 
197
  public static function destroy() {
198
  FrmAppHelper::permission_check( 'frm_edit_forms' );
@@ -216,30 +277,23 @@ class FrmFieldsController {
216
 
217
  $field = FrmField::getOne( $id );
218
 
219
- if ( 'other' == $opt_type ) {
220
  $opt = __( 'Other', 'formidable' );
221
- $other_val = '';
222
- $opt_key = 'other_' . $opt_key;
223
- } else {
224
  $opt = __( 'New Option', 'formidable' );
225
- }
226
- $field_val = $opt;
227
 
228
- $field_data = $field;
229
  $field = (array) $field;
230
  $field['separate_value'] = isset( $field_data->field_options['separate_value'] ) ? $field_data->field_options['separate_value'] : 0;
231
  unset( $field_data );
 
232
 
233
- $field_name = 'item_meta[' . $id . ']';
234
- $html_id = FrmFieldsHelper::get_html_id( $field );
235
- $checked = '';
236
 
237
- if ( 'other' == $opt_type ) {
238
- include( FrmAppHelper::plugin_path() . '/pro/classes/views/frmpro-fields/other-option.php' );
239
- } else {
240
- require( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/single-option.php' );
241
- }
242
- wp_die();
243
  }
244
 
245
  public static function edit_option() {
@@ -348,16 +402,7 @@ class FrmFieldsController {
348
 
349
  $field['options'] = $opts;
350
 
351
- if ( $field['type'] == 'radio' || $field['type'] == 'checkbox' ) {
352
- $field_name = 'item_meta[' . $field['id'] . ']';
353
-
354
- // Get html_id which will be used in single-option.php
355
- $html_id = FrmFieldsHelper::get_html_id( $field );
356
-
357
- require( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/radio.php' );
358
- } else {
359
- FrmFieldsHelper::show_single_option( $field );
360
- }
361
 
362
  wp_die();
363
  }
@@ -376,9 +421,11 @@ class FrmFieldsController {
376
  public static function change_type( $type ) {
377
  $type_switch = array(
378
  'scale' => 'radio',
 
379
  '10radio' => 'radio',
380
  'rte' => 'textarea',
381
  'website' => 'url',
 
382
  );
383
  if ( isset( $type_switch[ $type ] ) ) {
384
  $type = $type_switch[ $type ];
@@ -393,36 +440,31 @@ class FrmFieldsController {
393
  return $type;
394
  }
395
 
396
- public static function display_field_options( $display ) {
397
- switch ( $display['type'] ) {
398
- case 'captcha':
399
- $display['required'] = false;
400
- $display['invalid'] = true;
401
- $display['default_blank'] = false;
402
- $display['captcha_size'] = true;
403
- break;
404
- case 'radio':
405
- $display['default_blank'] = false;
406
- break;
407
- case 'text':
408
- case 'textarea':
409
- $display['size'] = true;
410
- $display['clear_on_focus'] = true;
411
- break;
412
- case 'select':
413
- $display['size'] = true;
414
- break;
415
- case 'url':
416
- case 'website':
417
- case 'email':
418
- $display['size'] = true;
419
- $display['clear_on_focus'] = true;
420
- $display['invalid'] = true;
421
- }
422
 
423
- return $display;
424
  }
425
 
 
 
 
 
 
 
 
 
 
 
426
  public static function input_html( $field, $echo = true ) {
427
  $class = array(); //$field['type'];
428
  self::add_input_classes( $field, $class );
@@ -437,7 +479,8 @@ class FrmFieldsController {
437
 
438
  FrmFormsHelper::add_html_attr( $class, 'class', $add_html );
439
 
440
- self::add_shortcodes_to_html( $field, $add_html );
 
441
 
442
  $add_html = apply_filters( 'frm_field_extra_html', $add_html, $field );
443
  $add_html = ' ' . implode( ' ', $add_html ) . ' ';
@@ -577,6 +620,10 @@ class FrmFieldsController {
577
  * get the label to use as the placeholder
578
  *
579
  * @since 2.05
 
 
 
 
580
  */
581
  public static function get_default_value_from_name( $field ) {
582
  $position = FrmField::get_option( $field, 'label' );
@@ -590,11 +637,13 @@ class FrmFieldsController {
590
 
591
  /**
592
  * use HMTL5 placeholder with js fallback
 
 
 
593
  */
594
  private static function add_placeholder_to_input( $field, &$add_html ) {
595
  if ( FrmFieldsHelper::is_placeholder_field_type( $field['type'] ) ) {
596
  $add_html['placeholder'] = 'placeholder="' . esc_attr( $field['default_value'] ) . '"';
597
- wp_enqueue_script( 'jquery-placeholder' );
598
  }
599
  }
600
 
@@ -638,6 +687,28 @@ class FrmFieldsController {
638
  }
639
  }
640
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
641
  public static function check_value( $opt, $opt_key, $field ) {
642
  if ( is_array( $opt ) ) {
643
  if ( FrmField::is_option_true( $field, 'separate_value' ) ) {
14
  $_GET['page'] = 'formidable';
15
  $fields = stripslashes_deep( $fields );
16
 
17
+ $values = array(
18
+ 'id' => FrmAppHelper::get_post_param( 'form_id', '', 'absint' ),
19
+ 'doing_ajax' => true,
20
+ );
21
  $field_html = array();
22
 
23
  foreach ( $fields as $field ) {
24
+ $field = htmlspecialchars_decode( nl2br( $field ) );
25
+ $field = json_decode( $field );
26
+ if ( ! isset( $field->id ) || ! is_numeric( $field->id ) ) {
27
+ // this field may have already been loaded
28
+ continue;
29
+ }
 
 
 
 
 
 
30
 
31
+ if ( ! isset( $field->value ) ) {
32
+ $field->value = '';
33
+ }
34
+ $field->field_options = json_decode( json_encode( $field->field_options ), true );
35
+ $field->options = json_decode( json_encode( $field->options ), true );
36
 
37
+ ob_start();
38
+ self::load_single_field( $field, $values );
39
+ $field_html[ absint( $field->id ) ] = ob_get_contents();
40
+ ob_end_clean();
41
  }
42
 
 
 
43
  echo json_encode( $field_html );
44
 
45
  wp_die();
85
  return false;
86
  }
87
 
88
+ $field = self::get_field_array_from_id( $field_id );
89
+ self::load_single_field( $field, $values, $form_id );
90
 
91
  return $field;
92
  }
93
 
94
  public static function edit_name( $field = 'name', $id = '' ) {
95
+ _deprecated_function( __FUNCTION__, '3.0' );
96
+
97
  FrmAppHelper::permission_check( 'frm_edit_forms' );
98
  check_ajax_referer( 'frm_ajax', 'nonce' );
99
 
149
  FrmAppHelper::permission_check( 'frm_edit_forms' );
150
  check_ajax_referer( 'frm_ajax', 'nonce' );
151
 
 
 
152
  $field_id = FrmAppHelper::get_post_param( 'field_id', 0, 'absint' );
153
  $form_id = FrmAppHelper::get_post_param( 'form_id', 0, 'absint' );
154
 
165
  $values = apply_filters( 'frm_prepare_single_field_for_duplication', $values );
166
 
167
  $field_id = FrmField::create( $values );
168
+ if ( $field_id ) {
169
+ self::load_single_field( $field_id, $values );
170
  }
171
 
 
 
172
  wp_die();
173
  }
174
 
175
+ /**
176
+ * Load a single field in the form builder along with all needed variables
177
+ *
178
+ * @param int $field_id
179
+ * @param array $values
180
+ * @param int $form_id
181
+ *
182
+ * @return array
183
+ */
184
+ public static function include_single_field( $field_id, $values, $form_id = 0 ) {
185
+ _deprecated_function( __FUNCTION__, '3.0', 'FrmFieldsController::load_single_field' );
186
+
187
  $field = FrmFieldsHelper::setup_edit_vars( FrmField::getOne( $field_id ) );
188
+ self::load_single_field( $field, $values, $form_id );
 
 
 
 
 
189
 
190
+ return $field;
191
+ }
192
 
193
+ /**
194
+ * @since 3.0
195
+ *
196
+ * @param int $field_id
197
+ *
198
+ * @return array
199
+ */
200
+ public static function get_field_array_from_id( $field_id ) {
201
+ $field = FrmField::getOne( $field_id );
202
+ return FrmFieldsHelper::setup_edit_vars( $field );
203
+ }
204
+
205
+ /**
206
+ * @since 3.0
207
+ *
208
+ * @param int|array|object $field_object
209
+ * @param array $values
210
+ * @param int $form_id
211
+ */
212
+ public static function load_single_field( $field_object, $values, $form_id = 0 ) {
213
+ if ( is_numeric( $field_object ) ) {
214
+ $field_object = FrmField::getOne( $field_object );
215
+ } elseif ( is_array( $field_object ) ) {
216
+ $field = $field_object;
217
+ $field_object = FrmField::getOne( $field['id'] );
218
+ }
219
+
220
+ $field_obj = FrmFieldFactory::get_field_factory( $field_object );
221
+ $display = self::display_field_options( array(), $field_obj );
222
+
223
+ $ajax_loading = isset( $values['ajax_load'] ) && $values['ajax_load'];
224
+ $ajax_this_field = isset( $values['count'] ) && $values['count'] > 10 && ! in_array( $field_object->type, array( 'divider', 'end_divider' ) );
225
+
226
+ if ( $ajax_loading && $ajax_this_field ) {
227
+ $li_classes = self::get_classes_for_builder_field( array(), $display, $field_obj );
228
+ include( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/ajax-field-placeholder.php' );
229
+ } else {
230
+ $frm_settings = FrmAppHelper::get_settings();
231
+
232
+ $pro_field_selection = FrmField::pro_field_selection();
233
+ $frm_all_field_selection = array_merge( FrmField::field_selection(), $pro_field_selection );
234
+ $disabled_fields = FrmAppHelper::pro_is_installed() ? array() : $pro_field_selection;
235
+
236
+ if ( ! isset( $field ) && is_object( $field_object ) ) {
237
+ $field = FrmFieldsHelper::setup_edit_vars( $field_object );
238
+ }
239
+
240
+ $li_classes = self::get_classes_for_builder_field( $field, $display, $field_obj );
241
+ $li_classes .= ' ui-state-default widgets-holder-wrap';
242
+
243
+ require( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/add_field.php' );
244
+ }
245
+ }
246
+
247
+ /**
248
+ * @since 3.0
249
+ */
250
+ private static function get_classes_for_builder_field( $field, $display, $field_info ) {
251
+ $li_classes = $field_info->form_builder_classes( $display['type'] );
252
+ if ( ! empty( $field ) ) {
253
+ $li_classes = apply_filters( 'frm_build_field_class', $li_classes, $field );
254
+ }
255
+ return $li_classes;
256
+ }
257
 
258
  public static function destroy() {
259
  FrmAppHelper::permission_check( 'frm_edit_forms' );
277
 
278
  $field = FrmField::getOne( $id );
279
 
280
+ if ( 'other' == $opt_type ) {
281
  $opt = __( 'Other', 'formidable' );
282
+ $opt_key = 'other_' . $opt_key;
283
+ } else {
 
284
  $opt = __( 'New Option', 'formidable' );
285
+ }
 
286
 
287
+ $field_data = $field;
288
  $field = (array) $field;
289
  $field['separate_value'] = isset( $field_data->field_options['separate_value'] ) ? $field_data->field_options['separate_value'] : 0;
290
  unset( $field_data );
291
+ $field['html_name'] = 'item_meta[' . $field['id'] . ']';
292
 
293
+ $field['options'] = array( $opt_key => $opt );
294
+ FrmFieldsHelper::show_single_option( $field );
 
295
 
296
+ wp_die();
 
 
 
 
 
297
  }
298
 
299
  public static function edit_option() {
402
 
403
  $field['options'] = $opts;
404
 
405
+ FrmFieldsHelper::show_single_option( $field );
 
 
 
 
 
 
 
 
 
406
 
407
  wp_die();
408
  }
421
  public static function change_type( $type ) {
422
  $type_switch = array(
423
  'scale' => 'radio',
424
+ 'star' => 'radio',
425
  '10radio' => 'radio',
426
  'rte' => 'textarea',
427
  'website' => 'url',
428
+ 'image' => 'url',
429
  );
430
  if ( isset( $type_switch[ $type ] ) ) {
431
  $type = $type_switch[ $type ];
440
  return $type;
441
  }
442
 
443
+ /**
444
+ * @param array $settings
445
+ * @param object $field_info
446
+ *
447
+ * @return array
448
+ */
449
+ public static function display_field_options( $settings, $field_info = null ) {
450
+ if ( $field_info ) {
451
+ $settings = $field_info->display_field_settings();
452
+ $settings['field_data'] = $field_info->field;
453
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
454
 
455
+ return apply_filters( 'frm_display_field_options', $settings );
456
  }
457
 
458
+ /**
459
+ * Display the format option
460
+ *
461
+ * @since 3.0
462
+ * @param array $field
463
+ */
464
+ public static function show_format_option( $field ) {
465
+ include( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/value-format.php' );
466
+ }
467
+
468
  public static function input_html( $field, $echo = true ) {
469
  $class = array(); //$field['type'];
470
  self::add_input_classes( $field, $class );
479
 
480
  FrmFormsHelper::add_html_attr( $class, 'class', $add_html );
481
 
482
+ self::add_shortcodes_to_html( $field, $add_html );
483
+ self::add_pattern_attribute( $field, $add_html );
484
 
485
  $add_html = apply_filters( 'frm_field_extra_html', $add_html, $field );
486
  $add_html = ' ' . implode( ' ', $add_html ) . ' ';
620
  * get the label to use as the placeholder
621
  *
622
  * @since 2.05
623
+ *
624
+ * @param array $field
625
+ *
626
+ * @return string
627
  */
628
  public static function get_default_value_from_name( $field ) {
629
  $position = FrmField::get_option( $field, 'label' );
637
 
638
  /**
639
  * use HMTL5 placeholder with js fallback
640
+ *
641
+ * @param array $field
642
+ * @param array $add_html
643
  */
644
  private static function add_placeholder_to_input( $field, &$add_html ) {
645
  if ( FrmFieldsHelper::is_placeholder_field_type( $field['type'] ) ) {
646
  $add_html['placeholder'] = 'placeholder="' . esc_attr( $field['default_value'] ) . '"';
 
647
  }
648
  }
649
 
687
  }
688
  }
689
 
690
+ /**
691
+ * Add pattern attribute
692
+ *
693
+ * @since 3.0
694
+ * @param array $field
695
+ * @param array $add_html
696
+ */
697
+ private static function add_pattern_attribute( $field, array &$add_html ) {
698
+ $has_format = FrmField::is_option_true_in_array( $field, 'format' );
699
+ $format_field = FrmField::is_field_type( $field, 'text' );
700
+
701
+ if ( $field['type'] == 'phone' || ( $has_format && $format_field ) ) {
702
+ $frm_settings = FrmAppHelper::get_settings();
703
+
704
+ if ( $frm_settings->use_html ) {
705
+ $format = FrmEntryValidate::phone_format( $field );
706
+ $format = substr( $format, 2, -1 );
707
+ $add_html['pattern'] = 'pattern="' . esc_attr( $format ) . '"';
708
+ }
709
+ }
710
+ }
711
+
712
  public static function check_value( $opt, $opt_key, $field ) {
713
  if ( is_array( $opt ) ) {
714
  if ( FrmField::is_option_true( $field, 'separate_value' ) ) {
classes/controllers/FrmFormsController.php CHANGED
@@ -18,10 +18,10 @@ class FrmFormsController {
18
  return;
19
  }
20
 
21
- add_filter('get_user_option_managetoplevel_page_formidablecolumnshidden', 'FrmFormsController::hidden_columns' );
22
 
23
- add_filter('manage_toplevel_page_formidable_columns', 'FrmFormsController::get_columns', 0 );
24
- add_filter('manage_toplevel_page_formidable_sortable_columns', 'FrmFormsController::get_sortable_columns' );
25
  }
26
 
27
  public static function head() {
@@ -117,7 +117,8 @@ class FrmFormsController {
117
  $form = FrmForm::getOne( $id );
118
  $fields = FrmField::get_all_for_form($id);
119
 
120
- $values = FrmAppHelper::setup_edit_vars($form, 'forms', $fields, true);
 
121
  $all_templates = FrmForm::getAll( array( 'is_template' => 1 ), 'name' );
122
 
123
  require( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/new.php' );
@@ -163,18 +164,21 @@ class FrmFormsController {
163
  }
164
 
165
  public static function edit_key() {
 
166
  $values = self::edit_in_place_value( 'form_key' );
167
- echo wp_kses( stripslashes( FrmForm::getKeyById( $values['form_id'] ) ), array() );
168
  wp_die();
169
  }
170
 
171
  public static function edit_description() {
 
172
  $values = self::edit_in_place_value( 'description' );
173
  echo wp_kses_post( FrmAppHelper::use_wpautop( stripslashes( $values['description'] ) ) );
174
  wp_die();
175
  }
176
 
177
  private static function edit_in_place_value( $field ) {
 
178
  check_ajax_referer( 'frm_ajax', 'nonce' );
179
  FrmAppHelper::permission_check('frm_edit_forms', 'hide');
180
 
@@ -218,16 +222,6 @@ class FrmFormsController {
218
  }
219
  }
220
 
221
- public static function bulk_create_template( $ids ) {
222
- FrmAppHelper::permission_check( 'frm_edit_forms' );
223
-
224
- foreach ( $ids as $id ) {
225
- FrmForm::duplicate( $id, true, true );
226
- }
227
-
228
- return __( 'Form template was Successfully Created', 'formidable' );
229
- }
230
-
231
  /**
232
  * Redirect to the url for creating from a template
233
  * Also delete the current form
@@ -244,7 +238,7 @@ class FrmFormsController {
244
  FrmForm::destroy( $current_form );
245
  }
246
 
247
- echo esc_url_raw( admin_url( 'admin.php?page=formidable&action=duplicate&id=' . $template_id ) );
248
  wp_die();
249
  }
250
 
@@ -268,26 +262,117 @@ class FrmFormsController {
268
  }
269
 
270
  $form = FrmForm::getOne( $params['form'] );
271
- if ( ! $form ) {
272
- return;
273
- }
274
- return self::show_form( $form->id, '', true, true );
275
  }
276
 
 
 
 
 
 
 
 
277
  public static function preview() {
278
  do_action( 'frm_wp' );
279
 
280
  global $frm_vars;
281
  $frm_vars['preview'] = true;
282
 
283
- if ( ! defined( 'ABSPATH' ) && ! defined( 'XMLRPC_REQUEST' ) ) {
284
- global $wp;
285
- $root = dirname( dirname( dirname( dirname( __FILE__ ) ) ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
286
  include_once( $root . '/wp-config.php' );
287
- $wp->init();
288
- $wp->register_globals();
289
- }
 
290
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
291
  header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) );
292
 
293
  $key = FrmAppHelper::simple_get( 'form', 'sanitize_title' );
@@ -298,11 +383,10 @@ class FrmFormsController {
298
  $form = FrmForm::getAll( array( 'form_key' => $key ), '', 1 );
299
  if ( empty( $form ) ) {
300
  $form = FrmForm::getAll( array(), '', 1 );
301
- }
302
 
303
  require( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/direct.php' );
304
- wp_die();
305
- }
306
 
307
  public static function register_pro_scripts() {
308
  _deprecated_function( __FUNCTION__, '2.03', 'FrmProEntriesController::register_scripts' );
@@ -441,11 +525,6 @@ class FrmFormsController {
441
  self::display_forms_list( array(), $message );
442
  }
443
 
444
- public static function scheduled_delete( $delete_timestamp = '' ) {
445
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmForm::scheduled_delete' );
446
- return FrmForm::scheduled_delete( $delete_timestamp );
447
- }
448
-
449
  /**
450
  * Inserts Formidable button
451
  * Hook exists since 2.5.0
@@ -530,12 +609,8 @@ class FrmFormsController {
530
  wp_die();
531
  }
532
 
533
- public static function display_forms_list( $params = array(), $message = '', $errors = array(), $deprecated_errors = array() ) {
534
  FrmAppHelper::permission_check( 'frm_view_forms' );
535
- if ( ! empty( $deprecated_errors ) ) {
536
- $errors = $deprecated_errors;
537
- _deprecated_argument( 'errors', '2.0.8' );
538
- }
539
 
540
  global $wpdb, $frm_vars;
541
 
@@ -647,7 +722,8 @@ class FrmFormsController {
647
  unset($end_section_values, $last_order, $open, $reset_fields);
648
 
649
  $args = array( 'parent_form_id' => $form->id );
650
- $values = FrmAppHelper::setup_edit_vars( $form, 'forms', $fields, true, array(), $args );
 
651
 
652
  $edit_message = __( 'Form was Successfully Updated', 'formidable' );
653
  if ( $form->is_template && $message == $edit_message ) {
@@ -690,6 +766,8 @@ class FrmFormsController {
690
 
691
  $styles = apply_filters('frm_get_style_opts', array());
692
 
 
 
693
  require( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/settings.php' );
694
  }
695
 
@@ -769,12 +847,6 @@ class FrmFormsController {
769
  $entry_shortcodes['default-message'] = __( 'Default Msg', 'formidable' );
770
  $entry_shortcodes['default-html'] = __( 'Default HTML', 'formidable' );
771
  $entry_shortcodes['default-plain'] = __( 'Default Plain', 'formidable' );
772
- } else {
773
- $entry_shortcodes['detaillink'] = __( 'Detail Link', 'formidable' );
774
- $entry_shortcodes['editlink location="front" label="Edit" page_id=x'] = __( 'Edit Entry Link', 'formidable' );
775
- $entry_shortcodes['evenodd'] = __( 'Even/Odd', 'formidable' );
776
- $entry_shortcodes['entry_count'] = __( 'Entry Count', 'formidable' );
777
- $entry_shortcodes['event_date format="Y-m-d"'] = __( 'Calendar Date', 'formidable' );
778
  }
779
 
780
  /**
@@ -787,22 +859,29 @@ class FrmFormsController {
787
  return $entry_shortcodes;
788
  }
789
 
790
- // Insert the form class setting into the form
 
 
791
  public static function form_classes( $form ) {
792
- if ( isset($form->options['form_class']) ) {
793
  echo esc_attr( sanitize_text_field( $form->options['form_class'] ) );
794
- }
795
- }
 
 
 
 
 
 
 
 
796
 
797
- public static function get_email_html() {
798
- FrmAppHelper::permission_check('frm_view_forms');
799
- check_ajax_referer( 'frm_ajax', 'nonce' );
800
  echo FrmEntriesController::show_entry_shortcode( array(
801
  'form_id' => FrmAppHelper::get_post_param( 'form_id', '', 'absint' ),
802
- 'default_email' => true,
803
  'plain_text' => FrmAppHelper::get_post_param( 'plain_text', '', 'absint' ),
804
- ) );
805
- wp_die();
806
  }
807
 
808
  public static function filter_content( $content, $form, $entry = false ) {
@@ -876,13 +955,10 @@ class FrmFormsController {
876
  break;
877
  case 'untrash':
878
  $message = self::bulk_untrash( $ids );
879
- break;
880
- case 'create_template':
881
- $message = self::bulk_create_template( $ids );
882
  }
883
 
884
  if ( isset( $message ) && ! empty( $message ) ) {
885
- echo '<div id="message" class="updated frm_msg_padding">' . FrmAppHelper::kses( $message, array( 'a' ) ) . '</div>';
886
  }
887
 
888
  return $errors;
@@ -1171,6 +1247,8 @@ class FrmFormsController {
1171
  public static function get_form( $form, $title, $description, $atts = array() ) {
1172
  ob_start();
1173
 
 
 
1174
  self::get_form_contents( $form, $title, $description, $atts );
1175
  self::enqueue_scripts( FrmForm::get_params( $form ) );
1176
 
@@ -1209,18 +1287,15 @@ class FrmFormsController {
1209
 
1210
  if ( apply_filters( 'frm_continue_to_create', true, $form->id ) ) {
1211
  $entry_id = self::just_created_entry( $form->id );
 
 
 
 
 
1212
 
1213
- $conf_method = apply_filters( 'frm_success_filter', 'message', $form, 'create' );
1214
- if ( $entry_id && is_numeric( $entry_id ) && $conf_method != 'message' ) {
1215
- self::run_success_action( compact( 'entry_id', 'form', 'conf_method' ) );
1216
- } else {
1217
- $pass_args['reset'] = true;
1218
- $pass_args['entry_id'] = $entry_id;
1219
- self::show_message_after_save( $pass_args );
1220
- }
1221
  do_action( 'frm_after_entry_processed', array(
1222
  'entry_id' => $entry_id,
1223
- 'form' => $form,
1224
  ) );
1225
  }
1226
  }
@@ -1249,12 +1324,143 @@ class FrmFormsController {
1249
  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;
1250
  }
1251
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1252
  /**
1253
  * Used when the success action is not 'message'
1254
  * @since 2.05
1255
  */
1256
  public static function run_success_action( $args ) {
1257
- do_action( 'frm_success_action', $args['conf_method'], $args['form'], $args['form']->options, $args['entry_id'] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1258
  }
1259
 
1260
  /**
@@ -1354,9 +1560,14 @@ class FrmFormsController {
1354
 
1355
  public static function front_head() {
1356
  $version = FrmAppHelper::plugin_version();
1357
- $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
1358
- wp_register_script( 'formidable', FrmAppHelper::plugin_url() . "/js/formidable{$suffix}.js", array( 'jquery' ), $version, true );
1359
- wp_register_script( 'jquery-placeholder', FrmAppHelper::plugin_url() . '/js/jquery/jquery.placeholder.min.js', array( 'jquery' ), '2.3.1', true );
 
 
 
 
 
1360
  add_filter( 'script_loader_tag', 'FrmFormsController::defer_script_loading', 10, 2 );
1361
 
1362
  if ( FrmAppHelper::is_admin() ) {
@@ -1368,6 +1579,13 @@ class FrmFormsController {
1368
  FrmStylesController::enqueue_css( 'register' );
1369
  }
1370
 
 
 
 
 
 
 
 
1371
  public static function maybe_load_css( $form, $this_load, $global_load ) {
1372
  $load_css = FrmForm::is_form_loaded( $form, $this_load, $global_load );
1373
 
@@ -1413,4 +1631,15 @@ class FrmFormsController {
1413
  private static function is_minification_on( $atts ) {
1414
  return isset( $atts['minimize'] ) && ! empty( $atts['minimize'] );
1415
  }
 
 
 
 
 
 
 
 
 
 
 
1416
  }
18
  return;
19
  }
20
 
21
+ add_filter( 'get_user_option_managetoplevel_page_formidablecolumnshidden', 'FrmFormsController::hidden_columns' );
22
 
23
+ add_filter( 'manage_toplevel_page_formidable_columns', 'FrmFormsController::get_columns', 0 );
24
+ add_filter( 'manage_toplevel_page_formidable_sortable_columns', 'FrmFormsController::get_sortable_columns' );
25
  }
26
 
27
  public static function head() {
117
  $form = FrmForm::getOne( $id );
118
  $fields = FrmField::get_all_for_form($id);
119
 
120
+ $values = FrmAppHelper::setup_edit_vars($form, 'forms', '', true);
121
+ $values['fields'] = $fields;
122
  $all_templates = FrmForm::getAll( array( 'is_template' => 1 ), 'name' );
123
 
124
  require( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/new.php' );
164
  }
165
 
166
  public static function edit_key() {
167
+ _deprecated_function( __METHOD__, '3.0' );
168
  $values = self::edit_in_place_value( 'form_key' );
169
+ echo wp_kses( stripslashes( FrmForm::get_key_by_id( $values['form_id'] ) ), array() );
170
  wp_die();
171
  }
172
 
173
  public static function edit_description() {
174
+ _deprecated_function( __METHOD__, '3.0' );
175
  $values = self::edit_in_place_value( 'description' );
176
  echo wp_kses_post( FrmAppHelper::use_wpautop( stripslashes( $values['description'] ) ) );
177
  wp_die();
178
  }
179
 
180
  private static function edit_in_place_value( $field ) {
181
+ _deprecated_function( __METHOD__, '3.0' );
182
  check_ajax_referer( 'frm_ajax', 'nonce' );
183
  FrmAppHelper::permission_check('frm_edit_forms', 'hide');
184
 
222
  }
223
  }
224
 
 
 
 
 
 
 
 
 
 
 
225
  /**
226
  * Redirect to the url for creating from a template
227
  * Also delete the current form
238
  FrmForm::destroy( $current_form );
239
  }
240
 
241
+ echo esc_url_raw( admin_url( 'admin.php?page=formidable&frm_action=duplicate&id=' . absint( $template_id ) ) );
242
  wp_die();
243
  }
244
 
262
  }
263
 
264
  $form = FrmForm::getOne( $params['form'] );
265
+ if ( $form ) {
266
+ return self::show_form( $form->id, '', true, true );
267
+ }
 
268
  }
269
 
270
+ /**
271
+ * @since 3.0
272
+ */
273
+ public static function show_page_preview() {
274
+ echo self::page_preview();
275
+ }
276
+
277
  public static function preview() {
278
  do_action( 'frm_wp' );
279
 
280
  global $frm_vars;
281
  $frm_vars['preview'] = true;
282
 
283
+ self::load_wp();
284
+
285
+ $include_theme = FrmAppHelper::get_param( 'theme', '', 'get', 'absint' );
286
+ if ( $include_theme ) {
287
+ self::set_preview_query();
288
+ self::load_theme_preview();
289
+ } else {
290
+ self::load_direct_preview();
291
+ }
292
+
293
+ wp_die();
294
+ }
295
+
296
+ /**
297
+ * @since 3.0
298
+ */
299
+ private static function load_wp() {
300
+ if ( ! defined( 'ABSPATH' ) && ! defined( 'XMLRPC_REQUEST' ) ) {
301
+ global $wp;
302
+ $root = dirname( dirname( dirname( dirname( __FILE__ ) ) ) );
303
  include_once( $root . '/wp-config.php' );
304
+ $wp->init();
305
+ $wp->register_globals();
306
+ }
307
+ }
308
 
309
+ private static function set_preview_query() {
310
+ $random_page = get_posts( array(
311
+ 'numberposts' => 1,
312
+ 'orderby' => 'date',
313
+ 'order' => 'ASC',
314
+ 'post_type' => 'page',
315
+ ) );
316
+
317
+ if ( ! empty( $random_page ) ) {
318
+ $random_page = reset( $random_page );
319
+ query_posts( array(
320
+ 'post_type' => 'page',
321
+ 'page_id' => $random_page->ID,
322
+ ) );
323
+ }
324
+ }
325
+
326
+ /**
327
+ * @since 3.0
328
+ */
329
+ private static function load_theme_preview() {
330
+ add_filter( 'wp_title', 'FrmFormsController::preview_title', 9999 );
331
+ add_filter( 'the_title', 'FrmFormsController::preview_page_title', 9999 );
332
+ add_filter( 'the_content', 'FrmFormsController::preview_content', 9999 );
333
+ add_action( 'loop_no_results', 'FrmFormsController::show_page_preview' );
334
+ add_filter( 'is_active_sidebar', '__return_false' );
335
+ get_template_part( 'page' );
336
+ }
337
+
338
+
339
+ /**
340
+ * Set the page title for the theme preview page
341
+ *
342
+ * @since 3.0
343
+ */
344
+ public static function preview_page_title( $title ) {
345
+ if ( in_the_loop() ) {
346
+ $title = self::preview_title( $title );
347
+ }
348
+ return $title;
349
+ }
350
+
351
+ /**
352
+ * Set the page title for the theme preview page
353
+ *
354
+ * @since 3.0
355
+ */
356
+ public static function preview_title( $title ) {
357
+ return __( 'Form Preview', 'formidable' );
358
+ }
359
+
360
+ /**
361
+ * Set the page content for the theme preview page
362
+ *
363
+ * @since 3.0
364
+ */
365
+ public static function preview_content( $content ) {
366
+ if ( in_the_loop() ) {
367
+ $content = FrmFormsController::show_page_preview();
368
+ }
369
+ return $content;
370
+ }
371
+
372
+ /**
373
+ * @since 3.0
374
+ */
375
+ private static function load_direct_preview() {
376
  header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) );
377
 
378
  $key = FrmAppHelper::simple_get( 'form', 'sanitize_title' );
383
  $form = FrmForm::getAll( array( 'form_key' => $key ), '', 1 );
384
  if ( empty( $form ) ) {
385
  $form = FrmForm::getAll( array(), '', 1 );
386
+ }
387
 
388
  require( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/direct.php' );
389
+ }
 
390
 
391
  public static function register_pro_scripts() {
392
  _deprecated_function( __FUNCTION__, '2.03', 'FrmProEntriesController::register_scripts' );
525
  self::display_forms_list( array(), $message );
526
  }
527
 
 
 
 
 
 
528
  /**
529
  * Inserts Formidable button
530
  * Hook exists since 2.5.0
609
  wp_die();
610
  }
611
 
612
+ public static function display_forms_list( $params = array(), $message = '', $errors = array() ) {
613
  FrmAppHelper::permission_check( 'frm_view_forms' );
 
 
 
 
614
 
615
  global $wpdb, $frm_vars;
616
 
722
  unset($end_section_values, $last_order, $open, $reset_fields);
723
 
724
  $args = array( 'parent_form_id' => $form->id );
725
+ $values = FrmAppHelper::setup_edit_vars( $form, 'forms', '', true, array(), $args );
726
+ $values['fields'] = $fields;
727
 
728
  $edit_message = __( 'Form was Successfully Updated', 'formidable' );
729
  if ( $form->is_template && $message == $edit_message ) {
766
 
767
  $styles = apply_filters('frm_get_style_opts', array());
768
 
769
+ $first_h3 = 'frm_first_h3';
770
+
771
  require( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/settings.php' );
772
  }
773
 
847
  $entry_shortcodes['default-message'] = __( 'Default Msg', 'formidable' );
848
  $entry_shortcodes['default-html'] = __( 'Default HTML', 'formidable' );
849
  $entry_shortcodes['default-plain'] = __( 'Default Plain', 'formidable' );
 
 
 
 
 
 
850
  }
851
 
852
  /**
859
  return $entry_shortcodes;
860
  }
861
 
862
+ /**
863
+ * Insert the form class setting into the form
864
+ */
865
  public static function form_classes( $form ) {
866
+ if ( isset($form->options['form_class']) ) {
867
  echo esc_attr( sanitize_text_field( $form->options['form_class'] ) );
868
+ }
869
+
870
+ if ( isset( $form->options['js_validate'] ) && $form->options['js_validate'] ) {
871
+ echo ' frm_js_validate ';
872
+ }
873
+ }
874
+
875
+ public static function get_email_html() {
876
+ FrmAppHelper::permission_check( 'frm_view_forms' );
877
+ check_ajax_referer( 'frm_ajax', 'nonce' );
878
 
 
 
 
879
  echo FrmEntriesController::show_entry_shortcode( array(
880
  'form_id' => FrmAppHelper::get_post_param( 'form_id', '', 'absint' ),
881
+ 'default_email' => true,
882
  'plain_text' => FrmAppHelper::get_post_param( 'plain_text', '', 'absint' ),
883
+ ) );
884
+ wp_die();
885
  }
886
 
887
  public static function filter_content( $content, $form, $entry = false ) {
955
  break;
956
  case 'untrash':
957
  $message = self::bulk_untrash( $ids );
 
 
 
958
  }
959
 
960
  if ( isset( $message ) && ! empty( $message ) ) {
961
+ echo '<div id="message" class="updated frm_updated_message">' . FrmAppHelper::kses( $message, array( 'a' ) ) . '</div>';
962
  }
963
 
964
  return $errors;
1247
  public static function get_form( $form, $title, $description, $atts = array() ) {
1248
  ob_start();
1249
 
1250
+ do_action( 'frm_before_get_form', $atts );
1251
+
1252
  self::get_form_contents( $form, $title, $description, $atts );
1253
  self::enqueue_scripts( FrmForm::get_params( $form ) );
1254
 
1287
 
1288
  if ( apply_filters( 'frm_continue_to_create', true, $form->id ) ) {
1289
  $entry_id = self::just_created_entry( $form->id );
1290
+ $pass_args['entry_id'] = $entry_id;
1291
+ $pass_args['reset'] = true;
1292
+ $pass_args['conf_method'] = self::get_confirmation_method( compact( 'form', 'entry_id' ) );
1293
+
1294
+ self::run_success_action( $pass_args );
1295
 
 
 
 
 
 
 
 
 
1296
  do_action( 'frm_after_entry_processed', array(
1297
  'entry_id' => $entry_id,
1298
+ 'form' => $form,
1299
  ) );
1300
  }
1301
  }
1324
  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;
1325
  }
1326
 
1327
+ /**
1328
+ * @since 3.0
1329
+ */
1330
+ private static function get_confirmation_method( $atts ) {
1331
+ $opt = 'success_action';
1332
+ $method = ( isset( $atts['form']->options[ $opt ] ) && ! empty( $atts['form']->options[ $opt ] ) ) ? $atts['form']->options[ $opt ] : 'message';
1333
+ $method = apply_filters( 'frm_success_filter', $method, $atts['form'], 'create' );
1334
+
1335
+ if ( $method != 'message' && ( ! $atts['entry_id'] || ! is_numeric( $atts['entry_id'] ) ) ) {
1336
+ $method = 'message';
1337
+ }
1338
+
1339
+ return $method;
1340
+ }
1341
+
1342
+ public static function maybe_trigger_redirect( $form, $params, $args ) {
1343
+ if ( ! isset( $params['id'] ) ) {
1344
+ global $frm_vars;
1345
+ $params['id'] = $frm_vars['created_entries'][ $form->id ]['entry_id'];
1346
+ }
1347
+
1348
+ $conf_method = self::get_confirmation_method( array(
1349
+ 'form' => $form,
1350
+ 'entry_id' => $params['id'],
1351
+ ) );
1352
+
1353
+ if ( 'redirect' === $conf_method ) {
1354
+ self::trigger_redirect( $form, $params, $args );
1355
+ }
1356
+ }
1357
+
1358
+ public static function trigger_redirect( $form, $params, $args ) {
1359
+ $success_args = array(
1360
+ 'action' => $params['action'],
1361
+ 'conf_method' => 'redirect',
1362
+ 'form' => $form,
1363
+ 'entry_id' => $params['id'],
1364
+ );
1365
+
1366
+ if ( isset( $args['ajax'] ) ) {
1367
+ $success_args['ajax'] = $args['ajax'];
1368
+ }
1369
+
1370
+ self::run_success_action( $success_args );
1371
+ }
1372
+
1373
  /**
1374
  * Used when the success action is not 'message'
1375
  * @since 2.05
1376
  */
1377
  public static function run_success_action( $args ) {
1378
+ $extra_args = $args;
1379
+ unset( $extra_args['form'] );
1380
+
1381
+ do_action( 'frm_success_action', $args['conf_method'], $args['form'], $args['form']->options, $args['entry_id'], $extra_args );
1382
+
1383
+ $opt = ( ! isset( $args['action'] ) || $args['action'] == 'create' ) ? 'success' : 'edit';
1384
+ $args['success_opt'] = $opt;
1385
+ if ( $args['conf_method'] == 'page' && is_numeric( $args['form']->options[ $opt . '_page_id' ] ) ) {
1386
+ self::load_page_after_submit( $args );
1387
+ } elseif ( $args['conf_method'] == 'redirect' ) {
1388
+ self::redirect_after_submit( $args );
1389
+ } else {
1390
+ self::show_message_after_save( $args );
1391
+ }
1392
+ }
1393
+
1394
+ /**
1395
+ * @since 3.0
1396
+ */
1397
+ private static function load_page_after_submit( $args ) {
1398
+ global $post;
1399
+ $opt = $args['success_opt'];
1400
+ if ( ! $post || $args['form']->options[ $opt . '_page_id' ] != $post->ID ) {
1401
+ $page = get_post( $args['form']->options[ $opt . '_page_id' ] );
1402
+ $old_post = $post;
1403
+ $post = $page;
1404
+ $content = apply_filters( 'frm_content', $page->post_content, $args['form'], $args['entry_id'] );
1405
+ echo apply_filters( 'the_content', $content );
1406
+ $post = $old_post;
1407
+ }
1408
+ }
1409
+
1410
+ /**
1411
+ * @since 3.0
1412
+ */
1413
+ private static function redirect_after_submit( $args ) {
1414
+ global $frm_vars;
1415
+
1416
+ add_filter( 'frm_use_wpautop', '__return_false' );
1417
+
1418
+ $opt = $args['success_opt'];
1419
+ $success_url = trim( $args['form']->options[ $opt . '_url' ] );
1420
+ $success_url = apply_filters( 'frm_content', $success_url, $args['form'], $args['entry_id'] );
1421
+
1422
+ $success_msg = isset( $args['form']->options[ $opt . '_msg' ] ) ? $args['form']->options[ $opt . '_msg' ] : __( 'Please wait while you are redirected.', 'formidable' );
1423
+
1424
+ $redirect_msg = self::get_redirect_message( $success_url, $success_msg, $args );
1425
+
1426
+ $args['id'] = $args['entry_id'];
1427
+ FrmEntriesController::delete_entry_before_redirect( $success_url, $args['form'], $args );
1428
+
1429
+ add_filter( 'frm_redirect_url', 'FrmEntriesController::prepare_redirect_url' );
1430
+ $success_url = apply_filters( 'frm_redirect_url', $success_url, $args['form'], $args);
1431
+
1432
+ $doing_ajax = FrmAppHelper::doing_ajax();
1433
+
1434
+ if ( isset( $args['ajax'] ) && $args['ajax'] && $doing_ajax ) {
1435
+ echo json_encode( array( 'redirect' => $success_url ) );
1436
+ wp_die();
1437
+ } elseif ( ! headers_sent() ) {
1438
+ wp_redirect( esc_url_raw( $success_url ) );
1439
+ die(); // do not use wp_die or redirect fails
1440
+ } else {
1441
+ add_filter( 'frm_use_wpautop', '__return_true' );
1442
+
1443
+ echo $redirect_msg;
1444
+ echo "<script type='text/javascript'>window.onload = function(){setTimeout(window.location='" . esc_url_raw( $success_url ) . "', 8000);}</script>";
1445
+ }
1446
+ }
1447
+
1448
+ /**
1449
+ * @since 3.0
1450
+ * @param string $success_url
1451
+ * @param string $success_msg
1452
+ * @param array $args
1453
+ */
1454
+ private static function get_redirect_message( $success_url, $success_msg, $args ) {
1455
+ $redirect_msg = '<div class="' . esc_attr( FrmFormsHelper::get_form_style_class( $args['form'] ) ) . '"><div class="frm-redirect-msg frm_message">' . $success_msg . '<br/>' .
1456
+ sprintf( __( '%1$sClick here%2$s if you are not automatically redirected.', 'formidable' ), '<a href="' . esc_url( $success_url ) . '">', '</a>') .
1457
+ '</div></div>';
1458
+
1459
+ return apply_filters( 'frm_redirect_msg', $redirect_msg, array(
1460
+ 'entry_id' => $args['entry_id'],
1461
+ 'form_id' => $args['form']->id,
1462
+ 'form' => $args['form'],
1463
+ ) );
1464
  }
1465
 
1466
  /**
1560
 
1561
  public static function front_head() {
1562
  $version = FrmAppHelper::plugin_version();
1563
+ $suffix = FrmAppHelper::js_suffix();
1564
+
1565
+ if ( ! empty( $suffix ) && self::has_combo_js_file() ) {
1566
+ wp_register_script( 'formidable', FrmAppHelper::plugin_url() . '/js/frm.min.js', array( 'jquery' ), $version, true );
1567
+ } else {
1568
+ wp_register_script( 'formidable', FrmAppHelper::plugin_url() . "/js/formidable{$suffix}.js", array( 'jquery' ), $version, true );
1569
+ }
1570
+
1571
  add_filter( 'script_loader_tag', 'FrmFormsController::defer_script_loading', 10, 2 );
1572
 
1573
  if ( FrmAppHelper::is_admin() ) {
1579
  FrmStylesController::enqueue_css( 'register' );
1580
  }
1581
 
1582
+ /**
1583
+ * @since 3.0
1584
+ */
1585
+ public static function has_combo_js_file() {
1586
+ return is_readable( FrmAppHelper::plugin_path() . '/js/frm.min.js' );
1587
+ }
1588
+
1589
  public static function maybe_load_css( $form, $this_load, $global_load ) {
1590
  $load_css = FrmForm::is_form_loaded( $form, $this_load, $global_load );
1591
 
1631
  private static function is_minification_on( $atts ) {
1632
  return isset( $atts['minimize'] ) && ! empty( $atts['minimize'] );
1633
  }
1634
+
1635
+ public static function bulk_create_template( $ids ) {
1636
+ _deprecated_function( __METHOD__, '3.0', 'FrmForm::duplicate( $id, true, true )' );
1637
+ FrmAppHelper::permission_check( 'frm_edit_forms' );
1638
+
1639
+ foreach ( $ids as $id ) {
1640
+ FrmForm::duplicate( $id, true, true );
1641
+ }
1642
+
1643
+ return __( 'Form template was Successfully Created', 'formidable' );
1644
+ }
1645
  }
classes/controllers/FrmHooksController.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
 
3
  class FrmHooksController {
 
4
  /**
5
  * Trigger plugin-wide hook loading
6
  */
@@ -44,16 +45,12 @@ class FrmHooksController {
44
  }
45
 
46
  public static function load_hooks() {
47
- if ( ! is_admin() ) {
48
- add_filter( 'the_content', 'FrmAppController::page_route', 10 );
49
- }
50
-
51
  add_action( 'plugins_loaded', 'FrmAppController::load_lang' );
52
  add_filter( 'widget_text', 'do_shortcode' );
53
 
54
  // Entries controller
55
  add_action( 'wp_loaded', 'FrmEntriesController::process_entry', 10, 0 );
56
- add_filter( 'frm_redirect_url', 'FrmEntriesController::delete_entry_before_redirect', 50, 3 );
57
  add_action( 'frm_after_entry_processed', 'FrmEntriesController::delete_entry_after_save', 100 );
58
 
59
  // Form Actions Controller
@@ -82,11 +79,13 @@ class FrmHooksController {
82
 
83
  public static function load_admin_hooks() {
84
  add_action( 'admin_menu', 'FrmAppController::menu', 1 );
 
85
  add_action( 'admin_enqueue_scripts', 'FrmAppController::load_wp_admin_style' );
86
  add_action( 'admin_notices', 'FrmAppController::pro_get_started_headline' );
87
  add_action( 'admin_init', 'FrmAppController::admin_init', 11 );
88
  add_filter( 'plugin_action_links_' . FrmAppHelper::plugin_folder() . '/formidable.php', 'FrmAppController::settings_link' );
89
  register_activation_hook( FrmAppHelper::plugin_folder() . '/formidable.php', 'FrmAppController::activation_install' );
 
90
 
91
  // Addons Controller
92
  add_action( 'admin_menu', 'FrmAddonsController::menu', 100 );
@@ -99,9 +98,6 @@ class FrmHooksController {
99
  add_filter( 'update_user_metadata', 'FrmEntriesController::check_hidden_cols', 10, 5 );
100
  add_action( 'updated_user_meta', 'FrmEntriesController::update_hidden_cols', 10, 4 );
101
 
102
- // Fields Controller
103
- add_filter( 'frm_display_field_options', 'FrmFieldsController::display_field_options' );
104
-
105
  // Form Actions Controller
106
  if ( FrmAppHelper::is_admin_page( 'formidable' ) ) {
107
  add_action( 'frm_before_update_form_settings', 'FrmFormActionsController::update_settings' );
@@ -133,8 +129,6 @@ class FrmHooksController {
133
  }
134
 
135
  public static function load_ajax_hooks() {
136
- add_action( 'wp_ajax_frm_silent_upgrade', 'FrmAppController::ajax_install' );
137
- add_action( 'wp_ajax_nopriv_frm_silent_upgrade', 'FrmAppController::ajax_install' );
138
  add_action( 'wp_ajax_frm_install', 'FrmAppController::ajax_install' );
139
  add_action( 'wp_ajax_frm_uninstall', 'FrmAppController::uninstall' );
140
  add_action( 'wp_ajax_frm_deauthorize', 'FrmAppController::deauthorize' );
@@ -147,7 +141,6 @@ class FrmHooksController {
147
  // Fields Controller
148
  add_action( 'wp_ajax_frm_load_field', 'FrmFieldsController::load_field' );
149
  add_action( 'wp_ajax_frm_insert_field', 'FrmFieldsController::create' );
150
- add_action( 'wp_ajax_frm_field_name_in_place_edit', 'FrmFieldsController::edit_name' );
151
  add_action( 'wp_ajax_frm_update_ajax_option', 'FrmFieldsController::update_ajax_option' );
152
  add_action( 'wp_ajax_frm_duplicate_field', 'FrmFieldsController::duplicate' );
153
  add_action( 'wp_ajax_frm_delete_field', 'FrmFieldsController::destroy' );
@@ -163,8 +156,6 @@ class FrmHooksController {
163
  // Forms Controller
164
  add_action( 'wp_ajax_frm_create_from_template', 'FrmFormsController::_create_from_template' );
165
  add_action( 'wp_ajax_frm_save_form', 'FrmFormsController::route' );
166
- add_action( 'wp_ajax_frm_form_key_in_place_edit', 'FrmFormsController::edit_key' );
167
- add_action( 'wp_ajax_frm_form_desc_in_place_edit', 'FrmFormsController::edit_description' );
168
  add_action( 'wp_ajax_frm_get_default_html', 'FrmFormsController::get_email_html' );
169
  add_action( 'wp_ajax_frm_get_shortcode_opts', 'FrmFormsController::get_shortcode_opts' );
170
  add_action( 'wp_ajax_frm_forms_preview', 'FrmFormsController::preview' );
1
  <?php
2
 
3
  class FrmHooksController {
4
+
5
  /**
6
  * Trigger plugin-wide hook loading
7
  */
45
  }
46
 
47
  public static function load_hooks() {
48
+ add_action( 'rest_api_init', 'FrmAppController::create_rest_routes', 0 );
 
 
 
49
  add_action( 'plugins_loaded', 'FrmAppController::load_lang' );
50
  add_filter( 'widget_text', 'do_shortcode' );
51
 
52
  // Entries controller
53
  add_action( 'wp_loaded', 'FrmEntriesController::process_entry', 10, 0 );
 
54
  add_action( 'frm_after_entry_processed', 'FrmEntriesController::delete_entry_after_save', 100 );
55
 
56
  // Form Actions Controller
79
 
80
  public static function load_admin_hooks() {
81
  add_action( 'admin_menu', 'FrmAppController::menu', 1 );
82
+ add_filter( 'admin_body_class', 'FrmAppController::add_admin_class', 999 );
83
  add_action( 'admin_enqueue_scripts', 'FrmAppController::load_wp_admin_style' );
84
  add_action( 'admin_notices', 'FrmAppController::pro_get_started_headline' );
85
  add_action( 'admin_init', 'FrmAppController::admin_init', 11 );
86
  add_filter( 'plugin_action_links_' . FrmAppHelper::plugin_folder() . '/formidable.php', 'FrmAppController::settings_link' );
87
  register_activation_hook( FrmAppHelper::plugin_folder() . '/formidable.php', 'FrmAppController::activation_install' );
88
+ add_filter( 'admin_footer_text', 'FrmAppController::set_footer_text' );
89
 
90
  // Addons Controller
91
  add_action( 'admin_menu', 'FrmAddonsController::menu', 100 );
98
  add_filter( 'update_user_metadata', 'FrmEntriesController::check_hidden_cols', 10, 5 );
99
  add_action( 'updated_user_meta', 'FrmEntriesController::update_hidden_cols', 10, 4 );
100
 
 
 
 
101
  // Form Actions Controller
102
  if ( FrmAppHelper::is_admin_page( 'formidable' ) ) {
103
  add_action( 'frm_before_update_form_settings', 'FrmFormActionsController::update_settings' );
129
  }
130
 
131
  public static function load_ajax_hooks() {
 
 
132
  add_action( 'wp_ajax_frm_install', 'FrmAppController::ajax_install' );
133
  add_action( 'wp_ajax_frm_uninstall', 'FrmAppController::uninstall' );
134
  add_action( 'wp_ajax_frm_deauthorize', 'FrmAppController::deauthorize' );
141
  // Fields Controller
142
  add_action( 'wp_ajax_frm_load_field', 'FrmFieldsController::load_field' );
143
  add_action( 'wp_ajax_frm_insert_field', 'FrmFieldsController::create' );
 
144
  add_action( 'wp_ajax_frm_update_ajax_option', 'FrmFieldsController::update_ajax_option' );
145
  add_action( 'wp_ajax_frm_duplicate_field', 'FrmFieldsController::duplicate' );
146
  add_action( 'wp_ajax_frm_delete_field', 'FrmFieldsController::destroy' );
156
  // Forms Controller
157
  add_action( 'wp_ajax_frm_create_from_template', 'FrmFormsController::_create_from_template' );
158
  add_action( 'wp_ajax_frm_save_form', 'FrmFormsController::route' );
 
 
159
  add_action( 'wp_ajax_frm_get_default_html', 'FrmFormsController::get_email_html' );
160
  add_action( 'wp_ajax_frm_get_shortcode_opts', 'FrmFormsController::get_shortcode_opts' );
161
  add_action( 'wp_ajax_frm_forms_preview', 'FrmFormsController::preview' );
classes/controllers/FrmStylesController.php CHANGED
@@ -85,9 +85,14 @@ class FrmStylesController {
85
  $css = apply_filters( 'get_frm_stylesheet', self::custom_stylesheet() );
86
 
87
  if ( ! empty( $css ) ) {
 
 
 
 
 
88
  $version = FrmAppHelper::plugin_version();
89
 
90
- foreach ( (array) $css as $css_key => $file ) {
91
  if ( $register_css ) {
92
  $this_version = self::get_css_version( $css_key, $version );
93
  wp_register_style( $css_key, $file, array(), $this_version );
@@ -441,6 +446,7 @@ class FrmStylesController {
441
  $frm_settings = FrmAppHelper::get_settings();
442
  if ( $frm_settings->load_style != 'none' ) {
443
  wp_enqueue_style( 'formidable' );
 
444
  $frm_vars['css_loaded'] = true;
445
  }
446
  }
@@ -478,11 +484,25 @@ class FrmStylesController {
478
 
479
  if ( $style ) {
480
  $class .= ' frm_style_' . $style->post_name;
 
481
  }
482
 
483
  return $class;
484
  }
485
 
 
 
 
 
 
 
 
 
 
 
 
 
 
486
  /**
487
  * @param string $val
488
  */
85
  $css = apply_filters( 'get_frm_stylesheet', self::custom_stylesheet() );
86
 
87
  if ( ! empty( $css ) ) {
88
+ $css = (array) $css;
89
+ if ( $frm_settings->old_css ) {
90
+ $css['frm-old'] = FrmAppHelper::plugin_url() . '/css/frm_old_grids.css';
91
+ }
92
+
93
  $version = FrmAppHelper::plugin_version();
94
 
95
+ foreach ( $css as $css_key => $file ) {
96
  if ( $register_css ) {
97
  $this_version = self::get_css_version( $css_key, $version );
98
  wp_register_style( $css_key, $file, array(), $this_version );
446
  $frm_settings = FrmAppHelper::get_settings();
447
  if ( $frm_settings->load_style != 'none' ) {
448
  wp_enqueue_style( 'formidable' );
449
+ wp_enqueue_style( 'frm-old' );
450
  $frm_vars['css_loaded'] = true;
451
  }
452
  }
484
 
485
  if ( $style ) {
486
  $class .= ' frm_style_' . $style->post_name;
487
+ self::maybe_add_rtl_class( $style, $class );
488
  }
489
 
490
  return $class;
491
  }
492
 
493
+ /**
494
+ * @param object $style
495
+ * @param string $class
496
+ *
497
+ * @since 3.0
498
+ */
499
+ private static function maybe_add_rtl_class( $style, &$class ) {
500
+ $is_rtl = isset( $style->post_content['direction'] ) && 'rtl' === $style->post_content['direction'];
501
+ if ( $is_rtl ) {
502
+ $class .= ' frm_rtl';
503
+ }
504
+ }
505
+
506
  /**
507
  * @param string $val
508
  */
classes/controllers/FrmXMLController.php CHANGED
@@ -118,7 +118,7 @@ class FrmXMLController {
118
  unset( $file_type );
119
 
120
  if ( ! function_exists( 'libxml_disable_entity_loader' ) ) {
121
- $errors[] = __( 'XML import is not enabled on your server.', 'formidable' );
122
  self::form( $errors );
123
  return;
124
  }
@@ -369,36 +369,11 @@ class FrmXMLController {
369
  * @return array $csv_fields
370
  */
371
  private static function get_fields_for_csv_export( $form_id, $form ) {
372
- // Phase frm_csv_field_ids out by 2.01.05
373
- $csv_field_ids = apply_filters( 'frm_csv_field_ids', '', $form_id, array(
374
- 'form' => $form,
375
- ) );
376
-
377
- if ( $csv_field_ids ) {
378
- _deprecated_function( 'The frm_csv_field_ids filter', '2.0.19', 'the frm_csv_columns filter' );
379
- $where = array(
380
- 'fi.type not' => FrmField::no_save_fields(),
381
- array(
382
- 'or' => 1,
383
- 'fi.form_id' => $form->id,
384
- 'fr.parent_form_id' => $form->id,
385
- ),
386
- );
387
-
388
- if ( ! is_array( $csv_field_ids ) ) {
389
- $csv_field_ids = explode( ',', $csv_field_ids );
390
- }
391
- if ( ! empty( $csv_field_ids ) ) {
392
- $where['fi.id'] = $csv_field_ids;
393
- }
394
- $csv_fields = FrmField::getAll( $where, 'field_order' );
395
- } else {
396
- $csv_fields = FrmField::get_all_for_form( $form_id, '', 'include', 'include' );
397
- $no_export_fields = FrmField::no_save_fields();
398
- foreach ( $csv_fields as $k => $f ) {
399
- if ( in_array( $f->type, $no_export_fields, true ) ) {
400
- unset( $csv_fields[ $k ] );
401
- }
402
  }
403
  }
404
 
118
  unset( $file_type );
119
 
120
  if ( ! function_exists( 'libxml_disable_entity_loader' ) ) {
121
+ $errors[] = __( 'XML import is not enabled on your server with the libxml_disable_entity_loader function.', 'formidable' );
122
  self::form( $errors );
123
  return;
124
  }
369
  * @return array $csv_fields
370
  */
371
  private static function get_fields_for_csv_export( $form_id, $form ) {
372
+ $csv_fields = FrmField::get_all_for_form( $form_id, '', 'include', 'include' );
373
+ $no_export_fields = FrmField::no_save_fields();
374
+ foreach ( $csv_fields as $k => $f ) {
375
+ if ( in_array( $f->type, $no_export_fields ) ) {
376
+ unset( $csv_fields[ $k ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
377
  }
378
  }
379
 
classes/factories/FrmFieldFactory.php CHANGED
@@ -28,4 +28,92 @@ class FrmFieldFactory {
28
 
29
  return $selector;
30
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  }
28
 
29
  return $selector;
30
  }
31
+
32
+ /**
33
+ * @since 3.0
34
+ * @param object|array $field
35
+ */
36
+ public static function get_field_factory( $field ) {
37
+ if ( is_object( $field ) ) {
38
+ $field_info = self::get_field_object( $field );
39
+ } elseif ( isset( $field['id'] ) && $field['id'] ) {
40
+ $field_info = self::get_field_object( $field['id'] );
41
+ } else {
42
+ $field_info = self::get_field_type( $field['type'], $field );
43
+ }
44
+ return $field_info;
45
+ }
46
+
47
+ public static function get_field_object( $field ) {
48
+ if ( ! is_object( $field ) ) {
49
+ $field = FrmField::getOne( $field );
50
+ }
51
+ return self::get_field_type( $field->type, $field );
52
+ }
53
+
54
+ /**
55
+ * @since 3.0
56
+ *
57
+ * @param string $field_type
58
+ * @param int|array|object $field
59
+ *
60
+ * @return stdClass
61
+ */
62
+ public static function get_field_type( $field_type, $field = 0 ) {
63
+ $class = self::get_field_type_class( $field_type );
64
+ if ( empty( $class ) ) {
65
+ $field = new FrmFieldDefault( $field, $field_type );
66
+ } else {
67
+ $field = new $class( $field );
68
+ }
69
+
70
+ return $field;
71
+ }
72
+
73
+ /**
74
+ * @since 3.0
75
+ *
76
+ * @param string $field_type
77
+ *
78
+ * @return string
79
+ */
80
+ private static function get_field_type_class( $field_type ) {
81
+ $type_classes = array(
82
+ 'text' => 'FrmFieldText',
83
+ 'textarea' => 'FrmFieldTextarea',
84
+ 'select' => 'FrmFieldSelect',
85
+ 'radio' => 'FrmFieldRadio',
86
+ 'checkbox' => 'FrmFieldCheckbox',
87
+ 'number' => 'FrmFieldNumber',
88
+ 'phone' => 'FrmFieldPhone',
89
+ 'url' => 'FrmFieldUrl',
90
+ 'website' => 'FrmFieldUrl',
91
+ 'email' => 'FrmFieldEmail',
92
+ 'user_id' => 'FrmFieldUserID',
93
+ 'html' => 'FrmFieldHTML',
94
+ 'hidden' => 'FrmFieldHidden',
95
+ 'captcha' => 'FrmFieldCaptcha',
96
+ );
97
+
98
+ $class = isset( $type_classes[ $field_type ] ) ? $type_classes[ $field_type ] : '';
99
+ return apply_filters( 'frm_get_field_type_class', $class, $field_type );
100
+ }
101
+
102
+ /**
103
+ * @since 3.0
104
+ */
105
+ public static function field_has_html( $type ) {
106
+ $has_html = self::field_has_property( $type, 'has_html' );
107
+
108
+ // this hook is here for reverse compatibility since 3.0
109
+ return apply_filters( 'frm_show_custom_html', $has_html, $type );
110
+ }
111
+
112
+ /**
113
+ * @since 3.0
114
+ */
115
+ public static function field_has_property( $type, $property ) {
116
+ $field = self::get_field_type( $type );
117
+ return $field->{$property};
118
+ }
119
  }
classes/helpers/FrmAppHelper.php CHANGED
@@ -4,13 +4,14 @@ if ( ! defined('ABSPATH') ) {
4
  }
5
 
6
  class FrmAppHelper {
7
- public static $db_version = 47; //version of the database we are moving to
8
  public static $pro_db_version = 37; //deprecated
 
9
 
10
  /**
11
  * @since 2.0
12
  */
13
- public static $plug_version = '2.05.09';
14
 
15
  /**
16
  * @since 1.07.02
@@ -99,19 +100,25 @@ class FrmAppHelper {
99
  return ! $frm_settings->no_ips;
100
  }
101
 
102
- /**
103
- * Show a message in place of pro features
104
- *
105
- * @since 2.0
106
- */
107
- public static function update_message() {
108
- _deprecated_function( __FUNCTION__, '2.0.19' );
109
- }
110
-
111
  public static function pro_is_installed() {
112
  return apply_filters('frm_pro_installed', false);
113
  }
114
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  /**
116
  * Check for certain page in Formidable settings
117
  *
@@ -124,7 +131,8 @@ class FrmAppHelper {
124
  global $pagenow;
125
  $get_page = self::simple_get( 'page', 'sanitize_title' );
126
  if ( $pagenow ) {
127
- return $pagenow == 'admin.php' && $get_page == $page;
 
128
  }
129
 
130
  return is_admin() && $get_page == $page;
@@ -156,6 +164,10 @@ class FrmAppHelper {
156
  return self::wp_doing_ajax() && ! self::is_preview_page();
157
  }
158
 
 
 
 
 
159
  /**
160
  * Use the WP 4.7 wp_doing_ajax function
161
  * @sine 2.05.07
@@ -198,7 +210,7 @@ class FrmAppHelper {
198
  * @return boolean
199
  */
200
  public static function is_empty_value( $value, $empty = '' ) {
201
- return ( is_array( $value ) && empty( $value ) ) || $value == $empty;
202
  }
203
 
204
  public static function is_not_empty_value( $value, $empty = '' ) {
@@ -421,6 +433,7 @@ class FrmAppHelper {
421
  'href' => array(),
422
  'id' => array(),
423
  'rel' => array(),
 
424
  'title' => array(),
425
  ),
426
  'abbr' => array(
@@ -455,7 +468,10 @@ class FrmAppHelper {
455
  'h4' => array(),
456
  'h5' => array(),
457
  'h6' => array(),
458
- 'i' => array(),
 
 
 
459
  'img' => array(
460
  'alt' => array(),
461
  'class' => array(),
@@ -530,6 +546,26 @@ class FrmAppHelper {
530
  return $value;
531
  }
532
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
533
  /**
534
  * @param string $type
535
  */
@@ -541,6 +577,26 @@ class FrmAppHelper {
541
  }
542
  }
543
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
544
  /**
545
  * Check a value from a shortcode to see if true or false.
546
  * True when value is 1, true, 'true', 'yes'
@@ -756,51 +812,6 @@ class FrmAppHelper {
756
  return ( is_array( $values ) && in_array( $current, $values ) ) || ( ! is_array( $values ) && $values == $current );
757
  }
758
 
759
- /**
760
- * Check if current field option is an "other" option
761
- *
762
- * @since 2.0
763
- *
764
- * @param string $opt_key
765
- * @return boolean Returns true if current field option is an "Other" option
766
- */
767
- public static function is_other_opt( $opt_key ) {
768
- _deprecated_function( __FUNCTION__, '2.0.6', 'FrmFieldsHelper::is_other_opt' );
769
- return FrmFieldsHelper::is_other_opt( $opt_key );
770
- }
771
-
772
- /**
773
- * Get value that belongs in "Other" text box
774
- *
775
- * @since 2.0
776
- *
777
- * @param string $opt_key
778
- * @param array $field
779
- * @return string $other_val
780
- */
781
- public static function get_other_val( $opt_key, $field, $parent = false, $pointer = false ) {
782
- _deprecated_function( __FUNCTION__, '2.0.6', 'FrmFieldsHelper::get_other_val' );
783
- return FrmFieldsHelper::get_other_val( compact( 'opt_key', 'field', 'parent', 'pointer' ) );
784
- }
785
-
786
- /**
787
- * Check if there is a saved value for the "Other" text field. If so, set it as the $other_val.
788
- * Intended for front-end use
789
- *
790
- * @since 2.0
791
- *
792
- * @param array $field
793
- * @param boolean $other_opt
794
- * @param string $checked
795
- * @param array $args should include opt_key and field name
796
- * @return string $other_val
797
- */
798
- public static function prepare_other_input( $field, &$other_opt, &$checked, $args = array() ) {
799
- _deprecated_function( __FUNCTION__, '2.0.6', 'FrmFieldsHelper::prepare_other_input' );
800
- $args['field'] = $field;
801
- return FrmFieldsHelper::prepare_other_input( $args, $other_opt, $checked );
802
- }
803
-
804
  public static function recursive_function_map( $value, $function ) {
805
  if ( is_array( $value ) ) {
806
  $original_function = $function;
@@ -1018,20 +1029,11 @@ class FrmAppHelper {
1018
  }
1019
 
1020
  $values['description'] = self::use_wpautop($values['description']);
1021
- $frm_settings = self::get_settings();
1022
- $is_form_builder = self::is_admin_page('formidable' );
1023
-
1024
- foreach ( (array) $fields as $field ) {
1025
- // Make sure to filter default values (for placeholder text), but not on the form builder page
1026
- if ( ! $is_form_builder ) {
1027
- $field->default_value = apply_filters('frm_get_default_value', $field->default_value, $field, true );
1028
- }
1029
- $parent_form_id = isset( $args['parent_form_id'] ) ? $args['parent_form_id'] : $field->form_id;
1030
- self::fill_field_defaults($field, $record, $values, compact('default', 'post_values', 'frm_settings', 'parent_form_id' ) );
1031
- }
1032
 
1033
  self::fill_form_opts($record, $table, $post_values, $values);
1034
 
 
 
1035
  if ( $table == 'entries' ) {
1036
  $values = FrmEntriesHelper::setup_edit_vars( $values, $record );
1037
  } else if ( $table == 'forms' ) {
@@ -1041,6 +1043,16 @@ class FrmAppHelper {
1041
  return $values;
1042
  }
1043
 
 
 
 
 
 
 
 
 
 
 
1044
  private static function fill_field_defaults( $field, $record, array &$values, $args ) {
1045
  $post_values = $args['post_values'];
1046
 
@@ -1065,27 +1077,14 @@ class FrmAppHelper {
1065
  $field_type = isset( $post_values['field_options'][ 'type_' . $field->id ] ) ? $post_values['field_options'][ 'type_' . $field->id ] : $field->type;
1066
  $new_value = isset( $post_values['item_meta'][ $field->id ] ) ? maybe_unserialize( $post_values['item_meta'][ $field->id ] ) : $meta_value;
1067
 
1068
- $field_array = array(
1069
- 'id' => $field->id,
1070
- 'value' => $new_value,
1071
- 'default_value' => $field->default_value,
1072
- 'name' => $field->name,
1073
- 'description' => $field->description,
1074
- 'type' => apply_filters('frm_field_type', $field_type, $field, $new_value),
1075
- 'options' => $field->options,
1076
- 'required' => $field->required,
1077
- 'field_key' => $field->field_key,
1078
- 'field_order' => $field->field_order,
1079
- 'form_id' => $field->form_id,
1080
- 'parent_form_id' => $args['parent_form_id'],
1081
- );
1082
 
1083
  $args['field_type'] = $field_type;
1084
- self::fill_field_opts($field, $field_array, $args);
1085
- // Track the original field's type
1086
- $field_array['original_type'] = isset( $field->field_options['original_type'] ) ? $field->field_options['original_type'] : $field->type;
1087
 
1088
- $field_array = apply_filters( 'frm_setup_edit_fields_vars', $field_array, $field, $values['id'], array() );
1089
 
1090
  if ( ! isset($field_array['unique']) || ! $field_array['unique'] ) {
1091
  $field_array['unique_msg'] = '';
@@ -1096,27 +1095,24 @@ class FrmAppHelper {
1096
  $values['fields'][ $field->id ] = $field_array;
1097
  }
1098
 
1099
- private static function fill_field_opts( $field, array &$field_array, $args ) {
1100
- $post_values = $args['post_values'];
1101
- $opt_defaults = FrmFieldsHelper::get_default_field_opts($field_array['type'], $field, true);
1102
-
1103
- foreach ( $opt_defaults as $opt => $default_opt ) {
1104
- $field_array[ $opt ] = ( $post_values && isset( $post_values['field_options'][ $opt . '_' . $field->id ] ) ) ? maybe_unserialize( $post_values['field_options'][ $opt . '_' . $field->id ] ) : ( isset( $field->field_options[ $opt ] ) ? $field->field_options[ $opt ] : $default_opt );
1105
- if ( $opt == 'blank' && $field_array[ $opt ] == '' ) {
1106
- $field_array[ $opt ] = $args['frm_settings']->blank_msg;
1107
- } else if ( $opt == 'invalid' && $field_array[ $opt ] == '' ) {
1108
- if ( $args['field_type'] == 'captcha' ) {
1109
- $field_array[ $opt ] = $args['frm_settings']->re_msg;
1110
- } else {
1111
- $field_array[ $opt ] = sprintf( __( '%s is invalid', 'formidable' ), $field_array['name'] );
1112
- }
1113
- }
1114
- }
1115
-
1116
- if ( $field_array['custom_html'] == '' ) {
1117
- $field_array['custom_html'] = FrmFieldsHelper::get_default_html($args['field_type']);
1118
- }
1119
- }
1120
 
1121
  /**
1122
  * @param string $table
@@ -1188,16 +1184,12 @@ class FrmAppHelper {
1188
  return $custom_style;
1189
  }
1190
 
1191
- public static function get_meta_value( $field_id, $entry ) {
1192
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryMeta::get_meta_value' );
1193
- return FrmEntryMeta::get_meta_value( $entry, $field_id );
1194
- }
1195
-
1196
  public static function insert_opt_html( $args ) {
1197
- $class = '';
1198
- if ( in_array( $args['type'], array( 'email', 'user_id', 'hidden', 'select', 'radio', 'checkbox', 'phone', 'text' ) ) ) {
1199
- $class .= 'show_frm_not_email_to';
1200
- }
 
1201
  ?>
1202
  <li>
1203
  <a href="javascript:void(0)" class="frmids frm_insert_code alignright <?php echo esc_attr($class) ?>" data-code="<?php echo esc_attr($args['id']) ?>" >[<?php echo esc_attr( $args['id'] ) ?>]</a>
4
  }
5
 
6
  class FrmAppHelper {
7
+ public static $db_version = 64; //version of the database we are moving to
8
  public static $pro_db_version = 37; //deprecated
9
+ public static $font_version = 3;
10
 
11
  /**
12
  * @since 2.0
13
  */
14
+ public static $plug_version = '3.0';
15
 
16
  /**
17
  * @since 1.07.02
100
  return ! $frm_settings->no_ips;
101
  }
102
 
 
 
 
 
 
 
 
 
 
103
  public static function pro_is_installed() {
104
  return apply_filters('frm_pro_installed', false);
105
  }
106
 
107
+ public static function is_formidable_admin() {
108
+ $page = self::simple_get( 'page', 'sanitize_title' );
109
+ $is_formidable = strpos( $page, 'formidable' ) !== false;
110
+ if ( empty( $page ) ) {
111
+ global $pagenow;
112
+ $post_type = self::simple_get( 'post_type', 'sanitize_title' );
113
+ $is_formidable = ( $post_type == 'frm_display' );
114
+ if ( empty( $post_type ) && $pagenow == 'post.php' ) {
115
+ global $post;
116
+ $is_formidable = ( $post && $post->post_type == 'frm_display' );
117
+ }
118
+ }
119
+ return $is_formidable;
120
+ }
121
+
122
  /**
123
  * Check for certain page in Formidable settings
124
  *
131
  global $pagenow;
132
  $get_page = self::simple_get( 'page', 'sanitize_title' );
133
  if ( $pagenow ) {
134
+ // allow this to be true during ajax load i.e. ajax form builder loading
135
+ return ( $pagenow == 'admin.php' || $pagenow == 'admin-ajax.php' ) && $get_page == $page;
136
  }
137
 
138
  return is_admin() && $get_page == $page;
164
  return self::wp_doing_ajax() && ! self::is_preview_page();
165
  }
166
 
167
+ public static function js_suffix() {
168
+ return defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
169
+ }
170
+
171
  /**
172
  * Use the WP 4.7 wp_doing_ajax function
173
  * @sine 2.05.07
210
  * @return boolean
211
  */
212
  public static function is_empty_value( $value, $empty = '' ) {
213
+ return ( is_array( $value ) && empty( $value ) ) || $value === $empty;
214
  }
215
 
216
  public static function is_not_empty_value( $value, $empty = '' ) {
433
  'href' => array(),
434
  'id' => array(),
435
  'rel' => array(),
436
+ 'target' => array(),
437
  'title' => array(),
438
  ),
439
  'abbr' => array(
468
  'h4' => array(),
469
  'h5' => array(),
470
  'h6' => array(),
471
+ 'i' => array(
472
+ 'class' => array(),
473
+ 'id' => array(),
474
+ ),
475
  'img' => array(
476
  'alt' => array(),
477
  'class' => array(),
546
  return $value;
547
  }
548
 
549
+ /**
550
+ * @since 3.0
551
+ */
552
+ public static function get_admin_header( $atts ) {
553
+ $has_nav = ( isset( $atts['form'] ) && ! empty( $atts['form'] ) && ( ! isset( $atts['is_template'] ) || ! $atts['is_template'] ) );
554
+ include( self::plugin_path() . '/classes/views/shared/admin-header.php' );
555
+ }
556
+
557
+ /**
558
+ * @since 3.0
559
+ */
560
+ public static function add_new_item_link( $atts ) {
561
+ if ( isset( $atts['new_link'] ) && ! empty( $atts['new_link'] ) ) { ?>
562
+ <a href="<?php echo esc_url( $atts['new_link'] ) ?>" class="add-new-h2 frm_animate_bg"><?php esc_html_e( 'Add New', 'formidable' ); ?></a>
563
+ <?php
564
+ } elseif ( isset( $atts['link_hook'] ) ) {
565
+ do_action( $atts['link_hook']['hook'], $atts['link_hook']['param'] );
566
+ }
567
+ }
568
+
569
  /**
570
  * @param string $type
571
  */
577
  }
578
  }
579
 
580
+ /**
581
+ * Save all front-end js scripts into a single file
582
+ *
583
+ * @since 3.0
584
+ */
585
+ public static function save_combined_js() {
586
+ $file_atts = array(
587
+ 'file_name' => 'frm.min.js',
588
+ 'new_file_path' => FrmAppHelper::plugin_path() . '/js',
589
+ );
590
+ $new_file = new FrmCreateFile( $file_atts );
591
+
592
+ $files = array(
593
+ FrmAppHelper::plugin_path() . '/js/jquery/jquery.placeholder.min.js',
594
+ FrmAppHelper::plugin_path() . '/js/formidable.min.js',
595
+ );
596
+ $files = apply_filters( 'frm_combined_js_files', $files );
597
+ $new_file->combine_files( $files );
598
+ }
599
+
600
  /**
601
  * Check a value from a shortcode to see if true or false.
602
  * True when value is 1, true, 'true', 'yes'
812
  return ( is_array( $values ) && in_array( $current, $values ) ) || ( ! is_array( $values ) && $values == $current );
813
  }
814
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
815
  public static function recursive_function_map( $value, $function ) {
816
  if ( is_array( $value ) ) {
817
  $original_function = $function;
1029
  }
1030
 
1031
  $values['description'] = self::use_wpautop($values['description']);
 
 
 
 
 
 
 
 
 
 
 
1032
 
1033
  self::fill_form_opts($record, $table, $post_values, $values);
1034
 
1035
+ self::prepare_field_arrays( $fields, $record, $values, array_merge( $args, compact( 'default', 'post_values' ) ) );
1036
+
1037
  if ( $table == 'entries' ) {
1038
  $values = FrmEntriesHelper::setup_edit_vars( $values, $record );
1039
  } else if ( $table == 'forms' ) {
1043
  return $values;
1044
  }
1045
 
1046
+ private static function prepare_field_arrays( $fields, $record, array &$values, $args ) {
1047
+ if ( ! empty( $fields ) ) {
1048
+ foreach ( (array) $fields as $field ) {
1049
+ $field->default_value = apply_filters('frm_get_default_value', $field->default_value, $field, true );
1050
+ $args['parent_form_id'] = isset( $args['parent_form_id'] ) ? $args['parent_form_id'] : $field->form_id;
1051
+ self::fill_field_defaults( $field, $record, $values, $args );
1052
+ }
1053
+ }
1054
+ }
1055
+
1056
  private static function fill_field_defaults( $field, $record, array &$values, $args ) {
1057
  $post_values = $args['post_values'];
1058
 
1077
  $field_type = isset( $post_values['field_options'][ 'type_' . $field->id ] ) ? $post_values['field_options'][ 'type_' . $field->id ] : $field->type;
1078
  $new_value = isset( $post_values['item_meta'][ $field->id ] ) ? maybe_unserialize( $post_values['item_meta'][ $field->id ] ) : $meta_value;
1079
 
1080
+ $field_array = self::start_field_array( $field );
1081
+ $field_array['value'] = $new_value;
1082
+ $field_array['type'] = apply_filters( 'frm_field_type', $field_type, $field, $new_value );
1083
+ $field_array['parent_form_id'] = $args['parent_form_id'];
 
 
 
 
 
 
 
 
 
 
1084
 
1085
  $args['field_type'] = $field_type;
 
 
 
1086
 
1087
+ FrmFieldsHelper::prepare_edit_front_field( $field_array, $field, $values['id'], $args );
1088
 
1089
  if ( ! isset($field_array['unique']) || ! $field_array['unique'] ) {
1090
  $field_array['unique_msg'] = '';
1095
  $values['fields'][ $field->id ] = $field_array;
1096
  }
1097
 
1098
+ /**
1099
+ * @since 3.0
1100
+ * @param object $field
1101
+ * @return array
1102
+ */
1103
+ public static function start_field_array( $field ) {
1104
+ return array(
1105
+ 'id' => $field->id,
1106
+ 'default_value' => $field->default_value,
1107
+ 'name' => $field->name,
1108
+ 'description' => $field->description,
1109
+ 'options' => $field->options,
1110
+ 'required' => $field->required,
1111
+ 'field_key' => $field->field_key,
1112
+ 'field_order' => $field->field_order,
1113
+ 'form_id' => $field->form_id,
1114
+ );
1115
+ }
 
 
 
1116
 
1117
  /**
1118
  * @param string $table
1184
  return $custom_style;
1185
  }
1186
 
 
 
 
 
 
1187
  public static function insert_opt_html( $args ) {
1188
+ $class = '';
1189
+ $possible_email_field = FrmFieldFactory::field_has_property( $args['type'], 'holds_email_values' );
1190
+ if ( $possible_email_field ) {
1191
+ $class .= 'show_frm_not_email_to';
1192
+ }
1193
  ?>
1194
  <li>
1195
  <a href="javascript:void(0)" class="frmids frm_insert_code alignright <?php echo esc_attr($class) ?>" data-code="<?php echo esc_attr($args['id']) ?>" >[<?php echo esc_attr( $args['id'] ) ?>]</a>
classes/helpers/FrmEntriesHelper.php CHANGED
@@ -18,42 +18,20 @@ class FrmEntriesHelper {
18
  }
19
 
20
  foreach ( (array) $fields as $field ) {
 
21
  self::prepare_field_default_value( $field );
22
- $new_value = self::get_field_value_for_new_entry( $field, $reset, $args );
23
-
24
- $field_array = array(
25
- 'id' => $field->id,
26
- 'value' => $new_value,
27
- 'default_value' => $field->default_value,
28
- 'name' => $field->name,
29
- 'description' => $field->description,
30
- 'type' => apply_filters('frm_field_type', $field->type, $field, $new_value),
31
- 'options' => $field->options,
32
- 'required' => $field->required,
33
- 'field_key' => $field->field_key,
34
- 'field_order' => $field->field_order,
35
- 'form_id' => $field->form_id,
36
- 'parent_form_id' => isset( $args['parent_form_id'] ) ? $args['parent_form_id'] : $field->form_id,
37
- 'reset_value' => $reset,
38
- 'in_embed_form' => isset( $args['in_embed_form'] ) ? $args['in_embed_form'] : '0',
39
- );
40
-
41
- $opt_defaults = FrmFieldsHelper::get_default_field_opts($field_array['type'], $field, true);
42
- $opt_defaults['required_indicator'] = '';
43
- $opt_defaults['original_type'] = $field->type;
44
-
45
- foreach ( $opt_defaults as $opt => $default_opt ) {
46
- $field_array[ $opt ] = ( isset( $field->field_options[ $opt ] ) && $field->field_options[ $opt ] != '' ) ? $field->field_options[ $opt ] : $default_opt;
47
- unset($opt, $default_opt);
48
- }
49
 
50
- unset($opt_defaults);
 
 
 
 
 
 
51
 
52
- if ( $field_array['custom_html'] == '' ) {
53
- $field_array['custom_html'] = FrmFieldsHelper::get_default_html($field->type);
54
- }
55
 
56
- $field_array = apply_filters('frm_setup_new_fields_vars', $field_array, $field, $args );
57
  $field_array = array_merge( $field->field_options, $field_array );
58
 
59
  $values['fields'][] = $field_array;
@@ -80,6 +58,8 @@ class FrmEntriesHelper {
80
 
81
  /**
82
  * @since 2.05
 
 
83
  */
84
  private static function prepare_field_default_value( &$field ) {
85
  //If checkbox, multi-select dropdown, or checkbox data from entries field, the value should be an array
@@ -154,31 +134,6 @@ class FrmEntriesHelper {
154
  return apply_filters('frm_setup_edit_entry_vars', $values, $record);
155
  }
156
 
157
- public static function get_admin_params( $form = null ) {
158
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmForm::get_admin_params' );
159
- return FrmForm::set_current_form( $form );
160
- }
161
-
162
- public static function set_current_form( $form_id ) {
163
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmForm::set_current_form' );
164
- return FrmForm::set_current_form( $form_id );
165
- }
166
-
167
- public static function get_current_form( $form_id = 0 ) {
168
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmForm::get_current_form' );
169
- return FrmForm::get_current_form( $form_id );
170
- }
171
-
172
- public static function get_current_form_id() {
173
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmForm::get_current_form_id' );
174
- return FrmForm::get_current_form_id();
175
- }
176
-
177
- public static function maybe_get_entry( &$entry ) {
178
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntry::maybe_get_entry' );
179
- FrmEntry::maybe_get_entry( $entry );
180
- }
181
-
182
  public static function replace_default_message( $message, $atts ) {
183
  if ( strpos($message, '[default-message') === false &&
184
  strpos($message, '[default_message') === false &&
@@ -261,9 +216,14 @@ class FrmEntriesHelper {
261
  }
262
 
263
  /**
264
- * Prepare the saved value for display
265
- * @return string
266
- */
 
 
 
 
 
267
  public static function display_value( $value, $field, $atts = array() ) {
268
 
269
  $defaults = array(
@@ -280,6 +240,12 @@ class FrmEntriesHelper {
280
  );
281
 
282
  $atts = wp_parse_args( $atts, $defaults );
 
 
 
 
 
 
283
  $atts = apply_filters('frm_display_value_atts', $atts, $field, $value);
284
 
285
  if ( ! isset($field->field_options['post_field']) ) {
@@ -303,31 +269,15 @@ class FrmEntriesHelper {
303
  return $value;
304
  }
305
 
306
- $value = apply_filters('frm_display_value_custom', maybe_unserialize($value), $field, $atts);
 
307
  $value = apply_filters( 'frm_display_' . $field->type . '_value_custom', $value, compact( 'field', 'atts' ) );
308
 
309
- $new_value = '';
310
-
311
- if ( is_array($value) && $atts['type'] != 'file' ) {
312
- foreach ( $value as $val ) {
313
- if ( is_array($val) ) {
314
- //TODO: add options for display (li or ,)
315
- $new_value .= implode($atts['sep'], $val);
316
- if ( $atts['type'] != 'data' ) {
317
- $new_value .= '<br/>';
318
- }
319
- }
320
- unset($val);
321
- }
322
- }
323
-
324
- if ( ! empty($new_value) ) {
325
- $value = $new_value;
326
- } else if ( is_array($value) && $atts['type'] != 'file' && ! $atts['return_array'] ) {
327
- $value = implode($atts['sep'], $value);
328
- }
329
 
330
- if ( $atts['truncate'] && $atts['type'] != 'image' ) {
331
  $value = FrmAppHelper::truncate($value, 50);
332
  }
333
 
@@ -335,7 +285,7 @@ class FrmEntriesHelper {
335
  $value = FrmAppHelper::kses( $value, 'all' );
336
  }
337
 
338
- return apply_filters('frm_display_value', $value, $field, $atts);
339
  }
340
 
341
  public static function set_posted_value( $field, $value, $args ) {
@@ -471,11 +421,6 @@ class FrmEntriesHelper {
471
  }
472
  }
473
 
474
- public static function enqueue_scripts( $params ) {
475
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmFormsController::enqueue_scripts' );
476
- FrmFormsController::enqueue_scripts( $params );
477
- }
478
-
479
  // Add submitted values to a string for spam checking
480
  public static function entry_array_to_string( $values ) {
481
  $content = '';
@@ -572,4 +517,30 @@ class FrmEntriesHelper {
572
  return $bname . ' ' . $version . ' / ' . $platform;
573
  }
574
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
575
  }
18
  }
19
 
20
  foreach ( (array) $fields as $field ) {
21
+ $original_default = $field->default_value;
22
  self::prepare_field_default_value( $field );
23
+ $new_value = self::get_field_value_for_new_entry( $field, $reset, $args );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
+ $field_array = FrmAppHelper::start_field_array( $field );
26
+ $field_array['value'] = $new_value;
27
+ $field_array['type'] = apply_filters( 'frm_field_type', $field->type, $field, $new_value );
28
+ $field_array['parent_form_id'] = isset( $args['parent_form_id'] ) ? $args['parent_form_id'] : $field->form_id;
29
+ $field_array['reset_value'] = $reset;
30
+ $field_array['in_embed_form'] = isset( $args['in_embed_form'] ) ? $args['in_embed_form'] : '0';
31
+ $field_array['original_default'] = $original_default;
32
 
33
+ FrmFieldsHelper::prepare_new_front_field( $field_array, $field, $args );
 
 
34
 
 
35
  $field_array = array_merge( $field->field_options, $field_array );
36
 
37
  $values['fields'][] = $field_array;
58
 
59
  /**
60
  * @since 2.05
61
+ *
62
+ * @param object $field
63
  */
64
  private static function prepare_field_default_value( &$field ) {
65
  //If checkbox, multi-select dropdown, or checkbox data from entries field, the value should be an array
134
  return apply_filters('frm_setup_edit_entry_vars', $values, $record);
135
  }
136
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  public static function replace_default_message( $message, $atts ) {
138
  if ( strpos($message, '[default-message') === false &&
139
  strpos($message, '[default_message') === false &&
216
  }
217
 
218
  /**
219
+ * Prepare the saved value for display
220
+ *
221
+ * @param array|string $value
222
+ * @param object $field
223
+ * @param array $atts
224
+ *
225
+ * @return string
226
+ */
227
  public static function display_value( $value, $field, $atts = array() ) {
228
 
229
  $defaults = array(
240
  );
241
 
242
  $atts = wp_parse_args( $atts, $defaults );
243
+
244
+ if ( FrmField::is_image( $field ) || $field->type == 'star' ) {
245
+ $atts['truncate'] = false;
246
+ $atts['html'] = true;
247
+ }
248
+
249
  $atts = apply_filters('frm_display_value_atts', $atts, $field, $value);
250
 
251
  if ( ! isset($field->field_options['post_field']) ) {
269
  return $value;
270
  }
271
 
272
+ $unfiltered_value = maybe_unserialize( $value );
273
+ $value = apply_filters('frm_display_value_custom', $unfiltered_value, $field, $atts);
274
  $value = apply_filters( 'frm_display_' . $field->type . '_value_custom', $value, compact( 'field', 'atts' ) );
275
 
276
+ if ( $value == $unfiltered_value ) {
277
+ $value = FrmFieldsHelper::get_unfiltered_display_value( compact( 'value', 'field', 'atts' ) );
278
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
279
 
280
+ if ( $atts['truncate'] && $atts['type'] != 'url' ) {
281
  $value = FrmAppHelper::truncate($value, 50);
282
  }
283
 
285
  $value = FrmAppHelper::kses( $value, 'all' );
286
  }
287
 
288
+ return apply_filters( 'frm_display_value', $value, $field, $atts );
289
  }
290
 
291
  public static function set_posted_value( $field, $value, $args ) {
421
  }
422
  }
423
 
 
 
 
 
 
424
  // Add submitted values to a string for spam checking
425
  public static function entry_array_to_string( $values ) {
426
  $content = '';
517
  return $bname . ' ' . $version . ' / ' . $platform;
518
  }
519
 
520
+ /**
521
+ * @since 3.0
522
+ */
523
+ public static function actions_dropdown( $atts ) {
524
+ $id = isset( $atts['id'] ) ? $atts['id'] : FrmAppHelper::get_param( 'id', 0, 'get', 'absint' );
525
+ $links = self::get_action_links( $id, $atts['entry'] );
526
+ include( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/actions-dropdown.php' );
527
+ }
528
+
529
+ /**
530
+ * @since 3.0
531
+ */
532
+ private static function get_action_links( $id, $entry ) {
533
+ $actions = array();
534
+
535
+ if ( current_user_can( 'frm_delete_entries' ) ) {
536
+ $actions['frm_delete'] = array(
537
+ 'url' => admin_url( 'admin.php?page=formidable-entries&frm_action=destroy&id=' . $id . '&form=' . $entry->form_id ),
538
+ 'label' => __( 'Delete' ),
539
+ 'icon' => 'frm_icon_font frm_delete_icon',
540
+ 'data' => array( 'frmverify' => __( 'Really delete?', 'formidable' ) ),
541
+ );
542
+ }
543
+
544
+ return apply_filters( 'frm_entry_actions_dropdown', $actions, compact( 'id', 'entry' ) );
545
+ }
546
  }
classes/helpers/FrmEntriesListHelper.php CHANGED
@@ -44,7 +44,7 @@ class FrmEntriesListHelper extends FrmListHelper {
44
 
45
  if ( strpos( $orderby, 'meta' ) !== false ) {
46
  $order_field_type = FrmField::get_type( str_replace( 'meta_', '', $orderby ) );
47
- $orderby .= in_array( $order_field_type, array( 'number', 'scale' ) ) ? ' +0 ' : '';
48
  }
49
 
50
  $order = self::get_param( array(
@@ -242,7 +242,7 @@ class FrmEntriesListHelper extends FrmListHelper {
242
 
243
  if ( current_user_can('frm_delete_entries') ) {
244
  $delete_link = '?page=formidable-entries&frm_action=destroy&id=' . $item->id . '&form=' . $this->params['form'];
245
- $actions['delete'] = '<a href="' . esc_url( wp_nonce_url( $delete_link ) ) . '" class="submitdelete" onclick="return confirm(\'' . esc_attr( __( 'Are you sure you want to delete that?', 'formidable' ) ) . '\')">' . __( 'Delete' ) . '</a>';
246
  }
247
 
248
  $actions = apply_filters('frm_row_actions', $actions, $item);
44
 
45
  if ( strpos( $orderby, 'meta' ) !== false ) {
46
  $order_field_type = FrmField::get_type( str_replace( 'meta_', '', $orderby ) );
47
+ $orderby .= in_array( $order_field_type, array( 'number', 'scale', 'star' ) ) ? ' +0 ' : '';
48
  }
49
 
50
  $order = self::get_param( array(
242
 
243
  if ( current_user_can('frm_delete_entries') ) {
244
  $delete_link = '?page=formidable-entries&frm_action=destroy&id=' . $item->id . '&form=' . $this->params['form'];
245
+ $actions['delete'] = '<a href="' . esc_url( wp_nonce_url( $delete_link ) ) . '" class="submitdelete" data-frmverify="' . esc_attr__( 'Are you sure?', 'formidable' ) . '">' . __( 'Delete' ) . '</a>';
246
  }
247
 
248
  $actions = apply_filters('frm_row_actions', $actions, $item);
classes/helpers/FrmFieldsHelper.php CHANGED
@@ -11,60 +11,23 @@ class FrmFieldsHelper {
11
  list($type, $setting) = explode('|', $type);
12
  }
13
 
14
- $defaults = self::get_default_field_opts($type, $form_id);
15
- $defaults['field_options']['custom_html'] = self::get_default_html($type);
16
 
17
- $values = array();
 
18
 
19
- foreach ( $defaults as $var => $default ) {
20
- if ( $var == 'field_options' ) {
21
- $values['field_options'] = array();
22
- foreach ( $default as $opt_var => $opt_default ) {
23
- $values['field_options'][ $opt_var ] = $opt_default;
24
- unset($opt_var, $opt_default);
25
- }
26
- } else {
27
- $values[ $var ] = $default;
28
- }
29
- unset($var, $default);
30
- }
31
-
32
- if ( isset( $setting ) && ! empty( $setting ) ) {
33
- if ( in_array( $type, array( 'data', 'lookup' ) ) ) {
34
- $values['field_options']['data_type'] = $setting;
35
- } else {
36
- $values['field_options'][ $setting ] = 1;
37
- }
38
- }
39
-
40
- if ( $type == 'radio' || $type == 'checkbox' ) {
41
- $values['options'] = serialize( array(
42
- __( 'Option 1', 'formidable' ),
43
- __( 'Option 2', 'formidable' ),
44
- ) );
45
- } else if ( $type == 'select' ) {
46
- $values['options'] = serialize( array(
47
- '',
48
- __( 'Option 1', 'formidable' ),
49
- ) );
50
- } else if ( $type == 'textarea' ) {
51
- $values['field_options']['max'] = '5';
52
- } else if ( $type == 'captcha' ) {
53
- $frm_settings = FrmAppHelper::get_settings();
54
- $values['invalid'] = $frm_settings->re_msg;
55
- $values['field_options']['label'] = 'none';
56
- } else if ( 'url' == $type ) {
57
- $values['name'] = __( 'Website', 'formidable' );
58
- }
59
-
60
- $fields = FrmField::field_selection();
61
- $fields = array_merge($fields, FrmField::pro_field_selection());
62
-
63
- if ( isset( $fields[ $type ] ) ) {
64
- $values['name'] = is_array( $fields[ $type ] ) ? $fields[ $type ]['name'] : $fields[ $type ];
65
- }
66
 
67
- unset($fields);
 
 
 
 
 
 
68
 
69
  return $values;
70
  }
@@ -73,101 +36,208 @@ class FrmFieldsHelper {
73
  return apply_filters( 'frm_field_html_id', 'field_' . $field['field_key'] . $plus, $field );
74
  }
75
 
76
- public static function setup_edit_vars( $record, $doing_ajax = false ) {
77
- $values = array(
78
- 'id' => $record->id,
79
- 'form_id' => $record->form_id,
80
- );
81
- $defaults = array(
82
- 'name' => $record->name,
83
- 'description' => $record->description,
84
- 'field_key' => $record->field_key,
85
- 'type' => $record->type,
86
- 'default_value' => $record->default_value,
87
- 'field_order' => $record->field_order,
88
- 'required' => $record->required,
89
- );
90
 
91
- if ( $doing_ajax ) {
92
- $values = $values + $defaults;
93
- $values['form_name'] = '';
94
- } else {
95
- foreach ( $defaults as $var => $default ) {
96
- $values[ $var ] = FrmAppHelper::get_param( $var, $default, 'get', 'htmlspecialchars' );
97
- unset($var, $default);
98
- }
99
 
100
- $values['form_name'] = $record->form_id ? FrmForm::getName( $record->form_id ) : '';
101
- }
102
 
103
- unset( $defaults );
104
 
105
- $values['options'] = $record->options;
106
- $values['field_options'] = $record->field_options;
107
 
108
- $defaults = self::get_default_field_opts($values['type'], $record, true);
 
 
109
 
110
- if ( $values['type'] == 'captcha' ) {
111
- $frm_settings = FrmAppHelper::get_settings();
112
- $defaults['invalid'] = $frm_settings->re_msg;
113
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
 
115
  foreach ( $defaults as $opt => $default ) {
116
- $values[ $opt ] = isset( $record->field_options[ $opt ] ) ? $record->field_options[ $opt ] : $default;
117
- unset($opt, $default);
118
- }
119
 
120
- $values['custom_html'] = ( isset( $record->field_options['custom_html'] ) ) ? $record->field_options['custom_html'] : self::get_default_html( $record->type );
 
 
121
 
122
- return apply_filters( 'frm_setup_edit_field_vars', $values, array( 'doing_ajax' => $doing_ajax ) );
123
- }
 
124
 
125
- public static function get_default_field_opts( $type, $field, $limit = false ) {
126
- $field_options = array(
127
- 'size' => '',
128
- 'max' => '',
129
- 'label' => '',
130
- 'blank' => '',
131
- 'required_indicator' => '*',
132
- 'invalid' => '',
133
- 'separate_value' => 0,
134
- 'clear_on_focus' => 0,
135
- 'default_blank' => 0,
136
- 'classes' => '',
137
- 'custom_html' => '',
138
- 'captcha_size' => 'normal',
139
- 'captcha_theme' => 'light',
140
- );
141
 
142
- if ( $limit ) {
143
- return $field_options;
144
  }
145
 
146
- global $wpdb;
 
 
 
 
 
 
147
 
148
- $form_id = ( is_numeric( $field ) ) ? $field : $field->form_id;
149
-
150
- $key = is_numeric( $field ) ? FrmAppHelper::get_unique_key( '', $wpdb->prefix . 'frm_fields', 'field_key' ) : $field->field_key;
151
-
152
- $field_count = FrmDb::get_var( 'frm_fields', array( 'form_id' => $form_id ), 'field_order', array( 'order_by' => 'field_order DESC' ) );
153
-
154
- $frm_settings = FrmAppHelper::get_settings();
155
- return array(
156
- 'name' => __( 'Untitled', 'formidable' ),
157
- 'description' => '',
158
- 'field_key' => $key,
159
- 'type' => $type,
160
- 'options' => '',
161
- 'default_value' => '',
162
- 'field_order' => $field_count + 1,
163
- 'required' => false,
164
- 'blank' => $frm_settings->blank_msg,
165
- 'unique_msg' => $frm_settings->unique_msg,
166
- 'invalid' => __( 'This field is invalid', 'formidable' ),
167
- 'form_id' => $form_id,
168
- 'field_options' => $field_options,
169
- );
170
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
 
172
  public static function fill_field( &$values, $field, $form_id, $new_key = '' ) {
173
  global $wpdb;
@@ -182,9 +252,14 @@ class FrmFieldsHelper {
182
  }
183
  }
184
 
185
- /**
186
- * @since 2.0
187
- */
 
 
 
 
 
188
  public static function get_error_msg( $field, $error ) {
189
  $frm_settings = FrmAppHelper::get_settings();
190
  $default_settings = $frm_settings->default_options();
@@ -218,191 +293,70 @@ class FrmFieldsHelper {
218
 
219
  public static function get_form_fields( $form_id, $error = array() ) {
220
  $fields = FrmField::get_all_for_form( $form_id );
221
- $fields = apply_filters( 'frm_get_paged_fields', $fields, $form_id, $error );
222
- return $fields;
223
  }
224
 
225
  public static function get_default_html( $type = 'text' ) {
226
- if ( apply_filters( 'frm_normal_field_type_html', true, $type ) ) {
227
- $input = ( in_array( $type, array( 'radio', 'checkbox', 'data' ) ) ) ? '<div class="frm_opt_container">[input]</div>' : '[input]';
228
- $for = '';
229
- if ( ! in_array( $type, array( 'radio', 'checkbox', 'data', 'scale' ) ) ) {
230
- $for = 'for="field_[key]"';
231
- }
232
-
233
- $default_html = <<<DEFAULT_HTML
234
- <div id="frm_field_[id]_container" class="frm_form_field form-field [required_class][error_class]">
235
- <label $for class="frm_primary_label">[field_name]
236
- <span class="frm_required">[required_label]</span>
237
- </label>
238
- $input
239
- [if description]<div class="frm_description">[description]</div>[/if description]
240
- [if error]<div class="frm_error">[error]</div>[/if error]
241
- </div>
242
- DEFAULT_HTML;
243
- } else {
244
- $default_html = apply_filters('frm_other_custom_html', '', $type);
245
- }
246
-
247
- return apply_filters('frm_custom_html', $default_html, $type);
248
- }
249
-
250
- public static function replace_shortcodes( $html, $field, $errors = array(), $form = false, $args = array() ) {
251
- $html = apply_filters('frm_before_replace_shortcodes', $html, $field, $errors, $form);
252
-
253
- $defaults = array(
254
- 'field_name' => 'item_meta[' . $field['id'] . ']',
255
- 'field_id' => $field['id'],
256
- 'field_plus_id' => '',
257
- 'section_id' => '',
258
- );
259
- $args = wp_parse_args($args, $defaults);
260
- $field_name = $args['field_name'];
261
- $field_id = $args['field_id'];
262
- $html_id = self::get_html_id($field, $args['field_plus_id']);
263
-
264
- if ( FrmField::is_multiple_select($field) ) {
265
- $field_name .= '[]';
266
- }
267
-
268
- //replace [id]
269
- $html = str_replace('[id]', $field_id, $html);
270
 
271
- // Remove the for attribute for captcha
272
- if ( $field['type'] == 'captcha' ) {
273
- $html = str_replace(' for="field_[key]"', '', $html);
274
- }
275
-
276
- // set the label for
277
- $html = str_replace('field_[key]', $html_id, $html);
278
-
279
- //replace [key]
280
- $html = str_replace('[key]', $field['field_key'], $html);
281
-
282
- //replace [description] and [required_label] and [error]
283
- $required = FrmField::is_required( $field ) ? $field['required_indicator'] : '';
284
- if ( ! is_array( $errors ) ) {
285
- $errors = array();
286
- }
287
- $error = isset( $errors[ 'field' . $field_id ] ) ? $errors[ 'field' . $field_id ] : false;
288
-
289
- //If field type is section heading, add class so a bottom margin can be added to either the h3 or description
290
- if ( $field['type'] == 'divider' ) {
291
- if ( FrmField::is_option_true( $field, 'description' ) ) {
292
- $html = str_replace( 'frm_description', 'frm_description frm_section_spacing', $html );
293
- } else {
294
- $html = str_replace('[label_position]', '[label_position] frm_section_spacing', $html);
295
- }
296
- }
297
-
298
- $codes = array(
299
- 'description' => $field['description'],
300
- 'required_label' => $required,
301
- 'error' => $error,
302
- );
303
- foreach ( $codes as $code => $value ) {
304
- self::remove_inline_conditions( ( $value && $value != '' ), $code, $value, $html );
305
- }
306
-
307
- //replace [required_class]
308
- $required_class = FrmField::is_required( $field ) ? ' frm_required_field' : '';
309
- $html = str_replace('[required_class]', $required_class, $html);
310
-
311
- //replace [label_position]
312
- $field['label'] = self::label_position( $field['label'], $field, $form );
313
- self::add_class_to_label( $field, $html );
314
-
315
- //replace [field_name]
316
- $html = str_replace('[field_name]', $field['name'], $html);
317
-
318
- self::add_field_div_classes( $field_id, $field, $errors, $html );
319
-
320
- //replace [entry_key]
321
- $entry_key = FrmAppHelper::simple_get( 'entry', 'sanitize_title' );
322
- $html = str_replace('[entry_key]', $entry_key, $html);
323
-
324
- if ( $form ) {
325
- $form = (array) $form;
326
-
327
- //replace [form_key]
328
- $html = str_replace('[form_key]', $form['form_key'], $html);
329
-
330
- //replace [form_name]
331
- $html = str_replace('[form_name]', $form['name'], $html);
332
  }
333
 
334
- self::process_wp_shortcodes( $html );
335
-
336
- //replace [input]
337
- preg_match_all("/\[(input|deletelink)\b(.*?)(?:(\/))?\]/s", $html, $shortcodes, PREG_PATTERN_ORDER);
338
- global $frm_vars;
339
- $frm_settings = FrmAppHelper::get_settings();
340
-
341
- foreach ( $shortcodes[0] as $short_key => $tag ) {
342
- $atts = FrmShortcodeHelper::get_shortcode_attribute_array( $shortcodes[2][ $short_key ] );
343
- $tag = self::get_shortcode_tag( $shortcodes, $short_key, array(
344
- 'conditional' => false,
345
- 'conditional_check' => false,
346
- ) );
347
-
348
- $replace_with = '';
349
-
350
- if ( $tag == 'input' ) {
351
- if ( isset($atts['opt']) ) {
352
- $atts['opt']--;
353
- }
354
-
355
- $field['input_class'] = isset($atts['class']) ? $atts['class'] : '';
356
- if ( isset($atts['class']) ) {
357
- unset($atts['class']);
358
- }
359
-
360
- $field['shortcodes'] = $atts;
361
- ob_start();
362
- include( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/input.php' );
363
- $replace_with = ob_get_contents();
364
- ob_end_clean();
365
- } else if ( $tag == 'deletelink' && FrmAppHelper::pro_is_installed() ) {
366
- $replace_with = FrmProEntriesController::entry_delete_link($atts);
367
- }
368
-
369
- $html = str_replace( $shortcodes[0][ $short_key ], $replace_with, $html );
370
- }
371
-
372
- $html .= "\n";
373
-
374
- //Return html if conf_field to prevent loop
375
- if ( isset($field['conf_field']) && $field['conf_field'] == 'stop' ) {
376
- return $html;
377
- }
378
 
379
- //If field is in repeating section
380
- if ( $args['section_id'] ) {
381
- $html = apply_filters( 'frm_replace_shortcodes', $html, $field, array(
382
- 'errors' => $errors,
383
- 'form' => $form,
384
- 'field_name' => $field_name,
385
- 'field_id' => $field_id,
386
- 'field_plus_id' => $args['field_plus_id'],
387
- 'section_id' => $args['section_id'],
388
- ) );
389
- } else {
390
- $html = apply_filters( 'frm_replace_shortcodes', $html, $field, array(
391
- 'errors' => $errors,
392
- 'form' => $form,
393
- ) );
394
- }
395
 
396
- self::remove_collapse_shortcode( $html );
 
 
 
 
 
 
 
 
 
 
 
 
 
397
 
398
- return $html;
399
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
400
 
401
  /**
402
  * Get the class to use for the label position
403
  * @since 2.05
404
  */
405
- private static function &label_position( $position, $field, $form ) {
406
  if ( $position && $position != '' ) {
407
  return $position;
408
  }
@@ -427,141 +381,19 @@ DEFAULT_HTML;
427
  * @since 2.05
428
  */
429
  public static function is_placeholder_field_type( $type ) {
430
- return ! in_array( $type, array( 'select', 'radio', 'checkbox', 'hidden' ) );
431
- }
432
-
433
- /**
434
- * Add the label position class into the HTML
435
- * If the label position is inside, add a class to show the label if the field has a value.
436
- *
437
- * @since 2.05
438
- */
439
- private static function add_class_to_label( $field, &$html ) {
440
- $label_class = in_array( $field['type'], array( 'divider', 'end_divider', 'break' ) ) ? $field['label'] : ' frm_primary_label';
441
- $html = str_replace( '[label_position]', $label_class, $html );
442
- if ( $field['label'] == 'inside' && $field['value'] != '' ) {
443
- $html = str_replace( 'frm_primary_label', 'frm_primary_label frm_visible', $html );
444
- }
445
  }
446
 
447
- /**
448
- * This filters shortcodes in the field HTML
449
- *
450
- * @since 2.02.11
451
- */
452
- private static function process_wp_shortcodes( &$html ) {
453
- if ( apply_filters( 'frm_do_html_shortcodes', true ) ) {
454
- $html = do_shortcode( $html );
455
- }
456
  }
457
 
458
- /**
459
- * Add classes to a field div
460
- *
461
- * @since 2.02.05
462
- *
463
- * @param string $field_id
464
- * @param array $field
465
- * @param array $errors
466
- * @param string $html
467
- */
468
- private static function add_field_div_classes( $field_id, $field, $errors, &$html ) {
469
- $classes = self::get_field_div_classes( $field_id, $field, $errors, $html );
470
-
471
- if ( $field['type'] == 'html' && strpos( $html, '[error_class]' ) === false ) {
472
- // there is no error_class shortcode for HTML fields
473
- $html = str_replace( 'class="frm_form_field', 'class="frm_form_field ' . $classes, $html );
474
- }
475
- $html = str_replace( '[error_class]', $classes, $html );
476
- }
477
-
478
- /**
479
- * Get the classes for a field div
480
- *
481
- * @since 2.02.05
482
- *
483
- * @param string $field_id
484
- * @param array $field
485
- * @param array $errors
486
- * @param string $html
487
- * @return string $classes
488
- */
489
- private static function get_field_div_classes( $field_id, $field, $errors, $html ) {
490
- // Add error class
491
- $classes = isset( $errors[ 'field' . $field_id ] ) ? ' frm_blank_field' : '';
492
-
493
- // Add label position class
494
- $classes .= ' frm_' . $field['label'] . '_container';
495
-
496
- // Add CSS layout classes
497
- if ( ! empty( $field['classes'] ) ) {
498
- if ( ! strpos( $html, 'frm_form_field ') ) {
499
- $classes .= ' frm_form_field';
500
- }
501
- $classes .= ' ' . $field['classes'];
502
- }
503
-
504
- // Get additional classes
505
- $classes = apply_filters( 'frm_field_div_classes', $classes, $field, array( 'field_id' => $field_id ) );
506
-
507
- return $classes;
508
- }
509
-
510
- public static function remove_inline_conditions( $no_vars, $code, $replace_with, &$html ) {
511
- if ( $no_vars ) {
512
- $html = str_replace( '[if ' . $code . ']', '', $html );
513
- $html = str_replace( '[/if ' . $code . ']', '', $html );
514
- } else {
515
- $html = preg_replace( '/(\[if\s+' . $code . '\])(.*?)(\[\/if\s+' . $code . '\])/mis', '', $html );
516
- }
517
-
518
- $html = str_replace( '[' . $code . ']', $replace_with, $html );
519
- }
520
-
521
  public static function get_shortcode_tag( $shortcodes, $short_key, $args ) {
522
- $args = wp_parse_args( $args, array(
523
- 'conditional' => false,
524
- 'conditional_check' => false,
525
- 'foreach' => false,
526
- ) );
527
- if ( ( $args['conditional'] || $args['foreach'] ) && ! $args['conditional_check'] ) {
528
- $args['conditional_check'] = true;
529
- }
530
-
531
- $prefix = '';
532
- if ( $args['conditional_check'] ) {
533
- if ( $args['conditional'] ) {
534
- $prefix = 'if ';
535
- } else if ( $args['foreach'] ) {
536
- $prefix = 'foreach ';
537
- }
538
- }
539
-
540
- $with_tags = $args['conditional_check'] ? 3 : 2;
541
- if ( ! empty( $shortcodes[ $with_tags ][ $short_key ] ) ) {
542
- $tag = str_replace( '[' . $prefix, '', $shortcodes[0][ $short_key ] );
543
- $tag = str_replace(']', '', $tag);
544
- $tags = explode(' ', $tag);
545
- if ( is_array($tags) ) {
546
- $tag = $tags[0];
547
- }
548
- } else {
549
- $tag = $shortcodes[ $with_tags - 1 ][ $short_key ];
550
- }
551
-
552
- return $tag;
553
  }
554
 
555
- /**
556
- * Remove [collapse_this] if it's still included after all processing
557
- * @since 2.0.8
558
- */
559
- private static function remove_collapse_shortcode( &$html ) {
560
- if ( preg_match( '/\[(collapse_this)\]/s', $html ) ) {
561
- $html = str_replace( '[collapse_this]', '', $html );
562
- }
563
- }
564
-
565
  public static function get_checkbox_id( $field, $opt_key ) {
566
  $id = $field['id'];
567
  if ( isset( $field['in_section'] ) && $field['in_section'] ) {
@@ -571,57 +403,58 @@ DEFAULT_HTML;
571
  }
572
 
573
  public static function display_recaptcha( $field ) {
574
- $frm_settings = FrmAppHelper::get_settings();
575
- $lang = apply_filters( 'frm_recaptcha_lang', $frm_settings->re_lang, $field );
576
-
577
- $class_prefix = '';
578
- $api_js_url = 'https://www.google.com/recaptcha/api.js?';
579
-
580
- $allow_mutiple = $frm_settings->re_multi;
581
- if ( $allow_mutiple ) {
582
- $api_js_url .= '&onload=frmRecaptcha&render=explicit';
583
- $class_prefix = 'frm-';
584
- }
585
 
586
- if ( ! empty( $lang ) ) {
587
- $api_js_url .= '&hl=' . $lang;
 
588
  }
589
- $api_js_url = apply_filters( 'frm_recaptcha_js_url', $api_js_url );
590
 
591
- wp_register_script( 'recaptcha-api', $api_js_url, array( 'formidable' ), true );
592
- wp_enqueue_script( 'recaptcha-api' );
593
 
594
- // for reverse compatibility
595
- $field['captcha_size'] = ( $field['captcha_size'] == 'default' ) ? 'normal' : $field['captcha_size'];
596
- $field['captcha_size'] = ( $frm_settings->re_type == 'invisible' ) ? 'invisible' : $field['captcha_size'];
597
 
598
- ?>
599
- <div id="field_<?php echo esc_attr( $field['field_key'] ) ?>" class="<?php echo esc_attr( $class_prefix ) ?>g-recaptcha" data-sitekey="<?php echo esc_attr( $frm_settings->pubkey ) ?>" data-size="<?php echo esc_attr( $field['captcha_size'] ) ?>" data-theme="<?php echo esc_attr( $field['captcha_theme'] ) ?>" <?php echo ( 'invisible' === $field['captcha_size'] && ! $allow_mutiple ) ? 'data-callback="frmAfterRecaptcha"' : ''; ?>></div>
600
- <?php
601
- }
602
 
603
- public static function show_single_option( $field ) {
604
- $field_name = $field['name'];
605
- $html_id = self::get_html_id($field);
606
- foreach ( $field['options'] as $opt_key => $opt ) {
607
- $field_val = apply_filters('frm_field_value_saved', $opt, $opt_key, $field);
608
- $opt = apply_filters('frm_field_label_seen', $opt, $opt_key, $field);
609
 
610
- // If this is an "Other" option, get the HTML for it
611
  if ( self::is_other_opt( $opt_key ) ) {
612
- // Get string for Other text field, if needed
613
- $other_val = self::get_other_val( compact( 'opt_key', 'field' ) );
614
- require( FrmAppHelper::plugin_path() . '/pro/classes/views/frmpro-fields/other-option.php' );
615
- } else {
616
  require( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/single-option.php' );
617
- }
618
- }
 
 
619
  }
620
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
621
  public static function get_term_link( $tax_id ) {
622
  $tax = get_taxonomy($tax_id);
623
  if ( ! $tax ) {
624
- return;
625
  }
626
 
627
  $link = sprintf(
@@ -755,118 +588,120 @@ DEFAULT_HTML;
755
  }
756
 
757
  public static function replace_content_shortcodes( $content, $entry, $shortcodes ) {
758
- $shortcode_values = array(
759
- 'id' => $entry->id,
760
- 'key' => $entry->item_key,
761
- 'ip' => $entry->ip,
762
- );
763
-
764
  foreach ( $shortcodes[0] as $short_key => $tag ) {
765
  if ( empty( $tag ) ) {
766
  continue;
767
  }
768
 
769
- $atts = FrmShortcodeHelper::get_shortcode_attribute_array( $shortcodes[3][ $short_key ] );
770
-
771
- if ( ! empty( $shortcodes[3][ $short_key ] ) ) {
772
- $tag = str_replace( array( '[', ']' ), '', $shortcodes[0][ $short_key ] );
773
- $tags = explode(' ', $tag);
774
- if ( is_array($tags) ) {
775
- $tag = $tags[0];
776
- }
777
- } else {
778
- $tag = $shortcodes[2][ $short_key ];
779
- }
780
-
781
- switch ( $tag ) {
782
- case 'id':
783
- case 'key':
784
- case 'ip':
785
- $replace_with = $shortcode_values[ $tag ];
786
- break;
787
-
788
- case 'user_agent':
789
- case 'user-agent':
790
- $entry->description = maybe_unserialize($entry->description);
791
- $replace_with = FrmEntriesHelper::get_browser( $entry->description['browser'] );
792
- break;
793
-
794
- case 'created_at':
795
- case 'created-at':
796
- case 'updated_at':
797
- case 'updated-at':
798
- if ( isset($atts['format']) ) {
799
- $time_format = ' ';
800
- } else {
801
- $atts['format'] = get_option('date_format');
802
- $time_format = '';
803
- }
804
-
805
- $this_tag = str_replace('-', '_', $tag);
806
- $replace_with = FrmAppHelper::get_formatted_time($entry->{$this_tag}, $atts['format'], $time_format);
807
- unset($this_tag);
808
- break;
809
-
810
- case 'created_by':
811
- case 'created-by':
812
- case 'updated_by':
813
- case 'updated-by':
814
- $this_tag = str_replace('-', '_', $tag);
815
- $replace_with = self::get_display_value( $entry->{$this_tag}, (object) array( 'type' => 'user_id' ), $atts );
816
- unset($this_tag);
817
- break;
818
-
819
- case 'admin_email':
820
- case 'siteurl':
821
- case 'frmurl':
822
- case 'sitename':
823
- case 'get':
824
- $replace_with = self::dynamic_default_values( $tag, $atts );
825
- break;
826
-
827
- default:
828
- $field = FrmField::getOne( $tag );
829
- if ( ! $field ) {
830
- break;
831
- }
832
-
833
- $sep = isset($atts['sep']) ? $atts['sep'] : ', ';
834
-
835
- $replace_with = FrmEntryMeta::get_meta_value( $entry, $field->id );
836
-
837
- $atts['entry_id'] = $entry->id;
838
- $atts['entry_key'] = $entry->item_key;
839
-
840
- if ( isset($atts['show']) && $atts['show'] == 'field_label' ) {
841
- $replace_with = $field->name;
842
- } else if ( isset($atts['show']) && $atts['show'] == 'description' ) {
843
- $replace_with = $field->description;
844
- } else {
845
- $string_value = $replace_with;
846
- if ( is_array( $replace_with ) ) {
847
- $string_value = implode( $sep, $replace_with );
848
- }
849
-
850
- if ( empty( $string_value ) && $string_value != '0' ) {
851
- $replace_with = '';
852
- } else {
853
- $replace_with = self::get_display_value( $replace_with, $field, $atts );
854
- }
855
- }
856
 
857
- unset($field);
858
- }
 
859
 
860
- if ( isset($replace_with) ) {
861
- $content = str_replace( $shortcodes[0][ $short_key ], $replace_with, $content );
862
- }
863
 
864
- unset($atts, $conditional, $replace_with);
865
  }
866
 
867
  return $content;
868
  }
869
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
870
  /**
871
  * Get the value to replace a few standard shortcodes
872
  *
@@ -890,7 +725,6 @@ DEFAULT_HTML;
890
  break;
891
  case 'get':
892
  $new_value = self::process_get_shortcode( $atts, $return_array );
893
- break;
894
  }
895
 
896
  return $new_value;
@@ -930,35 +764,70 @@ DEFAULT_HTML;
930
  return $new_value;
931
  }
932
 
933
- public static function get_display_value( $replace_with, $field, $atts = array() ) {
934
- $sep = isset( $atts['sep'] ) ? $atts['sep'] : ', ';
935
 
936
- $replace_with = apply_filters( 'frm_get_' . $field->type . '_display_value', $replace_with, $field, $atts );
937
- $replace_with = apply_filters( 'frm_get_display_value', $replace_with, $field, $atts );
938
 
939
- if ( $field->type == 'textarea' || $field->type == 'rte' ) {
940
- $autop = isset($atts['wpautop']) ? $atts['wpautop'] : true;
941
- if ( apply_filters('frm_use_wpautop', $autop) ) {
942
- if ( is_array($replace_with) ) {
943
- $replace_with = implode("\n", $replace_with);
944
- }
945
- $replace_with = wpautop($replace_with);
946
- }
947
- unset( $autop );
948
- } else if ( is_array( $replace_with ) ) {
949
- if ( isset( $atts['show'] ) && $atts['show'] && isset( $replace_with[ $atts['show'] ] ) ) {
950
- $replace_with = $replace_with[ $atts['show'] ];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
951
  } else {
952
- $replace_with = implode( $sep, $replace_with );
 
 
 
 
953
  }
954
  }
955
 
956
- return $replace_with;
 
 
 
 
957
  }
958
 
959
  public static function get_field_types( $type ) {
960
- $single_input = array( 'text', 'textarea', 'rte', 'number', 'email', 'url', 'image', 'file', 'date', 'phone', 'hidden', 'time', 'user_id', 'tag', 'password' );
961
- $multiple_input = array( 'radio', 'checkbox', 'select', 'scale', 'lookup' );
962
  $other_type = array( 'html', 'break' );
963
 
964
  $field_selection = array_merge( FrmField::pro_field_selection(), FrmField::field_selection() );
@@ -1093,7 +962,7 @@ DEFAULT_HTML;
1093
  * @param array $args should include field, opt_key and field name
1094
  * @param boolean $other_opt
1095
  * @param string $checked
1096
- * @return string $other_val
1097
  */
1098
  public static function prepare_other_input( $args, &$other_opt, &$checked ) {
1099
  //Check if this is an "Other" option
@@ -1183,7 +1052,13 @@ DEFAULT_HTML;
1183
  // Set up HTML ID for Other field
1184
  $other_id = self::get_other_field_html_id( $args['field']['type'], $args['html_id'], $args['opt_key'] );
1185
 
1186
- echo '<input type="text" id="' . esc_attr( $other_id ) . '" class="' . sanitize_text_field( implode( ' ', $classes ) ) . '" ' . ( $args['read_only'] ? ' readonly="readonly" disabled="disabled"' : '' ) . ' name="' . esc_attr( $args['name'] ) . '" value="' . esc_attr( $args['value'] ) . '" />';
 
 
 
 
 
 
1187
  }
1188
 
1189
  /**
@@ -1434,46 +1309,18 @@ DEFAULT_HTML;
1434
  return $field_array + $field_options;
1435
  }
1436
 
1437
- public static function field_selection() {
1438
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmField::field_selection' );
1439
- return FrmField::field_selection();
1440
- }
1441
-
1442
- public static function pro_field_selection() {
1443
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmField::pro_field_selection' );
1444
- return FrmField::pro_field_selection();
1445
- }
1446
-
1447
- public static function is_no_save_field( $type ) {
1448
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmField::is_no_save_field' );
1449
- return FrmField::is_no_save_field( $type );
1450
- }
1451
-
1452
- public static function no_save_fields() {
1453
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmField::no_save_fields' );
1454
- return FrmField::no_save_fields();
1455
- }
1456
-
1457
- public static function is_multiple_select( $field ) {
1458
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmField::is_multiple_select' );
1459
- return FrmField::is_multiple_select( $field );
1460
- }
1461
-
1462
- public static function is_field_with_multiple_values( $field ) {
1463
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmField::is_field_with_multiple_values' );
1464
- return FrmField::is_field_with_multiple_values( $field );
1465
- }
1466
 
1467
- public static function is_required_field( $field ) {
1468
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmField::is_required' );
1469
- return FrmField::is_required( $field );
1470
  }
1471
 
1472
- public static function maybe_get_field( &$field ) {
1473
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmField::maybe_get_field' );
1474
- FrmField::maybe_get_field( $field );
1475
- }
1476
-
1477
  public static function dropdown_categories( $args ) {
1478
  _deprecated_function( __FUNCTION__, '2.02.07', 'FrmProPost::get_category_dropdown' );
1479
 
11
  list($type, $setting) = explode('|', $type);
12
  }
13
 
14
+ $values = self::get_default_field( $type );
 
15
 
16
+ global $wpdb;
17
+ $field_count = FrmDb::get_var( 'frm_fields', array( 'form_id' => $form_id ), 'field_order', array( 'order_by' => 'field_order DESC' ) );
18
 
19
+ $values['field_key'] = FrmAppHelper::get_unique_key( '', $wpdb->prefix . 'frm_fields', 'field_key' );
20
+ $values['form_id'] = $form_id;
21
+ $values['field_order'] = $field_count + 1;
22
+ $values['field_options']['custom_html'] = self::get_default_html( $type );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
+ if ( isset( $setting ) && ! empty( $setting ) ) {
25
+ if ( in_array( $type, array( 'data', 'lookup' ) ) ) {
26
+ $values['field_options']['data_type'] = $setting;
27
+ } else {
28
+ $values['field_options'][ $setting ] = 1;
29
+ }
30
+ }
31
 
32
  return $values;
33
  }
36
  return apply_filters( 'frm_field_html_id', 'field_' . $field['field_key'] . $plus, $field );
37
  }
38
 
39
+ public static function setup_edit_vars( $field, $doing_ajax = false ) {
40
+ $values = self::field_object_to_array( $field );
41
+ return apply_filters( 'frm_setup_edit_field_vars', $values, array( 'doing_ajax' => $doing_ajax ) );
42
+ }
 
 
 
 
 
 
 
 
 
 
43
 
44
+ public static function field_object_to_array( $field ) {
45
+ $values = (array) $field;
 
 
 
 
 
 
46
 
47
+ self::fill_field_array( $field, $values );
 
48
 
49
+ $values['custom_html'] = ( isset( $field->field_options['custom_html'] ) ) ? $field->field_options['custom_html'] : self::get_default_html( $field->type );
50
 
51
+ return $values;
52
+ }
53
 
54
+ private static function fill_field_array( $field, array &$field_array ) {
55
+ $field_array['options'] = $field->options;
56
+ $field_array['value'] = $field->default_value;
57
 
58
+ self::prepare_edit_front_field( $field_array, $field );
59
+
60
+ $field_array = array_merge( $field->field_options, $field_array );
61
+ }
62
+
63
+ /**
64
+ * Prepare field while creating a new entry
65
+ * @since 3.0
66
+ */
67
+ public static function prepare_new_front_field( &$field_array, $field, $args = array() ) {
68
+ $args['action'] = 'new';
69
+ self::prepare_front_field( $field_array, $field, $args );
70
+ }
71
+
72
+ /**
73
+ * Prepare field while editing an entry
74
+ * @since 3.0
75
+ */
76
+ public static function prepare_edit_front_field( &$field_array, $field, $entry_id = 0, $args = array() ) {
77
+ $args['entry_id'] = $entry_id;
78
+ $args['action'] = 'edit';
79
+ self::prepare_front_field( $field_array, $field, $args );
80
+ }
81
+
82
+ /**
83
+ * Prepare field while creating a new entry
84
+ * @since 3.0
85
+ */
86
+ private static function prepare_front_field( &$field_array, $field, $args ) {
87
+ self::fill_default_field_opts( $field, $field_array );
88
+ self::fill_cleared_strings( $field, $field_array );
89
+
90
+ // Track the original field's type
91
+ $field_array['original_type'] = isset( $field->field_options['original_type'] ) ? $field->field_options['original_type'] : $field->type;
92
+
93
+ if ( $args['action'] == 'edit' ) {
94
+ $field_array = apply_filters( 'frm_setup_edit_fields_vars', $field_array, $field, $args['entry_id'], $args );
95
+ } else {
96
+ $field_array = apply_filters( 'frm_setup_new_fields_vars', $field_array, $field, $args );
97
+ }
98
+
99
+ self::prepare_field_options_for_display( $field_array, $field, $args );
100
+ }
101
+
102
+ /**
103
+ * @since 3.0
104
+ *
105
+ * @param string $type
106
+ *
107
+ * @return array
108
+ */
109
+ public static function get_default_field_options( $type ) {
110
+ $field_type = FrmFieldFactory::get_field_type( $type );
111
+ return $field_type->get_default_field_options();
112
+ }
113
+
114
+ /**
115
+ * @since 3.0
116
+ *
117
+ * @param object $field
118
+ * @param array $values
119
+ */
120
+ private static function fill_default_field_opts( $field, array &$values ) {
121
+ $check_post = FrmAppHelper::is_admin() && $_POST && isset( $_POST['field_options'] );
122
+
123
+ $defaults = self::get_default_field_options_from_field( $field, $values );
124
+ if ( ! $check_post ) {
125
+ $defaults['required_indicator'] = '';
126
+ $defaults['original_type'] = $field->type;
127
+ }
128
 
129
  foreach ( $defaults as $opt => $default ) {
130
+ $values[ $opt ] = isset( $field->field_options[ $opt ] ) ? $field->field_options[ $opt ] : $default;
 
 
131
 
132
+ if ( $check_post ) {
133
+ self::get_posted_field_setting( $opt . '_' . $field->id, $values[ $opt ] );
134
+ }
135
 
136
+ unset( $opt, $default );
137
+ }
138
+ }
139
 
140
+ /**
141
+ * Fill the required message, invalid message,
142
+ * and refill the HTML when cleared
143
+ *
144
+ * @since 3.0
145
+ *
146
+ * @param object $field
147
+ * @param array $field_array
148
+ */
149
+ private static function fill_cleared_strings( $field, array &$field_array ) {
150
+ $frm_settings = FrmAppHelper::get_settings();
 
 
 
 
 
151
 
152
+ if ( '' == $field_array['blank'] && '1' === $field_array['required'] ) {
153
+ $field_array['blank'] = $frm_settings->blank_msg;
154
  }
155
 
156
+ if ( '' == $field_array['invalid'] ) {
157
+ if ( 'captcha' === $field->type ) {
158
+ $field_array['invalid'] = $frm_settings->re_msg;
159
+ } else {
160
+ $field_array['invalid'] = sprintf( __( '%s is invalid', 'formidable' ), $field_array['name'] );
161
+ }
162
+ }
163
 
164
+ if ( '' == $field_array['custom_html'] ) {
165
+ $field_array['custom_html'] = FrmFieldsHelper::get_default_html( $field->type );
166
+ }
167
+ }
168
+
169
+ /**
170
+ * @since 3.0
171
+ *
172
+ * @param string $setting
173
+ * @param mixed $current
174
+ */
175
+ private static function get_posted_field_setting( $setting, &$value ) {
176
+ if ( isset( $_POST['field_options'][ $setting ] ) ) {
177
+ $value = maybe_unserialize( $_POST['field_options'][ $setting ] );
178
+ if ( strpos( $setting, 'html' ) !== false ) {
179
+ // strip slashes from HTML but not regex
180
+ $value = stripslashes_deep( $value );
181
+ }
182
+ }
183
+ }
184
+
185
+ /**
186
+ * @since 3.0
187
+ *
188
+ * @param object $field
189
+ * @param array $values The field array is needed for hooks
190
+ *
191
+ * @return array
192
+ */
193
+ public static function get_default_field_options_from_field( $field, $values = array() ) {
194
+ $field_type = self::get_original_field( $field );
195
+ $opts = $field_type->get_default_field_options();
196
+
197
+ $opts = apply_filters( 'frm_default_field_opts', $opts, $values, $field );
198
+ $opts = apply_filters( 'frm_default_' . $field->type . '_field_opts', $opts, $values, $field );
199
+
200
+ return $opts;
201
+ }
202
+
203
+ /**
204
+ * @since 3.0
205
+ *
206
+ * @param object $field
207
+ *
208
+ * @return array
209
+ */
210
+ private static function get_original_field( $field ) {
211
+ $original_type = FrmField::get_option( $field, 'original_type' );
212
+ if ( ! empty( $original_type ) && $field->type != $original_type ) {
213
+ $field->type = $original_type;
214
+ }
215
+ return FrmFieldFactory::get_field_object( $field );
216
+ }
217
+
218
+ /**
219
+ * @since 3.0
220
+ *
221
+ * @param array $field_array
222
+ * @param object $field
223
+ * @param array $atts
224
+ */
225
+ private static function prepare_field_options_for_display( &$field_array, $field, $atts ) {
226
+ $field_obj = FrmFieldFactory::get_field_object( $field );
227
+ $field_array = $field_obj->prepare_front_field( $field_array, $atts );
228
+ }
229
+
230
+ /**
231
+ * @since 3.0
232
+ *
233
+ * @param string $type
234
+ *
235
+ * @return array
236
+ */
237
+ public static function get_default_field( $type ) {
238
+ $field_type = FrmFieldFactory::get_field_type( $type );
239
+ return $field_type->get_new_field_defaults();
240
+ }
241
 
242
  public static function fill_field( &$values, $field, $form_id, $new_key = '' ) {
243
  global $wpdb;
252
  }
253
  }
254
 
255
+ /**
256
+ * @since 2.0
257
+ *
258
+ * @param $field
259
+ * @param $error
260
+ *
261
+ * @return string
262
+ */
263
  public static function get_error_msg( $field, $error ) {
264
  $frm_settings = FrmAppHelper::get_settings();
265
  $default_settings = $frm_settings->default_options();
293
 
294
  public static function get_form_fields( $form_id, $error = array() ) {
295
  $fields = FrmField::get_all_for_form( $form_id );
296
+ return apply_filters( 'frm_get_paged_fields', $fields, $form_id, $error );
 
297
  }
298
 
299
  public static function get_default_html( $type = 'text' ) {
300
+ $field = FrmFieldFactory::get_field_type( $type );
301
+ $default_html = $field->default_html();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
 
303
+ // these hooks are here for reverse compatibility since 3.0
304
+ if ( ! apply_filters( 'frm_normal_field_type_html', true, $type ) ) {
305
+ $default_html = apply_filters( 'frm_other_custom_html', '', $type );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
306
  }
307
 
308
+ return apply_filters('frm_custom_html', $default_html, $type);
309
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
310
 
311
+ /**
312
+ * @param array $fields
313
+ * @param array $errors
314
+ * @param object $form
315
+ * @param $form_action
316
+ */
317
+ public static function show_fields( $fields, $errors, $form, $form_action ) {
318
+ foreach ( $fields as $field ) {
319
+ $field_obj = FrmFieldFactory::get_field_type( $field['type'], $field );
320
+ $field_obj->show_field( compact( 'errors', 'form', 'form_action' ) );
321
+ }
322
+ }
 
 
 
 
323
 
324
+ /**
325
+ * @param string $html
326
+ * @param array $field
327
+ * @param array $errors
328
+ * @param object $form
329
+ * @param array $args
330
+ *
331
+ * @return string
332
+ */
333
+ public static function replace_shortcodes( $html, $field, $errors = array(), $form = false, $args = array() ) {
334
+ _deprecated_function( __FUNCTION__, '3.0', 'FrmFieldType::prepare_field_html' );
335
+ $field_obj = FrmFieldFactory::get_field_type( $field['type'], $field );
336
+ return $field_obj->prepare_field_html( compact( 'errors', 'form' ) );
337
+ }
338
 
339
+ /**
340
+ * @since 3.0
341
+ *
342
+ * @param array $atts
343
+ * @param string|array $value
344
+ */
345
+ public static function run_wpautop( $atts, &$value ) {
346
+ $autop = isset( $atts['wpautop'] ) ? $atts['wpautop'] : true;
347
+ if ( apply_filters( 'frm_use_wpautop', $autop ) ) {
348
+ if ( is_array( $value ) ) {
349
+ $value = implode( "\n", $value );
350
+ }
351
+ $value = wpautop( $value );
352
+ }
353
+ }
354
 
355
  /**
356
  * Get the class to use for the label position
357
  * @since 2.05
358
  */
359
+ public static function &label_position( $position, $field, $form ) {
360
  if ( $position && $position != '' ) {
361
  return $position;
362
  }
381
  * @since 2.05
382
  */
383
  public static function is_placeholder_field_type( $type ) {
384
+ return ! in_array( $type, array( 'select', 'radio', 'checkbox', 'hidden', 'file' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
385
  }
386
 
387
+ public static function remove_inline_conditions( $no_vars, $code, $replace_with, &$html ) {
388
+ _deprecated_function( __FUNCTION__, '3.0', 'FrmShortcodeHelper::remove_inline_conditions' );
389
+ FrmShortcodeHelper::remove_inline_conditions( $no_vars, $code, $replace_with, $html );
 
 
 
 
 
 
390
  }
391
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
392
  public static function get_shortcode_tag( $shortcodes, $short_key, $args ) {
393
+ _deprecated_function( __FUNCTION__, '3.0', 'FrmShortcodeHelper::get_shortcode_tag' );
394
+ return FrmShortcodeHelper::get_shortcode_tag( $shortcodes, $short_key, $args );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
395
  }
396
 
 
 
 
 
 
 
 
 
 
 
397
  public static function get_checkbox_id( $field, $opt_key ) {
398
  $id = $field['id'];
399
  if ( isset( $field['in_section'] ) && $field['in_section'] ) {
403
  }
404
 
405
  public static function display_recaptcha( $field ) {
406
+ _deprecated_function( __FUNCTION__, '3.0', 'FrmFieldCaptcha::field_input' );
407
+ }
 
 
 
 
 
 
 
 
 
408
 
409
+ public static function show_single_option( $field ) {
410
+ if ( ! is_array( $field['options'] ) ) {
411
+ return;
412
  }
 
413
 
414
+ $field_name = isset( $field['html_name'] ) ? $field['html_name'] : $field['name'];
415
+ $html_id = isset( $field['html_id'] ) ? $field['html_id'] : self::get_html_id( $field );
416
 
417
+ foreach ( $field['options'] as $opt_key => $opt ) {
418
+ $field_val = self::get_value_from_array( $opt, $opt_key, $field );
419
+ $opt = self::get_label_from_array( $opt, $opt_key, $field );
420
 
421
+ // Get string for Other text field, if needed
422
+ $other_val = self::get_other_val( compact( 'opt_key', 'field' ) );
 
 
423
 
424
+ $checked = ( $other_val || isset( $field['value'] ) && ( ( ! is_array( $field['value'] ) && $field['value'] == $field_val ) || ( is_array($field['value'] ) && in_array( $field_val, $field['value'] ) ) ) ) ? ' checked="checked"' : '';
 
 
 
 
 
425
 
426
+ // If this is an "Other" option, get the HTML for it
427
  if ( self::is_other_opt( $opt_key ) ) {
428
+ if ( FrmAppHelper::pro_is_installed() ) {
429
+ require( FrmProAppHelper::plugin_path() . '/classes/views/frmpro-fields/other-option.php' );
430
+ }
431
+ } else {
432
  require( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/single-option.php' );
433
+ }
434
+
435
+ unset( $checked, $other_val );
436
+ }
437
  }
438
 
439
+ public static function get_value_from_array( $opt, $opt_key, $field ) {
440
+ $opt = apply_filters( 'frm_field_value_saved', $opt, $opt_key, $field );
441
+ return FrmFieldsController::check_value( $opt, $opt_key, $field );
442
+ }
443
+
444
+ public static function get_label_from_array( $opt, $opt_key, $field ) {
445
+ $opt = apply_filters( 'frm_field_label_seen', $opt, $opt_key, $field );
446
+ return FrmFieldsController::check_label( $opt );
447
+ }
448
+
449
+ /**
450
+ * @param int $tax_id
451
+ *
452
+ * @return string
453
+ */
454
  public static function get_term_link( $tax_id ) {
455
  $tax = get_taxonomy($tax_id);
456
  if ( ! $tax ) {
457
+ return '';
458
  }
459
 
460
  $link = sprintf(
588
  }
589
 
590
  public static function replace_content_shortcodes( $content, $entry, $shortcodes ) {
 
 
 
 
 
 
591
  foreach ( $shortcodes[0] as $short_key => $tag ) {
592
  if ( empty( $tag ) ) {
593
  continue;
594
  }
595
 
596
+ $atts = FrmShortcodeHelper::get_shortcode_attribute_array( $shortcodes[3][ $short_key ] );
597
+ $tag = FrmShortcodeHelper::get_shortcode_tag( $shortcodes, $short_key );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
598
 
599
+ $atts['entry'] = $entry;
600
+ $atts['tag'] = $tag;
601
+ $replace_with = self::get_value_for_shortcode( $atts );
602
 
603
+ if ( $replace_with !== null ) {
604
+ $content = str_replace( $shortcodes[0][ $short_key ], $replace_with, $content );
605
+ }
606
 
607
+ unset( $atts, $replace_with );
608
  }
609
 
610
  return $content;
611
  }
612
 
613
+ /**
614
+ * @since 3.0
615
+ *
616
+ * @param $atts
617
+ *
618
+ * @return string
619
+ */
620
+ private static function get_value_for_shortcode( $atts ) {
621
+ $clean_tag = str_replace( '-', '_', $atts['tag'] );
622
+
623
+ $shortcode_values = array(
624
+ 'id' => $atts['entry']->id,
625
+ 'key' => $atts['entry']->item_key,
626
+ 'ip' => $atts['entry']->ip,
627
+ );
628
+
629
+ $dynamic_default = array( 'admin_email', 'siteurl', 'frmurl', 'sitename', 'get' );
630
+
631
+ if ( isset( $shortcode_values[ $atts['tag'] ] ) ) {
632
+ $replace_with = $shortcode_values[ $atts['tag'] ];
633
+ } elseif ( in_array( $atts['tag'], $dynamic_default ) ) {
634
+ $replace_with = self::dynamic_default_values( $atts['tag'], $atts );
635
+ } elseif ( $clean_tag == 'user_agent' ) {
636
+ $description = maybe_unserialize( $atts['entry']->description );
637
+ $replace_with = FrmEntriesHelper::get_browser( $description['browser'] );
638
+ } elseif ( $clean_tag == 'created_at' || $clean_tag == 'updated_at' ) {
639
+ $atts['tag'] = $clean_tag;
640
+ $replace_with = self::get_entry_timestamp( $atts );
641
+ } elseif ( $clean_tag == 'created_by' || $clean_tag == 'updated_by' ) {
642
+ $replace_with = self::get_display_value( $atts['entry']->{$clean_tag}, (object) array( 'type' => 'user_id' ), $atts );
643
+ } else {
644
+ $replace_with = self::get_field_shortcode_value( $atts );
645
+ }
646
+
647
+ return $replace_with;
648
+ }
649
+
650
+ /**
651
+ * @since 3.0
652
+ *
653
+ * @param $atts
654
+ *
655
+ * @return string
656
+ */
657
+ private static function get_entry_timestamp( $atts ) {
658
+ if ( isset( $atts['format'] ) ) {
659
+ $time_format = ' ';
660
+ } else {
661
+ $atts['format'] = get_option('date_format');
662
+ $time_format = '';
663
+ }
664
+
665
+ return FrmAppHelper::get_formatted_time( $atts['entry']->{$atts['tag']}, $atts['format'], $time_format );
666
+ }
667
+
668
+ /**
669
+ * @since 3.0
670
+ *
671
+ * @param $atts
672
+ *
673
+ * @return null|string
674
+ */
675
+ private static function get_field_shortcode_value( $atts ) {
676
+ $field = FrmField::getOne( $atts['tag'] );
677
+ if ( empty( $field ) ) {
678
+ return null;
679
+ }
680
+
681
+ if ( isset( $atts['show'] ) && $atts['show'] == 'field_label' ) {
682
+ $replace_with = $field->name;
683
+ } elseif ( isset( $atts['show'] ) && $atts['show'] == 'description' ) {
684
+ $replace_with = $field->description;
685
+ } else {
686
+ $replace_with = FrmEntryMeta::get_meta_value( $atts['entry'], $field->id );
687
+ $string_value = $replace_with;
688
+ if ( is_array( $replace_with ) ) {
689
+ $sep = isset( $atts['sep'] ) ? $atts['sep'] : ', ';
690
+ $string_value = implode( $sep, $replace_with );
691
+ }
692
+
693
+ if ( empty( $string_value ) && $string_value != '0' ) {
694
+ $replace_with = '';
695
+ } else {
696
+ $atts['entry_id'] = $atts['entry']->id;
697
+ $atts['entry_key'] = $atts['entry']->item_key;
698
+ $replace_with = self::get_display_value( $replace_with, $field, $atts );
699
+ }
700
+ }
701
+
702
+ return $replace_with;
703
+ }
704
+
705
  /**
706
  * Get the value to replace a few standard shortcodes
707
  *
725
  break;
726
  case 'get':
727
  $new_value = self::process_get_shortcode( $atts, $return_array );
 
728
  }
729
 
730
  return $new_value;
764
  return $new_value;
765
  }
766
 
767
+ public static function get_display_value( $value, $field, $atts = array() ) {
 
768
 
769
+ $value = apply_filters( 'frm_get_' . $field->type . '_display_value', $value, $field, $atts );
770
+ $value = apply_filters( 'frm_get_display_value', $value, $field, $atts );
771
 
772
+ return self::get_unfiltered_display_value( compact( 'value', 'field', 'atts' ) );
773
+ }
774
+
775
+ /**
776
+ * @param $atts array Includes value, field, and atts
777
+ */
778
+ public static function get_unfiltered_display_value( $atts ) {
779
+ $value = $atts['value'];
780
+ $field = $atts['field'];
781
+ $atts = isset( $atts['atts'] ) ? $atts['atts'] : $atts;
782
+
783
+ if ( is_array( $field ) ) {
784
+ $field = $field['id'];
785
+ }
786
+
787
+ $field_obj = FrmFieldFactory::get_field_object( $field );
788
+ return $field_obj->get_display_value( $value, $atts );
789
+ }
790
+
791
+ /**
792
+ * Get a value from the user profile from the user ID
793
+ * @since 3.0
794
+ */
795
+ public static function get_user_display_name( $user_id, $user_info = 'display_name', $args = array() ) {
796
+ $defaults = array(
797
+ 'blank' => false,
798
+ 'link' => false,
799
+ 'size' => 96,
800
+ );
801
+
802
+ $args = wp_parse_args($args, $defaults);
803
+
804
+ $user = get_userdata($user_id);
805
+ $info = '';
806
+
807
+ if ( $user ) {
808
+ if ( $user_info == 'avatar' ) {
809
+ $info = get_avatar( $user_id, $args['size'] );
810
+ } elseif ( $user_info == 'author_link' ) {
811
+ $info = get_author_posts_url( $user_id );
812
  } else {
813
+ $info = isset($user->$user_info) ? $user->$user_info : '';
814
+ }
815
+
816
+ if ( 'display_name' === $user_info && empty( $info ) && ! $args['blank'] ) {
817
+ $info = $user->user_login;
818
  }
819
  }
820
 
821
+ if ( $args['link'] ) {
822
+ $info = '<a href="' . esc_url( admin_url('user-edit.php?user_id=' . $user_id ) ) . '">' . $info . '</a>';
823
+ }
824
+
825
+ return $info;
826
  }
827
 
828
  public static function get_field_types( $type ) {
829
+ $single_input = array( 'text', 'textarea', 'rte', 'number', 'email', 'url', 'file', 'date', 'phone', 'hidden', 'time', 'user_id', 'tag', 'password' );
830
+ $multiple_input = array( 'radio', 'checkbox', 'select', 'scale', 'star', 'lookup' );
831
  $other_type = array( 'html', 'break' );
832
 
833
  $field_selection = array_merge( FrmField::pro_field_selection(), FrmField::field_selection() );
962
  * @param array $args should include field, opt_key and field name
963
  * @param boolean $other_opt
964
  * @param string $checked
965
+ * @return array $other_args
966
  */
967
  public static function prepare_other_input( $args, &$other_opt, &$checked ) {
968
  //Check if this is an "Other" option
1052
  // Set up HTML ID for Other field
1053
  $other_id = self::get_other_field_html_id( $args['field']['type'], $args['html_id'], $args['opt_key'] );
1054
 
1055
+ $label = isset( $args['opt_label'] ) ? $args['opt_label'] : $args['field']['name'];
1056
+
1057
+ ?><label for="<?php echo esc_attr( $other_id ) ?>" class="frm_screen_reader"><?php
1058
+ echo esc_html( $label );
1059
+ ?></label><input type="text" id="<?php echo esc_attr( $other_id ) ?>" class="<?php echo sanitize_text_field( implode( ' ', $classes ) ) ?>" <?php
1060
+ echo ( $args['read_only'] ? ' readonly="readonly" disabled="disabled"' : '' );
1061
+ ?> name="<?php echo esc_attr( $args['name'] ) ?>" value="<?php echo esc_attr( $args['value'] ); ?>" /><?php
1062
  }
1063
 
1064
  /**
1309
  return $field_array + $field_options;
1310
  }
1311
 
1312
+ public static function get_default_field_opts( $type, $field = null, $limit = false ) {
1313
+ if ( $limit ) {
1314
+ _deprecated_function( __FUNCTION__, '3.0', 'FrmFieldHelper::get_default_field_options' );
1315
+ $field_options = self::get_default_field_options( $type );
1316
+ } else {
1317
+ _deprecated_function( __FUNCTION__, '3.0', 'FrmFieldHelper::get_default_field' );
1318
+ $field_options = self::get_default_field( $type );
1319
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1320
 
1321
+ return $field_options;
 
 
1322
  }
1323
 
 
 
 
 
 
1324
  public static function dropdown_categories( $args ) {
1325
  _deprecated_function( __FUNCTION__, '2.02.07', 'FrmProPost::get_category_dropdown' );
1326
 
classes/helpers/FrmFormActionsHelper.php CHANGED
@@ -10,16 +10,6 @@ class FrmFormActionsHelper {
10
  return FrmFormAction::get_action_for_form( $form_id, $type, $limit );
11
  }
12
 
13
- public static function action_args( $form_id = 0, $limit = 99 ) {
14
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmFormAction::action_args' );
15
- return FrmFormAction::action_args( $form_id, $limit );
16
- }
17
-
18
- public static function action_conditions_met( $action, $entry ) {
19
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmFormAction::action_conditions_met' );
20
- return FrmFormAction::action_conditions_met( $action, $entry );
21
- }
22
-
23
  public static function default_action_opts( $class = '' ) {
24
  //_deprecated_function( __FUNCTION__, '2.0.9', 'FrmFormAction::default_action_opts' );
25
  return FrmFormAction::default_action_opts( $class );
10
  return FrmFormAction::get_action_for_form( $form_id, $type, $limit );
11
  }
12
 
 
 
 
 
 
 
 
 
 
 
13
  public static function default_action_opts( $class = '' ) {
14
  //_deprecated_function( __FUNCTION__, '2.0.9', 'FrmFormAction::default_action_opts' );
15
  return FrmFormAction::default_action_opts( $class );
classes/helpers/FrmFormsHelper.php CHANGED
@@ -5,11 +5,6 @@ if ( ! defined('ABSPATH') ) {
5
 
6
  class FrmFormsHelper {
7
 
8
- public static function maybe_get_form( &$form ) {
9
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmForm::maybe_get_form' );
10
- FrmForm::maybe_get_form( $form );
11
- }
12
-
13
  /**
14
  * @since 2.2.10
15
  */
@@ -103,7 +98,7 @@ class FrmFormsHelper {
103
  }
104
 
105
  ?>
106
- <li class="dropdown last" id="frm_bs_dropdown">
107
  <a href="#" id="frm-navbarDrop" class="frm-dropdown-toggle" data-toggle="dropdown"><?php esc_html_e( 'Switch Form', 'formidable' ) ?> <b class="caret"></b></a>
108
  <ul class="frm-dropdown-menu frm-on-top" role="menu" aria-labelledby="frm-navbarDrop">
109
  <?php
@@ -130,6 +125,30 @@ class FrmFormsHelper {
130
  echo ( $sort_col == $col && $sort_dir == 'desc' ) ? ' asc' : ' desc';
131
  }
132
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  /**
134
  * Get the invalid form error message
135
  *
@@ -263,6 +282,7 @@ class FrmFormsHelper {
263
  'akismet' => '',
264
  'no_save' => 0,
265
  'ajax_load' => 0,
 
266
  'form_class' => '',
267
  'custom_style' => 1,
268
  'before_html' => self::get_default_html( 'before' ),
@@ -299,7 +319,7 @@ $draft_link
299
  SUBMIT_HTML;
300
  } else if ( $loc == 'before' ) {
301
  $default_html = <<<BEFORE_HTML
302
- <legend class="frm_hidden">[form_name]</legend>
303
  [if form_name]<h3 class="frm_form_title">[form_name]</h3>[/if form_name]
304
  [if form_description]<div class="frm_description">[form_description]</div>[/if form_description]
305
  BEFORE_HTML;
@@ -437,7 +457,7 @@ BEFORE_HTML;
437
  $replace_with = '';
438
  }
439
 
440
- FrmFieldsHelper::remove_inline_conditions( ( FrmAppHelper::is_true($show) && $replace_with != '' ), $code, $replace_with, $html );
441
  }
442
 
443
  //replace [form_key]
@@ -512,9 +532,10 @@ BEFORE_HTML;
512
 
513
  $submit_align = isset( $form['submit_align'] ) ? $form['submit_align'] : '';
514
 
515
- if ( $submit_align == 'inline' ) {
516
  $class .= ' frm_inline_form';
517
- } else if ( $submit_align == 'center' ) {
 
518
  $class .= ' frm_center_submit';
519
  }
520
 
@@ -523,6 +544,55 @@ BEFORE_HTML;
523
  return $class;
524
  }
525
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
526
  /**
527
  * @param string|boolean $form
528
  *
@@ -582,6 +652,9 @@ BEFORE_HTML;
582
  * @since 2.0.6
583
  */
584
  public static function show_error( $args ) {
 
 
 
585
  $line_break_first = $args['show_img'];
586
  foreach ( $args['errors'] as $error_key => $error ) {
587
  if ( $line_break_first && ! is_numeric( $error_key ) && ( $error_key == 'cptch_number' || strpos( $error_key, 'field' ) === 0 ) ) {
@@ -617,6 +690,57 @@ BEFORE_HTML;
617
  echo '<script type="text/javascript">document.addEventListener(\'DOMContentLoaded\',function(){frmFrontForm.scrollMsg(' . (int) $form_id . ');})</script>';
618
  }
619
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
620
  public static function edit_form_link( $form_id ) {
621
  if ( is_object($form_id) ) {
622
  $form = $form_id;
@@ -635,37 +759,167 @@ BEFORE_HTML;
635
  return $val;
636
  }
637
 
638
- public static function delete_trash_link( $id, $status, $length = 'long' ) {
639
- $link = '';
640
- $labels = array(
641
- 'restore' => array(
642
- 'long' => __( 'Restore from Trash', 'formidable' ),
643
- 'short' => __( 'Restore', 'formidable' ),
644
- ),
645
- 'trash' => array(
646
- 'long' => __( 'Move to Trash', 'formidable' ),
647
- 'short' => __( 'Trash', 'formidable' ),
648
- ),
649
- 'delete' => array(
650
- 'long' => __( 'Delete Permanently', 'formidable' ),
651
- 'short' => __( 'Delete', 'formidable' ),
652
- ),
653
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
654
 
 
 
 
 
 
 
 
655
  $current_page = FrmAppHelper::get_simple_request( array( 'param' => 'form_type' ) );
656
  $base_url = '?page=formidable&form_type=' . $current_page . '&id=' . $id;
657
- if ( 'trash' == $status ) {
658
- $link = '<a href="' . esc_url( wp_nonce_url( $base_url . '&frm_action=untrash', 'untrash_form_' . $id ) ) . '" class="submitdelete deletion">' . $labels['restore'][ $length ] . '</a>';
659
- } else if ( current_user_can('frm_delete_forms') ) {
660
- if ( EMPTY_TRASH_DAYS ) {
661
- $link = '<a href="' . esc_url( wp_nonce_url( $base_url . '&frm_action=trash', 'trash_form_' . $id ) ) . '" class="submitdelete deletion">' . $labels['trash'][ $length ] . '</a>';
662
- } else {
663
- $link = '<a href="' . esc_url( wp_nonce_url( $base_url . '&frm_action=destroy', 'destroy_form_' . $id ) ) . '" class="submitdelete deletion" onclick="return confirm(\'' . esc_attr( __( 'Are you sure you want to delete this form and all its entries?', 'formidable' ) ) . '\')">' . $labels['delete'][ $length ] . '</a>';
664
- }
665
- }
666
 
667
- return $link;
668
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
669
 
670
  public static function status_nice_name( $status ) {
671
  $nice_names = array(
@@ -682,14 +936,4 @@ BEFORE_HTML;
682
 
683
  return $name;
684
  }
685
-
686
- public static function get_params() {
687
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmForm::list_page_params' );
688
- return FrmForm::list_page_params();
689
- }
690
-
691
- public static function form_loaded( $form, $this_load, $global_load ) {
692
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmFormsController::maybe_load_css' );
693
- FrmFormsController::maybe_load_css( $form, $this_load, $global_load );
694
- }
695
  }
5
 
6
  class FrmFormsHelper {
7
 
 
 
 
 
 
8
  /**
9
  * @since 2.2.10
10
  */
98
  }
99
 
100
  ?>
101
+ <li id="frm_bs_dropdown" class="dropdown <?php echo esc_attr( is_rtl() ? 'pull-right' : 'pull-left' ) ?>">
102
  <a href="#" id="frm-navbarDrop" class="frm-dropdown-toggle" data-toggle="dropdown"><?php esc_html_e( 'Switch Form', 'formidable' ) ?> <b class="caret"></b></a>
103
  <ul class="frm-dropdown-menu frm-on-top" role="menu" aria-labelledby="frm-navbarDrop">
104
  <?php
125
  echo ( $sort_col == $col && $sort_dir == 'desc' ) ? ' asc' : ' desc';
126
  }
127
 
128
+ /**
129
+ * @since 3.0
130
+ */
131
+ public static function get_field_link_name( $field_type ) {
132
+ if ( is_array( $field_type ) ) {
133
+ $field_label = $field_type['name'];
134
+ } else {
135
+ $field_label = $field_type;
136
+ }
137
+ return $field_label;
138
+ }
139
+
140
+ /**
141
+ * @since 3.0
142
+ */
143
+ public static function get_field_link_icon( $field_type ) {
144
+ if ( is_array( $field_type ) && isset( $field_type['icon'] ) ) {
145
+ $icon = $field_type['icon'];
146
+ } else {
147
+ $icon = 'frm_icon_font frm_pencil_icon';
148
+ }
149
+ return $icon;
150
+ }
151
+
152
  /**
153
  * Get the invalid form error message
154
  *
282
  'akismet' => '',
283
  'no_save' => 0,
284
  'ajax_load' => 0,
285
+ 'js_validate' => 0,
286
  'form_class' => '',
287
  'custom_style' => 1,
288
  'before_html' => self::get_default_html( 'before' ),
319
  SUBMIT_HTML;
320
  } else if ( $loc == 'before' ) {
321
  $default_html = <<<BEFORE_HTML
322
+ <legend class="frm_screen_reader">[form_name]</legend>
323
  [if form_name]<h3 class="frm_form_title">[form_name]</h3>[/if form_name]
324
  [if form_description]<div class="frm_description">[form_description]</div>[/if form_description]
325
  BEFORE_HTML;
457
  $replace_with = '';
458
  }
459
 
460
+ FrmShortcodeHelper::remove_inline_conditions( ( FrmAppHelper::is_true( $show ) && $replace_with != '' ), $code, $replace_with, $html );
461
  }
462
 
463
  //replace [form_key]
532
 
533
  $submit_align = isset( $form['submit_align'] ) ? $form['submit_align'] : '';
534
 
535
+ if ( 'inline' === $submit_align ) {
536
  $class .= ' frm_inline_form';
537
+ $class .= self::maybe_align_fields_top( $form );
538
+ } elseif ( 'center' === $submit_align ) {
539
  $class .= ' frm_center_submit';
540
  }
541
 
544
  return $class;
545
  }
546
 
547
+ /**
548
+ * Returns appropriate class if form has top labels
549
+ *
550
+ * @param $form
551
+ *
552
+ * @return string
553
+ */
554
+ private static function maybe_align_fields_top( $form ) {
555
+ return self::form_has_top_labels( $form ) ? ' frm_inline_top' : '';
556
+ }
557
+
558
+ /**
559
+ * Determine if a form has fields with top labels so submit button can be aligned properly
560
+ *
561
+ * @param $form
562
+ *
563
+ * @return bool
564
+ */
565
+ private static function form_has_top_labels( $form ) {
566
+ $fields = $form['fields'];
567
+ if ( count( $fields ) <= 0 ) {
568
+ return false;
569
+ }
570
+
571
+ $fields = array_reverse( $fields ); // start from the fields closest to the submit button
572
+ foreach ( $fields as $field ) {
573
+ $type = isset( $field['original_type'] ) ? $field['original_type'] : $field['type'];
574
+ $has_input = FrmFieldFactory::field_has_property( $type, 'has_input' );
575
+ if ( $has_input ) {
576
+ return self::field_has_top_label( $field, $form );
577
+ }
578
+ }
579
+
580
+ return false;
581
+ }
582
+
583
+ /**
584
+ * Check if a field's label position is set to "top"
585
+ *
586
+ * @param $field
587
+ * @param $form
588
+ *
589
+ * @return bool
590
+ */
591
+ private static function field_has_top_label( $field, $form ) {
592
+ $label_position = FrmFieldsHelper::label_position( $field['label'], $field, $form );
593
+ return in_array( $label_position, array( 'top', 'inside', 'hidden' ) );
594
+ }
595
+
596
  /**
597
  * @param string|boolean $form
598
  *
652
  * @since 2.0.6
653
  */
654
  public static function show_error( $args ) {
655
+ // remove any blank messages
656
+ $args['errors'] = array_filter( $args['errors'] );
657
+
658
  $line_break_first = $args['show_img'];
659
  foreach ( $args['errors'] as $error_key => $error ) {
660
  if ( $line_break_first && ! is_numeric( $error_key ) && ( $error_key == 'cptch_number' || strpos( $error_key, 'field' ) === 0 ) ) {
690
  echo '<script type="text/javascript">document.addEventListener(\'DOMContentLoaded\',function(){frmFrontForm.scrollMsg(' . (int) $form_id . ');})</script>';
691
  }
692
 
693
+ /**
694
+ * @since 3.0
695
+ */
696
+ public static function actions_dropdown( $atts ) {
697
+ if ( FrmAppHelper::is_admin_page('formidable' ) ) {
698
+ $status = $atts['status'];
699
+ $form_id = isset( $atts['id'] ) ? $atts['id'] : FrmAppHelper::get_param( 'id', 0, 'get', 'absint' );
700
+ $trash_link = self::delete_trash_info( $form_id, $status );
701
+ $links = self::get_action_links( $form_id, $status );
702
+ include( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/actions-dropdown.php' );
703
+ }
704
+ }
705
+
706
+ /**
707
+ * @since 3.0
708
+ */
709
+ public static function get_action_links( $form_id, $form ) {
710
+ if ( ! is_object( $form ) ) {
711
+ $form = FrmForm::getOne( $form_id );
712
+ }
713
+
714
+ $actions = array();
715
+ $trash_links = self::delete_trash_links( $form_id );
716
+ if ( 'trash' == $form->status ) {
717
+ $actions['restore'] = $trash_links['restore'];
718
+
719
+ if ( current_user_can('frm_delete_forms') ) {
720
+ $actions['trash'] = $trash_links['delete'];
721
+ }
722
+ } else {
723
+ $duplicate_link = '?page=formidable&frm_action=duplicate&id=' . $form_id;
724
+ if ( $form->is_template ) {
725
+ $actions['frm_duplicate'] = array(
726
+ 'url' => wp_nonce_url( $duplicate_link ),
727
+ 'label' => __( 'Create Form from Template', 'formidable' ),
728
+ 'icon' => 'frm_icon_font frm_duplicate_icon',
729
+ );
730
+ } elseif ( FrmAppHelper::pro_is_installed() ) {
731
+ $actions['duplicate'] = array(
732
+ 'url' => wp_nonce_url( $duplicate_link ),
733
+ 'label' => __( 'Duplicate Form', 'formidable' ),
734
+ 'icon' => 'frm_icon_font frm_duplicate_icon',
735
+ );
736
+ }
737
+
738
+ $actions['trash'] = self::delete_trash_info( $form_id, $form->status );
739
+ }
740
+
741
+ return $actions;
742
+ }
743
+
744
  public static function edit_form_link( $form_id ) {
745
  if ( is_object($form_id) ) {
746
  $form = $form_id;
759
  return $val;
760
  }
761
 
762
+ public static function delete_trash_link( $id, $status, $length = 'label' ) {
763
+ $link_details = self::delete_trash_info( $id, $status );
764
+
765
+ return self::format_link_html( $link_details, $length );
766
+ }
767
+
768
+ /**
769
+ * @since 3.0
770
+ */
771
+ public static function format_link_html( $link_details, $length = 'label' ) {
772
+ $link = '';
773
+ if ( ! empty( $link_details ) ) {
774
+ $link = '<a href="' . esc_url( $link_details['url'] ) . '"';
775
+ if ( isset( $link_details['data'] ) ) {
776
+ foreach ( $link_details['data'] as $data => $value ) {
777
+ $link .= ' data-' . esc_attr( $data ) . '="' . esc_attr( $value ) . '"';
778
+ }
779
+ } elseif ( isset( $link_details['confirm'] ) ) {
780
+ $link .= ' onclick="return confirm(\'' . esc_attr( $link_details['confirm'] ) . '\')"';
781
+ }
782
+ $label = ( isset( $link_details[ $length ] ) ? $link_details[ $length ] : $link_details['label'] );
783
+ $link .= '>' . $label . '</a>';
784
+ }
785
+ return $link;
786
+ }
787
+
788
+ /**
789
+ * @since 3.0
790
+ */
791
+ public static function delete_trash_info( $id, $status ) {
792
+ $labels = self::delete_trash_links( $id );
793
+
794
+ if ( 'trash' == $status ) {
795
+ $info = $labels['restore'];
796
+ } elseif ( current_user_can('frm_delete_forms') ) {
797
+ if ( EMPTY_TRASH_DAYS ) {
798
+ $info = $labels['trash'];
799
+ } else {
800
+ $info = $labels['delete'];
801
+ }
802
+ } else {
803
+ $info = array();
804
+ }
805
 
806
+ return $info;
807
+ }
808
+
809
+ /**
810
+ * @since 3.0
811
+ */
812
+ private static function delete_trash_links( $id ) {
813
  $current_page = FrmAppHelper::get_simple_request( array( 'param' => 'form_type' ) );
814
  $base_url = '?page=formidable&form_type=' . $current_page . '&id=' . $id;
 
 
 
 
 
 
 
 
 
815
 
816
+ return array(
817
+ 'restore' => array(
818
+ 'label' => __( 'Restore from Trash', 'formidable' ),
819
+ 'short' => __( 'Restore', 'formidable' ),
820
+ 'url' => wp_nonce_url( $base_url . '&frm_action=untrash', 'untrash_form_' . $id ),
821
+ ),
822
+ 'trash' => array(
823
+ 'label' => __( 'Move Form to Trash', 'formidable' ),
824
+ 'short' => __( 'Trash', 'formidable' ),
825
+ 'url' => wp_nonce_url( $base_url . '&frm_action=trash', 'trash_form_' . $id ),
826
+ 'icon' => 'frm_icon_font frm_delete_icon',
827
+ 'data' => array( 'frmverify' => __( 'Are you sure?', 'formidable' ) ),
828
+ ),
829
+ 'delete' => array(
830
+ 'label' => __( 'Delete Permanently', 'formidable' ),
831
+ 'short' => __( 'Delete', 'formidable' ),
832
+ 'url' => wp_nonce_url( $base_url . '&frm_action=destroy', 'destroy_form_' . $id ),
833
+ 'confirm' => __( 'Are you sure you want to delete this form and all its entries?', 'formidable' ),
834
+ 'icon' => 'frm_icon_font frm_delete_icon',
835
+ 'data' => array( 'frmverify' => __( 'Delete form & entries?', 'formidable' ) ),
836
+ ),
837
+ );
838
+ }
839
+
840
+ /**
841
+ * @since 3.0
842
+ */
843
+ public static function css_classes() {
844
+ $classes = array(
845
+ 'frm_inline' => array(
846
+ 'label' => __( 'Inline', 'formidable' ),
847
+ 'title' => __( 'Align fields in a row without a specific width.', 'formidable' ),
848
+ ),
849
+ 'frm_first' => array(
850
+ 'label' => __( 'First', 'formidable' ),
851
+ 'title' => __( 'Add this to the first field in each row along with a width. ie frm_first frm4', 'formidable' ),
852
+ ),
853
+ 'frm_alignright' => __( 'Right', 'formidable' ),
854
+ 'frm_total' => array(
855
+ 'label' => __( 'Total', 'formidable' ),
856
+ 'title' => __( 'Add this to a read-only field to display the text in bold without a border or background.', 'formidable' ),
857
+ ),
858
+ 'frm_grid_first' => __( 'First Grid Row', 'formidable' ),
859
+ 'frm_grid' => __( 'Even Grid Row', 'formidable' ),
860
+ 'frm_grid_odd' => __( 'Odd Grid Row', 'formidable' ),
861
+ 'frm_two_col' => array(
862
+ 'label' => __( '2 Col Options', 'formidable' ),
863
+ 'title' => __( 'Put your radio button or checkbox options into two columns.', 'formidable' ),
864
+ ),
865
+ 'frm_three_col' => array(
866
+ 'label' => __( '3 Col Options', 'formidable' ),
867
+ 'title' => __( 'Put your radio button or checkbox options into three columns.', 'formidable' ),
868
+ ),
869
+ 'frm_four_col' => array(
870
+ 'label' => __( '4 Col Options', 'formidable' ),
871
+ 'title' => __( 'Put your radio button or checkbox options into four columns.', 'formidable' ),
872
+ ),
873
+ 'frm_scroll_box' => array(
874
+ 'label' => __( 'Scroll Box', 'formidable' ),
875
+ 'title' => __( 'If you have many checkbox or radio button options, you may add this class to allow your user to easily scroll through the options.', 'formidable' ),
876
+ ),
877
+ 'frm_capitalize' => array(
878
+ 'label' => __( 'Capitalize', 'formidable' ),
879
+ 'title' => __( 'Automatically capitalize the first letter in each word.', 'formidable' ),
880
+ ),
881
+ );
882
+
883
+ return apply_filters( 'frm_layout_classes', $classes );
884
+ }
885
+
886
+ public static function grid_classes() {
887
+ return array(
888
+ 'frm_half' => '1/2',
889
+
890
+ 'frm_third' => '1/3',
891
+ 'frm_two_thirds' => '2/3',
892
+
893
+ 'frm_fourth' => '1/4',
894
+ 'frm_three_fourths' => '3/4',
895
+
896
+ 'frm_sixth' => '1/6',
897
+ 'frm10' => '5/6',
898
+
899
+ 'frm11' => '11/12',
900
+ 'frm1' => '1/12',
901
+
902
+ 'frm5' => '5/12',
903
+ 'frm7' => '7/12',
904
+
905
+ 'frm12' => '100%',
906
+ );
907
+ }
908
+
909
+ /**
910
+ * @since 3.0
911
+ */
912
+ public static function style_class_label( $style, $class ) {
913
+ $label = '';
914
+ if ( empty( $style ) ) {
915
+ $label = $class;
916
+ } elseif ( ! is_array( $style ) ) {
917
+ $label = $style;
918
+ } else if ( isset( $style['label'] ) ) {
919
+ $label = $style['label'];
920
+ }
921
+ return $label;
922
+ }
923
 
924
  public static function status_nice_name( $status ) {
925
  $nice_names = array(
936
 
937
  return $name;
938
  }
 
 
 
 
 
 
 
 
 
 
939
  }
classes/helpers/FrmFormsListHelper.php CHANGED
@@ -101,10 +101,6 @@ class FrmFormsListHelper extends FrmListHelper {
101
  public function get_bulk_actions() {
102
  $actions = array();
103
 
104
- if ( in_array( $this->status, array( '', 'published' ) ) ) {
105
- $actions['bulk_create_template'] = __( 'Create Template', 'formidable' );
106
- }
107
-
108
  if ( 'trash' == $this->status ) {
109
  if ( current_user_can('frm_edit_forms') ) {
110
  $actions['bulk_untrash'] = __( 'Restore', 'formidable' );
@@ -225,9 +221,8 @@ class FrmFormsListHelper extends FrmListHelper {
225
  // Set up the hover actions for this user
226
  $actions = array();
227
  $edit_link = '?page=formidable&frm_action=edit&id=' . $item->id;
228
- $duplicate_link = '?page=formidable&frm_action=duplicate&id=' . $item->id;
229
 
230
- $this->get_actions($actions, $item, $edit_link, $duplicate_link);
231
 
232
  $action_links = $this->row_actions( $actions );
233
 
@@ -306,43 +301,29 @@ class FrmFormsListHelper extends FrmListHelper {
306
 
307
  /**
308
  * @param string $edit_link
309
- * @param string $duplicate_link
310
  */
311
- private function get_actions( &$actions, $item, $edit_link, $duplicate_link ) {
312
- if ( 'trash' == $this->status ) {
313
- if ( current_user_can('frm_edit_forms') ) {
314
- $actions['restore'] = FrmFormsHelper::delete_trash_link( $item->id, $item->status, 'short' );
315
- }
316
 
317
- if ( current_user_can('frm_delete_forms') ) {
318
- $trash_url = wp_nonce_url( '?page=formidable&form_status=trash&frm_action=destroy&id=' . $item->id, 'destroy_form_' . $item->id );
319
- $actions['trash'] = '<a href="' . esc_url( $trash_url ) . '" class="submitdelete" onclick="return confirm(\'' . __( 'Are you sure you want to permanently delete that?', 'formidable' ) . '\')">' . __( 'Delete Permanently' ) . '</a>';
320
- }
321
- return;
322
  }
323
 
324
  if ( current_user_can('frm_edit_forms') ) {
325
- if ( ! $item->is_template || ! $item->default_template ) {
326
  $actions['frm_edit'] = '<a href="' . esc_url( $edit_link ) . '">' . __( 'Edit' ) . '</a>';
327
- }
328
 
329
- if ( $item->is_template ) {
330
- $actions['frm_duplicate'] = '<a href="' . esc_url( wp_nonce_url( $duplicate_link ) ) . '">' . __( 'Create Form from Template', 'formidable' ) . '</a>';
331
- } else {
332
  $actions['frm_settings'] = '<a href="' . esc_url( '?page=formidable&frm_action=settings&id=' . $item->id ) . '">' . __( 'Settings', 'formidable' ) . '</a>';
333
-
334
- if ( FrmAppHelper::pro_is_installed() ) {
335
- $actions['duplicate'] = '<a href="' . esc_url( wp_nonce_url( $duplicate_link ) ) . '">' . __( 'Duplicate', 'formidable' ) . '</a>';
336
- }
337
- }
338
- }
339
-
340
- $actions['trash'] = FrmFormsHelper::delete_trash_link( $item->id, $item->status, 'short' );
341
- if ( empty( $actions['trash'] ) ) {
342
- // the user doesn't have permission
343
- unset( $actions['trash'] );
344
  }
345
 
 
346
  $actions['view'] = '<a href="' . esc_url( FrmFormsHelper::get_direct_link( $item->form_key, $item ) ) . '" target="_blank">' . __( 'Preview') . '</a>';
347
  }
348
 
101
  public function get_bulk_actions() {
102
  $actions = array();
103
 
 
 
 
 
104
  if ( 'trash' == $this->status ) {
105
  if ( current_user_can('frm_edit_forms') ) {
106
  $actions['bulk_untrash'] = __( 'Restore', 'formidable' );
221
  // Set up the hover actions for this user
222
  $actions = array();
223
  $edit_link = '?page=formidable&frm_action=edit&id=' . $item->id;
 
224
 
225
+ $this->get_actions( $actions, $item, $edit_link );
226
 
227
  $action_links = $this->row_actions( $actions );
228
 
301
 
302
  /**
303
  * @param string $edit_link
 
304
  */
305
+ private function get_actions( &$actions, $item, $edit_link ) {
306
+ $new_actions = FrmFormsHelper::get_action_links( $item->id, $item );
307
+ foreach ( $new_actions as $link => $action ) {
308
+ $new_actions[ $link ] = FrmFormsHelper::format_link_html( $action, 'short' );
309
+ }
310
 
311
+ if ( 'trash' == $this->status ) {
312
+ $actions = $new_actions;
313
+ return;
 
 
314
  }
315
 
316
  if ( current_user_can('frm_edit_forms') ) {
317
+ if ( ! $item->is_template || ! $item->default_template ) {
318
  $actions['frm_edit'] = '<a href="' . esc_url( $edit_link ) . '">' . __( 'Edit' ) . '</a>';
319
+ }
320
 
321
+ if ( ! $item->is_template ) {
 
 
322
  $actions['frm_settings'] = '<a href="' . esc_url( '?page=formidable&frm_action=settings&id=' . $item->id ) . '">' . __( 'Settings', 'formidable' ) . '</a>';
323
+ }
 
 
 
 
 
 
 
 
 
 
324
  }
325
 
326
+ $actions = array_merge( $actions, $new_actions );
327
  $actions['view'] = '<a href="' . esc_url( FrmFormsHelper::get_direct_link( $item->form_key, $item ) ) . '" target="_blank">' . __( 'Preview') . '</a>';
328
  }
329
 
classes/helpers/FrmListHelper.php CHANGED
@@ -545,54 +545,26 @@ class FrmListHelper {
545
 
546
  $current = $this->get_pagenum();
547
 
548
- $current_url = set_url_scheme( 'http://' . FrmAppHelper::get_server_value( 'HTTP_HOST' ) . FrmAppHelper::get_server_value( 'REQUEST_URI' ) );
549
-
550
- $current_url = remove_query_arg( array( 'hotkeys_highlight_last', 'hotkeys_highlight_first' ), $current_url );
551
-
552
  $page_links = array();
553
 
554
  $total_pages_before = '<span class="paging-input">';
555
  $total_pages_after = '</span>';
556
 
557
- $disable_first = false;
558
- $disable_last = false;
559
- $disable_prev = false;
560
- $disable_next = false;
561
 
562
- if ( $current == 1 ) {
563
- $disable_first = true;
564
- $disable_prev = true;
565
- }
566
- if ( $current == 2 ) {
567
- $disable_first = true;
568
- }
569
- if ( $current == $total_pages ) {
570
- $disable_last = true;
571
- $disable_next = true;
572
- }
573
- if ( $current == $total_pages - 1 ) {
574
- $disable_last = true;
575
- }
576
-
577
- if ( $disable_first ) {
578
- $page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">&laquo;</span>';
579
- } else {
580
- $page_links[] = sprintf( "<a class='first-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
581
- esc_url( remove_query_arg( 'paged', $current_url ) ),
582
- __( 'First page' ),
583
- '&laquo;'
584
- );
585
- }
586
 
587
- if ( $disable_prev ) {
588
- $page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">&lsaquo;</span>';
589
- } else {
590
- $page_links[] = sprintf( "<a class='prev-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
591
- esc_url( add_query_arg( 'paged', max( 1, $current - 1 ), $current_url ) ),
592
- __( 'Previous page' ),
593
- '&lsaquo;'
594
- );
595
- }
596
 
597
  if ( 'bottom' == $which ) {
598
  $html_current_page = $current;
@@ -607,25 +579,19 @@ class FrmListHelper {
607
  $html_total_pages = sprintf( "<span class='total-pages'>%s</span>", number_format_i18n( $total_pages ) );
608
  $page_links[] = $total_pages_before . sprintf( _x( '%1$s of %2$s', 'paging' ), $html_current_page, $html_total_pages ) . $total_pages_after;
609
 
610
- if ( $disable_next ) {
611
- $page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">&rsaquo;</span>';
612
- } else {
613
- $page_links[] = sprintf( "<a class='next-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
614
- esc_url( add_query_arg( 'paged', min( $total_pages, $current + 1 ), $current_url ) ),
615
- __( 'Next page' ),
616
- '&rsaquo;'
617
- );
618
- }
619
 
620
- if ( $disable_last ) {
621
- $page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">&raquo;</span>';
622
- } else {
623
- $page_links[] = sprintf( "<a class='last-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
624
- esc_url( add_query_arg( 'paged', $total_pages, $current_url ) ),
625
- __( 'Last page' ),
626
- '&raquo;'
627
- );
628
- }
629
 
630
  $pagination_links_class = 'pagination-links';
631
  if ( ! empty( $infinite_scroll ) ) {
@@ -643,6 +609,70 @@ class FrmListHelper {
643
  echo $this->_pagination;
644
  }
645
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
646
  /**
647
  * Get a list of sortable columns. The format is:
648
  * 'internal-name' => 'orderby'
545
 
546
  $current = $this->get_pagenum();
547
 
 
 
 
 
548
  $page_links = array();
549
 
550
  $total_pages_before = '<span class="paging-input">';
551
  $total_pages_after = '</span>';
552
 
553
+ $disable = $this->disabled_pages( $total_pages );
 
 
 
554
 
555
+ $page_links[] = $this->add_page_link( array(
556
+ 'page' => 'first',
557
+ 'arrow' => '&laquo;',
558
+ 'number' => '',
559
+ 'disabled' => $disable['first'],
560
+ ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
561
 
562
+ $page_links[] = $this->add_page_link( array(
563
+ 'page' => 'prev',
564
+ 'arrow' => '&lsaquo;',
565
+ 'number' => max( 1, $current - 1 ),
566
+ 'disabled' => $disable['prev'],
567
+ ) );
 
 
 
568
 
569
  if ( 'bottom' == $which ) {
570
  $html_current_page = $current;
579
  $html_total_pages = sprintf( "<span class='total-pages'>%s</span>", number_format_i18n( $total_pages ) );
580
  $page_links[] = $total_pages_before . sprintf( _x( '%1$s of %2$s', 'paging' ), $html_current_page, $html_total_pages ) . $total_pages_after;
581
 
582
+ $page_links[] = $this->add_page_link( array(
583
+ 'page' => 'next',
584
+ 'arrow' => '&rsaquo;',
585
+ 'number' => min( $total_pages, $current + 1 ),
586
+ 'disabled' => $disable['next'],
587
+ ) );
 
 
 
588
 
589
+ $page_links[] = $this->add_page_link( array(
590
+ 'page' => 'last',
591
+ 'arrow' => '&raquo;',
592
+ 'number' => $total_pages,
593
+ 'disabled' => $disable['last'],
594
+ ) );
 
 
 
595
 
596
  $pagination_links_class = 'pagination-links';
597
  if ( ! empty( $infinite_scroll ) ) {
609
  echo $this->_pagination;
610
  }
611
 
612
+ private function disabled_pages( $total_pages ) {
613
+ $current = $this->get_pagenum();
614
+ $disable = array(
615
+ 'first' => false,
616
+ 'last' => false,
617
+ 'prev' => false,
618
+ 'next' => false,
619
+ );
620
+
621
+ if ( $current == 1 ) {
622
+ $disable['first'] = true;
623
+ $disable['prev'] = true;
624
+ } elseif ( $current == 2 ) {
625
+ $disable['first'] = true;
626
+ }
627
+
628
+ if ( $current == $total_pages ) {
629
+ $disable['last'] = true;
630
+ $disable['next'] = true;
631
+ } elseif ( $current == $total_pages - 1 ) {
632
+ $disable['last'] = true;
633
+ }
634
+
635
+ return $disable;
636
+ }
637
+
638
+ private function link_label( $link ) {
639
+ $labels = array(
640
+ 'first' => __( 'First page' ),
641
+ 'last' => __( 'Last page' ),
642
+ 'prev' => __( 'Previous page' ),
643
+ 'next' => __( 'Next page' ),
644
+ );
645
+ return $labels[ $link ];
646
+ }
647
+
648
+ private function current_url() {
649
+ $current_url = set_url_scheme( 'http://' . FrmAppHelper::get_server_value( 'HTTP_HOST' ) . FrmAppHelper::get_server_value( 'REQUEST_URI' ) );
650
+
651
+ return remove_query_arg( array( 'hotkeys_highlight_last', 'hotkeys_highlight_first' ), $current_url );
652
+ }
653
+
654
+ private function add_page_link( $atts ) {
655
+ if ( $atts['disabled'] ) {
656
+ $link = $this->add_disabled_link( $atts['arrow'] );
657
+ } else {
658
+ $link = $this->add_active_link( $atts );
659
+ }
660
+ return $link;
661
+ }
662
+
663
+ private function add_disabled_link( $label ) {
664
+ return '<span class="tablenav-pages-navspan" aria-hidden="true">' . $label . '</span>';
665
+ }
666
+
667
+ private function add_active_link( $atts ) {
668
+ $url = esc_url( add_query_arg( 'paged', $atts['number'], $this->current_url() ) );
669
+ $label = $this->link_label( $atts['page'] );
670
+ return sprintf(
671
+ "<a class='%s-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
672
+ $atts['page'], $url, $label, $atts['arrow']
673
+ );
674
+ }
675
+
676
  /**
677
  * Get a list of sortable columns. The format is:
678
  * 'internal-name' => 'orderby'
classes/helpers/FrmShortcodeHelper.php CHANGED
@@ -25,4 +25,59 @@ class FrmShortcodeHelper {
25
 
26
  return $atts;
27
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  }
25
 
26
  return $atts;
27
  }
28
+
29
+ /**
30
+ * Get the name of the shortcode from the regEx
31
+ *
32
+ * @since 3.0
33
+ * @param array $shortcodes
34
+ * @param int $short_key The position in the shortcodes array
35
+ * @param array $args
36
+ *
37
+ * @return string
38
+ */
39
+ public static function get_shortcode_tag( $shortcodes, $short_key, $args = array() ) {
40
+ $args = wp_parse_args( $args, array(
41
+ 'conditional' => false,
42
+ 'conditional_check' => false,
43
+ 'foreach' => false,
44
+ ) );
45
+ if ( ( $args['conditional'] || $args['foreach'] ) && ! $args['conditional_check'] ) {
46
+ $args['conditional_check'] = true;
47
+ }
48
+
49
+ $prefix = '';
50
+ if ( $args['conditional_check'] ) {
51
+ if ( $args['conditional'] ) {
52
+ $prefix = 'if ';
53
+ } else if ( $args['foreach'] ) {
54
+ $prefix = 'foreach ';
55
+ }
56
+ }
57
+
58
+ $with_tags = $args['conditional_check'] ? 3 : 2;
59
+ if ( ! empty( $shortcodes[ $with_tags ][ $short_key ] ) ) {
60
+ $tag = str_replace( '[' . $prefix, '', $shortcodes[0][ $short_key ] );
61
+ $tag = str_replace(']', '', $tag);
62
+ $tags = explode(' ', $tag);
63
+ if ( is_array($tags) ) {
64
+ $tag = $tags[0];
65
+ }
66
+ } else {
67
+ $tag = $shortcodes[ $with_tags - 1 ][ $short_key ];
68
+ }
69
+
70
+ return $tag;
71
+ }
72
+
73
+ public static function remove_inline_conditions( $no_vars, $code, $replace_with, &$html ) {
74
+ if ( $no_vars ) {
75
+ $html = str_replace( '[if ' . $code . ']', '', $html );
76
+ $html = str_replace( '[/if ' . $code . ']', '', $html );
77
+ } else {
78
+ $html = preg_replace( '/(\[if\s+' . $code . '\])(.*?)(\[\/if\s+' . $code . '\])/mis', '', $html );
79
+ }
80
+
81
+ $html = str_replace( '[' . $code . ']', $replace_with, $html );
82
+ }
83
  }
classes/helpers/FrmStylesHelper.php CHANGED
@@ -257,21 +257,13 @@ class FrmStylesHelper {
257
  }
258
 
259
  public static function hex2rgb( $hex ) {
260
- $hex = str_replace('#', '', $hex);
 
 
261
 
262
- if ( strlen($hex) == 3 ) {
263
- $r = hexdec( substr( $hex, 0, 1 ) . substr( $hex, 0, 1 ) );
264
- $g = hexdec( substr( $hex, 1, 1 ) . substr( $hex, 1, 1 ) );
265
- $b = hexdec( substr( $hex, 2, 1 ) . substr( $hex, 2, 1 ) );
266
- } else {
267
- $r = hexdec( substr( $hex, 0, 2 ) );
268
- $g = hexdec( substr( $hex, 2, 2 ) );
269
- $b = hexdec( substr( $hex, 4, 2 ) );
270
- }
271
  $rgb = array( $r, $g, $b );
272
- return implode(',', $rgb); // returns the rgb values separated by commas
273
- //return $rgb; // returns an array with the rgb values
274
- }
275
 
276
  /**
277
  * @param $hex string - The original color in hex format #ffffff
257
  }
258
 
259
  public static function hex2rgb( $hex ) {
260
+ $hex = str_replace( '#', '', $hex );
261
+
262
+ list( $r, $g, $b ) = sscanf( $hex, '%02x%02x%02x' );
263
 
 
 
 
 
 
 
 
 
 
264
  $rgb = array( $r, $g, $b );
265
+ return implode( ',', $rgb );
266
+ }
 
267
 
268
  /**
269
  * @param $hex string - The original color in hex format #ffffff
classes/helpers/FrmTipsHelper.php CHANGED
@@ -196,12 +196,12 @@ class FrmTipsHelper {
196
  $tips = array(
197
  array(
198
  'link' => '',
199
- 'tip' => __( 'Looking for more options to get professional results?', 'formidable' ),
200
  'call' => __( 'Take your forms to the next level.', 'formidable' ),
201
  ),
202
  array(
203
  'link' => '',
204
- 'tip' => __( 'Increase conversions in your long forms.', 'formidable' ),
205
  'call' => __( 'Add conditional logic, page breaks, and section headings.', 'formidable' ),
206
  ),
207
  array(
196
  $tips = array(
197
  array(
198
  'link' => '',
199
+ 'tip' => __( 'Looking for more ways to get professional results?', 'formidable' ),
200
  'call' => __( 'Take your forms to the next level.', 'formidable' ),
201
  ),
202
  array(
203
  'link' => '',
204
+ 'tip' => __( 'Increase conversions in long forms.', 'formidable' ),
205
  'call' => __( 'Add conditional logic, page breaks, and section headings.', 'formidable' ),
206
  ),
207
  array(
classes/helpers/FrmXMLHelper.php CHANGED
@@ -314,7 +314,7 @@ class FrmXMLHelper {
314
  foreach ( $xml_fields as $field ) {
315
  $f = self::fill_field( $field, $form_id );
316
 
317
- $has_default = array( 'text', 'email', 'url', 'textarea', 'number', 'phone', 'date', 'hidden', 'password', 'tag', 'image' );
318
  if ( is_array( $f['default_value'] ) && in_array( $f['type'], $has_default, true ) ) {
319
  if ( count( $f['default_value'] ) === 1 ) {
320
  $f['default_value'] = '[' . reset( $f['default_value'] ) . ']';
@@ -750,7 +750,8 @@ class FrmXMLHelper {
750
  $v = FrmAppHelper::get_user_id_param($v);
751
  } else if ( '_thumbnail_id' == $k && FrmAppHelper::pro_is_installed() ) {
752
  //change the attachment ID
753
- $v = FrmProXMLHelper::get_file_id($v);
 
754
  }
755
 
756
  update_post_meta($post_id, $k, $v);
314
  foreach ( $xml_fields as $field ) {
315
  $f = self::fill_field( $field, $form_id );
316
 
317
+ $has_default = array( 'text', 'email', 'url', 'textarea', 'number', 'phone', 'date', 'hidden', 'password', 'tag' );
318
  if ( is_array( $f['default_value'] ) && in_array( $f['type'], $has_default, true ) ) {
319
  if ( count( $f['default_value'] ) === 1 ) {
320
  $f['default_value'] = '[' . reset( $f['default_value'] ) . ']';
750
  $v = FrmAppHelper::get_user_id_param($v);
751
  } else if ( '_thumbnail_id' == $k && FrmAppHelper::pro_is_installed() ) {
752
  //change the attachment ID
753
+ $field_obj = FrmFieldFactory::get_field_type( 'file' );
754
+ $v = $field_obj->get_file_id( $v );
755
  }
756
 
757
  update_post_meta($post_id, $k, $v);
classes/models/FrmAddon.php CHANGED
@@ -15,6 +15,7 @@ class FrmAddon {
15
  public $version;
16
  public $author = 'Strategy11';
17
  private $license;
 
18
 
19
  public function __construct() {
20
 
@@ -65,6 +66,7 @@ class FrmAddon {
65
  'version' => $this->version,
66
  'license' => $license,
67
  'author' => $this->author,
 
68
  );
69
  if ( is_numeric( $this->download_id ) ) {
70
  $api_data['item_id'] = $this->download_id;
@@ -137,13 +139,15 @@ class FrmAddon {
137
  public function clear_license() {
138
  delete_option( $this->option_name . 'active' );
139
  delete_option( $this->option_name . 'key' );
140
- delete_site_transient( $this->transient_key() );
 
141
  delete_transient( 'frm_api_licence' );
142
  }
143
 
144
  public function set_active( $is_active ) {
145
  update_option( $this->option_name . 'active', $is_active );
146
  delete_transient( 'frm_api_licence' );
 
147
  }
148
 
149
  public function show_license_message( $file, $plugin ) {
@@ -169,14 +173,19 @@ class FrmAddon {
169
  }
170
  } elseif ( isset( $transient->response ) && isset( $transient->response[ $this->plugin_folder ] ) ) {
171
  $cache_key = $this->version_cache_key();
172
- $version_info = get_transient( $cache_key );
173
 
174
  $this->clear_old_plugin_version( $version_info );
175
 
 
 
 
 
 
176
  if ( false !== $version_info && version_compare( $version_info->new_version, $this->version, '>' ) ) {
177
  $transient->response[ $this->plugin_folder ] = $version_info;
178
  } else {
179
- delete_transient( $cache_key );
180
  if ( ! $this->has_been_cleared() ) {
181
  // if the transient has expired, clear the update and trigger it again
182
  $this->cleared_plugins();
@@ -195,7 +204,8 @@ class FrmAddon {
195
  * @since 2.05.05
196
  */
197
  private function version_cache_key() {
198
- return 'edd_plugin_' . md5( sanitize_key( $this->license . $this->version ) . '_get_version' );
 
199
  }
200
 
201
  /**
@@ -206,16 +216,11 @@ class FrmAddon {
206
  */
207
  private function clear_old_plugin_version( &$version_info ) {
208
  if ( false !== $version_info ) {
209
-
210
- $cache_key = $this->version_cache_key();
211
- $expiration = get_option( '_transient_timeout_' . $cache_key );
212
-
213
- if ( false === $expiration ) {
214
- $last_checked = ( is_array( $version_info->sections ) && isset( $version_info->sections['last_checked'] ) ) ? $version_info->sections['last_checked'] : 0;
215
-
216
- if ( $last_checked < strtotime( '-48 hours' ) ) {
217
- $version_info = false;
218
- }
219
  }
220
  }
221
  }
@@ -247,11 +252,22 @@ class FrmAddon {
247
  return;
248
  }
249
 
250
- $last_checked = get_site_option( $this->transient_key() );
 
 
 
 
 
251
  $seven_days_ago = date( 'Y-m-d H:i:s', strtotime( '-7 days' ) );
252
 
253
  if ( ! $last_checked || $last_checked < $seven_days_ago ) {
254
- update_site_option( $this->transient_key(), date( 'Y-m-d H:i:s' ) ); // check weekly
 
 
 
 
 
 
255
  $response = $this->get_license_status();
256
  if ( 'revoked' === $response['status'] ) {
257
  $this->clear_license();
15
  public $version;
16
  public $author = 'Strategy11';
17
  private $license;
18
+ protected $get_beta = false;
19
 
20
  public function __construct() {
21
 
66
  'version' => $this->version,
67
  'license' => $license,
68
  'author' => $this->author,
69
+ 'beta' => $this->get_beta,
70
  );
71
  if ( is_numeric( $this->download_id ) ) {
72
  $api_data['item_id'] = $this->download_id;
139
  public function clear_license() {
140
  delete_option( $this->option_name . 'active' );
141
  delete_option( $this->option_name . 'key' );
142
+ delete_site_option( $this->transient_key() );
143
+ delete_option( $this->transient_key() );
144
  delete_transient( 'frm_api_licence' );
145
  }
146
 
147
  public function set_active( $is_active ) {
148
  update_option( $this->option_name . 'active', $is_active );
149
  delete_transient( 'frm_api_licence' );
150
+ FrmAppHelper::save_combined_js();
151
  }
152
 
153
  public function show_license_message( $file, $plugin ) {
173
  }
174
  } elseif ( isset( $transient->response ) && isset( $transient->response[ $this->plugin_folder ] ) ) {
175
  $cache_key = $this->version_cache_key();
176
+ $version_info = get_option( $cache_key );
177
 
178
  $this->clear_old_plugin_version( $version_info );
179
 
180
+ if ( is_array( $version_info ) && isset( $version_info['value'] ) ) {
181
+ $version_info = json_decode( $version_info['value'] );
182
+ $version_info->new_version = trim( $version_info->new_version, 'p' );
183
+ }
184
+
185
  if ( false !== $version_info && version_compare( $version_info->new_version, $this->version, '>' ) ) {
186
  $transient->response[ $this->plugin_folder ] = $version_info;
187
  } else {
188
+ delete_option( $cache_key );
189
  if ( ! $this->has_been_cleared() ) {
190
  // if the transient has expired, clear the update and trigger it again
191
  $this->cleared_plugins();
204
  * @since 2.05.05
205
  */
206
  private function version_cache_key() {
207
+ $slug = basename( $this->plugin_file, '.php' );
208
+ return md5( serialize( $slug . $this->version . $this->license . $this->get_beta ) );
209
  }
210
 
211
  /**
216
  */
217
  private function clear_old_plugin_version( &$version_info ) {
218
  if ( false !== $version_info ) {
219
+ $timeout = ( isset( $version_info['timeout'] ) && ! empty( $version_info['timeout'] ) ) ? $version_info['timeout'] : 0;
220
+ if ( empty( $timeout ) || current_time( 'timestamp' ) > $timeout ) {
221
+ $version_info = false; // Cache is expired
222
+ } elseif ( ( ! is_array( $version_info ) || ! isset( $version_info['value'] ) ) ) {
223
+ $version_info = false; // the value isn't formated as expected
 
 
 
 
 
224
  }
225
  }
226
  }
252
  return;
253
  }
254
 
255
+ if ( is_multisite() ) {
256
+ $last_checked = get_site_option( $this->transient_key() );
257
+ } else {
258
+ $last_checked = get_option( $this->transient_key() );
259
+ }
260
+
261
  $seven_days_ago = date( 'Y-m-d H:i:s', strtotime( '-7 days' ) );
262
 
263
  if ( ! $last_checked || $last_checked < $seven_days_ago ) {
264
+ // check weekly
265
+ if ( is_multisite() ) {
266
+ update_site_option( $this->transient_key(), date( 'Y-m-d H:i:s' ) );
267
+ } else {
268
+ update_option( $this->transient_key(), date( 'Y-m-d H:i:s' ) );
269
+ }
270
+
271
  $response = $this->get_license_status();
272
  if ( 'revoked' === $response['status'] ) {
273
  $this->clear_license();
classes/models/FrmCreateFile.php CHANGED
@@ -6,29 +6,40 @@ if ( ! defined( 'ABSPATH' ) ) {
6
 
7
  class FrmCreateFile {
8
 
9
- public $folder_name = '';
10
- public $file_name = '';
11
- public $error_message = '';
12
- public $uploads = array();
 
13
  public $chmod_dir = 0755;
14
  public $chmod_file = 0644;
 
15
 
16
  public function __construct( $atts ) {
17
- $this->folder_name = $atts['folder_name'];
18
  $this->file_name = $atts['file_name'];
19
  $this->error_message = isset( $atts['error_message'] ) ? $atts['error_message'] : '';
20
  $this->uploads = wp_upload_dir();
 
21
  $this->chmod_dir = defined('FS_CHMOD_DIR') ? FS_CHMOD_DIR : ( fileperms( ABSPATH ) & 0777 | 0755 );
22
  $this->chmod_file = defined('FS_CHMOD_FILE') ? FS_CHMOD_FILE : ( fileperms( ABSPATH . 'index.php' ) & 0777 | 0644 );
23
- }
24
 
25
- public function create_file( $file_content ) {
26
- $creds = $this->get_creds();
27
 
28
- if ( empty( $creds ) || ! WP_Filesystem( $creds ) ) {
29
- // initialize the API - any problems and we exit
30
- $this->show_error_message();
 
 
 
31
  } else {
 
 
 
 
 
 
32
  $dirs_exist = true;
33
 
34
  // Create the directories if need be
@@ -37,10 +48,80 @@ class FrmCreateFile {
37
  // only write the file if the folders exist
38
  if ( $dirs_exist ) {
39
  global $wp_filesystem;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
- $new_file = $this->uploads['basedir'] . '/' . $this->folder_name . '/' . $this->file_name;
42
- $wp_filesystem->put_contents( $new_file, $file_content, $this->chmod_file );
 
 
 
 
 
 
 
 
 
 
 
43
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  }
45
  }
46
 
@@ -50,11 +131,11 @@ class FrmCreateFile {
50
  $needed_dirs = $this->get_needed_dirs();
51
  foreach ( $needed_dirs as $_dir ) {
52
  // Only check to see if the Dir exists upon creation failure. Less I/O this way.
53
- if ( $wp_filesystem->mkdir( $_dir, $this->chmod_dir ) || $wp_filesystem->is_dir( $_dir ) ) {
54
  $index_path = $_dir . '/index.php';
55
  $wp_filesystem->put_contents( $index_path, "<?php\n// Silence is golden.\n?>", $this->chmod_file );
56
  } else {
57
- $dirs_exist = false;
58
  }
59
  }
60
  }
@@ -73,6 +154,10 @@ class FrmCreateFile {
73
  }
74
 
75
  private function get_creds() {
 
 
 
 
76
  $access_type = get_filesystem_method();
77
  if ( $access_type === 'direct' ) {
78
  $creds = request_filesystem_credentials( site_url() . '/wp-admin/', '', false, false, array() );
6
 
7
  class FrmCreateFile {
8
 
9
+ public $folder_name;
10
+ public $file_name;
11
+ public $error_message;
12
+ public $uploads;
13
+ private $new_file_path;
14
  public $chmod_dir = 0755;
15
  public $chmod_file = 0644;
16
+ private $has_permission = false;
17
 
18
  public function __construct( $atts ) {
19
+ $this->folder_name = isset( $atts['folder_name'] ) ? $atts['folder_name'] : '';
20
  $this->file_name = $atts['file_name'];
21
  $this->error_message = isset( $atts['error_message'] ) ? $atts['error_message'] : '';
22
  $this->uploads = wp_upload_dir();
23
+ $this->set_new_file_path( $atts );
24
  $this->chmod_dir = defined('FS_CHMOD_DIR') ? FS_CHMOD_DIR : ( fileperms( ABSPATH ) & 0777 | 0755 );
25
  $this->chmod_file = defined('FS_CHMOD_FILE') ? FS_CHMOD_FILE : ( fileperms( ABSPATH . 'index.php' ) & 0777 | 0644 );
 
26
 
27
+ $this->check_permission();
28
+ }
29
 
30
+ /**
31
+ * @since 3.0
32
+ */
33
+ private function set_new_file_path( $atts ) {
34
+ if ( isset( $atts['new_file_path'] ) ) {
35
+ $this->new_file_path = $atts['new_file_path'] . '/' . $this->file_name;
36
  } else {
37
+ $this->new_file_path = $this->uploads['basedir'] . '/' . $this->folder_name . '/' . $this->file_name;
38
+ }
39
+ }
40
+
41
+ public function create_file( $file_content ) {
42
+ if ( $this->has_permission ) {
43
  $dirs_exist = true;
44
 
45
  // Create the directories if need be
48
  // only write the file if the folders exist
49
  if ( $dirs_exist ) {
50
  global $wp_filesystem;
51
+ $wp_filesystem->put_contents( $this->new_file_path, $file_content, $this->chmod_file );
52
+ }
53
+ }
54
+ }
55
+
56
+ /**
57
+ * @since 3.0
58
+ */
59
+ public function append_file( $file_content ) {
60
+ if ( $this->has_permission ) {
61
+
62
+ if ( file_exists( $this->new_file_path ) ) {
63
+
64
+ $existing_content = $this->get_contents();
65
+ $file_content = $existing_content . $file_content;
66
+ }
67
+
68
+ $this->create_file( $file_content );
69
+ }
70
+ }
71
 
72
+ /**
73
+ * Combine an array of files into one
74
+ *
75
+ * @since 3.0
76
+ *
77
+ * @param array $file_names And array of file paths
78
+ * @param string $new_location The path for the file to be saved
79
+ */
80
+ public function combine_files( $file_names ) {
81
+ if ( $this->has_permission ) {
82
+ $content = '';
83
+ foreach ( $file_names as $file_name ) {
84
+ $content .= $this->get_contents( $file_name ) . "\n";
85
  }
86
+ $this->create_file( $content );
87
+ }
88
+ }
89
+
90
+ /**
91
+ * @since 3.0
92
+ */
93
+ public function get_file_contents() {
94
+ $content = '';
95
+
96
+ if ( $this->has_permission ) {
97
+ $content = $this->get_contents();
98
+ }
99
+
100
+ return $content;
101
+ }
102
+
103
+ /**
104
+ * @since 3.0
105
+ */
106
+ private function get_contents( $file = '' ) {
107
+ global $wp_filesystem;
108
+ if ( empty( $file ) ) {
109
+ $file = $this->new_file_path;
110
+ }
111
+ return $wp_filesystem->get_contents( $file );
112
+ }
113
+
114
+ /**
115
+ * @since 3.0
116
+ */
117
+ private function check_permission() {
118
+ $creds = $this->get_creds();
119
+
120
+ $this->has_permission = true;
121
+ if ( empty( $creds ) || ! WP_Filesystem( $creds ) ) {
122
+ // initialize the API - any problems and we exit
123
+ $this->show_error_message();
124
+ $this->has_permission = false;
125
  }
126
  }
127
 
131
  $needed_dirs = $this->get_needed_dirs();
132
  foreach ( $needed_dirs as $_dir ) {
133
  // Only check to see if the Dir exists upon creation failure. Less I/O this way.
134
+ if ( $wp_filesystem->mkdir( $_dir, $this->chmod_dir ) ) {
135
  $index_path = $_dir . '/index.php';
136
  $wp_filesystem->put_contents( $index_path, "<?php\n// Silence is golden.\n?>", $this->chmod_file );
137
  } else {
138
+ $dirs_exist = $wp_filesystem->is_dir( $_dir );
139
  }
140
  }
141
  }
154
  }
155
 
156
  private function get_creds() {
157
+ if ( ! function_exists('get_filesystem_method') ) {
158
+ include_once( ABSPATH . 'wp-admin/includes/file.php' );
159
+ }
160
+
161
  $access_type = get_filesystem_method();
162
  if ( $access_type === 'direct' ) {
163
  $creds = request_filesystem_credentials( site_url() . '/wp-admin/', '', false, false, array() );
classes/models/FrmDb.php CHANGED
@@ -169,7 +169,8 @@ class FrmDb {
169
  */
170
  private static function add_query_placeholder( $key, $value, &$where ) {
171
  if ( is_numeric( $value ) && ( strpos( $key, 'meta_value' ) === false || strpos( $key, '+0' ) !== false ) ) {
172
- $where .= '%d';
 
173
  } else {
174
  $where .= '%s';
175
  }
@@ -408,7 +409,7 @@ class FrmDb {
408
  } else {
409
  /**
410
  * Allow the $where to be prepared before we recieve it here.
411
- * This is a fallback for reverse compatability, but is not recommended
412
  */
413
  _deprecated_argument( 'where', '2.0', __( 'Use the query in an array format so it can be properly prepared.', 'formidable' ) );
414
  $query .= $where . ' ' . implode( ' ', $args );
169
  */
170
  private static function add_query_placeholder( $key, $value, &$where ) {
171
  if ( is_numeric( $value ) && ( strpos( $key, 'meta_value' ) === false || strpos( $key, '+0' ) !== false ) ) {
172
+ $value = $value + 0; // switch string to number
173
+ $where .= is_float( $value ) ? '%f' : '%d';
174
  } else {
175
  $where .= '%s';
176
  }
409
  } else {
410
  /**
411
  * Allow the $where to be prepared before we recieve it here.
412
+ * This is a fallback for reverse compatibility, but is not recommended
413
  */
414
  _deprecated_argument( 'where', '2.0', __( 'Use the query in an array format so it can be properly prepared.', 'formidable' ) );
415
  $query .= $where . ' ' . implode( ' ', $args );
classes/models/FrmEDD_SL_Plugin_Updater.php CHANGED
@@ -1,8 +1,5 @@
1
  <?php
2
 
3
- // uncomment this line for testing
4
- //set_site_transient( 'update_plugins', null );
5
-
6
  // Exit if accessed directly
7
  if ( ! defined( 'ABSPATH' ) ) {
8
  exit;
@@ -22,6 +19,7 @@ class FrmEDD_SL_Plugin_Updater {
22
  private $slug = '';
23
  private $version = '';
24
  private $wp_override = false;
 
25
 
26
  /**
27
  * Class constructor.
@@ -42,6 +40,8 @@ class FrmEDD_SL_Plugin_Updater {
42
  $this->slug = basename( $_plugin_file, '.php' );
43
  $this->version = $_api_data['version'];
44
  $this->wp_override = isset( $_api_data['wp_override'] ) ? (bool) $_api_data['wp_override'] : false;
 
 
45
 
46
  $frm_edd_plugin_data[ $this->slug ] = $this->api_data;
47
 
@@ -87,7 +87,17 @@ class FrmEDD_SL_Plugin_Updater {
87
  return $_transient_data;
88
  }
89
 
90
- $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug ) );
 
 
 
 
 
 
 
 
 
 
91
 
92
  if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
93
 
@@ -101,7 +111,7 @@ class FrmEDD_SL_Plugin_Updater {
101
 
102
  }
103
 
104
- $_transient_data->last_checked = time();
105
  $_transient_data->checked[ $this->name ] = $this->version;
106
 
107
  }
@@ -137,15 +147,49 @@ class FrmEDD_SL_Plugin_Updater {
137
  'slug' => $this->slug,
138
  'is_ssl' => is_ssl(),
139
  'fields' => array(
140
- 'banners' => false, // These will be supported soon hopefully
141
  'reviews' => false,
142
  ),
143
  );
144
 
145
- $api_response = $this->api_request( 'plugin_information', $to_send );
146
 
147
- if ( false !== $api_response ) {
148
- $_data = $api_response;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  }
150
 
151
  return $_data;
@@ -161,7 +205,7 @@ class FrmEDD_SL_Plugin_Updater {
161
  public function http_request_args( $args, $url ) {
162
  // If it is an https request and we are performing a package download, disable ssl verification
163
  if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
164
- $args['sslverify'] = false;
165
  }
166
  return $args;
167
  }
@@ -196,21 +240,16 @@ class FrmEDD_SL_Plugin_Updater {
196
  'license' => ! empty( $data['license'] ) ? $data['license'] : '',
197
  'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false,
198
  'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
 
199
  'slug' => $data['slug'],
200
  'author' => $data['author'],
201
  'url' => home_url(),
 
202
  );
203
 
204
- $cache_key = 'edd_plugin_' . md5( sanitize_key( $api_params['license'] . $this->version ) . '_' . $api_params['edd_action'] );
205
- $cached_response = get_transient( $cache_key );
206
- if ( $cached_response !== false ) {
207
- // if this has been checked within 24 hours, don't check again
208
- return $cached_response;
209
- }
210
-
211
  $request = wp_remote_post( $this->api_url, array(
212
  'timeout' => 15,
213
- 'sslverify' => false,
214
  'body' => $api_params,
215
  ) );
216
 
@@ -218,33 +257,38 @@ class FrmEDD_SL_Plugin_Updater {
218
  $request = json_decode( wp_remote_retrieve_body( $request ) );
219
  }
220
 
 
 
 
 
 
 
221
  if ( $request && isset( $request->sections ) ) {
222
  $request->sections = maybe_unserialize( $request->sections );
223
- if ( is_array( $request->sections ) ) {
224
- $request->sections['last_checked'] = time();
225
- }
226
- set_transient( $cache_key, $request, DAY_IN_SECONDS );
227
  } else {
228
  $request = false;
229
- set_transient( $cache_key, 0, DAY_IN_SECONDS );
230
  }
231
 
232
- return $request;
 
 
 
 
 
 
 
 
233
  }
234
 
235
  public function show_changelog() {
236
 
237
  global $frm_edd_plugin_data;
238
 
239
- if ( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' != $_REQUEST['edd_sl_action'] ) {
240
- return;
241
- }
242
-
243
- if ( empty( $_REQUEST['plugin'] ) ) {
244
  return;
245
  }
246
 
247
- if ( empty( $_REQUEST['slug'] ) ) {
248
  return;
249
  }
250
 
@@ -253,7 +297,8 @@ class FrmEDD_SL_Plugin_Updater {
253
  }
254
 
255
  $data = $frm_edd_plugin_data[ $_REQUEST['slug'] ];
256
- $cache_key = md5( 'edd_plugin_' . sanitize_key( $_REQUEST['plugin'] ) . '_version_info' );
 
257
  $version_info = get_transient( $cache_key );
258
 
259
  if ( false === $version_info ) {
@@ -262,14 +307,15 @@ class FrmEDD_SL_Plugin_Updater {
262
  'edd_action' => 'get_version',
263
  'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false,
264
  'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
265
- 'slug' => $_REQUEST['slug'],
266
  'author' => $data['author'],
267
  'url' => home_url(),
 
268
  );
269
 
270
  $request = wp_remote_post( $this->api_url, array(
271
  'timeout' => 15,
272
- 'sslverify' => false,
273
  'body' => $api_params,
274
  ) );
275
 
@@ -283,7 +329,13 @@ class FrmEDD_SL_Plugin_Updater {
283
  $version_info = false;
284
  }
285
 
286
- set_transient( $cache_key, $version_info, DAY_IN_SECONDS );
 
 
 
 
 
 
287
 
288
  }
289
 
@@ -293,4 +345,25 @@ class FrmEDD_SL_Plugin_Updater {
293
 
294
  exit;
295
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296
  }
1
  <?php
2
 
 
 
 
3
  // Exit if accessed directly
4
  if ( ! defined( 'ABSPATH' ) ) {
5
  exit;
19
  private $slug = '';
20
  private $version = '';
21
  private $wp_override = false;
22
+ private $beta = false;
23
 
24
  /**
25
  * Class constructor.
40
  $this->slug = basename( $_plugin_file, '.php' );
41
  $this->version = $_api_data['version'];
42
  $this->wp_override = isset( $_api_data['wp_override'] ) ? (bool) $_api_data['wp_override'] : false;
43
+ $this->beta = ! empty( $this->api_data['beta'] );
44
+ $this->cache_key = md5( serialize( $this->slug . $this->version . $this->api_data['license'] . $this->beta ) );
45
 
46
  $frm_edd_plugin_data[ $this->slug ] = $this->api_data;
47
 
87
  return $_transient_data;
88
  }
89
 
90
+ $version_info = $this->get_cached_version_info( $this->cache_key );
91
+
92
+ if ( false === $version_info ) {
93
+ $version_info = $this->api_request( 'plugin_latest_version', array(
94
+ 'slug' => $this->slug,
95
+ 'beta' => $this->beta,
96
+ ) );
97
+
98
+ $this->set_version_info_cache( $version_info, $this->cache_key );
99
+
100
+ }
101
 
102
  if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
103
 
111
 
112
  }
113
 
114
+ $_transient_data->last_checked = current_time( 'timestamp' );
115
  $_transient_data->checked[ $this->name ] = $this->version;
116
 
117
  }
147
  'slug' => $this->slug,
148
  'is_ssl' => is_ssl(),
149
  'fields' => array(
150
+ 'banners' => array(),
151
  'reviews' => false,
152
  ),
153
  );
154
 
155
+ $cache_key = 'edd_api_request_' . $this->cache_key;
156
 
157
+ // Get the transient where we store the api request for this plugin for 24 hours
158
+ $edd_api_request_transient = $this->get_cached_version_info( $cache_key );
159
+
160
+ //If we have no transient-saved value, run the API, set a fresh transient with the API value, and return that value too right now.
161
+ if ( empty( $edd_api_request_transient ) ) {
162
+
163
+ $api_response = $this->api_request( 'plugin_information', $to_send );
164
+
165
+ // Expires in 3 hours
166
+ $this->set_version_info_cache( $api_response, $cache_key );
167
+
168
+ if ( false !== $api_response ) {
169
+ $_data = $api_response;
170
+ }
171
+ } else {
172
+ $_data = $edd_api_request_transient;
173
+ }
174
+
175
+ // Convert sections into an associative array, since we're getting an object, but Core expects an array.
176
+ if ( isset( $_data->sections ) && ! is_array( $_data->sections ) ) {
177
+ $new_sections = array();
178
+ foreach ( $_data->sections as $key => $value ) {
179
+ $new_sections[ $key ] = $value;
180
+ }
181
+
182
+ $_data->sections = $new_sections;
183
+ }
184
+
185
+ // Convert banners into an associative array, since we're getting an object, but Core expects an array.
186
+ if ( isset( $_data->banners ) && ! is_array( $_data->banners ) ) {
187
+ $new_banners = array();
188
+ foreach ( $_data->banners as $key => $value ) {
189
+ $new_banners[ $key ] = $value;
190
+ }
191
+
192
+ $_data->banners = $new_banners;
193
  }
194
 
195
  return $_data;
205
  public function http_request_args( $args, $url ) {
206
  // If it is an https request and we are performing a package download, disable ssl verification
207
  if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
208
+ $args['sslverify'] = true;
209
  }
210
  return $args;
211
  }
240
  'license' => ! empty( $data['license'] ) ? $data['license'] : '',
241
  'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false,
242
  'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
243
+ 'version' => isset( $data['version'] ) ? $data['version'] : false,
244
  'slug' => $data['slug'],
245
  'author' => $data['author'],
246
  'url' => home_url(),
247
+ 'beta' => ! empty( $data['beta'] ),
248
  );
249
 
 
 
 
 
 
 
 
250
  $request = wp_remote_post( $this->api_url, array(
251
  'timeout' => 15,
252
+ 'sslverify' => true,
253
  'body' => $api_params,
254
  ) );
255
 
257
  $request = json_decode( wp_remote_retrieve_body( $request ) );
258
  }
259
 
260
+ $this->prepare_response( $request );
261
+
262
+ return $request;
263
+ }
264
+
265
+ private function prepare_response( &$request ) {
266
  if ( $request && isset( $request->sections ) ) {
267
  $request->sections = maybe_unserialize( $request->sections );
 
 
 
 
268
  } else {
269
  $request = false;
 
270
  }
271
 
272
+ if ( $request && isset( $request->banners ) ) {
273
+ $request->banners = maybe_unserialize( $request->banners );
274
+ }
275
+
276
+ if ( ! empty( $request->sections ) ) {
277
+ foreach ( $request->sections as $key => $section ) {
278
+ $request->$key = (array) $section;
279
+ }
280
+ }
281
  }
282
 
283
  public function show_changelog() {
284
 
285
  global $frm_edd_plugin_data;
286
 
287
+ if ( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' !== $_REQUEST['edd_sl_action'] ) {
 
 
 
 
288
  return;
289
  }
290
 
291
+ if ( empty( $_REQUEST['plugin'] ) || empty( $_REQUEST['slug'] ) ) {
292
  return;
293
  }
294
 
297
  }
298
 
299
  $data = $frm_edd_plugin_data[ $_REQUEST['slug'] ];
300
+ $beta = ! empty( $data['beta'] );
301
+ $cache_key = md5( 'edd_plugin_' . sanitize_key( $_REQUEST['plugin'] ) . '_' . $beta . '_version_info' );
302
  $version_info = get_transient( $cache_key );
303
 
304
  if ( false === $version_info ) {
307
  'edd_action' => 'get_version',
308
  'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false,
309
  'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
310
+ 'slug' => sanitize_text_field( $_REQUEST['slug'] ),
311
  'author' => $data['author'],
312
  'url' => home_url(),
313
+ 'beta' => $beta,
314
  );
315
 
316
  $request = wp_remote_post( $this->api_url, array(
317
  'timeout' => 15,
318
+ 'sslverify' => true,
319
  'body' => $api_params,
320
  ) );
321
 
329
  $version_info = false;
330
  }
331
 
332
+ if ( ! empty( $version_info ) ) {
333
+ foreach ( $version_info->sections as $key => $section ) {
334
+ $version_info->$key = (array) $section;
335
+ }
336
+ }
337
+
338
+ $this->set_version_info_cache( $version_info, $cache_key );
339
 
340
  }
341
 
345
 
346
  exit;
347
  }
348
+
349
+ public function get_cached_version_info( $cache_key = '' ) {
350
+ $cache = get_option( $cache_key );
351
+
352
+ if ( empty( $cache['timeout'] ) || current_time( 'timestamp' ) > $cache['timeout'] ) {
353
+ return false; // Cache is expired
354
+ }
355
+
356
+ return json_decode( $cache['value'] );
357
+
358
+ }
359
+
360
+ public function set_version_info_cache( $value = '', $cache_key = '' ) {
361
+ $data = array(
362
+ 'timeout' => strtotime( '+24 hours', current_time( 'timestamp' ) ),
363
+ 'value' => json_encode( $value ),
364
+ );
365
+
366
+ update_option( $cache_key, $data );
367
+
368
+ }
369
  }
classes/models/FrmEntry.php CHANGED
@@ -248,7 +248,11 @@ class FrmEntry {
248
  * @since 2.0.11
249
  */
250
  public static function get_new_entry_name( $values, $default = '' ) {
251
- return isset( $values['item_name'] ) ? $values['item_name'] : ( isset( $values['name'] ) ? $values['name'] : $default );
 
 
 
 
252
  }
253
 
254
  /**
@@ -259,6 +263,8 @@ class FrmEntry {
259
  public static function maybe_get_entry( &$entry ) {
260
  if ( $entry && is_numeric( $entry ) ) {
261
  $entry = self::getOne( $entry );
 
 
262
  }
263
  }
264
 
@@ -556,10 +562,6 @@ class FrmEntry {
556
  'user_id' => self::get_entry_user_id( $values ),
557
  );
558
 
559
- if ( is_array($new_values['name']) ) {
560
- $new_values['name'] = reset($new_values['name']);
561
- }
562
-
563
  $new_values['updated_by'] = isset($values['updated_by']) ? $values['updated_by'] : $new_values['user_id'];
564
 
565
  return $new_values;
@@ -881,44 +883,4 @@ class FrmEntry {
881
  $entry_id = FrmDb::get_var( 'frm_items', array( 'item_key' => sanitize_title( $key ) ) );
882
  return $entry_id;
883
  }
884
-
885
- public static function validate( $values, $exclude = false ) {
886
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::validate' );
887
- return FrmEntryValidate::validate( $values, $exclude );
888
- }
889
-
890
- public static function validate_field( $posted_field, &$errors, $values, $args = array() ) {
891
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::validate_field' );
892
- FrmEntryValidate::validate_field( $posted_field, $errors, $values, $args );
893
- }
894
-
895
- public static function validate_url_field( &$errors, $field, &$value, $args ) {
896
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::validate_url_field' );
897
- FrmEntryValidate::validate_url_field( $errors, $field, $value, $args );
898
- }
899
-
900
- public static function validate_email_field( &$errors, $field, $value, $args ) {
901
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::validate_email_field' );
902
- FrmEntryValidate::validate_email_field( $errors, $field, $value, $args );
903
- }
904
-
905
- public static function validate_recaptcha( &$errors, $field, $args ) {
906
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::validate_recaptcha' );
907
- FrmEntryValidate::validate_recaptcha( $errors, $field, $args );
908
- }
909
-
910
- public static function spam_check( $exclude, $values, &$errors ) {
911
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::spam_check' );
912
- FrmEntryValidate::spam_check( $exclude, $values, $errors );
913
- }
914
-
915
- public static function blacklist_check( $values ) {
916
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::blacklist_check' );
917
- return FrmEntryValidate::blacklist_check( $values );
918
- }
919
-
920
- public static function akismet( $values ) {
921
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::akismet' );
922
- return FrmEntryValidate::akismet( $values );
923
- }
924
  }
248
  * @since 2.0.11
249
  */
250
  public static function get_new_entry_name( $values, $default = '' ) {
251
+ $name = isset( $values['item_name'] ) ? $values['item_name'] : ( isset( $values['name'] ) ? $values['name'] : $default );
252
+ if ( is_array( $name ) ) {
253
+ $name = reset( $name );
254
+ }
255
+ return $name;
256
  }
257
 
258
  /**
263
  public static function maybe_get_entry( &$entry ) {
264
  if ( $entry && is_numeric( $entry ) ) {
265
  $entry = self::getOne( $entry );
266
+ } elseif ( empty( $entry ) ) {
267
+ $entry = false;
268
  }
269
  }
270
 
562
  'user_id' => self::get_entry_user_id( $values ),
563
  );
564
 
 
 
 
 
565
  $new_values['updated_by'] = isset($values['updated_by']) ? $values['updated_by'] : $new_values['user_id'];
566
 
567
  return $new_values;
883
  $entry_id = FrmDb::get_var( 'frm_items', array( 'item_key' => sanitize_title( $key ) ) );
884
  return $entry_id;
885
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
886
  }
classes/models/FrmEntryFormatter.php CHANGED
@@ -73,9 +73,15 @@ class FrmEntryFormatter {
73
 
74
  /**
75
  * @var array
76
- * @since 2.04
 
 
 
 
 
 
77
  */
78
- protected $skip_fields = array( 'captcha', 'html' );
79
 
80
  /**
81
  * FrmEntryFormat constructor
@@ -97,12 +103,16 @@ class FrmEntryFormatter {
97
  $this->init_include_blank( $atts );
98
  $this->init_direction( $atts );
99
  $this->init_include_user_info( $atts );
 
 
100
  $this->init_entry_values( $atts );
101
 
102
  if ( $this->format === 'table' ) {
103
  $this->init_table_generator( $atts );
104
  $this->init_is_clickable( $atts );
105
  }
 
 
106
  }
107
 
108
  /**
@@ -133,8 +143,30 @@ class FrmEntryFormatter {
133
  * @param array $atts
134
  */
135
  protected function init_entry_values( $atts ) {
136
- $atts['source'] = 'entry_formatter';
137
- $this->entry_values = new FrmEntryValues( $this->entry->id, $atts );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
  }
139
 
140
  /**
@@ -231,6 +263,37 @@ class FrmEntryFormatter {
231
  }
232
  }
233
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
  /**
235
  * Set the table_generator property
236
  *
@@ -255,6 +318,27 @@ class FrmEntryFormatter {
255
  }
256
  }
257
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
258
  /**
259
  * Get the field key or ID, depending on array_key property
260
  *
@@ -309,10 +393,7 @@ class FrmEntryFormatter {
309
  protected function prepare_html_table() {
310
  $content = $this->table_generator->generate_table_header();
311
 
312
- foreach ( $this->entry_values->get_field_values() as $field_id => $field_value ) {
313
- $this->add_field_value_to_content( $field_value, $content );
314
- }
315
-
316
  $this->add_user_info_to_html_table( $content );
317
 
318
  $content .= $this->table_generator->generate_table_footer();
@@ -324,6 +405,24 @@ class FrmEntryFormatter {
324
  return $content;
325
  }
326
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
  /**
328
  * Return the formatted plain text content
329
  *
@@ -334,10 +433,7 @@ class FrmEntryFormatter {
334
  protected function prepare_plain_text_block() {
335
  $content = '';
336
 
337
- foreach ( $this->entry_values->get_field_values() as $field_id => $field_value ) {
338
- $this->add_field_value_to_content( $field_value, $content );
339
- }
340
-
341
  $this->add_user_info_to_plain_text_content( $content );
342
 
343
  return $content;
@@ -368,6 +464,10 @@ class FrmEntryFormatter {
368
  */
369
  protected function push_field_values_to_array( $field_values, &$output ) {
370
  foreach ( $field_values as $field_value ) {
 
 
 
 
371
  $this->push_single_field_to_array( $field_value, $output );
372
  }
373
  }
@@ -420,6 +520,43 @@ class FrmEntryFormatter {
420
  * @param string $content
421
  */
422
  protected function add_field_value_to_content( $field_value, &$content ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
423
  if ( ! $this->include_field_in_content( $field_value ) ) {
424
  return;
425
  }
@@ -432,6 +569,111 @@ class FrmEntryFormatter {
432
  }
433
  }
434
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
435
  /**
436
  * Package the value arguments for an HTML row
437
  *
@@ -501,18 +743,9 @@ class FrmEntryFormatter {
501
  $include = true;
502
 
503
  if ( $this->is_extra_field( $field_value ) ) {
504
-
505
  $include = $this->is_extra_field_included( $field_value );
506
-
507
- } else {
508
- $displayed_value = $field_value->get_displayed_value();
509
-
510
- if ( $displayed_value === '' || ( is_array( $displayed_value ) && empty( $displayed_value ) ) ) {
511
-
512
- if ( ! $this->include_blank ) {
513
- $include = false;
514
- }
515
- }
516
  }
517
 
518
  return $include;
@@ -528,7 +761,7 @@ class FrmEntryFormatter {
528
  * @return bool
529
  */
530
  protected function is_extra_field( $field_value ) {
531
- return in_array( $field_value->get_field_type(), $this->skip_fields );
532
  }
533
 
534
  /**
@@ -589,7 +822,7 @@ class FrmEntryFormatter {
589
  */
590
  protected function prepare_display_value_for_html_table( $display_value, $field_type = '' ) {
591
  $display_value = $this->flatten_array( $display_value );
592
- $display_value = str_replace( "\r\n", '<br/>', $display_value );
593
 
594
  return $display_value;
595
  }
73
 
74
  /**
75
  * @var array
76
+ * @since 3.0
77
+ */
78
+ protected $single_cell_fields = array();
79
+
80
+ /**
81
+ * @var array
82
+ * @since 3.0
83
  */
84
+ protected $atts = array();
85
 
86
  /**
87
  * FrmEntryFormat constructor
103
  $this->init_include_blank( $atts );
104
  $this->init_direction( $atts );
105
  $this->init_include_user_info( $atts );
106
+ $this->init_include_extras( $atts );
107
+ $this->init_single_cell_fields();
108
  $this->init_entry_values( $atts );
109
 
110
  if ( $this->format === 'table' ) {
111
  $this->init_table_generator( $atts );
112
  $this->init_is_clickable( $atts );
113
  }
114
+
115
+ $this->init_atts( $atts );
116
  }
117
 
118
  /**
143
  * @param array $atts
144
  */
145
  protected function init_entry_values( $atts ) {
146
+ $entry_atts = $this->prepare_entry_attributes( $atts );
147
+ $this->entry_values = new FrmEntryValues( $this->entry->id, $entry_atts );
148
+ }
149
+
150
+ /**
151
+ * Prepare attributes array for FrmEntryValues constructor
152
+ *
153
+ * @since 2.05
154
+ *
155
+ * @param array $atts
156
+ *
157
+ * @return array
158
+ */
159
+ protected function prepare_entry_attributes( $atts ) {
160
+ $entry_atts = array();
161
+
162
+ $conditionally_add = array( 'include_fields', 'fields', 'exclude_fields' );
163
+ foreach ( $conditionally_add as $index ) {
164
+ if ( isset( $atts[ $index ] ) ) {
165
+ $entry_atts[ $index ] = $atts[ $index ];
166
+ }
167
+ }
168
+
169
+ return $entry_atts;
170
  }
171
 
172
  /**
263
  }
264
  }
265
 
266
+ /**
267
+ * Which fields to skip by default
268
+ *
269
+ * @since 3.0
270
+ */
271
+ protected function skip_fields() {
272
+ return array( 'captcha', 'html' );
273
+ }
274
+
275
+ /**
276
+ * Set the include_extras property
277
+ *
278
+ * @since 3.0
279
+ *
280
+ * @param array $atts
281
+ */
282
+ protected function init_include_extras( $atts ) {
283
+ if ( isset( $atts['include_extras'] ) && $atts['include_extras'] ) {
284
+ $this->include_extras = array_map( 'strtolower', array_map( 'trim', explode( ',', $atts['include_extras'] ) ) );
285
+ }
286
+ }
287
+
288
+ /**
289
+ * Initialize the single_cell_fields property
290
+ *
291
+ * @since 3.0
292
+ */
293
+ protected function init_single_cell_fields() {
294
+ $this->single_cell_fields = array( 'html' );
295
+ }
296
+
297
  /**
298
  * Set the table_generator property
299
  *
318
  }
319
  }
320
 
321
+ /**
322
+ * Save the passed atts for other calls. Exclude some attributes to prevent
323
+ * interaction with processing field values like time format.
324
+ *
325
+ * @since 3.0
326
+ */
327
+ protected function init_atts( $atts ) {
328
+ $atts['source'] = 'entry_formatter';
329
+ $atts['wpautop'] = false;
330
+ $atts['return_array'] = true;
331
+
332
+ $unset = array( 'id', 'entry', 'form_id', 'format', 'plain_text' );
333
+ foreach ( $unset as $param ) {
334
+ if ( isset( $atts[ $param ] ) ) {
335
+ unset( $atts[ $param ] );
336
+ }
337
+ }
338
+
339
+ $this->atts = $atts;
340
+ }
341
+
342
  /**
343
  * Get the field key or ID, depending on array_key property
344
  *
393
  protected function prepare_html_table() {
394
  $content = $this->table_generator->generate_table_header();
395
 
396
+ $this->add_field_values_to_content( $content );
 
 
 
397
  $this->add_user_info_to_html_table( $content );
398
 
399
  $content .= $this->table_generator->generate_table_footer();
405
  return $content;
406
  }
407
 
408
+ /**
409
+ * Add field values to table or plain text content
410
+ *
411
+ * @since 2.05
412
+ *
413
+ * @param string $content
414
+ */
415
+ protected function add_field_values_to_content( &$content ) {
416
+ foreach ( $this->entry_values->get_field_values() as $field_id => $field_value ) {
417
+
418
+ /**
419
+ * @var FrmFieldValue $field_value
420
+ */
421
+ $field_value->prepare_displayed_value( $this->atts );
422
+ $this->add_field_value_to_content( $field_value, $content );
423
+ }
424
+ }
425
+
426
  /**
427
  * Return the formatted plain text content
428
  *
433
  protected function prepare_plain_text_block() {
434
  $content = '';
435
 
436
+ $this->add_field_values_to_content( $content );
 
 
 
437
  $this->add_user_info_to_plain_text_content( $content );
438
 
439
  return $content;
464
  */
465
  protected function push_field_values_to_array( $field_values, &$output ) {
466
  foreach ( $field_values as $field_value ) {
467
+ /**
468
+ * @var FrmFieldValue $field_value
469
+ */
470
+ $field_value->prepare_displayed_value( $this->atts );
471
  $this->push_single_field_to_array( $field_value, $output );
472
  }
473
  }
520
  * @param string $content
521
  */
522
  protected function add_field_value_to_content( $field_value, &$content ) {
523
+ if ( $this->is_extra_field( $field_value ) ) {
524
+ $this->add_row_for_extra_field( $field_value, $content );
525
+
526
+ } else {
527
+ $this->add_row_for_standard_field( $field_value, $content );
528
+ }
529
+ }
530
+
531
+ /**
532
+ * Add an extra field to plain text or html table content
533
+ *
534
+ * @since 3.0
535
+ *
536
+ * @param FrmFieldValue $field_value
537
+ * @param string $content
538
+ */
539
+ protected function add_row_for_extra_field( $field_value, &$content ) {
540
+ if ( ! $this->include_field_in_content( $field_value ) ) {
541
+ return;
542
+ }
543
+
544
+ if ( $this->format === 'plain_text_block' ) {
545
+ $this->add_plain_text_row_for_included_extra( $field_value, $content );
546
+ } else if ( $this->format === 'table' ) {
547
+ $this->add_html_row_for_included_extra( $field_value, $content );
548
+ }
549
+ }
550
+
551
+ /**
552
+ * Add a standard row to plain text or html table content
553
+ *
554
+ * @since 3.0
555
+ *
556
+ * @param FrmFieldValue $field_value
557
+ * @param string $content
558
+ */
559
+ protected function add_row_for_standard_field( $field_value, &$content ) {
560
  if ( ! $this->include_field_in_content( $field_value ) ) {
561
  return;
562
  }
569
  }
570
  }
571
 
572
+ /**
573
+ * Add a row to table for included extra
574
+ *
575
+ * @since 3.0
576
+ *
577
+ * @param FrmFieldValue $field_value
578
+ * @param string $content
579
+ */
580
+ protected function add_html_row_for_included_extra( $field_value, &$content ) {
581
+ $this->prepare_html_display_value_for_extra_fields( $field_value, $display_value );
582
+
583
+ if ( in_array( $field_value->get_field_type(), $this->single_cell_fields ) ) {
584
+ $this->add_single_cell_html_row( $display_value, $content );
585
+ } else {
586
+ $value_args = $this->package_value_args( $field_value );
587
+ $this->add_html_row( $value_args, $content );
588
+ }
589
+ }
590
+
591
+ /**
592
+ * Add a plain text row for included extra
593
+ *
594
+ * @since 3.0
595
+ *
596
+ * @param FrmFieldValue $field_value
597
+ * @param string $content
598
+ */
599
+ protected function add_plain_text_row_for_included_extra( $field_value, &$content ) {
600
+ $this->prepare_plain_text_display_value_for_extra_fields( $field_value, $display_value );
601
+
602
+ if ( in_array( $field_value->get_field_type(), $this->single_cell_fields ) ) {
603
+ $this->add_single_value_plain_text_row( $display_value, $content );
604
+ } else {
605
+ $this->add_plain_text_row( $field_value->get_field_label(), $display_value, $content );
606
+ }
607
+ }
608
+
609
+ /**
610
+ * Add a single cell row to an HTML table
611
+ *
612
+ * @since 3.0
613
+ *
614
+ * @param string $display_value
615
+ * @param string $content
616
+ */
617
+ protected function add_single_cell_html_row( $display_value, &$content ) {
618
+ // TODO: maybe move to FrmFieldValue
619
+ $display_value = $this->prepare_display_value_for_html_table( $display_value );
620
+
621
+ $content .= $this->table_generator->generate_single_cell_table_row( $display_value );
622
+ }
623
+
624
+ /**
625
+ * Add a single value plain text row
626
+ *
627
+ * @since 3.0
628
+ *
629
+ * @param string $display_value
630
+ * @param string $content
631
+ */
632
+ protected function add_single_value_plain_text_row( $display_value, &$content ) {
633
+ $content .= $this->prepare_display_value_for_plain_text_content( $display_value );
634
+ }
635
+
636
+ /**
637
+ * Prepare the display value for extra fields an HTML table
638
+ *
639
+ * @since 3.0
640
+ *
641
+ * @param FrmFieldValue $field_value
642
+ * @param mixed $display_value
643
+ */
644
+ protected function prepare_html_display_value_for_extra_fields( $field_value, &$display_value ) {
645
+ $display_value = $field_value->get_displayed_value();
646
+ }
647
+
648
+ /**
649
+ * Prepare a plain text value for extra fields
650
+ *
651
+ * @since 3.0
652
+ *
653
+ * @param FrmFieldValue $field_value
654
+ * @param mixed $display_value
655
+ */
656
+ protected function prepare_plain_text_display_value_for_extra_fields( $field_value, &$display_value ) {
657
+ $display_value = $field_value->get_displayed_value() . "\r\n";
658
+ }
659
+
660
+ /**
661
+ * Add a standard row to plain text or html table content
662
+ *
663
+ * @since 2.04
664
+ *
665
+ * @param FrmProFieldValue $field_value
666
+ * @param string $content
667
+ */
668
+ protected function add_standard_row( $field_value, &$content ) {
669
+ if ( $this->format === 'plain_text_block' ) {
670
+ $this->add_plain_text_row( $field_value->get_field_label(), $field_value->get_displayed_value(), $content );
671
+ } else if ( $this->format === 'table' ) {
672
+ $value_args = $this->package_value_args( $field_value );
673
+ $this->add_html_row( $value_args, $content );
674
+ }
675
+ }
676
+
677
  /**
678
  * Package the value arguments for an HTML row
679
  *
743
  $include = true;
744
 
745
  if ( $this->is_extra_field( $field_value ) ) {
 
746
  $include = $this->is_extra_field_included( $field_value );
747
+ } elseif ( FrmAppHelper::is_empty_value( $field_value->get_displayed_value() ) && ! $this->include_blank ) {
748
+ $include = false;
 
 
 
 
 
 
 
 
749
  }
750
 
751
  return $include;
761
  * @return bool
762
  */
763
  protected function is_extra_field( $field_value ) {
764
+ return in_array( $field_value->get_field_type(), $this->skip_fields() );
765
  }
766
 
767
  /**
822
  */
823
  protected function prepare_display_value_for_html_table( $display_value, $field_type = '' ) {
824
  $display_value = $this->flatten_array( $display_value );
825
+ $display_value = str_replace( array( "\r\n", "\n" ), '<br/>', $display_value );
826
 
827
  return $display_value;
828
  }
classes/models/FrmEntryMeta.php CHANGED
@@ -23,6 +23,7 @@ class FrmEntryMeta {
23
  'created_at' => current_time('mysql', 1),
24
  );
25
 
 
26
  $new_values = apply_filters('frm_add_entry_meta', $new_values);
27
 
28
  $query_results = $wpdb->insert( $wpdb->prefix . 'frm_item_metas', $new_values );
@@ -38,9 +39,14 @@ class FrmEntryMeta {
38
  return $id;
39
  }
40
 
41
- /**
42
- * @param string $meta_key
43
- */
 
 
 
 
 
44
  public static function update_entry_meta( $entry_id, $field_id, $meta_key = null, $meta_value ) {
45
  if ( ! $field_id ) {
46
  return false;
@@ -54,7 +60,9 @@ class FrmEntryMeta {
54
  );
55
  $where_values = $values;
56
  $values['meta_value'] = $meta_value;
 
57
  $values = apply_filters('frm_update_entry_meta', $values);
 
58
  if ( is_array($values['meta_value']) ) {
59
  $values['meta_value'] = array_filter( $values['meta_value'], 'FrmAppHelper::is_not_empty_value' );
60
  }
@@ -66,6 +74,32 @@ class FrmEntryMeta {
66
  return $wpdb->update( $wpdb->prefix . 'frm_item_metas', array( 'meta_value' => $meta_value ), $where_values );
67
  }
68
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  public static function update_entry_metas( $entry_id, $values ) {
70
  global $wpdb;
71
 
@@ -80,8 +114,7 @@ class FrmEntryMeta {
80
  $field = FrmField::getOne( $field_id );
81
  }
82
 
83
- // set the value for the file upload field and add new tags (in Pro version)
84
- $meta_value = apply_filters( 'frm_prepare_data_before_db', $meta_value, $field_id, $entry_id, compact( 'field' ) );
85
 
86
  if ( $prev_values && in_array($field_id, $prev_values) ) {
87
 
23
  'created_at' => current_time('mysql', 1),
24
  );
25
 
26
+ self::set_value_before_save( $new_values );
27
  $new_values = apply_filters('frm_add_entry_meta', $new_values);
28
 
29
  $query_results = $wpdb->insert( $wpdb->prefix . 'frm_item_metas', $new_values );
39
  return $id;
40
  }
41
 
42
+ /**
43
+ * @param int $entry_id
44
+ * @param int $field_id
45
+ * @param string $meta_key deprecated
46
+ * @param array|string $meta_value
47
+ *
48
+ * @return bool|false|int
49
+ */
50
  public static function update_entry_meta( $entry_id, $field_id, $meta_key = null, $meta_value ) {
51
  if ( ! $field_id ) {
52
  return false;
60
  );
61
  $where_values = $values;
62
  $values['meta_value'] = $meta_value;
63
+ self::set_value_before_save( $values );
64
  $values = apply_filters('frm_update_entry_meta', $values);
65
+
66
  if ( is_array($values['meta_value']) ) {
67
  $values['meta_value'] = array_filter( $values['meta_value'], 'FrmAppHelper::is_not_empty_value' );
68
  }
74
  return $wpdb->update( $wpdb->prefix . 'frm_item_metas', array( 'meta_value' => $meta_value ), $where_values );
75
  }
76
 
77
+ /**
78
+ * @since 3.0
79
+ */
80
+ private static function set_value_before_save( &$values ) {
81
+ $field = FrmField::getOne( $values['field_id'] );
82
+ if ( $field ) {
83
+ $field_obj = FrmFieldFactory::get_field_object( $field );
84
+ $values['meta_value'] = $field_obj->set_value_before_save( $values['meta_value'] );
85
+ }
86
+ }
87
+
88
+ /**
89
+ * @since 3.0
90
+ */
91
+ private static function get_value_to_save( $atts, &$value ) {
92
+ if ( is_object( $atts['field'] ) ) {
93
+ $field_obj = FrmFieldFactory::get_field_object( $atts['field'] );
94
+ $value = $field_obj->get_value_to_save( $value, array(
95
+ 'entry_id' => $atts['entry_id'],
96
+ 'field_id' => $atts['field_id'],
97
+ ) );
98
+ }
99
+
100
+ $value = apply_filters( 'frm_prepare_data_before_db', $value, $atts['field_id'], $atts['entry_id'], array( 'field' => $atts['field'] ) );
101
+ }
102
+
103
  public static function update_entry_metas( $entry_id, $values ) {
104
  global $wpdb;
105
 
114
  $field = FrmField::getOne( $field_id );
115
  }
116
 
117
+ self::get_value_to_save( compact( 'field', 'field_id', 'entry_id' ), $meta_value );
 
118
 
119
  if ( $prev_values && in_array($field_id, $prev_values) ) {
120
 
classes/models/FrmEntryShortcodeFormatter.php CHANGED
@@ -17,6 +17,12 @@ class FrmEntryShortcodeFormatter {
17
  */
18
  protected $skip_fields = array( 'captcha', 'html' );
19
 
 
 
 
 
 
 
20
  /**
21
  * @var array
22
  * @since 2.04
17
  */
18
  protected $skip_fields = array( 'captcha', 'html' );
19
 
20
+ /**
21
+ * @var array
22
+ * @since 3.0
23
+ */
24
+ protected $single_cell_fields = array( 'html' );
25
+
26
  /**
27
  * @var array
28
  * @since 2.04
classes/models/FrmEntryValidate.php CHANGED
@@ -83,21 +83,23 @@ class FrmEntryValidate {
83
  $value = reset($value);
84
  }
85
 
 
 
 
 
86
  if ( $posted_field->required == '1' && ! is_array( $value ) && trim( $value ) == '' ) {
87
  $errors[ 'field' . $args['id'] ] = FrmFieldsHelper::get_error_msg( $posted_field, 'blank' );
88
  } else if ( $posted_field->type == 'text' && ! isset( $_POST['item_name'] ) ) {
89
  $_POST['item_name'] = $value;
90
  }
91
 
 
 
92
  if ( $value != '' ) {
93
- self::validate_url_field( $errors, $posted_field, $value, $args );
94
- self::validate_email_field( $errors, $posted_field, $value, $args );
95
- self::validate_number_field( $errors, $posted_field, $value, $args );
96
  self::validate_phone_field( $errors, $posted_field, $value, $args );
97
  }
98
 
99
- FrmEntriesHelper::set_posted_value($posted_field, $value, $args);
100
-
101
  self::validate_recaptcha($errors, $posted_field, $args);
102
 
103
  $errors = apply_filters( 'frm_validate_' . $posted_field->type . '_field_entry', $errors, $posted_field, $value, $args );
@@ -122,62 +124,46 @@ class FrmEntryValidate {
122
  }
123
  }
124
 
125
- public static function validate_url_field( &$errors, $field, &$value, $args ) {
126
- if ( $value == '' || ! in_array( $field->type, array( 'website', 'url', 'image' ) ) ) {
127
- return;
128
- }
129
 
130
- if ( trim($value) == 'http://' ) {
131
- $value = '';
132
- } else {
133
- $value = esc_url_raw( $value );
134
- $value = preg_match( '/^(https?|ftps?|mailto|news|feed|telnet):/is', $value ) ? $value : 'http://' . $value;
135
- }
136
 
137
- // validate the url format
138
- if ( ! preg_match('/^http(s)?:\/\/(?:localhost|(?:[\da-z\.-]+\.[\da-z\.-]+))/i', $value) ) {
139
- $errors[ 'field' . $args['id'] ] = FrmFieldsHelper::get_error_msg( $field, 'invalid' );
 
 
140
  }
141
- }
142
 
143
- public static function validate_email_field( &$errors, $field, $value, $args ) {
144
- if ( $value == '' || $field->type != 'email' ) {
145
- return;
146
- }
147
 
148
- //validate the email format
149
- if ( ! is_email($value) ) {
150
- $errors[ 'field' . $args['id'] ] = FrmFieldsHelper::get_error_msg( $field, 'invalid' );
151
- }
152
- }
153
 
154
- public static function validate_number_field( &$errors, $field, &$value, $args ) {
155
- //validate the number format
156
- if ( $field->type != 'number' ) {
157
  return;
158
  }
159
 
160
- if ( strpos( $value, ',' ) ) {
161
- $value = str_replace( ',', '', $value );
162
- }
163
 
164
- if ( ! is_numeric( $value) ) {
165
- $errors[ 'field' . $args['id'] ] = FrmFieldsHelper::get_error_msg( $field, 'invalid' );
166
- }
167
 
168
- // validate number settings
169
- if ( $value != '' ) {
170
- $frm_settings = FrmAppHelper::get_settings();
171
- // only check if options are available in settings
172
- if ( $frm_settings->use_html && isset( $field->field_options['minnum'] ) && isset( $field->field_options['maxnum'] ) ) {
173
- //minnum maxnum
174
- if ( (float) $value < $field->field_options['minnum'] ) {
175
- $errors[ 'field' . $args['id'] ] = __( 'Please select a higher number', 'formidable' );
176
- } else if ( (float) $value > $field->field_options['maxnum'] ) {
177
- $errors[ 'field' . $args['id'] ] = __( 'Please select a lower number', 'formidable' );
178
- }
179
- }
180
  }
 
 
181
  }
182
 
183
  public static function validate_phone_field( &$errors, $field, $value, $args ) {
83
  $value = reset($value);
84
  }
85
 
86
+ if ( ! is_array( $value ) ) {
87
+ $value = trim( $value );
88
+ }
89
+
90
  if ( $posted_field->required == '1' && ! is_array( $value ) && trim( $value ) == '' ) {
91
  $errors[ 'field' . $args['id'] ] = FrmFieldsHelper::get_error_msg( $posted_field, 'blank' );
92
  } else if ( $posted_field->type == 'text' && ! isset( $_POST['item_name'] ) ) {
93
  $_POST['item_name'] = $value;
94
  }
95
 
96
+ FrmEntriesHelper::set_posted_value( $posted_field, $value, $args );
97
+
98
  if ( $value != '' ) {
99
+ self::validate_field_types( $errors, $posted_field, $value, $args );
 
 
100
  self::validate_phone_field( $errors, $posted_field, $value, $args );
101
  }
102
 
 
 
103
  self::validate_recaptcha($errors, $posted_field, $args);
104
 
105
  $errors = apply_filters( 'frm_validate_' . $posted_field->type . '_field_entry', $errors, $posted_field, $value, $args );
124
  }
125
  }
126
 
127
+ public static function validate_field_types( &$errors, $posted_field, $value, $args ) {
128
+ $field_obj = FrmFieldFactory::get_field_object( $posted_field );
129
+ $args['value'] = $value;
130
+ $args['errors'] = $errors;
131
 
132
+ $new_errors = $field_obj->validate( $args );
133
+ if ( ! empty( $new_errors ) ) {
134
+ $errors = array_merge( $errors, $new_errors );
135
+ }
136
+ }
 
137
 
138
+ public static function validate_url_field( &$errors, $field, $value, $args ) {
139
+ _deprecated_function( __FUNCTION__, '3.0', 'FrmFieldType::validate' );
140
+
141
+ if ( $value == '' || ! in_array( $field->type, array( 'website', 'url' ) ) ) {
142
+ return;
143
  }
 
144
 
145
+ self::validate_field_types( $errors, $field, $value, $args );
146
+ }
 
 
147
 
148
+ public static function validate_email_field( &$errors, $field, $value, $args ) {
149
+ _deprecated_function( __FUNCTION__, '3.0', 'FrmFieldType::validate' );
 
 
 
150
 
151
+ if ( $field->type != 'email' ) {
 
 
152
  return;
153
  }
154
 
155
+ self::validate_field_types( $errors, $field, $value, $args );
156
+ }
 
157
 
158
+ public static function validate_number_field( &$errors, $field, $value, $args ) {
159
+ _deprecated_function( __FUNCTION__, '3.0', 'FrmFieldType::validate' );
 
160
 
161
+ //validate the number format
162
+ if ( $field->type != 'number' ) {
163
+ return;
 
 
 
 
 
 
 
 
 
164
  }
165
+
166
+ self::validate_field_types( $errors, $field, $value, $args );
167
  }
168
 
169
  public static function validate_phone_field( &$errors, $field, $value, $args ) {
classes/models/FrmEntryValues.php CHANGED
@@ -40,13 +40,6 @@ class FrmEntryValues {
40
  */
41
  protected $exclude_fields = array();
42
 
43
- /**
44
- * @since 2.04
45
- *
46
- * @var string
47
- */
48
- protected $source = '';
49
-
50
  /**
51
  * FrmEntryValues constructor
52
  *
@@ -63,7 +56,6 @@ class FrmEntryValues {
63
  }
64
 
65
  $this->init_form_id();
66
- $this->init_source( $atts );
67
  $this->init_include_fields( $atts );
68
  $this->init_exclude_fields( $atts );
69
  $this->init_fields();
@@ -105,12 +97,17 @@ class FrmEntryValues {
105
 
106
  if ( isset( $atts['fields'] ) && ! empty( $atts['fields'] ) ) {
107
 
108
- $atts['include_fields'] = '';
109
- foreach ( $atts['fields'] as $included_field ) {
110
- $atts['include_fields'] .= $included_field->id . ',';
111
- }
 
 
 
 
112
 
113
- $atts['include_fields'] = rtrim( $atts['include_fields'], ',' );
 
114
  }
115
  }
116
 
@@ -128,21 +125,6 @@ class FrmEntryValues {
128
  $this->exclude_fields = $this->prepare_array_property( 'exclude_fields', $atts );
129
  }
130
 
131
- /**
132
- * Initialize the source property
133
- *
134
- * @since 2.04
135
- *
136
- * @param array $atts
137
- */
138
- protected function init_source( $atts ) {
139
- if ( isset( $atts['source'] ) && is_string( $atts['source'] ) && $atts['source'] !== '' ) {
140
- $this->source = (string) $atts['source'];
141
- } else {
142
- $this->source = 'general';
143
- }
144
- }
145
-
146
  /**
147
  * Prepare an array property value, such as include_fields and exclude_fields
148
  *
@@ -292,6 +274,6 @@ class FrmEntryValues {
292
  * @param stdClass $field
293
  */
294
  protected function add_field_values( $field ) {
295
- $this->field_values[ $field->id ] = new FrmFieldValue( $field, $this->entry, array( 'source' => $this->source ) );
296
  }
297
  }
40
  */
41
  protected $exclude_fields = array();
42
 
 
 
 
 
 
 
 
43
  /**
44
  * FrmEntryValues constructor
45
  *
56
  }
57
 
58
  $this->init_form_id();
 
59
  $this->init_include_fields( $atts );
60
  $this->init_exclude_fields( $atts );
61
  $this->init_fields();
97
 
98
  if ( isset( $atts['fields'] ) && ! empty( $atts['fields'] ) ) {
99
 
100
+ if ( ! is_array( $atts['fields'] ) ) {
101
+ $atts['include_fields'] = $atts['fields'];
102
+ } else {
103
+ $atts['include_fields'] = '';
104
+
105
+ foreach ( $atts['fields'] as $included_field ) {
106
+ $atts['include_fields'] .= $included_field->id . ',';
107
+ }
108
 
109
+ $atts['include_fields'] = rtrim( $atts['include_fields'], ',' );
110
+ }
111
  }
112
  }
113
 
125
  $this->exclude_fields = $this->prepare_array_property( 'exclude_fields', $atts );
126
  }
127
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  /**
129
  * Prepare an array property value, such as include_fields and exclude_fields
130
  *
274
  * @param stdClass $field
275
  */
276
  protected function add_field_values( $field ) {
277
+ $this->field_values[ $field->id ] = new FrmFieldValue( $field, $this->entry );
278
  }
279
  }
classes/models/FrmField.php CHANGED
@@ -10,45 +10,141 @@ class FrmField {
10
 
11
  public static function field_selection() {
12
  $fields = apply_filters('frm_available_fields', array(
13
- 'text' => __( 'Single Line Text', 'formidable' ),
14
- 'textarea' => __( 'Paragraph Text', 'formidable' ),
15
- 'checkbox' => __( 'Checkboxes', 'formidable' ),
16
- 'radio' => __( 'Radio Buttons', 'formidable' ),
17
- 'select' => __( 'Dropdown', 'formidable' ),
18
- 'email' => __( 'Email Address', 'formidable' ),
19
- 'url' => __( 'Website/URL', 'formidable' ),
20
- 'captcha' => __( 'reCAPTCHA', 'formidable' ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  ));
22
 
23
  return $fields;
24
  }
25
 
26
  public static function pro_field_selection() {
27
- return apply_filters('frm_pro_available_fields', array(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  'end_divider' => array(
29
  'name' => __( 'End Section', 'formidable' ),
30
  'switch_from' => 'divider',
31
  ),
32
- 'divider' => __( 'Section', 'formidable' ),
33
- 'break' => __( 'Page Break', 'formidable' ),
34
- 'file' => __( 'File Upload', 'formidable' ),
35
- 'rte' => __( 'Rich Text', 'formidable' ),
36
- 'number' => __( 'Number', 'formidable' ),
37
- 'phone' => __( 'Phone Number', 'formidable' ),
38
- 'date' => __( 'Date', 'formidable' ),
39
- 'time' => __( 'Time', 'formidable' ),
40
- 'image' => __( 'Image URL', 'formidable' ),
41
- 'scale' => __( 'Scale', 'formidable' ),
42
- 'data' => __( 'Dynamic Field', 'formidable' ),
43
- 'lookup' => __( 'Lookup', 'formidable' ),
44
- 'form' => __( 'Embed Form', 'formidable' ),
45
- 'hidden' => __( 'Hidden Field', 'formidable' ),
46
- 'user_id' => __( 'User ID (hidden)', 'formidable' ),
47
- 'password' => __( 'Password', 'formidable' ),
48
- 'html' => __( 'HTML', 'formidable' ),
49
- 'tag' => __( 'Tags', 'formidable' ),
50
- 'credit_card' => __( 'Credit Card', 'formidable' ),
51
- 'address' => __( 'Address', 'formidable' ),
 
 
 
 
 
 
 
 
52
  ));
53
  }
54
 
@@ -76,6 +172,8 @@ class FrmField {
76
  $new_values = apply_filters('frm_duplicated_field', $new_values);
77
  }
78
 
 
 
79
  foreach ( $new_values as $k => $v ) {
80
  if ( is_array( $v ) ) {
81
  $new_values[ $k ] = serialize( $v );
@@ -620,25 +718,40 @@ class FrmField {
620
  return false;
621
  }
622
 
623
- $field_type = is_array( $field ) ? $field['type'] : $field->type;
624
- $data_type = self::get_option( $field, 'data_type' );
625
- $original_type = self::get_option( $field, 'original_type' );
626
-
627
- if ( ! empty( $original_type ) && $original_type != $field_type ) {
628
- $field_type = $original_type; // check the original type for arrays
629
- }
630
 
631
  $is_multi_value_field = (
632
- $field_type == 'checkbox' ||
633
  $field_type == 'address' ||
634
- ( $field_type == 'data' && $data_type == 'checkbox' ) ||
635
- ( $field_type == 'lookup' && $data_type == 'checkbox' ) ||
636
  self::is_multiple_select( $field )
637
  );
638
 
639
  return $is_multi_value_field;
640
  }
641
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
642
  /**
643
  * Check if this is a multiselect dropdown field
644
  *
@@ -646,7 +759,7 @@ class FrmField {
646
  * @return boolean
647
  */
648
  public static function is_multiple_select( $field ) {
649
- $field_type = is_array( $field ) ? $field['type'] : $field->type;
650
  $data_type = self::get_option( $field, 'data_type' );
651
 
652
  return self::is_option_true( $field, 'multiple' ) && ( ( $field_type == 'select' || ( $field_type == 'data' && $data_type == 'select' ) ) );
@@ -762,4 +875,66 @@ class FrmField {
762
  public static function get_key_by_id( $id ) {
763
  return FrmDb::get_var( 'frm_fields', array( 'id' => $id ), 'field_key' );
764
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
765
  }
10
 
11
  public static function field_selection() {
12
  $fields = apply_filters('frm_available_fields', array(
13
+ 'text' => array(
14
+ 'name' => __( 'Text', 'formidable' ),
15
+ 'icon' => 'frm_css_icon frm_text_icon',
16
+ ),
17
+ 'textarea' => array(
18
+ 'name' => __( 'Paragraph', 'formidable' ),
19
+ 'icon' => 'frm_icon_font frm_paragraph_icon',
20
+ ),
21
+ 'checkbox' => array(
22
+ 'name' => __( 'Checkboxes', 'formidable' ),
23
+ 'icon' => 'frm_icon_font frm_check-square_icon',
24
+ ),
25
+ 'radio' => array(
26
+ 'name' => __( 'Radio Button', 'formidable' ),
27
+ 'icon' => 'frm_icon_font frm_radio-checked_icon',
28
+ ),
29
+ 'select' => array(
30
+ 'name' => __( 'Dropdown', 'formidable' ),
31
+ 'icon' => 'frm_icon_font frm_caret-square-down_icon',
32
+ ),
33
+ 'email' => array(
34
+ 'name' => __( 'Email', 'formidable' ),
35
+ 'icon' => 'frm_icon_font frm_envelope_icon',
36
+ ),
37
+ 'url' => array(
38
+ 'name' => __( 'Website/URL', 'formidable' ),
39
+ 'icon' => 'dashicons dashicons-admin-links',
40
+ ),
41
+ 'number' => array(
42
+ 'name' => __( 'Number', 'formidable' ),
43
+ 'icon' => 'frm_css_icon frm_number_icon',
44
+ ),
45
+ 'phone' => array(
46
+ 'name' => __( 'Phone', 'formidable' ),
47
+ 'icon' => 'frm_icon_font frm_phone_icon',
48
+ ),
49
+ 'html' => array(
50
+ 'name' => __( 'HTML', 'formidable' ),
51
+ 'icon' => 'frm_icon_font frm_embed2_icon',
52
+ ),
53
+ 'hidden' => array(
54
+ 'name' => __( 'Hidden Field', 'formidable' ),
55
+ 'icon' => 'frm_icon_font frm_eye-slash_icon',
56
+ ),
57
+ 'user_id' => array(
58
+ 'name' => __( 'User ID', 'formidable' ),
59
+ 'icon' => 'frm_icon_font frm_user_icon',
60
+ ),
61
+ 'captcha' => array(
62
+ 'name' => __( 'reCAPTCHA', 'formidable' ),
63
+ 'icon' => 'frm_icon_font frm_shield-check_icon',
64
+ ),
65
  ));
66
 
67
  return $fields;
68
  }
69
 
70
  public static function pro_field_selection() {
71
+ return apply_filters( 'frm_pro_available_fields', array(
72
+ 'file' => array(
73
+ 'name' => __( 'File Upload', 'formidable' ),
74
+ 'icon' => 'frm_icon_font frm_upload2_icon',
75
+ ),
76
+ 'rte' => array(
77
+ 'name' => __( 'Rich Text', 'formidable' ),
78
+ 'icon' => 'dashicons dashicons-editor-alignright',
79
+ ),
80
+ 'date' => array(
81
+ 'name' => __( 'Date', 'formidable' ),
82
+ 'icon' => 'frm_icon_font frm_calendar_icon',
83
+ ),
84
+ 'time' => array(
85
+ 'name' => __( 'Time', 'formidable' ),
86
+ 'icon' => 'frm_icon_font frm_clock-o_icon',
87
+ ),
88
+ 'scale' => array(
89
+ 'name' => __( 'Scale', 'formidable' ),
90
+ 'icon' => 'frm_icon_font frm_linear_scale_icon',
91
+ ),
92
+ 'star' => array(
93
+ 'name' => __( 'Star Rating', 'formidable' ),
94
+ 'icon' => 'frm_icon_font frm_star-full_icon',
95
+ ),
96
+ 'range' => array(
97
+ 'name' => __( 'Slider', 'formidable' ),
98
+ 'icon' => 'frm_icon_font frm_sliders_icon',
99
+ ),
100
+ 'toggle' => array(
101
+ 'name' => __( 'Toggle', 'formidable' ),
102
+ 'icon' => 'frm_icon_font frm_toggle-on_icon',
103
+ ),
104
+ 'data' => array(
105
+ 'name' => __( 'Dynamic', 'formidable' ),
106
+ 'icon' => 'frm_icon_font frm_sitemap_icon',
107
+ ),
108
+ 'lookup' => array(
109
+ 'name' => __( 'Lookup', 'formidable' ),
110
+ 'icon' => 'frm_icon_font frm_search_icon',
111
+ ),
112
+ 'divider|repeat' => array(
113
+ 'name' => __( 'Repeater', 'formidable' ),
114
+ 'icon' => 'frm_icon_font frm_repeat_icon',
115
+ ),
116
  'end_divider' => array(
117
  'name' => __( 'End Section', 'formidable' ),
118
  'switch_from' => 'divider',
119
  ),
120
+ 'divider' => array(
121
+ 'name' => __( 'Section', 'formidable' ),
122
+ 'icon' => 'frm_css_icon frm_heading_icon',
123
+ ),
124
+ 'break' => array(
125
+ 'name' => __( 'Page Break', 'formidable' ),
126
+ 'icon' => 'frm_icon_font frm_page-break_icon',
127
+ ),
128
+ 'form' => array(
129
+ 'name' => __( 'Embed Form', 'formidable' ),
130
+ 'icon' => 'dashicons dashicons-editor-table',
131
+ ),
132
+ 'password' => array(
133
+ 'name' => __( 'Password', 'formidable' ),
134
+ 'icon' => 'frm_icon_font frm_key_icon',
135
+ ),
136
+ 'tag' => array(
137
+ 'name' => __( 'Tags', 'formidable' ),
138
+ 'icon' => 'frm_icon_font frm_price-tags_icon',
139
+ ),
140
+ 'credit_card' => array(
141
+ 'name' => __( 'Credit Card', 'formidable' ),
142
+ 'icon' => 'frm_icon_font frm_credit-card-alt_icon',
143
+ ),
144
+ 'address' => array(
145
+ 'name' => __( 'Address', 'formidable' ),
146
+ 'icon' => 'frm_icon_font frm_location_icon',
147
+ ),
148
  ));
149
  }
150
 
172
  $new_values = apply_filters('frm_duplicated_field', $new_values);
173
  }
174
 
175
+ self::preserve_format_option_backslashes( $new_values );
176
+
177
  foreach ( $new_values as $k => $v ) {
178
  if ( is_array( $v ) ) {
179
  $new_values[ $k ] = serialize( $v );
718
  return false;
719
  }
720
 
721
+ $field_type = self::get_original_field_type( $field );
 
 
 
 
 
 
722
 
723
  $is_multi_value_field = (
724
+ self::is_checkbox( $field ) ||
725
  $field_type == 'address' ||
 
 
726
  self::is_multiple_select( $field )
727
  );
728
 
729
  return $is_multi_value_field;
730
  }
731
 
732
+ /**
733
+ * @since 3.0
734
+ * @return string
735
+ */
736
+ public static function get_field_type( $field ) {
737
+ return is_array( $field ) ? $field['type'] : $field->type;
738
+ }
739
+
740
+ /**
741
+ * @since 3.0
742
+ * @return string
743
+ */
744
+ public static function get_original_field_type( $field ) {
745
+ $field_type = self::get_field_type( $field );
746
+ $original_type = self::get_option( $field, 'original_type' );
747
+
748
+ if ( ! empty( $original_type ) && $original_type != $field_type ) {
749
+ $field_type = $original_type; // check the original type for arrays
750
+ }
751
+
752
+ return $field_type;
753
+ }
754
+
755
  /**
756
  * Check if this is a multiselect dropdown field
757
  *
759
  * @return boolean
760
  */
761
  public static function is_multiple_select( $field ) {
762
+ $field_type = self::get_field_type( $field );
763
  $data_type = self::get_option( $field, 'data_type' );
764
 
765
  return self::is_option_true( $field, 'multiple' ) && ( ( $field_type == 'select' || ( $field_type == 'data' && $data_type == 'select' ) ) );
875
  public static function get_key_by_id( $id ) {
876
  return FrmDb::get_var( 'frm_fields', array( 'id' => $id ), 'field_key' );
877
  }
878
+
879
+ public static function is_image( $field ) {
880
+ $type = self::get_field_type( $field );
881
+ return ( $type == 'url' && self::get_option( $field, 'show_image' ) );
882
+ }
883
+
884
+ /**
885
+ * Check if field is radio or Dynamic radio
886
+ *
887
+ * @since 3.0
888
+ *
889
+ * @param array $field
890
+ * @return boolean true if field type is radio or Dynamic radio
891
+ */
892
+ public static function is_radio( $field ) {
893
+ return self::is_field_type( $field, 'radio' );
894
+ }
895
+
896
+ /**
897
+ * Check if field is checkbox or Dynamic checkbox
898
+ *
899
+ * @since 3.0
900
+ *
901
+ * @param array $field
902
+ * @return boolean true if field type is checkbox or Dynamic checkbox
903
+ */
904
+ public static function is_checkbox( $field ) {
905
+ return self::is_field_type( $field, 'checkbox' );
906
+ }
907
+
908
+ /**
909
+ * Check if field is checkbox or radio
910
+ *
911
+ * @since 3.0
912
+ *
913
+ * @param array|object $field
914
+ * @param string $is_type Options include radio, checkbox, text
915
+ * @return boolean true if field type is checkbox or Dynamic checkbox
916
+ */
917
+ public static function is_field_type( $field, $is_type ) {
918
+ $field_type = self::get_original_field_type( $field );
919
+ $data_type = self::get_option( $field, 'data_type' );
920
+
921
+ return (
922
+ $is_type === $field_type ||
923
+ ( 'data' === $field_type && $is_type === $data_type ) ||
924
+ ( 'lookup' === $field_type && $is_type === $data_type )
925
+ );
926
+ }
927
+
928
+ /**
929
+ * Check if a field might by taller than other fields
930
+ * @since 3.0
931
+ *
932
+ * @param array|object $field
933
+ *
934
+ * @return bool
935
+ */
936
+ public static function is_tall_field( $field ) {
937
+ $field_type = FrmField::get_field_type( $field );
938
+ return FrmFieldFactory::field_has_property( $field_type, 'is_tall' );
939
+ }
940
  }
classes/models/FrmFieldFormHtml.php ADDED
@@ -0,0 +1,406 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @since 3.0
4
+ */
5
+
6
+ class FrmFieldFormHtml {
7
+
8
+ private $html;
9
+
10
+ private $html_id;
11
+
12
+ /**
13
+ * @var FrmFieldType
14
+ */
15
+ private $field_obj;
16
+
17
+ private $field_id;
18
+
19
+ private $form = array();
20
+
21
+ private $pass_args = array();
22
+
23
+ /**
24
+ * @since 3.0
25
+ *
26
+ * @param array $atts
27
+ */
28
+ public function __construct( $atts ) {
29
+ $this->_set( 'field_obj', $atts );
30
+ $this->set_field_id( $atts );
31
+ $this->_set( 'form', $atts );
32
+ $this->_set( 'html_id', $atts );
33
+ $this->set_html( $atts );
34
+ $this->set_pass_args( $atts );
35
+ }
36
+
37
+ /**
38
+ * @since 3.0
39
+ *
40
+ * @param string $param
41
+ * @param array $atts
42
+ */
43
+ private function _set( $param, $atts ) {
44
+ if ( isset( $atts[ $param ] ) ) {
45
+ $this->{$param} = $atts[ $param ];
46
+ }
47
+ }
48
+
49
+ /**
50
+ * @since 3.0
51
+ *
52
+ * @param array $atts
53
+ */
54
+ private function set_html( $atts ) {
55
+ $this->set_from_field( $atts, array(
56
+ 'param' => 'html',
57
+ 'default' => 'custom_html',
58
+ ) );
59
+ }
60
+
61
+ /**
62
+ * @since 3.0
63
+ *
64
+ * @param array $atts
65
+ */
66
+ private function set_field_id( $atts ) {
67
+ $this->set_from_field( $atts, array(
68
+ 'param' => 'field_id',
69
+ 'default' => 'id',
70
+ ) );
71
+ }
72
+
73
+ /**
74
+ * @since 3.0
75
+ *
76
+ * @param array $atts
77
+ */
78
+ private function set_pass_args( $atts ) {
79
+ $this->pass_args = $atts;
80
+ $exclude = array( 'field_obj', 'html' );
81
+
82
+ foreach ( $exclude as $ex ) {
83
+ if ( isset( $atts[ $ex ] ) ) {
84
+ unset( $this->pass_args[ $ex ] );
85
+ }
86
+ }
87
+ }
88
+
89
+ /**
90
+ * @since 3.0
91
+ *
92
+ * @param array $atts
93
+ * @param array $set
94
+ */
95
+ private function set_from_field( $atts, $set ) {
96
+ if ( isset( $atts[ $set['param'] ] ) ) {
97
+ $this->{$set['param']} = $atts[ $set['param'] ];
98
+ } else {
99
+ $this->{$set['param']} = $this->field_obj->get_field_column( $set['default'] );
100
+ }
101
+ }
102
+
103
+ public function get_html() {
104
+ $this->replace_shortcodes_before_input();
105
+ $this->replace_shortcodes_with_atts();
106
+ $this->replace_shortcodes_after_input();
107
+
108
+ return $this->html;
109
+ }
110
+
111
+ /**
112
+ * @since 3.0
113
+ */
114
+ private function replace_shortcodes_before_input() {
115
+ $this->html = apply_filters( 'frm_before_replace_shortcodes', $this->html, $this->field_obj->get_field(), $this->pass_args['errors'], $this->form );
116
+
117
+ $this->replace_field_values();
118
+
119
+ $this->replace_required_label_shortcode();
120
+ $this->replace_required_class();
121
+ $this->maybe_replace_description_shortcode( false );
122
+ $this->replace_error_shortcode();
123
+ $this->add_class_to_label();
124
+ $this->add_field_div_classes();
125
+
126
+ $this->replace_entry_key();
127
+ $this->replace_form_shortcodes();
128
+ $this->process_wp_shortcodes();
129
+ $this->maybe_replace_description_shortcode( true );
130
+ }
131
+
132
+ /**
133
+ * @since 3.0
134
+ */
135
+ private function replace_field_values() {
136
+ //replace [id]
137
+ $this->html = str_replace( '[id]', $this->field_id, $this->html );
138
+
139
+ // set the label for
140
+ $this->html = str_replace( 'field_[key]', $this->html_id, $this->html );
141
+
142
+ //replace [key]
143
+ $this->html = str_replace( '[key]', $this->field_obj->get_field_column('field_key'), $this->html );
144
+
145
+ //replace [field_name]
146
+ $this->html = str_replace('[field_name]', $this->field_obj->get_field_column('name'), $this->html );
147
+ }
148
+
149
+ /**
150
+ * @since 3.0
151
+ */
152
+ private function replace_required_label_shortcode() {
153
+ $required = FrmField::is_required( $this->field_obj->get_field() ) ? $this->field_obj->get_field_column('required_indicator') : '';
154
+ FrmShortcodeHelper::remove_inline_conditions( ! empty( $required ), 'required_label', $required, $this->html );
155
+ }
156
+
157
+ /**
158
+ * If this is an HTML field, the values are included in the description.
159
+ * In this case, we don't want to run the wp shortcodes with the description included.
160
+ *
161
+ * @since 3.0
162
+ */
163
+ private function maybe_replace_description_shortcode( $wp_processed = false ) {
164
+ $is_html = 'html' === $this->field_obj->get_field_column( 'type' );
165
+ $should_replace = ( $is_html && $wp_processed ) || ( ! $is_html && ! $wp_processed );
166
+ if ( $should_replace ) {
167
+ $this->replace_description_shortcode();
168
+ }
169
+ }
170
+
171
+ /**
172
+ * @since 3.0
173
+ */
174
+ private function replace_description_shortcode() {
175
+ $this->maybe_add_description_id();
176
+ $description = $this->field_obj->get_field_column('description');
177
+ FrmShortcodeHelper::remove_inline_conditions( ( $description && $description != '' ), 'description', $description, $this->html );
178
+ }
179
+
180
+ /**
181
+ * Add an ID to the description for aria-describedby.
182
+ * This ID was added to the HTML in v3.0.
183
+ * @since 3.0
184
+ */
185
+ private function maybe_add_description_id() {
186
+ $description = $this->field_obj->get_field_column('description');
187
+ if ( $description != '' ) {
188
+
189
+ $description_html = preg_match_all( '/(\[if\s+description\])(.*?)(\[\/if\s+description\])/mis', $this->html, $inner_html );
190
+ if ( isset( $inner_html[2] ) && is_string( $inner_html[2] ) ) {
191
+ $has_id = strpos( $inner_html[2], ' id=' );
192
+ if ( ! $has_id ) {
193
+ $id = 'frm_desc_' . $this->html_id;
194
+ $this->html = str_replace( 'class="frm_description', 'id="' . esc_attr( $id ) . '" class="frm_description', $this->html );
195
+ }
196
+ }
197
+ }
198
+ }
199
+
200
+ /**
201
+ * @since 3.0
202
+ */
203
+ private function replace_error_shortcode() {
204
+ $error = isset( $this->pass_args['errors'][ 'field' . $this->field_id ] ) ? $this->pass_args['errors'][ 'field' . $this->field_id ] : false;
205
+ FrmShortcodeHelper::remove_inline_conditions( ! empty( $error ), 'error', $error, $this->html );
206
+ }
207
+
208
+ /**
209
+ * replace [required_class]
210
+ *
211
+ * @since 3.0
212
+ */
213
+ private function replace_required_class() {
214
+ $required_class = FrmField::is_required( $this->field_obj->get_field() ) ? ' frm_required_field' : '';
215
+ $this->html = str_replace( '[required_class]', $required_class, $this->html );
216
+ }
217
+
218
+ /**
219
+ * @since 3.0
220
+ */
221
+ private function replace_form_shortcodes() {
222
+ if ( ! empty( $this->form ) ) {
223
+ $form = (array) $this->form;
224
+
225
+ //replace [form_key]
226
+ $this->html = str_replace( '[form_key]', $form['form_key'], $this->html );
227
+
228
+ //replace [form_name]
229
+ $this->html = str_replace( '[form_name]', $form['name'], $this->html );
230
+ }
231
+ }
232
+
233
+ /**
234
+ * @since 3.0
235
+ */
236
+ public function replace_shortcodes_after_input() {
237
+ $this->html .= "\n";
238
+
239
+ // Stop html filtering on confirmation field to prevent loop
240
+ if ( $this->field_obj->get_field_column('conf_field') != 'stop' ) {
241
+ $this->filter_for_more_shortcodes();
242
+ }
243
+ }
244
+
245
+ /**
246
+ * @since 3.0
247
+ */
248
+ private function filter_for_more_shortcodes() {
249
+ $atts = $this->pass_args;
250
+
251
+ //If field is not in repeating section
252
+ if ( empty( $atts['section_id'] ) ) {
253
+ $atts = array(
254
+ 'errors' => $this->pass_args['errors'],
255
+ 'form' => $this->form,
256
+ );
257
+ }
258
+ $this->html = apply_filters( 'frm_replace_shortcodes', $this->html, $this->field_obj->get_field(), $atts );
259
+ }
260
+
261
+ /**
262
+ * Remove [collapse_this] if it's still included after all processing
263
+ * @since 3.0
264
+ *
265
+ * @param string $html
266
+ */
267
+ public function remove_collapse_shortcode( &$html ) {
268
+ if ( strpos( $html, '[collapse_this]' ) ) {
269
+ $html = str_replace( '[collapse_this]', '', $html );
270
+ }
271
+ }
272
+
273
+ /**
274
+ * @since 3.0
275
+ */
276
+ private function replace_shortcodes_with_atts() {
277
+ preg_match_all("/\[(input|deletelink)\b(.*?)(?:(\/))?\]/s", $this->html, $shortcodes, PREG_PATTERN_ORDER);
278
+
279
+ foreach ( $shortcodes[0] as $short_key => $tag ) {
280
+ $shortcode_atts = FrmShortcodeHelper::get_shortcode_attribute_array( $shortcodes[2][ $short_key ] );
281
+ $tag = FrmShortcodeHelper::get_shortcode_tag( $shortcodes, $short_key );
282
+
283
+ $replace_with = '';
284
+
285
+ if ( $tag == 'deletelink' && FrmAppHelper::pro_is_installed() ) {
286
+ $replace_with = FrmProEntriesController::entry_delete_link( $shortcode_atts );
287
+ } elseif ( $tag == 'input' ) {
288
+ $replace_with = $this->replace_input_shortcode( $shortcode_atts );
289
+ }
290
+
291
+ $this->html = str_replace( $shortcodes[0][ $short_key ], $replace_with, $this->html );
292
+ }
293
+ }
294
+
295
+ /**
296
+ * @param array $shortcode_atts
297
+ *
298
+ * @return string
299
+ */
300
+ private function replace_input_shortcode( $shortcode_atts ) {
301
+ $shortcode_atts = $this->prepare_input_shortcode_atts( $shortcode_atts );
302
+ return $this->field_obj->include_front_field_input( $this->pass_args, $shortcode_atts );
303
+ }
304
+
305
+ /**
306
+ * @param array $shortcode_atts
307
+ *
308
+ * @return array
309
+ */
310
+ private function prepare_input_shortcode_atts( $shortcode_atts ) {
311
+ if ( isset( $shortcode_atts['opt'] ) ) {
312
+ $shortcode_atts['opt']--;
313
+ }
314
+
315
+ $field_class = isset( $shortcode_atts['class'] ) ? $shortcode_atts['class'] : '';
316
+ $this->field_obj->set_field_column( 'input_class', $field_class );
317
+
318
+ if ( isset( $shortcode_atts['class'] ) ) {
319
+ unset( $shortcode_atts['class'] );
320
+ }
321
+
322
+ $this->field_obj->set_field_column( 'shortcodes', $shortcode_atts );
323
+
324
+ return $shortcode_atts;
325
+ }
326
+
327
+ /**
328
+ * Add the label position class into the HTML
329
+ * If the label position is inside, add a class to show the label if the field has a value.
330
+ *
331
+ * @since 3.0
332
+ */
333
+ private function add_class_to_label() {
334
+ $label_class = $this->field_obj->get_label_class();
335
+ $this->html = str_replace( '[label_position]', $label_class, $this->html );
336
+ if ( $this->field_obj->get_field_column('label') == 'inside' && $this->field_obj->get_field_column('value') != '' ) {
337
+ $this->html = str_replace( 'frm_primary_label', 'frm_primary_label frm_visible', $this->html );
338
+ }
339
+ }
340
+
341
+ /**
342
+ * replace [entry_key]
343
+ *
344
+ * @since 3.0
345
+ */
346
+ private function replace_entry_key() {
347
+ $entry_key = FrmAppHelper::simple_get( 'entry', 'sanitize_title' );
348
+ $this->html = str_replace( '[entry_key]', $entry_key, $this->html );
349
+ }
350
+
351
+ /**
352
+ * Add classes to a field div
353
+ *
354
+ * @since 3.0
355
+ */
356
+ private function add_field_div_classes() {
357
+ $classes = $this->get_field_div_classes();
358
+
359
+ if ( $this->field_obj->get_field_column('type') == 'html' && strpos( $this->html, '[error_class]' ) === false ) {
360
+ // there is no error_class shortcode for HTML fields
361
+ $this->html = str_replace( 'class="frm_form_field', 'class="frm_form_field ' . $classes, $this->html );
362
+ }
363
+ $this->html = str_replace( '[error_class]', $classes, $this->html );
364
+ }
365
+
366
+
367
+ /**
368
+ * Get the classes for a field div
369
+ *
370
+ * @since 3.0
371
+ *
372
+ * @return string $classes
373
+ */
374
+ private function get_field_div_classes() {
375
+ // Add error class
376
+ $classes = isset( $this->pass_args['errors'][ 'field' . $this->field_id ] ) ? ' frm_blank_field' : '';
377
+
378
+ // Add label position class
379
+ $classes .= ' frm_' . $this->field_obj->get_field_column('label') . '_container';
380
+
381
+ // Add CSS layout classes
382
+ $extra_classes = $this->field_obj->get_field_column('classes');
383
+ if ( ! empty( $extra_classes ) ) {
384
+ if ( ! strpos( $this->html, 'frm_form_field ') ) {
385
+ $classes .= ' frm_form_field';
386
+ }
387
+ $classes .= ' ' . $extra_classes;
388
+ }
389
+
390
+ $classes .= $this->field_obj->get_container_class();
391
+
392
+ // Get additional classes
393
+ return apply_filters( 'frm_field_div_classes', $classes, $this->field_obj->get_field(), array( 'field_id' => $this->field_id ) );
394
+ }
395
+
396
+ /**
397
+ * This filters shortcodes in the field HTML
398
+ *
399
+ * @since 3.0
400
+ */
401
+ private function process_wp_shortcodes() {
402
+ if ( apply_filters( 'frm_do_html_shortcodes', true ) ) {
403
+ $this->html = do_shortcode( $this->html );
404
+ }
405
+ }
406
+ }
classes/models/FrmFieldValue.php CHANGED
@@ -15,16 +15,9 @@ class FrmFieldValue {
15
  /**
16
  * @since 2.04
17
  *
18
- * @var stdClass
19
  */
20
- protected $entry = null;
21
-
22
- /**
23
- * @since 2.04
24
- *
25
- * @var string
26
- */
27
- protected $source = '';
28
 
29
  /**
30
  * @since 2.04
@@ -38,50 +31,36 @@ class FrmFieldValue {
38
  *
39
  * @var mixed
40
  */
41
- protected $displayed_value = '';
42
 
43
  /**
44
  * FrmFieldValue constructor.
45
  *
46
  * @param stdClass $field
47
  * @param stdClass $entry
48
- * @param array $atts
49
  */
50
- public function __construct( $field, $entry, $atts = array() ) {
51
  if ( ! is_object( $field ) || ! is_object( $entry ) || ! isset( $entry->metas ) ) {
52
  return;
53
  }
54
 
 
55
  $this->field = $field;
56
- $this->entry = $entry;
57
- $this->init_source( $atts );
58
- $this->init_saved_value();
59
- $this->init_displayed_value();
60
- }
61
-
62
- /**
63
- * Initialize the source property
64
- *
65
- * @since 2.04
66
- *
67
- * @param array $atts
68
- */
69
- protected function init_source( $atts ) {
70
- if ( isset( $atts['source'] ) && is_string( $atts['source'] ) && $atts['source'] !== '' ) {
71
- $this->source = (string) $atts['source'];
72
- } else {
73
- $this->source = 'general';
74
- }
75
  }
76
 
77
  /**
78
  * Initialize the saved_value property
79
  *
80
  * @since 2.04
 
 
81
  */
82
- protected function init_saved_value() {
83
- if ( isset( $this->entry->metas[ $this->field->id ] ) ) {
84
- $this->saved_value = $this->entry->metas[ $this->field->id ];
 
 
85
  } else {
86
  $this->saved_value = '';
87
  }
@@ -90,23 +69,16 @@ class FrmFieldValue {
90
  }
91
 
92
  /**
93
- * Initialize a field's displayed value
94
  *
95
- * @since 2.04
96
- */
97
- protected function init_displayed_value() {
98
- $this->displayed_value = $this->saved_value;
99
-
100
- $this->filter_displayed_value();
101
- }
102
-
103
- /**
104
- * Get the saved_value property
105
  *
106
- * @since 2.04
107
  */
108
- public function get_saved_value() {
109
- return $this->saved_value;
 
 
110
  }
111
 
112
  /**
@@ -153,42 +125,76 @@ class FrmFieldValue {
153
  return $this->field->type;
154
  }
155
 
 
 
 
 
 
 
 
 
 
156
  /**
157
  * Get the displayed_value property
158
  *
159
  * @since 2.04
160
  */
161
  public function get_displayed_value() {
 
 
 
 
162
  return $this->displayed_value;
163
  }
164
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  /**
166
  * Filter the displayed_value property
167
  *
168
  * @since 2.04
 
 
169
  */
170
- protected function filter_displayed_value() {
 
171
 
172
- if ( $this->source === 'entry_formatter' ) {
 
173
  // Deprecated frm_email_value hook
174
  $meta = array(
175
- 'item_id' => $this->entry->id,
176
  'field_id' => $this->field->id,
177
  'meta_value' => $this->saved_value,
178
  'field_type' => $this->field->type,
179
  );
180
- $this->displayed_value = apply_filters( 'frm_email_value', $this->displayed_value, (object) $meta, $this->entry, array(
181
- 'field' => $this->field,
182
- ) );
183
  if ( has_filter( 'frm_email_value' ) ) {
184
  _deprecated_function( 'The frm_email_value filter', '2.04', 'the frm_display_{fieldtype}_value_custom filter' );
 
 
 
185
  }
186
  }
187
 
188
  // frm_display_{fieldtype}_value_custom hook
189
  $this->displayed_value = apply_filters( 'frm_display_' . $this->field->type . '_value_custom', $this->displayed_value, array(
190
  'field' => $this->field,
191
- 'entry' => $this->entry,
192
  ) );
193
  }
194
 
15
  /**
16
  * @since 2.04
17
  *
18
+ * @var int
19
  */
20
+ protected $entry_id = 0;
 
 
 
 
 
 
 
21
 
22
  /**
23
  * @since 2.04
31
  *
32
  * @var mixed
33
  */
34
+ protected $displayed_value = 'frm_not_prepared';
35
 
36
  /**
37
  * FrmFieldValue constructor.
38
  *
39
  * @param stdClass $field
40
  * @param stdClass $entry
 
41
  */
42
+ public function __construct( $field, $entry ) {
43
  if ( ! is_object( $field ) || ! is_object( $entry ) || ! isset( $entry->metas ) ) {
44
  return;
45
  }
46
 
47
+ $this->entry_id = $entry->id;
48
  $this->field = $field;
49
+ $this->init_saved_value( $entry );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  }
51
 
52
  /**
53
  * Initialize the saved_value property
54
  *
55
  * @since 2.04
56
+ *
57
+ * @param stdClass $entry
58
  */
59
+ protected function init_saved_value( $entry ) {
60
+ if ( $this->field->type === 'html' ) {
61
+ $this->saved_value = $this->field->description;
62
+ } else if ( isset( $entry->metas[ $this->field->id ] ) ) {
63
+ $this->saved_value = $entry->metas[ $this->field->id ];
64
  } else {
65
  $this->saved_value = '';
66
  }
69
  }
70
 
71
  /**
72
+ * Prepare the display value
73
  *
74
+ * @since 2.05
 
 
 
 
 
 
 
 
 
75
  *
76
+ * @param array $atts
77
  */
78
+ public function prepare_displayed_value( $atts = array() ) {
79
+ $this->displayed_value = $this->saved_value;
80
+ $this->generate_displayed_value_for_field_type( $atts );
81
+ $this->filter_displayed_value( $atts );
82
  }
83
 
84
  /**
125
  return $this->field->type;
126
  }
127
 
128
+ /**
129
+ * Get the saved_value property
130
+ *
131
+ * @since 2.04
132
+ */
133
+ public function get_saved_value() {
134
+ return $this->saved_value;
135
+ }
136
+
137
  /**
138
  * Get the displayed_value property
139
  *
140
  * @since 2.04
141
  */
142
  public function get_displayed_value() {
143
+ if ( $this->displayed_value === 'frm_not_prepared' ) {
144
+ return __( 'The display value has not been prepared. Please use the prepare_display_value() method before calling get_displayed_value().', 'formidable' );
145
+ }
146
+
147
  return $this->displayed_value;
148
  }
149
 
150
+ /**
151
+ * Get the displayed value for different field types
152
+ *
153
+ * @since 3.0
154
+ *
155
+ * @param array $atts
156
+ *
157
+ * @return mixed
158
+ */
159
+ protected function generate_displayed_value_for_field_type( $atts ) {
160
+ if ( ! FrmAppHelper::is_empty_value( $this->displayed_value, '' ) ) {
161
+ $field_obj = FrmFieldFactory::get_field_object( $this->field );
162
+ $this->displayed_value = $field_obj->get_display_value( $this->displayed_value, $atts );
163
+ }
164
+ }
165
+
166
  /**
167
  * Filter the displayed_value property
168
  *
169
  * @since 2.04
170
+ *
171
+ * @param array $atts
172
  */
173
+ protected function filter_displayed_value( $atts ) {
174
+ $entry = FrmEntry::getOne( $this->entry_id, true );
175
 
176
+ // TODO: maybe change from 'source' to 'run_filters' = 'email'
177
+ if ( isset( $atts['source'] ) && $atts['source'] === 'entry_formatter' ) {
178
  // Deprecated frm_email_value hook
179
  $meta = array(
180
+ 'item_id' => $entry->id,
181
  'field_id' => $this->field->id,
182
  'meta_value' => $this->saved_value,
183
  'field_type' => $this->field->type,
184
  );
185
+
 
 
186
  if ( has_filter( 'frm_email_value' ) ) {
187
  _deprecated_function( 'The frm_email_value filter', '2.04', 'the frm_display_{fieldtype}_value_custom filter' );
188
+ $this->displayed_value = apply_filters( 'frm_email_value', $this->displayed_value, (object) $meta, $entry, array(
189
+ 'field' => $this->field,
190
+ ) );
191
  }
192
  }
193
 
194
  // frm_display_{fieldtype}_value_custom hook
195
  $this->displayed_value = apply_filters( 'frm_display_' . $this->field->type . '_value_custom', $this->displayed_value, array(
196
  'field' => $this->field,
197
+ 'entry' => $entry,
198
  ) );
199
  }
200
 
classes/models/FrmFieldValueSelector.php CHANGED
@@ -137,7 +137,8 @@ class FrmFieldValueSelector {
137
  * @since 2.03.05
138
  */
139
  protected function set_options() {
140
- $this->options = maybe_unserialize( $this->db_row->options );
 
141
  }
142
 
143
  /**
137
  * @since 2.03.05
138
  */
139
  protected function set_options() {
140
+ $field_obj = FrmFieldFactory::get_field_object( $this->db_row );
141
+ $this->options = $field_obj->get_options( array() );
142
  }
143
 
144
  /**
classes/models/FrmForm.php CHANGED
@@ -228,32 +228,23 @@ class FrmForm {
228
 
229
  $is_settings_page = ( isset( $values['options'] ) || isset( $values['field_options'][ 'custom_html_' . $field_id ] ) );
230
  if ( $is_settings_page ) {
231
- //updating the settings page
232
- if ( isset( $values['field_options'][ 'custom_html_' . $field_id ] ) ) {
233
- $field->field_options['custom_html'] = isset( $values['field_options'][ 'custom_html_' . $field_id ] ) ? $values['field_options'][ 'custom_html_' . $field_id ] : ( isset( $field->field_options['custom_html'] ) ? $field->field_options['custom_html'] : FrmFieldsHelper::get_default_html( $field->type ) );
234
- $field->field_options = apply_filters('frm_update_form_field_options', $field->field_options, $field, $values);
235
- FrmField::update( $field_id, array( 'field_options' => $field->field_options ) );
236
- } else if ( $field->type == 'hidden' || $field->type == 'user_id' ) {
237
- $prev_opts = $field->field_options;
238
- $field->field_options = apply_filters('frm_update_form_field_options', $field->field_options, $field, $values);
239
- if ( $prev_opts != $field->field_options ) {
240
- FrmField::update( $field_id, array( 'field_options' => $field->field_options ) );
241
- }
242
- unset($prev_opts);
243
- }
244
- }
245
 
246
- if ( $is_settings_page && ! defined( 'WP_IMPORTING' ) ) {
247
- continue;
248
- }
 
249
 
250
- //updating the form
251
- $update_options = FrmFieldsHelper::get_default_field_opts( $field->type, $field, true );
252
  unset( $update_options['custom_html'] ); // don't check for POST html
253
  $update_options = apply_filters( 'frm_field_options_to_update', $update_options );
254
 
255
  foreach ( $update_options as $opt => $default ) {
256
- $field->field_options[ $opt ] = isset( $values['field_options'][ $opt . '_' . $field_id ] ) ? trim( sanitize_text_field( $values['field_options'][ $opt . '_' . $field_id ] ) ) : $default;
 
 
 
257
  }
258
 
259
  $field->field_options = apply_filters('frm_update_field_options', $field->field_options, $field, $values);
@@ -275,13 +266,34 @@ class FrmForm {
275
  return $values;
276
  }
277
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
  private static function prepare_field_update_values( $field, $values, &$new_field ) {
279
  $field_cols = array(
280
- 'field_key' => '',
281
- 'required' => false,
282
- 'type' => '',
283
  'description' => '',
284
- 'options' => '',
 
285
  );
286
  foreach ( $field_cols as $col => $default ) {
287
  $default = ( $default === '' ) ? $field->{$col} : $default;
@@ -459,18 +471,29 @@ class FrmForm {
459
  }
460
 
461
  /**
 
462
  * @param string $key
463
  * @return int form id
464
  */
465
- public static function getIdByKey( $key ) {
466
  return (int) FrmDb::get_var( 'frm_forms', array( 'form_key' => sanitize_title( $key ) ) );
467
  }
468
 
469
  /**
 
 
 
 
 
 
 
 
 
 
470
  * @param int $id
471
  * @return string form key
472
  */
473
- public static function getKeyById( $id ) {
474
  $id = (int) $id;
475
  $cache = FrmDb::check_cache( $id, 'frm_form' );
476
  if ( $cache ) {
@@ -482,6 +505,11 @@ class FrmForm {
482
  return $key;
483
  }
484
 
 
 
 
 
 
485
  /**
486
  * If $form is numeric, get the form object
487
  * @param object|int $form
228
 
229
  $is_settings_page = ( isset( $values['options'] ) || isset( $values['field_options'][ 'custom_html_' . $field_id ] ) );
230
  if ( $is_settings_page ) {
231
+ self::get_settings_page_html( $values, $field );
 
 
 
 
 
 
 
 
 
 
 
 
 
232
 
233
+ if ( ! defined( 'WP_IMPORTING' ) ) {
234
+ continue;
235
+ }
236
+ }
237
 
238
+ //updating the form
239
+ $update_options = FrmFieldsHelper::get_default_field_options_from_field( $field );
240
  unset( $update_options['custom_html'] ); // don't check for POST html
241
  $update_options = apply_filters( 'frm_field_options_to_update', $update_options );
242
 
243
  foreach ( $update_options as $opt => $default ) {
244
+ $field->field_options[ $opt ] = isset( $values['field_options'][ $opt . '_' . $field_id ] ) ? $values['field_options'][ $opt . '_' . $field_id ] : $default;
245
+ if ( is_string( $field->field_options[ $opt ] ) ) {
246
+ $field->field_options[ $opt ] = trim( sanitize_text_field( $field->field_options[ $opt ] ) );
247
+ }
248
  }
249
 
250
  $field->field_options = apply_filters('frm_update_field_options', $field->field_options, $field, $values);
266
  return $values;
267
  }
268
 
269
+ /**
270
+ * updating the settings page
271
+ */
272
+ private static function get_settings_page_html( $values, &$field ) {
273
+ if ( isset( $values['field_options'][ 'custom_html_' . $field->id ] ) ) {
274
+ $prev_opts = array();
275
+ $fallback_html = isset( $field->field_options['custom_html'] ) ? $field->field_options['custom_html'] : FrmFieldsHelper::get_default_html( $field->type );
276
+ $field->field_options['custom_html'] = isset( $values['field_options'][ 'custom_html_' . $field->id ] ) ? $values['field_options'][ 'custom_html_' . $field->id ] : $fallback_html;
277
+ } elseif ( $field->type == 'hidden' || $field->type == 'user_id' ) {
278
+ $prev_opts = $field->field_options;
279
+ }
280
+
281
+ if ( isset( $prev_opts ) ) {
282
+ $field->field_options = apply_filters( 'frm_update_form_field_options', $field->field_options, $field, $values );
283
+ if ( $prev_opts != $field->field_options ) {
284
+ FrmField::update( $field->id, array( 'field_options' => $field->field_options ) );
285
+ }
286
+ }
287
+ }
288
+
289
  private static function prepare_field_update_values( $field, $values, &$new_field ) {
290
  $field_cols = array(
291
+ 'field_key' => '',
292
+ 'required' => false,
293
+ 'type' => '',
294
  'description' => '',
295
+ 'options' => '',
296
+ 'name' => '',
297
  );
298
  foreach ( $field_cols as $col => $default ) {
299
  $default = ( $default === '' ) ? $field->{$col} : $default;
471
  }
472
 
473
  /**
474
+ * @since 3.0
475
  * @param string $key
476
  * @return int form id
477
  */
478
+ public static function get_id_by_key( $key ) {
479
  return (int) FrmDb::get_var( 'frm_forms', array( 'form_key' => sanitize_title( $key ) ) );
480
  }
481
 
482
  /**
483
+ * @param string $key
484
+ * @return int form id
485
+ */
486
+ public static function getIdByKey( $key ) {
487
+ _deprecated_function( __METHOD__, '3.0', 'FrmForm::get_id_by_key' );
488
+ return self::get_id_by_key( $key );
489
+ }
490
+
491
+ /**
492
+ * @since 3.0
493
  * @param int $id
494
  * @return string form key
495
  */
496
+ public static function get_key_by_id( $id ) {
497
  $id = (int) $id;
498
  $cache = FrmDb::check_cache( $id, 'frm_form' );
499
  if ( $cache ) {
505
  return $key;
506
  }
507
 
508
+ public static function getKeyById( $id ) {
509
+ _deprecated_function( __METHOD__, '3.0', 'FrmForm::get_key_by_id' );
510
+ return self::get_key_by_id( $id );
511
+ }
512
+
513
  /**
514
  * If $form is numeric, get the form object
515
  * @param object|int $form
classes/models/FrmFormDeprecated.php CHANGED
@@ -111,16 +111,16 @@ class FrmFormDeprecated {
111
  public static function getIdByKey( $key ) {
112
  _deprecated_function( __FUNCTION__, '2.03.05', 'FrmForm::getIdByKey' );
113
 
114
- return FrmForm::getIdByKey( $key );
115
  }
116
 
117
  /**
118
  * @deprecated 2.03.05
119
  */
120
  public static function getKeyById( $id ) {
121
- _deprecated_function( __FUNCTION__, '2.03.05', 'FrmForm::getKeyById' );
122
 
123
- return FrmForm::getKeyById( $id );
124
  }
125
 
126
  /**
111
  public static function getIdByKey( $key ) {
112
  _deprecated_function( __FUNCTION__, '2.03.05', 'FrmForm::getIdByKey' );
113
 
114
+ return FrmForm::get_id_by_key( $key );
115
  }
116
 
117
  /**
118
  * @deprecated 2.03.05
119
  */
120
  public static function getKeyById( $id ) {
121
+ _deprecated_function( __FUNCTION__, '2.03.05', 'FrmForm::get_key_by_id' );
122
 
123
+ return FrmForm::get_key_by_id( $id );
124
  }
125
 
126
  /**
classes/models/FrmMigrate.php CHANGED
@@ -21,7 +21,10 @@ class FrmMigrate {
21
  public function upgrade( $old_db_version = false ) {
22
  do_action( 'frm_before_install' );
23
 
24
- global $wpdb;
 
 
 
25
  //$frm_db_version is the version of the database we're moving to
26
  $frm_db_version = FrmAppHelper::$db_version;
27
  $old_db_version = (float) $old_db_version;
@@ -41,6 +44,8 @@ class FrmMigrate {
41
  /***** SAVE DB VERSION *****/
42
  update_option('frm_db_version', $frm_db_version);
43
 
 
 
44
  /**** ADD/UPDATE DEFAULT TEMPLATES ****/
45
  FrmXMLController::add_default_templates();
46
 
@@ -51,6 +56,8 @@ class FrmMigrate {
51
 
52
  do_action('frm_after_install');
53
 
 
 
54
  /**** update the styling settings ****/
55
  if ( is_admin() && function_exists( 'get_filesystem_method' ) ) {
56
  $frm_style = new FrmStyle();
@@ -164,7 +171,7 @@ class FrmMigrate {
164
  }
165
 
166
  private function maybe_create_contact_form() {
167
- $template_id = FrmForm::getIdByKey( 'contact' );
168
  if ( $template_id ) {
169
  $form_id = FrmForm::duplicate( $template_id, false, true );
170
  if ( $form_id ) {
@@ -336,8 +343,6 @@ class FrmMigrate {
336
  * Migrate post and email notification settings into actions
337
  */
338
  private function migrate_to_16() {
339
- global $wpdb;
340
-
341
  $forms = FrmDb::get_results( $this->forms, array(), 'id, options, is_template, default_template' );
342
 
343
  /**
21
  public function upgrade( $old_db_version = false ) {
22
  do_action( 'frm_before_install' );
23
 
24
+ global $wpdb, $frm_vars;
25
+
26
+ $frm_vars['doing_upgrade'] = true;
27
+
28
  //$frm_db_version is the version of the database we're moving to
29
  $frm_db_version = FrmAppHelper::$db_version;
30
  $old_db_version = (float) $old_db_version;
44
  /***** SAVE DB VERSION *****/
45
  update_option('frm_db_version', $frm_db_version);
46
 
47
+ FrmAppHelper::save_combined_js();
48
+
49
  /**** ADD/UPDATE DEFAULT TEMPLATES ****/
50
  FrmXMLController::add_default_templates();
51
 
56
 
57
  do_action('frm_after_install');
58
 
59
+ $frm_vars['doing_upgrade'] = false;
60
+
61
  /**** update the styling settings ****/
62
  if ( is_admin() && function_exists( 'get_filesystem_method' ) ) {
63
  $frm_style = new FrmStyle();
171
  }
172
 
173
  private function maybe_create_contact_form() {
174
+ $template_id = FrmForm::get_id_by_key( 'contact' );
175
  if ( $template_id ) {
176
  $form_id = FrmForm::duplicate( $template_id, false, true );
177
  if ( $form_id ) {
343
  * Migrate post and email notification settings into actions
344
  */
345
  private function migrate_to_16() {
 
 
346
  $forms = FrmDb::get_results( $this->forms, array(), 'id, options, is_template, default_template' );
347
 
348
  /**
classes/models/FrmSettings.php CHANGED
@@ -4,11 +4,11 @@ class FrmSettings {
4
  public $option_name = 'frm_options';
5
  public $menu;
6
  public $mu_menu;
7
- public $preview_page_id;
8
  public $use_html;
9
  public $jquery_css;
10
  public $accordion_js;
11
  public $fade_form;
 
12
 
13
  public $success_msg;
14
  public $blank_msg;
@@ -82,11 +82,11 @@ class FrmSettings {
82
  return array(
83
  'menu' => apply_filters( 'frm_default_menu', 'Formidable' ),
84
  'mu_menu' => 0,
85
- 'preview_page_id' => 0,
86
  'use_html' => true,
87
  'jquery_css' => false,
88
  'accordion_js' => false,
89
  'fade_form' => false,
 
90
 
91
  're_multi' => 0,
92
 
@@ -209,12 +209,12 @@ class FrmSettings {
209
  $this->re_multi = isset( $params['frm_re_multi'] ) ? $params['frm_re_multi'] : 0;
210
 
211
  $this->load_style = $params['frm_load_style'];
212
- $this->preview_page_id = (int) $params['frm-preview-page-id'];
213
 
214
  $this->use_html = isset($params['frm_use_html']) ? $params['frm_use_html'] : 0;
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
 
4
  public $option_name = 'frm_options';
5
  public $menu;
6
  public $mu_menu;
 
7
  public $use_html;
8
  public $jquery_css;
9
  public $accordion_js;
10
  public $fade_form;
11
+ public $old_css;
12
 
13
  public $success_msg;
14
  public $blank_msg;
82
  return array(
83
  'menu' => apply_filters( 'frm_default_menu', 'Formidable' ),
84
  'mu_menu' => 0,
 
85
  'use_html' => true,
86
  'jquery_css' => false,
87
  'accordion_js' => false,
88
  'fade_form' => false,
89
+ 'old_css' => false,
90
 
91
  're_multi' => 0,
92
 
209
  $this->re_multi = isset( $params['frm_re_multi'] ) ? $params['frm_re_multi'] : 0;
210
 
211
  $this->load_style = $params['frm_load_style'];
 
212
 
213
  $this->use_html = isset($params['frm_use_html']) ? $params['frm_use_html'] : 0;
214
  $this->jquery_css = isset( $params['frm_jquery_css'] ) ? absint( $params['frm_jquery_css'] ) : 0;
215
  $this->accordion_js = isset( $params['frm_accordion_js'] ) ? absint( $params['frm_accordion_js'] ) : 0;
216
  $this->fade_form = isset( $params['frm_fade_form'] ) ? absint( $params['frm_fade_form'] ) : 0;
217
+ $this->old_css = isset( $params['frm_old_css'] ) ? absint( $params['frm_old_css'] ) : 0;
218
  $this->no_ips = isset( $params['frm_no_ips'] ) ? absint( $params['frm_no_ips'] ) : 0;
219
  }
220
 
classes/models/fields/FrmFieldCaptcha.php ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @since 3.0
5
+ */
6
+ class FrmFieldCaptcha extends FrmFieldType {
7
+
8
+ /**
9
+ * @var string
10
+ * @since 3.0
11
+ */
12
+ protected $type = 'captcha';
13
+
14
+ /**
15
+ * @var bool
16
+ * @since 3.0
17
+ */
18
+ protected $has_for_label = false;
19
+
20
+ protected $is_tall = true;
21
+
22
+ /**
23
+ * @return string
24
+ */
25
+ protected function include_form_builder_file() {
26
+ return FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/field-captcha.php';
27
+ }
28
+
29
+ /**
30
+ * @return array
31
+ */
32
+ protected function field_settings_for_type() {
33
+ return array(
34
+ 'required' => false,
35
+ 'invalid' => true,
36
+ 'default_blank' => false,
37
+ 'captcha_size' => true,
38
+ );
39
+ }
40
+
41
+ /**
42
+ * @return array
43
+ */
44
+ protected function new_field_settings() {
45
+ $frm_settings = FrmAppHelper::get_settings();
46
+ return array(
47
+ 'invalid' => $frm_settings->re_msg,
48
+ );
49
+ }
50
+
51
+ /**
52
+ * @return array
53
+ */
54
+ protected function extra_field_opts() {
55
+ return array(
56
+ 'label' => 'none',
57
+ 'captcha_size' => 'normal',
58
+ 'captcha_theme' => 'light',
59
+ );
60
+ }
61
+
62
+ /**
63
+ * Remove the "for" attribute for captcha
64
+ *
65
+ * @param array $args
66
+ * @param string $html
67
+ *
68
+ * @return string
69
+ */
70
+ protected function before_replace_html_shortcodes( $args, $html ) {
71
+ return str_replace( ' for="field_[key]"', '', $html );
72
+ }
73
+
74
+ public function front_field_input( $args, $shortcode_atts ) {
75
+ $frm_settings = FrmAppHelper::get_settings();
76
+ if ( empty( $frm_settings->pubkey ) ) {
77
+ return '';
78
+ }
79
+
80
+ $class_prefix = $this->class_prefix();
81
+ $captcha_size = $this->captcha_size();
82
+ $allow_mutiple = $frm_settings->re_multi;
83
+
84
+ $html = '<div id="' . esc_attr( $args['html_id'] ) . '" class="' . esc_attr( $class_prefix ) . 'g-recaptcha" data-sitekey="' . esc_attr( $frm_settings->pubkey ) . '" data-size="' . esc_attr( $captcha_size ) . '" data-theme="' . esc_attr( $this->field['captcha_theme'] ) . '"';
85
+ if ( $captcha_size == 'invisible' && ! $allow_mutiple ) {
86
+ $html .= ' data-callback="frmAfterRecaptcha"';
87
+ }
88
+ $html .= '></div>';
89
+
90
+ return $html;
91
+ }
92
+
93
+ protected function load_field_scripts( $args ) {
94
+ $api_js_url = $this->api_url();
95
+
96
+ wp_register_script( 'recaptcha-api', $api_js_url, array( 'formidable' ), true );
97
+ wp_enqueue_script( 'recaptcha-api' );
98
+ }
99
+
100
+ protected function api_url() {
101
+ $api_js_url = 'https://www.google.com/recaptcha/api.js?';
102
+
103
+ $frm_settings = FrmAppHelper::get_settings();
104
+ $allow_mutiple = $frm_settings->re_multi;
105
+ if ( $allow_mutiple ) {
106
+ $api_js_url .= '&onload=frmRecaptcha&render=explicit';
107
+ }
108
+
109
+ $lang = apply_filters( 'frm_recaptcha_lang', $frm_settings->re_lang, $this->field );
110
+ if ( ! empty( $lang ) ) {
111
+ $api_js_url .= '&hl=' . $lang;
112
+ }
113
+
114
+ return apply_filters( 'frm_recaptcha_js_url', $api_js_url );
115
+ }
116
+
117
+ protected function class_prefix() {
118
+ if ( $this->allow_multiple() ) {
119
+ $class_prefix = 'frm-';
120
+ } else {
121
+ $class_prefix = '';
122
+ }
123
+ return $class_prefix;
124
+ }
125
+
126
+ protected function allow_multiple() {
127
+ $frm_settings = FrmAppHelper::get_settings();
128
+ return $frm_settings->re_multi;
129
+ }
130
+
131
+ protected function captcha_size() {
132
+ // for reverse compatibility
133
+ $frm_settings = FrmAppHelper::get_settings();
134
+ $captcha_size = ( $this->field['captcha_size'] == 'default' ) ? 'normal' : $this->field['captcha_size'];
135
+ return ( $frm_settings->re_type == 'invisible' ) ? 'invisible' : $captcha_size;
136
+ }
137
+
138
+ public function validate( $args ) {
139
+ $errors = array();
140
+
141
+ if ( ! $this->should_validate() ) {
142
+ return $errors;
143
+ }
144
+
145
+ if ( ! isset( $_POST['g-recaptcha-response']) ) {
146
+ // If captcha is missing, check if it was already verified
147
+ if ( ! isset( $_POST['recaptcha_checked'] ) || ! wp_verify_nonce( $_POST['recaptcha_checked'], 'frm_ajax' ) ) {
148
+ // There was no captcha submitted
149
+ $errors[ 'field' . $args['id'] ] = __( 'The captcha is missing from this form', 'formidable' );
150
+ }
151
+ return $errors;
152
+ }
153
+
154
+ $frm_settings = FrmAppHelper::get_settings();
155
+
156
+ $resp = $this->send_api_check( $frm_settings );
157
+ $response = json_decode( wp_remote_retrieve_body( $resp ), true );
158
+
159
+ if ( isset( $response['success'] ) && ! $response['success'] ) {
160
+ // What happens when the CAPTCHA was entered incorrectly
161
+ $invalid_message = FrmField::get_option( $this->field, 'invalid' );
162
+ $errors[ 'field' . $args['id'] ] = ( $invalid_message == '' ? $frm_settings->re_msg : $invalid_message );
163
+ } elseif ( is_wp_error( $resp ) ) {
164
+ $error_string = $resp->get_error_message();
165
+ $errors[ 'field' . $args['id'] ] = __( 'There was a problem verifying your recaptcha', 'formidable' );
166
+ $errors[ 'field' . $args['id'] ] .= ' ' . $error_string;
167
+ }
168
+
169
+ return $errors;
170
+ }
171
+
172
+ protected function should_validate() {
173
+ $is_hidden_field = apply_filters( 'frm_is_field_hidden', false, $this->field, stripslashes_deep( $_POST ) );
174
+ if ( FrmAppHelper::is_admin() || $is_hidden_field ) {
175
+ return false;
176
+ }
177
+
178
+ $frm_settings = FrmAppHelper::get_settings();
179
+ if ( empty( $frm_settings->pubkey ) ) {
180
+ // don't require the captcha if it shouldn't be shown
181
+ return false;
182
+ }
183
+
184
+ return true;
185
+ }
186
+
187
+ protected function send_api_check( $frm_settings ) {
188
+ $arg_array = array(
189
+ 'body' => array(
190
+ 'secret' => $frm_settings->privkey,
191
+ 'response' => $_POST['g-recaptcha-response'],
192
+ 'remoteip' => FrmAppHelper::get_ip_address(),
193
+ ),
194
+ );
195
+
196
+ return wp_remote_post( 'https://www.google.com/recaptcha/api/siteverify', $arg_array );
197
+ }
198
+ }
classes/models/fields/FrmFieldCheckbox.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @since 3.0
5
+ */
6
+ class FrmFieldCheckbox extends FrmFieldType {
7
+
8
+ /**
9
+ * @var string
10
+ * @since 3.0
11
+ */
12
+ protected $type = 'checkbox';
13
+
14
+ /**
15
+ * @var bool
16
+ * @since 3.0
17
+ */
18
+ protected $holds_email_values = true;
19
+
20
+ protected $is_tall = true;
21
+
22
+ protected function input_html() {
23
+ return $this->multiple_input_html();
24
+ }
25
+
26
+ protected function include_form_builder_file() {
27
+ return FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/field-multiple.php';
28
+ }
29
+
30
+ protected function field_settings_for_type() {
31
+ return array(
32
+ 'default_blank' => false,
33
+ );
34
+ }
35
+
36
+ protected function new_field_settings() {
37
+ return array(
38
+ 'options' => serialize( array(
39
+ __( 'Option 1', 'formidable' ),
40
+ __( 'Option 2', 'formidable' ),
41
+ ) ),
42
+ );
43
+ }
44
+
45
+ protected function extra_field_opts() {
46
+ $form_id = $this->get_field_column('form_id');
47
+ return array(
48
+ 'align' => FrmStylesController::get_style_val( 'check_align', ( empty( $form_id ) ? 'default' : $form_id ) ),
49
+ );
50
+ }
51
+
52
+ protected function include_front_form_file() {
53
+ return FrmAppHelper::plugin_path() . '/classes/views/frm-fields/front-end/checkbox-field.php';
54
+ }
55
+
56
+ protected function show_readonly_hidden() {
57
+ return true;
58
+ }
59
+
60
+ protected function prepare_import_value( $value, $atts ) {
61
+ return $this->get_multi_opts_for_import( $value );
62
+ }
63
+ }
classes/models/fields/FrmFieldDefault.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @since 3.0
5
+ */
6
+ class FrmFieldDefault extends FrmFieldType {
7
+
8
+ /**
9
+ * @var bool
10
+ * @since 3.0
11
+ */
12
+ protected $holds_email_values = true;
13
+
14
+ /**
15
+ * @param $type string
16
+ */
17
+ protected function set_type( $type ) {
18
+ if ( empty( $type ) ) {
19
+ $type = 'text';
20
+ }
21
+ parent::set_type( $type );
22
+ }
23
+
24
+ public function show_on_form_builder( $name = '' ) {
25
+ $field = FrmFieldsHelper::setup_edit_vars( $this->field );
26
+
27
+ ob_start();
28
+ do_action( 'frm_display_added_fields', $field );
29
+ do_action( 'frm_display_added_' . $this->type . '_field', $field );
30
+ $input_html = ob_get_contents();
31
+ ob_end_clean();
32
+
33
+ if ( empty( $input_html ) ) {
34
+ echo $this->builder_text_field();
35
+ } else {
36
+ echo $input_html;
37
+ }
38
+ }
39
+
40
+ public function front_field_input( $args, $shortcode_atts ) {
41
+ $pass_args = array(
42
+ 'errors' => $args['errors'],
43
+ 'html_id' => $args['html_id'],
44
+ );
45
+ ob_start();
46
+ do_action( 'frm_form_fields', $this->field, $args['field_name'], $pass_args );
47
+ do_action( 'frm_form_field_' . $this->type, $this->field, $args['field_name'], $pass_args );
48
+ $input_html = ob_get_contents();
49
+ ob_end_clean();
50
+
51
+ return $input_html;
52
+ }
53
+ }
classes/models/fields/FrmFieldEmail.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @since 3.0
5
+ */
6
+ class FrmFieldEmail extends FrmFieldType {
7
+
8
+ /**
9
+ * @var string
10
+ * @since 3.0
11
+ */
12
+ protected $type = 'email';
13
+ protected $display_type = 'text';
14
+
15
+ /**
16
+ * @var bool
17
+ * @since 3.0
18
+ */
19
+ protected $holds_email_values = true;
20
+
21
+ protected function field_settings_for_type() {
22
+ return array(
23
+ 'size' => true,
24
+ 'clear_on_focus' => true,
25
+ 'invalid' => true,
26
+ );
27
+ }
28
+
29
+ /**
30
+ * validate the email format
31
+ *
32
+ * @param array $args
33
+ *
34
+ * @return array
35
+ */
36
+ public function validate( $args ) {
37
+ $errors = array();
38
+ if ( $args['value'] != '' && ! is_email( $args['value'] ) ) {
39
+ $errors[ 'field' . $args['id'] ] = FrmFieldsHelper::get_error_msg( $this->field, 'invalid' );
40
+ }
41
+ return $errors;
42
+ }
43
+ }
classes/models/fields/FrmFieldHTML.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @since 3.0
5
+ */
6
+ class FrmFieldHTML extends FrmFieldType {
7
+
8
+ /**
9
+ * @var string
10
+ * @since 3.0
11
+ */
12
+ protected $type = 'html';
13
+
14
+ /**
15
+ * @var bool
16
+ * @since 3.0
17
+ */
18
+ protected $has_input = false;
19
+
20
+ protected $is_tall = true;
21
+
22
+ public function default_html() {
23
+ return '<div id="frm_field_[id]_container" class="frm_form_field form-field">[description]</div>';
24
+ }
25
+
26
+ /**
27
+ * @since 3.0
28
+ */
29
+ protected function after_replace_html_shortcodes( $args, $html ) {
30
+ FrmFieldsHelper::run_wpautop( array( 'wpautop' => true ), $html );
31
+ $pre_filter = $html;
32
+ $html = apply_filters( 'frm_get_default_value', $html, (object) $this->field, false );
33
+ if ( $pre_filter === $html ) {
34
+ $html = do_shortcode( $html );
35
+ }
36
+ return $html;
37
+ }
38
+
39
+ public function get_container_class() {
40
+ return ' frm_html_container';
41
+ }
42
+
43
+ protected function include_form_builder_file() {
44
+ return FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/field-html.php';
45
+ }
46
+ }
classes/models/fields/FrmFieldHidden.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @since 3.0
5
+ */
6
+ class FrmFieldHidden extends FrmFieldType {
7
+
8
+ /**
9
+ * @var string
10
+ * @since 3.0
11
+ */
12
+ protected $type = 'hidden';
13
+
14
+ /**
15
+ * @var bool
16
+ * @since 3.0
17
+ */
18
+ protected $has_input = false;
19
+
20
+ /**
21
+ * @var bool
22
+ * @since 3.0
23
+ */
24
+ protected $has_html = false;
25
+
26
+ /**
27
+ * @var bool
28
+ * @since 3.0
29
+ */
30
+ protected $holds_email_values = true;
31
+
32
+ protected function field_settings_for_type() {
33
+ $settings = parent::field_settings_for_type();
34
+ $settings['css'] = false;
35
+ return $settings;
36
+ }
37
+
38
+ protected function include_form_builder_file() {
39
+ return FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/field-hidden.php';
40
+ }
41
+
42
+ protected function html5_input_type() {
43
+ return 'hidden';
44
+ }
45
+ }
classes/models/fields/FrmFieldNumber.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @since 3.0
5
+ */
6
+ class FrmFieldNumber extends FrmFieldType {
7
+
8
+ /**
9
+ * @var string
10
+ * @since 3.0
11
+ */
12
+ protected $type = 'number';
13
+ protected $display_type = 'text';
14
+
15
+ protected function field_settings_for_type() {
16
+ $settings = array(
17
+ 'size' => true,
18
+ 'clear_on_focus' => true,
19
+ 'invalid' => true,
20
+ 'range' => true,
21
+ );
22
+
23
+ $frm_settings = FrmAppHelper::get_settings();
24
+ if ( $frm_settings->use_html ) {
25
+ $settings['max'] = false;
26
+ }
27
+
28
+ return $settings;
29
+ }
30
+
31
+ protected function extra_field_opts() {
32
+ return array(
33
+ 'minnum' => 0,
34
+ 'maxnum' => 9999999,
35
+ 'step' => 'any',
36
+ );
37
+ }
38
+
39
+ public function validate( $args ) {
40
+ $errors = array();
41
+
42
+ $this->remove_commas_from_number( $args );
43
+
44
+ //validate the number format
45
+ if ( ! is_numeric( $args['value'] ) ) {
46
+ $errors[ 'field' . $args['id'] ] = FrmFieldsHelper::get_error_msg( $this->field, 'invalid' );
47
+ }
48
+
49
+ // validate number settings
50
+ if ( $args['value'] != '' ) {
51
+ $frm_settings = FrmAppHelper::get_settings();
52
+ // only check if options are available in settings
53
+ $minnum = FrmField::get_option( $this->field, 'minnum' );
54
+ $maxnum = FrmField::get_option( $this->field, 'maxnum' );
55
+ if ( $frm_settings->use_html && $maxnum != '' && $minnum != '' ) {
56
+ $value = (float) $args['value'];
57
+ if ( $value < $minnum ) {
58
+ $errors[ 'field' . $args['id'] ] = __( 'Please select a higher number', 'formidable' );
59
+ } elseif ( $value > $maxnum ) {
60
+ $errors[ 'field' . $args['id'] ] = __( 'Please select a lower number', 'formidable' );
61
+ }
62
+ }
63
+ }
64
+
65
+ return $errors;
66
+ }
67
+
68
+
69
+ /**
70
+ * IE fallback for number fields
71
+ * Remove the comma when HTML5 isn't supported
72
+ *
73
+ * @since 3.0
74
+ */
75
+ private function remove_commas_from_number( &$args ) {
76
+ if ( strpos( $args['value'], ',' ) ) {
77
+ $args['value'] = str_replace( ',', '', $args['value'] );
78
+ FrmEntriesHelper::set_posted_value( $this->field, $args['value'], $args );
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Force the value to be numeric before it's saved in the DB
84
+ */
85
+ public function set_value_before_save( $value ) {
86
+ if ( ! is_numeric( $value ) ) {
87
+ $value = (float) $value;
88
+ }
89
+ return $value;
90
+ }
91
+ }
classes/models/fields/FrmFieldPhone.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @since 3.0
5
+ */
6
+ class FrmFieldPhone extends FrmFieldType {
7
+
8
+ /**
9
+ * @var string
10
+ * @since 3.0
11
+ */
12
+ protected $type = 'phone';
13
+ protected $display_type = 'text';
14
+
15
+ /**
16
+ * @var bool
17
+ * @since 3.0
18
+ */
19
+ protected $holds_email_values = true;
20
+
21
+ protected function field_settings_for_type() {
22
+ return array(
23
+ 'size' => true,
24
+ 'clear_on_focus' => true,
25
+ 'invalid' => true,
26
+ 'format' => true,
27
+ );
28
+ }
29
+
30
+ protected function html5_input_type() {
31
+ $frm_settings = FrmAppHelper::get_settings();
32
+ return $frm_settings->use_html ? 'tel' : 'text';
33
+ }
34
+ }
classes/models/fields/FrmFieldRadio.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @since 3.0
5
+ */
6
+ class FrmFieldRadio extends FrmFieldType {
7
+
8
+ /**
9
+ * @var string
10
+ * @since 3.0
11
+ */
12
+ protected $type = 'radio';
13
+
14
+ /**
15
+ * @var bool
16
+ * @since 3.0
17
+ */
18
+ protected $holds_email_values = true;
19
+
20
+ protected $is_tall = true;
21
+
22
+ protected function input_html() {
23
+ return $this->multiple_input_html();
24
+ }
25
+
26
+ protected function include_form_builder_file() {
27
+ return FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/field-multiple.php';
28
+ }
29
+
30
+ protected function field_settings_for_type() {
31
+ return array(
32
+ 'default_blank' => false,
33
+ );
34
+ }
35
+
36
+ protected function extra_field_opts() {
37
+ $form_id = $this->get_field_column('form_id');
38
+ return array(
39
+ 'align' => FrmStylesController::get_style_val( 'radio_align', ( empty( $form_id ) ? 'default' : $form_id ) ),
40
+ );
41
+ }
42
+
43
+ protected function new_field_settings() {
44
+ return array(
45
+ 'options' => serialize( array(
46
+ __( 'Option 1', 'formidable' ),
47
+ __( 'Option 2', 'formidable' ),
48
+ ) ),
49
+ );
50
+ }
51
+
52
+ protected function include_front_form_file() {
53
+ return FrmAppHelper::plugin_path() . '/classes/views/frm-fields/front-end/radio-field.php';
54
+ }
55
+
56
+ protected function show_readonly_hidden() {
57
+ return true;
58
+ }
59
+ }
classes/models/fields/FrmFieldSelect.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @since 3.0
5
+ */
6
+ class FrmFieldSelect extends FrmFieldType {
7
+
8
+ /**
9
+ * @var string
10
+ * @since 3.0
11
+ */
12
+ protected $type = 'select';
13
+
14
+ /**
15
+ * @var bool
16
+ * @since 3.0
17
+ */
18
+ protected $holds_email_values = true;
19
+
20
+ protected function include_form_builder_file() {
21
+ return FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/dropdown-field.php';
22
+ }
23
+
24
+ protected function field_settings_for_type() {
25
+ return array(
26
+ 'size' => true,
27
+ );
28
+ }
29
+
30
+ protected function new_field_settings() {
31
+ return array(
32
+ 'options' => serialize( array(
33
+ '',
34
+ __( 'Option 1', 'formidable' ),
35
+ ) ),
36
+ );
37
+ }
38
+
39
+ protected function include_front_form_file() {
40
+ return FrmAppHelper::plugin_path() . '/classes/views/frm-fields/front-end/dropdown-field.php';
41
+ }
42
+
43
+ protected function show_readonly_hidden() {
44
+ return true;
45
+ }
46
+
47
+ protected function prepare_import_value( $value, $atts ) {
48
+ if ( FrmField::is_option_true( $this->field, 'multiple' ) ) {
49
+ $value = $this->get_multi_opts_for_import( $value );
50
+ }
51
+ return $value;
52
+ }
53
+ }
classes/models/fields/FrmFieldText.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @since 3.0
5
+ */
6
+ class FrmFieldText extends FrmFieldType {
7
+
8
+ /**
9
+ * @var string
10
+ * @since 3.0
11
+ */
12
+ protected $type = 'text';
13
+
14
+ /**
15
+ * @var bool
16
+ * @since 3.0
17
+ */
18
+ protected $holds_email_values = true;
19
+
20
+ protected function field_settings_for_type() {
21
+ return array(
22
+ 'size' => true,
23
+ 'clear_on_focus' => true,
24
+ 'format' => true,
25
+ 'invalid' => true,
26
+ );
27
+ }
28
+ }
classes/models/fields/FrmFieldTextarea.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @since 3.0
5
+ */
6
+ class FrmFieldTextarea extends FrmFieldType {
7
+
8
+ /**
9
+ * @var string
10
+ * @since 3.0
11
+ */
12
+ protected $type = 'textarea';
13
+
14
+ protected $is_tall = true;
15
+
16
+ protected function field_settings_for_type() {
17
+ return array(
18
+ 'size' => true,
19
+ 'clear_on_focus' => true,
20
+ );
21
+ }
22
+
23
+ protected function extra_field_opts() {
24
+ return array(
25
+ 'max' => '5',
26
+ );
27
+ }
28
+
29
+ /**
30
+ * @param string $name
31
+ */
32
+ public function show_on_form_builder( $name = '' ) {
33
+ $size = FrmField::get_option( $this->field, 'size' );
34
+ $size_html = $size ? ' style="width:' . esc_attr( $size . ( is_numeric( $size ) ? 'px' : '' ) ) . '";' : '';
35
+
36
+ $max = FrmField::get_option( $this->field, 'max' );
37
+ $default_value = FrmAppHelper::esc_textarea( force_balance_tags( $this->get_field_column('default_value') ) );
38
+
39
+ echo '<textarea name="' . esc_attr( $this->html_name( $name ) ) . '" ' .
40
+ $size_html . ' rows="' . esc_attr( $max ) . '" ' .
41
+ 'id="' . esc_attr( $this->html_id() ) . '" class="dyn_default_value">' .
42
+ $default_value .
43
+ '</textarea>';
44
+ }
45
+
46
+ protected function prepare_display_value( $value, $atts ) {
47
+ FrmFieldsHelper::run_wpautop( $atts, $value );
48
+
49
+ return $value;
50
+ }
51
+
52
+ /**
53
+ * @param array $args
54
+ * @param array $shortcode_atts
55
+ *
56
+ * @return string
57
+ */
58
+ public function front_field_input( $args, $shortcode_atts ) {
59
+ $input_html = $this->get_field_input_html_hook( $this->field );
60
+ $this->add_aria_description( $args, $input_html );
61
+ $rows = ( $this->field['max'] ) ? 'rows="' . esc_attr( $this->field['max'] ) . '" ' : '';
62
+
63
+ return '<textarea name="' . esc_attr( $args['field_name'] ) . '" id="' . esc_attr( $args['html_id'] ) . '" ' .
64
+ $rows . $input_html . '>' .
65
+ FrmAppHelper::esc_textarea( $this->field['value'] ) .
66
+ '</textarea>';
67
+ }
68
+ }
classes/models/fields/FrmFieldType.php ADDED
@@ -0,0 +1,834 @@