HEX
Server: LiteSpeed
System: Linux eko108.isimtescil.net 4.18.0-477.21.1.lve.1.el8.x86_64 #1 SMP Tue Sep 5 23:08:35 UTC 2023 x86_64
User: uyarreklamcomtr (11202)
PHP: 7.4.33
Disabled: opcache_get_status
Upload Files
File: /var/www/vhosts/uyarreklam.com.tr/httpdocs/Domain.tar
Bootstrap.php000064400000043132151550142640007240 0ustar00<?php
namespace Automattic\WooCommerce\Blocks\Domain;

use Automattic\WooCommerce\Blocks\Assets\Api as AssetApi;
use Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry;
use Automattic\WooCommerce\Blocks\AssetsController;
use Automattic\WooCommerce\Blocks\BlockPatterns;
use Automattic\WooCommerce\Blocks\BlockTemplatesController;
use Automattic\WooCommerce\Blocks\BlockTypesController;
use Automattic\WooCommerce\Blocks\Domain\Services\CreateAccount;
use Automattic\WooCommerce\Blocks\Domain\Services\Notices;
use Automattic\WooCommerce\Blocks\Domain\Services\DraftOrders;
use Automattic\WooCommerce\Blocks\Domain\Services\FeatureGating;
use Automattic\WooCommerce\Blocks\Domain\Services\GoogleAnalytics;
use Automattic\WooCommerce\Blocks\Domain\Services\Hydration;
use Automattic\WooCommerce\Blocks\InboxNotifications;
use Automattic\WooCommerce\Blocks\Installer;
use Automattic\WooCommerce\Blocks\Migration;
use Automattic\WooCommerce\Blocks\Payments\Api as PaymentsApi;
use Automattic\WooCommerce\Blocks\Payments\Integrations\BankTransfer;
use Automattic\WooCommerce\Blocks\Payments\Integrations\CashOnDelivery;
use Automattic\WooCommerce\Blocks\Payments\Integrations\Cheque;
use Automattic\WooCommerce\Blocks\Payments\Integrations\PayPal;
use Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry;
use Automattic\WooCommerce\Blocks\Registry\Container;
use Automattic\WooCommerce\Blocks\Templates\CartTemplate;
use Automattic\WooCommerce\Blocks\Templates\CheckoutHeaderTemplate;
use Automattic\WooCommerce\Blocks\Templates\CheckoutTemplate;
use Automattic\WooCommerce\Blocks\Templates\ClassicTemplatesCompatibility;
use Automattic\WooCommerce\Blocks\Templates\OrderConfirmationTemplate;
use Automattic\WooCommerce\Blocks\Templates\ProductAttributeTemplate;
use Automattic\WooCommerce\Blocks\Templates\ProductSearchResultsTemplate;
use Automattic\WooCommerce\StoreApi\RoutesController;
use Automattic\WooCommerce\StoreApi\SchemaController;
use Automattic\WooCommerce\StoreApi\StoreApi;
use Automattic\WooCommerce\Blocks\Shipping\ShippingController;
use Automattic\WooCommerce\Blocks\Templates\SingleProductTemplateCompatibility;
use Automattic\WooCommerce\Blocks\Templates\ArchiveProductTemplatesCompatibility;

/**
 * Takes care of bootstrapping the plugin.
 *
 * @since 2.5.0
 */
class Bootstrap {

	/**
	 * Holds the Dependency Injection Container
	 *
	 * @var Container
	 */
	private $container;

	/**
	 * Holds the Package instance
	 *
	 * @var Package
	 */
	private $package;


	/**
	 * Holds the Migration instance
	 *
	 * @var Migration
	 */
	private $migration;

	/**
	 * Constructor
	 *
	 * @param Container $container  The Dependency Injection Container.
	 */
	public function __construct( Container $container ) {
		$this->container = $container;
		$this->package   = $container->get( Package::class );
		$this->migration = $container->get( Migration::class );

		if ( $this->has_core_dependencies() ) {
			$this->init();
			/**
			 * Fires when the woocommerce blocks are loaded and ready to use.
			 *
			 * This hook is intended to be used as a safe event hook for when the plugin
			 * has been loaded, and all dependency requirements have been met.
			 *
			 * To ensure blocks are initialized, you must use the `woocommerce_blocks_loaded`
			 * hook instead of the `plugins_loaded` hook. This is because the functions
			 * hooked into plugins_loaded on the same priority load in an inconsistent and unpredictable manner.
			 *
			 * @since 2.5.0
			 */
			do_action( 'woocommerce_blocks_loaded' );
		}
	}

	/**
	 * Init the package - load the blocks library and define constants.
	 */
	protected function init() {
		$this->register_dependencies();
		$this->register_payment_methods();
		$this->load_interactivity_api();

		// This is just a temporary solution to make sure the migrations are run. We have to refactor this. More details: https://github.com/woocommerce/woocommerce-blocks/issues/10196.
		if ( $this->package->get_version() !== $this->package->get_version_stored_on_db() ) {
			$this->migration->run_migrations();
			$this->package->set_version_stored_on_db();
		}

		add_action(
			'admin_init',
			function() {
				// Delete this notification because the blocks are included in WC Core now. This will handle any sites
				// with lingering notices.
				InboxNotifications::delete_surface_cart_checkout_blocks_notification();
			},
			10,
			0
		);

		$is_rest = wc()->is_rest_api_request();
		// phpcs:disable WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		$is_store_api_request = $is_rest && ! empty( $_SERVER['REQUEST_URI'] ) && ( false !== strpos( $_SERVER['REQUEST_URI'], trailingslashit( rest_get_url_prefix() ) . 'wc/store/' ) );

		// Load and init assets.
		$this->container->get( StoreApi::class )->init();
		$this->container->get( PaymentsApi::class )->init();
		$this->container->get( DraftOrders::class )->init();
		$this->container->get( CreateAccount::class )->init();
		$this->container->get( ShippingController::class )->init();

		// Load assets in admin and on the frontend.
		if ( ! $is_rest ) {
			$this->add_build_notice();
			$this->container->get( AssetDataRegistry::class );
			$this->container->get( AssetsController::class );
			$this->container->get( Installer::class )->init();
			$this->container->get( GoogleAnalytics::class )->init();
		}

		// Load assets unless this is a request specifically for the store API.
		if ( ! $is_store_api_request ) {
			// Template related functionality. These won't be loaded for store API requests, but may be loaded for
			// regular rest requests to maintain compatibility with the store editor.
			$this->container->get( BlockPatterns::class );
			$this->container->get( BlockTypesController::class );
			$this->container->get( BlockTemplatesController::class );
			$this->container->get( ProductSearchResultsTemplate::class );
			$this->container->get( ProductAttributeTemplate::class );
			$this->container->get( CartTemplate::class );
			$this->container->get( CheckoutTemplate::class );
			$this->container->get( CheckoutHeaderTemplate::class );
			$this->container->get( OrderConfirmationTemplate::class );
			$this->container->get( ClassicTemplatesCompatibility::class );
			$this->container->get( ArchiveProductTemplatesCompatibility::class )->init();
			$this->container->get( SingleProductTemplateCompatibility::class )->init();
			$this->container->get( Notices::class )->init();
		}
	}

