PluginProbe ʕ •ᴥ•ʔ
WooCommerce / 4.2.4
WooCommerce v4.2.4
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 5 years ago admin 5 years ago cli 5 years ago customizer 5 years ago data-stores 4 years ago emails 5 years ago export 5 years ago gateways 5 years ago import 5 years ago integrations 5 years ago interfaces 5 years ago legacy 5 years ago libraries 5 years ago log-handlers 5 years ago payment-tokens 5 years ago queue 5 years ago shipping 5 years ago shortcodes 5 years ago theme-support 5 years ago tracks 5 years ago traits 5 years ago walkers 5 years ago wccom-site 5 years ago widgets 5 years ago class-wc-ajax.php 5 years ago class-wc-api.php 5 years ago class-wc-auth.php 5 years ago class-wc-autoloader.php 5 years ago class-wc-background-emailer.php 5 years ago class-wc-background-updater.php 5 years ago class-wc-breadcrumb.php 5 years ago class-wc-cache-helper.php 5 years ago class-wc-cart-fees.php 5 years ago class-wc-cart-session.php 5 years ago class-wc-cart-totals.php 5 years ago class-wc-cart.php 5 years ago class-wc-checkout.php 5 years ago class-wc-cli.php 5 years ago class-wc-comments.php 5 years ago class-wc-countries.php 5 years ago class-wc-coupon.php 5 years ago class-wc-customer-download-log.php 5 years ago class-wc-customer-download.php 5 years ago class-wc-customer.php 5 years ago class-wc-data-exception.php 5 years ago class-wc-data-store.php 5 years ago class-wc-datetime.php 5 years ago class-wc-deprecated-action-hooks.php 5 years ago class-wc-deprecated-filter-hooks.php 5 years ago class-wc-discounts.php 5 years ago class-wc-download-handler.php 5 years ago class-wc-emails.php 5 years ago class-wc-embed.php 5 years ago class-wc-form-handler.php 5 years ago class-wc-frontend-scripts.php 5 years ago class-wc-geo-ip.php 5 years ago class-wc-geolite-integration.php 5 years ago class-wc-geolocation.php 5 years ago class-wc-https.php 5 years ago class-wc-install.php 4 years ago class-wc-integrations.php 5 years ago class-wc-log-levels.php 5 years ago class-wc-logger.php 5 years ago class-wc-meta-data.php 5 years ago class-wc-order-factory.php 5 years ago class-wc-order-item-coupon.php 5 years ago class-wc-order-item-fee.php 5 years ago class-wc-order-item-meta.php 5 years ago class-wc-order-item-product.php 5 years ago class-wc-order-item-shipping.php 5 years ago class-wc-order-item-tax.php 5 years ago class-wc-order-item.php 5 years ago class-wc-order-query.php 5 years ago class-wc-order-refund.php 5 years ago class-wc-order.php 5 years ago class-wc-payment-gateways.php 5 years ago class-wc-payment-tokens.php 5 years ago class-wc-post-data.php 5 years ago class-wc-post-types.php 5 years ago class-wc-privacy-background-process.php 5 years ago class-wc-privacy-erasers.php 5 years ago class-wc-privacy-exporters.php 5 years ago class-wc-privacy.php 5 years ago class-wc-product-attribute.php 5 years ago class-wc-product-download.php 5 years ago class-wc-product-external.php 5 years ago class-wc-product-factory.php 5 years ago class-wc-product-grouped.php 5 years ago class-wc-product-query.php 5 years ago class-wc-product-simple.php 5 years ago class-wc-product-variable.php 5 years ago class-wc-product-variation.php 5 years ago class-wc-query.php 5 years ago class-wc-rate-limiter.php 5 years ago class-wc-regenerate-images-request.php 5 years ago class-wc-regenerate-images.php 5 years ago class-wc-register-wp-admin-settings.php 5 years ago class-wc-rest-authentication.php 5 years ago class-wc-rest-exception.php 5 years ago class-wc-session-handler.php 5 years ago class-wc-shipping-rate.php 5 years ago class-wc-shipping-zone.php 5 years ago class-wc-shipping-zones.php 5 years ago class-wc-shipping.php 5 years ago class-wc-shortcodes.php 5 years ago class-wc-structured-data.php 5 years ago class-wc-tax.php 5 years ago class-wc-template-loader.php 5 years ago class-wc-tracker.php 5 years ago class-wc-validation.php 5 years ago class-wc-webhook.php 5 years ago class-woocommerce.php 4 years ago wc-account-functions.php 5 years ago wc-attribute-functions.php 5 years ago wc-cart-functions.php 5 years ago wc-conditional-functions.php 5 years ago wc-core-functions.php 5 years ago wc-coupon-functions.php 5 years ago wc-deprecated-functions.php 5 years ago wc-formatting-functions.php 5 years ago wc-notice-functions.php 5 years ago wc-order-functions.php 5 years ago wc-order-item-functions.php 5 years ago wc-page-functions.php 5 years ago wc-product-functions.php 5 years ago wc-rest-functions.php 5 years ago wc-stock-functions.php 5 years ago wc-template-functions.php 5 years ago wc-template-hooks.php 5 years ago wc-term-functions.php 5 years ago wc-update-functions.php 4 years ago wc-user-functions.php 5 years ago wc-webhook-functions.php 5 years ago wc-widget-functions.php 5 years ago
class-wc-countries.php
1417 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 /**
12 * The WooCommerce countries class stores country/state data.
13 */
14 class WC_Countries {
15
16 /**
17 * Locales list.
18 *
19 * @var array
20 */
21 public $locale = array();
22
23 /**
24 * List of address formats for locales.
25 *
26 * @var array
27 */
28 public $address_formats = array();
29
30 /**
31 * Auto-load in-accessible properties on demand.
32 *
33 * @param mixed $key Key.
34 * @return mixed
35 */
36 public function __get( $key ) {
37 if ( 'countries' === $key ) {
38 return $this->get_countries();
39 } elseif ( 'states' === $key ) {
40 return $this->get_states();
41 }
42 }
43
44 /**
45 * Get all countries.
46 *
47 * @return array
48 */
49 public function get_countries() {
50 if ( empty( $this->countries ) ) {
51 $this->countries = apply_filters( 'woocommerce_countries', include WC()->plugin_path() . '/i18n/countries.php' );
52 if ( apply_filters( 'woocommerce_sort_countries', true ) ) {
53 uasort( $this->countries, 'wc_ascii_uasort_comparison' );
54 }
55 }
56
57 return $this->countries;
58 }
59
60 /**
61 * Get all continents.
62 *
63 * @return array
64 */
65 public function get_continents() {
66 if ( empty( $this->continents ) ) {
67 $this->continents = apply_filters( 'woocommerce_continents', include WC()->plugin_path() . '/i18n/continents.php' );
68 }
69
70 return $this->continents;
71 }
72
73 /**
74 * Get continent code for a country code.
75 *
76 * @since 2.6.0
77 * @param string $cc Country code.
78 * @return string
79 */
80 public function get_continent_code_for_country( $cc ) {
81 $cc = trim( strtoupper( $cc ) );
82 $continents = $this->get_continents();
83 $continents_and_ccs = wp_list_pluck( $continents, 'countries' );
84 foreach ( $continents_and_ccs as $continent_code => $countries ) {
85 if ( false !== array_search( $cc, $countries, true ) ) {
86 return $continent_code;
87 }
88 }
89
90 return '';
91 }
92
93 /**
94 * Get calling code for a country code.
95 *
96 * @since 3.6.0
97 * @param string $cc Country code.
98 * @return string|array Some countries have multiple. The code will be stripped of - and spaces and always be prefixed with +.
99 */
100 public function get_country_calling_code( $cc ) {
101 $codes = wp_cache_get( 'calling-codes', 'countries' );
102
103 if ( ! $codes ) {
104 $codes = include WC()->plugin_path() . '/i18n/phone.php';
105 wp_cache_set( 'calling-codes', $codes, 'countries' );
106 }
107
108 $calling_code = isset( $codes[ $cc ] ) ? $codes[ $cc ] : '';
109
110 if ( is_array( $calling_code ) ) {
111 $calling_code = $calling_code[0];
112 }
113
114 return $calling_code;
115 }
116
117 /**
118 * Get continents that the store ships to.
119 *
120 * @since 3.6.0
121 * @return array
122 */
123 public function get_shipping_continents() {
124 $continents = $this->get_continents();
125 $shipping_countries = $this->get_shipping_countries();
126 $shipping_country_codes = array_keys( $shipping_countries );
127 $shipping_continents = array();
128
129 foreach ( $continents as $continent_code => $continent ) {
130 if ( count( array_intersect( $continent['countries'], $shipping_country_codes ) ) ) {
131 $shipping_continents[ $continent_code ] = $continent;
132 }
133 }
134
135 return $shipping_continents;
136 }
137
138 /**
139 * Load the states.
140 *
141 * @deprecated 3.6.0 This method was used to load state files, but is no longer needed. @see get_states().
142 */
143 public function load_country_states() {
144 global $states;
145
146 $states = include WC()->plugin_path() . '/i18n/states.php';
147 $this->states = apply_filters( 'woocommerce_states', $states );
148 }
149
150 /**
151 * Get the states for a country.
152 *
153 * @param string $cc Country code.
154 * @return false|array of states
155 */
156 public function get_states( $cc = null ) {
157 if ( ! isset( $this->states ) ) {
158 $this->states = apply_filters( 'woocommerce_states', include WC()->plugin_path() . '/i18n/states.php' );
159 }
160
161 if ( ! is_null( $cc ) ) {
162 return isset( $this->states[ $cc ] ) ? $this->states[ $cc ] : false;
163 } else {
164 return $this->states;
165 }
166 }
167
168 /**
169 * Get the base address (first line) for the store.
170 *
171 * @since 3.1.1
172 * @return string
173 */
174 public function get_base_address() {
175 $base_address = get_option( 'woocommerce_store_address', '' );
176 return apply_filters( 'woocommerce_countries_base_address', $base_address );
177 }
178
179 /**
180 * Get the base address (second line) for the store.
181 *
182 * @since 3.1.1
183 * @return string
184 */
185 public function get_base_address_2() {
186 $base_address_2 = get_option( 'woocommerce_store_address_2', '' );
187 return apply_filters( 'woocommerce_countries_base_address_2', $base_address_2 );
188 }
189
190 /**
191 * Get the base country for the store.
192 *
193 * @return string
194 */
195 public function get_base_country() {
196 $default = wc_get_base_location();
197 return apply_filters( 'woocommerce_countries_base_country', $default['country'] );
198 }
199
200 /**
201 * Get the base state for the store.
202 *
203 * @return string
204 */
205 public function get_base_state() {
206 $default = wc_get_base_location();
207 return apply_filters( 'woocommerce_countries_base_state', $default['state'] );
208 }
209
210 /**
211 * Get the base city for the store.
212 *
213 * @version 3.1.1
214 * @return string
215 */
216 public function get_base_city() {
217 $base_city = get_option( 'woocommerce_store_city', '' );
218 return apply_filters( 'woocommerce_countries_base_city', $base_city );
219 }
220
221 /**
222 * Get the base postcode for the store.
223 *
224 * @since 3.1.1
225 * @return string
226 */
227 public function get_base_postcode() {
228 $base_postcode = get_option( 'woocommerce_store_postcode', '' );
229 return apply_filters( 'woocommerce_countries_base_postcode', $base_postcode );
230 }
231
232 /**
233 * Get countries that the store sells to.
234 *
235 * @return array
236 */
237 public function get_allowed_countries() {
238 if ( 'all' === get_option( 'woocommerce_allowed_countries' ) ) {
239 return apply_filters( 'woocommerce_countries_allowed_countries', $this->countries );
240 }
241
242 if ( 'all_except' === get_option( 'woocommerce_allowed_countries' ) ) {
243 $except_countries = get_option( 'woocommerce_all_except_countries', array() );
244
245 if ( ! $except_countries ) {
246 return $this->countries;
247 } else {
248 $all_except_countries = $this->countries;
249 foreach ( $except_countries as $country ) {
250 unset( $all_except_countries[ $country ] );
251 }
252 return apply_filters( 'woocommerce_countries_allowed_countries', $all_except_countries );
253 }
254 }
255
256 $countries = array();
257
258 $raw_countries = get_option( 'woocommerce_specific_allowed_countries', array() );
259
260 if ( $raw_countries ) {
261 foreach ( $raw_countries as $country ) {
262 $countries[ $country ] = $this->countries[ $country ];
263 }
264 }
265
266 return apply_filters( 'woocommerce_countries_allowed_countries', $countries );
267 }
268
269 /**
270 * Get countries that the store ships to.
271 *
272 * @return array
273 */
274 public function get_shipping_countries() {
275 if ( '' === get_option( 'woocommerce_ship_to_countries' ) ) {
276 return $this->get_allowed_countries();
277 }
278
279 if ( 'all' === get_option( 'woocommerce_ship_to_countries' ) ) {
280 return $this->countries;
281 }
282
283 $countries = array();
284
285 $raw_countries = get_option( 'woocommerce_specific_ship_to_countries' );
286
287 if ( $raw_countries ) {
288 foreach ( $raw_countries as $country ) {
289 $countries[ $country ] = $this->countries[ $country ];
290 }
291 }
292
293 return apply_filters( 'woocommerce_countries_shipping_countries', $countries );
294 }
295
296 /**
297 * Get allowed country states.
298 *
299 * @return array
300 */
301 public function get_allowed_country_states() {
302 if ( get_option( 'woocommerce_allowed_countries' ) !== 'specific' ) {
303 return $this->states;
304 }
305
306 $states = array();
307
308 $raw_countries = get_option( 'woocommerce_specific_allowed_countries' );
309
310 if ( $raw_countries ) {
311 foreach ( $raw_countries as $country ) {
312 if ( isset( $this->states[ $country ] ) ) {
313 $states[ $country ] = $this->states[ $country ];
314 }
315 }
316 }
317
318 return apply_filters( 'woocommerce_countries_allowed_country_states', $states );
319 }
320
321 /**
322 * Get shipping country states.
323 *
324 * @return array
325 */
326 public function get_shipping_country_states() {
327 if ( get_option( 'woocommerce_ship_to_countries' ) === '' ) {
328 return $this->get_allowed_country_states();
329 }
330
331 if ( get_option( 'woocommerce_ship_to_countries' ) !== 'specific' ) {
332 return $this->states;
333 }
334
335 $states = array();
336
337 $raw_countries = get_option( 'woocommerce_specific_ship_to_countries' );
338
339 if ( $raw_countries ) {
340 foreach ( $raw_countries as $country ) {
341 if ( ! empty( $this->states[ $country ] ) ) {
342 $states[ $country ] = $this->states[ $country ];
343 }
344 }
345 }
346
347 return apply_filters( 'woocommerce_countries_shipping_country_states', $states );
348 }
349
350 /**
351 * Gets an array of countries in the EU.
352 *
353 * @param string $type Type of countries to retrieve. Blank for EU member countries. eu_vat for EU VAT countries.
354 * @return string[]
355 */
356 public function get_european_union_countries( $type = '' ) {
357 $countries = array( 'AT', 'BE', 'BG', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GR', 'HU', 'HR', 'IE', 'IT', 'LT', 'LU', 'LV', 'MT', 'NL', 'PL', 'PT', 'RO', 'SE', 'SI', 'SK' );
358
359 if ( 'eu_vat' === $type ) {
360 $countries[] = 'MC';
361 $countries[] = 'IM';
362 // The UK is still part of the EU VAT zone.
363 $countries[] = 'GB';
364 }
365
366 return apply_filters( 'woocommerce_european_union_countries', $countries, $type );
367 }
368
369 /**
370 * 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
371 *
372 * @deprecated 4.0.0
373 * @since 3.9.0
374 * @return string[]
375 */
376 public function countries_using_vat() {
377 wc_deprecated_function( 'countries_using_vat', '4.0', 'WC_Countries::get_vat_countries' );
378 $countries = array( 'AL', 'AR', 'AZ', 'BS', 'BH', 'BY', 'BB', 'BO', 'EG', 'ET', 'CL', 'CO', 'EC', 'SV', 'FJ', 'GM', 'GH', 'GT', 'IN', 'IR', 'IL', 'KZ', 'MU', 'MK', 'MX', 'MD', 'MN', 'ME', 'NA', 'NP', 'NG', 'PS', 'PY', 'RU', 'RW', 'KN', 'SA', 'RS', 'ZA', 'KR', 'LK', 'TH', 'TR', 'UA', 'UY', 'UZ', 'VE', 'VN', 'AE' );
379
380 return apply_filters( 'woocommerce_countries_using_vat', $countries );
381 }
382
383 /**
384 * Gets an array of countries using VAT.
385 *
386 * @since 4.0.0
387 * @return string[] of country codes.
388 */
389 public function get_vat_countries() {
390 $eu_countries = $this->get_european_union_countries();
391 $vat_countries = array( 'AE', 'AL', 'AR', 'AZ', 'BB', 'BH', 'BO', 'BS', 'BY', 'CL', 'CO', 'EC', 'EG', 'ET', 'FJ', 'GB', 'GH', 'GM', 'GT', 'IL', 'IM', 'IN', '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' );
392
393 return apply_filters( 'woocommerce_vat_countries', array_merge( $eu_countries, $vat_countries ) );
394 }
395
396 /**
397 * Gets the correct string for shipping - either 'to the' or 'to'.
398 *
399 * @param string $country_code Country code.
400 * @return string
401 */
402 public function shipping_to_prefix( $country_code = '' ) {
403 $country_code = $country_code ? $country_code : WC()->customer->get_shipping_country();
404 $countries = array( 'GB', 'US', 'AE', 'CZ', 'DO', 'NL', 'PH', 'USAF' );
405 $return = in_array( $country_code, $countries, true ) ? __( 'to the', 'woocommerce' ) : __( 'to', 'woocommerce' );
406
407 return apply_filters( 'woocommerce_countries_shipping_to_prefix', $return, $country_code );
408 }
409
410 /**
411 * Prefix certain countries with 'the'.
412 *
413 * @param string $country_code Country code.
414 * @return string
415 */
416 public function estimated_for_prefix( $country_code = '' ) {
417 $country_code = $country_code ? $country_code : $this->get_base_country();
418 $countries = array( 'GB', 'US', 'AE', 'CZ', 'DO', 'NL', 'PH', 'USAF' );
419 $return = in_array( $country_code, $countries, true ) ? __( 'the', 'woocommerce' ) . ' ' : '';
420
421 return apply_filters( 'woocommerce_countries_estimated_for_prefix', $return, $country_code );
422 }
423
424 /**
425 * Correctly name tax in some countries VAT on the frontend.
426 *
427 * @return string
428 */
429 public function tax_or_vat() {
430 $return = in_array( $this->get_base_country(), $this->get_vat_countries(), true ) ? __( 'VAT', 'woocommerce' ) : __( 'Tax', 'woocommerce' );
431
432 return apply_filters( 'woocommerce_countries_tax_or_vat', $return );
433 }
434
435 /**
436 * Include the Inc Tax label.
437 *
438 * @return string
439 */
440 public function inc_tax_or_vat() {
441 $return = in_array( $this->get_base_country(), $this->get_vat_countries(), true ) ? __( '(incl. VAT)', 'woocommerce' ) : __( '(incl. tax)', 'woocommerce' );
442
443 return apply_filters( 'woocommerce_countries_inc_tax_or_vat', $return );
444 }
445
446 /**
447 * Include the Ex Tax label.
448 *
449 * @return string
450 */
451 public function ex_tax_or_vat() {
452 $return = in_array( $this->get_base_country(), $this->get_vat_countries(), true ) ? __( '(ex. VAT)', 'woocommerce' ) : __( '(ex. tax)', 'woocommerce' );
453
454 return apply_filters( 'woocommerce_countries_ex_tax_or_vat', $return );
455 }
456
457 /**
458 * Outputs the list of countries and states for use in dropdown boxes.
459 *
460 * @param string $selected_country Selected country.
461 * @param string $selected_state Selected state.
462 * @param bool $escape If we should escape HTML.
463 */
464 public function country_dropdown_options( $selected_country = '', $selected_state = '', $escape = false ) {
465 if ( $this->countries ) {
466 foreach ( $this->countries as $key => $value ) {
467 $states = $this->get_states( $key );
468 if ( $states ) {
469 echo '<optgroup label="' . esc_attr( $value ) . '">';
470 foreach ( $states as $state_key => $state_value ) {
471 echo '<option value="' . esc_attr( $key ) . ':' . esc_attr( $state_key ) . '"';
472
473 if ( $selected_country === $key && $selected_state === $state_key ) {
474 echo ' selected="selected"';
475 }
476
477 echo '>' . esc_html( $value ) . ' &mdash; ' . ( $escape ? esc_html( $state_value ) : $state_value ) . '</option>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
478
479 }
480 echo '</optgroup>';
481 } else {
482 echo '<option';
483 if ( $selected_country === $key && '*' === $selected_state ) {
484 echo ' selected="selected"';
485 }
486 echo ' value="' . esc_attr( $key ) . '">' . ( $escape ? esc_html( $value ) : $value ) . '</option>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
487 }
488 }
489 }
490 }
491
492 /**
493 * Get country address formats.
494 *
495 * These define how addresses are formatted for display in various countries.
496 *
497 * @return array
498 */
499 public function get_address_formats() {
500 if ( empty( $this->address_formats ) ) {
501 $this->address_formats = apply_filters(
502 'woocommerce_localisation_address_formats',
503 array(
504 'default' => "{name}\n{company}\n{address_1}\n{address_2}\n{city}\n{state}\n{postcode}\n{country}",
505 'AU' => "{name}\n{company}\n{address_1}\n{address_2}\n{city} {state} {postcode}\n{country}",
506 'AT' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
507 'BE' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
508 'CA' => "{company}\n{name}\n{address_1}\n{address_2}\n{city} {state_code} {postcode}\n{country}",
509 'CH' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
510 'CL' => "{company}\n{name}\n{address_1}\n{address_2}\n{state}\n{postcode} {city}\n{country}",
511 'CN' => "{country} {postcode}\n{state}, {city}, {address_2}, {address_1}\n{company}\n{name}",
512 'CZ' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
513 'DE' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
514 'EE' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
515 'FI' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
516 'DK' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
517 'FR' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city_upper}\n{country}",
518 'HK' => "{company}\n{first_name} {last_name_upper}\n{address_1}\n{address_2}\n{city_upper}\n{state_upper}\n{country}",
519 'HU' => "{name}\n{company}\n{city}\n{address_1}\n{address_2}\n{postcode}\n{country}",
520 'IN' => "{company}\n{name}\n{address_1}\n{address_2}\n{city} {postcode}\n{state}, {country}",
521 'IS' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
522 'IT' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode}\n{city}\n{state_upper}\n{country}",
523 'JP' => "{postcode}\n{state} {city} {address_1}\n{address_2}\n{company}\n{last_name} {first_name}\n{country}",
524 'TW' => "{company}\n{last_name} {first_name}\n{address_1}\n{address_2}\n{state}, {city} {postcode}\n{country}",
525 'LI' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
526 'NL' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
527 'NZ' => "{name}\n{company}\n{address_1}\n{address_2}\n{city} {postcode}\n{country}",
528 'NO' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
529 'PL' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
530 'PT' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
531 'SK' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
532 'RS' => "{name}\n{company}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
533 'SI' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
534 'ES' => "{name}\n{company}\n{address_1}\n{address_2}\n{postcode} {city}\n{state}\n{country}",
535 'SE' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
536 'TR' => "{name}\n{company}\n{address_1}\n{address_2}\n{postcode} {city} {state}\n{country}",
537 'UG' => "{name}\n{company}\n{address_1}\n{address_2}\n{city}\n{state}, {country}",
538 'US' => "{name}\n{company}\n{address_1}\n{address_2}\n{city}, {state_code} {postcode}\n{country}",
539 'VN' => "{name}\n{company}\n{address_1}\n{city}\n{country}",
540 )
541 );
542 }
543 return $this->address_formats;
544 }
545
546 /**
547 * Get country address format.
548 *
549 * @param array $args Arguments.
550 * @param string $separator How to separate address lines. @since 3.5.0.
551 * @return string
552 */
553 public function get_formatted_address( $args = array(), $separator = '<br/>' ) {
554 $default_args = array(
555 'first_name' => '',
556 'last_name' => '',
557 'company' => '',
558 'address_1' => '',
559 'address_2' => '',
560 'city' => '',
561 'state' => '',
562 'postcode' => '',
563 'country' => '',
564 );
565
566 $args = array_map( 'trim', wp_parse_args( $args, $default_args ) );
567 $state = $args['state'];
568 $country = $args['country'];
569
570 // Get all formats.
571 $formats = $this->get_address_formats();
572
573 // Get format for the address' country.
574 $format = ( $country && isset( $formats[ $country ] ) ) ? $formats[ $country ] : $formats['default'];
575
576 // Handle full country name.
577 $full_country = ( isset( $this->countries[ $country ] ) ) ? $this->countries[ $country ] : $country;
578
579 // Country is not needed if the same as base.
580 if ( $country === $this->get_base_country() && ! apply_filters( 'woocommerce_formatted_address_force_country_display', false ) ) {
581 $format = str_replace( '{country}', '', $format );
582 }
583
584 // Handle full state name.
585 $full_state = ( $country && $state && isset( $this->states[ $country ][ $state ] ) ) ? $this->states[ $country ][ $state ] : $state;
586
587 // Substitute address parts into the string.
588 $replace = array_map(
589 'esc_html',
590 apply_filters(
591 'woocommerce_formatted_address_replacements',
592 array(
593 '{first_name}' => $args['first_name'],
594 '{last_name}' => $args['last_name'],
595 '{name}' => $args['first_name'] . ' ' . $args['last_name'],
596 '{company}' => $args['company'],
597 '{address_1}' => $args['address_1'],
598 '{address_2}' => $args['address_2'],
599 '{city}' => $args['city'],
600 '{state}' => $full_state,
601 '{postcode}' => $args['postcode'],
602 '{country}' => $full_country,
603 '{first_name_upper}' => wc_strtoupper( $args['first_name'] ),
604 '{last_name_upper}' => wc_strtoupper( $args['last_name'] ),
605 '{name_upper}' => wc_strtoupper( $args['first_name'] . ' ' . $args['last_name'] ),
606 '{company_upper}' => wc_strtoupper( $args['company'] ),
607 '{address_1_upper}' => wc_strtoupper( $args['address_1'] ),
608 '{address_2_upper}' => wc_strtoupper( $args['address_2'] ),
609 '{city_upper}' => wc_strtoupper( $args['city'] ),
610 '{state_upper}' => wc_strtoupper( $full_state ),
611 '{state_code}' => wc_strtoupper( $state ),
612 '{postcode_upper}' => wc_strtoupper( $args['postcode'] ),
613 '{country_upper}' => wc_strtoupper( $full_country ),
614 ),
615 $args
616 )
617 );
618
619 $formatted_address = str_replace( array_keys( $replace ), $replace, $format );
620
621 // Clean up white space.
622 $formatted_address = preg_replace( '/ +/', ' ', trim( $formatted_address ) );
623 $formatted_address = preg_replace( '/\n\n+/', "\n", $formatted_address );
624
625 // Break newlines apart and remove empty lines/trim commas and white space.
626 $formatted_address = array_filter( array_map( array( $this, 'trim_formatted_address_line' ), explode( "\n", $formatted_address ) ) );
627
628 // Add html breaks.
629 $formatted_address = implode( $separator, $formatted_address );
630
631 // We're done!
632 return $formatted_address;
633 }
634
635 /**
636 * Trim white space and commas off a line.
637 *
638 * @param string $line Line.
639 * @return string
640 */
641 private function trim_formatted_address_line( $line ) {
642 return trim( $line, ', ' );
643 }
644
645 /**
646 * Returns the fields we show by default. This can be filtered later on.
647 *
648 * @return array
649 */
650 public function get_default_address_fields() {
651 if ( 'optional' === get_option( 'woocommerce_checkout_address_2_field', 'optional' ) ) {
652 $address_2_placeholder = __( 'Apartment, suite, unit, etc. (optional)', 'woocommerce' );
653 } else {
654 $address_2_placeholder = __( 'Apartment, suite, unit, etc.', 'woocommerce' );
655 }
656
657 $fields = array(
658 'first_name' => array(
659 'label' => __( 'First name', 'woocommerce' ),
660 'required' => true,
661 'class' => array( 'form-row-first' ),
662 'autocomplete' => 'given-name',
663 'priority' => 10,
664 ),
665 'last_name' => array(
666 'label' => __( 'Last name', 'woocommerce' ),
667 'required' => true,
668 'class' => array( 'form-row-last' ),
669 'autocomplete' => 'family-name',
670 'priority' => 20,
671 ),
672 'company' => array(
673 'label' => __( 'Company name', 'woocommerce' ),
674 'class' => array( 'form-row-wide' ),
675 'autocomplete' => 'organization',
676 'priority' => 30,
677 'required' => 'required' === get_option( 'woocommerce_checkout_company_field', 'optional' ),
678 ),
679 'country' => array(
680 'type' => 'country',
681 'label' => __( 'Country / Region', 'woocommerce' ),
682 'required' => true,
683 'class' => array( 'form-row-wide', 'address-field', 'update_totals_on_change' ),
684 'autocomplete' => 'country',
685 'priority' => 40,
686 ),
687 'address_1' => array(
688 'label' => __( 'Street address', 'woocommerce' ),
689 /* translators: use local order of street name and house number. */
690 'placeholder' => esc_attr__( 'House number and street name', 'woocommerce' ),
691 'required' => true,
692 'class' => array( 'form-row-wide', 'address-field' ),
693 'autocomplete' => 'address-line1',
694 'priority' => 50,
695 ),
696 'address_2' => array(
697 'placeholder' => esc_attr( $address_2_placeholder ),
698 'class' => array( 'form-row-wide', 'address-field' ),
699 'autocomplete' => 'address-line2',
700 'priority' => 60,
701 'required' => 'required' === get_option( 'woocommerce_checkout_address_2_field', 'optional' ),
702 ),
703 'city' => array(
704 'label' => __( 'Town / City', 'woocommerce' ),
705 'required' => true,
706 'class' => array( 'form-row-wide', 'address-field' ),
707 'autocomplete' => 'address-level2',
708 'priority' => 70,
709 ),
710 'state' => array(
711 'type' => 'state',
712 'label' => __( 'State / County', 'woocommerce' ),
713 'required' => true,
714 'class' => array( 'form-row-wide', 'address-field' ),
715 'validate' => array( 'state' ),
716 'autocomplete' => 'address-level1',
717 'priority' => 80,
718 ),
719 'postcode' => array(
720 'label' => __( 'Postcode / ZIP', 'woocommerce' ),
721 'required' => true,
722 'class' => array( 'form-row-wide', 'address-field' ),
723 'validate' => array( 'postcode' ),
724 'autocomplete' => 'postal-code',
725 'priority' => 90,
726 ),
727 );
728
729 if ( 'hidden' === get_option( 'woocommerce_checkout_company_field', 'optional' ) ) {
730 unset( $fields['company'] );
731 }
732
733 if ( 'hidden' === get_option( 'woocommerce_checkout_address_2_field', 'optional' ) ) {
734 unset( $fields['address_2'] );
735 }
736
737 $default_address_fields = apply_filters( 'woocommerce_default_address_fields', $fields );
738 // Sort each of the fields based on priority.
739 uasort( $default_address_fields, 'wc_checkout_fields_uasort_comparison' );
740
741 return $default_address_fields;
742 }
743
744 /**
745 * Get JS selectors for fields which are shown/hidden depending on the locale.
746 *
747 * @return array
748 */
749 public function get_country_locale_field_selectors() {
750 $locale_fields = array(
751 'address_1' => '#billing_address_1_field, #shipping_address_1_field',
752 'address_2' => '#billing_address_2_field, #shipping_address_2_field',
753 'state' => '#billing_state_field, #shipping_state_field, #calc_shipping_state_field',
754 'postcode' => '#billing_postcode_field, #shipping_postcode_field, #calc_shipping_postcode_field',
755 'city' => '#billing_city_field, #shipping_city_field, #calc_shipping_city_field',
756 );
757 return apply_filters( 'woocommerce_country_locale_field_selectors', $locale_fields );
758 }
759
760 /**
761 * Get country locale settings.
762 *
763 * These locales override the default country selections after a country is chosen.
764 *
765 * @return array
766 */
767 public function get_country_locale() {
768 if ( empty( $this->locale ) ) {
769 $this->locale = apply_filters(
770 'woocommerce_get_country_locale',
771 array(
772 'AE' => array(
773 'postcode' => array(
774 'required' => false,
775 'hidden' => true,
776 ),
777 'state' => array(
778 'required' => false,
779 ),
780 ),
781 'AF' => array(
782 'state' => array(
783 'required' => false,
784 ),
785 ),
786 'AO' => array(
787 'postcode' => array(
788 'required' => false,
789 'hidden' => true,
790 ),
791 'state' => array(
792 'label' => __( 'Province', 'woocommerce' ),
793 ),
794 ),
795 'AT' => array(
796 'postcode' => array(
797 'priority' => 65,
798 ),
799 'state' => array(
800 'required' => false,
801 ),
802 ),
803 'AU' => array(
804 'city' => array(
805 'label' => __( 'Suburb', 'woocommerce' ),
806 ),
807 'postcode' => array(
808 'label' => __( 'Postcode', 'woocommerce' ),
809 ),
810 'state' => array(
811 'label' => __( 'State', 'woocommerce' ),
812 ),
813 ),
814 'AX' => array(
815 'postcode' => array(
816 'priority' => 65,
817 ),
818 'state' => array(
819 'required' => false,
820 ),
821 ),
822 'BD' => array(
823 'postcode' => array(
824 'required' => false,
825 ),
826 'state' => array(
827 'label' => __( 'District', 'woocommerce' ),
828 ),
829 ),
830 'BE' => array(
831 'postcode' => array(
832 'priority' => 65,
833 ),
834 'state' => array(
835 'required' => false,
836 'label' => __( 'Province', 'woocommerce' ),
837 ),
838 ),
839 'BH' => array(
840 'postcode' => array(
841 'required' => false,
842 ),
843 'state' => array(
844 'required' => false,
845 ),
846 ),
847 'BI' => array(
848 'state' => array(
849 'required' => false,
850 ),
851 ),
852 'BO' => array(
853 'postcode' => array(
854 'required' => false,
855 'hidden' => true,
856 ),
857 ),
858 'BS' => array(
859 'postcode' => array(
860 'required' => false,
861 'hidden' => true,
862 ),
863 ),
864 'CA' => array(
865 'postcode' => array(
866 'label' => __( 'Postal code', 'woocommerce' ),
867 ),
868 'state' => array(
869 'label' => __( 'Province', 'woocommerce' ),
870 ),
871 ),
872 'CH' => array(
873 'postcode' => array(
874 'priority' => 65,
875 ),
876 'state' => array(
877 'label' => __( 'Canton', 'woocommerce' ),
878 'required' => false,
879 ),
880 ),
881 'CL' => array(
882 'city' => array(
883 'required' => true,
884 ),
885 'postcode' => array(
886 'required' => false,
887 ),
888 'state' => array(
889 'label' => __( 'Region', 'woocommerce' ),
890 ),
891 ),
892 'CN' => array(
893 'state' => array(
894 'label' => __( 'Province', 'woocommerce' ),
895 ),
896 ),
897 'CO' => array(
898 'postcode' => array(
899 'required' => false,
900 ),
901 ),
902 'CZ' => array(
903 'state' => array(
904 'required' => false,
905 ),
906 ),
907 'DE' => array(
908 'postcode' => array(
909 'priority' => 65,
910 ),
911 'state' => array(
912 'required' => false,
913 'hidden' => true,
914 ),
915 ),
916 'DK' => array(
917 'postcode' => array(
918 'priority' => 65,
919 ),
920 'state' => array(
921 'required' => false,
922 'hidden' => true,
923 ),
924 ),
925 'EE' => array(
926 'postcode' => array(
927 'priority' => 65,
928 ),
929 'state' => array(
930 'required' => false,
931 ),
932 ),
933 'FI' => array(
934 'postcode' => array(
935 'priority' => 65,
936 ),
937 'state' => array(
938 'required' => false,
939 ),
940 ),
941 'FR' => array(
942 'postcode' => array(
943 'priority' => 65,
944 ),
945 'state' => array(
946 'required' => false,
947 ),
948 ),
949 'GH' => array(
950 'postcode' => array(
951 'required' => false,
952 ),
953 'state' => array(
954 'label' => __( 'Region', 'woocommerce' ),
955 ),
956 ),
957 'GP' => array(
958 'state' => array(
959 'required' => false,
960 ),
961 ),
962 'GF' => array(
963 'state' => array(
964 'required' => false,
965 ),
966 ),
967 'GR' => array(
968 'state' => array(
969 'required' => false,
970 ),
971 ),
972 'HK' => array(
973 'postcode' => array(
974 'required' => false,
975 ),
976 'city' => array(
977 'label' => __( 'Town / District', 'woocommerce' ),
978 ),
979 'state' => array(
980 'label' => __( 'Region', 'woocommerce' ),
981 ),
982 ),
983 'HU' => array(
984 'state' => array(
985 'label' => __( 'County', 'woocommerce' ),
986 ),
987 ),
988 'ID' => array(
989 'state' => array(
990 'label' => __( 'Province', 'woocommerce' ),
991 ),
992 ),
993 'IE' => array(
994 'postcode' => array(
995 'required' => false,
996 'label' => __( 'Eircode', 'woocommerce' ),
997 ),
998 'state' => array(
999 'label' => __( 'County', 'woocommerce' ),
1000 ),
1001 ),
1002 'IS' => array(
1003 'postcode' => array(
1004 'priority' => 65,
1005 ),
1006 'state' => array(
1007 'required' => false,
1008 ),
1009 ),
1010 'IL' => array(
1011 'postcode' => array(
1012 'priority' => 65,
1013 ),
1014 'state' => array(
1015 'required' => false,
1016 ),
1017 ),
1018 'IM' => array(
1019 'state' => array(
1020 'required' => false,
1021 ),
1022 ),
1023 'IT' => array(
1024 'postcode' => array(
1025 'priority' => 65,
1026 ),
1027 'state' => array(
1028 'required' => true,
1029 'label' => __( 'Province', 'woocommerce' ),
1030 ),
1031 ),
1032 'JP' => array(
1033 'last_name' => array(
1034 'class' => array( 'form-row-first' ),
1035 'priority' => 10,
1036 ),
1037 'first_name' => array(
1038 'class' => array( 'form-row-last' ),
1039 'priority' => 20,
1040 ),
1041 'postcode' => array(
1042 'class' => array( 'form-row-first' ),
1043 'priority' => 65,
1044 ),
1045 'state' => array(
1046 'label' => __( 'Prefecture', 'woocommerce' ),
1047 'class' => array( 'form-row-last' ),
1048 'priority' => 66,
1049 ),
1050 'city' => array(
1051 'priority' => 67,
1052 ),
1053 'address_1' => array(
1054 'priority' => 68,
1055 ),
1056 'address_2' => array(
1057 'priority' => 69,
1058 ),
1059 ),
1060 'KR' => array(
1061 'state' => array(
1062 'required' => false,
1063 ),
1064 ),
1065 'KW' => array(
1066 'state' => array(
1067 'required' => false,
1068 ),
1069 ),
1070 'LV' => array(
1071 'state' => array(
1072 'label' => __( 'Municipality', 'woocommerce' ),
1073 'required' => false,
1074 ),
1075 ),
1076 'LB' => array(
1077 'state' => array(
1078 'required' => false,
1079 ),
1080 ),
1081 'MQ' => array(
1082 'state' => array(
1083 'required' => false,
1084 ),
1085 ),
1086 'MT' => array(
1087 'state' => array(
1088 'required' => false,
1089 ),
1090 ),
1091 'MZ' => array(
1092 'postcode' => array(
1093 'required' => false,
1094 'hidden' => true,
1095 ),
1096 'state' => array(
1097 'label' => __( 'Province', 'woocommerce' ),
1098 ),
1099 ),
1100 'NL' => array(
1101 'postcode' => array(
1102 'priority' => 65,
1103 ),
1104 'state' => array(
1105 'required' => false,
1106 'label' => __( 'Province', 'woocommerce' ),
1107 ),
1108 ),
1109 'NG' => array(
1110 'postcode' => array(
1111 'label' => __( 'Postcode', 'woocommerce' ),
1112 'required' => false,
1113 'hidden' => true,
1114 ),
1115 'state' => array(
1116 'label' => __( 'State', 'woocommerce' ),
1117 ),
1118 ),
1119 'NZ' => array(
1120 'postcode' => array(
1121 'label' => __( 'Postcode', 'woocommerce' ),
1122 ),
1123 'state' => array(
1124 'required' => false,
1125 'label' => __( 'Region', 'woocommerce' ),
1126 ),
1127 ),
1128 'NO' => array(
1129 'postcode' => array(
1130 'priority' => 65,
1131 ),
1132 'state' => array(
1133 'required' => false,
1134 ),
1135 ),
1136 'NP' => array(
1137 'state' => array(
1138 'label' => __( 'State / Zone', 'woocommerce' ),
1139 ),
1140 'postcode' => array(
1141 'required' => false,
1142 ),
1143 ),
1144 'PL' => array(
1145 'postcode' => array(
1146 'priority' => 65,
1147 ),
1148 'state' => array(
1149 'required' => false,
1150 ),
1151 ),
1152 'PT' => array(
1153 'state' => array(
1154 'required' => false,
1155 ),
1156 ),
1157 'RE' => array(
1158 'state' => array(
1159 'required' => false,
1160 ),
1161 ),
1162 'RO' => array(
1163 'state' => array(
1164 'label' => __( 'County', 'woocommerce' ),
1165 'required' => true,
1166 ),
1167 ),
1168 'RS' => array(
1169 'state' => array(
1170 'required' => false,
1171 'hidden' => true,
1172 ),
1173 ),
1174 'SG' => array(
1175 'state' => array(
1176 'required' => false,
1177 ),
1178 'city' => array(
1179 'required' => false,
1180 ),
1181 ),
1182 'SK' => array(
1183 'postcode' => array(
1184 'priority' => 65,
1185 ),
1186 'state' => array(
1187 'required' => false,
1188 ),
1189 ),
1190 'SI' => array(
1191 'postcode' => array(
1192 'priority' => 65,
1193 ),
1194 'state' => array(
1195 'required' => false,
1196 ),
1197 ),
1198 'SR' => array(
1199 'postcode' => array(
1200 'required' => false,
1201 'hidden' => true,
1202 ),
1203 ),
1204 'ES' => array(
1205 'postcode' => array(
1206 'priority' => 65,
1207 ),
1208 'state' => array(
1209 'label' => __( 'Province', 'woocommerce' ),
1210 ),
1211 ),
1212 'LI' => array(
1213 'postcode' => array(
1214 'priority' => 65,
1215 ),
1216 'state' => array(
1217 'label' => __( 'Municipality', 'woocommerce' ),
1218 'required' => false,
1219 ),
1220 ),
1221 'LK' => array(
1222 'state' => array(
1223 'required' => false,
1224 ),
1225 ),
1226 'LU' => array(
1227 'state' => array(
1228 'required' => false,
1229 ),
1230 ),
1231 'MD' => array(
1232 'state' => array(
1233 'label' => __( 'Municipality / District', 'woocommerce' ),
1234 ),
1235 ),
1236 'SE' => array(
1237 'postcode' => array(
1238 'priority' => 65,
1239 ),
1240 'state' => array(
1241 'required' => false,
1242 'hidden' => true,
1243 ),
1244 ),
1245 'TR' => array(
1246 'postcode' => array(
1247 'priority' => 65,
1248 ),
1249 'state' => array(
1250 'label' => __( 'Province', 'woocommerce' ),
1251 ),
1252 ),
1253 'UG' => array(
1254 'postcode' => array(
1255 'required' => false,
1256 'hidden' => true,
1257 ),
1258 'city' => array(
1259 'label' => __( 'Town / Village', 'woocommerce' ),
1260 'required' => true,
1261 ),
1262 'state' => array(
1263 'label' => __( 'District', 'woocommerce' ),
1264 'required' => true,
1265 ),
1266 ),
1267 'US' => array(
1268 'postcode' => array(
1269 'label' => __( 'ZIP', 'woocommerce' ),
1270 ),
1271 'state' => array(
1272 'label' => __( 'State', 'woocommerce' ),
1273 ),
1274 ),
1275 'GB' => array(
1276 'postcode' => array(
1277 'label' => __( 'Postcode', 'woocommerce' ),
1278 ),
1279 'state' => array(
1280 'label' => __( 'County', 'woocommerce' ),
1281 'required' => false,
1282 ),
1283 ),
1284 'ST' => array(
1285 'postcode' => array(
1286 'required' => false,
1287 'hidden' => true,
1288 ),
1289 'state' => array(
1290 'label' => __( 'District', 'woocommerce' ),
1291 ),
1292 ),
1293 'VN' => array(
1294 'state' => array(
1295 'required' => false,
1296 'hidden' => true,
1297 ),
1298 'postcode' => array(
1299 'priority' => 65,
1300 'required' => false,
1301 'hidden' => false,
1302 ),
1303 'address_2' => array(
1304 'required' => false,
1305 'hidden' => true,
1306 ),
1307 ),
1308 'WS' => array(
1309 'postcode' => array(
1310 'required' => false,
1311 'hidden' => true,
1312 ),
1313 ),
1314 'YT' => array(
1315 'state' => array(
1316 'required' => false,
1317 ),
1318 ),
1319 'ZA' => array(
1320 'state' => array(
1321 'label' => __( 'Province', 'woocommerce' ),
1322 ),
1323 ),
1324 'ZW' => array(
1325 'postcode' => array(
1326 'required' => false,
1327 'hidden' => true,
1328 ),
1329 ),
1330 )
1331 );
1332
1333 $this->locale = array_intersect_key( $this->locale, array_merge( $this->get_allowed_countries(), $this->get_shipping_countries() ) );
1334
1335 // Default Locale Can be filtered to override fields in get_address_fields(). Countries with no specific locale will use default.
1336 $this->locale['default'] = apply_filters( 'woocommerce_get_country_locale_default', $this->get_default_address_fields() );
1337
1338 // Filter default AND shop base locales to allow overides via a single function. These will be used when changing countries on the checkout.
1339 if ( ! isset( $this->locale[ $this->get_base_country() ] ) ) {
1340 $this->locale[ $this->get_base_country() ] = $this->locale['default'];
1341 }
1342
1343 $this->locale['default'] = apply_filters( 'woocommerce_get_country_locale_base', $this->locale['default'] );
1344 $this->locale[ $this->get_base_country() ] = apply_filters( 'woocommerce_get_country_locale_base', $this->locale[ $this->get_base_country() ] );
1345 }
1346
1347 return $this->locale;
1348 }
1349
1350 /**
1351 * Apply locale and get address fields.
1352 *
1353 * @param mixed $country Country.
1354 * @param string $type Address type, defaults to 'billing_'.
1355 * @return array
1356 */
1357 public function get_address_fields( $country = '', $type = 'billing_' ) {
1358 if ( ! $country ) {
1359 $country = $this->get_base_country();
1360 }
1361
1362 $fields = $this->get_default_address_fields();
1363 $locale = $this->get_country_locale();
1364
1365 if ( isset( $locale[ $country ] ) ) {
1366 $fields = wc_array_overlay( $fields, $locale[ $country ] );
1367 }
1368
1369 // Prepend field keys.
1370 $address_fields = array();
1371
1372 foreach ( $fields as $key => $value ) {
1373 if ( 'state' === $key ) {
1374 $value['country_field'] = $type . 'country';
1375 $value['country'] = $country;
1376 }
1377 $address_fields[ $type . $key ] = $value;
1378 }
1379
1380 // Add email and phone fields.
1381 if ( 'billing_' === $type ) {
1382 if ( 'hidden' !== get_option( 'woocommerce_checkout_phone_field', 'required' ) ) {
1383 $address_fields['billing_phone'] = array(
1384 'label' => __( 'Phone', 'woocommerce' ),
1385 'required' => 'required' === get_option( 'woocommerce_checkout_phone_field', 'required' ),
1386 'type' => 'tel',
1387 'class' => array( 'form-row-wide' ),
1388 'validate' => array( 'phone' ),
1389 'autocomplete' => 'tel',
1390 'priority' => 100,
1391 );
1392 }
1393 $address_fields['billing_email'] = array(
1394 'label' => __( 'Email address', 'woocommerce' ),
1395 'required' => true,
1396 'type' => 'email',
1397 'class' => array( 'form-row-wide' ),
1398 'validate' => array( 'email' ),
1399 'autocomplete' => 'no' === get_option( 'woocommerce_registration_generate_username' ) ? 'email' : 'email username',
1400 'priority' => 110,
1401 );
1402 }
1403
1404 /**
1405 * Important note on this filter: Changes to address fields can and will be overridden by
1406 * the woocommerce_default_address_fields. The locales/default locales apply on top based
1407 * on country selection. If you want to change things like the required status of an
1408 * address field, filter woocommerce_default_address_fields instead.
1409 */
1410 $address_fields = apply_filters( 'woocommerce_' . $type . 'fields', $address_fields, $country );
1411 // Sort each of the fields based on priority.
1412 uasort( $address_fields, 'wc_checkout_fields_uasort_comparison' );
1413
1414 return $address_fields;
1415 }
1416 }
1417