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/Assets.tar
Api.php000064400000026272151547714040006007 0ustar00<?php
namespace Automattic\WooCommerce\Blocks\Assets;

use Automattic\WooCommerce\Blocks\Domain\Package;
use Exception;
/**
 * The Api class provides an interface to various asset registration helpers.
 *
 * Contains asset api methods
 *
 * @since 2.5.0
 */
class Api {
	/**
	 * Stores inline scripts already enqueued.
	 *
	 * @var array
	 */
	private $inline_scripts = [];

	/**
	 * Determines if caching is enabled for script data.
	 *
	 * @var boolean
	 */
	private $disable_cache = false;

	/**
	 * Stores loaded script data for the current request
	 *
	 * @var array|null
	 */
	private $script_data = null;

	/**
	 * Stores the hash for the script data, made up of the site url, plugin version and package path.
	 *
	 * @var string
	 */
	private $script_data_hash;

	/**
	 * Stores the transient key used to cache the script data. This will change if the site is accessed via HTTPS or HTTP.
	 *
	 * @var string
	 */
	private $script_data_transient_key = 'woocommerce_blocks_asset_api_script_data';

	/**
	 * Reference to the Package instance
	 *
	 * @var Package
	 */
	private $package;

	/**
	 * Constructor for class
	 *
	 * @param Package $package An instance of Package.
	 */
	public function __construct( Package $package ) {
		$this->package       = $package;
		$this->disable_cache = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) || ! $this->package->feature()->is_production_environment();