	/**
	 * Check core dependencies exist.
	 *
	 * @return boolean
	 */
	protected function has_core_dependencies() {
		$has_needed_dependencies = class_exists( 'WooCommerce', false );
		if ( $has_needed_dependencies ) {
			$plugin_data = \get_file_data(
				$this->package->get_path( 'woocommerce-gutenberg-products-block.php' ),
				[
					'RequiredWCVersion' => 'WC requires at least',
				]
			);
			if ( isset( $plugin_data['RequiredWCVersion'] ) && version_compare( \WC()->version, $plugin_data['RequiredWCVersion'], '<' ) ) {
				$has_needed_dependencies = false;
				add_action(
					'admin_notices',
					function() {
						if ( should_display_compatibility_notices() ) {
							?>
							<div class="notice notice-error">
								<p><?php esc_html_e( 'The WooCommerce Blocks plugin requires a more recent version of WooCommerce and has been deactivated. Please update to the latest version of WooCommerce.', 'woocommerce' ); ?></p>
							</div>
							<?php
						}
					}
				);
			}
		}
		return $has_needed_dependencies;
	}

	/**
	 * See if files have been built or not.
	 *
	 * @return bool
	 */
	protected function is_built() {
		return file_exists(
			$this->package->get_path( 'build/featured-product.js' )
		);
	}

	/**
	 * Add a notice stating that the build has not been done yet.
	 */
	protected function add_build_notice() {
		if ( $this->is_built() ) {
			return;
		}
		add_action(
			'admin_notices',
			function() {
				echo '<div class="error"><p>';
				printf(
					/* translators: %1$s is the install command, %2$s is the build command, %3$s is the watch command. */
					esc_html__( 'WooCommerce Blocks development mode requires files to be built. From the plugin directory, run %1$s to install dependencies, %2$s to build the files or %3$s to build the files and watch for changes.', 'woocommerce' ),
					'<code>npm install</code>',
					'<code>npm run build</code>',
					'<code>npm start</code>'
				);
				echo '</p></div>';
			}
		);
	}

	/**
	 * Load and set up the Interactivity API if enabled.
	 */
	protected function load_interactivity_api() {
			require_once __DIR__ . '/../Interactivity/load.php';
	}

	/**
	 * Register core dependencies with the container.
	 */
	protected function register_dependencies() {
		$this->container->register(
			FeatureGating::class,
			function () {
				return new FeatureGating();
			}
		);
		$this->container->register(
			AssetApi::class,
			function ( Container $container ) {
				return new AssetApi( $container->get( Package::class ) );
			}
		);
		$this->container->register(
			AssetDataRegistry::class,
			function( Container $container ) {
				return new AssetDataRegistry( $container->get( AssetApi::class ) );
			}
		);
		$this->container->register(
			AssetsController::class,
			function( Container $container ) {
				return new AssetsController( $container->get( AssetApi::class ) );
			}
		);
		$this->container->register(
			PaymentMethodRegistry::class,
			function() {
				return new PaymentMethodRegistry();
			}
		);
		$this->container->register(
			Installer::class,
			function () {
				return new Installer();
			}
		);
		$this->container->register(
			BlockTypesController::class,
			function ( Container $container ) {
				$asset_api           = $container->get( AssetApi::class );
				$asset_data_registry = $container->get( AssetDataRegistry::class );
				return new BlockTypesController( $asset_api, $asset_data_registry );
			}
		);
		$this->container->register(
			BlockTemplatesController::class,
			function ( Container $container ) {
				return new BlockTemplatesController( $container->get( Package::class ) );
			}
		);
		$this->container->register(
			ProductSearchResultsTemplate::class,
			function () {
				return new ProductSearchResultsTemplate();
			}
		);
		$this->container->register(
			ProductAttributeTemplate::class,
			function () {
				return new ProductAttributeTemplate();
			}
		);
		$this->container->register(
			CartTemplate::class,
			function () {
				return new CartTemplate();
			}
		);
		$this->container->register(
			CheckoutTemplate::class,
			function () {
				return new CheckoutTemplate();
			}
		);
		$this->container->register(
			CheckoutHeaderTemplate::class,
			function () {
				return new CheckoutHeaderTemplate();
			}
		);
		$this->container->register(
			OrderConfirmationTemplate::class,
			function () {
				return new OrderConfirmationTemplate();
			}
		);
		$this->container->register(
			ClassicTemplatesCompatibility::class,
			function ( Container $container ) {
				$asset_data_registry = $container->get( AssetDataRegistry::class );
				return new ClassicTemplatesCompatibility( $asset_data_registry );
			}
		);
		$this->container->register(
			ArchiveProductTemplatesCompatibility::class,
			function () {
				return new ArchiveProductTemplatesCompatibility();
			}
		);

		$this->container->register(
			SingleProductTemplateCompatibility::class,
			function () {
				return new SingleProductTemplateCompatibility();
			}
		);
		$this->container->register(
			DraftOrders::class,
			function( Container $container ) {
				return new DraftOrders( $container->get( Package::class ) );
			}
		);
		$this->container->register(
			CreateAccount::class,
			function( Container $container ) {
				return new CreateAccount( $container->get( Package::class ) );
			}
		);
		$this->container->register(
			GoogleAnalytics::class,
			function( Container $container ) {
				$asset_api = $container->get( AssetApi::class );
				return new GoogleAnalytics( $asset_api );
			}
		);
		$this->container->register(
			Notices::class,
			function( Container $container ) {
				return new Notices( $container->get( Package::class ) );
			}
		);
		$this->container->register(
			Hydration::class,
			function( Container $container ) {
				return new Hydration( $container->get( AssetDataRegistry::class ) );
			}
		);
		$this->container->register(
			PaymentsApi::class,
			function ( Container $container ) {
				$payment_method_registry = $container->get( PaymentMethodRegistry::class );
				$asset_data_registry     = $container->get( AssetDataRegistry::class );
				return new PaymentsApi( $payment_method_registry, $asset_data_registry );
			}
		);
		$this->container->register(
			StoreApi::class,
			function () {
				return new StoreApi();
			}
		);
		// Maintains backwards compatibility with previous Store API namespace.
		$this->container->register(
			'Automattic\WooCommerce\Blocks\StoreApi\Formatters',
			function( Container $container ) {
				$this->deprecated_dependency( 'Automattic\WooCommerce\Blocks\StoreApi\Formatters', '7.2.0', 'Automattic\WooCommerce\StoreApi\Formatters', '7.4.0' );
				return $container->get( StoreApi::class )->container()->get( \Automattic\WooCommerce\StoreApi\Formatters::class );
			}
		);
		$this->container->register(
			'Automattic\WooCommerce\Blocks\Domain\Services\ExtendRestApi',
			function( Container $container ) {
				$this->deprecated_dependency( 'Automattic\WooCommerce\Blocks\Domain\Services\ExtendRestApi', '7.2.0', 'Automattic\WooCommerce\StoreApi\Schemas\ExtendSchema', '7.4.0' );
				return $container->get( StoreApi::class )->container()->get( \Automattic\WooCommerce\StoreApi\Schemas\ExtendSchema::class );
			}
		);
		$this->container->register(
			'Automattic\WooCommerce\Blocks\StoreApi\SchemaController',
			function( Container $container ) {
				$this->deprecated_dependency( 'Automattic\WooCommerce\Blocks\StoreApi\SchemaController', '7.2.0', 'Automattic\WooCommerce\StoreApi\SchemaController', '7.4.0' );
				return $container->get( StoreApi::class )->container()->get( SchemaController::class );
			}
		);
		$this->container->register(
			'Automattic\WooCommerce\Blocks\StoreApi\RoutesController',
			function( Container $container ) {
				$this->deprecated_dependency( 'Automattic\WooCommerce\Blocks\StoreApi\RoutesController', '7.2.0', 'Automattic\WooCommerce\StoreApi\RoutesController', '7.4.0' );
				return $container->get( StoreApi::class )->container()->get( RoutesController::class );
			}
		);
		$this->container->register(
			BlockPatterns::class,
			function () {
				return new BlockPatterns( $this->package );
			}
		);
		$this->container->register(
			ShippingController::class,
			function ( $container ) {
				$asset_api           = $container->get( AssetApi::class );
				$asset_data_registry = $container->get( AssetDataRegistry::class );
				return new ShippingController( $asset_api, $asset_data_registry );
			}
		);
	}

