__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

[email protected]: ~ $
<?php
declare(strict_types=1);

namespace Automattic\WooCommerce\StoreApi\Schemas\V1;

use Automattic\WooCommerce\StoreApi\SchemaController;
use Automattic\WooCommerce\StoreApi\Payments\PaymentResult;
use Automattic\WooCommerce\StoreApi\Schemas\ExtendSchema;
use Automattic\WooCommerce\Blocks\Domain\Services\CheckoutFields;
use Automattic\WooCommerce\Blocks\Package;
use Automattic\WooCommerce\StoreApi\Utilities\SanitizationUtils;
use Automattic\WooCommerce\StoreApi\Schemas\V1\CartSchema;

/**
 * CheckoutSchema class.
 */
class CheckoutSchema extends AbstractSchema {
	/**
	 * The schema item name.
	 *
	 * @var string
	 */
	protected $title = 'checkout';

	/**
	 * The schema item identifier.
	 *
	 * @var string
	 */
	const IDENTIFIER = 'checkout';

	/**
	 * Billing address schema instance.
	 *
	 * @var BillingAddressSchema
	 */
	protected $billing_address_schema;

	/**
	 * Shipping address schema instance.
	 *
	 * @var ShippingAddressSchema
	 */
	protected $shipping_address_schema;

	/**
	 * Image Attachment schema instance.
	 *
	 * @var ImageAttachmentSchema
	 */
	protected $image_attachment_schema;

	/**
	 * Cart schema instance.
	 *
	 * @var CartSchema
	 */
	protected $cart_schema;

	/**
	 * Additional fields controller.
	 *
	 * @var CheckoutFields
	 */
	protected $additional_fields_controller;

	/**
	 * Constructor.
	 *
	 * @param ExtendSchema     $extend Rest Extending instance.
	 * @param SchemaController $controller Schema Controller instance.
	 */
	public function __construct( ExtendSchema $extend, SchemaController $controller ) {
		parent::__construct( $extend, $controller );
		$this->billing_address_schema       = $this->controller->get( BillingAddressSchema::IDENTIFIER );
		$this->shipping_address_schema      = $this->controller->get( ShippingAddressSchema::IDENTIFIER );
		$this->image_attachment_schema      = $this->controller->get( ImageAttachmentSchema::IDENTIFIER );
		$this->cart_schema                  = $this->controller->get( CartSchema::IDENTIFIER );
		$this->additional_fields_controller = Package::container()->get( CheckoutFields::class );
	}

