HEX
Server: Apache/2.4.65 (Debian)
System: Linux kubikelcreative 5.10.0-35-amd64 #1 SMP Debian 5.10.237-1 (2025-05-19) x86_64
User: www-data (33)
PHP: 8.4.13
Disabled: NONE
Upload Files
File: /var/www/indoadvisory/wp/wp-content/plugins/polylang-wc/include/store-blocks.php
<?php
/**
 * @package Polylang-WC
 */

/**
 * A class to handle blocks.
 *
 * @since 1.9.5
 */
class PLLWC_Store_Blocks {

	/**
	 * Setups actions filters.
	 *
	 * @since 1.9.5
	 *
	 * @return void
	 */
	public function init() {
		if ( did_action( 'pll_language_defined' ) ) {
			$this->add_filters();
		} else {
			add_action( 'pll_language_defined', array( $this, 'add_filters' ), 1 );
		}

		// The language is not defined yet in REST.
		if ( Polylang::is_rest_request() ) {
			add_filter( 'locale', array( $this, 'get_locale' ) );
		}
	}

	/**
	 * Setups actions filters once the language is defined.
	 *
	 * @since 1.9.5
	 *
	 * @return void
	 */
	public function add_filters() {
		add_action( 'wp_footer', array( $this, 'filter_dynamic_blocks' ), 0 );

		// Use `render_block_data` to translate only attribute ids rather than content (which contains content such as post titles and links).
		add_filter( 'render_block_data', array( $this, 'filter_reviews_by_product_block_id' ) );

		// Fix assets URLs when using one domain per language.
		if ( PLL()->options['force_lang'] > 1 ) {
			add_filter( 'transient_woocommerce_blocks_asset_api_script_data', array( $this, 'blocks_assets_links' ) );
			add_filter( 'transient_woocommerce_blocks_asset_api_script_data_ssl', array( $this, 'blocks_assets_links' ) );
		}
	}

	/**
	 * Adds a script to allow filtering blocks relying on the WC REST API.
	 *
	 * @since 1.3
	 *
	 * @return void
	 */
	public function filter_dynamic_blocks() {
		// Backward compatibility with WC < 6.4.
		$path = '/wc/store/products';

		// Since WC 6.4.
		if ( version_compare( WC()->version, '6.4', '>=' ) ) {
			$path = '/wc/store/v1';
		}
		$script = $this->get_filter_script( $path );

		// Since WC 5.6.
		wp_add_inline_script( 'wc-reviews-block-frontend', $script, 'before' );
		wp_add_inline_script( 'wc-all-products-block-frontend', $script, 'before' );

		// Since WC 6.9.
		wp_add_inline_script( 'wc-checkout-block-frontend', $script, 'before' );

		// Backward compatibility with WC < 7.1.
		wp_add_inline_script( 'wc-attribute-filter-block-frontend', $script, 'before' );

		// Since WC 7.1.
		wp_add_inline_script( 'wc-filter-wrapper-block-frontend', $script, 'before' );

		/**
		 * WooCommerce `wc-cart-checkout-base` script which send REST requests to apply or remove coupon
		 * is loaded before `wp-api-fetch` we're using to register our script to filter by language.
		 * So we need to check `wc-cart-checkout-base` is enqueued to add our script after `wp-api-fetch`
		 * only in this case.
		*/
		if ( wp_script_is( 'wc-cart-checkout-base' ) ) {
			wp_add_inline_script( 'wp-api-fetch', $script, 'after' );
		}
	}

	/**
	 * Get a script to allow filtering blocks relying on the WC REST API.
	 *
	 * @since 1.5.3
	 *
	 * @param string $path The REST API path to filter.
	 * @return string Inline js script to add.
	 */
	protected function get_filter_script( $path ) {
		/** @var string $current_language This cannot be false because the language is defined at this point */
		$current_language = pll_current_language();

		$path   = esc_js( $path );
		$lang   = esc_js( $current_language );

		return "wp.apiFetch.use(
			function( options, next ) {
				if ( 'undefined' !== options.path && options.path.indexOf( '{$path}' ) >= 0 ) {
					options.path = wp.url.addQueryArgs( options.path, { lang: '{$lang}' } );
				}
				return next( options );
			}
		);";
	}

	/**
	 * Translates the product ID for the widget block reviews by product.
	 *
	 * @since 1.9
	 *
	 * @param array $parsed_block The block being rendered.
	 * @return array
	 */
	public function filter_reviews_by_product_block_id( $parsed_block ) {
		if ( 'woocommerce/reviews-by-product' !== $parsed_block['blockName'] ) {
			return $parsed_block;
		}

		if ( empty( PLL()->curlang ) || empty( $parsed_block['attrs']['productId'] ) ) {
			return $parsed_block;
		}

		/** @var PLLWC_Product_Language_CPT */
		$data_store = PLLWC_Data_Store::load( 'product_language' );

		$product_language = $data_store->get_language( $parsed_block['attrs']['productId'] );
		if ( PLL()->curlang->slug === $product_language ) {
			return $parsed_block;
		}

		$translated_product_id = $data_store->get( $parsed_block['attrs']['productId'] );
		if ( ! $translated_product_id ) {
			return $parsed_block;
		}

		$parsed_block['attrs']['productId'] = $translated_product_id;

		return $parsed_block;
	}

	/**
	 * Filters the locale when an account is created during checkout (REST request).
	 *
	 * @since 1.9.5
	 *
	 * @param  string $locale The locale ID.
	 * @return string
	 */
	public function get_locale( $locale ) {
		$requested_url = pll_get_requested_url();
		if ( ! is_string( $requested_url ) || ! strpos( $requested_url, '/wc/store/v1' ) ) {
			return $locale;
		}

		if ( empty( $_GET['lang'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
			return $locale;
		}

		$lang = PLL()->model->get_language( sanitize_key( $_GET['lang'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
		if ( empty( $lang ) ) {
			return $locale;
		}

		return $lang->locale;
	}

	/**
	 * Replaces blocks assets URLs in WooCommerce transient depending on the current language
	 * when using one domain per language.
	 *
	 * @since 2.1
	 *
	 * @param string|false $value Current value of the WooCommerce transient (JSON encoded).
	 * @return string|false WooCommerce transient with blocks assets URLs modified with the current language.
	 */
	public function blocks_assets_links( $value ) {
		$transient_value = (array) json_decode( (string) $value, true );

		if (
			json_last_error() !== JSON_ERROR_NONE ||
			empty( $transient_value['script_data'] ) ||
			! is_array( $transient_value['script_data'] )
		) {
			return $value;
		}

		foreach ( $transient_value['script_data'] as $key => $script_data ) {
			if ( empty( $script_data['src'] ) ) {
				continue;
			}
			/** @var PLL_Language $language */
			$language = PLL()->curlang;

			$transient_value['script_data'][ $key ]['src'] = PLL()->links_model->switch_language_in_link( $script_data['src'], $language );
		}

		return wp_json_encode( $transient_value );
	}
}