		// If the site is accessed via HTTPS, change the transient key. This is to prevent the script URLs being cached
		// with the first scheme they are accessed on after cache expiry.
		if ( is_ssl() ) {
			$this->script_data_transient_key .= '_ssl';
		}
		if ( ! $this->disable_cache ) {
			$this->script_data_hash = $this->get_script_data_hash();
		}
		add_action( 'shutdown', array( $this, 'update_script_data_cache' ), 20 );
	}

	/**
	 * Get the file modified time as a cache buster if we're in dev mode.
	 *
	 * @param string $file Local path to the file (relative to the plugin
	 *                     directory).
	 * @return string The cache buster value to use for the given file.
	 */
	protected function get_file_version( $file ) {
		if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG && file_exists( $this->package->get_path() . $file ) ) {
			return filemtime( $this->package->get_path( trim( $file, '/' ) ) );
		}
		return $this->package->get_version();
	}

	/**
	 * Retrieve the url to an asset for this plugin.
	 *
	 * @param string $relative_path An optional relative path appended to the
	 *                              returned url.
	 *
	 * @return string
	 */
	protected function get_asset_url( $relative_path = '' ) {
		return $this->package->get_url( $relative_path );
	}

	/**
	 * Get the path to a block's metadata
	 *
	 * @param string $block_name The block to get metadata for.
	 * @param string $path Optional. The path to the metadata file inside the 'build' folder.
	 *
	 * @return string|boolean False if metadata file is not found for the block.
	 */
	public function get_block_metadata_path( $block_name, $path = '' ) {
		$path_to_metadata_from_plugin_root = $this->package->get_path( 'build/' . $path . $block_name . '/block.json' );
		if ( ! file_exists( $path_to_metadata_from_plugin_root ) ) {
			return false;
		}
		return $path_to_metadata_from_plugin_root;
	}

	/**
	 * Generates a hash containing the site url, plugin version and package path.
	 *
	 * Moving the plugin, changing the version, or changing the site url will result in a new hash and the cache will be invalidated.
	 *
	 * @return string The generated hash.
	 */
	private function get_script_data_hash() {
		return md5( get_option( 'siteurl', '' ) . $this->package->get_version() . $this->package->get_path() );
	}

	/**
	 * Initialize and load cached script data from the transient cache.
	 *
	 * @return array
	 */
	private function get_cached_script_data() {
		if ( $this->disable_cache ) {
			return [];
		}

		$transient_value = json_decode( (string) get_transient( $this->script_data_transient_key ), true );

		if (
			json_last_error() !== JSON_ERROR_NONE ||
			empty( $transient_value ) ||
			empty( $transient_value['script_data'] ) ||
			empty( $transient_value['version'] ) ||
			$transient_value['version'] !== $this->package->get_version() ||
			empty( $transient_value['hash'] ) ||
			$transient_value['hash'] !== $this->script_data_hash
		) {
			return [];
		}

		return (array) ( $transient_value['script_data'] ?? [] );
	}

	/**
	 * Store all cached script data in the transient cache.
	 */
	public function update_script_data_cache() {
		if ( is_null( $this->script_data ) || $this->disable_cache ) {
			return;
		}
		set_transient(
			$this->script_data_transient_key,
			wp_json_encode(
				array(
					'script_data' => $this->script_data,
					'version'     => $this->package->get_version(),
					'hash'        => $this->script_data_hash,
				)
			),
			DAY_IN_SECONDS * 30
		);
	}

	/**
	 * Get src, version and dependencies given a script relative src.
	 *
	 * @param string $relative_src Relative src to the script.
	 * @param array  $dependencies Optional. An array of registered script handles this script depends on. Default empty array.
	 *
	 * @return array src, version and dependencies of the script.
	 */
	public function get_script_data( $relative_src, $dependencies = [] ) {
		if ( ! $relative_src ) {
			return array(
				'src'          => '',
				'version'      => '1',
				'dependencies' => $dependencies,
			);
		}

		if ( is_null( $this->script_data ) ) {
			$this->script_data = $this->get_cached_script_data();
		}

		if ( empty( $this->script_data[ $relative_src ] ) ) {
			$asset_path = $this->package->get_path( str_replace( '.js', '.asset.php', $relative_src ) );
			// The following require is safe because we are checking if the file exists and it is not a user input.
			// nosemgrep audit.php.lang.security.file.inclusion-arg.
			$asset = file_exists( $asset_path ) ? require $asset_path : [];

			$this->script_data[ $relative_src ] = array(
				'src'          => $this->get_asset_url( $relative_src ),
				'version'      => ! empty( $asset['version'] ) ? $asset['version'] : $this->get_file_version( $relative_src ),
				'dependencies' => ! empty( $asset['dependencies'] ) ? $asset['dependencies'] : [],
			);
		}

		// Return asset details as well as the requested dependencies array.
		return [
			'src'          => $this->script_data[ $relative_src ]['src'],
			'version'      => $this->script_data[ $relative_src ]['version'],
			'dependencies' => array_merge( $this->script_data[ $relative_src ]['dependencies'], $dependencies ),
		];
	}

	/**
	 * Registers a script according to `wp_register_script`, adding the correct prefix, and additionally loading translations.
	 *
	 * When creating script assets, the following rules should be followed:
	 *   1. All asset handles should have a `wc-` prefix.
	 *   2. If the asset handle is for a Block (in editor context) use the `-block` suffix.
	 *   3. If the asset handle is for a Block (in frontend context) use the `-block-frontend` suffix.
	 *   4. If the asset is for any other script being consumed or enqueued by the blocks plugin, use the `wc-blocks-` prefix.
	 *
	 * @since 2.5.0
	 * @throws Exception If the registered script has a dependency on itself.
	 *
	 * @param string $handle        Unique name of the script.
	 * @param string $relative_src  Relative url for the script to the path from plugin root.
	 * @param array  $dependencies  Optional. An array of registered script handles this script depends on. Default empty array.
	 * @param bool   $has_i18n      Optional. Whether to add a script translation call to this file. Default: true.
	 */
	public function register_script( $handle, $relative_src, $dependencies = [], $has_i18n = true ) {
		$script_data = $this->get_script_data( $relative_src, $dependencies );

		if ( in_array( $handle, $script_data['dependencies'], true ) ) {
			if ( $this->package->feature()->is_development_environment() ) {
				$dependencies = array_diff( $script_data['dependencies'], [ $handle ] );
					add_action(
						'admin_notices',
						function() use ( $handle ) {
								echo '<div class="error"><p>';
								/* translators: %s file handle name. */
								printf( esc_html__( 'Script with handle %s had a dependency on itself which has been removed. This is an indicator that your JS code has a circular dependency that can cause bugs.', 'woocommerce' ), esc_html( $handle ) );
								echo '</p></div>';
						}
					);
			} else {
				throw new Exception( sprintf( 'Script with handle %s had a dependency on itself. This is an indicator that your JS code has a circular dependency that can cause bugs.', $handle ) );
			}
		}

		/**
		 * Filters the list of script dependencies.
		 *
		 * @since 3.0.0
		 *
		 * @param array $dependencies The list of script dependencies.
		 * @param string $handle The script's handle.
		 * @return array
		 */
		$script_dependencies = apply_filters( 'woocommerce_blocks_register_script_dependencies', $script_data['dependencies'], $handle );

		wp_register_script( $handle, $script_data['src'], $script_dependencies, $script_data['version'], true );

		if ( $has_i18n && function_exists( 'wp_set_script_translations' ) ) {
			wp_set_script_translations( $handle, 'woocommerce', $this->package->get_path( 'languages' ) );
		}
	}

	/**
	 * Registers a style according to `wp_register_style`.
	 *
	 * @since 2.5.0
	 * @since 2.6.0 Change src to be relative source.
	 *
	 * @param string  $handle       Name of the stylesheet. Should be unique.
	 * @param string  $relative_src Relative source of the stylesheet to the plugin path.
	 * @param array   $deps         Optional. An array of registered stylesheet handles this stylesheet depends on. Default empty array.
	 * @param string  $media        Optional. The media for which this stylesheet has been defined. Default 'all'. Accepts media types like
	 *                              'all', 'print' and 'screen', or media queries like '(orientation: portrait)' and '(max-width: 640px)'.
	 * @param boolean $rtl   Optional. Whether or not to register RTL styles.
	 */
	public function register_style( $handle, $relative_src, $deps = [], $media = 'all', $rtl = false ) {
		$filename = str_replace( plugins_url( '/', __DIR__ ), '', $relative_src );
		$src      = $this->get_asset_url( $relative_src );
		$ver      = $this->get_file_version( $filename );
		wp_register_style( $handle, $src, $deps, $ver, $media );

		if ( $rtl ) {
			wp_style_add_data( $handle, 'rtl', 'replace' );
		}
	}

	/**
	 * Returns the appropriate asset path for current builds.
	 *
	 * @param   string $filename  Filename for asset path (without extension).
	 * @param   string $type      File type (.css or .js).
	 * @return  string             The generated path.
	 */
	public function get_block_asset_build_path( $filename, $type = 'js' ) {
		return "build/$filename.$type";
	}

	/**
	 * Adds an inline script, once.
	 *
	 * @param string $handle Script handle.
	 * @param string $script Script contents.
	 */
	public function add_inline_script( $handle, $script ) {
		if ( ! empty( $this->inline_scripts[ $handle ] ) && in_array( $script, $this->inline_scripts[ $handle ], true ) ) {
			return;
		}

		wp_add_inline_script( $handle, $script );

		if ( isset( $this->inline_scripts[ $handle ] ) ) {
			$this->inline_scripts[ $handle ][] = $script;
		} else {
			$this->inline_scripts[ $handle ] = array( $script );
		}
	}
}
AssetDataRegistry.php000064400000032541151547714040010674 0ustar00<?php
namespace Automattic\WooCommerce\Blocks\Assets;