	/**
	 * Checkout schema properties.
	 *
	 * @return array
	 */
	public function get_properties() {
		$additional_field_schema = $this->get_additional_fields_schema();
		return [
			'order_id'          => [
				'description' => __( 'The order ID to process during checkout.', 'woocommerce' ),
				'type'        => 'integer',
				'context'     => [ 'view', 'edit' ],
				'readonly'    => true,
			],
			'status'            => [
				'description' => __( 'Order status. Payment providers will update this value after payment.', 'woocommerce' ),
				'type'        => 'string',
				'context'     => [ 'view', 'edit' ],
				'readonly'    => true,
			],
			'order_key'         => [
				'description' => __( 'Order key used to check validity or protect access to certain order data.', 'woocommerce' ),
				'type'        => 'string',
				'context'     => [ 'view', 'edit' ],
				'readonly'    => true,
			],
			'order_number'      => [
				'description' => __( 'Order number used for display.', 'woocommerce' ),
				'type'        => 'string',
				'context'     => [ 'view', 'edit' ],
				'readonly'    => true,
			],
			'customer_note'     => [
				'description' => __( 'Note added to the order by the customer during checkout.', 'woocommerce' ),
				'type'        => 'string',
				'context'     => [ 'view', 'edit' ],
			],
			'customer_id'       => [
				'description' => __( 'Customer ID if registered. Will return 0 for guests.', 'woocommerce' ),
				'type'        => 'integer',
				'context'     => [ 'view', 'edit' ],
				'readonly'    => true,
			],
			'billing_address'   => [
				'description' => __( 'Billing address.', 'woocommerce' ),
				'type'        => 'object',
				'context'     => [ 'view', 'edit' ],
				'properties'  => $this->billing_address_schema->get_properties(),
				'arg_options' => [
					'sanitize_callback' => [ $this->billing_address_schema, 'sanitize_callback' ],
					'validate_callback' => [ $this->billing_address_schema, 'validate_callback' ],
				],
				'required'    => true,
			],
			'shipping_address'  => [
				'description' => __( 'Shipping address.', 'woocommerce' ),
				'type'        => 'object',
				'context'     => [ 'view', 'edit' ],
				'properties'  => $this->shipping_address_schema->get_properties(),
				'arg_options' => [
					'sanitize_callback' => [ $this->shipping_address_schema, 'sanitize_callback' ],
					'validate_callback' => [ $this->shipping_address_schema, 'validate_callback' ],
				],
			],
			'payment_method'    => [
				'description' => __( 'The ID of the payment method being used to process the payment.', 'woocommerce' ),
				'type'        => 'string',
				'context'     => [ 'view', 'edit' ],
				// Validation may be based on cart contents which is not available here; this returns all enabled
				// gateways. Further validation occurs during the request.
				'enum'        => array_merge( [ '' ], array_values( WC()->payment_gateways->get_payment_gateway_ids() ) ),
			],
			'create_account'    => [
				'description' => __( 'Whether to create a new user account as part of order processing.', 'woocommerce' ),
				'type'        => 'boolean',
				'context'     => [ 'view', 'edit' ],
			],
			'payment_result'    => [
				'description' => __( 'Result of payment processing, or null if not yet processed.', 'woocommerce' ),
				'type'        => [ 'object', 'null' ],
				'context'     => [ 'view', 'edit' ],
				'readonly'    => true,
				'properties'  => [
					'payment_status'  => [
						'description' => __( 'Status of the payment returned by the gateway. One of success, pending, failure, error.', 'woocommerce' ),
						'readonly'    => true,
						'type'        => 'string',
					],
					'payment_details' => [
						'description' => __( 'An array of data being returned from the payment gateway.', 'woocommerce' ),
						'readonly'    => true,
						'type'        => 'array',
						'items'       => [
							'type'       => 'object',
							'properties' => [
								'key'   => [
									'type' => 'string',
								],
								'value' => [
									'type' => 'string',
								],
							],
						],
					],
					'redirect_url'    => [
						'description' => __( 'A URL to redirect the customer after checkout. This could be, for example, a link to the payment processors website.', 'woocommerce' ),
						'readonly'    => true,
						'type'        => 'string',
					],
				],
			],
			'additional_fields' => [
				'description' => __( 'Additional fields to be persisted on the order.', 'woocommerce' ),
				'type'        => 'object',
				'context'     => [ 'view', 'edit' ],
				'properties'  => $additional_field_schema,
				'arg_options' => [
					'sanitize_callback' => [ $this, 'sanitize_additional_fields' ],
					'validate_callback' => [ $this, 'validate_additional_fields' ],
				],
				'required'    => $this->schema_has_required_property( $additional_field_schema ),
			],
			self::EXTENDING_KEY => $this->get_extended_schema( self::IDENTIFIER ),
		];
	}

	/**
	 * Return the response for checkout.
	 *
	 * @param object $item Results from checkout action.
	 * @return array
	 */
	public function get_item_response( $item ) {
		$cart           = property_exists( $item, 'cart' ) ? $item->cart : null;
		$payment_result = property_exists( $item, 'payment_result' ) ? $item->payment_result : null;
		return $this->get_checkout_response( $item->order, $payment_result, $cart );
	}

	/**
	 * Get the checkout response based on the current order and any payments.
	 *
	 * @param \WC_Order          $order          Order object.
	 * @param PaymentResult|null $payment_result Payment result object.
	 * @param \WC_Cart|null      $cart           Cart object.
	 * @return array
	 */
	protected function get_checkout_response( \WC_Order $order, ?PaymentResult $payment_result = null, ?\WC_Cart $cart = null ) {
		$payment_result = $payment_result ? [
			'payment_status'  => $payment_result->status,
			'payment_details' => $this->prepare_payment_details_for_response( $payment_result->payment_details ),
			'redirect_url'    => $payment_result->redirect_url,
		] : null;

		return [
			'order_id'           => $order->get_id(),
			'status'             => $order->get_status(),
			'order_key'          => $order->get_order_key(),
			'order_number'       => $order->get_order_number(),
			'customer_note'      => $order->get_customer_note(),
			'customer_id'        => $order->get_customer_id(),
			'billing_address'    => (object) $this->billing_address_schema->get_item_response( $order ),
			'shipping_address'   => (object) $this->shipping_address_schema->get_item_response( $order ),
			'payment_method'     => $order->get_payment_method(),
			'payment_result'     => $payment_result,
			'additional_fields'  => (object) $this->get_additional_fields_response( $order ),
			'__experimentalCart' => $cart ? (object) $this->cart_schema->get_item_response( $cart ) : null,
			self::EXTENDING_KEY  => $this->get_extended_data( self::IDENTIFIER ),
		];
	}

