Я пытался решить эту проблему в течение нескольких дней, и либо я упускаю что-то явно очевидное (возможно / вероятно), в Woocommerce есть (несерьезная) ошибка в форматировании адреса (возможно, но маловероятно) ) или то, что я пытаюсь сделать, просто невозможно при использовании формата по умолчанию (скорее всего), поэтому я не возражаю, если кто-то обратится к этому за меня.
Конечной целью является форматирование адресов WC, как описано ниже.
- (AF1) Там, где нет списка штатов (в states.php) для страны, форматируйте адрес, как показано ниже. Это включает, где страна отсутствует в states.php или указана с пустым массивом (например,
'AF' => array(),
)
Address_1 (form-row-wide)
Town (form-row-first) Postcode (form-row-last)
- (AF2) Если список состояний существует (в states.php) и не является пустым, отформатируйте адрес как
Address_1 (form-row-first) Town/City (form-row-last)
State (form-row-first) Postcode (form-row-last)
NB. Я понял, что во всем, что я пробовал, есть форматы адресов, которые не вписываются в вышесказанное, где почтовый индекс или город не являются частью адреса (например, Сингапур не требует города, а ОАЭ не нет почтовых индексов). Я еще не рассматривал эти варианты использования, поскольку изо всех сил стараюсь, чтобы вышеуказанные форматы (которые охватывают большинство стран) работали правильно.
Результаты, которые я получаю, в лучшем случае противоречивы. Я подробно описал некоторые из них ниже.
Изображение, показывающее результаты (зеленым цветом обозначено 100% для этого сценария, красным выделено неправильное значение для указанного формата)
Код, который дает результаты на рисунке ниже. Я перепробовал много разных перестановок, но, похоже, просто не могу получить тот, который работает.
add_filter( 'woocommerce_default_address_fields', 'AF_woocommerce_default_address_fields', 100, 1 );
function AF_woocommerce_default_address_fields( $fields ) {
$fields['state']['required'] = false;
$fields['state']['hidden'] = true;
$fields['state']['label'] = 'this is the default label for state';
$fields['state']['class'] = array('form-row-first', 'address-field' );
unset( $fields['address_2'] );
unset( $fields['company'] );
$fields['city']['class'] = array( 'form-row-first', 'address-field' );
$fields['postcode']['class'] = array( 'form-row-last', 'address-field' );
return $fields;
}
add_filter( 'woocommerce_get_country_locale', 'AF_woocommerce_get_country_locale', 100, 1 );
function AF_woocommerce_get_country_locale( $locale ) {
$woo_countries = new WC_Countries();
$states = $woo_countries->get_states();
foreach( $locale as $country => $locale_details ) {
if( isset( $states[$country] ) ) {
if( ! empty( $states[$country] ) ) {
$locale[$country]['state']['required'] = true;
$locale[$country]['state']['label'] = 'this is state label';
$locale[$country]['state']['hidden'] = false;
$locale[$country]['city']['class'] = array( 'form-row-last', 'address-field' );
$locale[$country]['state']['class'] = array( 'form-row-first', 'address-field' );
$locale[$country]['address_1']['class'] = array( 'form-row-first', 'address-field' );
$locale[$country]['postcode']['class'] = array( 'form-row-last', 'address-field' );
}
}
}
return $locale;
}
Я начинаю думать, что вместо того, чтобы полагаться на формат по умолчанию, который мне нужно заполнить и объединить (в woocommerce_get_country_locale
) со всеми странами и указать формат для каждой отдельной страны, который, хотя и достаточно легко сделать, выглядит как неправильный путь к вещам.
Кто-нибудь сталкивался с этим раньше или есть идеи относительно того, что мне не хватает?
Спасибо
РЕДАКТИРОВАТЬ: Кажется, даже установка формата для каждой страны в woocommerce_get_country_locale
(игнорирование того, что было передано и возврат совершенно нового массива) также не работает. Изображение, показывающее результаты этого
РЕДАКТИРОВАТЬ 2: Подумайте, есть ли ошибка в WC или она просто не закодирована для исправления классов при изменении страны - см. Ниже.
Дальнейшее расследование показывает, что js не применяет классы при изменении страны. С помощью приведенного ниже кода все страны будут отображать поле состояния (при необходимости), если список состояний существует, и не будут отображать поле состояния, когда список не существует.
add_filter( 'woocommerce_states', 'AF_woocommerce_states', 10, 1 );
function AF_woocommerce_states( $states ){
$woo_countries = new WC_Countries();
$wc_countries = $woo_countries->get_countries();
foreach( $wc_countries as $country => $country_name ) {
if( ! isset( $states[$country] ) ) {
$states[$country] = array();
}
}
return $states;
}
add_filter( 'woocommerce_default_address_fields', 'FA_woocommerce_default_address_fields' );
function FA_woocommerce_default_address_fields( $fields ) {
unset( $fields['company'] );
unset( $fields['address_2'] );
return $fields;
}
add_filter( 'woocommerce_get_country_locale', 'AF_woocommerce_get_country_locale' );
function AF_woocommerce_get_country_locale( $locale ) {
$woo_countries = new WC_Countries();
$wc_states = $woo_countries->get_states();
foreach( $wc_states as $country => $state_details ) {
if( empty( $state_details ) ) {
$locale[$country]['state']['required'] = false;
} else {
if( isset( $locale[$country] ) && $locale[$country]['state']['required'] === false ) {
$locale[$country]['state']['required'] = true;
}
}
}
return $locale;
}
Если вы затем добавите классы в каждую страну, изменив последний фильтр (woocommerce_get_country_locale) выше на код ниже, тогда произойдет следующее.
NB - все еще игнорируем те страны, которые переупорядочивают поля штата / почтового индекса на минуту.
После ввода / обновления оформления заказа в стране, в которой требуется состояние (например, существует список состояний), формат будет правильным, как
address_1 (form-row-first) city (form-row-last)
state (form-row-first) postcode (form-row-last)
При переходе от вышеуказанного (скажем, США) к другой стране, для которой требуется штат (например, существует список штатов - скажем, NZ), формат сохраняется, как указано выше, и является правильным.
Если вы переходите из США или Новой Зеландии в страну, в которой не требуется штат, скажем, Великобритания, то поле штата скрыто, однако js не применяет классы Великобритании к остальным полям, и формат становится
address_1 (form-row-first) city (form-row-last)
<blank space where state was> postcode (form-row-last)
Когда это должно быть
address_1 (form-row-wide)
city (form-row-first) postcode (form-row-last)
Обратное также верно, когда вы вводите оформление заказа / обновление в стране, для которой не требуется состояние, тогда формат является правильным:
address_1 (form-row-wide)
city (form-row-first) postcode (form-row-last)
При переходе в другую страну, для которой не требуется состояние, формат сохраняется. При переходе на страну, для которой требуется состояние, формат становится
address_1 (form-row-wide)
city (form-row-first) <blank space>
state (form-row-wide
<blank space> postcode (form-row last)
код ниже
add_filter( 'woocommerce_get_country_locale', 'AF_woocommerce_get_country_locale' );
function AF_woocommerce_get_country_locale( $locale ) {
$woo_countries = new WC_Countries();
$wc_states = $woo_countries->get_states();
foreach( $wc_states as $country => $state_details ) {
if( empty( $state_details ) ) {
$locale[$country]['state']['required'] = false;
$locale[$country]['address_1']['class'] = array( 'form-row-wide', 'address-field' );
$locale[$country]['city']['class'] = array( 'form-row-first', 'address-field' );
$locale[$country]['postcode']['class'] = array( 'form-row-last', 'address-field' );
} else {
if( isset( $locale[$country] ) && $locale[$country]['state']['required'] === false ) {
$locale[$country]['state']['required'] = true;
}
$locale[$country]['address_1']['class'] = array( 'form-row-first', 'address-field' );
$locale[$country]['city']['class'] = array( 'form-row-last', 'address-field' );
$locale[$country]['state']['class'] = array( 'form-row-first', 'address-field' );
$locale[$country]['postcode']['class'] = array( 'form-row-last', 'address-field' );
}
}
return $locale;
}