y( 'label' => __('Author', 'ws-form'), 'variables' => array( 'author_id' => array( 'label' => __('ID', 'ws-form'), 'description' => __('Returns the author of the current post.', 'ws-form'), 'usage' => array('action'), 'secure' => true ), 'author_display_name' => array( 'label' => __('Display Name', 'ws-form'), 'description' => __('Returns the author of the current post.', 'ws-form'), 'usage' => array('action'), 'secure' => true ), 'author_first_name' => array( 'label' => __('First Name', 'ws-form'), 'description' => __('Returns the author of the current post.', 'ws-form'), 'usage' => array('action'), 'secure' => true ), 'author_last_name' => array( 'label' => __('Last Name', 'ws-form'), 'description' => __('Returns the author of the current post.', 'ws-form'), 'usage' => array('action'), 'secure' => true ), 'author_nickname' => array( 'label' => __('Nickname', 'ws-form'), 'description' => __('Returns the author of the current post.', 'ws-form'), 'usage' => array('action'), 'secure' => true ), 'author_email' => array( 'label' => __('Email', 'ws-form'), 'description' => __('Returns the author of the current post.', 'ws-form'), 'usage' => array('action'), 'secure' => true ) ) ); // URL $parse_variables['url'] = array( 'label' => __('URL', 'ws-form'), 'variables' => array( 'url_login' => array( 'label' => __('Login', 'ws-form'), 'description' => __('Returns the login URL.', 'ws-form'), 'usage' => array('action'), 'secure' => true ), 'url_logout' => array( 'label' => __('Logout', 'ws-form'), 'description' => __('Returns the logout URL.', 'ws-form'), 'usage' => array('action'), 'secure' => true ), 'url_lost_password' => array( 'label' => __('Lost Password', 'ws-form'), 'description' => __('Returns the lost password URL.', 'ws-form'), 'usage' => array('action'), 'secure' => true ), 'url_register' => array( 'label' => __('Register', 'ws-form'), 'description' => __('Returns the register URL.', 'ws-form'), 'usage' => array('action'), 'secure' => true ), ) ); if(!$public) { // Tracking $tracking_array = self::get_tracking($public); $parse_variables['tracking'] = array( 'label' => __('Tracking', 'ws-form'), 'variables' => array() ); foreach($tracking_array as $meta_key => $tracking) { $parse_variables['tracking']['variables'][$meta_key] = array( 'label' => $tracking['label'], 'description' => $tracking['description'], 'kb_slug' => 'tracking', 'usage' => $tracking['usage'], 'secure' => true ); } } // Get e-commerce config $ecommerce_config = self::get_ecommerce(); foreach($ecommerce_config['cart_price_types'] as $meta_key => $cart_price_type) { $parse_variables['ecommerce']['variables']['ecommerce_cart_' . $meta_key . '_span'] = array( 'label' => sprintf('%s (%s)', $cart_price_type['label'], __('Span', 'ws-form')), 'value' => sprintf('#ecommerce_cart_%1$s', $meta_key), 'description' => __('Excludes currency symbol.', 'ws-form'), 'kb_slug' => 'introduction-e-commerce', 'usage' => array('client') ); $parse_variables['ecommerce']['variables']['ecommerce_cart_' . $meta_key . '_span_currency'] = array( 'label' => sprintf('%s (%s)', $cart_price_type['label'], __('Span Currency', 'ws-form')), 'value' => sprintf('#ecommerce_cart_%1$s_currency', $meta_key), 'description' => __('Includes currency symbol.', 'ws-form'), 'kb_slug' => 'introduction-e-commerce', 'usage' => array('client') ); $parse_variables['ecommerce']['variables']['ecommerce_cart_' . $meta_key] = array( 'label' => $cart_price_type['label'], 'description' => __('Excludes currency symbol.', 'ws-form'), 'kb_slug' => 'introduction-e-commerce', 'usage' => array('client', 'action') ); $parse_variables['ecommerce']['variables']['ecommerce_cart_' . $meta_key . '_currency'] = array( 'label' => sprintf('%s (%s)', $cart_price_type['label'], __('Currency', 'ws-form')), 'description' => __('Includes currency symbol.', 'ws-form'), 'kb_slug' => 'introduction-e-commerce', 'usage' => array('client', 'action') ); } foreach($ecommerce_config['meta_keys'] as $meta_key => $meta_key_config) { $type = isset($meta_key_config['type']) ? $meta_key_config['type'] : false; if($type == 'price') { $parse_variables['ecommerce']['variables'][$meta_key . '_span'] = array( 'label' => sprintf('%s (%s)', $meta_key_config['label'], __('Span', 'ws-form')), 'value' => sprintf('%1$s', str_replace('_', '-', $meta_key)), 'description' => __('Excludes currency symbol.', 'ws-form'), 'kb_slug' => 'introduction-e-commerce', 'usage' => array('client') ); $parse_variables['ecommerce']['variables'][$meta_key . '_span_currency'] = array( 'label' => sprintf('%s (%s)', $meta_key_config['label'], __('Span Currency', 'ws-form')), 'value' => sprintf('%1$s_currency', str_replace('_', '-', $meta_key)), 'description' => __('Includes currency symbol.', 'ws-form'), 'kb_slug' => 'introduction-e-commerce', 'usage' => array('client') ); $parse_variables['ecommerce']['variables'][$meta_key . '_currency'] = array( 'label' => sprintf('%s (%s)', $meta_key_config['label'], __('Currency', 'ws-form')), 'description' => __('Includes currency symbol.', 'ws-form'), 'kb_slug' => 'introduction-e-commerce', 'usage' => array('client', 'action') ); } $parse_variables['ecommerce']['variables'][$meta_key] = array( 'label' => $meta_key_config['label'], 'kb_slug' => 'introduction-e-commerce', 'usage' => array('client', 'action') ); } // User $user = WS_Form_Common::get_user(); $user_id = (($user === false) ? 0 : $user->ID); // Build names $user_full_name_array = array(); $user_first_name = (($user_id > 0) ? get_user_meta($user_id, 'first_name', true) : ''); if(!empty($user_first_name)) { $user_full_name_array[] = $user_first_name; } $user_last_name = (($user_id > 0) ? get_user_meta($user_id, 'last_name', true) : ''); if(!empty($user_last_name)) { $user_full_name_array[] = $user_last_name; } $user_full_name = implode(' ', $user_full_name_array); // #user_language / #user_*: from get_user_locale() (WordPress user preference; falls back to site locale). $user_locale_raw = get_user_locale(); $user_locale = is_string( $user_locale_raw ) ? WS_Form_Common::language_tag_to_locale( $user_locale_raw ) : ''; $user_language = WS_Form_Common::locale_to_language_tag( $user_locale ); $user_locale_language_code = WS_Form_Common::get_language_code( $user_locale ); $user_locale_country_code = WS_Form_Common::get_country_code( $user_locale ); $parse_variables['user'] = array( 'label' => __('User', 'ws-form'), 'variables' => array( 'user_id' => array( 'label' => __('ID', 'ws-form'), 'description' => __('Returns the user ID if logged in.', 'ws-form'), 'value' => $user_id, 'usage' => array('client', 'action') ), 'user_login' => array( 'label' => __('Login', 'ws-form'), 'description' => __('Returns the user ID if logged in.', 'ws-form'), 'value' => ($user_id > 0) ? $user->user_login : '', 'usage' => array('client', 'action') ), 'user_nicename' => array( 'label' => __('Nice Name', 'ws-form'), 'description' => __('Returns the user nicename if logged in.', 'ws-form'), 'value' => ($user_id > 0) ? $user->user_nicename : '', 'usage' => array('client', 'action') ), 'user_email' => array( 'label' => __('Email', 'ws-form'), 'description' => __('Returns the user email address if logged in.', 'ws-form'), 'value' => ($user_id > 0) ? $user->user_email : '', 'usage' => array('client', 'action') ), 'user_display_name' => array( 'label' => __('Display Name', 'ws-form'), 'description' => __('Returns the user display name if logged in.', 'ws-form'), 'value' => ($user_id > 0) ? $user->display_name : '', 'usage' => array('client', 'action') ), 'user_url' => array( 'label' => __('URL', 'ws-form'), 'description' => __('Returns the user URL if logged in.', 'ws-form'), 'value' => ($user_id > 0) ? $user->user_url : '', 'usage' => array('client', 'action') ), 'user_registered' => array( 'label' => __('Registration Date', 'ws-form'), 'description' => __('Returns the user registration date if logged in.', 'ws-form'), 'value' => ($user_id > 0) ? $user->user_registered : '', 'usage' => array('client', 'action') ), 'user_language' => array( 'label' => __('Language (User)', 'ws-form'), 'description' => __('Language tag (RFC 5646) derived from get_user_locale(): ISO 639 with optional ISO 3166-1 alpha-2 region, hyphen-separated (for example en-US). When logged out, matches the site locale. Respects multilingual plugins via WordPress.', 'ws-form'), 'value' => $user_language, 'usage' => array('client', 'action') ), 'user_locale' => array( 'label' => __('Locale (User)', 'ws-form'), 'description' => __('POSIX-style locale identifier from get_user_locale() (underscore separator; for example en_US). Region uses ISO 3166-1 alpha-2 when present. When logged out, matches the site locale.', 'ws-form'), 'value' => $user_locale, 'usage' => array('client', 'action') ), 'user_locale_language_code' => array( 'label' => __('Language Code (User)', 'ws-form'), 'description' => __('Primary language subtag from the user locale (ISO 639; lowercase, typically ISO 639-1).', 'ws-form'), 'value' => $user_locale_language_code, 'usage' => array('client', 'action') ), 'user_locale_country_code' => array( 'label' => __('Country Code (User)', 'ws-form'), 'description' => __('Region subtag from the user locale using ISO 3166-1 alpha-2, or blank if none.', 'ws-form'), 'value' => $user_locale_country_code, 'usage' => array('client', 'action') ), 'user_first_name' => array( 'label' => __('First Name', 'ws-form'), 'description' => __('Returns the user first name if logged in.', 'ws-form'), 'value' => $user_first_name, 'usage' => array('client', 'action') ), 'user_last_name' => array( 'label' => __('Last Name', 'ws-form'), 'description' => __('Returns the user last name if logged in.', 'ws-form'), 'value' => $user_last_name, 'usage' => array('client', 'action') ), 'user_full_name' => array( 'label' => __('Full Name', 'ws-form'), 'description' => __('Returns the user full name if logged in.', 'ws-form'), 'value' => $user_full_name, 'usage' => array('client', 'action') ), 'user_bio' => array( 'label' => __('Bio', 'ws-form'), 'description' => __('Returns the user biography if logged in.', 'ws-form'), 'value' => ($user_id > 0) ? get_user_meta($user_id, 'description', true) : '', 'usage' => array('client', 'action') ), 'user_nickname' => array( 'label' => __('Nickname', 'ws-form'), 'description' => __('Returns the user nickname if logged in.', 'ws-form'), 'value' => ($user_id > 0) ? get_user_meta($user_id, 'nickname', true) : '', 'usage' => array('client', 'action') ), 'user_admin_color' => array( 'label' => __('Admin Color', 'ws-form'), 'description' => __('Returns the user admin color if logged in.', 'ws-form'), 'value' => ($user_id > 0) ? get_user_meta($user_id, 'admin_color', true) : '', 'usage' => array('client', 'action') ), 'user_lost_password_key' => array( 'label' => __('Lost Password Key', 'ws-form'), 'description' => __('Returns the user lost password key.', 'ws-form'), 'value' => ($user_id > 0) ? $user->lost_password_key : '', 'usage' => array('client', 'action'), 'secure' => true ), 'user_lost_password_url' => array( 'label' => __('Lost Password URL', 'ws-form'), 'description' => __('Returns the user lost password URL.', 'ws-form'), 'attributes' => array( array('id' => 'path', 'type' => 'string', 'required' => false, 'default' => '') ), 'usage' => array('action'), 'secure' => true ), 'user_meta' => array( 'label' => __('Meta Value', 'ws-form'), 'attributes' => array( array('id' => 'meta_key', 'type' => 'string') ), 'description' => __('Returns the user meta value for the key specified.', 'ws-form'), 'usage' => array('client', 'action'), 'scope' => array('form_parse'), 'secure' => true ) ) ); // Search $parse_variables['search'] = array( 'label' => __('Search', 'ws-form'), 'variables' => array( 'search_query' => array( 'label' => __('Query', 'ws-form'), 'value' => get_search_query(), 'description' => __('Returns the search query.', 'ws-form'), 'usage' => array('client', 'action') ) ) ); // Cache self::$parse_variables[$public] = $parse_variables; return self::get_parse_variables_return($parse_variables, $public); } // Return parse variables public static function get_parse_variables_return($parse_variables, $public) { // Apply filter // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- All hooks prefixed with wsf_ $parse_variables = apply_filters('wsf_config_parse_variables', $parse_variables); // Public - Optimize if($public) { $parameters_exclude = array('label', 'description', 'limit', 'kb_slug', 'usage', 'secure'); foreach($parse_variables as $variable_group => $variable_group_config) { foreach($variable_group_config['variables'] as $variable => $variable_config) { unset($parse_variables[$variable_group]['label']); foreach($parameters_exclude as $parameter_exclude) { if(isset($parse_variables[$variable_group]['variables'][$variable][$parameter_exclude])) { unset($parse_variables[$variable_group]['variables'][$variable][$parameter_exclude]); } } } } } // Process group lookups (Used by parse_variables_process to improve performance) foreach($parse_variables as $group_id => $group_config) { $var_lookups = array(); foreach($group_config['variables'] as $variable_id => $variable_config) { $underscore_pos = strpos($variable_id, '_'); $var_lookup = '#' . (($underscore_pos !== false) ? substr($variable_id, 0, $underscore_pos) : $variable_id); if(!empty($var_lookup) && !in_array($var_lookup, $var_lookups)) { $var_lookups[] = $var_lookup; } } $parse_variables[$group_id]['var_lookups'] = $var_lookups; } return $parse_variables; } // JavaScript public static function get_external() { global $wp_version; // CDN or local source? $jquery_source = WS_Form_Common::option_get('jquery_source', 'local'); $local = ($jquery_source == 'local'); // Minified scripts? $min = SCRIPT_DEBUG ? '' : '.min'; // Third party script paths (Local and included with WS Form) $coloris_js_local = sprintf('%spublic/js/external/coloris%s.js', WS_FORM_PLUGIN_DIR_URL, $min); $coloris_css_local = sprintf('%spublic/css/external/coloris%s.css', WS_FORM_PLUGIN_DIR_URL, $min); $inputmask_js_local = sprintf('%spublic/js/external/jquery.inputmask%s.js', WS_FORM_PLUGIN_DIR_URL, $min); $intl_tel_input_js_local = sprintf('%spublic/js/external/intlTelInput%s.js', WS_FORM_PLUGIN_DIR_URL, $min); $intl_tel_input_css_local = sprintf('%spublic/css/external/intlTelInput%s.css', WS_FORM_PLUGIN_DIR_URL, $min); $select2_js_local = sprintf('%sshared/js/external/select2.full%s.js', WS_FORM_PLUGIN_DIR_URL, $min); $select2_css_local = sprintf('%sshared/css/external/select2%s.css', WS_FORM_PLUGIN_DIR_URL, $min); $datetimepicker_js_local = sprintf('%spublic/js/external/jquery.datetimepicker.full%s.js', WS_FORM_PLUGIN_DIR_URL, $min); $datetimepicker_css_local = sprintf('%spublic/css/external/jquery.datetimepicker%s.css', WS_FORM_PLUGIN_DIR_URL, $min); $dropzonejs_js_local = sprintf('%spublic/js/external/dropzone%s.js', WS_FORM_PLUGIN_DIR_URL, $min); $media_capture_js_local = sprintf('%spublic/js/external/media-capture%s.js', WS_FORM_PLUGIN_DIR_URL, $min); $media_capture_css_local = sprintf('%spublic/css/external/media-capture%s.css', WS_FORM_PLUGIN_DIR_URL, $min); $signature_pad_js_local = sprintf('%spublic/js/external/signature_pad%s.js', WS_FORM_PLUGIN_DIR_URL, $min); // Script paths (CDN) $coloris_js_cdn = sprintf('https://cdn.jsdelivr.net/npm/@melloware/coloris@0.24.0/dist/umd/coloris%s.js', $min); $coloris_css_cdn = sprintf('https://cdn.jsdelivr.net/npm/@melloware/coloris@0.24.0/dist/coloris%s.css', $min); $datetimepicker_js_cdn = sprintf('https://cdn.jsdelivr.net/npm/jquery-datetimepicker@2.5.21/build/jquery.datetimepicker.full%s.js', $min); $datetimepicker_css_cdn = (SCRIPT_DEBUG ? 'https://cdn.jsdelivr.net/npm/jquery-datetimepicker@2.5.21/jquery.datetimepicker.css' : 'https://cdn.jsdelivr.net/npm/jquery-datetimepicker@2.5.21/build/jquery.datetimepicker.min.css'); $dropzonejs_js_cdn = sprintf('https://cdn.jsdelivr.net/npm/dropzone@5.7.6/dist/dropzone%s.js', $min); $inputmask_js_cdn = sprintf('https://cdn.jsdelivr.net/gh/RobinHerbots/jquery.inputmask@5.0.9/dist/jquery.inputmask%s.js', $min); $intl_tel_input_js_cdn = sprintf('https://cdn.jsdelivr.net/npm/intl-tel-input@19.2.19/build/js/intlTelInput%s.js', $min); $intl_tel_input_css_cdn = sprintf('https://cdn.jsdelivr.net/npm/intl-tel-input@19.2.19/build/css/intlTelInput%s.css', $min); $select2_js_cdn = sprintf('https://cdn.jsdelivr.net/npm/select2@4.0.13/dist/js/select2.full%s.js', $min); $select2_css_cdn = sprintf('https://cdn.jsdelivr.net/npm/select2@4.0.13/dist/css/select2%s.css', $min); $signature_pad_js_cdn = sprintf('https://cdn.jsdelivr.net/npm/signature_pad@2.3.2/dist/signature_pad%s.js', $min); $external = array( // Coloris 'coloris_js' => array('path' => ($local ? $coloris_js_local : $coloris_js_cdn), 'version' => '0.24.0'), 'coloris_css' => array('path' => ($local ? $coloris_css_local : $coloris_css_cdn), 'version' => '0.24.0'), // Date Time Picker 'datetimepicker_js' => array('path' => ($local ? $datetimepicker_js_local : $datetimepicker_js_cdn), 'version' => '2.5.21'), 'datetimepicker_css' => array('path' => ($local ? $datetimepicker_css_local : $datetimepicker_css_cdn), 'version' => '2.5.21'), // DropzoneJS 'dropzonejs_js' => array('path' => ($local ? $dropzonejs_js_local : $dropzonejs_js_cdn), 'version' => '5.7.6'), // Input mask bundle 'inputmask_js' => array('path' => ($local ? $inputmask_js_local : $inputmask_js_cdn), 'version' => '5.0.7'), // International Telephone Input 'intl_tel_input_js' => array('path' => ($local ? $intl_tel_input_js_local : $intl_tel_input_js_cdn), 'version' => '17.0.9'), 'intl_tel_input_css' => array('path' => ($local ? $intl_tel_input_css_local : $intl_tel_input_css_cdn), 'version' => '17.0.9'), // Media capture 'media_capture_js' => array('path' => $media_capture_js_local, 'version' => '1.0.0'), 'media_capture_css' => array('path' => $media_capture_css_local, 'version' => '1.0.0'), // Select2 'select2_js' => array('path' => ($local ? $select2_js_local : $select2_js_cdn), 'version' => '4.0.5'), 'select2_css' => array('path' => ($local ? $select2_css_local : $select2_css_cdn), 'version' => '4.0.5'), // Signature Pad 'signature_pad_js' => array('path' => ($local ? $signature_pad_js_local : $signature_pad_js_cdn), 'version' => '2.3.2'), ); // Apply filter // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- All hooks prefixed with wsf_ $external = apply_filters('wsf_config_external', $external); return $external; } public static function get_countries_alpha_2() { $countries_alpha_2 = array( 'AF' => 'Afghanistan', 'AX' => 'Aland Islands', 'AL' => 'Albania', 'DZ' => 'Algeria', 'AS' => 'American Samoa', 'AD' => 'Andorra', 'AO' => 'Angola', 'AI' => 'Anguilla', 'AQ' => 'Antarctica', 'AG' => 'Antigua And Barbuda', 'AR' => 'Argentina', 'AM' => 'Armenia', 'AW' => 'Aruba', 'AU' => 'Australia', 'AT' => 'Austria', 'AZ' => 'Azerbaijan', 'BS' => 'Bahamas', 'BH' => 'Bahrain', 'BD' => 'Bangladesh', 'BB' => 'Barbados', 'BY' => 'Belarus', 'BE' => 'Belgium', 'BZ' => 'Belize', 'BJ' => 'Benin', 'BM' => 'Bermuda', 'BT' => 'Bhutan', 'BO' => 'Bolivia', 'BA' => 'Bosnia And Herzegovina', 'BW' => 'Botswana', 'BV' => 'Bouvet Island', 'BR' => 'Brazil', 'IO' => 'British Indian Ocean Territory', 'BN' => 'Brunei Darussalam', 'BG' => 'Bulgaria', 'BF' => 'Burkina Faso', 'BI' => 'Burundi', 'KH' => 'Cambodia', 'CM' => 'Cameroon', 'CA' => 'Canada', 'CV' => 'Cape Verde', 'KY' => 'Cayman Islands', 'CF' => 'Central African Republic', 'TD' => 'Chad', 'CL' => 'Chile', 'CN' => 'China', 'CX' => 'Christmas Island', 'CC' => 'Cocos (Keeling) Islands', 'CO' => 'Colombia', 'KM' => 'Comoros', 'CG' => 'Congo', 'CD' => 'Congo, Democratic Republic', 'CK' => 'Cook Islands', 'CR' => 'Costa Rica', 'CI' => 'Cote D\'Ivoire', 'HR' => 'Croatia', 'CU' => 'Cuba', 'CY' => 'Cyprus', 'CZ' => 'Czech Republic', 'DK' => 'Denmark', 'DJ' => 'Djibouti', 'DM' => 'Dominica', 'DO' => 'Dominican Republic', 'EC' => 'Ecuador', 'EG' => 'Egypt', 'SV' => 'El Salvador', 'GQ' => 'Equatorial Guinea', 'ER' => 'Eritrea', 'EE' => 'Estonia', 'ET' => 'Ethiopia', 'FK' => 'Falkland Islands (Malvinas)', 'FO' => 'Faroe Islands', 'FJ' => 'Fiji', 'FI' => 'Finland', 'FR' => 'France', 'GF' => 'French Guiana', 'PF' => 'French Polynesia', 'TF' => 'French Southern Territories', 'GA' => 'Gabon', 'GM' => 'Gambia', 'GE' => 'Georgia', 'DE' => 'Germany', 'GH' => 'Ghana', 'GI' => 'Gibraltar', 'GR' => 'Greece', 'GL' => 'Greenland', 'GD' => 'Grenada', 'GP' => 'Guadeloupe', 'GU' => 'Guam', 'GT' => 'Guatemala', 'GG' => 'Guernsey', 'GN' => 'Guinea', 'GW' => 'Guinea-Bissau', 'GY' => 'Guyana', 'HT' => 'Haiti', 'HM' => 'Heard Island & Mcdonald Islands', 'VA' => 'Holy See (Vatican City State)', 'HN' => 'Honduras', 'HK' => 'Hong Kong', 'HU' => 'Hungary', 'IS' => 'Iceland', 'IN' => 'India', 'ID' => 'Indonesia', 'IR' => 'Iran, Islamic Republic Of', 'IQ' => 'Iraq', 'IE' => 'Ireland', 'IM' => 'Isle Of Man', 'IL' => 'Israel', 'IT' => 'Italy', 'JM' => 'Jamaica', 'JP' => 'Japan', 'JE' => 'Jersey', 'JO' => 'Jordan', 'KZ' => 'Kazakhstan', 'KE' => 'Kenya', 'KI' => 'Kiribati', 'KR' => 'Korea', 'KP' => 'North Korea', 'KW' => 'Kuwait', 'KG' => 'Kyrgyzstan', 'LA' => 'Lao People\'s Democratic Republic', 'LV' => 'Latvia', 'LB' => 'Lebanon', 'LS' => 'Lesotho', 'LR' => 'Liberia', 'LY' => 'Libyan Arab Jamahiriya', 'LI' => 'Liechtenstein', 'LT' => 'Lithuania', 'LU' => 'Luxembourg', 'MO' => 'Macao', 'MK' => 'Macedonia', 'MG' => 'Madagascar', 'MW' => 'Malawi', 'MY' => 'Malaysia', 'MV' => 'Maldives', 'ML' => 'Mali', 'MT' => 'Malta', 'MH' => 'Marshall Islands', 'MQ' => 'Martinique', 'MR' => 'Mauritania', 'MU' => 'Mauritius', 'YT' => 'Mayotte', 'MX' => 'Mexico', 'FM' => 'Micronesia, Federated States Of', 'MD' => 'Moldova', 'MC' => 'Monaco', 'MN' => 'Mongolia', 'ME' => 'Montenegro', 'MS' => 'Montserrat', 'MA' => 'Morocco', 'MZ' => 'Mozambique', 'MM' => 'Myanmar', 'NA' => 'Namibia', 'NR' => 'Nauru', 'NP' => 'Nepal', 'NL' => 'Netherlands', 'AN' => 'Netherlands Antilles', 'NC' => 'New Caledonia', 'NZ' => 'New Zealand', 'NI' => 'Nicaragua', 'NE' => 'Niger', 'NG' => 'Nigeria', 'NU' => 'Niue', 'NF' => 'Norfolk Island', 'MP' => 'Northern Mariana Islands', 'NO' => 'Norway', 'OM' => 'Oman', 'PK' => 'Pakistan', 'PW' => 'Palau', 'PS' => 'Palestinian Territory, Occupied', 'PA' => 'Panama', 'PG' => 'Papua New Guinea', 'PY' => 'Paraguay', 'PE' => 'Peru', 'PH' => 'Philippines', 'PN' => 'Pitcairn', 'PL' => 'Poland', 'PT' => 'Portugal', 'PR' => 'Puerto Rico', 'QA' => 'Qatar', 'RE' => 'Reunion', 'RO' => 'Romania', 'RU' => 'Russian Federation', 'RW' => 'Rwanda', 'BL' => 'Saint Barthelemy', 'SH' => 'Saint Helena', 'KN' => 'Saint Kitts And Nevis', 'LC' => 'Saint Lucia', 'MF' => 'Saint Martin', 'PM' => 'Saint Pierre And Miquelon', 'VC' => 'Saint Vincent And Grenadines', 'WS' => 'Samoa', 'SM' => 'San Marino', 'ST' => 'Sao Tome And Principe', 'SA' => 'Saudi Arabia', 'SN' => 'Senegal', 'RS' => 'Serbia', 'SC' => 'Seychelles', 'SL' => 'Sierra Leone', 'SG' => 'Singapore', 'SK' => 'Slovakia', 'SI' => 'Slovenia', 'SB' => 'Solomon Islands', 'SO' => 'Somalia', 'ZA' => 'South Africa', 'GS' => 'South Georgia And Sandwich Isl.', 'ES' => 'Spain', 'LK' => 'Sri Lanka', 'SD' => 'Sudan', 'SR' => 'Suriname', 'SJ' => 'Svalbard And Jan Mayen', 'SZ' => 'Swaziland', 'SE' => 'Sweden', 'CH' => 'Switzerland', 'SY' => 'Syrian Arab Republic', 'TW' => 'Taiwan', 'TJ' => 'Tajikistan', 'TZ' => 'Tanzania', 'TH' => 'Thailand', 'TL' => 'Timor-Leste', 'TG' => 'Togo', 'TK' => 'Tokelau', 'TO' => 'Tonga', 'TT' => 'Trinidad And Tobago', 'TN' => 'Tunisia', 'TR' => 'Turkey', 'TM' => 'Turkmenistan', 'TC' => 'Turks And Caicos Islands', 'TV' => 'Tuvalu', 'UG' => 'Uganda', 'UA' => 'Ukraine', 'AE' => 'United Arab Emirates', 'GB' => 'United Kingdom', 'US' => 'United States', 'UM' => 'United States Outlying Islands', 'UY' => 'Uruguay', 'UZ' => 'Uzbekistan', 'VU' => 'Vanuatu', 'VE' => 'Venezuela', 'VN' => 'Vietnam', 'VG' => 'Virgin Islands, British', 'VI' => 'Virgin Islands, U.S.', 'WF' => 'Wallis And Futuna', 'EH' => 'Western Sahara', 'YE' => 'Yemen', 'ZM' => 'Zambia', 'ZW' => 'Zimbabwe' ); // Apply filter // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- All hooks prefixed with wsf_ $countries_alpha_2 = apply_filters('wsf_config_countries_alpha_2', $countries_alpha_2); return $countries_alpha_2; } public static function get_currencies($sort_by_name = true) { $currencies = array( 'AED' => array('s' => 'د.إ','n' => 'United Arab Emirates dirham'), 'AFN' => array('s' => '؋','n' => 'Afghan afghani'), 'ALL' => array('s' => 'L','n' => 'Albanian lek'), 'AMD' => array('s' => 'AMD','n' => 'Armenian dram'), 'ANG' => array('s' => 'ƒ','n' => 'Netherlands Antillean guilder'), 'AOA' => array('s' => 'Kz','n' => 'Angolan kwanza'), 'ARS' => array('s' => '$','n' => 'Argentine peso'), 'AUD' => array('s' => '$','n' => 'Australian dollar'), 'AWG' => array('s' => 'Afl.','n' => 'Aruban florin'), 'AZN' => array('s' => 'AZN','n' => 'Azerbaijani manat'), 'BAM' => array('s' => 'KM','n' => 'Bosnia and Herzegovina convertible mark'), 'BBD' => array('s' => '$','n' => 'Barbadian dollar'), 'BDT' => array('s' => '৳ ','n' => 'Bangladeshi taka'), 'BGN' => array('s' => 'лв.','n' => 'Bulgarian lev'), 'BHD' => array('s' => '.د.ب','n' => 'Bahraini dinar'), 'BIF' => array('s' => 'Fr','n' => 'Burundian franc'), 'BMD' => array('s' => '$','n' => 'Bermudian dollar'), 'BND' => array('s' => '$','n' => 'Brunei dollar'), 'BOB' => array('s' => 'Bs.','n' => 'Bolivian boliviano'), 'BRL' => array('s' => 'R$','n' => 'Brazilian real'), 'BSD' => array('s' => '$','n' => 'Bahamian dollar'), 'BTC' => array('s' => '฿','n' => 'Bitcoin'), 'BTN' => array('s' => 'Nu.','n' => 'Bhutanese ngultrum'), 'BWP' => array('s' => 'P','n' => 'Botswana pula'), 'BYR' => array('s' => 'Br','n' => 'Belarusian ruble (old)'), 'BYN' => array('s' => 'Br','n' => 'Belarusian ruble'), 'BZD' => array('s' => '$','n' => 'Belize dollar'), 'CAD' => array('s' => '$','n' => 'Canadian dollar'), 'CDF' => array('s' => 'Fr','n' => 'Congolese franc'), 'CHF' => array('s' => 'CHF','n' => 'Swiss franc'), 'CLP' => array('s' => '$','n' => 'Chilean peso'), 'CNY' => array('s' => '¥','n' => 'Chinese yuan'), 'COP' => array('s' => '$','n' => 'Colombian peso'), 'CRC' => array('s' => '₡','n' => 'Costa Rican colón'), 'CUC' => array('s' => '$','n' => 'Cuban convertible peso'), 'CUP' => array('s' => '$','n' => 'Cuban peso'), 'CVE' => array('s' => '$','n' => 'Cape Verdean escudo'), 'CZK' => array('s' => 'Kč','n' => 'Czech koruna'), 'DJF' => array('s' => 'Fr','n' => 'Djiboutian franc'), 'DKK' => array('s' => 'kr.','n' => 'Danish krone'), 'DOP' => array('s' => 'RD$','n' => 'Dominican peso'), 'DZD' => array('s' => 'د.ج','n' => 'Algerian dinar'), 'EGP' => array('s' => 'EGP','n' => 'Egyptian pound'), 'ERN' => array('s' => 'Nfk','n' => 'Eritrean nakfa'), 'ETB' => array('s' => 'Br','n' => 'Ethiopian birr'), 'EUR' => array('s' => '€','n' => 'Euro'), 'FJD' => array('s' => '$','n' => 'Fijian dollar'), 'FKP' => array('s' => '£','n' => 'Falkland Islands pound'), 'GBP' => array('s' => '£','n' => 'Pound sterling'), 'GEL' => array('s' => '₾','n' => 'Georgian lari'), 'GGP' => array('s' => '£','n' => 'Guernsey pound'), 'GHS' => array('s' => '₵','n' => 'Ghana cedi'), 'GIP' => array('s' => '£','n' => 'Gibraltar pound'), 'GMD' => array('s' => 'D','n' => 'Gambian dalasi'), 'GNF' => array('s' => 'Fr','n' => 'Guinean franc'), 'GTQ' => array('s' => 'Q','n' => 'Guatemalan quetzal'), 'GYD' => array('s' => '$','n' => 'Guyanese dollar'), 'HKD' => array('s' => '$','n' => 'Hong Kong dollar'), 'HNL' => array('s' => 'L','n' => 'Honduran lempira'), 'HRK' => array('s' => 'kn','n' => 'Croatian kuna'), 'HTG' => array('s' => 'G','n' => 'Haitian gourde'), 'HUF' => array('s' => 'Ft','n' => 'Hungarian forint'), 'IDR' => array('s' => 'Rp','n' => 'Indonesian rupiah'), 'ILS' => array('s' => '₪','n' => 'Israeli new shekel'), 'IMP' => array('s' => '£','n' => 'Manx pound'), 'INR' => array('s' => '₹','n' => 'Indian rupee'), 'IQD' => array('s' => 'ع.د','n' => 'Iraqi dinar'), 'IRR' => array('s' => '﷼','n' => 'Iranian rial'), 'IRT' => array('s' => 'تومان','n' => 'Iranian toman'), 'ISK' => array('s' => 'kr.','n' => 'Icelandic króna'), 'JEP' => array('s' => '£','n' => 'Jersey pound'), 'JMD' => array('s' => '$','n' => 'Jamaican dollar'), 'JOD' => array('s' => 'د.ا','n' => 'Jordanian dinar'), 'JPY' => array('s' => '¥','n' => 'Japanese yen'), 'KES' => array('s' => 'KSh','n' => 'Kenyan shilling'), 'KGS' => array('s' => 'сом','n' => 'Kyrgyzstani som'), 'KHR' => array('s' => '៛','n' => 'Cambodian riel'), 'KMF' => array('s' => 'Fr','n' => 'Comorian franc'), 'KPW' => array('s' => '₩','n' => 'North Korean won'), 'KRW' => array('s' => '₩','n' => 'South Korean won'), 'KWD' => array('s' => 'د.ك','n' => 'Kuwaiti dinar'), 'KYD' => array('s' => '$','n' => 'Cayman Islands dollar'), 'KZT' => array('s' => '₸','n' => 'Kazakhstani tenge'), 'LAK' => array('s' => '₭','n' => 'Lao kip'), 'LBP' => array('s' => 'ل.ل','n' => 'Lebanese pound'), 'LKR' => array('s' => 'රු','n' => 'Sri Lankan rupee'), 'LRD' => array('s' => '$','n' => 'Liberian dollar'), 'LSL' => array('s' => 'L','n' => 'Lesotho loti'), 'LYD' => array('s' => 'ل.د','n' => 'Libyan dinar'), 'MAD' => array('s' => 'د.م.','n' => 'Moroccan dirham'), 'MDL' => array('s' => 'MDL','n' => 'Moldovan leu'), 'MGA' => array('s' => 'Ar','n' => 'Malagasy ariary'), 'MKD' => array('s' => 'ден','n' => 'Macedonian denar'), 'MMK' => array('s' => 'Ks','n' => 'Burmese kyat'), 'MNT' => array('s' => '₮','n' => 'Mongolian tögrög'), 'MOP' => array('s' => 'P','n' => 'Macanese pataca'), 'MRU' => array('s' => 'UM','n' => 'Mauritanian ouguiya'), 'MUR' => array('s' => '₨','n' => 'Mauritian rupee'), 'MVR' => array('s' => '.ރ','n' => 'Maldivian rufiyaa'), 'MWK' => array('s' => 'MK','n' => 'Malawian kwacha'), 'MXN' => array('s' => '$','n' => 'Mexican peso'), 'MYR' => array('s' => 'RM','n' => 'Malaysian ringgit'), 'MZN' => array('s' => 'MT','n' => 'Mozambican metical'), 'NAD' => array('s' => 'N$','n' => 'Namibian dollar'), 'NGN' => array('s' => '₦','n' => 'Nigerian naira'), 'NIO' => array('s' => 'C$','n' => 'Nicaraguan córdoba'), 'NOK' => array('s' => 'kr','n' => 'Norwegian krone'), 'NPR' => array('s' => '₨','n' => 'Nepalese rupee'), 'NZD' => array('s' => '$','n' => 'New Zealand dollar'), 'OMR' => array('s' => 'ر.ع.','n' => 'Omani rial'), 'PAB' => array('s' => 'B/.','n' => 'Panamanian balboa'), 'PEN' => array('s' => 'S/','n' => 'Sol'), 'PGK' => array('s' => 'K','n' => 'Papua New Guinean kina'), 'PHP' => array('s' => '₱','n' => 'Philippine peso'), 'PKR' => array('s' => '₨','n' => 'Pakistani rupee'), 'PLN' => array('s' => 'zł','n' => 'Polish złoty'), 'PRB' => array('s' => 'р.','n' => 'Transnistrian ruble'), 'PYG' => array('s' => '₲','n' => 'Paraguayan guaraní'), 'QAR' => array('s' => 'ر.ق','n' => 'Qatari riyal'), 'RON' => array('s' => 'lei','n' => 'Romanian leu'), 'RSD' => array('s' => 'рсд','n' => 'Serbian dinar'), 'RUB' => array('s' => '₽','n' => 'Russian ruble'), 'RWF' => array('s' => 'Fr','n' => 'Rwandan franc'), 'SAR' => array('s' => 'ر.س','n' => 'Saudi riyal'), 'SBD' => array('s' => '$','n' => 'Solomon Islands dollar'), 'SCR' => array('s' => '₨','n' => 'Seychellois rupee'), 'SDG' => array('s' => 'ج.س.','n' => 'Sudanese pound'), 'SEK' => array('s' => 'kr','n' => 'Swedish krona'), 'SGD' => array('s' => '$','n' => 'Singapore dollar'), 'SHP' => array('s' => '£','n' => 'Saint Helena pound'), 'SLL' => array('s' => 'Le','n' => 'Sierra Leonean leone'), 'SOS' => array('s' => 'Sh','n' => 'Somali shilling'), 'SRD' => array('s' => '$','n' => 'Surinamese dollar'), 'SSP' => array('s' => '£','n' => 'South Sudanese pound'), 'STN' => array('s' => 'Db','n' => 'São Tomé and Príncipe dobra'), 'SYP' => array('s' => 'ل.س','n' => 'Syrian pound'), 'SZL' => array('s' => 'L','n' => 'Swazi lilangeni'), 'THB' => array('s' => '฿','n' => 'Thai baht'), 'TJS' => array('s' => 'ЅМ','n' => 'Tajikistani somoni'), 'TMT' => array('s' => 'm','n' => 'Turkmenistan manat'), 'TND' => array('s' => 'د.ت','n' => 'Tunisian dinar'), 'TOP' => array('s' => 'T$','n' => 'Tongan paʻanga'), 'TRY' => array('s' => '₺','n' => 'Turkish lira'), 'TTD' => array('s' => '$','n' => 'Trinidad and Tobago dollar'), 'TWD' => array('s' => 'NT$','n' => 'New Taiwan dollar'), 'TZS' => array('s' => 'Sh','n' => 'Tanzanian shilling'), 'UAH' => array('s' => '₴','n' => 'Ukrainian hryvnia'), 'UGX' => array('s' => 'UGX','n' => 'Ugandan shilling'), 'USD' => array('s' => '$','n' => 'United States (US) dollar'), 'UYU' => array('s' => '$','n' => 'Uruguayan peso'), 'UZS' => array('s' => 'UZS','n' => 'Uzbekistani som'), 'VEF' => array('s' => 'Bs F','n' => 'Venezuelan bolívar'), 'VES' => array('s' => 'Bs.S','n' => 'Bolívar soberano'), 'VND' => array('s' => '₫','n' => 'Vietnamese đồng'), 'VUV' => array('s' => 'Vt','n' => 'Vanuatu vatu'), 'WST' => array('s' => 'T','n' => 'Samoan tālā'), 'XAF' => array('s' => 'CFA','n' => 'Central African CFA franc'), 'XCD' => array('s' => '$','n' => 'East Caribbean dollar'), 'XOF' => array('s' => 'CFA','n' => 'West African CFA franc'), 'XPF' => array('s' => 'Fr','n' => 'CFP franc'), 'YER' => array('s' => '﷼','n' => 'Yemeni rial'), 'ZAR' => array('s' => 'R','n' => 'South African rand'), 'ZMW' => array('s' => 'ZK','n' => 'Zambian kwacha') ); // Sort by name if($sort_by_name) { uasort($currencies, function ($currency_1, $currency_2) { return ($currency_1['n'] == $currency_2['n']) ? 0 : (($currency_1['n'] < $currency_2['n']) ? -1 : 1); }); } // Apply filter // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- All hooks prefixed with wsf_ $currencies = apply_filters('wsf_config_currencies', $currencies); return $currencies; } public static function get_ecommerce() { // Check cache if(self::$ecommerce !== false) { return self::$ecommerce; } $ecommerce = array( 'cart_price_types' => array( 'subtotal' => array('label' => __('Subtotal', 'ws-form'), 'priority' => 10, 'multiple' => false, 'render' => true), 'shipping' => array('label' => __('Shipping', 'ws-form'), 'priority' => 20), 'discount' => array('label' => __('Discount', 'ws-form'), 'priority' => 30), 'handling_fee' => array('label' => __('Handling Fee', 'ws-form'), 'priority' => 40), 'shipping_discount' => array('label' => __('Shipping Discount', 'ws-form'), 'priority' => 50), 'insurance' => array('label' => __('Insurance', 'ws-form'), 'priority' => 60), 'gift_wrap' => array('label' => __('Gift Wrap', 'ws-form'), 'priority' => 70), 'other' => array('label' => __('Other', 'ws-form'), 'priority' => 80), 'tax' => array('label' => __('Tax', 'ws-form'), 'priority' => 100) ), 'status' => array( 'new' => array('label' => __('New', 'ws-form')), 'pending_payment' => array('label' => __('Pending Payment', 'ws-form')), 'processing' => array('label' => __('Processing', 'ws-form')), 'active' => array('label' => __('Active', 'ws-form')), 'cancelled' => array('label' => __('Cancelled', 'ws-form')), 'authorized' => array('label' => __('Authorized', 'ws-form')), 'completed' => array('label' => __('Completed', 'ws-form')), 'failed' => array('label' => __('Failed', 'ws-form')), 'refunded' => array('label' => __('Refunded', 'ws-form')), 'voided' => array('label' => __('Voided', 'ws-form')) ), 'meta_keys' => array( 'ecommerce_cart_total' => array('label' => __('Total', 'ws-form'), 'type' => 'price', 'priority' => 200), 'ecommerce_status' => array('label' => __('Order Status', 'ws-form'), 'lookup' => 'status', 'priority' => 5), 'ecommerce_transaction_id' => array('label' => __('Transaction ID', 'ws-form'), 'priority' => 1010), 'ecommerce_payment_method' => array('label' => __('Payment Method', 'ws-form'), 'priority' => 1020) ) ); // Apply filter // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- All hooks prefixed with wsf_ $ecommerce = apply_filters('wsf_config_ecommerce', $ecommerce); // Cache self::$ecommerce = $ecommerce; return $ecommerce; } public static function get_options_language() { return array( array('value' => '', 'text' => 'Auto Detect'), array('value' => 'ar', 'text' => 'Arabic'), array('value' => 'af', 'text' => 'Afrikaans'), array('value' => 'am', 'text' => 'Amharic'), array('value' => 'hy', 'text' => 'Armenian'), array('value' => 'az', 'text' => 'Azerbaijani'), array('value' => 'eu', 'text' => 'Basque'), array('value' => 'bn', 'text' => 'Bengali'), array('value' => 'bg', 'text' => 'Bulgarian'), array('value' => 'ca', 'text' => 'Catalan'), array('value' => 'zh-HK', 'text' => 'Chinese (Hong Kong)'), array('value' => 'zh-CN', 'text' => 'Chinese (Simplified)'), array('value' => 'zh-TW', 'text' => 'Chinese (Traditional)'), array('value' => 'hr', 'text' => 'Croatian'), array('value' => 'cs', 'text' => 'Czech'), array('value' => 'da', 'text' => 'Danish'), array('value' => 'nl', 'text' => 'Dutch'), array('value' => 'en-GB', 'text' => 'English (UK)'), array('value' => 'en', 'text' => 'English (US)'), array('value' => 'et', 'text' => 'Estonian'), array('value' => 'fil', 'text' => 'Filipino'), array('value' => 'fi', 'text' => 'Finnish'), array('value' => 'fr', 'text' => 'French'), array('value' => 'fr-CA', 'text' => 'French (Canadian)'), array('value' => 'gl', 'text' => 'Galician'), array('value' => 'ka', 'text' => 'Georgian'), array('value' => 'de', 'text' => 'German'), array('value' => 'de-AT', 'text' => 'German (Austria)'), array('value' => 'de-CH', 'text' => 'German (Switzerland)'), array('value' => 'el', 'text' => 'Greek'), array('value' => 'gu', 'text' => 'Gujarati'), array('value' => 'iw', 'text' => 'Hebrew'), array('value' => 'hi', 'text' => 'Hindi'), array('value' => 'hu', 'text' => 'Hungarian'), array('value' => 'is', 'text' => 'Icelandic'), array('value' => 'id', 'text' => 'Indonesian'), array('value' => 'it', 'text' => 'Italian'), array('value' => 'ja', 'text' => 'Japanese'), array('value' => 'kn', 'text' => 'Kannada'), array('value' => 'ko', 'text' => 'Korean'), array('value' => 'lo', 'text' => 'Laothian'), array('value' => 'lv', 'text' => 'Latvian'), array('value' => 'lt', 'text' => 'Lithuanian'), array('value' => 'ms', 'text' => 'Malay'), array('value' => 'ml', 'text' => 'Malayalam'), array('value' => 'mr', 'text' => 'Marathi'), array('value' => 'mn', 'text' => 'Mongolian'), array('value' => 'no', 'text' => 'Norwegian'), array('value' => 'fa', 'text' => 'Persian'), array('value' => 'pl', 'text' => 'Polish'), array('value' => 'pt', 'text' => 'Portuguese'), array('value' => 'pt-BR', 'text' => 'Portuguese (Brazil)'), array('value' => 'pt-PT', 'text' => 'Portuguese (Portugal)'), array('value' => 'ro', 'text' => 'Romanian'), array('value' => 'ru', 'text' => 'Russian'), array('value' => 'sr', 'text' => 'Serbian'), array('value' => 'si', 'text' => 'Sinhalese'), array('value' => 'sk', 'text' => 'Slovak'), array('value' => 'sl', 'text' => 'Slovenian'), array('value' => 'es', 'text' => 'Spanish'), array('value' => 'es-419', 'text' => 'Spanish (Latin America)'), array('value' => 'sw', 'text' => 'Swahili'), array('value' => 'sv', 'text' => 'Swedish'), array('value' => 'ta', 'text' => 'Tamil'), array('value' => 'te', 'text' => 'Telugu'), array('value' => 'th', 'text' => 'Thai'), array('value' => 'tr', 'text' => 'Turkish'), array('value' => 'uk', 'text' => 'Ukrainian'), array('value' => 'ur', 'text' => 'Urdu'), array('value' => 'vi', 'text' => 'Vietnamese'), array('value' => 'zu', 'text' => 'Zul') ); } }1.5-1.3 3-4.2.7.7c.4.8-.7 2.4-1.5 3.6zM15.9 28.1h.1l.4-.6.8-1.3v-.1l1-1.7v-.1h-.1l-6.2-4h-.1v.1l-2 3v.1l.1.1 6 4.5zm-4-7.7l6 3.9-.9 1.6v.1l-.8 1.3-.3.5a135 135 0 01-5.9-4.6l1.9-2.8zM28.8 37.3l-11-8 .5-.8.8-1.4.9-1.5 16 10.6a104 104 0 00-1.6 3.7h.2l1.6-3.7v-.1h-.1L19.9 25.4l-.1-.1v.1l-.9 1.6-.8 1.4-.5.8v.1l.1.1 11.1 8.1 3.5 2.5h.3l-3.8-2.7z"/>', $field_x, $label_offset_y, ($field_width / 150), (($field_height * 4) / 40), esc_attr($ws_form_css->color_default_lighter), $ws_form_css->border_width, $field_width, ($field_height * 4), esc_attr($ws_form_css->color_primary), (($field_width / 2) - 8) ); // Add to SVG array $svg_single = array('svg' => $svg_field, 'height' => $label_offset_y + ($field_height * 4)); break; case 'texteditor' : case 'html' : // Rectangle $svg_field .= sprintf( '', $field_x, $label_offset_y, esc_attr( $ws_form_css->color_default_inverted ), esc_attr( $ws_form_css->color_default_lighter ), $ws_form_css->border_width, $ws_form_css->border_radius, $field_width, $field_height * 2 ); // Label $svg_field .= sprintf( '%s', esc_attr( $ws_form_css->color_default ), $label_inside_x, $label_inside_y, $field['label'] ); // Add to SVG array $svg_single = array('svg' => $svg_field, 'height' => $label_offset_y + ($field_height * 2)); break; case 'recaptcha' : case 'hcaptcha' : case 'turnstile' : // Rectangle $svg_field .= sprintf( '', $field_x, $label_offset_y, $field_width, $field_height * 2 ); $checkbox_x = is_rtl() ? ( $field_x + $field_width - ( $field_height + ( $field_height / 2 ) ) ) : $field_x + ( $field_height / 2 ); $label_x = is_rtl() ? ( $field_x + $field_width - ( $field_height * 2 ) ) : $field_x + ( $field_height * 2 ); // Checkbox $svg_field .= sprintf( '', $checkbox_x, $label_offset_y + ( $field_height / 2 ), $field_height, $field_height ); // Label $svg_field .= sprintf( 'I\'m not a robot', $label_x, $label_inside_y + ( $field_height / 2 ) ); // Add to SVG array $svg_single = array( 'svg' => $svg_field, 'height' => $label_offset_y + ( $field_height * 2 ) ); break; case 'divider' : // Divider - Line $svg_field .= sprintf( '', $field_x, $field_x + $field_width, $label_offset_y + ( $field_height / 2 ), $label_offset_y + ( $field_height / 2 ), esc_attr( $ws_form_css->color_default_lighter ), $ws_form_css->border_width ); // Add to SVG array $svg_single = array( 'svg' => $svg_field, 'height' => $label_offset_y + $field_height ); break; case 'spacer' : // Add to SVG array $svg_single = array('svg' => '', 'height' => $field_height); break; case 'section_icons' : // Section Icons - Path + $svg_field .= sprintf( '', $field_x + ( is_rtl() ? ( $field_height + 3 ) : 0 ), $label_offset_y ); // Section Icons - Path - $svg_field .= sprintf( '', $field_x + ( is_rtl() ? 0 : ( $field_height + 3 ) ), $label_offset_y ); // Add to SVG array $svg_single = array( 'svg' => $svg_field, 'height' => $label_offset_y + $field_height ); break; case 'color' : // Color - Random Fill $rect_fill = sprintf( '#%06X', wp_rand( 0, 0xFFFFFF ) ); $rect_x = is_rtl() ? ( $field_x + $field_width - $field_height ) : $field_x; // Default - Rectangle $svg_field .= sprintf( '', $field_x, $label_offset_y, esc_attr( $ws_form_css->color_default_inverted ), esc_attr( $ws_form_css->color_default_lighter ), $ws_form_css->border_width, $ws_form_css->border_radius, $field_width, $field_height ); // Color - Rectangle $svg_field .= sprintf( '', $rect_x, $label_offset_y, esc_attr( $rect_fill ), esc_attr( $ws_form_css->color_default_lighter ), $ws_form_css->border_width, $ws_form_css->border_radius, $field_height, $field_height ); // Add to SVG array $svg_single = array( 'svg' => $svg_field, 'height' => $label_offset_y + $field_height ); break; case 'checkbox' : case 'price_checkbox' : $rect_x = is_rtl() ? ( $svg_width - $field_x - $field_height ) : $field_x; // Checkbox - Rectangle $svg_field .= sprintf( '', $rect_x, esc_attr( $ws_form_css->color_default_inverted ), esc_attr( $ws_form_css->color_default_lighter ), $ws_form_css->border_width, $ws_form_css->border_radius, $field_height, $field_height ); // Add to SVG array $svg_single = array( 'svg' => $svg_field, 'height' => $field_height ); break; case 'radio' : case 'price_radio' : $circle_x = ( is_rtl() ? ( $svg_width - $field_x - $field_height ) : $field_x ) + ( $field_height / 2 ); // Radio - Circle $svg_field .= sprintf( '', $circle_x, $field_height / 2, esc_attr( $ws_form_css->color_default_inverted ), esc_attr( $ws_form_css->color_default_lighter ), $ws_form_css->border_width, $field_height / 2 ); // Add to SVG array $svg_single = array( 'svg' => $svg_field, 'height' => $field_height ); break; case 'file' : $button_width = $field_width / 3; $button_xpos = is_rtl() ? ( $field_x + $field_width - $button_width ) : $field_x; $label_button_x = $button_xpos + ( $button_width / 2 ); // File - Rectangle - Outer $svg_field .= sprintf( '', $field_x, $label_offset_y, esc_attr( $ws_form_css->color_default_inverted ), esc_attr( $ws_form_css->color_default_lighter ), $ws_form_css->border_width, $ws_form_css->border_radius, $field_width, $field_height ); // File - Rectangle - Button $svg_field .= sprintf( '', $button_xpos, $label_offset_y, esc_attr( $ws_form_css->color_default_lightest ), esc_attr( $ws_form_css->color_default_lighter ), $ws_form_css->border_width, $ws_form_css->border_radius, $button_width, $field_height ); // File - Text - Button $svg_field .= sprintf( 'Choose File', esc_attr( $ws_form_css->color_default ), $label_button_x, $label_offset_y + $label_inside_y ); // Add to SVG array $svg_single = array( 'svg' => $svg_field, 'height' => $label_offset_y + $field_height ); break; default : // Default - Rectangle $svg_field .= sprintf( '', $field_x, $label_offset_y, esc_attr( $ws_form_css->color_default_inverted ), esc_attr( $ws_form_css->color_default_lighter ), $ws_form_css->border_width, $ws_form_css->border_radius, $field_width, $field_height ); // Add to SVG array $svg_single = array( 'svg' => $svg_field, 'height' => $label_offset_y + $field_height ); } } if($svg_single['svg'] !== false) { $svg_array[] = $svg_single; } // Col index $col_index += $field_size_columns + $field_offset_columns; if($col_index >= $col_index_max) { // Process row $get_svg_row_return = self::get_svg_row($svg_array); // Return row $svg .= sprintf('%s', $offset_y, $get_svg_row_return['svg']); // Work out position of offset_x and offset_y $row_height = $get_svg_row_return['height']; $offset_y += $row_height + (($row_height > 0) ? $row_spacing : 0); // Reset for next row $col_index = 0; $svg_array = array(); $offset_x = $origin_x; } else { $offset_x += $field_width + $gutter_width; } // Stop rendering if we're over the bottom edge if($offset_y > $svg_height) { break; } } // Add last row if ( count( $svg_array ) > 0 ) { // Process row $get_svg_row_return = self::get_svg_row( $svg_array ); // Return row $svg .= sprintf( '%s', $offset_y, $get_svg_row_return['svg'] ); } // Left rectangle $svg .= sprintf( '', $origin_x - 1, $svg_height, esc_attr( $ws_form_css->color_form_background ) ); // Right rectangle $svg .= sprintf( '', ( $svg_width - $origin_x ) + 1, $origin_x, $svg_height, esc_attr( $ws_form_css->color_form_background ) ); // Bottom rectangles $svg .= sprintf( '', $svg_height - $gradient_height - $origin_x, $svg_width, $gradient_height, esc_attr( $gradient_id ) ); $svg .= sprintf( '', $svg_height - $origin_x, $svg_width, $origin_x + 1, esc_attr( $ws_form_css->color_form_background ) ); // End of SVG $svg .= ''; return $svg; } // Get SVG row public function get_svg_row($svg_array) { $svg = ''; $height = 0; // Get overall height foreach($svg_array as $svg_field) { $svg_field_height = $svg_field['height']; if($svg_field_height > $height) { $height = $svg_field_height; } } // Build SVG foreach($svg_array as $svg_field) { $svg_field_svg = $svg_field['svg']; $svg_field_height = $svg_field['height']; $svg .= sprintf('%s', ($height - $svg_field_height), $svg_field_svg); } return array('svg' => $svg, 'height' => $height); } // Style resolve public function db_style_resolve($bypass_user_capability_check = false) { global $wpdb; // Meta $ws_form_meta = new WS_Form_Meta(); $ws_form_meta->object = 'form'; // Style $ws_form_style = new WS_Form_Style(); // Get all forms with missing or invalid style_id meta values // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom database table $forms = $wpdb->get_results("SELECT f.id FROM {$wpdb->prefix}wsf_form f LEFT JOIN {$wpdb->prefix}wsf_form_meta m ON m.parent_id = f.id AND m.meta_key = 'style_id' LEFT JOIN {$wpdb->prefix}wsf_style s ON (m.meta_value = s.id OR m.meta_value = 0) AND s.status = 'publish' WHERE m.id IS NULL OR s.id IS NULL;"); if($forms) { $meta = array( 'style_id' => 0 // Style ID of 0 will use the default style ); foreach($forms as $form) { $ws_form_meta->parent_id = $form->id; $ws_form_meta->db_update_from_array($meta, false, $bypass_user_capability_check); } } } // Style ID to zero (Used by style db_default method) public function style_id_to_zero($old_style_id) { global $wpdb; // Meta $ws_form_meta = new WS_Form_Meta(); $ws_form_meta->object = 'form'; // Set all forms with style ID of $old_style_id to 0 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom database table $wpdb->query($wpdb->prepare( "UPDATE {$wpdb->prefix}wsf_form_meta SET meta_value = 0 WHERE meta_key = 'style_id' AND meta_value = %d AND parent_id IN (SELECT id FROM {$wpdb->prefix}wsf_form);", // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQueryUse -- Has IN $old_style_id )); } // Style ID conversational to zero (Used by style db_default method) public function style_id_conv_to_zero($old_style_id_conv) { global $wpdb; // Meta $ws_form_meta = new WS_Form_Meta(); $ws_form_meta->object = 'form'; // Set all forms with style ID conv of $old_style_id_conv to 0 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom database table $wpdb->query($wpdb->prepare( "UPDATE {$wpdb->prefix}wsf_form_meta SET meta_value = 0 WHERE meta_key = 'style_id_conv' AND meta_value = %d AND parent_id IN (SELECT id FROM {$wpdb->prefix}wsf_form);", // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQueryUse -- Has IN $old_style_id_conv )); } // Check if action row ID is permitted for form object (For conditional logic Run Immediately) public function action_row_id_permitted($form_object, $row_id_filter) { // Get conditional logic $conditional = WS_Form_Common::get_object_meta_value($form_object, 'conditional', false); // Validate conditional logic if( !is_object($conditional) || !isset($conditional->groups) || !is_array($conditional->groups) || (count($conditional->groups) == 0) || !isset($conditional->groups[0]) || !is_object($conditional->groups[0]) || !isset($conditional->groups[0]->rows) || !is_array($conditional->groups[0]->rows) || (count($conditional->groups[0]->rows) == 0) ) { return false; } // Process rows foreach($conditional->groups[0]->rows as $row) { if( !is_object($row) || !isset($row->data) || !is_array($row->data) || !isset($row->data[1]) ) { continue; } $data_json = $row->data[1]; $data = json_decode($data_json); if( empty($data) || !is_object($data) || !isset($data->then) || !is_array($data->then) || !isset($data->else) || !is_array($data->else) ) { continue; } // Check then if(self::action_row_id_permitted_then_else($data->then, $row_id_filter)) { return true; } // Check else if(self::action_row_id_permitted_then_else($data->else, $row_id_filter)) { return true; } } return false; } // Check then or else statement to see if action row ID is present public function action_row_id_permitted_then_else($then_else_array, $row_id_filter) { foreach($then_else_array as $then_else) { if( !isset($then_else->object) || ($then_else->object !== 'action') || !isset($then_else->object_id) || !isset($then_else->action) || ($then_else->action !== 'action_run') ) { continue; } if($then_else->object_id == $row_id_filter) { return true; } } return false; } // Is valid public function is_valid($form_object) { return ( is_object($form_object) && property_exists($form_object, 'id') && property_exists($form_object, 'label') ); } }$meta_new[$field_name])) { // We don't store the fallback data to the database, it is just made available to any actions that need it $meta_new[$field_name]['db_ignore'] = true; // Set repeatable index to false $meta_new[$field_name]['repeatable_index'] = false; // Replace $this->meta[$field_name] = $submit_object->meta[$field_name] = $meta_new[$field_name]; } } // Rebuild section_repeatable if($section_repeatable_edited) { $this->section_repeatable = $submit_object->section_repeatable = ($section_repeatable_serialized ? serialize($section_repeatable_array) : $section_repeatable_array); } } return $submit_object; } // Handle server side error - Invalid feedback public function db_throw_error_field_invalid_feedback($field_id, $section_repeatable_index, $message) { // Only process first error for field if(isset($this->error_validation_actions[$field_id])) { return; } $this->error_validation_actions[$field_id] = array( 'action' => 'field_invalid_feedback', 'field_id' => $field_id, 'section_repeatable_index' => $section_repeatable_index, 'message' => $message ); } // Find submit meta value by type (first_name, last_name, email) public function find_field_value($field_type) { $fields = \WS_Form_Common::get_fields_from_form( $this->form_object, true ); switch($field_type) { case 'first_name': $possible_matches = [ 'first name', 'firstname', 'given name', 'forename' ]; break; case 'last_name': $possible_matches = [ 'last name', 'lastname', 'surname', 'family name' ]; break; case 'email': $possible_matches = []; break; default: return false; } $is_full_name = false; // Look for specific first, last or email type $field_id = self::find_field_value_process($fields, $field_type, $possible_matches); // If not found, look for possible full name matches if( ($field_id === false) && in_array($field_type, array('first_name', 'last_name')) ) { $possible_matches = [ 'full name', 'your name', 'name' ]; $field_id = self::find_field_value_process($fields, $field_type, $possible_matches); $is_full_name = true; } if($field_id === false) { return false; } // Build meta key and get value $meta_key = sprintf( 'field_%u', $field_id ); $value = trim( \WS_Form_Action::get_submit_value( $this, $meta_key ) ); // Handle full name field using existing parser if ( $is_full_name ) { $components = \WS_Form_Common::get_full_name_components( $value ); switch ( $field_type ) { case 'first_name': return !empty( $components['name_first'] ) ? $components['name_first'] : false; case 'last_name': return !empty( $components['name_last'] ) ? $components['name_last'] : false; default: return false; } } return $value ?: false; } public function find_field_value_process($fields, $field_type, $possible_matches) { $field_id = false; foreach ( $fields as $field ) { if ( empty( $field->type ) ) { continue; } // Handle email field if ( $field_type === 'email' ) { if($field->type === 'email') { $field_id = $field->id; break; } continue; } // Handle text-based fields for name detection if ( $field->type === 'text' ) { $label = strtolower( trim( $field->label ?? '' ) ); foreach ( $possible_matches as $match ) { if ( preg_match( '/\b' . preg_quote( $match, '/' ) . '\b/', $label ) ) { $field_id = $field->id; break 2; } } } } return $field_id; } // Send error notification public function report_submit_error_send($e = 'test') { // Check for test send if($e === 'test') { $test = true; $form_id = 123; $form_label = __('Test form label', 'ws-form'); $form_url = '#'; $message = __('Test message', 'ws-form'); $code = __('Test code', 'ws-form'); $file = __('Test file', 'ws-form'); $line = __('Test line', 'ws-form'); $trace = __('Test trace', 'ws-form'); } else { $test = false; // Check for error object if(is_object($e)) { $message = method_exists($e, 'getMessage') ? $e->getMessage() :false; $code = method_exists($e, 'getCode') ? $e->getCode() : false; $file = method_exists($e, 'getFile') ? $e->getFile() : false; $line = method_exists($e, 'getLine') ? $e->getLine() : false; $trace = method_exists($e, 'getTraceAsString') ? $e->getTraceAsString() : false; } else { $message = $code = $file = $line = $trace = false; } if(is_object($this->form_object)) { $form_id = $this->form_object->id; $form_label = $this->form_object->label; $form_url = WS_Form_Common::get_admin_url('ws-form-edit', $form_id); } else { $form_id = $form_label = $form_url = false; } } // Get options $frequency = WS_Form_Common::option_get('report_submit_error_frequency', 'minute'); if(empty($frequency)) { $frequency = 'minute'; } $email_to = WS_Form_Common::option_get('report_submit_error_email_to', get_bloginfo('admin_email')); if(empty($email_to)) { $email_to = get_bloginfo('admin_email'); } $email_subject = WS_Form_Common::option_get('report_submit_error_email_subject', __('WS Form - Form Submission Error', 'ws-form')); if(empty($email_subject)) { $email_subject = __('WS Form - Form Submission Error', 'ws-form'); } // Parse options $email_to = trim(WS_Form_Common::parse_variables_process($email_to, false, false, 'text/plain')); $email_subject = trim(WS_Form_Common::parse_variables_process($email_subject, false, false, 'text/plain')); // Split email addresses if(strpos($email_to, ' ') !== false) { $email_to_array = explode(' ', $email_to); } else { $email_to_array = explode(',', $email_to); } // Check options if(!in_array($frequency, array('all', 'minute', 'hour', 'day'))) { parent::db_throw_error(__('Invalid frequency', 'ws-form')); } foreach($email_to_array as $email_to) { if(!filter_var($email_to, FILTER_VALIDATE_EMAIL)) { parent::db_throw_error(sprintf( /* translators: %s: Email address */ __('Invalid email address: %s', 'ws-form'), $email_to )); } } if(empty($email_subject)) { parent::db_throw_error(__('Invalid email subject', 'ws-form')); } // Check when error notification was last sent if($frequency != 'all') { $report_submit_error_last = WS_Form_Common::option_get('report_submit_error_last', false); if(!empty($report_submit_error_last)) { // Get time of last error $report_submit_error_last_time = absint($report_submit_error_last['time']); // Get time delta $report_submit_error_last_delta = time() - $report_submit_error_last_time; // Get time delta max switch($frequency) { case 'day' : $report_submit_error_last_delta_max = 86400; break; case 'hour' : $report_submit_error_last_delta_max = 3600; break; default : $report_submit_error_last_delta_max = 60; break; } // Check delta, if too soon, do not proceed if($report_submit_error_last_delta < $report_submit_error_last_delta_max) { return false; } } } // Build email message // URL $email_message = sprintf( '

