PluginProbe ʕ •ᴥ•ʔ
WooCommerce / 9.9.5
WooCommerce v9.9.5
10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 7.8.0-beta.1 7.8.0-beta.2 7.8.0-rc.1 7.8.0-rc.2 7.8.1 7.8.2 7.8.3 7.8.4 7.9.0 7.9.0-beta.1 7.9.0-beta.2 7.9.0-rc.2 7.9.0-rc.3 7.9.1 7.9.2 8.0.0 8.0.0-beta.1 8.0.0-beta.2 8.0.0-rc.1 8.0.0-rc.2 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.1.0 8.1.0-beta.1 8.1.0-rc.1 8.1.0-rc.2 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 8.2.0-beta.1 8.2.0-rc.1 8.2.0-rc.2 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.3.0 8.3.0-beta.1 8.3.0-rc.1 8.3.0-rc.2 8.3.1 8.3.2 8.3.3 8.3.4 8.4.0 8.4.0-beta.1 8.4.0-rc.1 8.4.1 8.4.2 8.4.3 8.5.0 8.5.0-beta.1 8.5.0-rc.1 8.5.1 8.5.2 8.5.3 8.5.4 8.5.5 8.6.0 8.6.0-beta.1 8.6.0-rc.1 8.6.1 8.6.2 8.6.3 8.6.4 8.7.0 8.7.0-beta.1 8.7.0-beta.2 8.7.0-rc.1 8.7.1 8.7.2 8.7.3 8.8.0 8.8.0-beta.1 8.8.0-rc.1 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.8.6 8.8.7 8.9.0 8.9.0-beta.1 8.9.0-rc.1 8.9.1 8.9.2 8.9.3 8.9.4 8.9.5 9.0.0 9.0.0-beta.1 9.0.0-beta.2 9.0.0-rc.1 9.0.1 9.0.2 9.0.3 9.0.4 9.1.0 9.1.0-beta.1 9.1.0-rc.1 9.1.1 9.1.2 9.1.3 9.1.4 9.1.5 9.1.6 9.2.0 9.2.0-beta.1 9.2.0-rc.1 9.2.1 9.2.2 9.2.3 9.2.4 9.2.5 9.3.0 9.3.0-beta.1 9.3.0-rc.1 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.3.6 9.4.0 9.4.0-beta.1 9.4.0-beta.2 9.4.0-rc.1 9.4.0-rc.2 9.4.0-rc.3 9.4.0-rc.4 9.4.1 9.4.2 9.4.3 9.4.4 9.4.5 9.5.0 9.5.0-beta.1 9.5.0-beta.2 9.5.0-rc.1 9.5.1 9.5.2 9.5.3 9.5.4 9.6.0 9.6.0-beta.1 9.6.0-beta.2 9.6.0-rc.1 9.6.1 9.6.2 9.6.3 9.6.4 9.7.0 9.7.0-beta.1 9.7.0-rc.1 9.7.1 9.7.2 9.7.3 9.8.0 9.8.0-beta.1 9.8.0-rc.1 9.8.1 9.8.2 9.8.3 9.8.4 9.8.5 9.8.6 9.8.7 9.9.0 9.9.0-beta.1 9.9.0-rc.1 9.9.1 9.9.2 9.9.3 9.9.4 9.9.5 9.9.6 9.9.7 3.7.3 7.1.2 3.8.0 7.2.0 3.8.0-beta.1 7.2.0-beta.1 3.8.0-rc.1 7.2.0-beta.2 3.8.0-rc.2 7.2.0-rc.1 3.8.1 7.2.0-rc.2 3.8.2 7.2.1 3.8.3 7.2.2 3.9.0 7.2.3 3.9.0-beta.1 7.2.4 3.9.0-beta.2 7.3.0 3.9.0-rc.1 7.3.0-beta.1 3.9.0-rc.2 7.3.0-beta.2 3.9.0-rc.3 7.3.0-rc.1 3.9.0-rc.4 7.3.0-rc.2 3.9.1 7.3.1 3.9.2 7.4.0 3.9.3 7.4.0-beta.1 3.9.4 7.4.0-beta.2 3.9.5 7.4.0-rc.1 4.0.0 7.4.0-rc.2 4.0.0-beta.1 7.4.1 4.0.0-rc.1 7.4.2 4.0.0-rc.2 7.5.0 4.0.1 7.5.0-beta.1 4.0.2 7.5.0-beta.2 4.0.3 7.5.0-rc.1 4.0.4 7.5.1 4.1.0 7.5.2 4.1.0-beta.1 7.6.0 4.1.0-beta.2 7.6.0-beta.1 4.1.0-rc.1 7.6.0-beta.2 4.1.0-rc.2 7.6.0-rc.1 4.1.1 7.6.0-rc.2 4.1.2 7.6.0-rc.3 4.1.3 7.6.1 4.1.4 7.6.2 4.2.0 7.7.0 4.2.0-RC.1 7.7.0-beta.1 4.2.0-RC.2 7.7.0-beta.2 4.2.0-beta.1 7.7.0-rc.1 4.2.1 7.7.1 4.2.2 7.7.2 4.2.3 7.7.3 4.2.4 7.8.0 4.2.5 4.3.0 4.3.0-beta.1 4.3.0-rc.1 4.3.0-rc.2 4.3.0-rc.3 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.4.0 4.4.0-beta.1 4.4.0-rc.1 4.4.1 4.4.2 4.4.3 4.4.4 4.5.0 4.5.0-beta.1 4.5.0-rc.1 4.5.0-rc.3 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.6.0-beta.1 4.6.0-rc.1 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.7.0 4.7.0-beta.1 4.7.0-beta.2 4.7.0-rc.1 4.7.1 4.7.1-beta.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.0-beta.1 4.8.0-rc.1 4.8.0-rc.2 4.8.1 4.8.2 4.8.3 4.9.0 4.9.0-beta.1 4.9.0-rc.1 4.9.0-rc.2 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 5.0.0 5.0.0-beta.1 5.0.0-beta.2 5.0.0-rc.1 5.0.0-rc.2 5.0.0-rc.3 5.0.1 5.0.2 5.0.3 5.1.0 5.1.0-beta.1 5.1.0-rc.1 trunk 5.1.1 10.0.0 5.1.2 10.0.0-rc.1 5.1.3 10.0.0-rc.2 5.2.0 10.0.1 5.2.0-beta.1 10.0.2 5.2.0-rc.1 10.0.3 5.2.0-rc.2 10.0.4 5.2.1 10.0.5 5.2.2 10.0.6 5.2.3 10.1.0 5.2.4 10.1.0-rc.1 5.2.5 10.1.0-rc.2 5.3.0 10.1.0-rc.3 5.3.0-beta.1 10.1.0-rc.4 5.3.0-rc.1 10.1.1 5.3.0-rc.2 10.1.2 5.3.1 10.1.3 5.3.2 10.1.4 5.3.3 10.2.0 5.4.0 10.2.0-beta.1 5.4.0-beta.1 10.2.0-beta.2 5.4.0-rc.1 10.2.0-rc.1 5.4.1 10.2.1 5.4.2 10.2.2 5.4.3 10.2.3 5.4.4 10.2.4 5.4.5 10.3.0 5.5.0 10.3.0-beta.1 5.5.0-beta.1 10.3.0-beta.2 5.5.0-rc.1 10.3.0-rc.1 5.5.0-rc.2 10.3.0-rc.2 5.5.1 10.3.1 5.5.2 10.3.2 5.5.3 10.3.3 5.5.4 10.3.4 5.5.5 10.3.5 5.6.0 10.3.6 5.6.0-beta.1 10.3.7 5.6.0-rc.1 10.3.8 5.6.0-rc.2 10.4.0 5.6.1 10.4.0-beta.1 5.6.2 10.4.0-beta.2 5.6.3 10.4.0-rc.1 5.7.0 10.4.1 5.7.0-beta.1 10.4.2 5.7.0-rc.1 10.4.3 5.7.1 10.4.4 5.7.2 10.5.0 5.7.3 10.5.0-beta.1 5.8.0 10.5.0-beta.2 5.8.0-beta.1 10.5.0-rc.1 5.8.0-beta.2 10.5.0-rc.2 5.8.0-rc.1 10.5.0-rc.3 5.8.1 10.5.1 5.8.2 10.5.2 5.9.0 10.5.3 5.9.0-beta.1 10.6.0 5.9.0-rc.1 10.6.0-beta.1 5.9.0-rc.2 10.6.0-beta.2 5.9.1 10.6.0-rc.1 5.9.2 10.6.1 6.0.0 10.6.2 6.0.0-beta.1 10.7.0 6.0.0-rc.1 10.7.0-beta.1 6.0.1 10.7.0-beta.2 6.0.2 10.7.0-rc.1 6.1.0 3.0.0 6.1.0-beta.1 3.0.1 6.1.0-rc.1 3.0.2 6.1.0-rc.2 3.0.3 6.1.1 3.0.4 6.1.2 3.0.5 6.1.3 3.0.6 6.2.0 3.0.7 6.2.0-beta.1 3.0.8 6.2.0-rc.1 3.0.9 6.2.0-rc.2 3.1.0 6.2.1 3.1.1 6.2.2 3.1.2 6.2.3 3.2.0 6.3.0 3.2.1 6.3.0-beta.1 3.2.2 6.3.0-rc.1 3.2.3 6.3.0-rc.2 3.2.4 6.3.1 3.2.5 6.3.2 3.2.6 6.4.0 3.3.0 6.4.0-beta.1 3.3.1 6.4.0-rc.1 3.3.2 6.4.1 3.3.2-rc.1 6.4.2 3.3.3 6.5.0 3.3.4 6.5.0-beta.1 3.3.5 6.5.0-rc.1 3.3.6 6.5.0-rc.2 3.4.0 6.5.1 3.4.0-beta.1 6.5.2 3.4.0-rc.2 6.6.0 3.4.1 6.6.0-beta.1 3.4.2 6.6.0-rc.1 3.4.3 6.6.0-rc.2 3.4.4 6.6.1 3.4.5 6.6.2 3.4.6 6.7.0 3.4.7 6.7.0-beta.1 3.4.8 6.7.0-beta.2 3.5.0 6.7.0-rc.1 3.5.0-beta.1 6.7.1 3.5.0-rc.1 6.8.0 3.5.0-rc.2 6.8.0-beta.1 3.5.1 6.8.0-beta.2 3.5.10 6.8.0-rc.1 3.5.2 6.8.1 3.5.3 6.8.2 3.5.4 6.8.3 3.5.5 6.9.0 3.5.6 6.9.0-beta.1 3.5.7 6.9.0-beta.2 3.5.8 6.9.0-rc.1 3.5.9 6.9.1 3.6.0 6.9.2 3.6.0-beta.1 6.9.3 3.6.0-rc.1 6.9.4 3.6.0-rc.2 6.9.5 3.6.0-rc.3 7.0.0 3.6.1 7.0.0-beta.1 3.6.2 7.0.0-beta.2 3.6.3 7.0.0-beta.3 3.6.4 7.0.0-rc.1 3.6.5 7.0.0-rc.2 3.6.6 7.0.1 3.6.7 7.0.2 3.7.0 7.1.0 3.7.0-beta.1 7.1.0-beta.1 3.7.0-rc.1 7.1.0-beta.2 3.7.0-rc.2 7.1.0-rc.1 3.7.1 7.1.0-rc.2 3.7.2 7.1.1
woocommerce / includes / class-wc-countries.php
woocommerce / includes Last commit date
abstracts 11 months ago admin 11 months ago blocks 1 year ago cli 1 year ago customizer 1 year ago data-stores 1 year ago emails 11 months ago export 1 year ago gateways 1 year ago import 1 year ago integrations 2 years ago interfaces 1 year ago legacy 1 year ago libraries 1 year ago log-handlers 1 year ago payment-tokens 5 years ago product-usage 1 year ago queue 4 years ago react-admin 1 year ago rest-api 11 months ago shipping 1 year ago shortcodes 1 year ago theme-support 2 years ago tracks 1 year ago traits 5 years ago walkers 5 years ago wccom-site 1 year ago widgets 1 year ago class-wc-ajax.php 1 year ago class-wc-auth.php 1 year ago class-wc-autoloader.php 1 year ago class-wc-background-emailer.php 5 years ago class-wc-background-updater.php 5 years ago class-wc-brands-brand-settings-manager.php 1 year ago class-wc-brands-coupons.php 1 year ago class-wc-brands.php 1 year ago class-wc-breadcrumb.php 5 years ago class-wc-cache-helper.php 1 year ago class-wc-cart-fees.php 2 years ago class-wc-cart-session.php 1 year ago class-wc-cart-totals.php 1 year ago class-wc-cart.php 1 year ago class-wc-checkout.php 1 year ago class-wc-cli.php 1 year ago class-wc-comments.php 1 year ago class-wc-countries.php 1 year ago class-wc-coupon.php 1 year ago class-wc-customer-download-log.php 5 years ago class-wc-customer-download.php 1 year ago class-wc-customer.php 1 year ago class-wc-data-exception.php 8 years ago class-wc-data-store.php 3 years ago class-wc-datetime.php 4 years ago class-wc-deprecated-action-hooks.php 2 years ago class-wc-deprecated-filter-hooks.php 3 years ago class-wc-discounts.php 1 year ago class-wc-download-handler.php 1 year ago class-wc-emails.php 1 year ago class-wc-embed.php 1 year ago class-wc-form-handler.php 1 year ago class-wc-frontend-scripts.php 1 year ago class-wc-geo-ip.php 1 year ago class-wc-geolite-integration.php 6 years ago class-wc-geolocation.php 1 year ago class-wc-https.php 2 years ago class-wc-install.php 1 year ago class-wc-integrations.php 5 years ago class-wc-log-levels.php 2 years ago class-wc-logger.php 1 year ago class-wc-meta-data.php 4 years ago class-wc-order-factory.php 2 years ago class-wc-order-item-coupon.php 4 years ago class-wc-order-item-fee.php 1 year ago class-wc-order-item-meta.php 4 years ago class-wc-order-item-product.php 1 year ago class-wc-order-item-shipping.php 1 year ago class-wc-order-item-tax.php 4 years ago class-wc-order-item.php 1 year ago class-wc-order-query.php 4 years ago class-wc-order-refund.php 1 year ago class-wc-order.php 1 year ago class-wc-payment-gateways.php 1 year ago class-wc-payment-tokens.php 3 years ago class-wc-post-data.php 1 year ago class-wc-post-types.php 1 year ago class-wc-privacy-background-process.php 1 year ago class-wc-privacy-erasers.php 1 year ago class-wc-privacy-exporters.php 4 years ago class-wc-privacy.php 1 year ago class-wc-product-attribute.php 4 years ago class-wc-product-download.php 2 years ago class-wc-product-external.php 1 year ago class-wc-product-factory.php 1 year ago class-wc-product-grouped.php 1 year ago class-wc-product-query.php 1 year ago class-wc-product-simple.php 1 year ago class-wc-product-variable.php 1 year ago class-wc-product-variation.php 1 year ago class-wc-query.php 1 year ago class-wc-rate-limiter.php 4 years ago class-wc-regenerate-images-request.php 3 years ago class-wc-regenerate-images.php 1 year ago class-wc-register-wp-admin-settings.php 4 years ago class-wc-rest-authentication.php 1 year ago class-wc-rest-exception.php 5 years ago class-wc-session-handler.php 1 year ago class-wc-shipping-rate.php 1 year ago class-wc-shipping-zone.php 5 years ago class-wc-shipping-zones.php 5 years ago class-wc-shipping.php 1 year ago class-wc-shortcodes.php 1 year ago class-wc-structured-data.php 1 year ago class-wc-tax.php 2 years ago class-wc-template-loader.php 11 months ago class-wc-tracker.php 1 year ago class-wc-validation.php 2 years ago class-wc-webhook.php 1 year ago class-woocommerce.php 11 months ago wc-account-functions.php 1 year ago wc-attribute-functions.php 1 year ago wc-brands-functions.php 1 year ago wc-cart-functions.php 1 year ago wc-conditional-functions.php 1 year ago wc-core-functions.php 1 year ago wc-coupon-functions.php 1 year ago wc-deprecated-functions.php 1 year ago wc-formatting-functions.php 1 year ago wc-notice-functions.php 1 year ago wc-order-functions.php 1 year ago wc-order-item-functions.php 3 years ago wc-order-step-logger-functions.php 1 year ago wc-page-functions.php 1 year ago wc-product-functions.php 1 year ago wc-rest-functions.php 1 year ago wc-stock-functions.php 1 year ago wc-template-functions.php 1 year ago wc-template-hooks.php 1 year ago wc-term-functions.php 11 months ago wc-update-functions.php 1 year ago wc-user-functions.php 1 year ago wc-webhook-functions.php 1 year ago wc-widget-functions.php 5 years ago
class-wc-countries.php
1753 lines
1 <?php
2 /**
3 * WooCommerce countries
4 *
5 * @package WooCommerce\l10n
6 * @version 3.3.0
7 */
8
9 defined( 'ABSPATH' ) || exit;
10
11 use Automattic\WooCommerce\Blocks\Utils\CartCheckoutUtils;
12
13 /**
14 * The WooCommerce countries class stores country/state data.
15 */
16 class WC_Countries {
17
18 /**
19 * Locales list.
20 *
21 * @var array
22 */
23 public $locale = array();
24
25 /**
26 * List of address formats for locales.
27 *
28 * @var array
29 */
30 public $address_formats = array();
31
32 /**
33 * Cache of geographical regions.
34 *
35 * Only to be used by the get_* and load_* methods, as other methods may expect the regions to be
36 * loaded on demand.
37 *
38 * @var array
39 */
40 private $geo_cache = array();
41
42 /**
43 * Auto-load in-accessible properties on demand.
44 *
45 * @param mixed $key Key.
46 * @return mixed
47 */
48 public function __get( $key ) {
49 if ( 'countries' === $key ) {
50 return $this->get_countries();
51 } elseif ( 'states' === $key ) {
52 return $this->get_states();
53 } elseif ( 'continents' === $key ) {
54 return $this->get_continents();
55 }
56 }
57
58 /**
59 * Get all countries.
60 *
61 * @return array
62 */
63 public function get_countries() {
64 if ( empty( $this->geo_cache['countries'] ) ) {
65 /**
66 * Allows filtering of the list of countries in WC.
67 *
68 * @since 1.5.3
69 *
70 * @param array $countries
71 */
72 $this->geo_cache['countries'] = apply_filters( 'woocommerce_countries', include WC()->plugin_path() . '/i18n/countries.php' );
73 if ( apply_filters( 'woocommerce_sort_countries', true ) ) {
74 wc_asort_by_locale( $this->geo_cache['countries'] );
75 }
76 }
77
78 return $this->geo_cache['countries'];
79 }
80
81 /**
82 * Check if a given code represents a valid ISO 3166-1 alpha-2 code for a country known to us.
83 *
84 * @since 5.1.0
85 * @param string $country_code The country code to check as a ISO 3166-1 alpha-2 code.
86 * @return bool True if the country is known to us, false otherwise.
87 */
88 public function country_exists( $country_code ) {
89 return isset( $this->get_countries()[ $country_code ] );
90 }
91
92 /**
93 * Get all continents.
94 *
95 * @return array
96 */
97 public function get_continents() {
98 if ( empty( $this->geo_cache['continents'] ) ) {
99 /**
100 * Allows filtering of continents in WC.
101 *
102 * @since 2.6.0
103 *
104 * @param array[array] $continents
105 */
106 $this->geo_cache['continents'] = apply_filters( 'woocommerce_continents', include WC()->plugin_path() . '/i18n/continents.php' );
107 }
108
109 return $this->geo_cache['continents'];
110 }
111
112 /**
113 * Get continent code for a country code.
114 *
115 * @since 2.6.0
116 * @param string $cc Country code.
117 * @return string
118 */
119 public function get_continent_code_for_country( $cc ) {
120 $cc = trim( strtoupper( $cc ) );
121 $continents = $this->get_continents();
122 $continents_and_ccs = wp_list_pluck( $continents, 'countries' );
123 foreach ( $continents_and_ccs as $continent_code => $countries ) {
124 if ( false !== array_search( $cc, $countries, true ) ) {
125 return $continent_code;
126 }
127 }
128
129 return '';
130 }
131
132 /**
133 * Get calling code for a country code.
134 *
135 * @since 3.6.0
136 * @param string $cc Country code.
137 * @return string|array Some countries have multiple. The code will be stripped of - and spaces and always be prefixed with +.
138 */
139 public function get_country_calling_code( $cc ) {
140 $codes = wp_cache_get( 'calling-codes', 'countries' );
141
142 if ( ! $codes ) {
143 $codes = include WC()->plugin_path() . '/i18n/phone.php';
144 wp_cache_set( 'calling-codes', $codes, 'countries' );
145 }
146
147 $calling_code = isset( $codes[ $cc ] ) ? $codes[ $cc ] : '';
148
149 if ( is_array( $calling_code ) ) {
150 $calling_code = $calling_code[0];
151 }
152
153 return $calling_code;
154 }
155
156 /**
157 * Get continents that the store ships to.
158 *
159 * @since 3.6.0
160 * @return array
161 */
162 public function get_shipping_continents() {
163 $continents = $this->get_continents();
164 $shipping_countries = $this->get_shipping_countries();
165 $shipping_country_codes = array_keys( $shipping_countries );
166 $shipping_continents = array();
167
168 foreach ( $continents as $continent_code => $continent ) {
169 if ( count( array_intersect( $continent['countries'], $shipping_country_codes ) ) ) {
170 $shipping_continents[ $continent_code ] = $continent;
171 }
172 }
173
174 return $shipping_continents;
175 }
176
177 /**
178 * Load the states.
179 *
180 * @deprecated 3.6.0 This method was used to load state files, but is no longer needed. @see get_states().
181 */
182 public function load_country_states() {
183 global $states;
184
185 $states = include WC()->plugin_path() . '/i18n/states.php';
186
187 /**
188 * Allows filtering of country states in WC.
189 *
190 * @since 1.5.3
191 *
192 * @param array $states
193 */
194 $this->geo_cache['states'] = apply_filters( 'woocommerce_states', $states );
195 }
196
197 /**
198 * Get the states for a country.
199 *
200 * @param string $cc Country code.
201 * @return false|array of states
202 */
203 public function get_states( $cc = null ) {
204 if ( ! isset( $this->geo_cache['states'] ) ) {
205 /**
206 * Allows filtering of country states in WC.
207 *
208 * @since 1.5.3
209 *
210 * @param array $states
211 */
212 $this->geo_cache['states'] = apply_filters( 'woocommerce_states', include WC()->plugin_path() . '/i18n/states.php' );
213 }
214
215 if ( ! is_null( $cc ) ) {
216 return isset( $this->geo_cache['states'][ $cc ] ) ? $this->geo_cache['states'][ $cc ] : false;
217 } else {
218 return $this->geo_cache['states'];
219 }
220 }
221
222 /**
223 * Get the base address (first line) for the store.
224 *
225 * @since 3.1.1
226 * @return string
227 */
228 public function get_base_address() {
229 $base_address = get_option( 'woocommerce_store_address', '' );
230 return apply_filters( 'woocommerce_countries_base_address', $base_address );
231 }
232
233 /**
234 * Get the base address (second line) for the store.
235 *
236 * @since 3.1.1
237 * @return string
238 */
239 public function get_base_address_2() {
240 $base_address_2 = get_option( 'woocommerce_store_address_2', '' );
241 return apply_filters( 'woocommerce_countries_base_address_2', $base_address_2 );
242 }
243
244 /**
245 * Get the base country for the store.
246 *
247 * @return string
248 */
249 public function get_base_country() {
250 $default = wc_get_base_location();
251 return apply_filters( 'woocommerce_countries_base_country', $default['country'] );
252 }
253
254 /**
255 * Get the base state for the store.
256 *
257 * @return string
258 */
259 public function get_base_state() {
260 $default = wc_get_base_location();
261 return apply_filters( 'woocommerce_countries_base_state', $default['state'] );
262 }
263
264 /**
265 * Get the base city for the store.
266 *
267 * @version 3.1.1
268 * @return string
269 */
270 public function get_base_city() {
271 $base_city = get_option( 'woocommerce_store_city', '' );
272 return apply_filters( 'woocommerce_countries_base_city', $base_city );
273 }
274
275 /**
276 * Get the base postcode for the store.
277 *
278 * @since 3.1.1
279 * @return string
280 */
281 public function get_base_postcode() {
282 $base_postcode = get_option( 'woocommerce_store_postcode', '' );
283 return apply_filters( 'woocommerce_countries_base_postcode', $base_postcode );
284 }
285
286 /**
287 * Get countries that the store sells to.
288 *
289 * @return array
290 */
291 public function get_allowed_countries() {
292 $countries = $this->countries;
293 $allowed_countries = get_option( 'woocommerce_allowed_countries' );
294
295 if ( 'all_except' === $allowed_countries ) {
296 $except_countries = get_option( 'woocommerce_all_except_countries', array() );
297
298 if ( $except_countries ) {
299 foreach ( $except_countries as $country ) {
300 unset( $countries[ $country ] );
301 }
302 }
303 } elseif ( 'specific' === $allowed_countries ) {
304 $countries = array();
305 $raw_countries = get_option( 'woocommerce_specific_allowed_countries', array() );
306
307 if ( $raw_countries ) {
308 foreach ( $raw_countries as $country ) {
309 $countries[ $country ] = $this->countries[ $country ];
310 }
311 }
312 }
313
314 /**
315 * Filter the list of allowed selling countries.
316 *
317 * @since 3.3.0
318 * @param array $countries
319 */
320 return apply_filters( 'woocommerce_countries_allowed_countries', $countries );
321 }
322
323 /**
324 * Get countries that the store ships to.
325 *
326 * @return array
327 */
328 public function get_shipping_countries() {
329 // If shipping is disabled, return an empty array.
330 if ( 'disabled' === get_option( 'woocommerce_ship_to_countries' ) ) {
331 return array();
332 }
333
334 // Default to selling countries.
335 $countries = $this->get_allowed_countries();
336
337 // All indicates that all countries are allowed, regardless of where you sell to.
338 if ( 'all' === get_option( 'woocommerce_ship_to_countries' ) ) {
339 $countries = $this->countries;
340 } elseif ( 'specific' === get_option( 'woocommerce_ship_to_countries' ) ) {
341 $countries = array();
342 $raw_countries = get_option( 'woocommerce_specific_ship_to_countries', array() );
343
344 if ( $raw_countries ) {
345 foreach ( $raw_countries as $country ) {
346 $countries[ $country ] = $this->countries[ $country ];
347 }
348 }
349 }
350
351 /**
352 * Filter the list of allowed selling countries.
353 *
354 * @since 3.3.0
355 * @param array $countries
356 */
357 return apply_filters( 'woocommerce_countries_shipping_countries', $countries );
358 }
359
360 /**
361 * Get allowed country states.
362 *
363 * @return array
364 */
365 public function get_allowed_country_states() {
366 if ( get_option( 'woocommerce_allowed_countries' ) !== 'specific' ) {
367 return $this->states;
368 }
369
370 $states = array();
371
372 $raw_countries = get_option( 'woocommerce_specific_allowed_countries' );
373
374 if ( $raw_countries ) {
375 foreach ( $raw_countries as $country ) {
376 if ( isset( $this->states[ $country ] ) ) {
377 $states[ $country ] = $this->states[ $country ];
378 }
379 }
380 }
381
382 return apply_filters( 'woocommerce_countries_allowed_country_states', $states );
383 }
384
385 /**
386 * Get shipping country states.
387 *
388 * @return array
389 */
390 public function get_shipping_country_states() {
391 if ( get_option( 'woocommerce_ship_to_countries' ) === '' ) {
392 return $this->get_allowed_country_states();
393 }
394
395 if ( get_option( 'woocommerce_ship_to_countries' ) !== 'specific' ) {
396 return $this->states;
397 }
398
399 $states = array();
400
401 $raw_countries = get_option( 'woocommerce_specific_ship_to_countries' );
402
403 if ( $raw_countries ) {
404 foreach ( $raw_countries as $country ) {
405 if ( ! empty( $this->states[ $country ] ) ) {
406 $states[ $country ] = $this->states[ $country ];
407 }
408 }
409 }
410
411 return apply_filters( 'woocommerce_countries_shipping_country_states', $states );
412 }
413
414 /**
415 * Gets an array of countries in the EU.
416 *
417 * @param string $type Type of countries to retrieve. Blank for EU member countries. eu_vat for EU VAT countries.
418 * @return string[]
419 */
420 public function get_european_union_countries( $type = '' ) {
421 $countries = array( 'AT', 'BE', 'BG', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GR', 'HR', 'HU', 'IE', 'IT', 'LT', 'LU', 'LV', 'MT', 'NL', 'PL', 'PT', 'RO', 'SE', 'SI', 'SK' );
422
423 if ( 'eu_vat' === $type ) {
424 $countries[] = 'MC';
425 }
426
427 return apply_filters( 'woocommerce_european_union_countries', $countries, $type );
428 }
429
430 /**
431 * Gets an array of Non-EU countries that use VAT as the Local name for their taxes based on this list - https://en.wikipedia.org/wiki/Value-added_tax#Non-European_Union_countries
432 *
433 * @deprecated 4.0.0
434 * @since 3.9.0
435 * @return string[]
436 */
437 public function countries_using_vat() {
438 wc_deprecated_function( 'countries_using_vat', '4.0', 'WC_Countries::get_vat_countries' );
439 $countries = array( 'AE', 'AL', 'AR', 'AZ', 'BB', 'BH', 'BO', 'BS', 'BY', 'CL', 'CO', 'EC', 'EG', 'ET', 'FJ', 'GH', 'GM', 'GT', 'IL', 'IR', 'KN', 'KR', 'KZ', 'LK', 'MD', 'ME', 'MK', 'MN', 'MU', 'MX', 'NA', 'NG', 'NP', 'PS', 'PY', 'RS', 'RU', 'RW', 'SA', 'SV', 'TH', 'TR', 'UA', 'UY', 'UZ', 'VE', 'VN', 'ZA' );
440
441 return apply_filters( 'woocommerce_countries_using_vat', $countries );
442 }
443
444 /**
445 * Gets an array of countries using VAT.
446 *
447 * @since 4.0.0
448 * @return string[] of country codes.
449 */
450 public function get_vat_countries() {
451 $eu_countries = $this->get_european_union_countries();
452 $vat_countries = array( 'AE', 'AL', 'AR', 'AZ', 'BB', 'BH', 'BO', 'BS', 'BY', 'CL', 'CO', 'EC', 'EG', 'ET', 'FJ', 'GB', 'GH', 'GM', 'GT', 'IL', 'IM', 'IR', 'KN', 'KR', 'KZ', 'LK', 'MC', 'MD', 'ME', 'MK', 'MN', 'MU', 'MX', 'NA', 'NG', 'NO', 'NP', 'PS', 'PY', 'RS', 'RU', 'RW', 'SA', 'SV', 'TH', 'TR', 'UA', 'UY', 'UZ', 'VE', 'VN', 'ZA' );
453
454 return apply_filters( 'woocommerce_vat_countries', array_merge( $eu_countries, $vat_countries ) );
455 }
456
457 /**
458 * Gets the correct string for shipping - either 'to the' or 'to'.
459 *
460 * @param string $country_code Country code.
461 * @return string
462 */
463 public function shipping_to_prefix( $country_code = '' ) {
464 $country_code = $country_code ? $country_code : WC()->customer->get_shipping_country();
465 $countries = array( 'AE', 'CZ', 'DO', 'GB', 'NL', 'PH', 'US', 'USAF' );
466 $return = in_array( $country_code, $countries, true ) ? _x( 'to the', 'shipping country prefix', 'woocommerce' ) : _x( 'to', 'shipping country prefix', 'woocommerce' );
467
468 return apply_filters( 'woocommerce_countries_shipping_to_prefix', $return, $country_code );
469 }
470
471 /**
472 * Prefix certain countries with 'the'.
473 *
474 * @param string $country_code Country code.
475 * @return string
476 */
477 public function estimated_for_prefix( $country_code = '' ) {
478 $country_code = $country_code ? $country_code : $this->get_base_country();
479 $countries = array( 'AE', 'CZ', 'DO', 'GB', 'NL', 'PH', 'US', 'USAF' );
480 $return = in_array( $country_code, $countries, true ) ? __( 'the', 'woocommerce' ) . ' ' : '';
481
482 return apply_filters( 'woocommerce_countries_estimated_for_prefix', $return, $country_code );
483 }
484
485 /**
486 * Correctly name tax in some countries VAT on the frontend.
487 *
488 * @return string
489 */
490 public function tax_or_vat() {
491 $return = in_array( $this->get_base_country(), $this->get_vat_countries(), true ) ? __( 'VAT', 'woocommerce' ) : __( 'Tax', 'woocommerce' );
492
493 return apply_filters( 'woocommerce_countries_tax_or_vat', $return );
494 }
495
496 /**
497 * Include the Inc Tax label.
498 *
499 * @return string
500 */
501 public function inc_tax_or_vat() {
502 $return = in_array( $this->get_base_country(), $this->get_vat_countries(), true ) ? __( '(incl. VAT)', 'woocommerce' ) : __( '(incl. tax)', 'woocommerce' );
503
504 return apply_filters( 'woocommerce_countries_inc_tax_or_vat', $return );
505 }
506
507 /**
508 * Include the Ex Tax label.
509 *
510 * @return string
511 */
512 public function ex_tax_or_vat() {
513 $return = in_array( $this->get_base_country(), $this->get_vat_countries(), true ) ? __( '(ex. VAT)', 'woocommerce' ) : __( '(ex. tax)', 'woocommerce' );
514
515 return apply_filters( 'woocommerce_countries_ex_tax_or_vat', $return );
516 }
517
518 /**
519 * Outputs the list of countries and states for use in dropdown boxes.
520 *
521 * @param string $selected_country Selected country.
522 * @param string $selected_state Selected state.
523 * @param bool $escape If we should escape HTML.
524 */
525 public function country_dropdown_options( $selected_country = '', $selected_state = '', $escape = false ) {
526 if ( $this->countries ) {
527 foreach ( $this->countries as $key => $value ) {
528 $states = $this->get_states( $key );
529 if ( $states ) {
530 // Maybe default the selected state as the first one.
531 if ( $selected_country === $key && '*' === $selected_state ) {
532 $selected_state = key( $states ) ?? '*';
533 }
534
535 echo '<optgroup label="' . esc_attr( $value ) . '">';
536 foreach ( $states as $state_key => $state_value ) {
537 echo '<option value="' . esc_attr( $key ) . ':' . esc_attr( $state_key ) . '"';
538
539 if ( $selected_country === $key && $selected_state === $state_key ) {
540 echo ' selected="selected"';
541 }
542
543 echo '>' . esc_html( $value ) . ' &mdash; ' . ( $escape ? esc_html( $state_value ) : $state_value ) . '</option>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
544
545 }
546 echo '</optgroup>';
547 } else {
548 echo '<option';
549 if ( $selected_country === $key && '*' === $selected_state ) {
550 echo ' selected="selected"';
551 }
552 echo ' value="' . esc_attr( $key ) . '">' . ( $escape ? esc_html( $value ) : $value ) . '</option>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
553 }
554 }
555 }
556 }
557
558 /**
559 * Get country address formats.
560 *
561 * These define how addresses are formatted for display in various countries.
562 *
563 * @return array
564 */
565 public function get_address_formats() {
566 if ( empty( $this->address_formats ) ) {
567 $this->address_formats = apply_filters(
568 'woocommerce_localisation_address_formats',
569 array(
570 'default' => "{name}\n{company}\n{address_1}\n{address_2}\n{city}\n{state}\n{postcode}\n{country}",
571 'AT' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
572 'AU' => "{name}\n{company}\n{address_1}\n{address_2}\n{city} {state} {postcode}\n{country}",
573 'BE' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
574 'CA' => "{company}\n{name}\n{address_1}\n{address_2}\n{city} {state_code} {postcode}\n{country}",
575 'CH' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
576 'CL' => "{company}\n{name}\n{address_1}\n{address_2}\n{state}\n{postcode} {city}\n{country}",
577 'CN' => "{country} {postcode}\n{state}, {city}, {address_2}, {address_1}\n{company}\n{name}",
578 'CZ' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
579 'DE' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
580 'DK' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
581 'EE' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
582 'ES' => "{name}\n{company}\n{address_1}\n{address_2}\n{postcode} {city}\n{state}\n{country}",
583 'FI' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
584 'FR' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city_upper}\n{country}",
585 'HK' => "{company}\n{first_name} {last_name_upper}\n{address_1}\n{address_2}\n{city_upper}\n{state_upper}\n{country}",
586 'HU' => "{last_name} {first_name}\n{company}\n{city}\n{address_1}\n{address_2}\n{postcode}\n{country}",
587 'IN' => "{company}\n{name}\n{address_1}\n{address_2}\n{city} {postcode}\n{state}, {country}",
588 'IS' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
589 'IT' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode}\n{city}\n{state_upper}\n{country}",
590 'JM' => "{name}\n{company}\n{address_1}\n{address_2}\n{city}\n{state}\n{postcode_upper}\n{country}",
591 'JP' => "{postcode}\n{state} {city} {address_1}\n{address_2}\n{company}\n{last_name} {first_name}\n{country}",
592 'LI' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
593 'NL' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
594 'NO' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
595 'NZ' => "{name}\n{company}\n{address_1}\n{address_2}\n{city} {postcode}\n{country}",
596 'PL' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
597 'PR' => "{company}\n{name}\n{address_1} {address_2}\n{city} \n{country} {postcode}",
598 'PT' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
599 'RS' => "{name}\n{company}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
600 'SE' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
601 'SI' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
602 'SK' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
603 'TR' => "{name}\n{company}\n{address_1}\n{address_2}\n{postcode} {city} {state}\n{country}",
604 'TW' => "{company}\n{last_name} {first_name}\n{address_1}\n{address_2}\n{state}, {city} {postcode}\n{country}",
605 'UG' => "{name}\n{company}\n{address_1}\n{address_2}\n{city}\n{state}, {country}",
606 'US' => "{name}\n{company}\n{address_1}\n{address_2}\n{city}, {state_code} {postcode}\n{country}",
607 'VN' => "{name}\n{company}\n{address_1}\n{address_2}\n{city} {postcode}\n{country}",
608 )
609 );
610 }
611 return $this->address_formats;
612 }
613
614 /**
615 * Get country address format.
616 *
617 * @param array $args Arguments.
618 * @param string $separator How to separate address lines. @since 3.5.0.
619 * @return string
620 */
621 public function get_formatted_address( $args = array(), $separator = '<br/>' ) {
622 $default_args = array(
623 'first_name' => '',
624 'last_name' => '',
625 'company' => '',
626 'address_1' => '',
627 'address_2' => '',
628 'city' => '',
629 'state' => '',
630 'postcode' => '',
631 'country' => '',
632 );
633
634 $args = array_map( 'trim', wp_parse_args( $args, $default_args ) );
635 $state = $args['state'];
636 $country = $args['country'];
637
638 // Get all formats.
639 $formats = $this->get_address_formats();
640
641 // Get format for the address' country.
642 $format = ( $country && isset( $formats[ $country ] ) ) ? $formats[ $country ] : $formats['default'];
643
644 // Handle full country name.
645 $full_country = ( isset( $this->countries[ $country ] ) ) ? $this->countries[ $country ] : $country;
646
647 // Country is not needed if the same as base.
648 if ( $country === $this->get_base_country() && ! apply_filters( 'woocommerce_formatted_address_force_country_display', false ) ) {
649 $format = str_replace( '{country}', '', $format );
650 }
651
652 // Handle full state name.
653 $full_state = ( $country && $state && isset( $this->states[ $country ][ $state ] ) ) ? $this->states[ $country ][ $state ] : $state;
654
655 // Substitute address parts into the string.
656 $replace = array_map(
657 'esc_html',
658 apply_filters(
659 'woocommerce_formatted_address_replacements',
660 array(
661 '{first_name}' => $args['first_name'],
662 '{last_name}' => $args['last_name'],
663 '{name}' => sprintf(
664 /* translators: 1: first name 2: last name */
665 _x( '%1$s %2$s', 'full name', 'woocommerce' ),
666 $args['first_name'],
667 $args['last_name']
668 ),
669 '{company}' => $args['company'],
670 '{address_1}' => $args['address_1'],
671 '{address_2}' => $args['address_2'],
672 '{city}' => $args['city'],
673 '{state}' => $full_state,
674 '{postcode}' => $args['postcode'],
675 '{country}' => $full_country,
676 '{first_name_upper}' => wc_strtoupper( $args['first_name'] ),
677 '{last_name_upper}' => wc_strtoupper( $args['last_name'] ),
678 '{name_upper}' => wc_strtoupper(
679 sprintf(
680 /* translators: 1: first name 2: last name */
681 _x( '%1$s %2$s', 'full name', 'woocommerce' ),
682 $args['first_name'],
683 $args['last_name']
684 )
685 ),
686 '{company_upper}' => wc_strtoupper( $args['company'] ),
687 '{address_1_upper}' => wc_strtoupper( $args['address_1'] ),
688 '{address_2_upper}' => wc_strtoupper( $args['address_2'] ),
689 '{city_upper}' => wc_strtoupper( $args['city'] ),
690 '{state_upper}' => wc_strtoupper( $full_state ),
691 '{state_code}' => wc_strtoupper( $state ),
692 '{postcode_upper}' => wc_strtoupper( $args['postcode'] ),
693 '{country_upper}' => wc_strtoupper( $full_country ),
694 ),
695 $args
696 )
697 );
698
699 $formatted_address = str_replace( array_keys( $replace ), $replace, $format );
700
701 // Clean up white space.
702 $formatted_address = preg_replace( '/ +/', ' ', trim( $formatted_address ) );
703 $formatted_address = preg_replace( '/\n\n+/', "\n", $formatted_address );
704
705 // Break newlines apart and remove empty lines/trim commas and white space.
706 $formatted_address = array_filter( array_map( array( $this, 'trim_formatted_address_line' ), explode( "\n", $formatted_address ) ) );
707
708 // Add html breaks.
709 $formatted_address = implode( $separator, $formatted_address );
710
711 // We're done!
712 return $formatted_address;
713 }
714
715 /**
716 * Trim white space and commas off a line.
717 *
718 * @param string $line Line.
719 * @return string
720 */
721 private function trim_formatted_address_line( $line ) {
722 return trim( $line, ', ' );
723 }
724
725 /**
726 * Returns the fields we show by default. This can be filtered later on.
727 *
728 * @return array
729 */
730 public function get_default_address_fields() {
731 $address_2_label = __( 'Apartment, suite, unit, etc.', 'woocommerce' );
732
733 // If necessary, append '(optional)' to the placeholder: we don't need to worry about the
734 // label, though, as woocommerce_form_field() takes care of that.
735 if ( 'optional' === CartCheckoutUtils::get_address_2_field_visibility() ) {
736 $address_2_placeholder = __( 'Apartment, suite, unit, etc. (optional)', 'woocommerce' );
737 } else {
738 $address_2_placeholder = $address_2_label;
739 }
740
741 $fields = array(
742 'first_name' => array(
743 'label' => __( 'First name', 'woocommerce' ),
744 'required' => true,
745 'class' => array( 'form-row-first' ),
746 'autocomplete' => 'given-name',
747 'priority' => 10,
748 ),
749 'last_name' => array(
750 'label' => __( 'Last name', 'woocommerce' ),
751 'required' => true,
752 'class' => array( 'form-row-last' ),
753 'autocomplete' => 'family-name',
754 'priority' => 20,
755 ),
756 'company' => array(
757 'label' => __( 'Company name', 'woocommerce' ),
758 'class' => array( 'form-row-wide' ),
759 'autocomplete' => 'organization',
760 'priority' => 30,
761 'required' => 'required' === CartCheckoutUtils::get_company_field_visibility(),
762 ),
763 'country' => array(
764 'type' => 'country',
765 'label' => __( 'Country / Region', 'woocommerce' ),
766 'required' => true,
767 'class' => array( 'form-row-wide', 'address-field', 'update_totals_on_change' ),
768 'autocomplete' => 'country',
769 'priority' => 40,
770 ),
771 'address_1' => array(
772 'label' => __( 'Street address', 'woocommerce' ),
773 /* translators: use local order of street name and house number. */
774 'placeholder' => esc_attr__( 'House number and street name', 'woocommerce' ),
775 'required' => true,
776 'class' => array( 'form-row-wide', 'address-field' ),
777 'autocomplete' => 'address-line1',
778 'priority' => 50,
779 ),
780 'address_2' => array(
781 'label' => $address_2_label,
782 'label_class' => array( 'screen-reader-text' ),
783 'placeholder' => esc_attr( $address_2_placeholder ),
784 'class' => array( 'form-row-wide', 'address-field' ),
785 'autocomplete' => 'address-line2',
786 'priority' => 60,
787 'required' => 'required' === CartCheckoutUtils::get_address_2_field_visibility(),
788 ),
789 'city' => array(
790 'label' => __( 'Town / City', 'woocommerce' ),
791 'required' => true,
792 'class' => array( 'form-row-wide', 'address-field' ),
793 'autocomplete' => 'address-level2',
794 'priority' => 70,
795 ),
796 'state' => array(
797 'type' => 'state',
798 'label' => __( 'State / County', 'woocommerce' ),
799 'required' => true,
800 'class' => array( 'form-row-wide', 'address-field' ),
801 'validate' => array( 'state' ),
802 'autocomplete' => 'address-level1',
803 'priority' => 80,
804 ),
805 'postcode' => array(
806 'label' => __( 'Postcode / ZIP', 'woocommerce' ),
807 'required' => true,
808 'class' => array( 'form-row-wide', 'address-field' ),
809 'validate' => array( 'postcode' ),
810 'autocomplete' => 'postal-code',
811 'priority' => 90,
812 ),
813 );
814
815 if ( 'hidden' === CartCheckoutUtils::get_company_field_visibility() ) {
816 unset( $fields['company'] );
817 }
818
819 if ( 'hidden' === CartCheckoutUtils::get_address_2_field_visibility() ) {
820 unset( $fields['address_2'] );
821 }
822
823 $default_address_fields = apply_filters( 'woocommerce_default_address_fields', $fields );
824 // Sort each of the fields based on priority.
825 uasort( $default_address_fields, 'wc_checkout_fields_uasort_comparison' );
826
827 return $default_address_fields;
828 }
829
830 /**
831 * Get JS selectors for fields which are shown/hidden depending on the locale.
832 *
833 * @return array
834 */
835 public function get_country_locale_field_selectors() {
836 $locale_fields = array(
837 'address_1' => '#billing_address_1_field, #shipping_address_1_field',
838 'address_2' => '#billing_address_2_field, #shipping_address_2_field',
839 'state' => '#billing_state_field, #shipping_state_field, #calc_shipping_state_field',
840 'postcode' => '#billing_postcode_field, #shipping_postcode_field, #calc_shipping_postcode_field',
841 'city' => '#billing_city_field, #shipping_city_field, #calc_shipping_city_field',
842 );
843 return apply_filters( 'woocommerce_country_locale_field_selectors', $locale_fields );
844 }
845
846 /**
847 * Get country locale settings.
848 *
849 * These locales override the default country selections after a country is chosen.
850 *
851 * @return array
852 */
853 public function get_country_locale() {
854 if ( empty( $this->locale ) ) {
855 $this->locale = apply_filters(
856 'woocommerce_get_country_locale',
857 array(
858 'AE' => array(
859 'postcode' => array(
860 'required' => false,
861 'hidden' => true,
862 ),
863 'state' => array(
864 'required' => false,
865 ),
866 ),
867 'AF' => array(
868 'state' => array(
869 'required' => false,
870 'hidden' => true,
871 ),
872 ),
873 'AL' => array(
874 'state' => array(
875 'label' => __( 'County', 'woocommerce' ),
876 ),
877 ),
878 'AO' => array(
879 'postcode' => array(
880 'required' => false,
881 'hidden' => true,
882 ),
883 'state' => array(
884 'label' => __( 'Province', 'woocommerce' ),
885 ),
886 ),
887 'AT' => array(
888 'postcode' => array(
889 'priority' => 65,
890 ),
891 'state' => array(
892 'required' => false,
893 'hidden' => true,
894 ),
895 ),
896 'AU' => array(
897 'city' => array(
898 'label' => __( 'Suburb', 'woocommerce' ),
899 ),
900 'postcode' => array(
901 'label' => __( 'Postcode', 'woocommerce' ),
902 ),
903 'state' => array(
904 'label' => __( 'State', 'woocommerce' ),
905 ),
906 ),
907 'AX' => array(
908 'postcode' => array(
909 'priority' => 65,
910 ),
911 'state' => array(
912 'required' => false,
913 'hidden' => true,
914 ),
915 ),
916 'BA' => array(
917 'postcode' => array(
918 'priority' => 65,
919 ),
920 'state' => array(
921 'label' => __( 'Canton', 'woocommerce' ),
922 'required' => false,
923 'hidden' => true,
924 ),
925 ),
926 'BD' => array(
927 'postcode' => array(
928 'required' => false,
929 ),
930 'state' => array(
931 'label' => __( 'District', 'woocommerce' ),
932 ),
933 ),
934 'BE' => array(
935 'postcode' => array(
936 'priority' => 65,
937 ),
938 'state' => array(
939 'required' => false,
940 'hidden' => true,
941 ),
942 ),
943 'BG' => array(
944 'state' => array(
945 'required' => false,
946 ),
947 ),
948 'BH' => array(
949 'postcode' => array(
950 'required' => false,
951 ),
952 'state' => array(
953 'required' => false,
954 'hidden' => true,
955 ),
956 ),
957 'BI' => array(
958 'state' => array(
959 'required' => false,
960 'hidden' => true,
961 ),
962 ),
963 'BO' => array(
964 'postcode' => array(
965 'required' => false,
966 'hidden' => true,
967 ),
968 'state' => array(
969 'label' => __( 'Department', 'woocommerce' ),
970 ),
971 ),
972 'BS' => array(
973 'postcode' => array(
974 'required' => false,
975 'hidden' => true,
976 ),
977 ),
978 'BW' => array(
979 'postcode' => array(
980 'required' => false,
981 'hidden' => true,
982 ),
983 'state' => array(
984 'required' => false,
985 'hidden' => true,
986 'label' => __( 'District', 'woocommerce' ),
987 ),
988 ),
989 'BZ' => array(
990 'postcode' => array(
991 'required' => false,
992 'hidden' => true,
993 ),
994 'state' => array(
995 'required' => false,
996 ),
997 ),
998 'CA' => array(
999 'postcode' => array(
1000 'label' => __( 'Postal code', 'woocommerce' ),
1001 ),
1002 'state' => array(
1003 'label' => __( 'Province', 'woocommerce' ),
1004 ),
1005 ),
1006 'CH' => array(
1007 'postcode' => array(
1008 'priority' => 65,
1009 ),
1010 'state' => array(
1011 'label' => __( 'Canton', 'woocommerce' ),
1012 'required' => false,
1013 ),
1014 ),
1015 'CL' => array(
1016 'city' => array(
1017 'required' => true,
1018 ),
1019 'postcode' => array(
1020 'required' => false,
1021 // Hidden for stores within Chile. @see https://github.com/woocommerce/woocommerce/issues/36546.
1022 'hidden' => 'CL' === $this->get_base_country(),
1023 ),
1024 'state' => array(
1025 'label' => __( 'Region', 'woocommerce' ),
1026 ),
1027 ),
1028 'CN' => array(
1029 'state' => array(
1030 'label' => __( 'Province', 'woocommerce' ),
1031 ),
1032 ),
1033 'CO' => array(
1034 'postcode' => array(
1035 'required' => false,
1036 ),
1037 'state' => array(
1038 'label' => __( 'Department', 'woocommerce' ),
1039 ),
1040 ),
1041 'CR' => array(
1042 'state' => array(
1043 'label' => __( 'Province', 'woocommerce' ),
1044 ),
1045 ),
1046 'CW' => array(
1047 'postcode' => array(
1048 'required' => false,
1049 'hidden' => true,
1050 ),
1051 'state' => array(
1052 'required' => false,
1053 ),
1054 ),
1055 'CY' => array(
1056 'state' => array(
1057 'required' => false,
1058 'hidden' => true,
1059 ),
1060 ),
1061 'CZ' => array(
1062 'state' => array(
1063 'required' => false,
1064 'hidden' => true,
1065 ),
1066 ),
1067 'DE' => array(
1068 'postcode' => array(
1069 'priority' => 65,
1070 ),
1071 'state' => array(
1072 'required' => false,
1073 ),
1074 ),
1075 'DK' => array(
1076 'postcode' => array(
1077 'priority' => 65,
1078 ),
1079 'state' => array(
1080 'required' => false,
1081 'hidden' => true,
1082 ),
1083 ),
1084 'DO' => array(
1085 'state' => array(
1086 'label' => __( 'Province', 'woocommerce' ),
1087 ),
1088 ),
1089 'EC' => array(
1090 'state' => array(
1091 'label' => __( 'Province', 'woocommerce' ),
1092 ),
1093 ),
1094 'EE' => array(
1095 'postcode' => array(
1096 'priority' => 65,
1097 ),
1098 'state' => array(
1099 'required' => false,
1100 'hidden' => true,
1101 ),
1102 ),
1103 'ET' => array(
1104 'state' => array(
1105 'required' => false,
1106 'hidden' => true,
1107 ),
1108 ),
1109 'FI' => array(
1110 'postcode' => array(
1111 'priority' => 65,
1112 ),
1113 'state' => array(
1114 'required' => false,
1115 'hidden' => true,
1116 ),
1117 ),
1118 'FR' => array(
1119 'postcode' => array(
1120 'priority' => 65,
1121 ),
1122 'state' => array(
1123 'required' => false,
1124 'hidden' => true,
1125 ),
1126 ),
1127 'GG' => array(
1128 'state' => array(
1129 'required' => false,
1130 'label' => __( 'Parish', 'woocommerce' ),
1131 ),
1132 ),
1133 'GH' => array(
1134 'postcode' => array(
1135 'required' => false,
1136 ),
1137 'state' => array(
1138 'label' => __( 'Region', 'woocommerce' ),
1139 ),
1140 ),
1141 'GP' => array(
1142 'state' => array(
1143 'required' => false,
1144 'hidden' => true,
1145 ),
1146 ),
1147 'GF' => array(
1148 'state' => array(
1149 'required' => false,
1150 'hidden' => true,
1151 ),
1152 ),
1153 'GR' => array(
1154 'state' => array(
1155 'required' => false,
1156 ),
1157 ),
1158 'GT' => array(
1159 'postcode' => array(
1160 'required' => false,
1161 ),
1162 'state' => array(
1163 'label' => __( 'Department', 'woocommerce' ),
1164 ),
1165 ),
1166 'HK' => array(
1167 'postcode' => array(
1168 'required' => false,
1169 ),
1170 'city' => array(
1171 'label' => __( 'Town / District', 'woocommerce' ),
1172 ),
1173 'state' => array(
1174 'label' => __( 'Region', 'woocommerce' ),
1175 ),
1176 ),
1177 'HN' => array(
1178 'state' => array(
1179 'label' => __( 'Department', 'woocommerce' ),
1180 ),
1181 ),
1182 'HU' => array(
1183 'last_name' => array(
1184 'class' => array( 'form-row-first' ),
1185 'priority' => 10,
1186 ),
1187 'first_name' => array(
1188 'class' => array( 'form-row-last' ),
1189 'priority' => 20,
1190 ),
1191 'postcode' => array(
1192 'class' => array( 'form-row-first', 'address-field' ),
1193 'priority' => 65,
1194 ),
1195 'city' => array(
1196 'class' => array( 'form-row-last', 'address-field' ),
1197 ),
1198 'address_1' => array(
1199 'priority' => 71,
1200 ),
1201 'address_2' => array(
1202 'priority' => 72,
1203 ),
1204 'state' => array(
1205 'label' => __( 'County', 'woocommerce' ),
1206 'required' => false,
1207 ),
1208 ),
1209 'ID' => array(
1210 'state' => array(
1211 'label' => __( 'Province', 'woocommerce' ),
1212 ),
1213 ),
1214 'IE' => array(
1215 'postcode' => array(
1216 'required' => true,
1217 'label' => __( 'Eircode', 'woocommerce' ),
1218 ),
1219 'state' => array(
1220 'label' => __( 'County', 'woocommerce' ),
1221 ),
1222 ),
1223 'IS' => array(
1224 'postcode' => array(
1225 'priority' => 65,
1226 ),
1227 'state' => array(
1228 'required' => false,
1229 'hidden' => true,
1230 ),
1231 ),
1232 'IL' => array(
1233 'postcode' => array(
1234 'priority' => 65,
1235 ),
1236 'state' => array(
1237 'required' => false,
1238 'hidden' => true,
1239 ),
1240 ),
1241 'IM' => array(
1242 'state' => array(
1243 'required' => false,
1244 'hidden' => true,
1245 ),
1246 ),
1247 'IN' => array(
1248 'postcode' => array(
1249 'label' => __( 'PIN Code', 'woocommerce' ),
1250 ),
1251 'state' => array(
1252 'label' => __( 'State', 'woocommerce' ),
1253 ),
1254 ),
1255 'IR' => array(
1256 'state' => array(
1257 'priority' => 50,
1258 ),
1259 'city' => array(
1260 'priority' => 60,
1261 ),
1262 'address_1' => array(
1263 'priority' => 70,
1264 ),
1265 'address_2' => array(
1266 'priority' => 80,
1267 ),
1268 ),
1269 'IT' => array(
1270 'postcode' => array(
1271 'priority' => 65,
1272 ),
1273 'state' => array(
1274 'required' => true,
1275 'label' => __( 'Province', 'woocommerce' ),
1276 ),
1277 ),
1278 'JM' => array(
1279 'city' => array(
1280 'label' => __( 'Town / City / Post Office', 'woocommerce' ),
1281 ),
1282 'postcode' => array(
1283 'required' => false,
1284 'label' => __( 'Postal Code', 'woocommerce' ),
1285 ),
1286 'state' => array(
1287 'required' => true,
1288 'label' => __( 'Parish', 'woocommerce' ),
1289 ),
1290 ),
1291 'JP' => array(
1292 'last_name' => array(
1293 'class' => array( 'form-row-first' ),
1294 'priority' => 10,
1295 ),
1296 'first_name' => array(
1297 'class' => array( 'form-row-last' ),
1298 'priority' => 20,
1299 ),
1300 'postcode' => array(
1301 'class' => array( 'form-row-first', 'address-field' ),
1302 'priority' => 65,
1303 ),
1304 'state' => array(
1305 'label' => __( 'Prefecture', 'woocommerce' ),
1306 'class' => array( 'form-row-last', 'address-field' ),
1307 'priority' => 66,
1308 ),
1309 'city' => array(
1310 'priority' => 67,
1311 ),
1312 'address_1' => array(
1313 'priority' => 68,
1314 ),
1315 'address_2' => array(
1316 'priority' => 69,
1317 ),
1318 ),
1319 'KN' => array(
1320 'postcode' => array(
1321 'required' => false,
1322 'label' => __( 'Postal code', 'woocommerce' ),
1323 ),
1324 'state' => array(
1325 'required' => true,
1326 'label' => __( 'Parish', 'woocommerce' ),
1327 ),
1328 ),
1329 'KR' => array(
1330 'state' => array(
1331 'required' => false,
1332 'hidden' => true,
1333 ),
1334 ),
1335 'KW' => array(
1336 'state' => array(
1337 'required' => false,
1338 'hidden' => true,
1339 ),
1340 ),
1341 'LV' => array(
1342 'state' => array(
1343 'label' => __( 'Municipality', 'woocommerce' ),
1344 'required' => false,
1345 ),
1346 ),
1347 'LB' => array(
1348 'state' => array(
1349 'required' => false,
1350 'hidden' => true,
1351 ),
1352 ),
1353 'MF' => array(
1354 'state' => array(
1355 'required' => false,
1356 'hidden' => true,
1357 ),
1358 ),
1359 'MQ' => array(
1360 'state' => array(
1361 'required' => false,
1362 'hidden' => true,
1363 ),
1364 ),
1365 'MT' => array(
1366 'state' => array(
1367 'required' => false,
1368 'hidden' => true,
1369 ),
1370 ),
1371 'MZ' => array(
1372 'postcode' => array(
1373 'required' => false,
1374 'hidden' => true,
1375 ),
1376 'state' => array(
1377 'label' => __( 'Province', 'woocommerce' ),
1378 ),
1379 ),
1380 'NI' => array(
1381 'state' => array(
1382 'label' => __( 'Department', 'woocommerce' ),
1383 ),
1384 ),
1385 'NL' => array(
1386 'postcode' => array(
1387 'priority' => 65,
1388 ),
1389 'state' => array(
1390 'required' => false,
1391 'hidden' => true,
1392 ),
1393 ),
1394 'NG' => array(
1395 'postcode' => array(
1396 'label' => __( 'Postcode', 'woocommerce' ),
1397 'required' => false,
1398 'hidden' => true,
1399 ),
1400 'state' => array(
1401 'label' => __( 'State', 'woocommerce' ),
1402 ),
1403 ),
1404 'NZ' => array(
1405 'postcode' => array(
1406 'label' => __( 'Postcode', 'woocommerce' ),
1407 ),
1408 'state' => array(
1409 'required' => false,
1410 'label' => __( 'Region', 'woocommerce' ),
1411 ),
1412 ),
1413 'NO' => array(
1414 'postcode' => array(
1415 'priority' => 65,
1416 ),
1417 'state' => array(
1418 'required' => false,
1419 'hidden' => true,
1420 ),
1421 ),
1422 'NP' => array(
1423 'state' => array(
1424 'label' => __( 'State / Zone', 'woocommerce' ),
1425 ),
1426 'postcode' => array(
1427 'required' => false,
1428 ),
1429 ),
1430 'PA' => array(
1431 'state' => array(
1432 'label' => __( 'Province', 'woocommerce' ),
1433 ),
1434 ),
1435 'PL' => array(
1436 'postcode' => array(
1437 'priority' => 65,
1438 ),
1439 'state' => array(
1440 'required' => false,
1441 'hidden' => true,
1442 ),
1443 ),
1444 'PR' => array(
1445 'city' => array(
1446 'label' => __( 'Municipality', 'woocommerce' ),
1447 ),
1448 'state' => array(
1449 'required' => false,
1450 'hidden' => true,
1451 ),
1452 ),
1453 'PT' => array(
1454 'state' => array(
1455 'required' => false,
1456 'hidden' => true,
1457 ),
1458 ),
1459 'PY' => array(
1460 'state' => array(
1461 'label' => __( 'Department', 'woocommerce' ),
1462 ),
1463 ),
1464 'RE' => array(
1465 'state' => array(
1466 'required' => false,
1467 'hidden' => true,
1468 ),
1469 ),
1470 'RO' => array(
1471 'state' => array(
1472 'label' => __( 'County', 'woocommerce' ),
1473 'required' => true,
1474 ),
1475 ),
1476 'RS' => array(
1477 'city' => array(
1478 'required' => true,
1479 ),
1480 'postcode' => array(
1481 'required' => true,
1482 ),
1483 'state' => array(
1484 'label' => __( 'District', 'woocommerce' ),
1485 'required' => false,
1486 ),
1487 ),
1488 'RW' => array(
1489 'state' => array(
1490 'required' => false,
1491 'hidden' => true,
1492 ),
1493 ),
1494 'SG' => array(
1495 'state' => array(
1496 'required' => false,
1497 'hidden' => true,
1498 ),
1499 'city' => array(
1500 'required' => false,
1501 ),
1502 ),
1503 'SK' => array(
1504 'postcode' => array(
1505 'priority' => 65,
1506 ),
1507 'state' => array(
1508 'required' => false,
1509 'hidden' => true,
1510 ),
1511 ),
1512 'SI' => array(
1513 'postcode' => array(
1514 'priority' => 65,
1515 ),
1516 'state' => array(
1517 'required' => false,
1518 'hidden' => true,
1519 ),
1520 ),
1521 'SR' => array(
1522 'postcode' => array(
1523 'required' => false,
1524 'hidden' => true,
1525 ),
1526 ),
1527 'SV' => array(
1528 'state' => array(
1529 'label' => __( 'Department', 'woocommerce' ),
1530 ),
1531 ),
1532 'ES' => array(
1533 'postcode' => array(
1534 'priority' => 65,
1535 ),
1536 'state' => array(
1537 'label' => __( 'Province', 'woocommerce' ),
1538 ),
1539 ),
1540 'LI' => array(
1541 'postcode' => array(
1542 'priority' => 65,
1543 ),
1544 'state' => array(
1545 'required' => false,
1546 'hidden' => true,
1547 ),
1548 ),
1549 'LK' => array(
1550 'state' => array(
1551 'required' => false,
1552 'hidden' => true,
1553 ),
1554 ),
1555 'LU' => array(
1556 'state' => array(
1557 'required' => false,
1558 'hidden' => true,
1559 ),
1560 ),
1561 'MD' => array(
1562 'state' => array(
1563 'label' => __( 'Municipality / District', 'woocommerce' ),
1564 ),
1565 ),
1566 'SE' => array(
1567 'postcode' => array(
1568 'priority' => 65,
1569 ),
1570 'state' => array(
1571 'required' => false,
1572 'hidden' => true,
1573 ),
1574 ),
1575 'TR' => array(
1576 'postcode' => array(
1577 'priority' => 65,
1578 ),
1579 'state' => array(
1580 'label' => __( 'Province', 'woocommerce' ),
1581 ),
1582 ),
1583 'UG' => array(
1584 'postcode' => array(
1585 'required' => false,
1586 'hidden' => true,
1587 ),
1588 'city' => array(
1589 'label' => __( 'Town / Village', 'woocommerce' ),
1590 'required' => true,
1591 ),
1592 'state' => array(
1593 'label' => __( 'District', 'woocommerce' ),
1594 'required' => true,
1595 ),
1596 ),
1597 'US' => array(
1598 'postcode' => array(
1599 'label' => __( 'ZIP Code', 'woocommerce' ),
1600 ),
1601 'state' => array(
1602 'label' => __( 'State', 'woocommerce' ),
1603 ),
1604 ),
1605 'UY' => array(
1606 'state' => array(
1607 'label' => __( 'Department', 'woocommerce' ),
1608 ),
1609 ),
1610 'GB' => array(
1611 'postcode' => array(
1612 'label' => __( 'Postcode', 'woocommerce' ),
1613 ),
1614 'state' => array(
1615 'label' => __( 'County', 'woocommerce' ),
1616 'required' => false,
1617 ),
1618 ),
1619 'ST' => array(
1620 'postcode' => array(
1621 'required' => false,
1622 'hidden' => true,
1623 ),
1624 'state' => array(
1625 'label' => __( 'District', 'woocommerce' ),
1626 ),
1627 ),
1628 'VN' => array(
1629 'state' => array(
1630 'required' => false,
1631 'hidden' => true,
1632 ),
1633 'postcode' => array(
1634 'priority' => 65,
1635 'required' => false,
1636 'hidden' => false,
1637 ),
1638 'address_2' => array(
1639 'required' => false,
1640 'hidden' => false,
1641 ),
1642 ),
1643 'WS' => array(
1644 'postcode' => array(
1645 'required' => false,
1646 'hidden' => true,
1647 ),
1648 ),
1649 'YT' => array(
1650 'state' => array(
1651 'required' => false,
1652 'hidden' => true,
1653 ),
1654 ),
1655 'ZA' => array(
1656 'state' => array(
1657 'label' => __( 'Province', 'woocommerce' ),
1658 ),
1659 ),
1660 'ZW' => array(
1661 'postcode' => array(
1662 'required' => false,
1663 'hidden' => true,
1664 ),
1665 ),
1666 )
1667 );
1668
1669 $this->locale = array_intersect_key( $this->locale, array_merge( $this->get_allowed_countries(), $this->get_shipping_countries() ) );
1670
1671 // Default Locale Can be filtered to override fields in get_address_fields(). Countries with no specific locale will use default.
1672 $this->locale['default'] = apply_filters( 'woocommerce_get_country_locale_default', $this->get_default_address_fields() );
1673
1674 // Filter default AND shop base locales to allow overrides via a single function. These will be used when changing countries on the checkout.
1675 if ( ! isset( $this->locale[ $this->get_base_country() ] ) ) {
1676 $this->locale[ $this->get_base_country() ] = $this->locale['default'];
1677 }
1678
1679 $this->locale['default'] = apply_filters( 'woocommerce_get_country_locale_base', $this->locale['default'] );
1680 $this->locale[ $this->get_base_country() ] = apply_filters( 'woocommerce_get_country_locale_base', $this->locale[ $this->get_base_country() ] );
1681 }
1682
1683 return $this->locale;
1684 }
1685
1686 /**
1687 * Apply locale and get address fields.
1688 *
1689 * @param mixed $country Country.
1690 * @param string $type Address type, defaults to 'billing_'.
1691 * @return array
1692 */
1693 public function get_address_fields( $country = '', $type = 'billing_' ) {
1694 if ( ! $country ) {
1695 $country = $this->get_base_country();
1696 }
1697
1698 $fields = $this->get_default_address_fields();
1699 $locale = $this->get_country_locale();
1700
1701 if ( isset( $locale[ $country ] ) ) {
1702 $fields = wc_array_overlay( $fields, $locale[ $country ] );
1703 }
1704
1705 // Prepend field keys.
1706 $address_fields = array();
1707
1708 foreach ( $fields as $key => $value ) {
1709 if ( 'state' === $key ) {
1710 $value['country_field'] = $type . 'country';
1711 $value['country'] = $country;
1712 }
1713 $address_fields[ $type . $key ] = $value;
1714 }
1715
1716 // Add email and phone fields.
1717 if ( 'billing_' === $type ) {
1718 if ( 'hidden' !== CartCheckoutUtils::get_phone_field_visibility() ) {
1719 $address_fields['billing_phone'] = array(
1720 'label' => __( 'Phone', 'woocommerce' ),
1721 'required' => 'required' === CartCheckoutUtils::get_phone_field_visibility(),
1722 'type' => 'tel',
1723 'class' => array( 'form-row-wide' ),
1724 'validate' => array( 'phone' ),
1725 'autocomplete' => 'tel',
1726 'priority' => 100,
1727 );
1728 }
1729 $address_fields['billing_email'] = array(
1730 'label' => __( 'Email address', 'woocommerce' ),
1731 'required' => true,
1732 'type' => 'email',
1733 'class' => array( 'form-row-wide' ),
1734 'validate' => array( 'email' ),
1735 'autocomplete' => 'email',
1736 'priority' => 110,
1737 );
1738 }
1739
1740 /**
1741 * Important note on this filter: Changes to address fields can and will be overridden by
1742 * the woocommerce_default_address_fields. The locales/default locales apply on top based
1743 * on country selection. If you want to change things like the required status of an
1744 * address field, filter woocommerce_default_address_fields instead.
1745 */
1746 $address_fields = apply_filters( 'woocommerce_' . $type . 'fields', $address_fields, $country );
1747 // Sort each of the fields based on priority.
1748 uasort( $address_fields, 'wc_checkout_fields_uasort_comparison' );
1749
1750 return $address_fields;
1751 }
1752 }
1753