use Automattic\WooCommerce\Blocks\Package;
use Automattic\WooCommerce\Blocks\Domain\Services\Hydration;
use Exception;
use InvalidArgumentException;

/**
 * Class instance for registering data used on the current view session by
 * assets.
 *
 * Holds data registered for output on the current view session when
 * `wc-settings` is enqueued( directly or via dependency )
 *
 * @since 2.5.0
 */
class AssetDataRegistry {
	/**
	 * Contains registered data.
	 *
	 * @var array
	 */
	private $data = [];

	/**
	 * Contains preloaded API data.
	 *
	 * @var array
	 */
	private $preloaded_api_requests = [];

	/**
	 * Lazy data is an array of closures that will be invoked just before
	 * asset data is generated for the enqueued script.
	 *
	 * @var array
	 */
	private $lazy_data = [];

	/**
	 * Asset handle for registered data.
	 *
	 * @var string
	 */
	private $handle = 'wc-settings';

	/**
	 * Asset API interface for various asset registration.
	 *
	 * @var API
	 */
	private $api;

	/**
	 * Constructor
	 *
	 * @param Api $asset_api  Asset API interface for various asset registration.
	 */
	public function __construct( Api $asset_api ) {
		$this->api = $asset_api;
		$this->init();
	}

	/**
	 * Hook into WP asset registration for enqueueing asset data.
	 */
	protected function init() {
		add_action( 'init', array( $this, 'register_data_script' ) );
		add_action( is_admin() ? 'admin_print_footer_scripts' : 'wp_print_footer_scripts', array( $this, 'enqueue_asset_data' ), 1 );
	}