%1$s: %2$s', __('URL', 'ws-form'), WS_Form_Common::get_referrer() ); // Build date range $date_format = get_option('date_format'); if( ($form_url !== false) && ($form_label !== false) ) { $email_message .= sprintf( '

%s: %s', __('Form', 'ws-form'), $form_url, esc_html($form_label) ); } // Build error table if( ($message !== false) || ($code !== false) || ($file !== false) || ($line !== false) || ($trace !== false) ) { $email_message .= ''; // Message if($message !== false) { $email_message .= sprintf('', __('Message', 'ws-form'), esc_html($message)); } // File if($file !== false) { $email_message .= sprintf('', __('File', 'ws-form'), esc_html($file)); } // Line if($line !== false) { $email_message .= sprintf('', __('Line', 'ws-form'), esc_html($line)); } // Code if($code !== false) { $email_message .= sprintf('', __('Code', 'ws-form'), esc_html($code)); } // Trace if($trace !== false) { $email_message .= sprintf('', __('Trace', 'ws-form'), esc_html($trace)); } $email_message .= '
%s%s
%s%s
%s%s
%s%s
%s
%s
'; } else { $email_message .= sprintf( '

%s

', __('An unknown error occurred.', 'ws-form') ); $email_message .= ''; // Type $email_message .= sprintf('', __('Type', 'ws-form'), esc_html(gettype($e))); // Variable // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r -- Intentional use of print_r to build error string $email_message .= sprintf('', __('Variable', 'ws-form'), esc_html(print_r($e, true))); $email_message .= '
%s%s
%s%s
'; } // Get email template $email_template = WS_Form_File::file_get_contents(sprintf('%sincludes/templates/email/html/error.html', WS_FORM_PLUGIN_DIR_PATH)); // Parse email template $mask_values = array( 'email_subject' => esc_html($email_subject), 'email_title' => __('Form Submission Error', 'ws-form'), 'email_message' => $email_message ); $wp_mail_message = WS_Form_Common::mask_parse($email_template, $mask_values); // Build headers $headers = array( 'Content-Type: text/html' ); // Send email wp_mail($email_to_array, $email_subject, $wp_mail_message, $headers); // Store last error if(!$test) { WS_Form_Common::option_set('report_submit_error_last', array( 'time' => time(), 'form_id' => $form_id, 'form_label' => $form_label, 'message' => $message, 'code' => $code, 'file' => $file, 'line' => $line, 'trace' => $trace )); } } // Remove protected meta data public function db_remove_meta_protected() { $this->meta_protected = array(); } // Compact public function db_compact() { // Remove form_object if(isset($this->form_object)) { unset($this->form_object); } if(isset($this->field_types)) { unset($this->field_types); } } // Create hash public function db_create_hash() { if($this->hash == '') { $this->hash = esc_sql(wp_hash($this->id . '_' . $this->form_id . '_' . time() . '_' . wp_rand())); } // Check hash if(!WS_Form_Common::check_submit_hash($this->hash)) { self::return_forbidden(); } return $this->hash; } // Create token public function db_create_token() { if(!WS_Form_Common::check_submit_hash($this->hash)) { self::return_forbidden(); } if($this->token == '') { $this->token = esc_sql(wp_hash($this->id . '_' . $this->form_id . '_' . $this->token . '_' . time() . '_' . wp_rand())); } // Check hash if(!WS_Form_Common::check_submit_hash($this->token)) { self::return_forbidden(); } return $this->token; } // Check form id public function db_check_form_id() { if(absint($this->form_id) === 0) { parent::db_throw_error(__('Invalid form ID (WS_Form_Submit | db_check_form_id)', 'ws-form')); } return true; } // Check id public function db_check_id() { if(absint($this->id) === 0) { parent::db_throw_error(__('Invalid submit ID (WS_Form_Submit | db_check_id)', 'ws-form')); } return true; } // Is valid public function is_valid($submit_object) { return ( is_object($submit_object) && property_exists($submit_object, 'id') ); } }