	/**
	 * Throws a deprecation notice for a dependency without breaking requests.
	 *
	 * @param string $function Class or function being deprecated.
	 * @param string $version Version in which it was deprecated.
	 * @param string $replacement Replacement class or function, if applicable.
	 * @param string $trigger_error_version Optional version to start surfacing this as a PHP error rather than a log. Defaults to $version.
	 */
	protected function deprecated_dependency( $function, $version, $replacement = '', $trigger_error_version = '' ) {
		if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) {
			return;
		}

		$trigger_error_version = $trigger_error_version ? $trigger_error_version : $version;
		$error_message         = $replacement ? sprintf(
			'%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.',
			$function,
			$version,
			$replacement
		) : sprintf(
			'%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.',
			$function,
			$version
		);
		/**
		 * Fires when a deprecated function is called.
		 *
		 * @since 7.3.0
		 */
		do_action( 'deprecated_function_run', $function, $replacement, $version );

		$log_error = false;

		// If headers have not been sent yet, log to avoid breaking the request.
		if ( ! headers_sent() ) {
			$log_error = true;
		}

		// If the $trigger_error_version was not yet reached, only log the error.
		if ( version_compare( $this->package->get_version(), $trigger_error_version, '<' ) ) {
			$log_error = true;
		}

		/**
		 * Filters whether to trigger an error for deprecated functions. (Same as WP core)
		 *
		 * @since 7.3.0
		 *
		 * @param bool $trigger Whether to trigger the error for deprecated functions. Default true.
		 */
		if ( ! apply_filters( 'deprecated_function_trigger_error', true ) ) {
			$log_error = true;
		}

		if ( $log_error ) {
			// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
			error_log( $error_message );
		} else {
			// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
			trigger_error( $error_message, E_USER_DEPRECATED );
		}
	}

	/**
	 * Register payment method integrations with the container.
	 */
	protected function register_payment_methods() {
		$this->container->register(
			Cheque::class,
			function( Container $container ) {
				$asset_api = $container->get( AssetApi::class );
				return new Cheque( $asset_api );
			}
		);
		$this->container->register(
			PayPal::class,
			function( Container $container ) {
				$asset_api = $container->get( AssetApi::class );
				return new PayPal( $asset_api );
			}
		);
		$this->container->register(
			BankTransfer::class,
			function( Container $container ) {
				$asset_api = $container->get( AssetApi::class );
				return new BankTransfer( $asset_api );
			}
		);
		$this->container->register(
			CashOnDelivery::class,
			function( Container $container ) {
				$asset_api = $container->get( AssetApi::class );
				return new CashOnDelivery( $asset_api );
			}
		);
	}
}
Package.php000064400000006174151550142640006623 0ustar00<?php
namespace Automattic\WooCommerce\Blocks\Domain;

use Automattic\WooCommerce\Blocks\Options;
use Automattic\WooCommerce\Blocks\Domain\Services\FeatureGating;


/**
 * Main package class.
 *
 * Returns information about the package and handles init.
 *
 * @since 2.5.0
 */
class Package {

	/**
	 * Holds the current version of the blocks plugin.
	 *
	 * @var string
	 */
	private $version;

	/**
	 * Holds the main path to the blocks plugin directory.
	 *
	 * @var string
	 */
	private $path;

	/**
	 * Holds locally the plugin_dir_url to avoid recomputing it.
	 *
	 * @var string
	 */
	private $plugin_dir_url;

