| 1 |
<?php declare(strict_types=1); |
| 2 |
|
| 3 |
namespace MultiSafepay\WooCommerce\Services\Blocks; |
| 4 |
|
| 5 |
use Throwable; |
| 6 |
use WC_Blocks_Utils; |
| 7 |
|
| 8 |
/** |
| 9 |
* Helpers for detecting WooCommerce Blocks / Store API request context. |
| 10 |
*/ |
| 11 |
class BlocksContextService { |
| 12 |
|
| 13 |
/** |
| 14 |
* Returns true when the checkout page contains the WooCommerce Checkout block. |
| 15 |
* |
| 16 |
* This is used to decide whether the site is running block-based checkout. |
| 17 |
* |
| 18 |
* @return bool |
| 19 |
*/ |
| 20 |
public function is_checkout_blocks_active(): bool { |
| 21 |
if ( ! function_exists( 'wc_get_page_id' ) ) { |
| 22 |
return false; |
| 23 |
} |
| 24 |
|
| 25 |
if ( ! class_exists( '\\WC_Blocks_Utils' ) ) { |
| 26 |
return false; |
| 27 |
} |
| 28 |
|
| 29 |
$checkout_id = (int) wc_get_page_id( 'checkout' ); |
| 30 |
if ( $checkout_id <= 0 ) { |
| 31 |
return false; |
| 32 |
} |
| 33 |
|
| 34 |
try { |
| 35 |
return (bool) WC_Blocks_Utils::has_block_in_page( $checkout_id, 'woocommerce/checkout' ); |
| 36 |
} catch ( Throwable $exception ) { |
| 37 |
return false; |
| 38 |
} |
| 39 |
} |
| 40 |
|
| 41 |
/** |
| 42 |
* Returns true when the current request is a WooCommerce Store API request. |
| 43 |
* |
| 44 |
* @return bool |
| 45 |
*/ |
| 46 |
public function is_store_api_request(): bool { |
| 47 |
// Prefer WooCommerce's native detector when available (introduced in WC 9.x; not available in WC 6.x-8.x). |
| 48 |
// We keep the fallback below because this plugin supports older WooCommerce versions |
| 49 |
// and some Store API requests are routed via rest_route query vars, which the native |
| 50 |
// detector does not recognize consistently. |
| 51 |
if ( function_exists( 'WC' ) ) { |
| 52 |
$woocommerce = WC(); |
| 53 |
if ( is_object( $woocommerce ) && method_exists( $woocommerce, 'is_store_api_request' ) ) { |
| 54 |
if ( $woocommerce->is_store_api_request() ) { |
| 55 |
return true; |
| 56 |
} |
| 57 |
} |
| 58 |
} |
| 59 |
|
| 60 |
// Fallback for older WooCommerce versions and edge execution paths: |
| 61 |
// Store API requests may be routed either via pretty permalinks (/wp-json/wc/store/...) |
| 62 |
// or via the rest_route query param (?rest_route=/wc/store/...). |
| 63 |
// In some internal execution paths, REST_REQUEST may not be set when this code runs, |
| 64 |
// so we also check the explicit route. |
| 65 |
|
| 66 |
$rest_route = ''; |
| 67 |
if ( isset( $GLOBALS['wp'] ) && is_object( $GLOBALS['wp'] ) && isset( $GLOBALS['wp']->query_vars['rest_route'] ) ) { |
| 68 |
$rest_route = (string) $GLOBALS['wp']->query_vars['rest_route']; |
| 69 |
} |
| 70 |
|
| 71 |
// phpcs:disable WordPress.Security.NonceVerification.Recommended |
| 72 |
if ( '' === $rest_route && isset( $_GET['rest_route'] ) ) { |
| 73 |
$rest_route = sanitize_text_field( wp_unslash( $_GET['rest_route'] ) ); |
| 74 |
} |
| 75 |
// phpcs:enable WordPress.Security.NonceVerification.Recommended |
| 76 |
|
| 77 |
if ( '' !== $rest_route && false !== strpos( $rest_route, '/wc/store/' ) ) { |
| 78 |
return true; |
| 79 |
} |
| 80 |
|
| 81 |
if ( ! ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) { |
| 82 |
return false; |
| 83 |
} |
| 84 |
|
| 85 |
if ( ! isset( $_SERVER['REQUEST_URI'] ) ) { |
| 86 |
return false; |
| 87 |
} |
| 88 |
|
| 89 |
$request_uri = sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ); |
| 90 |
// Store API routes are under /wc/store/... |
| 91 |
return false !== strpos( $request_uri, '/wc/store/' ); |
| 92 |
} |
| 93 |
} |
| 94 |
|