	/**
	 * This prepares the payment details for the response so it's following the
	 * schema where it's an array of objects.
	 *
	 * @param array $payment_details An array of payment details from the processed payment.
	 *
	 * @return array An array of objects where each object has the key and value
	 *               as distinct properties.
	 */
	protected function prepare_payment_details_for_response( array $payment_details ) {
		return array_map(
			function ( $key, $value ) {
				return (object) [
					'key'   => $key,
					'value' => $value,
				];
			},
			array_keys( $payment_details ),
			$payment_details
		);
	}

	/**
	 * Get the additional fields response.
	 *
	 * @param \WC_Order $order Order object.
	 * @return array
	 */
	protected function get_additional_fields_response( \WC_Order $order ) {
		$fields = wp_parse_args(
			$this->additional_fields_controller->get_all_fields_from_object( $order, 'other' ),
			$this->additional_fields_controller->get_all_fields_from_object( wc()->customer, 'other' )
		);

		$additional_field_schema = $this->get_additional_fields_schema();
		foreach ( $fields as $key => $value ) {
			if ( ! isset( $additional_field_schema[ $key ] ) ) {
				unset( $fields[ $key ] );
				continue;
			}
			// This makes sure we're casting checkboxes from "1" and "0" to boolean. In the frontend, "0" is treated as truthy.
			if ( isset( $additional_field_schema[ $key ]['type'] ) && 'boolean' === $additional_field_schema[ $key ]['type'] ) {
				$fields[ $key ] = (bool) $value;
			} else {
				$fields[ $key ] = $this->prepare_html_response( $value );
			}
		}

		return (object) $fields;
	}

	/**
	 * Get the schema for additional fields.
	 *
	 * @return array
	 */
	protected function get_additional_fields_schema() {
		return $this->generate_additional_fields_schema(
			$this->additional_fields_controller->get_fields_for_location( 'contact' ),
			$this->additional_fields_controller->get_fields_for_location( 'order' )
		);
	}

	/**
	 * Generate the schema for additional fields.
	 *
	 * @param array[] ...$args One or more arrays of additional fields.
	 * @return array
	 */
	protected function generate_additional_fields_schema( ...$args ) {
		$additional_fields = array_merge( ...$args );
		$schema            = [];
		foreach ( $additional_fields as $key => $field ) {
			$field_schema = [
				'description' => $field['label'],
				'type'        => 'string',
				'context'     => [ 'view', 'edit' ],
				'required'    => $this->additional_fields_controller->is_conditional_field( $field ) ? false : true === $field['required'],
			];

			if ( 'select' === $field['type'] ) {
				$field_schema['enum'] = array_map(
					function ( $option ) {
						return $option['value'];
					},
					$field['options']
				);
				if ( true !== $field['required'] || $this->additional_fields_controller->is_conditional_field( $field ) ) {
					$field_schema['enum'][] = '';
				}
			}

			if ( 'checkbox' === $field['type'] ) {
				$field_schema['type'] = 'boolean';
			}

			if ( 'checkbox' === $field['type'] && true === $field['required'] ) {
				$field_schema['enum'][] = true;
			}

			$schema[ $key ] = $field_schema;
		}
		return $schema;
	}

	/**
	 * Check if any additional field is required, so that the parent item is required as well.
	 *
	 * @param array $additional_fields_schema Additional fields schema.
	 * @return bool
	 */
	protected function schema_has_required_property( $additional_fields_schema ) {
		return array_reduce(
			array_keys( $additional_fields_schema ),
			function ( $carry, $key ) use ( $additional_fields_schema ) {
				return $carry || true === $additional_fields_schema[ $key ]['required'];
			},
			false
		);
	}

