| @@ -106,8 +106,9 @@ | ||
| 106 | 106 | // $manage_field_types['optgroups']['standard']['options'][] = 'Checkbox'; |
| 107 | 107 | // $manage_field_types['optgroups']['standard']['options'][] = 'Radio'; |
| 108 | 108 | $manage_field_types['optgroups']['standard']['options'][] = 'HTML'; |
| 109 | 109 | $manage_field_types['optgroups']['standard']['options'][] = 'Upload'; |
| 110 | + $manage_field_types['optgroups']['standard']['options'][] = 'International Telephone Input'; | |
| 110 | 111 | // $manage_field_types['optgroups']['standard']['options'][] = 'Avatar'; |
| 111 | 112 | |
| 112 | 113 | $manage_field_types['optgroups']['advanced']['options'][] = 'Phone'; |
| 113 | 114 | $manage_field_types['optgroups']['advanced']['options'][] = 'Select (Country)'; |
| @@ -113,8 +114,9 @@ | ||
| 113 | 114 | $manage_field_types['optgroups']['advanced']['options'][] = 'Select (Country)'; |
| 114 | 115 | $manage_field_types['optgroups']['advanced']['options'][] = 'Select (Timezone)'; |
| 115 | 116 | $manage_field_types['optgroups']['advanced']['options'][] = 'Select (Currency)'; |
| 116 | 117 | $manage_field_types['optgroups']['advanced']['options'][] = 'Select (CPT)'; |
| 118 | + $manage_field_types['optgroups']['advanced']['options'][] = 'Select (Taxonomy)'; | |
| 117 | 119 | $manage_field_types['optgroups']['advanced']['options'][] = 'Checkbox (Terms and Conditions)'; |
| 118 | 120 | $manage_field_types['optgroups']['advanced']['options'][] = 'Datepicker'; |
| 119 | 121 | $manage_field_types['optgroups']['advanced']['options'][] = 'Timepicker'; |
| 120 | 122 | $manage_field_types['optgroups']['advanced']['options'][] = 'Colorpicker'; |
| @@ -119,8 +121,9 @@ | ||
| 119 | 121 | $manage_field_types['optgroups']['advanced']['options'][] = 'Timepicker'; |
| 120 | 122 | $manage_field_types['optgroups']['advanced']['options'][] = 'Colorpicker'; |
| 121 | 123 | $manage_field_types['optgroups']['advanced']['options'][] = 'Validation'; |
| 122 | 124 | $manage_field_types['optgroups']['advanced']['options'][] = 'Map'; |
| 125 | + $manage_field_types['optgroups']['advanced']['options'][] = 'Additional Map'; | |
| 123 | 126 | |
| 124 | 127 | $manage_field_types['optgroups']['other']['options'][] = 'Email'; |
| 125 | 128 | $manage_field_types['optgroups']['other']['options'][] = 'URL'; |
| 126 | 129 | |
| @@ -132,10 +135,15 @@ | ||
| 132 | 135 | } |
| 133 | 136 | |
| 134 | 137 | $manage_field_types['optgroups']['other']['options'][] = 'Email Confirmation'; |
| 135 | 138 | |
| 136 | - /* added recaptcha and user role field since version 2.6.2 */ | |
| 139 | + /* added recaptcha field since version 2.6.2 */ | |
| 137 | 140 | $manage_field_types['optgroups']['advanced']['options'][] = 'reCAPTCHA'; |
| 141 | + | |
| 142 | + /* added turnstile field since version 3.15. */ | |
| 143 | + $manage_field_types['optgroups']['advanced']['options'][] = 'Turnstile'; | |
| 144 | + | |
| 145 | + /* added user role field since version 2.6.2 */ | |
| 138 | 146 | $manage_field_types['optgroups']['advanced']['options'][] = 'Select (User Role)'; |
| 139 | 147 | |
| 140 | 148 | |
| 141 | 149 | $manage_field_types['optgroups']['other']['options'] = apply_filters( 'wppb_manage_fields_types', $manage_field_types['optgroups']['other']['options'] ); |
| @@ -150,8 +158,9 @@ | ||
| 150 | 158 | $manage_field_types['optgroups']['standard']['options'][] = array( 'field_name' => 'WYSIWYG', 'disabled' => true ); |
| 151 | 159 | $manage_field_types['optgroups']['standard']['options'][] = array( 'field_name' => 'Select (Multiple)', 'disabled' => true ); |
| 152 | 160 | $manage_field_types['optgroups']['standard']['options'][] = array( 'field_name' => 'HTML', 'disabled' => true ); |
| 153 | 161 | $manage_field_types['optgroups']['standard']['options'][] = array( 'field_name' => 'Upload', 'disabled' => true ); |
| 162 | + $manage_field_types['optgroups']['standard']['options'][] = array( 'field_name' => 'International Telephone Input', 'disabled' => true ); | |
| 154 | 163 | |
| 155 | 164 | $manage_field_types['optgroups']['advanced']['options'][] = array( 'field_name' => 'Phone', 'disabled' => true ); |
| 156 | 165 | $manage_field_types['optgroups']['advanced']['options'][] = array( 'field_name' => 'Select (Country)', 'disabled' => true ); |
| 157 | 166 | $manage_field_types['optgroups']['advanced']['options'][] = array( 'field_name' => 'Select (Timezone)', 'disabled' => true ); |
| @@ -156,8 +165,9 @@ | ||
| 156 | 165 | $manage_field_types['optgroups']['advanced']['options'][] = array( 'field_name' => 'Select (Country)', 'disabled' => true ); |
| 157 | 166 | $manage_field_types['optgroups']['advanced']['options'][] = array( 'field_name' => 'Select (Timezone)', 'disabled' => true ); |
| 158 | 167 | $manage_field_types['optgroups']['advanced']['options'][] = array( 'field_name' => 'Select (Currency)', 'disabled' => true ); |
| 159 | 168 | $manage_field_types['optgroups']['advanced']['options'][] = array( 'field_name' => 'Select (CPT)', 'disabled' => true ); |
| 169 | + $manage_field_types['optgroups']['advanced']['options'][] = array( 'field_name' => 'Select (Taxonomy)', 'disabled' => true ); | |
| 160 | 170 | $manage_field_types['optgroups']['advanced']['options'][] = array( 'field_name' => 'Checkbox (Terms and Conditions)', 'disabled' => true ); |
| 161 | 171 | $manage_field_types['optgroups']['advanced']['options'][] = array( 'field_name' => 'Datepicker', 'disabled' => true ); |
| 162 | 172 | $manage_field_types['optgroups']['advanced']['options'][] = array( 'field_name' => 'Timepicker', 'disabled' => true ); |
| 163 | 173 | $manage_field_types['optgroups']['advanced']['options'][] = array( 'field_name' => 'Colorpicker', 'disabled' => true ); |
| @@ -162,8 +172,9 @@ | ||
| 162 | 172 | $manage_field_types['optgroups']['advanced']['options'][] = array( 'field_name' => 'Timepicker', 'disabled' => true ); |
| 163 | 173 | $manage_field_types['optgroups']['advanced']['options'][] = array( 'field_name' => 'Colorpicker', 'disabled' => true ); |
| 164 | 174 | $manage_field_types['optgroups']['advanced']['options'][] = array( 'field_name' => 'Validation', 'disabled' => true ); |
| 165 | 175 | $manage_field_types['optgroups']['advanced']['options'][] = array( 'field_name' => 'Map', 'disabled' => true ); |
| 176 | + $manage_field_types['optgroups']['advanced']['options'][] = array( 'field_name' => 'Additional Map', 'disabled' => true ); | |
| 166 | 177 | |
| 167 | 178 | $manage_field_types['optgroups']['other']['options'][] = array( 'field_name' => 'WooCommerce Customer Billing Address', 'disabled' => true ); |
| 168 | 179 | $manage_field_types['optgroups']['other']['options'][] = array( 'field_name' => 'WooCommerce Customer Shipping Address', 'disabled' => true ); |
| 169 | 180 | $manage_field_types['optgroups']['other']['options'][] = array( 'field_name' => 'MailChimp Subscribe', 'disabled' => true ); |
| @@ -179,9 +190,9 @@ | ||
| 179 | 190 | |
| 180 | 191 | // Free to Pro call to action on Manage Fields page |
| 181 | 192 | $field_description = __('Choose one of the supported field types','profile-builder'); |
| 182 | 193 | if( PROFILE_BUILDER == 'Profile Builder Free' ) { |
| 183 | - $field_description .= sprintf( __('. Extra Field Types are available in <a href="%s">Basic or PRO versions</a>.' , 'profile-builder'), esc_url( 'https://www.cozmoslabs.com/wordpress-profile-builder/?utm_source=wpbackend&utm_medium=clientsite&utm_content=manage-fields-link&utm_campaign=PBFree' ) ); | |
| 194 | + $field_description .= sprintf( __('. Extra Field Types are available in <a href="%s">Basic or PRO versions</a>.' , 'profile-builder'), esc_url( 'https://www.cozmoslabs.com/wordpress-profile-builder/?utm_source=pb-form-fields&utm_medium=client-site&utm_campaign=pb-extra-fields#pricing' ) ); | |
| 184 | 195 | } |
| 185 | 196 | |
| 186 | 197 | //user roles |
| 187 | 198 | global $wp_roles; |
| @@ -208,11 +219,31 @@ | ||
| 208 | 219 | $default_currency_options[] = '%'. wppb_prepare_wck_labels( $currency_name ) .'%'.$iso_currency_code; |
| 209 | 220 | } |
| 210 | 221 | |
| 211 | 222 | //cpt select |
| 212 | - $post_types = get_post_types( array( 'public' => true ), 'names' ); | |
| 223 | + $post_types_objects = get_post_types( array( 'public' => true ), 'objects' ); | |
| 224 | + $post_types = array(); | |
| 213 | 225 | |
| 226 | + if ( !empty( $post_types_objects ) ) { | |
| 227 | + // Loop through the post types objects and extract the labels | |
| 228 | + foreach ( $post_types_objects as $types ) { | |
| 229 | + if ( isset( $types->label ) ) | |
| 230 | + array_push( $post_types, '%' . wppb_prepare_wck_labels( $types->label ) . '%' . $types->name ); | |
| 231 | + } | |
| 232 | + } | |
| 214 | 233 | |
| 234 | + //taxonomy select | |
| 235 | + $taxonomies_objects = get_taxonomies( array( 'public' => true ), 'objects' ); | |
| 236 | + $taxonomies = array(); | |
| 237 | + | |
| 238 | + if ( !empty( $taxonomies_objects ) ) { | |
| 239 | + // Loop through the taxonomies objects and extract the labels | |
| 240 | + foreach ( $taxonomies_objects as $taxonomy ) { | |
| 241 | + if ( isset( $taxonomy->label ) ) | |
| 242 | + array_push( $taxonomies, '%' . wppb_prepare_wck_labels( $taxonomy->label ) . '%' . $taxonomy->name ); | |
| 243 | + } | |
| 244 | + } | |
| 245 | + | |
| 215 | 246 | if( apply_filters( 'wppb_update_field_meta_key_in_db', false ) ) { |
| 216 | 247 | $meta_key_description = __( 'Use this in conjunction with WordPress functions to display the value in the page of your choosing<br/>Auto-completed but in some cases editable (in which case it must be unique)<br/>Changing this might take long in case of a very big user-count', 'profile-builder' ); |
| 217 | 248 | } |
| 218 | 249 | else{ |
| @@ -238,18 +269,25 @@ | ||
| 238 | 269 | array( 'type' => 'text', 'slug' => 'row-count', 'title' => __( 'Row Count', 'profile-builder' ), 'default' => 5, 'description' => __( "Specify the number of rows for a 'Textarea' field<br/>If not specified, defaults to 5", 'profile-builder' ) ), |
| 239 | 270 | array( 'type' => 'text', 'slug' => 'allowed-image-extensions', 'title' => __( 'Allowed Image Extensions', 'profile-builder' ), 'default' => '.*', 'description' => __( 'Specify the extension(s) you want to limit to upload<br/>Example: .ext1,.ext2,.ext3<br/>If not specified, defaults to: .jpg,.jpeg,.gif,.png (.*)', 'profile-builder' ) ), |
| 240 | 271 | array( 'type' => 'checkbox', 'slug' => 'simple-upload', 'title' => __( 'Use Simple Upload', 'profile-builder' ), 'options' => array( '%'.__('Yes','profile-builder').'%'.'yes' ), 'description' => __( 'Use a simple upload field instead of the WordPress upload', 'profile-builder' ) ), |
| 241 | 272 | array( 'type' => 'text', 'slug' => 'allowed-upload-extensions', 'title' => __( 'Allowed Upload Extensions', 'profile-builder' ), 'default' => '.*', 'description' => __( 'Specify the extension(s) you want to limit to upload<br/>Example: .ext1,.ext2,.ext3<br/>If not specified, defaults to all WordPress allowed file extensions (.*)', 'profile-builder' ) ), |
| 242 | - array( 'type' => 'text', 'slug' => 'avatar-size', 'title' => __( 'Avatar Size', 'profile-builder' ), 'default' => 100, 'description' => __( "Enter a value (between 20 and 200) for the size of the 'Avatar'<br/>If not specified, defaults to 100", 'profile-builder' ) ), | |
| 273 | + array( 'type' => 'text', 'slug' => 'avatar-size', 'title' => __( 'Avatar Size', 'profile-builder' ), 'default' => 100, 'description' => __( "Enter a value (between 20 and 800) for the size of the 'Avatar'<br/>If not specified, defaults to 100", 'profile-builder' ) ), | |
| 274 | + array( 'type' => 'text', 'slug' => 'max-file-size', 'title' => __( 'Maximum File Size (MB)', 'profile-builder' ), 'description' => __( 'Specify the maximum file size allowed for upload (in MB)<br/>If not specified, defaults to the server maximum upload size', 'profile-builder' ) ), | |
| 243 | 275 | array( 'type' => 'text', 'slug' => 'date-format', 'title' => __( 'Date-format', 'profile-builder' ), 'default' => 'mm/dd/yy', 'description' => __( 'Specify the format of the date when using Datepicker<br/>Valid options: mm/dd/yy, mm/yy/dd, dd/yy/mm, dd/mm/yy, yy/dd/mm, yy/mm/dd, mm-dd-yy, yy-mm-dd, D, dd M yy, D, d M y, DD, dd-M-y, D, d M yy, mm/yy, mm/dd, dd/mm, @<br/>If not specified, defaults to mm/dd/yy<br/>ATTENTION: if you plan to use this field for sorting, please make sure to use year first, then month, and day last.', 'profile-builder' ) ), |
| 244 | 276 | array( 'type' => 'textarea', 'slug' => 'terms-of-agreement', 'title' => __( 'Terms of Agreement', 'profile-builder' ), 'description' => __( 'Enter a detailed description of the terms of agreement for the user to read.<br/>Links can be inserted by using standard HTML syntax: <a href="custom_url">custom_text</a>', 'profile-builder' ) ), |
| 245 | 277 | array( 'type' => 'text', 'slug' => 'options', 'title' => __( 'Options', 'profile-builder' ), 'description' => __( "Enter a comma separated list of values<br/>This can be anything, as it is hidden from the user, but should not contain special characters or apostrophes", 'profile-builder' ) ), |
| 246 | 278 | array( 'type' => 'text', 'slug' => 'labels', 'title' => __( 'Labels', 'profile-builder' ), 'description' => __( "Enter a comma separated list of labels<br/>Visible for the user", 'profile-builder' ) ), |
| 247 | - array( 'type' => 'select', 'slug' => 'recaptcha-type', 'title' => __( 'reCAPTCHA Type', 'profile-builder' ), 'options' => array('%reCAPTCHA V2%v2', '%Invisible reCAPTCHA%invisible'), 'default' => 'v2', 'description' => __( 'Choose the <a href="https://developers.google.com/recaptcha/docs/versions" target="_blank">type of reCAPTCHA</a> you wish to add to this site.<br/>Please note that the Invisible reCAPTCHA is a type of reCAPTCHA v2.', 'profile-builder' ) ), | |
| 279 | + array( 'type' => 'select', 'slug' => 'recaptcha-type', 'title' => __( 'reCAPTCHA Type', 'profile-builder' ), 'options' => array('%reCAPTCHA V2 Checkbox%v2', '%reCAPTCHA V2 Invisible%invisible', '%reCAPTCHA V3%v3'), 'default' => 'v2', 'description' => __( 'Choose the <a href="https://developers.google.com/recaptcha/docs/versions" target="_blank">type of reCAPTCHA</a> you wish to add to this site.<br/>Please note that the Invisible reCAPTCHA is a type of reCAPTCHA v2.', 'profile-builder' ) ), | |
| 248 | 280 | array( 'type' => 'text', 'slug' => 'public-key', 'title' => __( 'Site Key', 'profile-builder' ), 'description' => __( 'The site key from Google, <a href="https://www.google.com/recaptcha/admin/create" target="_blank">https://www.google.com/recaptcha/admin/create</a>', 'profile-builder' ) ), |
| 249 | 281 | array( 'type' => 'text', 'slug' => 'private-key', 'title' => __( 'Secret Key', 'profile-builder' ), 'description' => __( 'The secret key from Google, <a href="https://www.google.com/recaptcha/admin/create" target="_blank">https://www.google.com/recaptcha/admin/create</a>', 'profile-builder' ) ), |
| 282 | + array( 'type' => 'text', 'slug' => 'score-threshold', 'title' => __( 'Score Threshold', 'profile-builder' ), 'default' => 0.5, 'description' => __( 'The required score threshold: 1.0 is very likely a good interaction, 0.0 is very likely a bot<br/>If not specified, defaults to 0.5', 'profile-builder' ) ), | |
| 250 | 283 | array( 'type' => 'checkbox', 'slug' => 'captcha-pb-forms', 'title' => __( 'Display on PB forms', 'profile-builder' ), 'options' => array( '%'.__('PB Login','profile-builder').'%'.'pb_login', '%'.__('PB Register','profile-builder').'%'.'pb_register', '%'.__('PB Recover Password','profile-builder').'%'.'pb_recover_password' ), 'default' => 'pb_register', 'description' => __( "Select on which Profile Builder forms to display reCAPTCHA", 'profile-builder' ) ), |
| 251 | - array( 'type' => 'checkbox', 'slug' => 'captcha-wp-forms', 'title' => __( 'Display on default WP forms', 'profile-builder' ), 'options' => array( '%'.__('Default WP Login', 'profile-builder').'%'.'default_wp_login', '%'.__('Default WP Register', 'profile-builder').'%'.'default_wp_register', '%'.__('Default WP Recover Password', 'profile-builder').'%'.'default_wp_recover_password'), 'default' => 'default_wp_register', 'description' => __( "Select on which default WP forms to display reCAPTCHA", 'profile-builder' ) ), | |
| 284 | + array( 'type' => 'checkbox', 'slug' => 'captcha-wp-forms', 'title' => __( 'Display on default WP forms', 'profile-builder' ), 'options' => array( '%'.__('Default WP Login', 'profile-builder').'%'.'default_wp_login', '%'.__('Default WP Register', 'profile-builder').'%'.'default_wp_register', '%'.__('Default WP Recover Password', 'profile-builder').'%'.'default_wp_recover_password', '%'.__('Default WP Comments', 'profile-builder').'%'.'default_wp_comments'), 'default' => 'default_wp_register', 'description' => __( "Select on which default WP forms to display reCAPTCHA", 'profile-builder' ) ), | |
| 285 | + array( 'type' => 'select', 'slug' => 'theme', 'title' => __( 'Turnstile Theme', 'profile-builder' ), 'options' => array('%Auto%auto', '%Light%light', '%Dark%dark'), 'default' => 'auto', 'description' => __( 'Choose the theme for the Turnstile widget. The Auto option conforms to the user system preferences.', 'profile-builder' ) ), | |
| 286 | + array( 'type' => 'text', 'slug' => 'turnstile-site-key', 'title' => __( 'Site Key', 'profile-builder' ), 'description' => __( 'The site key from <a href="https://dash.cloudflare.com/?to=/:account/turnstile" target="_blank">Cloudflare</a>', 'profile-builder' ) ), | |
| 287 | + array( 'type' => 'text', 'slug' => 'turnstile-secret-key', 'title' => __( 'Secret Key', 'profile-builder' ), 'description' => __( 'The secret key from <a href="https://dash.cloudflare.com/?to=/:account/turnstile" target="_blank">Cloudflare</a>', 'profile-builder' ) ), | |
| 288 | + array( 'type' => 'checkbox', 'slug' => 'turnstile-pb-forms', 'title' => __( 'Display on PB forms', 'profile-builder' ), 'options' => array( '%'.__('PB Login','profile-builder').'%'.'pb_login', '%'.__('PB Register','profile-builder').'%'.'pb_register', '%'.__('PB Recover Password','profile-builder').'%'.'pb_recover_password' ), 'default' => 'pb_register', 'description' => __( "Select on which Profile Builder forms to display Turnstile", 'profile-builder' ) ), | |
| 289 | + array( 'type' => 'checkbox', 'slug' => 'turnstile-wp-forms', 'title' => __( 'Display on default WP forms', 'profile-builder' ), 'options' => array( '%'.__('Default WP Login', 'profile-builder').'%'.'default_wp_login', '%'.__('Default WP Register', 'profile-builder').'%'.'default_wp_register', '%'.__('Default WP Recover Password', 'profile-builder').'%'.'default_wp_recover_password', '%'.__('Default WP Comments', 'profile-builder').'%'.'default_wp_comments'), 'default' => 'default_wp_register', 'description' => __( "Select on which default WP forms to display Turnstile", 'profile-builder' ) ), | |
| 252 | 290 | array( 'type' => 'checkbox', 'slug' => 'user-roles', 'title' => __( 'User Roles', 'profile-builder' ), 'options' => $user_roles, 'description' => __( "Select which user roles to show to the user ( drag and drop to re-order )", 'profile-builder' ) ), |
| 253 | 291 | array( 'type' => 'checkbox', 'slug' => 'user-roles-on-edit-profile', 'title' => __( 'Display on Edit Profile', 'profile-builder' ), 'options' => array('%Yes%yes'), 'description' => __( "Check if you want the select user role field to appear on Edit Profile forms", 'profile-builder' ) ), |
| 254 | 292 | array( 'type' => 'text', 'slug' => 'user-roles-sort-order', 'title' => __( 'User Roles Order', 'profile-builder' ), 'description' => __( "Save the user role order from the user roles checkboxes", 'profile-builder' ) ), |
| 255 | 293 | array( 'type' => 'text', 'slug' => 'default-value', 'title' => __( 'Default Value', 'profile-builder' ), 'description' => __( "Default value of the field", 'profile-builder' ) ), |
| @@ -259,8 +297,9 @@ | ||
| 259 | 297 | array( 'type' => 'select', 'slug' => 'default-option-timezone', 'title' => __( 'Default Option', 'profile-builder' ), 'options' => wppb_timezone_select_options( 'back_end' ), 'description' => __( "Default option of the field", 'profile-builder' ) ), |
| 260 | 298 | array( 'type' => 'select', 'slug' => 'default-option-currency', 'title' => __( 'Default Option', 'profile-builder' ), 'options' => ( isset( $default_currency_options ) ) ? $default_currency_options : '', 'description' => __( "Default option of the field", 'profile-builder' ) ), |
| 261 | 299 | array( 'type' => 'select', 'slug' => 'show-currency-symbol', 'title' => __( 'Show Currency Symbol', 'profile-builder' ), 'options' => array( 'No', 'Yes' ), 'default' => 'No', 'description' => __( 'Whether the currency symbol should be displayed after the currency name in the select option.', 'profile-builder' ) ), |
| 262 | 300 | array( 'type' => 'select', 'slug' => 'cpt', 'title' => __( 'Show Post Type', 'profile-builder' ), 'options' => $post_types, 'default' => 'post', 'description' => __( 'Posts from what post type will be displayed in the select.', 'profile-builder' ) ), |
| 301 | + array( 'type' => 'select', 'slug' => 'taxonomy', 'title' => __( 'Show Taxonomy Term', 'profile-builder' ), 'options' => $taxonomies, 'default' => 'category', 'description' => __( 'Terms from taxonomies', 'profile-builder' ) ), | |
| 263 | 302 | array( 'type' => 'text', 'slug' => 'validation-possible-values', 'title' => __( 'Allowable Values', 'profile-builder' ), 'description' => __( "Enter a comma separated list of possible values. Upon registration if the value provided by the user does not match one of these values, the user will not be registered.", 'profile-builder' ) ), |
| 264 | 303 | array( 'type' => 'text', 'slug' => 'custom-error-message', 'title' => __( 'Error Message', 'profile-builder' ), 'description' => __( "Set a custom error message that will be displayed to the user.", 'profile-builder' ) ), |
| 265 | 304 | array( 'type' => 'select', 'slug' => 'time-format', 'title' => __( 'Time Format', 'profile-builder' ), 'options' => array( '%12 Hours%12', '%24 Hours%24' ), 'description' => __( 'Specify the time format.', 'profile-builder' ) ), |
| 266 | 305 | array( 'type' => 'text', 'slug' => 'map-api-key', 'title' => __( 'Google Maps API Key', 'profile-builder' ), 'description' => __( 'Enter your Google Maps API key ( <a href="https://console.developers.google.com/flows/enableapi?apiid=maps_backend" target="_blank">Get your API key</a> ). If more than one map fields are added to a form the API key from the first map displayed will be used.', 'profile-builder' ) ), |
| @@ -293,13 +332,19 @@ | ||
| 293 | 332 | array( 'type' => 'text', 'slug' => 'phone-format', 'title' => __( 'Phone Format', 'profile-builder' ), 'default' => '(###) ###-####', 'description' => __( "You can use: # for numbers, parentheses ( ), - sign, + sign, dot . and spaces.", 'profile-builder' ) .'<br>'. __( "Eg. (###) ###-####", 'profile-builder' ) .'<br>'. __( "Empty field won't check for correct phone number.", 'profile-builder' ) ), |
| 294 | 333 | array( 'type' => 'select', 'slug' => 'heading-tag', 'title' => __( 'Heading Tag', 'profile-builder' ), 'options' => array( '%h1 - biggest size%h1', 'h2', 'h3', 'h4', 'h5', '%h6 - smallest size%h6' ), 'default' => 'h4', 'description' => __( 'Change heading field size on front-end forms', 'profile-builder' ) ), |
| 295 | 334 | array( 'type' => 'text', 'slug' => 'min-number-value', 'title' => __( 'Min Number Value', 'profile-builder' ), 'description' => __( "Min allowed number value (0 to allow only positive numbers)", 'profile-builder' ) .'<br>'. __( "Leave it empty for no min value", 'profile-builder' ) ), |
| 296 | 335 | array( 'type' => 'text', 'slug' => 'max-number-value', 'title' => __( 'Max Number Value', 'profile-builder' ), 'description' => __( "Max allowed number value (0 to allow only negative numbers)", 'profile-builder' ) .'<br>'. __( "Leave it empty for no max value", 'profile-builder' ) ), |
| 336 | + array( 'type' => 'checkbox', 'slug' => 'ask-current-password', 'title' => __( 'Ask for Current Password', 'profile-builder' ), 'options' => array( '%' . __( 'Yes', 'profile-builder' ) . '%yes' ), 'description' => __( 'On Edit Profile forms, require users to enter their current password before changing it. This applies only when users change their own password.', 'profile-builder' ) ), | |
| 297 | 337 | array( 'type' => 'text', 'slug' => 'number-step-value', 'title' => __( 'Number Step Value', 'profile-builder' ), 'description' => __( "Step value 1 to allow only integers, 0.1 to allow integers and numbers with 1 decimal", 'profile-builder' ) .'<br>'. __( "To allow multiple decimals use for eg. 0.01 (for 2 deciamls) and so on", 'profile-builder' ) .'<br>'. __( "You can also use step value to specify the legal number intervals (eg. step value 2 will allow only -4, -2, 0, 2 and so on)", 'profile-builder' ) .'<br>'. __( "Leave it empty for no restriction", 'profile-builder' ) ), |
| 298 | 338 | array( 'type' => 'select', 'slug' => 'required', 'title' => __( 'Required', 'profile-builder' ), 'options' => array( 'No', 'Yes' ), 'default' => 'No', 'description' => __( 'Whether the field is required or not', 'profile-builder' ) ), |
| 299 | 339 | array( 'type' => 'select', 'slug' => 'overwrite-existing', 'title' => __( 'Overwrite Existing', 'profile-builder' ), 'options' => array( 'No', 'Yes' ), 'default' => 'No', 'description' => __( "Selecting 'Yes' will add the field to the list, but will overwrite any other field in the database that has the same meta-name<br/>Use this at your own risk", 'profile-builder' ) ), |
| 340 | + array( 'type' => 'text', 'slug' => 'initial-country', 'title' => __( 'Initial Country', 'profile-builder' ), 'description' => __( "Set the initial country for the phone field. Use 'auto' to detect it automatically by IP, or enter one ISO 3166-1 alpha-2 country code (e.g. ro, jp, us).", 'profile-builder' ), 'default' => 'auto' ), | |
| 341 | + array( 'type' => 'text', 'slug' => 'preferred-countries', 'title' => __( 'Preferred Countries', 'profile-builder' ), 'description' => __( "Set preferred countries using ISO 3166-1 alpha-2 codes (e.g. ro, jp, us), separated by commas.", 'profile-builder' ), 'default' => '' ), | |
| 342 | + array( 'type' => 'text', 'slug' => 'excluded-countries', 'title' => __( 'Excluded Countries', 'profile-builder' ), 'description' => __( "Exclude countries using ISO 3166-1 alpha-2 codes (e.g. af, ru, us), separated by commas.", 'profile-builder' ), 'default' => '' ), | |
| 343 | + array( 'type' => 'checkbox', 'slug' => 'national-mode', 'title' => __( 'National Mode', 'profile-builder' ), 'options' => array( '%'.__('Yes','profile-builder').'%'.'yes' ), 'description' => __( "Enable National Mode to enter numbers in local format (without country prefix). Disable it to use International Mode (with country prefix).", 'profile-builder' ) ), | |
| 344 | + array( 'type' => 'checkbox', 'slug' => 'hide-flags', 'title' => __( 'Hide Flags', 'profile-builder' ), 'options' => array( '%'.__('Yes','profile-builder').'%'.'yes' ), 'description' => __( "Enable to hide country flags in the phone field.", 'profile-builder' ) ), | |
| 300 | 345 | |
| 301 | - // Added the new option for the map field type, that allows to customize the POIs load type. | |
| 346 | + // Added the new option for the map field type, that allows to customize the POIs load type. | |
| 302 | 347 | array( |
| 303 | 348 | 'type' => 'select', |
| 304 | 349 | 'slug' => 'map-pins-load-type', |
| 305 | 350 | 'title' => __( 'POIs Load Type', 'profile-builder' ), |
| @@ -353,19 +398,25 @@ | ||
| 353 | 398 | |
| 354 | 399 | /* this is redundant but it should have a very low impact and for comfort we leave it here as well */ |
| 355 | 400 | wppb_prepopulate_fields(); |
| 356 | 401 | |
| 357 | - // create the info side meta-box | |
| 358 | - $args = array( | |
| 359 | - 'metabox_id' => 'manage-fields-info', | |
| 360 | - 'metabox_title' => __( 'Registration & Edit Profile Forms', 'profile-builder' ), | |
| 361 | - 'post_type' => 'manage-fields', | |
| 362 | - 'meta_name' => 'wppb_manage_fields_info', | |
| 363 | - 'meta_array' => '', | |
| 364 | - 'context' => 'option', | |
| 365 | - 'mb_context' => 'normal' | |
| 366 | - ); | |
| 367 | - new Wordpress_Creation_Kit_PB( $args ); | |
| 402 | + | |
| 403 | + // skip this meta-box for the Repeater Field -> Edit Field Group view | |
| 404 | + if ( !isset( $_GET['wppb_rpf_repeater_meta_name'] ) ) { | |
| 405 | + | |
| 406 | + // create the info side meta-box | |
| 407 | + $args = array( | |
| 408 | + 'metabox_id' => 'manage-fields-info', | |
| 409 | + 'metabox_title' => __( 'Form Shortcodes', 'profile-builder' ), | |
| 410 | + 'post_type' => 'manage-fields', | |
| 411 | + 'meta_name' => 'wppb_manage_fields_info', | |
| 412 | + 'meta_array' => '', | |
| 413 | + 'context' => 'option', | |
| 414 | + 'mb_context' => 'side' | |
| 415 | + ); | |
| 416 | + new Wordpress_Creation_Kit_PB( $args ); | |
| 417 | + | |
| 418 | + } | |
| 368 | 419 | } |
| 369 | 420 | add_action( 'admin_init', 'wppb_populate_manage_fields', 1 ); |
| 370 | 421 | |
| 371 | 422 | /** |
| @@ -710,12 +761,30 @@ | ||
| 710 | 761 | 'ZW' => __( 'Zimbabwe', 'profile-builder' ), |
| 711 | 762 | ) |
| 712 | 763 | ); |
| 713 | 764 | |
| 714 | - return $country_array; | |
| 765 | + return wppb_translate_countries( $country_array ); | |
| 715 | 766 | } |
| 716 | 767 | |
| 768 | +/** | |
| 769 | + * Helper function to translate country names with WPML | |
| 770 | + * Registers strings in WPML String Translation and returns translated value | |
| 771 | + */ | |
| 772 | +function wppb_translate_countries( $countries ) { | |
| 717 | 773 | |
| 774 | + if ( !function_exists( 'icl_register_string' ) || !function_exists( 'icl_t' ) ) { | |
| 775 | + return $countries; | |
| 776 | + } | |
| 777 | + | |
| 778 | + foreach( $countries as $index => $country ){ | |
| 779 | + $prefix = 'country_' . $country; | |
| 780 | + icl_register_string( 'profile-builder', $prefix, $country ); | |
| 781 | + $countries[$index] = icl_t( 'profile-builder', $prefix, $country ); | |
| 782 | + } | |
| 783 | + | |
| 784 | + return $countries; | |
| 785 | +} | |
| 786 | + | |
| 718 | 787 | /** |
| 719 | 788 | * Function that returns an array with timezone options |
| 720 | 789 | * |
| 721 | 790 | * @since v.2.0 |
| @@ -1132,8 +1201,9 @@ | ||
| 1132 | 1201 | |
| 1133 | 1202 | if( !$only_default_fields ){ |
| 1134 | 1203 | $unique_field_list[] = 'Avatar'; |
| 1135 | 1204 | $unique_field_list[] = 'reCAPTCHA'; |
| 1205 | + $unique_field_list[] = 'Turnstile'; | |
| 1136 | 1206 | $unique_field_list[] = 'Select (User Role)'; |
| 1137 | 1207 | $unique_field_list[] = 'Map'; |
| 1138 | 1208 | } |
| 1139 | 1209 | |
| @@ -1173,8 +1243,13 @@ | ||
| 1173 | 1243 | if ( ( in_array ( $posted_values['field'], $unique_field_list ) ) && ( $posted_values['field'] == $field['field'] ) && ( $posted_values['id'] != $field['id'] ) ){ |
| 1174 | 1244 | $message .= __( "Please choose a different field type as this one already exists in your form (must be unique)\n", 'profile-builder' ); |
| 1175 | 1245 | break; |
| 1176 | 1246 | } |
| 1247 | + | |
| 1248 | + if ( ( $posted_values['field'] == 'reCAPTCHA' && $field['field'] == 'Turnstile' ) || ( $posted_values['field'] == 'Turnstile' && $field['field'] == 'reCAPTCHA' ) ){ | |
| 1249 | + $message .= __( "You cannot have both a reCAPTCHA and a Turnstile field! Please remove the other existing field first.\n", 'profile-builder' ); | |
| 1250 | + break; | |
| 1251 | + } | |
| 1177 | 1252 | } |
| 1178 | 1253 | } |
| 1179 | 1254 | // END check if the unique fields are only added once |
| 1180 | 1255 | |
| @@ -1180,10 +1255,10 @@ | ||
| 1180 | 1255 | |
| 1181 | 1256 | // check for avatar size |
| 1182 | 1257 | if ( $posted_values['field'] == 'Avatar' ){ |
| 1183 | 1258 | if ( is_numeric( $posted_values['avatar-size'] ) ){ |
| 1184 | - if ( ( $posted_values['avatar-size'] < 20 ) || ( $posted_values['avatar-size'] > 200 ) ) | |
| 1185 | - $message .= __( "The entered avatar size is not between 20 and 200\n", 'profile-builder' ); | |
| 1259 | + if ( ( $posted_values['avatar-size'] < 20 ) || ( $posted_values['avatar-size'] > 800 ) ) | |
| 1260 | + $message .= __( "The entered avatar size is not between 20 and 800\n", 'profile-builder' ); | |
| 1186 | 1261 | |
| 1187 | 1262 | }else |
| 1188 | 1263 | $message .= __( "The entered avatar size is not numerical\n", 'profile-builder' ); |
| 1189 | 1264 | |
| @@ -1189,8 +1264,17 @@ | ||
| 1189 | 1264 | |
| 1190 | 1265 | } |
| 1191 | 1266 | // END check for avatar size |
| 1192 | 1267 | |
| 1268 | + // check for max file size | |
| 1269 | + if ( in_array( $posted_values['field'], array( 'Avatar', 'Upload' ) ) ){ | |
| 1270 | + if ( isset( $posted_values['max-file-size'] ) && $posted_values['max-file-size'] !== '' ){ | |
| 1271 | + if ( !is_numeric( $posted_values['max-file-size'] ) || floatval( $posted_values['max-file-size'] ) <= 0 ) | |
| 1272 | + $message .= __( "The entered maximum file size is not a valid positive number\n", 'profile-builder' ); | |
| 1273 | + } | |
| 1274 | + } | |
| 1275 | + // END check for max file size | |
| 1276 | + | |
| 1193 | 1277 | // check for correct row value |
| 1194 | 1278 | if ( ( $posted_values['field'] == 'Default - Biographical Info' ) || ( $posted_values['field'] == 'Textarea' ) ){ |
| 1195 | 1279 | if ( !is_numeric( $posted_values['row-count'] ) ) |
| 1196 | 1280 | $message .= __( "The entered row number is not numerical\n", 'profile-builder' ); |
| @@ -1201,14 +1285,20 @@ | ||
| 1201 | 1285 | // END check for correct row value |
| 1202 | 1286 | |
| 1203 | 1287 | |
| 1204 | 1288 | // check for the public and private keys |
| 1205 | - if ( $posted_values['field'] == 'reCAPTCHA'){ | |
| 1289 | + if ( $posted_values['field'] == 'reCAPTCHA' ){ | |
| 1206 | 1290 | if ( trim( $posted_values['public-key'] ) == '' ) |
| 1207 | - $message .= __( "You must enter the site key\n", 'profile-builder' ); | |
| 1291 | + $message .= __( "You must enter the site key!\n", 'profile-builder' ); | |
| 1208 | 1292 | if ( trim( $posted_values['private-key'] ) == '' ) |
| 1209 | - $message .= __( "You must enter the secret key\n", 'profile-builder' ); | |
| 1293 | + $message .= __( "You must enter the secret key!\n", 'profile-builder' ); | |
| 1210 | 1294 | } |
| 1295 | + if ( $posted_values['field'] == 'Turnstile' ){ | |
| 1296 | + if ( trim( $posted_values['turnstile-site-key'] ) == '' ) | |
| 1297 | + $message .= __( "You must enter the site key!\n", 'profile-builder' ); | |
| 1298 | + if ( trim( $posted_values['turnstile-secret-key'] ) == '' ) | |
| 1299 | + $message .= __( "You must enter the secret key!\n", 'profile-builder' ); | |
| 1300 | + } | |
| 1211 | 1301 | // END check for the public and private keys |
| 1212 | 1302 | |
| 1213 | 1303 | // check for the correct the date-format |
| 1214 | 1304 | if ( $posted_values['field'] == 'Datepicker' ){ |
| @@ -1234,85 +1324,99 @@ | ||
| 1234 | 1324 | |
| 1235 | 1325 | } |
| 1236 | 1326 | // END check for the correct the date-format |
| 1237 | 1327 | |
| 1238 | - //check for empty meta-name and duplicate meta-name | |
| 1239 | - if ( $posted_values['overwrite-existing'] == 'No' ){ | |
| 1240 | - $skip_check_for_fields = wppb_return_unique_field_list(true); | |
| 1241 | - $skip_check_for_fields = apply_filters ( 'wppb_skip_check_for_fields', $skip_check_for_fields ); | |
| 1242 | 1328 | |
| 1243 | - if ( !in_array( trim( $posted_values['field'] ), $skip_check_for_fields ) ){ | |
| 1244 | - $reserved_meta_name_list = wppb_get_reserved_meta_name_list( $all_fields, $posted_values ); | |
| 1329 | + $skip_check_for_fields = wppb_return_unique_field_list(true); | |
| 1330 | + $skip_check_for_fields = apply_filters ( 'wppb_skip_check_for_fields', $skip_check_for_fields ); | |
| 1245 | 1331 | |
| 1246 | - //check to see if meta-name is empty | |
| 1247 | - $skip_empty_check_for_fields = array( 'Heading', 'Select (User Role)', 'reCAPTCHA', 'HTML', 'GDPR Delete Button' ); | |
| 1332 | + // check for empty, reserved and/or duplicate meta-name | |
| 1333 | + if ( !in_array( trim( $posted_values['field'] ), $skip_check_for_fields ) ) { | |
| 1334 | + $reserved_meta_name_list = wppb_get_reserved_meta_name_list( $all_fields, $posted_values ); | |
| 1248 | 1335 | |
| 1249 | - if( !in_array( $posted_values['field'], $skip_empty_check_for_fields ) && empty( $posted_values['meta-name'] ) ) { | |
| 1250 | - $message .= __( "The meta-name cannot be empty\n", 'profile-builder' ); | |
| 1336 | + //check to see if meta-name is empty | |
| 1337 | + $skip_empty_check_for_fields = array( 'Heading', 'Select (User Role)', 'reCAPTCHA', 'Turnstile', 'HTML', 'GDPR Delete Button' ); | |
| 1338 | + | |
| 1339 | + if( !in_array( $posted_values['field'], $skip_empty_check_for_fields ) && empty( $posted_values['meta-name'] ) ) { | |
| 1340 | + $message .= __( "The meta-name cannot be empty\n", 'profile-builder' ); | |
| 1341 | + } | |
| 1342 | + | |
| 1343 | + //check if the meta-name starts or ends with a space | |
| 1344 | + if ( strpos( $posted_values['meta-name'], " " ) === 0 ) { | |
| 1345 | + $message .= __( "The meta-name cannot begin with a space\n", 'profile-builder' ); | |
| 1346 | + } | |
| 1347 | + if ( strpos( $posted_values['meta-name'], " " ) === strlen( $posted_values['meta-name'] ) - 1 ) { | |
| 1348 | + $message .= __( "The meta-name cannot end with a space\n", 'profile-builder' ); | |
| 1349 | + } | |
| 1350 | + | |
| 1351 | + // meta names that are reserved and cannot be used as part of other meta names | |
| 1352 | + $reserved_meta_name_list_strict = apply_filters( 'wppb_unique_meta_name_list_strict', array( 'map' ) ); | |
| 1353 | + // skip meta name check for these fields | |
| 1354 | + $skip_unique_meta_name_list_check = apply_filters( 'wppb_skip_unique_meta_name_list_check', array( 'Map', 'Honeypot' ) ); | |
| 1355 | + | |
| 1356 | + // if the desired meta name is in the restricted list or if one of the meta names in the strictly | |
| 1357 | + // restricted list is part of it display an error message | |
| 1358 | + $is_reserved_meta_name = false; | |
| 1359 | + $trimmed_meta_name = trim( $posted_values['meta-name'] ); | |
| 1360 | + | |
| 1361 | + if ( !in_array( $posted_values['field'], $skip_unique_meta_name_list_check ) ) { | |
| 1362 | + foreach ( $reserved_meta_name_list as $reserved_meta_name ) { | |
| 1363 | + | |
| 1364 | + if ( in_array( $trimmed_meta_name, $reserved_meta_name_list ) || ( strpos( $trimmed_meta_name, $reserved_meta_name ) !== false && in_array( $reserved_meta_name, $reserved_meta_name_list_strict ) ) ) { | |
| 1365 | + $is_reserved_meta_name = true; | |
| 1366 | + break; | |
| 1367 | + } | |
| 1368 | + | |
| 1251 | 1369 | } |
| 1370 | + } | |
| 1252 | 1371 | |
| 1253 | - //check if the meta-name starts or ends with a space | |
| 1254 | - if ( strpos( $posted_values['meta-name'], " " ) === 0 ) { | |
| 1255 | - $message .= __( "The meta-name cannot begin with a space\n", 'profile-builder' ); | |
| 1256 | - } | |
| 1257 | - if ( strpos( $posted_values['meta-name'], " " ) === strlen( $posted_values['meta-name'] ) - 1 ) { | |
| 1258 | - $message .= __( "The meta-name cannot end with a space\n", 'profile-builder' ); | |
| 1259 | - } | |
| 1372 | + if ( $is_reserved_meta_name ) { | |
| 1373 | + $message .= __( "That meta-name can't be used, please choose another\n", 'profile-builder' ); | |
| 1374 | + } | |
| 1375 | + elseif ( $posted_values['overwrite-existing'] == 'No' ) { // check for duplicate meta-name | |
| 1376 | + $found_in_custom_fields = false; | |
| 1260 | 1377 | |
| 1261 | - // meta names that are reserved and cannot be used as part of other meta names | |
| 1262 | - $reserved_meta_name_list_strict = apply_filters( 'wppb_unique_meta_name_list_strict', array( 'map' ) ); | |
| 1263 | - // skip meta name check for these fields | |
| 1264 | - $skip_unique_meta_name_list_check = apply_filters( 'wppb_skip_unique_meta_name_list_check', array( 'Map', 'Honeypot' ) ); | |
| 1378 | + if( $all_fields != 'not_set' ) | |
| 1379 | + foreach( $all_fields as $field ){ | |
| 1265 | 1380 | |
| 1266 | - // if the desired meta name is in the restricted list or if one of the meta names in the strictly | |
| 1267 | - // restricted list is part of it display an error message | |
| 1268 | - $is_reserved_meta_name = false; | |
| 1269 | - $trimmed_meta_name = trim( $posted_values['meta-name'] ); | |
| 1270 | - if ( !in_array( $posted_values['field'], $skip_unique_meta_name_list_check ) ) { | |
| 1271 | - foreach ($reserved_meta_name_list as $reserved_meta_name) { | |
| 1272 | - if (in_array($trimmed_meta_name, $reserved_meta_name_list) || | |
| 1273 | - (strpos($trimmed_meta_name, $reserved_meta_name) !== false && in_array($reserved_meta_name, $reserved_meta_name_list_strict))) { | |
| 1274 | - $is_reserved_meta_name = true; | |
| 1275 | - break; | |
| 1381 | + if ( $posted_values['meta-name'] != '' && ( $field['meta-name'] == $posted_values['meta-name'] ) && ( $field['id'] != $posted_values['id'] ) ) { | |
| 1382 | + $message .= __( "That meta-name is already in use\n", 'profile-builder' ); | |
| 1383 | + $found_in_custom_fields = true; | |
| 1276 | 1384 | } |
| 1385 | + elseif ( ( $field['meta-name'] == $posted_values['meta-name'] ) && ( $field['id'] == $posted_values['id'] ) ) | |
| 1386 | + $found_in_custom_fields = true; | |
| 1387 | + | |
| 1277 | 1388 | } |
| 1278 | - } | |
| 1279 | - if ( $is_reserved_meta_name ) | |
| 1280 | - $message .= __( "That meta-name can't be used, please choose another\n", 'profile-builder' ); | |
| 1281 | 1389 | |
| 1282 | - else{ | |
| 1283 | - $found_in_custom_fields = false; | |
| 1390 | + if ( $found_in_custom_fields === false ) { | |
| 1284 | 1391 | |
| 1285 | - if( $all_fields != 'not_set' ) | |
| 1286 | - foreach( $all_fields as $field ){ | |
| 1287 | - if ( $posted_values['meta-name'] != '' && ( $field['meta-name'] == $posted_values['meta-name'] ) && ( $field['id'] != $posted_values['id'] ) ){ | |
| 1288 | - $message .= __( "That meta-name is already in use\n", 'profile-builder' ); | |
| 1289 | - $found_in_custom_fields = true; | |
| 1392 | + if( $posted_values['meta-name'] != '' ) { | |
| 1393 | + $found_meta_name = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->usermeta WHERE meta_key = %s", $posted_values['meta-name'] ) ); | |
| 1290 | 1394 | |
| 1291 | - }elseif ( ( $field['meta-name'] == $posted_values['meta-name'] ) && ( $field['id'] == $posted_values['id'] ) ) | |
| 1292 | - $found_in_custom_fields = true; | |
| 1293 | - } | |
| 1395 | + if ( $found_meta_name != null ) | |
| 1396 | + $message .= __( "That meta-name is already in use\n", 'profile-builder' ); | |
| 1294 | 1397 | |
| 1295 | - if ( $found_in_custom_fields === false ){ | |
| 1296 | - if( $posted_values['meta-name'] != '' ) { | |
| 1297 | - $found_meta_name = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->usermeta WHERE meta_key = %s", $posted_values['meta-name'])); | |
| 1298 | - if ($found_meta_name != null) | |
| 1299 | - $message .= __("That meta-name is already in use\n", 'profile-builder'); | |
| 1300 | - } | |
| 1301 | - } | |
| 1302 | - } | |
| 1303 | - } | |
| 1304 | - } | |
| 1305 | - //END check duplicate meta-name | |
| 1398 | + } | |
| 1306 | 1399 | |
| 1307 | - // check for correct meta name on upload field | |
| 1400 | + } | |
| 1401 | + | |
| 1402 | + } | |
| 1403 | + | |
| 1404 | + } | |
| 1405 | + //END check for empty, reserved and/or duplicate meta-name | |
| 1406 | + | |
| 1407 | + // check for correct meta name | |
| 1308 | 1408 | if( $posted_values['field'] == 'Upload' ) { |
| 1309 | 1409 | if( ! empty( $posted_values['meta-name'] ) && preg_match( '/([^a-z\d_-])/', $posted_values['meta-name'] ) ) { |
| 1310 | 1410 | $message .= __( "The meta-name can only contain lowercase letters, numbers, _ , - and no spaces.\n", 'profile-builder' ); |
| 1311 | 1411 | } |
| 1312 | 1412 | } |
| 1313 | - // END check for correct meta name on upload field | |
| 1413 | + elseif ( ! empty( $posted_values['meta-name'] ) && preg_match( '/\s/', $posted_values['meta-name'] ) ) { | |
| 1414 | + $message .= __( "The meta-name cannot contain spaces.\n", 'profile-builder' ); | |
| 1415 | + } | |
| 1314 | 1416 | |
| 1417 | + // END check for correct meta name | |
| 1418 | + | |
| 1315 | 1419 | // check for valid default option (checkbox, select, radio) |
| 1316 | 1420 | if ( ( $posted_values['field'] == 'Checkbox' ) || ( $posted_values['field'] == 'Select (Multiple)' ) ) { |
| 1317 | 1421 | $options = array_map( 'trim', explode( ',', $posted_values['options'] ) ); |
| 1318 | 1422 | $default_options = ( ( trim( $posted_values['default-options'] ) == '' ) ? array() : array_map( 'trim', explode( ',', $posted_values['default-options'] ) ) ); |
| @@ -1580,9 +1684,9 @@ | ||
| 1580 | 1684 | global $wpdb; |
| 1581 | 1685 | |
| 1582 | 1686 | $meta_name_underlined = $meta_name . '_'; |
| 1583 | 1687 | |
| 1584 | - $results = $wpdb->get_results( "SELECT meta_value, meta_key FROM {$wpdb->usermeta} WHERE user_id={$user_id} AND meta_key LIKE '%{$meta_name_underlined}%'", ARRAY_N ); | |
| 1688 | + $results = $wpdb->get_results( $wpdb->prepare( "SELECT meta_value, meta_key FROM {$wpdb->usermeta} WHERE user_id = %d AND meta_key LIKE '%s'", $user_id, '%' . $meta_name_underlined . '%' ), ARRAY_N ); | |
| 1585 | 1689 | |
| 1586 | 1690 | $markers = array(); |
| 1587 | 1691 | $i = 0; |
| 1588 | 1692 | |
| @@ -1719,27 +1823,13 @@ | ||
| 1719 | 1823 | global $wpdb; |
| 1720 | 1824 | $wppb_manage_fields = get_option('wppb_manage_fields'); |
| 1721 | 1825 | if (!empty($wppb_manage_fields)) { |
| 1722 | 1826 | |
| 1723 | - /* | |
| 1724 | - * We need to be sure this is not a repeater. | |
| 1725 | - * The way we're doing this is by checking if the $values['meta-name'] is found inside $wppb_manage_fields | |
| 1726 | - * If it's not, it's probably inside a repeater. | |
| 1727 | - * | |
| 1728 | - * The reason we're doing this is because when we're updating a repeater field the $meta is still 'wppb_manage_fields' for some reason, while $element_id comes from the position of the repeater. | |
| 1729 | - * | |
| 1730 | - * This means we're updating last_name (if it's the 9'th position in wppb_manage_fields) instead of 'something_repeater' that's also in the 9'th position but inside the repeater group. | |
| 1731 | - * | |
| 1732 | - * Also, this code didn't account for 'something_repeater_1' etc, meaning it would have changed just 1 field, causing data loss anyway. | |
| 1733 | - * | |
| 1734 | - */ | |
| 1735 | - $is_not_repeater = false; | |
| 1736 | - foreach ($wppb_manage_fields as $field){ | |
| 1737 | - if ( $field['meta-name'] == $values['meta-name'] ){ | |
| 1738 | - $is_not_repeater = true; | |
| 1739 | - } | |
| 1740 | - } | |
| 1827 | + $is_not_repeater = true; | |
| 1741 | 1828 | |
| 1829 | + if( !empty( $wppb_manage_fields[$element_id] ) && $wppb_manage_fields[$element_id]['field'] == 'Repeater' ) | |
| 1830 | + $is_not_repeater = false; | |
| 1831 | + | |
| 1742 | 1832 | if (!empty($values['meta-name']) && $wppb_manage_fields[$element_id]['meta-name'] != $values['meta-name'] && $is_not_repeater ) { |
| 1743 | 1833 | $wpdb->update( |
| 1744 | 1834 | $wpdb->usermeta, |
| 1745 | 1835 | array('meta_key' => sanitize_text_field($values['meta-name'])), |
| @@ -1796,4 +1886,219 @@ | ||
| 1796 | 1886 | return $tags; |
| 1797 | 1887 | } |
| 1798 | 1888 | } |
| 1799 | 1889 | add_filter( 'wppb_map_bubble_fields', 'wppb_filter_map_bubble_fields' ); |
| 1890 | + | |
| 1891 | + | |
| 1892 | +/** | |
| 1893 | + * Get field property mapping for cleaning up stored field data | |
| 1894 | + * | |
| 1895 | + * Maps each field type to its required properties based on the JavaScript | |
| 1896 | + * field definitions in assets/js/jquery-manage-fields-live-change.js | |
| 1897 | + * | |
| 1898 | + * @since 3.15.3 | |
| 1899 | + * @return array Field type to properties mapping | |
| 1900 | + */ | |
| 1901 | +function wppb_get_field_property_mapping() { | |
| 1902 | + | |
| 1903 | + // Properties that can be dynamically added by various add-ons to many field types | |
| 1904 | + $optional_addon_properties = array( | |
| 1905 | + // Conditional Fields add-on | |
| 1906 | + 'conditional-logic-enabled', | |
| 1907 | + 'conditional-logic', | |
| 1908 | + // WooCommerce Sync add-on | |
| 1909 | + 'woocommerce-checkout-field', | |
| 1910 | + // BuddyPress add-on | |
| 1911 | + 'bdp-default-visibility', | |
| 1912 | + 'bdp-allow-custom-visibility', | |
| 1913 | + // Field Visibility add-on | |
| 1914 | + 'visibility', | |
| 1915 | + 'user-role-visibility', | |
| 1916 | + 'location-visibility', | |
| 1917 | + // Edit Profile Approved by Admin add-on | |
| 1918 | + 'edit-profile-approved-by-admin', | |
| 1919 | + // Maximum Character Length add-on | |
| 1920 | + 'maximum-character-length', | |
| 1921 | + // Custom CSS Classes add-on | |
| 1922 | + 'class-field', | |
| 1923 | + ); | |
| 1924 | + | |
| 1925 | + /** | |
| 1926 | + * Filter the optional addon properties that are applied to all field types. | |
| 1927 | + * | |
| 1928 | + * Add-ons can use this filter to register properties that should be preserved | |
| 1929 | + * across all field types (e.g., properties that can be applied to any field). | |
| 1930 | + * | |
| 1931 | + * @since 3.15.3 | |
| 1932 | + * | |
| 1933 | + * @param array $optional_addon_properties Array of property slugs to preserve for all fields | |
| 1934 | + * | |
| 1935 | + * @example | |
| 1936 | + * add_filter( 'wppb_field_optional_properties', 'my_addon_register_optional_properties' ); | |
| 1937 | + * function my_addon_register_optional_properties( $properties ) { | |
| 1938 | + * $properties[] = 'my-custom-property'; | |
| 1939 | + * $properties[] = 'another-property'; | |
| 1940 | + * return $properties; | |
| 1941 | + * } | |
| 1942 | + */ | |
| 1943 | + $optional_addon_properties = apply_filters( 'wppb_field_optional_properties', $optional_addon_properties ); | |
| 1944 | + | |
| 1945 | + $mapping = array( | |
| 1946 | + // Default WordPress Fields - Headings | |
| 1947 | + 'Default - Name (Heading)' => array(), | |
| 1948 | + 'Default - Contact Info (Heading)' => array(), | |
| 1949 | + 'Default - About Yourself (Heading)' => array(), | |
| 1950 | + | |
| 1951 | + // Default WordPress Fields - User Data | |
| 1952 | + 'Default - Username' => array('default-value'), | |
| 1953 | + 'Default - First Name' => array('default-value'), | |
| 1954 | + 'Default - Last Name' => array('default-value'), | |
| 1955 | + 'Default - Nickname' => array('default-value'), | |
| 1956 | + 'Default - E-mail' => array('default-value'), | |
| 1957 | + 'Default - Website' => array('default-value'), | |
| 1958 | + 'Default - AIM' => array('default-value'), | |
| 1959 | + 'Default - Yahoo IM' => array('default-value'), | |
| 1960 | + 'Default - Jabber / Google Talk' => array('default-value'), | |
| 1961 | + 'Default - Password' => array('ask-current-password'), | |
| 1962 | + 'Default - Repeat Password' => array(), | |
| 1963 | + 'Default - Biographical Info' => array('row-count', 'default-content'), | |
| 1964 | + 'Default - Display name publicly as' => array('default-value'), | |
| 1965 | + 'Default - Blog Details' => array(), | |
| 1966 | + | |
| 1967 | + // GDPR Fields | |
| 1968 | + 'GDPR Checkbox' => array(), | |
| 1969 | + 'GDPR Delete Button' => array(), | |
| 1970 | + 'GDPR Communication Preferences' => array('gdpr-communication-preferences', 'gdpr-communication-preferences-sort-order'), | |
| 1971 | + | |
| 1972 | + // Standard Fields | |
| 1973 | + 'Heading' => array('heading-tag'), | |
| 1974 | + 'Input' => array('default-value'), | |
| 1975 | + 'Email' => array('default-value'), | |
| 1976 | + 'Email Confirmation' => array(), | |
| 1977 | + 'URL' => array('default-value'), | |
| 1978 | + 'Number' => array('default-value', 'min-number-value', 'max-number-value', 'number-step-value'), | |
| 1979 | + 'Input (Hidden)' => array('default-value'), | |
| 1980 | + 'Language' => array('default-value'), | |
| 1981 | + 'Textarea' => array('default-content', 'row-count'), | |
| 1982 | + 'WYSIWYG' => array('default-content', 'row-count'), | |
| 1983 | + 'Phone' => array('default-value', 'phone-format'), | |
| 1984 | + | |
| 1985 | + // Select Fields | |
| 1986 | + 'Select' => array('default-option', 'options', 'labels'), | |
| 1987 | + 'Select (Multiple)' => array('default-options', 'options', 'labels'), | |
| 1988 | + 'Select (Country)' => array('default-option-country'), | |
| 1989 | + 'Select (Currency)' => array('show-currency-symbol', 'default-option-currency'), | |
| 1990 | + 'Select (Timezone)' => array('default-option-timezone'), | |
| 1991 | + 'Select (CPT)' => array('default-option', 'cpt'), | |
| 1992 | + 'Select (Taxonomy)' => array('default-option', 'taxonomy'), | |
| 1993 | + 'Select2' => array('default-option', 'options', 'labels'), | |
| 1994 | + 'Select2 (Multiple)' => array('default-options', 'options', 'labels', 'select2-multiple-limit', 'select2-multiple-tags'), | |
| 1995 | + | |
| 1996 | + // Checkbox and Radio Fields | |
| 1997 | + 'Checkbox' => array('default-options', 'options', 'labels'), | |
| 1998 | + 'Checkbox (Terms and Conditions)' => array('terms-of-agreement'), | |
| 1999 | + 'Radio' => array('default-option', 'options', 'labels'), | |
| 2000 | + 'Honeypot' => array(), | |
| 2001 | + | |
| 2002 | + // Upload Fields | |
| 2003 | + 'Upload' => array('simple-upload', 'allowed-upload-extensions', 'max-file-size'), | |
| 2004 | + 'Avatar' => array('simple-upload', 'allowed-image-extensions', 'avatar-size', 'max-file-size'), | |
| 2005 | + | |
| 2006 | + // Date/Time Fields | |
| 2007 | + 'Datepicker' => array('default-value', 'date-format'), | |
| 2008 | + 'Timepicker' => array('time-format'), | |
| 2009 | + 'Colorpicker' => array('default-value'), | |
| 2010 | + | |
| 2011 | + // Advanced Fields | |
| 2012 | + 'Validation' => array('validation-possible-values', 'custom-error-message'), | |
| 2013 | + 'reCAPTCHA' => array('recaptcha-type', 'public-key', 'private-key', 'score-threshold', 'captcha-pb-forms', 'captcha-wp-forms'), | |
| 2014 | + 'Turnstile' => array('theme', 'turnstile-site-key', 'turnstile-secret-key', 'turnstile-pb-forms', 'turnstile-wp-forms'), | |
| 2015 | + 'Select (User Role)' => array('user-roles', 'user-roles-on-edit-profile', 'user-roles-sort-order'), | |
| 2016 | + 'Map' => array('map-api-key', 'map-default-lat', 'map-default-lng', 'map-default-zoom', 'map-height', 'map-pins-load-type', 'map-pagination-number', 'map-bubble-fields'), | |
| 2017 | + 'Additional Map' => array('map-default-lat', 'map-default-lng', 'map-default-zoom', 'map-height'), | |
| 2018 | + 'HTML' => array('html-content'), | |
| 2019 | + | |
| 2020 | + // WooCommerce Fields (added via JS by add-on) | |
| 2021 | + 'WooCommerce Customer Billing Address' => array('woo-billing-fields', 'woo-billing-fields-required', 'woo-billing-fields-sort-order', 'woo-billing-fields-name'), | |
| 2022 | + 'WooCommerce Customer Shipping Address' => array('woo-shipping-fields', 'woo-shipping-fields-required', 'woo-shipping-fields-sort-order', 'woo-shipping-fields-name'), | |
| 2023 | + | |
| 2024 | + // Add-on Fields (MailChimp, MailPoet, Campaign Monitor, etc. may add their own) | |
| 2025 | + 'MailChimp Subscribe' => array('mailchimp-lists', 'mailchimp-default-checked', 'mailchimp-hide-field'), | |
| 2026 | + 'MailPoet Subscribe' => array('mailpoet-lists', 'mailpoet-default-checked', 'mailpoet-hide-field'), | |
| 2027 | + 'Campaign Monitor Subscribe' => array('campaign-monitor-lists', 'campaign-monitor-hide-field'), | |
| 2028 | + 'Subscription Plans' => array('subscription-plans', 'subscription-plans-sort-order', 'subscription-plan-selected'), | |
| 2029 | + 'PMS Billing Fields' => array('pms-billing-fields'), | |
| 2030 | + 'Repeater' => array('rpf-enable-limit', 'rpf-limit', 'rpf-limit-reached-message', 'rpf-role-limit', 'rpf-button'), | |
| 2031 | + ); | |
| 2032 | + | |
| 2033 | + // Add optional addon properties to all field types | |
| 2034 | + foreach ( $mapping as $field_type => $properties ) { | |
| 2035 | + $mapping[$field_type] = array_merge( $properties, $optional_addon_properties ); | |
| 2036 | + } | |
| 2037 | + | |
| 2038 | + // Allow add-ons to register their field type property mappings | |
| 2039 | + $mapping = apply_filters( 'wppb_field_property_mapping', $mapping ); | |
| 2040 | + | |
| 2041 | + return $mapping; | |
| 2042 | +} | |
| 2043 | + | |
| 2044 | +/** | |
| 2045 | + * Clean up field properties before saving to database | |
| 2046 | + * | |
| 2047 | + * Removes unused properties from each field based on its type, reducing database bloat. | |
| 2048 | + * Common properties are kept for all fields, field-specific properties are kept only | |
| 2049 | + * when relevant to the field type. | |
| 2050 | + * | |
| 2051 | + * @since 3.15.3 | |
| 2052 | + * @param array $value New field data being saved | |
| 2053 | + * @param array $old_value Existing field data (not used) | |
| 2054 | + * @return array Cleaned field data | |
| 2055 | + */ | |
| 2056 | +function wppb_cleanup_manage_fields_before_save( $value, $old_value ) { | |
| 2057 | + // Only process if we have an array | |
| 2058 | + if ( ! is_array( $value ) ) { | |
| 2059 | + return $value; | |
| 2060 | + } | |
| 2061 | + | |
| 2062 | + // Get field type to property mapping | |
| 2063 | + $mapping = wppb_get_field_property_mapping(); | |
| 2064 | + | |
| 2065 | + // Common properties kept for all fields | |
| 2066 | + // Note: meta-name is kept even when not shown in UI, as it's set programmatically | |
| 2067 | + $common_properties = array( | |
| 2068 | + 'id', | |
| 2069 | + 'field', | |
| 2070 | + 'field-title', | |
| 2071 | + 'meta-name', | |
| 2072 | + 'description', | |
| 2073 | + 'required', | |
| 2074 | + 'overwrite-existing', | |
| 2075 | + ); | |
| 2076 | + | |
| 2077 | + // Process each field | |
| 2078 | + foreach ( $value as $key => $field ) { | |
| 2079 | + if ( ! isset( $field['field'] ) ) { | |
| 2080 | + continue; | |
| 2081 | + } | |
| 2082 | + | |
| 2083 | + $field_type = $field['field']; | |
| 2084 | + $allowed_properties = $common_properties; | |
| 2085 | + | |
| 2086 | + // Add field-specific properties if we have a mapping | |
| 2087 | + if ( isset( $mapping[$field_type] ) ) { | |
| 2088 | + $allowed_properties = array_merge( $allowed_properties, $mapping[$field_type] ); | |
| 2089 | + } else { | |
| 2090 | + // Unknown field type: keep common properties + any non-empty properties | |
| 2091 | + foreach ( $field as $prop_key => $prop_value ) { | |
| 2092 | + if ( ! in_array( $prop_key, $common_properties ) && ! empty( $prop_value ) ) { | |
| 2093 | + $allowed_properties[] = $prop_key; | |
| 2094 | + } | |
| 2095 | + } | |
| 2096 | + } | |
| 2097 | + | |
| 2098 | + // Filter the field to only keep allowed properties | |
| 2099 | + $value[$key] = array_intersect_key( $field, array_flip( $allowed_properties ) ); | |
| 2100 | + } | |
| 2101 | + | |
| 2102 | + return $value; | |
| 2103 | +} | |
| 2104 | +add_filter( 'pre_update_option_wppb_manage_fields', 'wppb_cleanup_manage_fields_before_save', 5, 2 ); | |