	/**
	 * Holds the feature gating class instance.
	 *
	 * @var FeatureGating
	 */
	private $feature_gating;

	/**
	 * Constructor
	 *
	 * @param string        $version        Version of the plugin.
	 * @param string        $plugin_path    Path to the main plugin file.
	 * @param FeatureGating $feature_gating Feature gating class instance.
	 */
	public function __construct( $version, $plugin_path, FeatureGating $feature_gating ) {
		$this->version        = $version;
		$this->path           = $plugin_path;
		$this->feature_gating = $feature_gating;
	}

	/**
	 * Returns the version of the plugin.
	 *
	 * @return string
	 */
	public function get_version() {
		return $this->version;
	}

	/**
	 * Returns the version of the plugin stored in the database.
	 *
	 * @return string
	 */
	public function get_version_stored_on_db() {
		return get_option( Options::WC_BLOCK_VERSION, '' );
	}

	/**
	 * Set the version of the plugin stored in the database.
	 * This is useful during the first installation or after the upgrade process.
	 */
	public function set_version_stored_on_db() {
		update_option( Options::WC_BLOCK_VERSION, $this->get_version() );

	}

	/**
	 * Returns the path to the plugin directory.
	 *
	 * @param string $relative_path  If provided, the relative path will be
	 *                               appended to the plugin path.
	 *
	 * @return string
	 */
	public function get_path( $relative_path = '' ) {
		return trailingslashit( $this->path ) . $relative_path;
	}

	/**
	 * Returns the url to the blocks plugin directory.
	 *
	 * @param string $relative_url If provided, the relative url will be
	 *                             appended to the plugin url.
	 *
	 * @return string
	 */
	public function get_url( $relative_url = '' ) {
		if ( ! $this->plugin_dir_url ) {
			// Append index.php so WP does not return the parent directory.
			$this->plugin_dir_url = plugin_dir_url( $this->path . '/index.php' );
		}

		return $this->plugin_dir_url . $relative_url;
	}

	/**
	 * Returns an instance of the the FeatureGating class.
	 *
	 * @return FeatureGating
	 */
	public function feature() {
		return $this->feature_gating;
	}

	/**
	 * Checks if we're executing the code in an experimental build mode.
	 *
	 * @return boolean
	 */
	public function is_experimental_build() {
		return $this->feature()->is_experimental_build();
	}

	/**
	 * Checks if we're executing the code in an feature plugin or experimental build mode.
	 *
	 * @return boolean
	 */
	public function is_feature_plugin_build() {
		return $this->feature()->is_feature_plugin_build();
	}
}
Services/CreateAccount.php000064400000004551151550142640011570 0ustar00<?php
namespace Automattic\WooCommerce\Blocks\Domain\Services;

use Automattic\WooCommerce\Blocks\Domain\Package;
use Automattic\WooCommerce\Blocks\Domain\Services\Email\CustomerNewAccount;

/**
 * Service class implementing new create account emails used for order processing via the Block Based Checkout.
 */
class CreateAccount {
	/**
	 * Reference to the Package instance
	 *
	 * @var Package
	 */
	private $package;

	/**
	 * Constructor.
	 *
	 * @param Package $package An instance of (Woo Blocks) Package.
	 */
	public function __construct( Package $package ) {
		$this->package = $package;
	}

	/**
	 * Init - register handlers for WooCommerce core email hooks.
	 */
	public function init() {
		// Override core email handlers to add our new improved "new account" email.
		add_action(
			'woocommerce_email',
			function ( $wc_emails_instance ) {
				// Remove core "new account" handler; we are going to replace it.
				remove_action( 'woocommerce_created_customer_notification', array( $wc_emails_instance, 'customer_new_account' ), 10, 3 );

				// Add custom "new account" handler.
				add_action(
					'woocommerce_created_customer_notification',
					function( $customer_id, $new_customer_data = array(), $password_generated = false ) use ( $wc_emails_instance ) {
						// If this is a block-based signup, send a new email with password reset link (no password in email).
						if ( isset( $new_customer_data['source'] ) && 'store-api' === $new_customer_data['source'] ) {
							$this->customer_new_account( $customer_id, $new_customer_data );
							return;
						}

						// Otherwise, trigger the existing legacy email (with new password inline).
						$wc_emails_instance->customer_new_account( $customer_id, $new_customer_data, $password_generated );
					},
					10,
					3
				);
			}
		);
	}

	/**
	 * Trigger new account email.
	 * This is intended as a replacement to WC_Emails::customer_new_account(),
	 * with a set password link instead of emailing the new password in email
	 * content.
	 *
	 * @param int   $customer_id       The ID of the new customer account.
	 * @param array $new_customer_data Assoc array of data for the new account.
	 */
	public function customer_new_account( $customer_id = 0, array $new_customer_data = array() ) {
		$new_account_email = new CustomerNewAccount( $this->package );
		$new_account_email->trigger( $customer_id, $new_customer_data );
	}
}
Services/DraftOrders.php000064400000016437151550142640011275 0ustar00<?php
namespace Automattic\WooCommerce\Blocks\Domain\Services;

use Automattic\WooCommerce\Blocks\Domain\Package;
use Exception;
use WC_Order;

/**
 * Service class for adding DraftOrder functionality to WooCommerce core.
 *
 * Sets up all logic related to the Checkout Draft Orders service
 *
 * @internal
 */
class DraftOrders {

	const DB_STATUS = 'wc-checkout-draft';
	const STATUS    = 'checkout-draft';

	/**
	 * Holds the Package instance
	 *
	 * @var Package
	 */
	private $package;

	/**
	 * Constructor
	 *
	 * @param Package $package An instance of the package class.
	 */
	public function __construct( Package $package ) {
		$this->package = $package;
	}

	/**
	 * Set all hooks related to adding Checkout Draft order functionality to Woo Core.
	 */
	public function init() {
		add_filter( 'wc_order_statuses', [ $this, 'register_draft_order_status' ] );
		add_filter( 'woocommerce_register_shop_order_post_statuses', [ $this, 'register_draft_order_post_status' ] );
		add_filter( 'woocommerce_analytics_excluded_order_statuses', [ $this, 'append_draft_order_post_status' ] );
		add_filter( 'woocommerce_valid_order_statuses_for_payment', [ $this, 'append_draft_order_post_status' ] );
		add_filter( 'woocommerce_valid_order_statuses_for_payment_complete', [ $this, 'append_draft_order_post_status' ] );
		// Hook into the query to retrieve My Account orders so draft status is excluded.
		add_action( 'woocommerce_my_account_my_orders_query', [ $this, 'delete_draft_order_post_status_from_args' ] );
		add_action( 'woocommerce_cleanup_draft_orders', [ $this, 'delete_expired_draft_orders' ] );
		add_action( 'admin_init', [ $this, 'install' ] );
	}

