Automattic\WooCommerce\StoreApi\Routes\V1

Checkout::validate_callbackpublicWC 1.0

Validation callback for the checkout route.

This runs after individual field validation_callbacks have been called.

Method of the class: Checkout{}

No Hooks.

Returns

true|\WP_Error.

Usage

$Checkout = new Checkout();
$Checkout->validate_callback( $request );
$request(WP_REST_Request) (required)
Request object.

Checkout::validate_callback() code WC 9.9.3

public function validate_callback( $request ) {
	$validate_contexts = [
		'shipping_address' => [
			'group'    => 'shipping',
			'location' => 'address',
			'param'    => 'shipping_address',
		],
		'billing_address'  => [
			'group'    => 'billing',
			'location' => 'address',
			'param'    => 'billing_address',
		],
		'contact'          => [
			'group'    => 'other',
			'location' => 'contact',
			'param'    => 'additional_fields',
		],
		'order'            => [
			'group'    => 'other',
			'location' => 'order',
			'param'    => 'additional_fields',
		],
	];

	if ( ! WC()->cart->needs_shipping() ) {
		unset( $validate_contexts['shipping_address'] );
	}

	$invalid_groups  = [];
	$invalid_details = [];
	$is_partial      = in_array( $request->get_method(), [ 'PUT', 'PATCH' ], true );

	foreach ( $validate_contexts as $context => $context_data ) {
		$errors = new \WP_Error();

		$document_object = $this->get_document_object_from_rest_request( $request );
		$document_object->set_context( $context );
		$additional_fields = $this->additional_fields_controller->get_contextual_fields_for_location( $context_data['location'], $document_object );

		// These values are used to validate custom rules and generate the document object.
		$field_values = (array) $request->get_param( $context_data['param'] ) ?? [];

		foreach ( $additional_fields as $field_key => $field ) {
			// Skip values that were not posted if the request is partial or the field is not required.
			if ( ! isset( $field_values[ $field_key ] ) && ( $is_partial || true !== $field['required'] ) ) {
				continue;
			}

			// Clean the field value to trim whitespace.
			$field_value = wc_clean( wp_unslash( $field_values[ $field_key ] ?? '' ) );

			if ( empty( $field_value ) ) {
				if ( true === $field['required'] ) {
					/* translators: %s: is the field label */
					$error_message = sprintf( __( '%s is required', 'woocommerce' ), $field['label'] );
					if ( 'shipping_address' === $context ) {
						/* translators: %s: is the field error message */
						$error_message = sprintf( __( 'There was a problem with the provided shipping address: %s', 'woocommerce' ), $error_message );
					} elseif ( 'billing_address' === $context ) {
						/* translators: %s: is the field error message */
						$error_message = sprintf( __( 'There was a problem with the provided billing address: %s', 'woocommerce' ), $error_message );
					}
					$errors->add( 'woocommerce_required_checkout_field', $error_message, [ 'key' => $field_key ] );
				}
				continue;
			}

			$valid_check = $this->additional_fields_controller->validate_field( $field, $field_value );

			if ( is_wp_error( $valid_check ) && $valid_check->has_errors() ) {
				foreach ( $valid_check->get_error_codes() as $code ) {
					$valid_check->add_data(
						array(
							'location' => $context_data['location'],
							'key'      => $field_key,
						),
						$code
					);
				}
				$errors->merge_from( $valid_check );
				continue;
			}
		}

		// Validate all fields for this location (this runs custom validation callbacks).
		$valid_location_check = $this->additional_fields_controller->validate_fields_for_location( $field_values, $context_data['location'], $context_data['group'] );

		if ( is_wp_error( $valid_location_check ) && $valid_location_check->has_errors() ) {
			foreach ( $valid_location_check->get_error_codes() as $code ) {
				$valid_location_check->add_data(
					array(
						'location' => $context_data['location'],
					),
					$code
				);
			}
			$errors->merge_from( $valid_location_check );
		}

		if ( $errors->has_errors() ) {
			$invalid_groups[ $context_data['param'] ]  = $errors->get_error_message();
			$invalid_details[ $context_data['param'] ] = rest_convert_error_to_response( $errors )->get_data();
		}
	}

	if ( $invalid_groups ) {
		return new \WP_Error(
			'rest_invalid_param',
			/* translators: %s: List of invalid parameters. */
			esc_html( sprintf( __( 'Invalid parameter(s): %s', 'woocommerce' ), implode( ', ', array_keys( $invalid_groups ) ) ) ),
			array(
				'status'  => 400,
				'params'  => $invalid_groups,
				'details' => $invalid_details,
			)
		);
	}

	return true;
}