	/**
	 * Sanitize and format additional fields object.
	 *
	 * @param array $fields Values being sanitized.
	 * @return array
	 */
	public function sanitize_additional_fields( $fields ) {
		$properties         = $this->get_additional_fields_schema();
		$sanitization_utils = new SanitizationUtils();
		$fields             = $sanitization_utils->wp_kses_array(
			array_reduce(
				array_keys( $fields ),
				function ( $carry, $key ) use ( $fields, $properties ) {
					if ( ! isset( $properties[ $key ] ) ) {
						return $carry;
					}
					$field_schema   = $properties[ $key ];
					$rest_sanitized = rest_sanitize_value_from_schema( wp_unslash( $fields[ $key ] ), $field_schema, $key );
					$rest_sanitized = $this->additional_fields_controller->sanitize_field( $key, $rest_sanitized );
					$carry[ $key ]  = $rest_sanitized;
					return $carry;
				},
				[]
			)
		);

		return $sanitization_utils->wp_kses_array( $fields );
	}

	/**
	 * Validate additional fields object. This does not validate required fields nor customer validation rules because
	 * this may be a partial request. That will happen later when the full request is processed during POST. This only
	 * validates against the schema.
	 *
	 * @see rest_validate_value_from_schema
	 *
	 * @param array            $fields Value being sanitized.
	 * @param \WP_REST_Request $request The Request.
	 * @return true|\WP_Error
	 */
	public function validate_additional_fields( $fields, $request ) {
		$errors                  = new \WP_Error();
		$fields                  = $this->sanitize_additional_fields( $fields );
		$additional_field_schema = $this->get_additional_fields_schema();

		// for PUT requests, we only want to validate the fields that are being updated.
		if ( $request->get_method() === 'PUT' ) {
			$additional_field_schema = array_intersect_key( $additional_field_schema, $fields );
		}

		// on POST, loop over the schema instead of the fields. This is to ensure missing fields are validated.
		foreach ( $additional_field_schema as $key => $schema ) {
			if ( ! isset( $fields[ $key ] ) && true !== $schema['required'] ) {
				// Optional fields can go missing.
				continue;
			}

			$result = rest_validate_value_from_schema( $fields[ $key ] ?? null, $schema, $key );

			if ( is_wp_error( $result ) && $result->has_errors() ) {
				$location = $this->additional_fields_controller->get_field_location( $key );
				foreach ( $result->get_error_codes() as $code ) {
					$result->add_data(
						array(
							'location' => $location,
							'key'      => $key,
						),
						$code
					);
				}
				$errors->merge_from( $result );
			}
		}

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

Filemanager

Name Type Size Permission Actions
AI Folder 0775
Agentic Folder 0775
AbstractAddressSchema.php File 10.58 KB 0664
AbstractSchema.php File 12.83 KB 0664
BatchSchema.php File 427 B 0664
BillingAddressSchema.php File 4.46 KB 0664
CartCouponSchema.php File 2.98 KB 0664
CartExtensionsSchema.php File 2.21 KB 0664
CartFeeSchema.php File 2.12 KB 0664
CartItemSchema.php File 7.55 KB 0664
CartSchema.php File 15.82 KB 0664
CartShippingRateSchema.php File 11.37 KB 0664
CheckoutOrderSchema.php File 752 B 0664
CheckoutSchema.php File 15.05 KB 0664
ErrorSchema.php File 1.12 KB 0664
ImageAttachmentSchema.php File 2.55 KB 0664
ItemSchema.php File 11.27 KB 0664
OrderCouponSchema.php File 2.41 KB 0664
OrderFeeSchema.php File 2.2 KB 0664
OrderItemSchema.php File 2.79 KB 0664
OrderSchema.php File 12.74 KB 0664
PatternsSchema.php File 673 B 0664
ProductAttributeSchema.php File 2.5 KB 0664
ProductBrandSchema.php File 3.49 KB 0664
ProductCategorySchema.php File 3.5 KB 0664
ProductCollectionDataSchema.php File 4.95 KB 0664
ProductReviewSchema.php File 6.12 KB 0664
ProductSchema.php File 32.79 KB 0664
ShippingAddressSchema.php File 2.84 KB 0664
TermSchema.php File 2.15 KB 0664
Filemanager