	/**
	 * Exposes core data via the wcSettings global. This data is shared throughout the client.
	 *
	 * Settings that are used by various components or multiple blocks should be added here. Note, that settings here are
	 * global so be sure not to add anything heavy if possible.
	 *
	 * @return array  An array containing core data.
	 */
	protected function get_core_data() {
		return [
			'adminUrl'           => admin_url(),
			'countries'          => WC()->countries->get_countries(),
			'currency'           => $this->get_currency_data(),
			'currentUserId'      => get_current_user_id(),
			'currentUserIsAdmin' => current_user_can( 'manage_woocommerce' ),
			'homeUrl'            => esc_url( home_url( '/' ) ),
			'locale'             => $this->get_locale_data(),
			'dashboardUrl'       => wc_get_account_endpoint_url( 'dashboard' ),
			'orderStatuses'      => $this->get_order_statuses(),
			'placeholderImgSrc'  => wc_placeholder_img_src(),
			'productsSettings'   => $this->get_products_settings(),
			'siteTitle'          => get_bloginfo( 'name' ),
			'storePages'         => $this->get_store_pages(),
			'wcAssetUrl'         => plugins_url( 'assets/', WC_PLUGIN_FILE ),
			'wcVersion'          => defined( 'WC_VERSION' ) ? WC_VERSION : '',
			'wpLoginUrl'         => wp_login_url(),
			'wpVersion'          => get_bloginfo( 'version' ),
		];
	}

	/**
	 * Get currency data to include in settings.
	 *
	 * @return array
	 */
	protected function get_currency_data() {
		$currency = get_woocommerce_currency();

		return [
			'code'              => $currency,
			'precision'         => wc_get_price_decimals(),
			'symbol'            => html_entity_decode( get_woocommerce_currency_symbol( $currency ) ),
			'symbolPosition'    => get_option( 'woocommerce_currency_pos' ),
			'decimalSeparator'  => wc_get_price_decimal_separator(),
			'thousandSeparator' => wc_get_price_thousand_separator(),
			'priceFormat'       => html_entity_decode( get_woocommerce_price_format() ),
		];
	}

	/**
	 * Get locale data to include in settings.
	 *
	 * @return array
	 */
	protected function get_locale_data() {
		global $wp_locale;

		return [
			'siteLocale'    => get_locale(),
			'userLocale'    => get_user_locale(),
			'weekdaysShort' => array_values( $wp_locale->weekday_abbrev ),
		];
	}

	/**
	 * Get store pages to include in settings.
	 *
	 * @return array
	 */
	protected function get_store_pages() {
		$store_pages = [
			'myaccount' => wc_get_page_id( 'myaccount' ),
			'shop'      => wc_get_page_id( 'shop' ),
			'cart'      => wc_get_page_id( 'cart' ),
			'checkout'  => wc_get_page_id( 'checkout' ),
			'privacy'   => wc_privacy_policy_page_id(),
			'terms'     => wc_terms_and_conditions_page_id(),
		];

		if ( is_callable( '_prime_post_caches' ) ) {
			_prime_post_caches( array_values( $store_pages ), false, false );
		}

		return array_map(
			[ $this, 'format_page_resource' ],
			$store_pages
		);
	}

	/**
	 * Get product related settings.
	 *
	 * Note: For the time being we are exposing only the settings that are used by blocks.
	 *
	 * @return array
	 */
	protected function get_products_settings() {
		return [
			'cartRedirectAfterAdd' => get_option( 'woocommerce_cart_redirect_after_add' ) === 'yes',
		];
	}

	/**
	 * Format a page object into a standard array of data.
	 *
	 * @param WP_Post|int $page Page object or ID.
	 * @return array
	 */
	protected function format_page_resource( $page ) {
		if ( is_numeric( $page ) && $page > 0 ) {
			$page = get_post( $page );
		}
		if ( ! is_a( $page, '\WP_Post' ) || 'publish' !== $page->post_status ) {
			return [
				'id'        => 0,
				'title'     => '',
				'permalink' => false,
			];
		}
		return [
			'id'        => $page->ID,
			'title'     => $page->post_title,
			'permalink' => get_permalink( $page->ID ),
		];
	}