	/**
	 * Installation related logic for Draft order functionality.
	 *
	 * @internal
	 */
	public function install() {
		$this->maybe_create_cronjobs();
	}

	/**
	 * Maybe create cron events.
	 */
	protected function maybe_create_cronjobs() {
		if ( function_exists( 'as_next_scheduled_action' ) && false === as_next_scheduled_action( 'woocommerce_cleanup_draft_orders' ) ) {
			as_schedule_recurring_action( strtotime( 'midnight tonight' ), DAY_IN_SECONDS, 'woocommerce_cleanup_draft_orders' );
		}
	}

	/**
	 * Register custom order status for orders created via the API during checkout.
	 *
	 * Draft order status is used before payment is attempted, during checkout, when a cart is converted to an order.
	 *
	 * @param array $statuses Array of statuses.
	 * @internal
	 * @return array
	 */
	public function register_draft_order_status( array $statuses ) {
		$statuses[ self::DB_STATUS ] = _x( 'Draft', 'Order status', 'woocommerce' );
		return $statuses;
	}

	/**
	 * Register custom order post status for orders created via the API during checkout.
	 *
	 * @param array $statuses Array of statuses.
	 * @internal

	 * @return array
	 */
	public function register_draft_order_post_status( array $statuses ) {
		$statuses[ self::DB_STATUS ] = $this->get_post_status_properties();
		return $statuses;
	}

	/**
	 * Returns the properties of this post status for registration.
	 *
	 * @return array
	 */
	private function get_post_status_properties() {
		return [
			'label'                     => _x( 'Draft', 'Order status', 'woocommerce' ),
			'public'                    => false,
			'exclude_from_search'       => false,
			'show_in_admin_all_list'    => false,
			'show_in_admin_status_list' => true,
			/* translators: %s: number of orders */
			'label_count'               => _n_noop( 'Drafts <span class="count">(%s)</span>', 'Drafts <span class="count">(%s)</span>', 'woocommerce' ),
		];
	}

	/**
	 * Remove draft status from the 'status' argument of an $args array.
	 *
	 * @param array $args Array of arguments containing statuses in the status key.
	 * @internal
	 * @return array
	 */
	public function delete_draft_order_post_status_from_args( $args ) {
		if ( ! array_key_exists( 'status', $args ) ) {
			$statuses = [];
			foreach ( wc_get_order_statuses() as $key => $label ) {
				if ( self::DB_STATUS !== $key ) {
					$statuses[] = str_replace( 'wc-', '', $key );
				}
			}
			$args['status'] = $statuses;
		} elseif ( self::DB_STATUS === $args['status'] ) {
			$args['status'] = '';
		} elseif ( is_array( $args['status'] ) ) {
			$args['status'] = array_diff_key( $args['status'], array( self::STATUS => null ) );
		}

		return $args;
	}

	/**
	 * Append draft status to a list of statuses.
	 *
	 * @param array $statuses Array of statuses.
	 * @internal

	 * @return array
	 */
	public function append_draft_order_post_status( $statuses ) {
		$statuses[] = self::STATUS;
		return $statuses;
	}

	/**
	 * Delete draft orders older than a day in batches of 20.
	 *
	 * Ran on a daily cron schedule.
	 *
	 * @internal
	 */
	public function delete_expired_draft_orders() {
		$count      = 0;
		$batch_size = 20;
		$this->ensure_draft_status_registered();
		$orders = wc_get_orders(
			[
				'date_modified' => '<=' . strtotime( '-1 DAY' ),
				'limit'         => $batch_size,
				'status'        => self::DB_STATUS,
				'type'          => 'shop_order',
			]
		);

		// do we bail because the query results are unexpected?
		try {
			$this->assert_order_results( $orders, $batch_size );
			if ( $orders ) {
				foreach ( $orders as $order ) {
					$order->delete( true );
					$count ++;
				}
			}
			if ( $batch_size === $count && function_exists( 'as_enqueue_async_action' ) ) {
				as_enqueue_async_action( 'woocommerce_cleanup_draft_orders' );
			}
		} catch ( Exception $error ) {
			wc_caught_exception( $error, __METHOD__ );
		}
	}

	/**
	 * Since it's possible for third party code to clobber the `$wp_post_statuses` global,
	 * we need to do a final check here to make sure the draft post status is
	 * registered with the global so that it is not removed by WP_Query status
	 * validation checks.
	 */
	private function ensure_draft_status_registered() {
		$is_registered = get_post_stati( [ 'name' => self::DB_STATUS ] );
		if ( empty( $is_registered ) ) {
			register_post_status(
				self::DB_STATUS,
				$this->get_post_status_properties()
			);
		}
	}

	/**
	 * Asserts whether incoming order results are expected given the query
	 * this service class executes.
	 *
	 * @param WC_Order[] $order_results The order results being asserted.
	 * @param int        $expected_batch_size The expected batch size for the results.
	 * @throws Exception If any assertions fail, an exception is thrown.
	 */
	private function assert_order_results( $order_results, $expected_batch_size ) {
		// if not an array, then just return because it won't get handled
		// anyways.
		if ( ! is_array( $order_results ) ) {
			return;
		}

		$suffix = ' This is an indicator that something is filtering WooCommerce or WordPress queries and modifying the query parameters.';

		// if count is greater than our expected batch size, then that's a problem.
		if ( count( $order_results ) > 20 ) {
			throw new Exception( 'There are an unexpected number of results returned from the query.' . $suffix );
		}

		// if any of the returned orders are not draft (or not a WC_Order), then that's a problem.
		foreach ( $order_results as $order ) {
			if ( ! ( $order instanceof WC_Order ) ) {
				throw new Exception( 'The returned results contain a value that is not a WC_Order.' . $suffix );
			}
			if ( ! $order->has_status( self::STATUS ) ) {
				throw new Exception( 'The results contain an order that is not a `wc-checkout-draft` status in the results.' . $suffix );
			}
		}
	}
}
Services/Email/CustomerNewAccount.php000064400000011042151550142640013660 0ustar00<?php
namespace Automattic\WooCommerce\Blocks\Domain\Services\Email;

