Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
Fix state validation to compare state codes, and only validate if a c…
Browse files Browse the repository at this point in the history
…ountry is given (#5132)

* Only get valid states from wc if there is a country

* Shared validation logic which uses keys
  • Loading branch information
mikejolley authored Nov 16, 2021
1 parent 127f6ce commit 1eb90c1
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 14 deletions.
48 changes: 38 additions & 10 deletions src/StoreApi/Schemas/AbstractAddressSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,18 +107,47 @@ public function sanitize_callback( $address, $request, $param ) {
}

/**
* Format a state based on the country. If country has defined states, will return an upper case state code.
* Get list of states for a country.
*
* @param string $country Country code.
* @return array Array of state names indexed by state keys.
*/
protected function get_states_for_country( $country ) {
return $country ? array_filter( (array) \wc()->countries->get_states( $country ) ) : [];
}

/**
* Validate provided state against a countries list of defined states.
*
* If there are no defined states for a country, any given state is valid.
*
* @param string $state State name or code (sanitized).
* @param string $country Country code.
* @return boolean Valid or not valid.
*/
protected function validate_state( $state, $country ) {
$states = $this->get_states_for_country( $country );

if ( count( $states ) && ! in_array( \wc_strtoupper( $state ), array_map( '\wc_strtoupper', array_keys( $states ) ), true ) ) {
return false;
}

return true;
}

/**
* Format a state based on the country. If country has defined states, will return a valid upper case state code.
*
* @param string $state State name or code (sanitized).
* @param string $country Country code.
* @return string
*/
protected function format_state( $state, $country ) {
$states = $country ? array_filter( (array) wc()->countries->get_states( $country ) ) : [];
$states = $this->get_states_for_country( $country );

if ( count( $states ) ) {
$state = wc_strtoupper( $state );
$state_values = array_map( 'wc_strtoupper', array_flip( array_map( 'wc_strtoupper', $states ) ) );
$state = \wc_strtoupper( $state );
$state_values = array_map( 'wc_strtoupper', array_flip( array_map( '\wc_strtoupper', $states ) ) );

if ( isset( $state_values[ $state ] ) ) {
// Convert to state code if a state name was provided.
Expand Down Expand Up @@ -163,15 +192,14 @@ public function validate_callback( $address, $request, $param ) {
return $errors;
}

$states = array_filter( array_keys( (array) wc()->countries->get_states( $address['country'] ) ) );

if ( ! empty( $address['state'] ) && count( $states ) && ! in_array( $address['state'], $states, true ) ) {
if ( ! empty( $address['state'] ) && ! $this->validate_state( $address['state'], $address['country'] ) ) {
$errors->add(
'invalid_state',
sprintf(
/* translators: %s valid states */
__( 'The provided state is not valid. Must be one of: %s', 'woo-gutenberg-products-block' ),
implode( ', ', $states )
/* translators: %1$s given state, %2$s valid states */
__( 'The provided state (%1$s) is not valid. Must be one of: %2$s', 'woo-gutenberg-products-block' ),
esc_html( $address['state'] ),
implode( ', ', array_keys( $this->get_states_for_country( $address['country'] ) ) )
)
);
}
Expand Down
3 changes: 1 addition & 2 deletions src/StoreApi/Schemas/BillingAddressSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,8 @@ public function get_item_response( $address ) {
if ( ( $address instanceof \WC_Customer || $address instanceof \WC_Order ) ) {
$billing_country = $address->get_billing_country();
$billing_state = $address->get_billing_state();
$valid_states = array_filter( (array) wc()->countries->get_states( $billing_country ) );

if ( ! empty( $billing_state ) && count( $valid_states ) && ! in_array( $billing_state, $valid_states, true ) ) {
if ( ! $this->validate_state( $billing_state, $billing_country ) ) {
$billing_state = '';
}

Expand Down
3 changes: 1 addition & 2 deletions src/StoreApi/Schemas/ShippingAddressSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,8 @@ public function get_item_response( $address ) {

$shipping_country = $address->get_shipping_country();
$shipping_state = $address->get_shipping_state();
$valid_states = array_filter( (array) wc()->countries->get_states( $shipping_country ) );

if ( ! empty( $shipping_state ) && count( $valid_states ) && ! in_array( $shipping_state, $valid_states, true ) ) {
if ( ! $this->validate_state( $shipping_state, $shipping_country ) ) {
$shipping_state = '';
}

Expand Down

0 comments on commit 1eb90c1

Please sign in to comment.