$request, ), '7.2.0', 'woocommerce_store_api_checkout_update_order_from_request', 'This action was deprecated in WooCommerce Blocks version 7.2.0. Please use woocommerce_store_api_checkout_update_order_from_request instead.' ); /** * Fires when the Checkout Block/Store API updates an order's from the API request data. * * This hook gives extensions the chance to update orders based on the data in the request. This can be used in * conjunction with the ExtendSchema class to post custom data and then process it. * * @since 7.2.0 * * @param \WC_Order $order Order object. * @param \WP_REST_Request $request Full details about the request. */ do_action( 'woocommerce_store_api_checkout_update_order_from_request', $order, $request ); if ( $persist ) { $order->save(); } } /** * Gets the chosen payment method title from the request. * * @throws RouteException On error. * @param \WP_REST_Request $request Request object. * @return string */ private function get_request_payment_method_title( \WP_REST_Request $request ) { $payment_method = $this->get_request_payment_method( $request ); return is_null( $payment_method ) ? '' : $payment_method->get_title(); } /** * Persist additional fields for the order after validating them. * * @throws RouteException If the order is missing. * * @param \WP_REST_Request $request Full details about the request. */ private function persist_additional_fields_for_order( \WP_REST_Request $request ) { // Local alias so the closure and downstream calls keep a non-null `WC_Order`. $order = $this->get_order_or_throw(); $this->resolve_and_persist_additional_fields( $request, function ( string $key, $value ) use ( $order ) { $this->additional_fields_controller->persist_field_for_order( $key, $value, $order, 'other', false ); } ); if ( 0 !== $order->get_customer_id() && get_current_user_id() === $order->get_customer_id() ) { $this->additional_fields_controller->sync_customer_additional_fields_with_order( $order, wc()->customer ); } } /** * Persist additional fields for the customer session. * * Counterpart to `persist_additional_fields_for_order` for routes that operate * without a persisted order (e.g. the deferred-draft PATCH path). * * @phpstan-param \WP_REST_Request> $request * * @param \WP_REST_Request $request Full details about the request. */ private function persist_additional_fields_for_customer( \WP_REST_Request $request ): void { $customer = wc()->customer; $this->resolve_and_persist_additional_fields( $request, function ( string $key, $value ) use ( $customer ) { $this->additional_fields_controller->persist_field_for_customer( $key, $value, $customer, 'other' ); } ); $customer->save(); } /** * Resolve the additional checkout fields from the request and persist each one * via the supplied callback. Fields hidden by conditional logic that were still * posted are cleared (passed with an empty value). * * @phpstan-param \WP_REST_Request> $request * * @param \WP_REST_Request $request Full details about the request. * @param callable $persist Callback invoked as `$persist( string $key, mixed $value )` for each field. */ private function resolve_and_persist_additional_fields( \WP_REST_Request $request, callable $persist ): void { if ( Features::is_enabled( 'experimental-blocks' ) ) { $document_object = $this->get_document_object_from_rest_request( $request ); $document_object->set_context( 'order' ); $additional_fields = array_merge( $this->additional_fields_controller->get_contextual_fields_for_location( 'order', $document_object ), $this->additional_fields_controller->get_contextual_fields_for_location( 'contact', $document_object ) ); } else { $additional_fields = array_merge( $this->additional_fields_controller->get_fields_for_location( 'order' ), $this->additional_fields_controller->get_fields_for_location( 'contact' ) ); } $field_values = isset( $request['additional_fields'] ) ? (array) $request['additional_fields'] : array(); foreach ( $additional_fields as $key => $field ) { if ( isset( $field_values[ $key ] ) ) { $persist( $key, $field_values[ $key ] ); } } $hidden_posted_field_values = array_diff_key( $field_values, $additional_fields ); foreach ( $hidden_posted_field_values as $key => $value ) { if ( $this->additional_fields_controller->is_field( $key ) ) { $persist( $key, '' ); } } } /** * Returns a document object from a REST request. * * @param \WP_REST_Request $request The REST request. * @return DocumentObject The document object or null if experimental blocks are not enabled. */ public function get_document_object_from_rest_request( \WP_REST_Request $request ) { return new DocumentObject( [ 'customer' => [ 'billing_address' => $request['billing_address'], 'shipping_address' => $request['shipping_address'], 'additional_fields' => array_intersect_key( $request['additional_fields'] ?? [], array_flip( $this->additional_fields_controller->get_contact_fields_keys() ) ), ], 'checkout' => [ 'payment_method' => $request['payment_method'], 'create_account' => $request['create_account'], 'customer_note' => $request['customer_note'], 'additional_fields' => array_intersect_key( $request['additional_fields'] ?? [], array_flip( $this->additional_fields_controller->get_order_fields_keys() ) ), ], ] ); } }