	/**
	 * Returns block-related data for enqueued wc-settings script.
	 * Format order statuses by removing a leading 'wc-' if present.
	 *
	 * @return array formatted statuses.
	 */
	protected function get_order_statuses() {
		$formatted_statuses = array();
		foreach ( wc_get_order_statuses() as $key => $value ) {
			$formatted_key                        = preg_replace( '/^wc-/', '', $key );
			$formatted_statuses[ $formatted_key ] = $value;
		}
		return $formatted_statuses;
	}

	/**
	 * Used for on demand initialization of asset data and registering it with
	 * the internal data registry.
	 *
	 * Note: core data will overwrite any externally registered data via the api.
	 */
	protected function initialize_core_data() {
		/**
		 * Filters the array of shared settings.
		 *
		 * Low level hook for registration of new data late in the cycle. This is deprecated.
		 * Instead, use the data api:
		 *
		 * ```php
		 * Automattic\WooCommerce\Blocks\Package::container()->get( Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry::class )->add( $key, $value )
		 * ```
		 *
		 * @since 5.0.0
		 *
		 * @deprecated
		 * @param array $data Settings data.
		 * @return array
		 */
		$settings = apply_filters( 'woocommerce_shared_settings', $this->data );

		// Surface a deprecation warning in the error console.
		if ( has_filter( 'woocommerce_shared_settings' ) ) {
			$error_handle  = 'deprecated-shared-settings-error';
			$error_message = '`woocommerce_shared_settings` filter in Blocks is deprecated. See https://github.com/woocommerce/woocommerce-gutenberg-products-block/blob/trunk/docs/contributors/block-assets.md';
			// phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NotInFooter,WordPress.WP.EnqueuedResourceParameters.MissingVersion
			wp_register_script( $error_handle, '' );
			wp_enqueue_script( $error_handle );
			wp_add_inline_script(
				$error_handle,
				sprintf( 'console.warn( "%s" );', $error_message )
			);
		}

		// note this WILL wipe any data already registered to these keys because they are protected.
		$this->data = array_replace_recursive( $settings, $this->get_core_data() );
	}

	/**
	 * Loops through each registered lazy data callback and adds the returned
	 * value to the data array.
	 *
	 * This method is executed right before preparing the data for printing to
	 * the rendered screen.
	 *
	 * @return void
	 */
	protected function execute_lazy_data() {
		foreach ( $this->lazy_data as $key => $callback ) {
			$this->data[ $key ] = $callback();
		}
	}

	/**
	 * Exposes private registered data to child classes.
	 *
	 * @return array  The registered data on the private data property
	 */
	protected function get() {
		return $this->data;
	}

	/**
	 * Allows checking whether a key exists.
	 *
	 * @param string $key  The key to check if exists.
	 * @return bool  Whether the key exists in the current data registry.
	 */
	public function exists( $key ) {
		return array_key_exists( $key, $this->data );
	}

	/**
	 * Interface for adding data to the registry.
	 *
	 * You can only register data that is not already in the registry identified by the given key. If there is a
	 * duplicate found, unless $ignore_duplicates is true, an exception will be thrown.
	 *
	 * @param string  $key              The key used to reference the data being registered. This should use camelCase.
	 * @param mixed   $data             If not a function, registered to the registry as is. If a function, then the
	 *                                  callback is invoked right before output to the screen.
	 * @param boolean $check_key_exists If set to true, duplicate data will be ignored if the key exists.
	 *                                  If false, duplicate data will cause an exception.
	 *
	 * @throws InvalidArgumentException  Only throws when site is in debug mode. Always logs the error.
	 */
	public function add( $key, $data, $check_key_exists = false ) {
		if ( $check_key_exists && $this->exists( $key ) ) {
			return;
		}
		try {
			$this->add_data( $key, $data );
		} catch ( Exception $e ) {
			if ( $this->debug() ) {
				// bubble up.
				throw $e;
			}
			wc_caught_exception( $e, __METHOD__, [ $key, $data ] );
		}
	}

