diff --git a/src/Assets.php b/src/Assets.php index e2c6e725442..47336929981 100644 --- a/src/Assets.php +++ b/src/Assets.php @@ -3,12 +3,11 @@ use Automattic\WooCommerce\Blocks\Package; use Automattic\WooCommerce\Blocks\Assets\Api as AssetApi; -use Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry as AssetDataRegistry; /** * Assets class. - * Initializes block assets. * + * @deprecated $VID:$ This class will be removed in a future release. This has been replaced by AssetsController. * @internal */ class Assets { @@ -17,121 +16,63 @@ class Assets { * Initialize class features on init. * * @since 2.5.0 - * Moved most initialization to BootStrap and AssetDataRegistry - * classes as a part of ongoing refactor + * @deprecated $VID:$ */ public static function init() { - add_action( 'init', array( __CLASS__, 'register_assets' ) ); - add_action( 'body_class', array( __CLASS__, 'add_theme_body_class' ), 1 ); - add_action( 'admin_body_class', array( __CLASS__, 'add_theme_admin_body_class' ), 1 ); - add_action( 'woocommerce_login_form_end', array( __CLASS__, 'redirect_to_field' ) ); - add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) ); - add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) ); + _deprecated_function( 'Assets::init', '$VID:$' ); } /** * Register block scripts & styles. * * @since 2.5.0 - * Moved data related enqueuing to new AssetDataRegistry class as part of ongoing refactoring. + * @deprecated $VID:$ */ public static function register_assets() { - $asset_api = Package::container()->get( AssetApi::class ); - - self::register_style( 'wc-block-editor', plugins_url( $asset_api->get_block_asset_build_path( 'editor', 'css' ), __DIR__ ), array( 'wp-edit-blocks' ) ); - self::register_style( 'wc-block-style', plugins_url( $asset_api->get_block_asset_build_path( 'style', 'css' ), __DIR__ ), array( 'wc-block-vendors-style' ) ); - - wp_style_add_data( 'wc-block-editor', 'rtl', 'replace' ); - wp_style_add_data( 'wc-block-style', 'rtl', 'replace' ); - - // Shared libraries and components across multiple blocks. - $asset_api->register_script( 'wc-blocks-middleware', 'build/wc-blocks-middleware.js', [], false ); - $asset_api->register_script( 'wc-blocks-data-store', 'build/wc-blocks-data.js', [ 'wc-blocks-middleware' ] ); - $asset_api->register_script( 'wc-blocks', $asset_api->get_block_asset_build_path( 'blocks' ), [], false ); - $asset_api->register_script( 'wc-vendors', $asset_api->get_block_asset_build_path( 'vendors' ), [], false ); - $asset_api->register_script( 'wc-blocks-registry', 'build/wc-blocks-registry.js', [], false ); - $asset_api->register_script( 'wc-shared-context', 'build/wc-shared-context.js', [] ); - $asset_api->register_script( 'wc-shared-hocs', 'build/wc-shared-hocs.js', [], false ); - $asset_api->register_script( 'wc-price-format', 'build/price-format.js', [], false ); - - if ( Package::feature()->is_feature_plugin_build() ) { - $asset_api->register_script( 'wc-blocks-checkout', 'build/blocks-checkout.js', [] ); - } - - wp_add_inline_script( - 'wc-blocks-middleware', - " - var wcBlocksMiddlewareConfig = { - storeApiNonce: '" . esc_js( wp_create_nonce( 'wc_store_api' ) ) . "', - wcStoreApiNonceTimestamp: '" . esc_js( time() ) . "' - }; - ", - 'before' - ); + _deprecated_function( 'Assets::register_assets', '$VID:$' ); } /** * Register the vendors style file. We need to do it after the other files * because we need to check if `wp-edit-post` has been enqueued. + * + * @deprecated $VID:$ */ public static function enqueue_scripts() { - $asset_api = Package::container()->get( AssetApi::class ); - - // @todo Remove fix to load our stylesheets after editor CSS. - // See #3068 and #3898 for the rationale of this fix. It should be no - // longer necessary when the editor is loaded in an iframe (https://github.com/WordPress/gutenberg/issues/20797). - if ( wp_style_is( 'wp-edit-post' ) ) { - $block_style_dependencies = array( 'wp-edit-post' ); - } else { - $block_style_dependencies = array(); - } - self::register_style( 'wc-block-vendors-style', plugins_url( $asset_api->get_block_asset_build_path( 'vendors-style', 'css' ), __DIR__ ), $block_style_dependencies ); + _deprecated_function( 'Assets::enqueue_scripts', '$VID:$' ); } /** * Add body classes. * + * @deprecated $VID:$ * @param array $classes Array of CSS classnames. * @return array Modified array of CSS classnames. */ public static function add_theme_body_class( $classes = [] ) { - $classes[] = 'theme-' . get_template(); + _deprecated_function( 'Assets::add_theme_body_class', '$VID:$' ); return $classes; } /** * Add theme class to admin body. * + * @deprecated $VID:$ * @param array $classes String with the CSS classnames. * @return array Modified string of CSS classnames. */ public static function add_theme_admin_body_class( $classes = '' ) { - $classes .= ' theme-' . get_template(); + _deprecated_function( 'Assets::add_theme_admin_body_class', '$VID:$' ); return $classes; } /** * Adds a redirect field to the login form so blocks can redirect users after login. - */ - public static function redirect_to_field() { - // phpcs:ignore WordPress.Security.NonceVerification - if ( empty( $_GET['redirect_to'] ) ) { - return; - } - echo ''; // phpcs:ignore WordPress.Security.NonceVerification - } - - /** - * Get the file modified time as a cache buster if we're in dev mode. * - * @param string $file Local path to the file. - * @return string The cache buster value to use for the given file. + * @deprecated $VID:$ */ - protected static function get_file_version( $file ) { - if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG && file_exists( \Automattic\WooCommerce\Blocks\Package::get_path() . $file ) ) { - return filemtime( \Automattic\WooCommerce\Blocks\Package::get_path() . $file ); - } - return \Automattic\WooCommerce\Blocks\Package::get_version(); + public static function redirect_to_field() { + _deprecated_function( 'Assets::redirect_to_field', '$VID:$' ); } /** @@ -151,21 +92,4 @@ public static function register_block_script( $script_name, $handle = '', $depen $asset_api = Package::container()->get( AssetApi::class ); $asset_api->register_block_script( $script_name, $handle, $dependencies ); } - - /** - * Registers a style according to `wp_register_style`. - * - * @since 2.0.0 - * - * @param string $handle Name of the stylesheet. Should be unique. - * @param string $src Full URL of the stylesheet, or path of the stylesheet relative to the WordPress root directory. - * @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)'. - */ - protected static function register_style( $handle, $src, $deps = [], $media = 'all' ) { - $filename = str_replace( plugins_url( '/', __DIR__ ), '', $src ); - $ver = self::get_file_version( $filename ); - wp_register_style( $handle, $src, $deps, $ver, $media ); - } } diff --git a/src/Assets/Api.php b/src/Assets/Api.php index 5e2ce83c807..d4a36f694f8 100644 --- a/src/Assets/Api.php +++ b/src/Assets/Api.php @@ -121,29 +121,6 @@ function() use ( $handle ) { } } - /** - * Queues a block script in the frontend. - * - * @since 2.5.0 - * @since 2.6.0 Changed $name to $script_name and added $handle argument. - * @since 2.9.0 Made it so scripts are not loaded in admin pages. - * @deprecated 4.5.0 Block types register the scripts themselves. - * - * @param string $script_name Name of the script used to identify the file inside build folder. - * @param string $handle Optional. Provided if the handle should be different than the script name. `wc-` prefix automatically added. - * @param array $dependencies Optional. An array of registered script handles this script depends on. Default empty array. - */ - public function register_block_script( $script_name, $handle = '', $dependencies = [] ) { - _deprecated_function( 'register_block_script', '4.5.0' ); - if ( is_admin() ) { - return; - } - $relative_src = $this->get_block_asset_build_path( $script_name ); - $handle = '' !== $handle ? 'wc-' . $handle : 'wc-' . $script_name; - $this->register_script( $handle, $relative_src, $dependencies ); - wp_enqueue_script( $handle ); - } - /** * Registers a style according to `wp_register_style`. * diff --git a/src/AssetsController.php b/src/AssetsController.php new file mode 100644 index 00000000000..481f0da1e5d --- /dev/null +++ b/src/AssetsController.php @@ -0,0 +1,135 @@ +api = $asset_api; + $this->init(); + } + + /** + * Initialize class features. + */ + protected function init() { + add_action( 'init', array( $this, 'register_assets' ) ); + add_action( 'body_class', array( $this, 'add_theme_body_class' ), 1 ); + add_action( 'admin_body_class', array( $this, 'add_theme_body_class' ), 1 ); + add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); + } + + /** + * Register block scripts & styles. + */ + public function register_assets() { + $this->register_style( 'wc-block-editor', plugins_url( $this->api->get_block_asset_build_path( 'editor', 'css' ), __DIR__ ), array( 'wp-edit-blocks' ) ); + $this->register_style( 'wc-block-style', plugins_url( $this->api->get_block_asset_build_path( 'style', 'css' ), __DIR__ ), array( 'wc-block-vendors-style' ) ); + + wp_style_add_data( 'wc-block-editor', 'rtl', 'replace' ); + wp_style_add_data( 'wc-block-style', 'rtl', 'replace' ); + + $this->api->register_script( 'wc-blocks-middleware', 'build/wc-blocks-middleware.js', [], false ); + $this->api->register_script( 'wc-blocks-data-store', 'build/wc-blocks-data.js', [ 'wc-blocks-middleware' ] ); + $this->api->register_script( 'wc-blocks', $this->api->get_block_asset_build_path( 'blocks' ), [], false ); + $this->api->register_script( 'wc-vendors', $this->api->get_block_asset_build_path( 'vendors' ), [], false ); + $this->api->register_script( 'wc-blocks-registry', 'build/wc-blocks-registry.js', [], false ); + $this->api->register_script( 'wc-shared-context', 'build/wc-shared-context.js', [] ); + $this->api->register_script( 'wc-shared-hocs', 'build/wc-shared-hocs.js', [], false ); + $this->api->register_script( 'wc-price-format', 'build/price-format.js', [], false ); + + if ( Package::feature()->is_feature_plugin_build() ) { + $this->api->register_script( 'wc-blocks-checkout', 'build/blocks-checkout.js', [] ); + } + + wp_add_inline_script( + 'wc-blocks-middleware', + " + var wcBlocksMiddlewareConfig = { + storeApiNonce: '" . esc_js( wp_create_nonce( 'wc_store_api' ) ) . "', + wcStoreApiNonceTimestamp: '" . esc_js( time() ) . "' + }; + ", + 'before' + ); + } + + /** + * Register the vendors style file. We need to do it after the other files + * because we need to check if `wp-edit-post` has been enqueued. + */ + public function enqueue_scripts() { + // @todo Remove fix to load our stylesheets after editor CSS. + // See #3068 and #3898 for the rationale of this fix. It should be no + // longer necessary when the editor is loaded in an iframe (https://github.com/WordPress/gutenberg/issues/20797). + $this->register_style( 'wc-block-vendors-style', plugins_url( $this->api->get_block_asset_build_path( 'vendors-style', 'css' ), __DIR__ ), wp_style_is( 'wp-edit-post' ) ? [ 'wp-edit-post' ] : [] ); + } + + /** + * Add body classes to the frontend and within admin. + * + * @param string|array $classes Array or string of CSS classnames. + * @return string|array Modified classnames. + */ + public function add_theme_body_class( $classes ) { + $class = 'theme-' . get_template(); + + if ( is_array( $classes ) ) { + $classes[] = $class; + } else { + $classes .= ' ' . $class . ' '; + } + + return $classes; + } + + /** + * Get the file modified time as a cache buster if we're in dev mode. + * + * @param string $file Local path to the file. + * @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( \Automattic\WooCommerce\Blocks\Package::get_path() . $file ) ) { + return filemtime( \Automattic\WooCommerce\Blocks\Package::get_path() . $file ); + } + return \Automattic\WooCommerce\Blocks\Package::get_version(); + } + + /** + * Registers a style according to `wp_register_style`. + * + * @param string $handle Name of the stylesheet. Should be unique. + * @param string $src Full URL of the stylesheet, or path of the stylesheet relative to the WordPress root directory. + * @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)'. + */ + protected function register_style( $handle, $src, $deps = [], $media = 'all' ) { + $filename = str_replace( plugins_url( '/', __DIR__ ), '', $src ); + $ver = self::get_file_version( $filename ); + wp_register_style( $handle, $src, $deps, $ver, $media ); + } +} diff --git a/src/BlockTypesController.php b/src/BlockTypesController.php new file mode 100644 index 00000000000..1dbec4d92ef --- /dev/null +++ b/src/BlockTypesController.php @@ -0,0 +1,157 @@ +asset_api = $asset_api; + $this->asset_data_registry = $asset_data_registry; + $this->init(); + } + + /** + * Initialize class features. + */ + protected function init() { + add_action( 'init', array( $this, 'register_blocks' ) ); + add_action( 'woocommerce_login_form_end', array( $this, 'redirect_to_field' ) ); + } + + /** + * Register blocks, hooking up assets and render functions as needed. + */ + public function register_blocks() { + $block_types = $this->get_block_types(); + + foreach ( $block_types as $block_type ) { + $block_type_class = __NAMESPACE__ . '\\BlockTypes\\' . $block_type; + $block_type_instance = new $block_type_class( $this->asset_api, $this->asset_data_registry, new IntegrationRegistry() ); + } + + foreach ( self::get_atomic_blocks() as $block_type ) { + $block_type_instance = new AtomicBlock( $this->asset_api, $this->asset_data_registry, new IntegrationRegistry(), $block_type ); + } + } + + /** + * Adds a redirect field to the login form so blocks can redirect users after login. + */ + public function redirect_to_field() { + // phpcs:ignore WordPress.Security.NonceVerification + if ( empty( $_GET['redirect_to'] ) ) { + return; + } + echo ''; // phpcs:ignore WordPress.Security.NonceVerification + } + + /** + * Get list of block types. + * + * @return array + */ + protected function get_block_types() { + global $wp_version, $pagenow; + + $block_types = [ + 'AllReviews', + 'FeaturedCategory', + 'FeaturedProduct', + 'HandpickedProducts', + 'ProductBestSellers', + 'ProductCategories', + 'ProductCategory', + 'ProductNew', + 'ProductOnSale', + 'ProductsByAttribute', + 'ProductTopRated', + 'ReviewsByProduct', + 'ReviewsByCategory', + 'ProductSearch', + 'ProductTag', + 'AllProducts', + 'PriceFilter', + 'AttributeFilter', + 'ActiveFilters', + ]; + + if ( Package::feature()->is_feature_plugin_build() ) { + $block_types[] = 'Checkout'; + $block_types[] = 'Cart'; + } + + if ( Package::feature()->is_experimental_build() ) { + $block_types[] = 'SingleProduct'; + } + + /** + * This disables specific blocks in Widget Areas by not registering them. + */ + if ( 'themes.php' === $pagenow ) { + $block_types = array_diff( + $block_types, + [ + 'AllProducts', + 'PriceFilter', + 'AttributeFilter', + 'ActiveFilters', + ] + ); + } + + return $block_types; + } + + /** + * Get atomic blocks types. + * + * @return array + */ + protected function get_atomic_blocks() { + return [ + 'product-title', + 'product-button', + 'product-image', + 'product-price', + 'product-rating', + 'product-sale-badge', + 'product-summary', + 'product-sku', + 'product-category-list', + 'product-tag-list', + 'product-stock-indicator', + 'product-add-to-cart', + ]; + } +} diff --git a/src/Domain/Bootstrap.php b/src/Domain/Bootstrap.php index e34576a864f..22637eace4b 100644 --- a/src/Domain/Bootstrap.php +++ b/src/Domain/Bootstrap.php @@ -1,10 +1,10 @@ add_build_notice(); $this->container->get( AssetDataRegistry::class ); $this->container->get( Installer::class ); - BlockAssets::init(); + $this->container->get( AssetsController::class ); } $this->container->get( DraftOrders::class )->init(); $this->container->get( CreateAccount::class )->init(); @@ -89,7 +89,7 @@ protected function init() { $this->container->get( PaymentsApi::class ); $this->container->get( RestApi::class ); $this->container->get( GoogleAnalytics::class ); - Library::init(); + $this->container->get( BlockTypesController::class ); } /** @@ -157,6 +157,12 @@ 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( Container $container ) { @@ -183,6 +189,14 @@ function ( Container $container ) { 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( DraftOrders::class, function( Container $container ) { diff --git a/src/Library.php b/src/Library.php index f7ef5eea3ff..ad5871db57b 100644 --- a/src/Library.php +++ b/src/Library.php @@ -9,122 +9,36 @@ /** * Library class. - * Initializes blocks in WordPress. * + * @deprecated $VID:$ This class will be removed in a future release. This has been replaced by BlockTypesController. * @internal */ class Library { /** * Initialize block library features. + * + * @deprecated $VID:$ */ public static function init() { - add_action( 'init', array( __CLASS__, 'register_blocks' ) ); - add_action( 'init', array( __CLASS__, 'define_tables' ) ); + _deprecated_function( 'Library::init', '$VID:$' ); } /** * Register custom tables within $wpdb object. + * + * @deprecated $VID:$ */ public static function define_tables() { - global $wpdb; - - // List of tables without prefixes. - $tables = array( - 'wc_reserved_stock' => 'wc_reserved_stock', - ); - - foreach ( $tables as $name => $table ) { - $wpdb->$name = $wpdb->prefix . $table; - $wpdb->tables[] = $table; - } + _deprecated_function( 'Library::define_tables', '$VID:$' ); } /** * Register blocks, hooking up assets and render functions as needed. - */ - public static function register_blocks() { - global $wp_version, $pagenow; - - $blocks = [ - 'AllReviews', - 'FeaturedCategory', - 'FeaturedProduct', - 'HandpickedProducts', - 'ProductBestSellers', - 'ProductCategories', - 'ProductCategory', - 'ProductNew', - 'ProductOnSale', - 'ProductsByAttribute', - 'ProductTopRated', - 'ReviewsByProduct', - 'ReviewsByCategory', - 'ProductSearch', - 'ProductTag', - 'AllProducts', - 'PriceFilter', - 'AttributeFilter', - 'ActiveFilters', - ]; - - if ( Package::feature()->is_feature_plugin_build() ) { - $blocks[] = 'Checkout'; - $blocks[] = 'Cart'; - } - - if ( Package::feature()->is_experimental_build() ) { - $blocks[] = 'SingleProduct'; - } - - /** - * This disables specific blocks in Widget Areas by not registering them. - */ - if ( 'themes.php' === $pagenow ) { - $blocks = array_diff( - $blocks, - [ - 'AllProducts', - 'PriceFilter', - 'AttributeFilter', - 'ActiveFilters', - ] - ); - } - - // Provide block types access to assets, data registry, and integration registry. - $asset_api = Package::container()->get( AssetApi::class ); - $data_registry = Package::container()->get( AssetDataRegistry::class ); - - foreach ( $blocks as $block_type ) { - $block_type_class = __NAMESPACE__ . '\\BlockTypes\\' . $block_type; - $block_type_instance = new $block_type_class( $asset_api, $data_registry, new IntegrationRegistry() ); - } - - foreach ( self::get_atomic_blocks() as $block_type ) { - $block_type_instance = new AtomicBlock( $asset_api, $data_registry, new IntegrationRegistry(), $block_type ); - } - } - - /** - * Get atomic blocks types. * - * @return array + * @deprecated $VID:$ */ - protected static function get_atomic_blocks() { - return [ - 'product-title', - 'product-button', - 'product-image', - 'product-price', - 'product-rating', - 'product-sale-badge', - 'product-summary', - 'product-sku', - 'product-category-list', - 'product-tag-list', - 'product-stock-indicator', - 'product-add-to-cart', - ]; + public static function register_blocks() { + _deprecated_function( 'Library::register_blocks', '$VID:$' ); } }