use Automattic\WooCommerce\Blocks\Domain\Package;

/**
 * Customer New Account.
 *
 * An email sent to the customer when they create an account.
 * This is intended as a replacement to \WC_Email_Customer_New_Account(),
 * with a set password link instead of emailing the new password in email
 * content.
 *
 * @extends     \WC_Email
 */
class CustomerNewAccount extends \WC_Email {

	/**
	 * User login name.
	 *
	 * @var string
	 */
	public $user_login;

	/**
	 * User email.
	 *
	 * @var string
	 */
	public $user_email;

	/**
	 * Magic link to set initial password.
	 *
	 * @var string
	 */
	public $set_password_url;

	/**
	 * Override (force) default template path
	 *
	 * @var string
	 */
	public $default_template_path;

	/**
	 * Constructor.
	 *
	 * @param Package $package An instance of (Woo Blocks) Package.
	 */
	public function __construct( Package $package ) {
		// Note - we're using the same ID as the real email.
		// This ensures that any merchant tweaks (Settings > Emails)
		// apply to this email (consistent with the core email).
		$this->id                    = 'customer_new_account';
		$this->customer_email        = true;
		$this->title                 = __( 'New account', 'woocommerce' );
		$this->description           = __( '“New Account” emails are sent when a customer signs up via the checkout flow.', 'woocommerce' );
		$this->template_html         = 'emails/customer-new-account-blocks.php';
		$this->template_plain        = 'emails/plain/customer-new-account-blocks.php';
		$this->default_template_path = $package->get_path( '/templates/' );

		// Call parent constructor.
		parent::__construct();
	}

	/**
	 * Get email subject.
	 *
	 * @since  3.1.0
	 * @return string
	 */
	public function get_default_subject() {
		return __( 'Your {site_title} account has been created!', 'woocommerce' );
	}

	/**
	 * Get email heading.
	 *
	 * @since  3.1.0
	 * @return string
	 */
	public function get_default_heading() {
		return __( 'Welcome to {site_title}', 'woocommerce' );
	}

	/**
	 * Trigger.
	 *
	 * @param int    $user_id User ID.
	 * @param string $user_pass User password.
	 * @param bool   $password_generated Whether the password was generated automatically or not.
	 */
	public function trigger( $user_id, $user_pass = '', $password_generated = false ) {
		$this->setup_locale();

		if ( $user_id ) {
			$this->object = new \WP_User( $user_id );

			// Generate a magic link so user can set initial password.
			$key = get_password_reset_key( $this->object );
			if ( ! is_wp_error( $key ) ) {
				$action                 = 'newaccount';
				$this->set_password_url = wc_get_account_endpoint_url( 'lost-password' ) . "?action=$action&key=$key&login=" . rawurlencode( $this->object->user_login );
			}

			$this->user_login = stripslashes( $this->object->user_login );
			$this->user_email = stripslashes( $this->object->user_email );
			$this->recipient  = $this->user_email;
		}

		if ( $this->is_enabled() && $this->get_recipient() ) {
			$this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments(), $this->set_password_url );
		}

		$this->restore_locale();
	}

	/**
	 * Get content html.
	 *
	 * @return string
	 */
	public function get_content_html() {
		return wc_get_template_html(
			$this->template_html,
			array(
				'email_heading'      => $this->get_heading(),
				'additional_content' => $this->get_additional_content(),
				'user_login'         => $this->user_login,
				'blogname'           => $this->get_blogname(),
				'set_password_url'   => $this->set_password_url,
				'sent_to_admin'      => false,
				'plain_text'         => false,
				'email'              => $this,
			),
			'',
			$this->default_template_path
		);
	}

	/**
	 * Get content plain.
	 *
	 * @return string
	 */
	public function get_content_plain() {
		return wc_get_template_html(
			$this->template_plain,
			array(
				'email_heading'      => $this->get_heading(),
				'additional_content' => $this->get_additional_content(),
				'user_login'         => $this->user_login,
				'blogname'           => $this->get_blogname(),
				'set_password_url'   => $this->set_password_url,
				'sent_to_admin'      => false,
				'plain_text'         => true,
				'email'              => $this,
			),
			'',
			$this->default_template_path
		);
	}

	/**
	 * Default content to show below main email content.
	 *
	 * @since 3.7.0
	 * @return string
	 */
	public function get_default_additional_content() {
		return __( 'We look forward to seeing you soon.', 'woocommerce' );
	}
}
Services/FeatureGating.php000064400000007702151550142640011576 0ustar00<?php
namespace Automattic\WooCommerce\Blocks\Domain\Services;

/**
 * Service class that handles the feature flags.
 *
 * @internal
 */
class FeatureGating {

	/**
	 * Current flag value.
	 *
	 * @var int
	 */
	private $flag;

	const EXPERIMENTAL_FLAG   = 3;
	const FEATURE_PLUGIN_FLAG = 2;
	const CORE_FLAG           = 1;

	/**
	 * Current environment
	 *
	 * @var string
	 */
	private $environment;

	const PRODUCTION_ENVIRONMENT  = 'production';
	const DEVELOPMENT_ENVIRONMENT = 'development';
	const TEST_ENVIRONMENT        = 'test';

	/**
	 * Constructor
	 *
	 * @param int    $flag        Hardcoded flag value. Useful for tests.
	 * @param string $environment Hardcoded environment value. Useful for tests.
	 */
	public function __construct( $flag = 0, $environment = 'unset' ) {
		$this->flag        = $flag;
		$this->environment = $environment;
		$this->load_flag();
		$this->load_environment();
	}

	/**
	 * Set correct flag.
	 */
	public function load_flag() {
		if ( 0 === $this->flag ) {
			$default_flag = defined( 'WC_BLOCKS_IS_FEATURE_PLUGIN' ) ? self::FEATURE_PLUGIN_FLAG : self::CORE_FLAG;
			if ( file_exists( __DIR__ . '/../../../blocks.ini' ) ) {
				$allowed_flags = [ self::EXPERIMENTAL_FLAG, self::FEATURE_PLUGIN_FLAG, self::CORE_FLAG ];
				$woo_options   = parse_ini_file( __DIR__ . '/../../../blocks.ini' );
				$this->flag    = is_array( $woo_options ) && in_array( intval( $woo_options['woocommerce_blocks_phase'] ), $allowed_flags, true ) ? $woo_options['woocommerce_blocks_phase'] : $default_flag;
			} else {
				$this->flag = $default_flag;
			}
		}
	}