	/**
	 * Hydrate from the API.
	 *
	 * @param string $path REST API path to preload.
	 */
	public function hydrate_api_request( $path ) {
		if ( ! isset( $this->preloaded_api_requests[ $path ] ) ) {
			$this->preloaded_api_requests[ $path ] = Package::container()->get( Hydration::class )->get_rest_api_response_data( $path );
		}
	}

	/**
	 * Hydrate some data from the API.
	 *
	 * @param string  $key  The key used to reference the data being registered.
	 * @param string  $path REST API path to preload.
	 * @param boolean $check_key_exists If set to true, duplicate data will be ignored if the key exists.
	 *                                  If false, duplicate data will cause an exception.
	 *
	 * @throws InvalidArgumentException  Only throws when site is in debug mode. Always logs the error.
	 */
	public function hydrate_data_from_api_request( $key, $path, $check_key_exists = false ) {
		$this->add(
			$key,
			function() use ( $path ) {
				if ( isset( $this->preloaded_api_requests[ $path ], $this->preloaded_api_requests[ $path ]['body'] ) ) {
					return $this->preloaded_api_requests[ $path ]['body'];
				}
				$response = Package::container()->get( Hydration::class )->get_rest_api_response_data( $path );
				return $response['body'] ?? '';
			},
			$check_key_exists
		);
	}

	/**
	 * Adds a page permalink to the data registry.
	 *
	 * @param integer $page_id Page ID to add to the registry.
	 */
	public function register_page_id( $page_id ) {
		$permalink = $page_id ? get_permalink( $page_id ) : false;

		if ( $permalink ) {
			$this->data[ 'page-' . $page_id ] = $permalink;
		}
	}

	/**
	 * Callback for registering the data script via WordPress API.
	 *
	 * @return void
	 */
	public function register_data_script() {
		$this->api->register_script(
			$this->handle,
			'build/wc-settings.js',
			[ 'wp-api-fetch' ],
			true
		);
	}

	/**
	 * Callback for enqueuing asset data via the WP api.
	 *
	 * Note: while this is hooked into print/admin_print_scripts, it still only
	 * happens if the script attached to `wc-settings` handle is enqueued. This
	 * is done to allow for any potentially expensive data generation to only
	 * happen for routes that need it.
	 */
	public function enqueue_asset_data() {
		if ( wp_script_is( $this->handle, 'enqueued' ) ) {
			$this->initialize_core_data();
			$this->execute_lazy_data();

			$data                          = rawurlencode( wp_json_encode( $this->data ) );
			$wc_settings_script            = "var wcSettings = wcSettings || JSON.parse( decodeURIComponent( '" . esc_js( $data ) . "' ) );";
			$preloaded_api_requests_script = '';

			if ( count( $this->preloaded_api_requests ) > 0 ) {
				$preloaded_api_requests        = rawurlencode( wp_json_encode( $this->preloaded_api_requests ) );
				$preloaded_api_requests_script = "wp.apiFetch.use( wp.apiFetch.createPreloadingMiddleware( JSON.parse( decodeURIComponent( '" . esc_js( $preloaded_api_requests ) . "' ) ) ) );";
			}

			wp_add_inline_script(
				$this->handle,
				$wc_settings_script . $preloaded_api_requests_script,
				'before'
			);
		}
	}

	/**
	 * See self::add() for docs.
	 *
	 * @param   string $key   Key for the data.
	 * @param   mixed  $data  Value for the data.
	 *
	 * @throws InvalidArgumentException  If key is not a string or already
	 *                                   exists in internal data cache.
	 */
	protected function add_data( $key, $data ) {
		if ( ! is_string( $key ) ) {
			if ( $this->debug() ) {
				throw new InvalidArgumentException(
					'Key for the data being registered must be a string'
				);
			}
		}
		if ( isset( $this->data[ $key ] ) ) {
			if ( $this->debug() ) {
				throw new InvalidArgumentException(
					'Overriding existing data with an already registered key is not allowed'
				);
			}
			return;
		}
		if ( \is_callable( $data ) ) {
			$this->lazy_data[ $key ] = $data;
			return;
		}
		$this->data[ $key ] = $data;
	}

	/**
	 * Exposes whether the current site is in debug mode or not.
	 *
	 * @return boolean  True means the site is in debug mode.
	 */
	protected function debug() {
		return defined( 'WP_DEBUG' ) && WP_DEBUG;
	}
}