Файловый менеджер - Редактировать - /home/tuudkjt/globeasy/wp-includes/ID3/StoreApi.zip
Назад
PK /D.]«Co o ! Formatters/FormatterInterface.phpnu ��� <?php namespace Automattic\WooCommerce\StoreApi\Formatters; /** * FormatterInterface. */ interface FormatterInterface { /** * Format a given value and return the result. * * @param mixed $value Value to format. * @param array $options Options that influence the formatting. * @return mixed */ public function format( $value, array $options = [] ); } PK /D.]�Ri` ` Formatters/MoneyFormatter.phpnu ��� <?php namespace Automattic\WooCommerce\StoreApi\Formatters; /** * Money Formatter. * * Formats monetary values using store settings. */ class MoneyFormatter implements FormatterInterface { /** * Format a given price value and return the result as a string without decimals. * * @param int|float|string $value Value to format. Int is allowed, as it may also represent a valid price. * @param array $options Options that influence the formatting. * @return string */ public function format( $value, array $options = [] ) { if ( ! is_int( $value ) && ! is_string( $value ) && ! is_float( $value ) ) { wc_doing_it_wrong( __FUNCTION__, 'Function expects a $value arg of type INT, STRING or FLOAT.', '9.2' ); return ''; } $options = wp_parse_args( $options, [ 'decimals' => wc_get_price_decimals(), 'rounding_mode' => PHP_ROUND_HALF_UP, ] ); // Ensure rounding mode is valid. $rounding_modes = [ PHP_ROUND_HALF_UP, PHP_ROUND_HALF_DOWN, PHP_ROUND_HALF_EVEN, PHP_ROUND_HALF_ODD ]; $options['rounding_mode'] = absint( $options['rounding_mode'] ); if ( ! in_array( $options['rounding_mode'], $rounding_modes, true ) ) { $options['rounding_mode'] = PHP_ROUND_HALF_UP; } $value = floatval( $value ); // Remove the price decimal points for rounding purposes. $value = $value * pow( 10, absint( $options['decimals'] ) ); $value = round( $value, 0, $options['rounding_mode'] ); // This ensures returning the value as a string without decimal points ready for price parsing. return wc_format_decimal( $value, 0, true ); } } PK /D.]���I� � Formatters/HtmlFormatter.phpnu ��� <?php namespace Automattic\WooCommerce\StoreApi\Formatters; /** * Html Formatter. * * Formats HTML in API responses. * * @internal This API is used internally by Blocks--it is still in flux and may be subject to revisions. */ class HtmlFormatter implements FormatterInterface { /** * Format a given value and return the result. * * The wptexturize, convert_chars, and trim functions are also used in the `the_title` filter. * The function wp_kses_post removes disallowed HTML tags. * * @param string|array $value Value to format. * @param array $options Options that influence the formatting. * @return string */ public function format( $value, array $options = [] ) { if ( is_array( $value ) ) { return array_map( [ $this, 'format' ], $value ); } return is_scalar( $value ) ? wp_kses_post( trim( convert_chars( wptexturize( $value ) ) ) ) : $value; } } PK /D.]Q2� � Formatters/DefaultFormatter.phpnu ��� <?php namespace Automattic\WooCommerce\StoreApi\Formatters; /** * Default Formatter. */ class DefaultFormatter implements FormatterInterface { /** * Format a given value and return the result. * * @param mixed $value Value to format. * @param array $options Options that influence the formatting. * @return mixed */ public function format( $value, array $options = [] ) { return $value; } } PK /D.]�7F F Formatters/CurrencyFormatter.phpnu ��� <?php namespace Automattic\WooCommerce\StoreApi\Formatters; /** * Currency Formatter. * * Formats an array of monetary values by inserting currency data. */ class CurrencyFormatter implements FormatterInterface { /** * Format a given value and return the result. * * @param array $value Value to format. * @param array $options Options that influence the formatting. * @return array */ public function format( $value, array $options = [] ) { $position = get_option( 'woocommerce_currency_pos' ); $symbol = html_entity_decode( get_woocommerce_currency_symbol() ); $prefix = ''; $suffix = ''; switch ( $position ) { case 'left_space': $prefix = $symbol . ' '; break; case 'left': $prefix = $symbol; break; case 'right_space': $suffix = ' ' . $symbol; break; case 'right': $suffix = $symbol; break; } return array_merge( (array) $value, [ 'currency_code' => get_woocommerce_currency(), 'currency_symbol' => $symbol, 'currency_minor_unit' => wc_get_price_decimals(), 'currency_decimal_separator' => wc_get_price_decimal_separator(), 'currency_thousand_separator' => wc_get_price_thousand_separator(), 'currency_prefix' => $prefix, 'currency_suffix' => $suffix, ] ); } } PK /D.]�V� StoreApi.phpnu ��� <?php namespace Automattic\WooCommerce\StoreApi; use Automattic\WooCommerce\Blocks\Registry\Container; use Automattic\WooCommerce\StoreApi\Formatters; use Automattic\WooCommerce\StoreApi\Authentication; use Automattic\WooCommerce\StoreApi\Legacy; use Automattic\WooCommerce\StoreApi\Formatters\CurrencyFormatter; use Automattic\WooCommerce\StoreApi\Formatters\HtmlFormatter; use Automattic\WooCommerce\StoreApi\Formatters\MoneyFormatter; use Automattic\WooCommerce\StoreApi\RoutesController; use Automattic\WooCommerce\StoreApi\SchemaController; use Automattic\WooCommerce\StoreApi\Schemas\ExtendSchema; /** * StoreApi Main Class. */ final class StoreApi { /** * Init and hook in Store API functionality. */ public function init() { add_action( 'rest_api_init', function () { if ( ! wc_rest_should_load_namespace( 'wc/store' ) && ! wc_rest_should_load_namespace( 'wc/private' ) ) { return; } self::container()->get( Legacy::class )->init(); self::container()->get( RoutesController::class )->register_all_routes(); } ); // Runs on priority 11 after rest_api_default_filters() which is hooked at 10. add_action( 'rest_api_init', function () { if ( ! wc_rest_should_load_namespace( 'wc/store' ) ) { return; } self::container()->get( Authentication::class )->init(); }, 11 ); add_action( 'woocommerce_blocks_pre_get_routes_from_namespace', function ( $routes, $ns ) { if ( 'wc/store/v1' !== $ns ) { return $routes; } $routes = array_merge( $routes, self::container()->get( RoutesController::class )->get_all_routes( 'v1' ) ); return $routes; }, 10, 2 ); } /** * Loads the DI container for Store API. * * @internal This uses the Blocks DI container. If Store API were to move to core, this container could be replaced * with a different compatible container. * * @param boolean $reset Used to reset the container to a fresh instance. Note: this means all dependencies will be reconstructed. * @return mixed */ public static function container( $reset = false ) { static $container; if ( $reset ) { $container = null; } if ( $container ) { return $container; } $container = new Container(); $container->register( Authentication::class, function () { return new Authentication(); } ); $container->register( Legacy::class, function () { return new Legacy(); } ); $container->register( RoutesController::class, function ( $container ) { return new RoutesController( $container->get( SchemaController::class ) ); } ); $container->register( SchemaController::class, function ( $container ) { return new SchemaController( $container->get( ExtendSchema::class ) ); } ); $container->register( ExtendSchema::class, function ( $container ) { return new ExtendSchema( $container->get( Formatters::class ) ); } ); $container->register( Formatters::class, function () { $formatters = new Formatters(); $formatters->register( 'money', MoneyFormatter::class ); $formatters->register( 'html', HtmlFormatter::class ); $formatters->register( 'currency', CurrencyFormatter::class ); return $formatters; } ); return $container; } } PK /D.]��2 �2 Authentication.phpnu ��� <?php declare( strict_types=1 ); namespace Automattic\WooCommerce\StoreApi; use Automattic\WooCommerce\StoreApi\Utilities\RateLimits; use Automattic\WooCommerce\StoreApi\Utilities\CartTokenUtils; use Automattic\WooCommerce\Utilities\FeaturesUtil; /** * Authentication class. */ class Authentication { /** * Hook into WP lifecycle events. This is hooked by the StoreAPI class on `rest_api_init`. */ public function init() { if ( ! $this->is_request_to_store_api() ) { return; } add_filter( 'rest_authentication_errors', array( $this, 'check_authentication' ) ); add_filter( 'rest_authentication_errors', array( $this, 'opt_in_checkout_endpoint' ), 9, 1 ); add_action( 'set_logged_in_cookie', array( $this, 'set_logged_in_cookie' ) ); add_filter( 'rest_pre_serve_request', array( $this, 'send_cors_headers' ), 10, 4 ); add_filter( 'rest_allowed_cors_headers', array( $this, 'allowed_cors_headers' ) ); add_filter( 'rest_exposed_cors_headers', array( $this, 'exposed_cors_headers' ) ); // Remove the default CORS headers--we will add our own. remove_filter( 'rest_pre_serve_request', 'rest_send_cors_headers' ); } /** * Add allowed cors headers for store API headers. * * @param array $allowed_headers Allowed headers. * @return array */ public function allowed_cors_headers( $allowed_headers ) { $allowed_headers[] = 'Cart-Token'; $allowed_headers[] = 'Nonce'; return $allowed_headers; } /** * Expose Store API headers in CORS responses. * We're explicitly exposing the Cart-Token, not the nonce. Only one of them is needed. * * @param array $exposed_headers Exposed headers. * @return array */ public function exposed_cors_headers( $exposed_headers ) { $exposed_headers[] = 'Cart-Token'; return $exposed_headers; } /** * Add CORS headers to a response object. * * These checks prevent access to the Store API from non-allowed origins. By default, the WordPress REST API allows * access from any origin. Because some Store API routes return PII, we need to add our own CORS headers. * * Allowed origins can be changed using the WordPress `allowed_http_origins` or `allowed_http_origin` filters if * access needs to be granted to other domains. * * Users of valid Cart Tokens are also allowed access from any origin. * * @param bool $served Whether the request has already been served. * @param \WP_REST_Response $result The response object. * @param \WP_REST_Request $request The request object. * @param \WP_REST_Server $server The REST server instance. * @return bool */ public function send_cors_headers( $served, $result, $request, $server ) { $origin = get_http_origin(); if ( 'null' !== $origin ) { $origin = esc_url_raw( $origin ); } // Send standard CORS headers. $server->send_header( 'Access-Control-Allow-Methods', 'OPTIONS, GET, POST, PUT, PATCH, DELETE' ); $server->send_header( 'Access-Control-Allow-Credentials', 'true' ); $server->send_header( 'Vary', 'Origin', false ); // Allow preflight requests, certain http origins, and any origin if a cart token is present. Preflight requests // are allowed because we'll be unable to validate cart token headers at that point. if ( $this->is_preflight() || CartTokenUtils::validate_cart_token( $this->get_cart_token( $request ) ) || is_allowed_http_origin( $origin ) ) { $server->send_header( 'Access-Control-Allow-Origin', $origin ); } // Exit early during preflight requests. This is so someone cannot access API data by sending an OPTIONS request // with preflight headers and a _GET property to override the method. if ( $this->is_preflight() ) { exit; } return $served; } /** * Is the request a preflight request? Checks the request method * * @return boolean */ protected function is_preflight() { return isset( $_SERVER['REQUEST_METHOD'], $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'], $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'], $_SERVER['HTTP_ORIGIN'] ) && 'OPTIONS' === $_SERVER['REQUEST_METHOD']; } /** * Gets the cart token from the request header. * * @param \WP_REST_Request $request The REST request instance. * @return string */ protected function get_cart_token( \WP_REST_Request $request ) { return wc_clean( wp_unslash( $request->get_header( 'Cart-Token' ) ?? '' ) ); } /** * The Store API does not require authentication. * * @param \WP_Error|mixed $result Error from another authentication handler, null if we should handle it, or another value if not. * @return \WP_Error|null|bool */ public function check_authentication( $result ) { // Enable Rate Limiting for logged-in users without 'edit posts' capability. if ( ! current_user_can( 'edit_posts' ) ) { $result = $this->apply_rate_limiting( $result ); } // Pass through errors from other authentication methods used before this one. return ! empty( $result ) ? $result : true; } /** * When the login cookies are set, they are not available until the next page reload. For the Store API, specifically * for returning updated nonces, we need this to be available immediately. * * @param string $logged_in_cookie The value for the logged in cookie. */ public function set_logged_in_cookie( $logged_in_cookie ) { if ( ! defined( 'LOGGED_IN_COOKIE' ) ) { return; } $_COOKIE[ LOGGED_IN_COOKIE ] = $logged_in_cookie; } /** * Opt in to rate limiting for the checkout endpoint. * * @param \WP_Error|mixed $result Error from another authentication handler, null if we should handle it, or another value if not. * @return \WP_Error|null|bool */ public function opt_in_checkout_endpoint( $result ) { if ( FeaturesUtil::feature_is_enabled( 'rate_limit_checkout' ) && $this->is_request_to_store_api() && preg_match( '#/wc/store(?:/v\d+)?/checkout#', $GLOBALS['wp']->query_vars['rest_route'] ) && $this->is_only_post_request() ) { add_filter( 'woocommerce_store_api_rate_limit_options', function ( $options ) { $options['enabled'] = true; $options['limit'] = 3; $options['seconds'] = 60; return $options; }, 1, 1 ); } return $result; } /** * Applies Rate Limiting to the request, and passes through any errors from other authentication methods used before this one. * * @param \WP_Error|mixed $result Error from another authentication handler, null if we should handle it, or another value if not. * @return \WP_Error|null|bool */ protected function apply_rate_limiting( $result ) { $rate_limiting_options = RateLimits::get_options(); if ( $rate_limiting_options->enabled ) { $action_id = 'store_api_request_' . self::get_rate_limiting_id( $rate_limiting_options->proxy_support ); $retry = RateLimits::is_exceeded_retry_after( $action_id ); $server = rest_get_server(); $server->send_header( 'RateLimit-Limit', $rate_limiting_options->limit ); if ( false !== $retry ) { $server->send_header( 'RateLimit-Remaining', 0 ); $server->send_header( 'RateLimit-Retry-After', $retry ); $server->send_header( 'RateLimit-Reset', time() + $retry ); /** * Fires when the rate limit is exceeded. * * @param string $ip_address The IP address of the request. * @param string $action_id The grouping identifier to the request. * * @since 8.9.0 * @since 9.8.0 Added $action_id parameter. */ do_action( 'woocommerce_store_api_rate_limit_exceeded', self::get_ip_address( $rate_limiting_options->proxy_support ), $action_id ); return new \WP_Error( 'rate_limit_exceeded', sprintf( 'Too many requests. Please wait %d seconds before trying again.', $retry ), array( 'status' => 400 ) ); } $rate_limit = RateLimits::update_rate_limit( $action_id ); $server->send_header( 'RateLimit-Remaining', $rate_limit->remaining ); $server->send_header( 'RateLimit-Reset', $rate_limit->reset ); } return $result; } /** * Generates the request grouping identifier for the rate limiting. * * @param bool $proxy_support Rate Limiting proxy support. * * @return string */ protected static function get_rate_limiting_id( bool $proxy_support ): string { if ( is_user_logged_in() ) { $id = (string) get_current_user_id(); } else { $id = md5( self::get_ip_address( $proxy_support ) ); } /** * Filters the rate limiting identifier. * * @param string $id The rate limiting identifier. * * @since 9.8.0 */ $id = apply_filters( 'woocommerce_store_api_rate_limit_id', $id ); return sanitize_key( $id ); } /** * Check if is request to the Store API. * * @return bool */ protected function is_request_to_store_api() { if ( empty( $GLOBALS['wp']->query_vars['rest_route'] ) ) { return false; } return 0 === strpos( $GLOBALS['wp']->query_vars['rest_route'], '/wc/store/' ); } /** * Returns true only for POST requests that are NOT overridden to another method * via the X-HTTP-Method-Override header (used by wp.apiFetch for PUT/DELETE). * * @see https://github.com/wordpress/gutenberg/blob/trunk/packages/api-fetch/src/middlewares/http-v1.ts#L21-L43 * * @return bool */ private function is_only_post_request() { // Check that REQUEST_METHOD is POST. if ( ! isset( $_SERVER['REQUEST_METHOD'] ) || 'POST' !== $_SERVER['REQUEST_METHOD'] ) { return false; } // Check X-HTTP-Method-Override header if it exists and is not empty - it must also be POST. if ( isset( $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] ) ) { $method_override = strtoupper( sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] ) ) ); if ( '' !== $method_override && 'POST' !== $method_override ) { return false; } } return true; } /** * Get current user IP Address. * * X_REAL_IP and CLIENT_IP are custom implementations designed to facilitate obtaining a user's ip through proxies, load balancers etc. * * _FORWARDED_FOR (XFF) request header is a de-facto standard header for identifying the originating IP address of a client connecting to a web server through a proxy server. * Note for X_FORWARDED_FOR, Proxy servers can send through this header like this: X-Forwarded-For: client1, proxy1, proxy2. * Make sure we always only send through the first IP in the list which should always be the client IP. * Documentation at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For * * Forwarded request header contains information that may be added by reverse proxy servers (load balancers, CDNs, and so on). * Documentation at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded * Full RFC at https://datatracker.ietf.org/doc/html/rfc7239 * * @param boolean $proxy_support Enables/disables proxy support. * * @return string */ protected static function get_ip_address( bool $proxy_support = false ) { if ( ! $proxy_support ) { return self::validate_ip( sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ?? 'unresolved_ip' ) ) ); } if ( array_key_exists( 'HTTP_X_REAL_IP', $_SERVER ) ) { return self::validate_ip( sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_REAL_IP'] ) ) ); } if ( array_key_exists( 'HTTP_CLIENT_IP', $_SERVER ) ) { return self::validate_ip( sanitize_text_field( wp_unslash( $_SERVER['HTTP_CLIENT_IP'] ) ) ); } if ( array_key_exists( 'HTTP_X_FORWARDED_FOR', $_SERVER ) ) { $ips = explode( ',', sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) ); if ( is_array( $ips ) && ! empty( $ips ) ) { return self::validate_ip( trim( $ips[0] ) ); } } if ( array_key_exists( 'HTTP_FORWARDED', $_SERVER ) ) { // Using regex instead of explode() for a smaller code footprint. // Expected format: Forwarded: for=192.0.2.60;proto=http;by=203.0.113.43,for="[2001:db8:cafe::17]:4711"... preg_match( '/(?<=for\=)[^;,]*/i', // We catch everything on the first "for" entry, and validate later. sanitize_text_field( wp_unslash( $_SERVER['HTTP_FORWARDED'] ) ), $matches ); if ( strpos( $matches[0] ?? '', '"[' ) !== false ) { // Detect for ipv6, eg "[ipv6]:port". preg_match( '/(?<=\[).*(?=\])/i', // We catch only the ipv6 and overwrite $matches. $matches[0], $matches ); } if ( ! empty( $matches ) ) { return self::validate_ip( trim( $matches[0] ) ); } } return '0.0.0.0'; } /** * Uses filter_var() to validate and return ipv4 and ipv6 addresses * Will return 0.0.0.0 if the ip is not valid. This is done to group and still rate limit invalid ips. * * @param string $ip ipv4 or ipv6 ip string. * * @return string */ protected static function validate_ip( $ip ) { $ip = filter_var( $ip, FILTER_VALIDATE_IP, array( FILTER_FLAG_NO_RES_RANGE, FILTER_FLAG_IPV6 ) ); return $ip ?: '0.0.0.0'; } } PK /D.]�#=�9 9 Payments/PaymentContext.phpnu ��� <?php namespace Automattic\WooCommerce\StoreApi\Payments; /** * PaymentContext class. */ class PaymentContext { /** * Payment method ID. * * @var string */ protected $payment_method = ''; /** * Order object for the order being paid. * * @var \WC_Order */ protected $order; /** * Holds data to send to the payment gateway to support payment. * * @var array Key value pairs. */ protected $payment_data = []; /** * Magic getter for protected properties. * * @param string $name Property name. */ public function __get( $name ) { if ( in_array( $name, [ 'payment_method', 'order', 'payment_data' ], true ) ) { return $this->$name; } return null; } /** * Set the chosen payment method ID context. * * @param string $payment_method Payment method ID. */ public function set_payment_method( $payment_method ) { $this->payment_method = (string) $payment_method; } /** * Retrieve the payment method instance for the current set payment method. * * @return \WC_Payment_Gateway|null An instance of the payment gateway if it exists. */ public function get_payment_method_instance() { $available_gateways = WC()->payment_gateways->get_available_payment_gateways(); if ( ! isset( $available_gateways[ $this->payment_method ] ) ) { return; } return $available_gateways[ $this->payment_method ]; } /** * Set the order context. * * @param \WC_Order $order Order object. */ public function set_order( \WC_Order $order ) { $this->order = $order; } /** * Set payment data context. * * @param array $payment_data Array of key value pairs of data. */ public function set_payment_data( $payment_data = [] ) { $this->payment_data = []; foreach ( $payment_data as $key => $value ) { $this->payment_data[ (string) $key ] = (string) $value; } } } PK /D.]D�#� � Payments/PaymentResult.phpnu ��� <?php namespace Automattic\WooCommerce\StoreApi\Payments; /** * PaymentResult class. */ class PaymentResult { /** * List of valid payment statuses. * * @var array */ protected $valid_statuses = [ 'success', 'failure', 'pending', 'error' ]; /** * Current payment status. * * @var string */ protected $status = ''; /** * Array of details about the payment. * * @var string */ protected $payment_details = []; /** * Redirect URL for checkout. * * @var string */ protected $redirect_url = ''; /** * Constructor. * * @param string $status Sets the payment status for the result. */ public function __construct( $status = '' ) { if ( $status ) { $this->set_status( $status ); } } /** * Magic getter for protected properties. * * @param string $name Property name. */ public function __get( $name ) { if ( in_array( $name, [ 'status', 'payment_details', 'redirect_url' ], true ) ) { return $this->$name; } return null; } /** * Set payment status. * * @throws \Exception When an invalid status is provided. * * @param string $payment_status Status to set. */ public function set_status( $payment_status ) { if ( ! in_array( $payment_status, $this->valid_statuses, true ) ) { throw new \Exception( sprintf( 'Invalid payment status %s. Use one of %s', $payment_status, implode( ', ', $this->valid_statuses ) ) ); } $this->status = $payment_status; } /** * Set payment details. * * @param array $payment_details Array of key value pairs of data. */ public function set_payment_details( $payment_details = [] ) { $this->payment_details = []; foreach ( $payment_details as $key => $value ) { $this->payment_details[ (string) $key ] = (string) $value; } } /** * Set redirect URL. * * @param array $redirect_url URL to redirect the customer to after checkout. */ public function set_redirect_url( $redirect_url = [] ) { $this->redirect_url = esc_url_raw( $redirect_url ); } } PK /D.]uY�)� � deprecated.phpnu ��� <?php /** * Class Aliases for graceful Backwards compatibility. * * This file is autoloaded via composer.json and maps the old namespaces to new namespaces. */ $class_aliases = [ // Old to new namespaces for utils and exceptions. Automattic\WooCommerce\StoreApi\Exceptions\RouteException::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\RouteException::class, Automattic\WooCommerce\StoreApi\Schemas\ExtendSchema::class => Automattic\WooCommerce\Blocks\Domain\Services\ExtendRestApi::class, Automattic\WooCommerce\StoreApi\SchemaController::class => Automattic\WooCommerce\Blocks\StoreApi\SchemaController::class, Automattic\WooCommerce\StoreApi\RoutesController::class => Automattic\WooCommerce\Blocks\StoreApi\RoutesController::class, Automattic\WooCommerce\StoreApi\Formatters::class => Automattic\WooCommerce\Blocks\StoreApi\Formatters::class, Automattic\WooCommerce\StoreApi\Payments\PaymentResult::class => Automattic\WooCommerce\Blocks\Payments\PaymentResult::class, Automattic\WooCommerce\StoreApi\Payments\PaymentContext::class => Automattic\WooCommerce\Blocks\Payments\PaymentContext::class, // Old schemas to V1 schemas under new namespace. Automattic\WooCommerce\StoreApi\Schemas\V1\AbstractAddressSchema::class => Automattic\WooCommerce\Blocks\StoreApi\Schemas\AbstractAddressSchema::class, Automattic\WooCommerce\StoreApi\Schemas\V1\AbstractSchema::class => Automattic\WooCommerce\Blocks\StoreApi\Schemas\AbstractSchema::class, Automattic\WooCommerce\StoreApi\Schemas\V1\BillingAddressSchema::class => Automattic\WooCommerce\Blocks\StoreApi\Schemas\BillingAddressSchema::class, Automattic\WooCommerce\StoreApi\Schemas\V1\CartCouponSchema::class => Automattic\WooCommerce\Blocks\StoreApi\Schemas\CartCouponSchema::class, Automattic\WooCommerce\StoreApi\Schemas\V1\CartExtensionsSchema::class => Automattic\WooCommerce\Blocks\StoreApi\Schemas\CartExtensionsSchema::class, Automattic\WooCommerce\StoreApi\Schemas\V1\CartFeeSchema::class => Automattic\WooCommerce\Blocks\StoreApi\Schemas\CartFeeSchema::class, Automattic\WooCommerce\StoreApi\Schemas\V1\CartItemSchema::class => Automattic\WooCommerce\Blocks\StoreApi\Schemas\CartItemSchema::class, Automattic\WooCommerce\StoreApi\Schemas\V1\CartSchema::class => Automattic\WooCommerce\Blocks\StoreApi\Schemas\CartSchema::class, Automattic\WooCommerce\StoreApi\Schemas\V1\CartShippingRateSchema::class => Automattic\WooCommerce\Blocks\StoreApi\Schemas\CartShippingRateSchema::class, Automattic\WooCommerce\StoreApi\Schemas\V1\CheckoutSchema::class => Automattic\WooCommerce\Blocks\StoreApi\Schemas\CheckoutSchema::class, Automattic\WooCommerce\StoreApi\Schemas\V1\ErrorSchema::class => Automattic\WooCommerce\Blocks\StoreApi\Schemas\ErrorSchema::class, Automattic\WooCommerce\StoreApi\Schemas\V1\ImageAttachmentSchema::class => Automattic\WooCommerce\Blocks\StoreApi\Schemas\ImageAttachmentSchema::class, Automattic\WooCommerce\StoreApi\Schemas\V1\OrderCouponSchema::class => Automattic\WooCommerce\Blocks\StoreApi\Schemas\OrderCouponSchema::class, Automattic\WooCommerce\StoreApi\Schemas\V1\ProductAttributeSchema::class => Automattic\WooCommerce\Blocks\StoreApi\Schemas\ProductAttributeSchema::class, Automattic\WooCommerce\StoreApi\Schemas\V1\ProductCategorySchema::class => Automattic\WooCommerce\Blocks\StoreApi\Schemas\ProductCategorySchema::class, Automattic\WooCommerce\StoreApi\Schemas\V1\ProductCollectionDataSchema::class => Automattic\WooCommerce\Blocks\StoreApi\Schemas\ProductCollectionDataSchema::class, Automattic\WooCommerce\StoreApi\Schemas\V1\ProductReviewSchema::class => Automattic\WooCommerce\Blocks\StoreApi\Schemas\ProductReviewSchema::class, Automattic\WooCommerce\StoreApi\Schemas\V1\ProductSchema::class => Automattic\WooCommerce\Blocks\StoreApi\Schemas\ProductSchema::class, Automattic\WooCommerce\StoreApi\Schemas\V1\ShippingAddressSchema::class => Automattic\WooCommerce\Blocks\StoreApi\Schemas\ShippingAddressSchema::class, Automattic\WooCommerce\StoreApi\Schemas\V1\TermSchema::class => Automattic\WooCommerce\Blocks\StoreApi\Schemas\TermSchema::class, // Old routes to V1 routes under new namespace. Automattic\WooCommerce\StoreApi\Routes\V1\AbstractCartRoute::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\AbstractCartRoute::class, Automattic\WooCommerce\StoreApi\Routes\V1\AbstractRoute::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\AbstractRoute::class, Automattic\WooCommerce\StoreApi\Routes\V1\AbstractTermsRoute::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\AbstractTermsRoute::class, Automattic\WooCommerce\StoreApi\Routes\V1\Batch::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\Batch::class, Automattic\WooCommerce\StoreApi\Routes\V1\Cart::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\Cart::class, Automattic\WooCommerce\StoreApi\Routes\V1\CartAddItem::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\CartAddItem::class, Automattic\WooCommerce\StoreApi\Routes\V1\CartApplyCoupon::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\CartApplyCoupon::class, Automattic\WooCommerce\StoreApi\Routes\V1\CartCoupons::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\CartCoupons::class, Automattic\WooCommerce\StoreApi\Routes\V1\CartCouponsByCode::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\CartCouponsByCode::class, Automattic\WooCommerce\StoreApi\Routes\V1\CartExtensions::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\CartExtensions::class, Automattic\WooCommerce\StoreApi\Routes\V1\CartItems::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\CartItems::class, Automattic\WooCommerce\StoreApi\Routes\V1\CartItemsByKey::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\CartItemsByKey::class, Automattic\WooCommerce\StoreApi\Routes\V1\CartRemoveCoupon::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\CartRemoveCoupon::class, Automattic\WooCommerce\StoreApi\Routes\V1\CartRemoveItem::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\CartRemoveItem::class, Automattic\WooCommerce\StoreApi\Routes\V1\CartSelectShippingRate::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\CartSelectShippingRate::class, Automattic\WooCommerce\StoreApi\Routes\V1\CartUpdateCustomer::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\CartUpdateCustomer::class, Automattic\WooCommerce\StoreApi\Routes\V1\CartUpdateItem::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\CartUpdateItem::class, Automattic\WooCommerce\StoreApi\Routes\V1\Checkout::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\Checkout::class, Automattic\WooCommerce\StoreApi\Routes\V1\ProductAttributes::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\ProductAttributes::class, Automattic\WooCommerce\StoreApi\Routes\V1\ProductAttributesById::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\ProductAttributesById::class, Automattic\WooCommerce\StoreApi\Routes\V1\ProductAttributeTerms::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\ProductAttributeTerms::class, Automattic\WooCommerce\StoreApi\Routes\V1\ProductCategories::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\ProductCategories::class, Automattic\WooCommerce\StoreApi\Routes\V1\ProductCategoriesById::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\ProductCategoriesById::class, Automattic\WooCommerce\StoreApi\Routes\V1\ProductCollectionData::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\ProductCollectionData::class, Automattic\WooCommerce\StoreApi\Routes\V1\ProductReviews::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\ProductReviews::class, Automattic\WooCommerce\StoreApi\Routes\V1\Products::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\Products::class, Automattic\WooCommerce\StoreApi\Routes\V1\ProductsById::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\ProductsById::class, Automattic\WooCommerce\StoreApi\Routes\V1\ProductTags::class => Automattic\WooCommerce\Blocks\StoreApi\Routes\ProductTags::class, ]; foreach ( $class_aliases as $class => $alias ) { if ( ! class_exists( $alias, false ) ) { class_alias( $class, $alias ); } } unset( $class_aliases ); PK /D.]�|� RoutesController.phpnu ��� <?php declare( strict_types = 1 ); namespace Automattic\WooCommerce\StoreApi; use Automattic\WooCommerce\StoreApi\Routes\V1\AbstractRoute; use Automattic\WooCommerce\Utilities\FeaturesUtil; /** * RoutesController class. */ class RoutesController { /** * Stores schema_controller. * * @var SchemaController */ protected $schema_controller; /** * Stores routes. * * @var array */ protected $routes = []; /** * Namespace for the API. * * @var string */ private static $api_namespace = 'wc/store'; /** * Constructor. * * @param SchemaController $schema_controller Schema controller class passed to each route. */ public function __construct( SchemaController $schema_controller ) { $this->schema_controller = $schema_controller; $this->routes = [ 'v1' => [ Routes\V1\Batch::IDENTIFIER => Routes\V1\Batch::class, Routes\V1\Cart::IDENTIFIER => Routes\V1\Cart::class, Routes\V1\CartAddItem::IDENTIFIER => Routes\V1\CartAddItem::class, Routes\V1\CartApplyCoupon::IDENTIFIER => Routes\V1\CartApplyCoupon::class, Routes\V1\CartCoupons::IDENTIFIER => Routes\V1\CartCoupons::class, Routes\V1\CartCouponsByCode::IDENTIFIER => Routes\V1\CartCouponsByCode::class, Routes\V1\CartExtensions::IDENTIFIER => Routes\V1\CartExtensions::class, Routes\V1\CartItems::IDENTIFIER => Routes\V1\CartItems::class, Routes\V1\CartItemsByKey::IDENTIFIER => Routes\V1\CartItemsByKey::class, Routes\V1\CartRemoveCoupon::IDENTIFIER => Routes\V1\CartRemoveCoupon::class, Routes\V1\CartRemoveItem::IDENTIFIER => Routes\V1\CartRemoveItem::class, Routes\V1\CartSelectShippingRate::IDENTIFIER => Routes\V1\CartSelectShippingRate::class, Routes\V1\CartUpdateItem::IDENTIFIER => Routes\V1\CartUpdateItem::class, Routes\V1\CartUpdateCustomer::IDENTIFIER => Routes\V1\CartUpdateCustomer::class, Routes\V1\Checkout::IDENTIFIER => Routes\V1\Checkout::class, Routes\V1\CheckoutOrder::IDENTIFIER => Routes\V1\CheckoutOrder::class, Routes\V1\Order::IDENTIFIER => Routes\V1\Order::class, Routes\V1\ProductAttributes::IDENTIFIER => Routes\V1\ProductAttributes::class, Routes\V1\ProductAttributesById::IDENTIFIER => Routes\V1\ProductAttributesById::class, Routes\V1\ProductAttributeTerms::IDENTIFIER => Routes\V1\ProductAttributeTerms::class, Routes\V1\ProductCategories::IDENTIFIER => Routes\V1\ProductCategories::class, Routes\V1\ProductCategoriesById::IDENTIFIER => Routes\V1\ProductCategoriesById::class, Routes\V1\ProductBrands::IDENTIFIER => Routes\V1\ProductBrands::class, Routes\V1\ProductBrandsById::IDENTIFIER => Routes\V1\ProductBrandsById::class, Routes\V1\ProductCollectionData::IDENTIFIER => Routes\V1\ProductCollectionData::class, Routes\V1\ProductReviews::IDENTIFIER => Routes\V1\ProductReviews::class, Routes\V1\ProductTags::IDENTIFIER => Routes\V1\ProductTags::class, Routes\V1\Products::IDENTIFIER => Routes\V1\Products::class, Routes\V1\ProductsById::IDENTIFIER => Routes\V1\ProductsById::class, Routes\V1\ProductsBySlug::IDENTIFIER => Routes\V1\ProductsBySlug::class, ], 'private' => [ // This route should be moved outside of the Store API namespace. Routes\V1\Patterns::IDENTIFIER => Routes\V1\Patterns::class, ], 'agentic' => [ // Agentic Commerce Protocol endpoints. Routes\V1\Agentic\CheckoutSessions::IDENTIFIER => Routes\V1\Agentic\CheckoutSessions::class, Routes\V1\Agentic\CheckoutSessionsUpdate::IDENTIFIER => Routes\V1\Agentic\CheckoutSessionsUpdate::class, Routes\V1\Agentic\CheckoutSessionsComplete::IDENTIFIER => Routes\V1\Agentic\CheckoutSessionsComplete::class, ], ]; } /** * Register all Store API routes. This includes routes under specific version namespaces. */ public function register_all_routes() { $this->register_routes( 'v1', self::$api_namespace ); $this->register_routes( 'v1', self::$api_namespace . '/v1' ); $this->register_routes( 'private', 'wc/private' ); if ( FeaturesUtil::feature_is_enabled( 'agentic_checkout' ) ) { $this->register_routes( 'agentic', 'wc/agentic/v1' ); } } /** * Get a route class instance. * * Each route class is instantized with the SchemaController instance, and its main Schema Type. * * @throws \Exception If the schema does not exist. * @param string $name Name of schema. * @param string $version API Version being requested. * @return AbstractRoute */ public function get( $name, $version = 'v1' ) { $route = $this->routes[ $version ][ $name ] ?? false; if ( ! $route ) { throw new \Exception( "{$name} {$version} route does not exist" ); } return new $route( $this->schema_controller, $this->schema_controller->get( $route::SCHEMA_TYPE, $route::SCHEMA_VERSION ) ); } /** * Get a route path without instantiating the corresponding RoutesController object. * * @throws \Exception If the schema does not exist. * * @param string $version API Version being requested. * @param string $controller Whether to return controller name. If false, returns empty array. Note: * When $controller param is true, the output should not be used directly in front-end code, to prevent class names from leaking. It's not a security issue necessarily, but it's not a good practice. * When $controller param is false, it currently returns and empty array. But it can be modified in future to return include more details about the route info that can be used in frontend. * * @return string[] List of route paths. */ public function get_all_routes( $version = 'v1', $controller = false ) { $routes = array(); foreach ( $this->routes[ $version ] as $key => $route_class ) { if ( ! method_exists( $route_class, 'get_path_regex' ) ) { throw new \Exception( esc_html( "{$route_class} route does not have a get_path_regex method" ) ); } $route_path = '/' . trailingslashit( self::$api_namespace ) . $version . $route_class::get_path_regex(); $routes[ $route_path ] = $controller ? $route_class : array(); } return $routes; } /** * Register defined list of routes with WordPress. * * @param string $version API Version being registered.. * @param string $namespace Overrides the default route namespace. */ protected function register_routes( $version = 'v1', $namespace = 'wc/store/v1' ) { if ( ! isset( $this->routes[ $version ] ) ) { return; } $route_identifiers = array_keys( $this->routes[ $version ] ); foreach ( $route_identifiers as $route ) { $route_instance = $this->get( $route, $version ); $route_instance->set_namespace( $namespace ); register_rest_route( $route_instance->get_namespace(), $route_instance->get_path(), $route_instance->get_args() ); } } } PK /D.]RB�� � SessionHandler.phpnu ��� <?php declare(strict_types=1); namespace Automattic\WooCommerce\StoreApi; use Automattic\Jetpack\Constants; use Automattic\WooCommerce\StoreApi\Utilities\CartTokenUtils; use WC_Session; defined( 'ABSPATH' ) || exit; /** * SessionHandler class */ final class SessionHandler extends WC_Session { /** * Token from HTTP headers. * * @var string */ protected $token = ''; /** * Table name for session data. * * @var string Custom session table name */ protected $table = ''; /** * Expiration timestamp. * * @var int */ protected $session_expiration = 0; /** * Constructor for the session class. */ public function __construct() { $this->token = wc_clean( wp_unslash( $_SERVER['HTTP_CART_TOKEN'] ?? '' ) ); $this->table = $GLOBALS['wpdb']->prefix . 'woocommerce_sessions'; } /** * Init hooks and session data. */ public function init() { $this->init_session_from_token(); add_action( 'shutdown', array( $this, 'save_data' ), 20 ); } /** * Process the token header to load the correct session. */ protected function init_session_from_token() { $payload = CartTokenUtils::get_cart_token_payload( $this->token ); $this->_customer_id = $payload['user_id']; $this->session_expiration = $payload['exp']; $this->_data = (array) $this->get_session( $this->get_customer_id(), array() ); } /** * Returns the session. * * @param string $customer_id Customer ID. * @param mixed $default_value Default session value. * @return mixed Returns either the session data or the default value. Returns false if WP setup is in progress. */ public function get_session( $customer_id, $default_value = false ) { global $wpdb; // This mimics behaviour from default WC_Session_Handler class. There will be no sessions retrieved while WP setup is due. if ( Constants::is_defined( 'WP_SETUP_CONFIG' ) ) { return $default_value; } $value = $wpdb->get_var( $wpdb->prepare( 'SELECT session_value FROM %i WHERE session_key = %s', $this->table, $customer_id ) ); if ( is_null( $value ) ) { $value = $default_value; } return maybe_unserialize( $value ); } /** * Save data and delete user session. */ public function save_data() { // Dirty if something changed - prevents saving nothing new. if ( $this->_dirty ) { global $wpdb; $wpdb->query( $wpdb->prepare( 'INSERT INTO %i (`session_key`, `session_value`, `session_expiry`) VALUES (%s, %s, %d) ON DUPLICATE KEY UPDATE `session_value` = VALUES(`session_value`), `session_expiry` = VALUES(`session_expiry`)', $this->table, $this->get_customer_id(), maybe_serialize( $this->_data ), $this->session_expiration ) ); $this->_dirty = false; } } } PK /D.]xW& & ) Exceptions/PartialOutOfStockException.phpnu ��� <?php namespace Automattic\WooCommerce\StoreApi\Exceptions; /** * PartialOutOfStockException class. * * This exception is thrown when an item in a draft order has a quantity greater than what is available in stock. */ class PartialOutOfStockException extends StockAvailabilityException {} PK /D.]��{! &