		/**
		 * Set correct environment.
		 */
	public function load_environment() {
		if ( 'unset' === $this->environment ) {
			if ( file_exists( __DIR__ . '/../../../blocks.ini' ) ) {
				$allowed_environments = [ self::PRODUCTION_ENVIRONMENT, self::DEVELOPMENT_ENVIRONMENT, self::TEST_ENVIRONMENT ];
				$woo_options          = parse_ini_file( __DIR__ . '/../../../blocks.ini' );
				$this->environment    = is_array( $woo_options ) && in_array( $woo_options['woocommerce_blocks_env'], $allowed_environments, true ) ? $woo_options['woocommerce_blocks_env'] : self::PRODUCTION_ENVIRONMENT;
			} else {
				$this->environment = self::PRODUCTION_ENVIRONMENT;
			}
		}
	}

	/**
	 * Returns the current flag value.
	 *
	 * @return int
	 */
	public function get_flag() {
		return $this->flag;
	}

	/**
	 * Checks if we're executing the code in an experimental build mode.
	 *
	 * @return boolean
	 */
	public function is_experimental_build() {
		return $this->flag >= self::EXPERIMENTAL_FLAG;
	}

	/**
	 * Checks if we're executing the code in an feature plugin or experimental build mode.
	 *
	 * @return boolean
	 */
	public function is_feature_plugin_build() {
		return $this->flag >= self::FEATURE_PLUGIN_FLAG;
	}

	/**
	 * Returns the current environment value.
	 *
	 * @return string
	 */
	public function get_environment() {
		return $this->environment;
	}

	/**
	 * Checks if we're executing the code in an development environment.
	 *
	 * @return boolean
	 */
	public function is_development_environment() {
		return self::DEVELOPMENT_ENVIRONMENT === $this->environment;
	}

	/**
	 * Checks if we're executing the code in a production environment.
	 *
	 * @return boolean
	 */
	public function is_production_environment() {
		return self::PRODUCTION_ENVIRONMENT === $this->environment;
	}

	/**
	 * Checks if we're executing the code in a test environment.
	 *
	 * @return boolean
	 */
	public function is_test_environment() {
		return self::TEST_ENVIRONMENT === $this->environment;
	}

	/**
	 * Returns core flag value.
	 *
	 * @return number
	 */
	public static function get_core_flag() {
		return self::CORE_FLAG;
	}

	/**
	 * Returns feature plugin flag value.
	 *
	 * @return number
	 */
	public static function get_feature_plugin_flag() {
		return self::FEATURE_PLUGIN_FLAG;
	}

	/**
	 * Returns experimental flag value.
	 *
	 * @return number
	 */
	public static function get_experimental_flag() {
		return self::EXPERIMENTAL_FLAG;
	}

}
Services/GoogleAnalytics.php000064400000006451151550142640012135 0ustar00<?php
namespace Automattic\WooCommerce\Blocks\Domain\Services;

use Automattic\WooCommerce\Blocks\Package;
use Automattic\WooCommerce\Blocks\Assets\Api as AssetApi;

/**
 * Service class to integrate Blocks with the Google Analytics extension,
 */
class GoogleAnalytics {
	/**
	 * Instance of the asset API.
	 *
	 * @var AssetApi
	 */
	protected $asset_api;

	/**
	 * Constructor.
	 *
	 * @param AssetApi $asset_api Instance of the asset API.
	 */
	public function __construct( AssetApi $asset_api ) {
		$this->asset_api = $asset_api;
	}

	/**
	 * Hook into WP.
	 */
	public function init() {
		// Require Google Analytics Integration to be activated.
		if ( ! class_exists( 'WC_Google_Analytics_Integration', false ) ) {
			return;
		}
		add_action( 'init', array( $this, 'register_assets' ) );
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
		add_filter( 'script_loader_tag', array( $this, 'async_script_loader_tags' ), 10, 3 );
	}

	/**
	 * Register scripts.
	 */
	public function register_assets() {
		$this->asset_api->register_script( 'wc-blocks-google-analytics', 'build/wc-blocks-google-analytics.js', [ 'google-tag-manager' ] );
	}

	/**
	 * Enqueue the Google Tag Manager script if prerequisites are met.
	 */
	public function enqueue_scripts() {
		$settings = $this->get_google_analytics_settings();
		$prefix   = strstr( strtoupper( $settings['ga_id'] ), '-', true );

		// Require tracking to be enabled with a valid GA ID.
		if ( ! in_array( $prefix, [ 'G', 'GT' ], true ) ) {
			return;
		}

		/**
		 * Filter to disable Google Analytics tracking.
		 *
		 * @internal Matches filter name in GA extension.
		 * @since 4.9.0
		 *
		 * @param boolean $disable_tracking If true, tracking will be disabled.
		 */
		if ( apply_filters( 'woocommerce_ga_disable_tracking', ! wc_string_to_bool( $settings['ga_event_tracking_enabled'] ) ) ) {
			return;
		}

		if ( ! wp_script_is( 'google-tag-manager', 'registered' ) ) {
			// phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion
			wp_register_script( 'google-tag-manager', 'https://www.googletagmanager.com/gtag/js?id=' . $settings['ga_id'], [], null, false );
			wp_add_inline_script(
				'google-tag-manager',
				"
	window.dataLayer = window.dataLayer || [];
	function gtag(){dataLayer.push(arguments);}
	gtag('js', new Date());
	gtag('config', '" . esc_js( $settings['ga_id'] ) . "', { 'send_page_view': false });"
			);
		}
		wp_enqueue_script( 'wc-blocks-google-analytics' );
	}

	/**
	 * Get settings from the GA integration extension.
	 *
	 * @return array
	 */
	private function get_google_analytics_settings() {
		return wp_parse_args(
			get_option( 'woocommerce_google_analytics_settings' ),
			[
				'ga_id'                     => '',
				'ga_event_tracking_enabled' => 'no',
			]
		);
	}

