Automattic\WooCommerce\StoreApi\Schemas\V1

AbstractAddressSchema::validate_callback()publicWC 1.0

Validate the given address object.

Method of the class: AbstractAddressSchema{}

No Hooks.

Return

true|\WP_Error.

Usage

$AbstractAddressSchema = new AbstractAddressSchema();
$AbstractAddressSchema->validate_callback( $address, $request, $param );
$address(array) (required)
Value being sanitized.
$request(\WP_REST_Request) (required)
The Request.
$param(string) (required)
The param being sanitized.

Notes

AbstractAddressSchema::validate_callback() code WC 9.4.2

public function validate_callback( $address, $request, $param ) {
	$errors          = new \WP_Error();
	$address         = (array) $address;
	$validation_util = new ValidationUtils();
	$schema          = $this->get_properties();

	// Omit all keys from address that are not in the schema. This should account for email.
	$address = array_intersect_key( $address, $schema );

	// The flow is Validate -> Sanitize -> Re-Validate
	// First validation step is to ensure fields match their schema, then we sanitize to put them in the
	// correct format, and finally the second validation step is to ensure the correctly-formatted values
	// match what we expect (postcode etc.).
	foreach ( $address as $key => $value ) {

		// Only run specific validation on properties that are defined in the schema and present in the address.
		// This is for partial address pushes when only part of a customer address is sent.
		// Full schema address validation still happens later, so empty, required values are disallowed.
		if ( empty( $schema[ $key ] ) || empty( $address[ $key ] ) ) {
			continue;
		}

		if ( is_wp_error( rest_validate_value_from_schema( $value, $schema[ $key ], $key ) ) ) {
			$errors->add(
				'invalid_' . $key,
				sprintf(
					/* translators: %s: field name */
					__( 'Invalid %s provided.', 'woocommerce' ),
					$key
				)
			);
		}
	}

	// This condition will be true if any validation errors were encountered, e.g. wrong type supplied or invalid
	// option in enum fields.
	if ( $errors->has_errors() ) {
		return $errors;
	}

	$address = $this->sanitize_callback( $address, $request, $param );

	if ( ! empty( $address['country'] ) && ! in_array( $address['country'], array_keys( wc()->countries->get_countries() ), true ) ) {
		$errors->add(
			'invalid_country',
			sprintf(
				/* translators: %s valid country codes */
				__( 'Invalid country code provided. Must be one of: %s', 'woocommerce' ),
				implode( ', ', array_keys( wc()->countries->get_countries() ) )
			)
		);
		return $errors;
	}

	if ( ! empty( $address['state'] ) && ! $validation_util->validate_state( $address['state'], $address['country'] ) ) {
		$errors->add(
			'invalid_state',
			sprintf(
				/* translators: %1$s given state, %2$s valid states */
				__( 'The provided state (%1$s) is not valid. Must be one of: %2$s', 'woocommerce' ),
				esc_html( $address['state'] ),
				implode( ', ', array_keys( $validation_util->get_states_for_country( $address['country'] ) ) )
			)
		);
	}

	if ( ! empty( $address['postcode'] ) && ! \WC_Validation::is_postcode( $address['postcode'], $address['country'] ) ) {
		$errors->add(
			'invalid_postcode',
			__( 'The provided postcode / ZIP is not valid', 'woocommerce' )
		);
	}

	if ( ! empty( $address['phone'] ) && ! \WC_Validation::is_phone( $address['phone'] ) ) {
		$errors->add(
			'invalid_phone',
			__( 'The provided phone number is not valid', 'woocommerce' )
		);
	}

	// Get additional field keys here as we need to know if they are present in the address for validation.
	$additional_keys = array_keys( $this->get_additional_address_fields_schema() );

	foreach ( array_keys( $address ) as $key ) {

		// Skip email here it will be validated in BillingAddressSchema.
		if ( 'email' === $key ) {
			continue;
		}

		// Only run specific validation on properties that are defined in the schema and present in the address.
		// This is for partial address pushes when only part of a customer address is sent.
		// Full schema address validation still happens later, so empty, required values are disallowed.
		if ( empty( $schema[ $key ] ) || empty( $address[ $key ] ) ) {
			continue;
		}

		$result = rest_validate_value_from_schema( $address[ $key ], $schema[ $key ], $key );

		// Check if a field is in the list of additional fields then validate the value against the custom validation rules defined for it.
		// Skip additional validation if the schema validation failed.
		if ( true === $result && in_array( $key, $additional_keys, true ) ) {
			$result = $this->additional_fields_controller->validate_field( $key, $address[ $key ] );
		}

		if ( is_wp_error( $result ) && $result->has_errors() ) {
			$errors->merge_from( $result );
		}
	}

	$result = $this->additional_fields_controller->validate_fields_for_location( $address, 'address', 'billing_address' === $this->title ? 'billing' : 'shipping' );

	if ( is_wp_error( $result ) && $result->has_errors() ) {
		$errors->merge_from( $result );
	}

	return $errors->has_errors( $errors ) ? $errors : true;
}