	/**
	 * Add async to script tags with defined handles.
	 *
	 * @param string $tag HTML for the script tag.
	 * @param string $handle Handle of script.
	 * @param string $src Src of script.
	 * @return string
	 */
	public function async_script_loader_tags( $tag, $handle, $src ) {
		if ( ! in_array( $handle, array( 'google-tag-manager' ), true ) ) {
			return $tag;
		}
		// If script was output manually in wp_head, abort.
		if ( did_action( 'woocommerce_gtag_snippet' ) ) {
			return '';
		}
		return str_replace( '<script src', '<script async src', $tag );
	}
}
Services/Hydration.php000064400000005322151550142640011006 0ustar00<?php
namespace Automattic\WooCommerce\Blocks\Domain\Services;

use Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry;

/**
 * Service class that handles hydration of API data for blocks.
 */
class Hydration {
	/**
	 * Instance of the asset data registry.
	 *
	 * @var AssetDataRegistry
	 */
	protected $asset_data_registry;

	/**
	 * Cached notices to restore after hydrating the API.
	 *
	 * @var array
	 */
	protected $cached_store_notices = [];

	/**
	 * Constructor.
	 *
	 * @param AssetDataRegistry $asset_data_registry Instance of the asset data registry.
	 */
	public function __construct( AssetDataRegistry $asset_data_registry ) {
		$this->asset_data_registry = $asset_data_registry;
	}

	/**
	 * Hydrates the asset data registry with data from the API. Disables notices and nonces so requests contain valid
	 * data that is not polluted by the current session.
	 *
	 * @param array $path API paths to hydrate e.g. '/wc/store/v1/cart'.
	 * @return array Response data.
	 */
	public function get_rest_api_response_data( $path = '' ) {
		$this->cache_store_notices();
		$this->disable_nonce_check();

		// Preload the request and add it to the array. It will be $preloaded_requests['path']  and contain 'body' and 'headers'.
		$preloaded_requests = rest_preload_api_request( [], $path );

		$this->restore_cached_store_notices();
		$this->restore_nonce_check();

		// Returns just the single preloaded request.
		return $preloaded_requests[ $path ];
	}

	/**
	 * Disable the nonce check temporarily.
	 */
	protected function disable_nonce_check() {
		add_filter( 'woocommerce_store_api_disable_nonce_check', [ $this, 'disable_nonce_check_callback' ] );
	}

	/**
	 * Callback to disable the nonce check. While we could use `__return_true`, we use a custom named callback so that
	 * we can remove it later without affecting other filters.
	 */
	public function disable_nonce_check_callback() {
		return true;
	}

	/**
	 * Restore the nonce check.
	 */
	protected function restore_nonce_check() {
		remove_filter( 'woocommerce_store_api_disable_nonce_check', [ $this, 'disable_nonce_check_callback' ] );
	}

	/**
	 * Cache notices before hydrating the API if the customer has a session.
	 */
	protected function cache_store_notices() {
		if ( ! did_action( 'woocommerce_init' ) || null === WC()->session ) {
			return;
		}
		$this->cached_store_notices = WC()->session->get( 'wc_notices', array() );
		WC()->session->set( 'wc_notices', null );
	}

	/**
	 * Restore notices into current session from cache.
	 */
	protected function restore_cached_store_notices() {
		if ( ! did_action( 'woocommerce_init' ) || null === WC()->session ) {
			return;
		}
		WC()->session->set( 'wc_notices', $this->cached_store_notices );
		$this->cached_store_notices = [];
	}
}
Services/Notices.php000064400000005451151550142640010454 0ustar00<?php
namespace Automattic\WooCommerce\Blocks\Domain\Services;

use Automattic\WooCommerce\Blocks\Domain\Package;
use Automattic\WooCommerce\Blocks\Utils\CartCheckoutUtils;

/**
 * Service class for adding new-style Notices to WooCommerce core.
 *
 * @internal
 */
class Notices {
	/**
	 * Holds the Package instance
	 *
	 * @var Package
	 */
	private $package;

	/**
	 * Templates used for notices.
	 *
	 * @var array
	 */
	private $notice_templates = array(
		'notices/error.php',
		'notices/notice.php',
		'notices/success.php',
	);

	/**
	 * Constructor
	 *
	 * @param Package $package An instance of the package class.
	 */
	public function __construct( Package $package ) {
		$this->package = $package;
	}

	/**
	 * Set all hooks related to adding Checkout Draft order functionality to Woo Core. This is only enabled if the user
	 * is using the new block based cart/checkout.
	 */
	public function init() {
		if ( CartCheckoutUtils::is_cart_block_default() || CartCheckoutUtils::is_checkout_block_default() ) {
			add_filter( 'woocommerce_kses_notice_allowed_tags', [ $this, 'add_kses_notice_allowed_tags' ] );
			add_filter( 'wc_get_template', [ $this, 'get_notices_template' ], 10, 5 );
			add_action(
				'wp_head',
				function() {
					// These pages may return notices in ajax responses, so we need the styles to be ready.
					if ( is_cart() || is_checkout() ) {
						wp_enqueue_style( 'wc-blocks-style' );
					}
				}
			);
		}
	}

	/**
	 * Allow SVG icon in notices.
	 *
	 * @param array $allowed_tags Allowed tags.
	 * @return array
	 */
	public function add_kses_notice_allowed_tags( $allowed_tags ) {
		$svg_args = array(
			'svg'  => array(
				'aria-hidden' => true,
				'xmlns'       => true,
				'width'       => true,
				'height'      => true,
				'viewbox'     => true,
				'focusable'   => true,
			),
			'path' => array(
				'd' => true,
			),
		);
		return array_merge( $allowed_tags, $svg_args );
	}

	/**
	 * Replaces core notice templates with those from blocks.
	 *
	 * The new notice templates match block components with matching icons and styling. The only difference is that core
	 * only has notices for info, success, and error notices, whereas blocks has notices for info, success, error,
	 * warning, and a default notice type.
	 *
	 * @param string $template Located template path.
	 * @param string $template_name Template name.
	 * @param array  $args Template arguments.
	 * @param string $template_path Template path.
	 * @param string $default_path Default path.
	 * @return string
	 */
	public function get_notices_template( $template, $template_name, $args, $template_path, $default_path ) {
		if ( in_array( $template_name, $this->notice_templates, true ) ) {
			$template = $this->package->get_path( 'templates/' . $template_name );
			wp_enqueue_style( 'wc-blocks-style' );
		}
		return $template;
	}
}