PluginProbe ʕ •ᴥ•ʔ
WooCommerce / 10.2.1
WooCommerce v10.2.1
10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 7.8.0-beta.1 7.8.0-beta.2 7.8.0-rc.1 7.8.0-rc.2 7.8.1 7.8.2 7.8.3 7.8.4 7.9.0 7.9.0-beta.1 7.9.0-beta.2 7.9.0-rc.2 7.9.0-rc.3 7.9.1 7.9.2 8.0.0 8.0.0-beta.1 8.0.0-beta.2 8.0.0-rc.1 8.0.0-rc.2 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.1.0 8.1.0-beta.1 8.1.0-rc.1 8.1.0-rc.2 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 8.2.0-beta.1 8.2.0-rc.1 8.2.0-rc.2 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.3.0 8.3.0-beta.1 8.3.0-rc.1 8.3.0-rc.2 8.3.1 8.3.2 8.3.3 8.3.4 8.4.0 8.4.0-beta.1 8.4.0-rc.1 8.4.1 8.4.2 8.4.3 8.5.0 8.5.0-beta.1 8.5.0-rc.1 8.5.1 8.5.2 8.5.3 8.5.4 8.5.5 8.6.0 8.6.0-beta.1 8.6.0-rc.1 8.6.1 8.6.2 8.6.3 8.6.4 8.7.0 8.7.0-beta.1 8.7.0-beta.2 8.7.0-rc.1 8.7.1 8.7.2 8.7.3 8.8.0 8.8.0-beta.1 8.8.0-rc.1 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.8.6 8.8.7 8.9.0 8.9.0-beta.1 8.9.0-rc.1 8.9.1 8.9.2 8.9.3 8.9.4 8.9.5 9.0.0 9.0.0-beta.1 9.0.0-beta.2 9.0.0-rc.1 9.0.1 9.0.2 9.0.3 9.0.4 9.1.0 9.1.0-beta.1 9.1.0-rc.1 9.1.1 9.1.2 9.1.3 9.1.4 9.1.5 9.1.6 9.2.0 9.2.0-beta.1 9.2.0-rc.1 9.2.1 9.2.2 9.2.3 9.2.4 9.2.5 9.3.0 9.3.0-beta.1 9.3.0-rc.1 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.3.6 9.4.0 9.4.0-beta.1 9.4.0-beta.2 9.4.0-rc.1 9.4.0-rc.2 9.4.0-rc.3 9.4.0-rc.4 9.4.1 9.4.2 9.4.3 9.4.4 9.4.5 9.5.0 9.5.0-beta.1 9.5.0-beta.2 9.5.0-rc.1 9.5.1 9.5.2 9.5.3 9.5.4 9.6.0 9.6.0-beta.1 9.6.0-beta.2 9.6.0-rc.1 9.6.1 9.6.2 9.6.3 9.6.4 9.7.0 9.7.0-beta.1 9.7.0-rc.1 9.7.1 9.7.2 9.7.3 9.8.0 9.8.0-beta.1 9.8.0-rc.1 9.8.1 9.8.2 9.8.3 9.8.4 9.8.5 9.8.6 9.8.7 9.9.0 9.9.0-beta.1 9.9.0-rc.1 9.9.1 9.9.2 9.9.3 9.9.4 9.9.5 9.9.6 9.9.7 3.7.3 7.1.2 3.8.0 7.2.0 3.8.0-beta.1 7.2.0-beta.1 3.8.0-rc.1 7.2.0-beta.2 3.8.0-rc.2 7.2.0-rc.1 3.8.1 7.2.0-rc.2 3.8.2 7.2.1 3.8.3 7.2.2 3.9.0 7.2.3 3.9.0-beta.1 7.2.4 3.9.0-beta.2 7.3.0 3.9.0-rc.1 7.3.0-beta.1 3.9.0-rc.2 7.3.0-beta.2 3.9.0-rc.3 7.3.0-rc.1 3.9.0-rc.4 7.3.0-rc.2 3.9.1 7.3.1 3.9.2 7.4.0 3.9.3 7.4.0-beta.1 3.9.4 7.4.0-beta.2 3.9.5 7.4.0-rc.1 4.0.0 7.4.0-rc.2 4.0.0-beta.1 7.4.1 4.0.0-rc.1 7.4.2 4.0.0-rc.2 7.5.0 4.0.1 7.5.0-beta.1 4.0.2 7.5.0-beta.2 4.0.3 7.5.0-rc.1 4.0.4 7.5.1 4.1.0 7.5.2 4.1.0-beta.1 7.6.0 4.1.0-beta.2 7.6.0-beta.1 4.1.0-rc.1 7.6.0-beta.2 4.1.0-rc.2 7.6.0-rc.1 4.1.1 7.6.0-rc.2 4.1.2 7.6.0-rc.3 4.1.3 7.6.1 4.1.4 7.6.2 4.2.0 7.7.0 4.2.0-RC.1 7.7.0-beta.1 4.2.0-RC.2 7.7.0-beta.2 4.2.0-beta.1 7.7.0-rc.1 4.2.1 7.7.1 4.2.2 7.7.2 4.2.3 7.7.3 4.2.4 7.8.0 4.2.5 4.3.0 4.3.0-beta.1 4.3.0-rc.1 4.3.0-rc.2 4.3.0-rc.3 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.4.0 4.4.0-beta.1 4.4.0-rc.1 4.4.1 4.4.2 4.4.3 4.4.4 4.5.0 4.5.0-beta.1 4.5.0-rc.1 4.5.0-rc.3 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.6.0-beta.1 4.6.0-rc.1 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.7.0 4.7.0-beta.1 4.7.0-beta.2 4.7.0-rc.1 4.7.1 4.7.1-beta.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.0-beta.1 4.8.0-rc.1 4.8.0-rc.2 4.8.1 4.8.2 4.8.3 4.9.0 4.9.0-beta.1 4.9.0-rc.1 4.9.0-rc.2 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 5.0.0 5.0.0-beta.1 5.0.0-beta.2 5.0.0-rc.1 5.0.0-rc.2 5.0.0-rc.3 5.0.1 5.0.2 5.0.3 5.1.0 5.1.0-beta.1 5.1.0-rc.1 trunk 5.1.1 10.0.0 5.1.2 10.0.0-rc.1 5.1.3 10.0.0-rc.2 5.2.0 10.0.1 5.2.0-beta.1 10.0.2 5.2.0-rc.1 10.0.3 5.2.0-rc.2 10.0.4 5.2.1 10.0.5 5.2.2 10.0.6 5.2.3 10.1.0 5.2.4 10.1.0-rc.1 5.2.5 10.1.0-rc.2 5.3.0 10.1.0-rc.3 5.3.0-beta.1 10.1.0-rc.4 5.3.0-rc.1 10.1.1 5.3.0-rc.2 10.1.2 5.3.1 10.1.3 5.3.2 10.1.4 5.3.3 10.2.0 5.4.0 10.2.0-beta.1 5.4.0-beta.1 10.2.0-beta.2 5.4.0-rc.1 10.2.0-rc.1 5.4.1 10.2.1 5.4.2 10.2.2 5.4.3 10.2.3 5.4.4 10.2.4 5.4.5 10.3.0 5.5.0 10.3.0-beta.1 5.5.0-beta.1 10.3.0-beta.2 5.5.0-rc.1 10.3.0-rc.1 5.5.0-rc.2 10.3.0-rc.2 5.5.1 10.3.1 5.5.2 10.3.2 5.5.3 10.3.3 5.5.4 10.3.4 5.5.5 10.3.5 5.6.0 10.3.6 5.6.0-beta.1 10.3.7 5.6.0-rc.1 10.3.8 5.6.0-rc.2 10.4.0 5.6.1 10.4.0-beta.1 5.6.2 10.4.0-beta.2 5.6.3 10.4.0-rc.1 5.7.0 10.4.1 5.7.0-beta.1 10.4.2 5.7.0-rc.1 10.4.3 5.7.1 10.4.4 5.7.2 10.5.0 5.7.3 10.5.0-beta.1 5.8.0 10.5.0-beta.2 5.8.0-beta.1 10.5.0-rc.1 5.8.0-beta.2 10.5.0-rc.2 5.8.0-rc.1 10.5.0-rc.3 5.8.1 10.5.1 5.8.2 10.5.2 5.9.0 10.5.3 5.9.0-beta.1 10.6.0 5.9.0-rc.1 10.6.0-beta.1 5.9.0-rc.2 10.6.0-beta.2 5.9.1 10.6.0-rc.1 5.9.2 10.6.1 6.0.0 10.6.2 6.0.0-beta.1 10.7.0 6.0.0-rc.1 10.7.0-beta.1 6.0.1 10.7.0-beta.2 6.0.2 10.7.0-rc.1 6.1.0 3.0.0 6.1.0-beta.1 3.0.1 6.1.0-rc.1 3.0.2 6.1.0-rc.2 3.0.3 6.1.1 3.0.4 6.1.2 3.0.5 6.1.3 3.0.6 6.2.0 3.0.7 6.2.0-beta.1 3.0.8 6.2.0-rc.1 3.0.9 6.2.0-rc.2 3.1.0 6.2.1 3.1.1 6.2.2 3.1.2 6.2.3 3.2.0 6.3.0 3.2.1 6.3.0-beta.1 3.2.2 6.3.0-rc.1 3.2.3 6.3.0-rc.2 3.2.4 6.3.1 3.2.5 6.3.2 3.2.6 6.4.0 3.3.0 6.4.0-beta.1 3.3.1 6.4.0-rc.1 3.3.2 6.4.1 3.3.2-rc.1 6.4.2 3.3.3 6.5.0 3.3.4 6.5.0-beta.1 3.3.5 6.5.0-rc.1 3.3.6 6.5.0-rc.2 3.4.0 6.5.1 3.4.0-beta.1 6.5.2 3.4.0-rc.2 6.6.0 3.4.1 6.6.0-beta.1 3.4.2 6.6.0-rc.1 3.4.3 6.6.0-rc.2 3.4.4 6.6.1 3.4.5 6.6.2 3.4.6 6.7.0 3.4.7 6.7.0-beta.1 3.4.8 6.7.0-beta.2 3.5.0 6.7.0-rc.1 3.5.0-beta.1 6.7.1 3.5.0-rc.1 6.8.0 3.5.0-rc.2 6.8.0-beta.1 3.5.1 6.8.0-beta.2 3.5.10 6.8.0-rc.1 3.5.2 6.8.1 3.5.3 6.8.2 3.5.4 6.8.3 3.5.5 6.9.0 3.5.6 6.9.0-beta.1 3.5.7 6.9.0-beta.2 3.5.8 6.9.0-rc.1 3.5.9 6.9.1 3.6.0 6.9.2 3.6.0-beta.1 6.9.3 3.6.0-rc.1 6.9.4 3.6.0-rc.2 6.9.5 3.6.0-rc.3 7.0.0 3.6.1 7.0.0-beta.1 3.6.2 7.0.0-beta.2 3.6.3 7.0.0-beta.3 3.6.4 7.0.0-rc.1 3.6.5 7.0.0-rc.2 3.6.6 7.0.1 3.6.7 7.0.2 3.7.0 7.1.0 3.7.0-beta.1 7.1.0-beta.1 3.7.0-rc.1 7.1.0-beta.2 3.7.0-rc.2 7.1.0-rc.1 3.7.1 7.1.0-rc.2 3.7.2 7.1.1
woocommerce / src / Blocks / AssetsController.php
woocommerce / src / Blocks Last commit date
AI 1 year ago AIContent 1 year ago Assets 1 year ago BlockTypes 8 months ago Domain 10 months ago Images 1 year ago Integrations 2 years ago Patterns 11 months ago Payments 1 year ago Registry 2 years ago Shipping 11 months ago Templates 9 months ago Utils 9 months ago Assets.php 2 years ago AssetsController.php 10 months ago BlockPatterns.php 11 months ago BlockTemplatesController.php 8 months ago BlockTemplatesRegistry.php 9 months ago BlockTypesController.php 9 months ago InboxNotifications.php 2 years ago Installer.php 1 year ago Library.php 2 years ago Options.php 2 years ago Package.php 1 year ago QueryFilters.php 9 months ago TemplateOptions.php 1 year ago
AssetsController.php
505 lines
1 <?php
2 declare( strict_types = 1 );
3
4 namespace Automattic\WooCommerce\Blocks;
5
6 use Automattic\WooCommerce\Blocks\Assets\Api as AssetApi;
7 use Automattic\WooCommerce\Admin\Features\Features;
8
9 /**
10 * AssetsController class.
11 *
12 * @since 5.0.0
13 * @internal
14 */
15 final class AssetsController {
16
17 /**
18 * Asset API interface for various asset registration.
19 *
20 * @var AssetApi
21 */
22 private $api;
23
24 /**
25 * Constructor.
26 *
27 * @param AssetApi $asset_api Asset API interface for various asset registration.
28 */
29 public function __construct( AssetApi $asset_api ) {
30 $this->api = $asset_api;
31 $this->init();
32 }
33
34 /**
35 * Initialize class features.
36 */
37 protected function init() { // phpcs:ignore WooCommerce.Functions.InternalInjectionMethod.MissingPublic
38 add_action( 'init', array( $this, 'register_assets' ) );
39 add_action( 'init', array( $this, 'register_script_modules' ) );
40 add_action( 'enqueue_block_editor_assets', array( $this, 'register_and_enqueue_site_editor_assets' ) );
41 add_filter( 'wp_resource_hints', array( $this, 'add_resource_hints' ), 10, 2 );
42 add_action( 'body_class', array( $this, 'add_theme_body_class' ), 1 );
43 add_action( 'admin_body_class', array( $this, 'add_theme_body_class' ), 1 );
44 add_action( 'admin_enqueue_scripts', array( $this, 'update_block_style_dependencies' ), 20 );
45 add_action( 'wp_enqueue_scripts', array( $this, 'update_block_settings_dependencies' ), 100 );
46 add_action( 'admin_enqueue_scripts', array( $this, 'update_block_settings_dependencies' ), 100 );
47 add_filter( 'js_do_concat', array( $this, 'skip_boost_minification_for_cart_checkout' ), 10, 2 );
48
49 if ( Features::is_enabled( 'experimental-iapi-runtime' ) ) {
50 // Run after the WordPress iAPI runtime has been registered by setting a lower priority.
51 add_filter( 'wp_default_scripts', array( $this, 'reregister_core_iapi_runtime' ), 20 );
52 }
53 }
54
55 /**
56 * Re-registers the iAPI runtime registered by WordPress Core/Gutenberg, allowing WooCommerce to register its own version of the iAPI runtime.
57 */
58 public function reregister_core_iapi_runtime() {
59 $interactivity_api_asset_data = $this->api->get_asset_data(
60 $this->api->get_block_asset_build_path( 'interactivity-api-assets', 'php' )
61 );
62
63 foreach ( $interactivity_api_asset_data as $handle => $data ) {
64 $handle_without_js = str_replace( '.js', '', $handle );
65 if ( '@wordpress/interactivity' === $handle_without_js || '@wordpress/interactivity-router' === $handle_without_js ) {
66 wp_deregister_script_module( $handle_without_js );
67 }
68
69 wp_register_script_module( $handle_without_js, plugins_url( $this->api->get_block_asset_build_path( $handle_without_js ), dirname( __DIR__ ) ), $data['dependencies'], $data['version'] );
70 }
71 }
72
73 /**
74 * Register script modules.
75 */
76 public function register_script_modules() {
77 // Right now we only have one script modules build for supported interactivity API powered block front-ends.
78 // We generate a combined asset file for that via DependencyExtractionWebpackPlugin to make registration more
79 // efficient.
80 $asset_data = $this->api->get_asset_data(
81 $this->api->get_block_asset_build_path( 'interactivity-blocks-frontend-assets', 'php' )
82 );
83
84 foreach ( $asset_data as $handle => $data ) {
85 $handle_without_js = str_replace( '.js', '', $handle );
86 wp_register_script_module( $handle_without_js, plugins_url( $this->api->get_block_asset_build_path( $handle_without_js ), dirname( __DIR__ ) ), $data['dependencies'], $data['version'] );
87 }
88 }
89
90 /**
91 * Register block scripts & styles.
92 */
93 public function register_assets() {
94 $this->register_style( 'wc-blocks-packages-style', plugins_url( $this->api->get_block_asset_build_path( 'packages-style', 'css' ), dirname( __DIR__ ) ), array(), 'all', true );
95 $this->register_style( 'wc-blocks-style', plugins_url( $this->api->get_block_asset_build_path( 'wc-blocks', 'css' ), dirname( __DIR__ ) ), array(), 'all', true );
96 $this->register_style( 'wc-blocks-editor-style', plugins_url( $this->api->get_block_asset_build_path( 'wc-blocks-editor-style', 'css' ), dirname( __DIR__ ) ), array( 'wp-edit-blocks' ), 'all', true );
97
98 $this->api->register_script( 'wc-types', $this->api->get_block_asset_build_path( 'wc-types' ), array(), false );
99 $this->api->register_script( 'wc-blocks-middleware', 'assets/client/blocks/wc-blocks-middleware.js', array(), false );
100 $this->api->register_script( 'wc-blocks-data-store', 'assets/client/blocks/wc-blocks-data.js', array( 'wc-blocks-middleware' ) );
101 $this->api->register_script( 'wc-blocks-vendors', $this->api->get_block_asset_build_path( 'wc-blocks-vendors' ), array(), false );
102 $this->api->register_script( 'wc-blocks-registry', 'assets/client/blocks/wc-blocks-registry.js', array(), false );
103 $this->api->register_script( 'wc-blocks', $this->api->get_block_asset_build_path( 'wc-blocks' ), array( 'wc-blocks-vendors' ), false );
104 $this->api->register_script( 'wc-blocks-shared-context', 'assets/client/blocks/wc-blocks-shared-context.js' );
105 $this->api->register_script( 'wc-blocks-shared-hocs', 'assets/client/blocks/wc-blocks-shared-hocs.js', array(), false );
106
107 // The price package is shared externally so has no blocks prefix.
108 $this->api->register_script( 'wc-price-format', 'assets/client/blocks/price-format.js', array(), false );
109
110 // Vendor scripts for blocks frontends (not including cart and checkout).
111 $this->api->register_script( 'wc-blocks-frontend-vendors', $this->api->get_block_asset_build_path( 'wc-blocks-frontend-vendors-frontend' ), array(), true );
112
113 // Cart and checkout frontend scripts.
114 $this->api->register_script( 'wc-cart-checkout-vendors', $this->api->get_block_asset_build_path( 'wc-cart-checkout-vendors-frontend' ), array(), true );
115 $this->api->register_script( 'wc-cart-checkout-base', $this->api->get_block_asset_build_path( 'wc-cart-checkout-base-frontend' ), array(), true );
116 $this->api->register_script( 'wc-blocks-checkout', 'assets/client/blocks/blocks-checkout.js' );
117 $this->api->register_script( 'wc-blocks-checkout-events', 'assets/client/blocks/blocks-checkout-events.js' );
118 $this->api->register_script( 'wc-blocks-components', 'assets/client/blocks/blocks-components.js' );
119 $this->api->register_script( 'wc-schema-parser', 'assets/client/blocks/wc-schema-parser.js', array(), false );
120
121 // Customer Effort Score.
122 $this->api->register_script(
123 'wc-customer-effort-score',
124 'assets/client/admin/customer-effort-score/index.js',
125 array( 'wp-data', 'wp-data-controls', 'wc-store-data' )
126 );
127 $this->api->register_style(
128 'wc-customer-effort-score',
129 'assets/client/admin/customer-effort-score/style.css',
130 );
131
132 wp_add_inline_script(
133 'wc-blocks-middleware',
134 "
135 var wcBlocksMiddlewareConfig = {
136 storeApiNonce: '" . esc_js( wp_create_nonce( 'wc_store_api' ) ) . "',
137 wcStoreApiNonceTimestamp: '" . esc_js( time() ) . "'
138 };
139 ",
140 'before'
141 );
142 }
143
144 /**
145 * Register and enqueue assets for exclusive usage within the Site Editor.
146 */
147 public function register_and_enqueue_site_editor_assets() {
148 $this->api->register_script( 'wc-blocks-classic-template-revert-button', 'assets/client/blocks/wc-blocks-classic-template-revert-button.js' );
149 $this->api->register_style( 'wc-blocks-classic-template-revert-button-style', 'assets/client/blocks/wc-blocks-classic-template-revert-button-style.css' );
150
151 $current_screen = get_current_screen();
152 if ( $current_screen instanceof \WP_Screen && 'site-editor' === $current_screen->base ) {
153 wp_enqueue_script( 'wc-blocks-classic-template-revert-button' );
154 wp_enqueue_style( 'wc-blocks-classic-template-revert-button-style' );
155 }
156
157 // Customer Effort Score.
158 wp_enqueue_script( 'wc-customer-effort-score' );
159 wp_enqueue_style( 'wc-customer-effort-score' );
160 }
161
162 /**
163 * Defines resource hints to help speed up the loading of some critical blocks.
164 *
165 * These will not impact page loading times negatively because they are loaded once the current page is idle.
166 *
167 * @param array $urls URLs to print for resource hints. Each URL is an array of resource attributes, or a URL string.
168 * @param string $relation_type The relation type the URLs are printed. Possible values: preconnect, dns-prefetch, prefetch, prerender.
169 * @return array URLs to print for resource hints.
170 */
171 public function add_resource_hints( $urls, $relation_type ) {
172 if ( ! in_array( $relation_type, array( 'prefetch', 'prerender' ), true ) || is_admin() ) {
173 return $urls;
174 }
175
176 // We only need to prefetch when the cart has contents.
177 $cart = wc()->cart;
178
179 if ( ! $cart instanceof \WC_Cart || 0 === $cart->get_cart_contents_count() ) {
180 return $urls;
181 }
182
183 if ( 'prefetch' === $relation_type ) {
184 $urls = array_merge(
185 $urls,
186 $this->get_prefetch_resource_hints()
187 );
188 }
189
190 if ( 'prerender' === $relation_type ) {
191 $urls = array_merge(
192 $urls,
193 $this->get_prerender_resource_hints()
194 );
195 }
196
197 return $urls;
198 }
199
200 /**
201 * Get resource hints during prefetch requests.
202 *
203 * @return array Array of URLs.
204 */
205 private function get_prefetch_resource_hints() {
206 $urls = array();
207
208 // Core page IDs.
209 $cart_page_id = wc_get_page_id( 'cart' );
210 $checkout_page_id = wc_get_page_id( 'checkout' );
211
212 // Checks a specific page (by ID) to see if it contains the named block.
213 $has_block_cart = $cart_page_id && has_block( 'woocommerce/cart', $cart_page_id );
214 $has_block_checkout = $checkout_page_id && has_block( 'woocommerce/checkout', $checkout_page_id );
215
216 // Checks the current page to see if it contains the named block.
217 $is_block_cart = has_block( 'woocommerce/cart' );
218 $is_block_checkout = has_block( 'woocommerce/checkout' );
219
220 if ( $has_block_cart && ! $is_block_cart ) {
221 $urls = array_merge( $urls, $this->get_block_asset_resource_hints( 'cart-frontend' ) );
222 }
223
224 if ( $has_block_checkout && ! $is_block_checkout ) {
225 $urls = array_merge( $urls, $this->get_block_asset_resource_hints( 'checkout-frontend' ) );
226 }
227
228 return $urls;
229 }
230
231 /**
232 * Get resource hints during prerender requests.
233 *
234 * @return array Array of URLs.
235 */
236 private function get_prerender_resource_hints() {
237 $urls = array();
238 $is_block_cart = has_block( 'woocommerce/cart' );
239
240 if ( ! $is_block_cart ) {
241 return $urls;
242 }
243
244 $checkout_page_id = wc_get_page_id( 'checkout' );
245 $checkout_page_url = $checkout_page_id ? get_permalink( $checkout_page_id ) : '';
246
247 if ( $checkout_page_url ) {
248 $urls[] = $checkout_page_url;
249 }
250
251 return $urls;
252 }
253
254 /**
255 * Get the block asset resource hints in the cache or null if not found.
256 *
257 * @return array|null Array of resource hints.
258 */
259 private function get_block_asset_resource_hints_cache() {
260 if ( wp_is_development_mode( 'plugin' ) ) {
261 return null;
262 }
263
264 $cache = get_site_transient( 'woocommerce_block_asset_resource_hints' );
265
266 $current_version = array(
267 'woocommerce' => WOOCOMMERCE_VERSION,
268 'wordpress' => get_bloginfo( 'version' ),
269 'site_url' => wp_guess_url(),
270 );
271
272 if ( isset( $cache['version'] ) && $cache['version'] === $current_version ) {
273 return $cache['files'];
274 }
275
276 return null;
277 }
278
279 /**
280 * Set the block asset resource hints in the cache.
281 *
282 * @param string $filename File name.
283 * @param array $data Array of resource hints.
284 */
285 private function set_block_asset_resource_hints_cache( $filename, $data ) {
286 $cache = $this->get_block_asset_resource_hints_cache();
287 $updated = array(
288 'files' => $cache ?? array(),
289 'version' => array(
290 'woocommerce' => WOOCOMMERCE_VERSION,
291 'wordpress' => get_bloginfo( 'version' ),
292 'site_url' => wp_guess_url(),
293 ),
294 );
295
296 $updated['files'][ $filename ] = $data;
297 set_site_transient( 'woocommerce_block_asset_resource_hints', $updated, WEEK_IN_SECONDS );
298 }
299
300 /**
301 * Get resource hint for a block by name.
302 *
303 * @param string $filename Block filename.
304 * @return array
305 */
306 private function get_block_asset_resource_hints( $filename = '' ) {
307 if ( ! $filename ) {
308 return array();
309 }
310
311 $cached = $this->get_block_asset_resource_hints_cache();
312
313 if ( isset( $cached[ $filename ] ) ) {
314 return $cached[ $filename ];
315 }
316
317 $script_data = $this->api->get_script_data(
318 $this->api->get_block_asset_build_path( $filename )
319 );
320 $resources = array_merge(
321 array( esc_url( add_query_arg( 'ver', $script_data['version'], $script_data['src'] ) ) ),
322 $this->get_script_dependency_src_array( $script_data['dependencies'] )
323 );
324
325 $data = array_map(
326 function ( $src ) {
327 return array(
328 'href' => $src,
329 'as' => 'script',
330 );
331 },
332 array_unique( array_filter( $resources ) )
333 );
334
335 $this->set_block_asset_resource_hints_cache( $filename, $data );
336
337 return $data;
338 }
339
340 /**
341 * Get the src of all script dependencies (handles).
342 *
343 * @param array $dependencies Array of dependency handles.
344 * @return string[] Array of src strings.
345 */
346 private function get_script_dependency_src_array( array $dependencies ) {
347 $wp_scripts = wp_scripts();
348 return array_reduce(
349 $dependencies,
350 function ( $src, $handle ) use ( $wp_scripts ) {
351 if ( isset( $wp_scripts->registered[ $handle ] ) ) {
352 $src[] = esc_url( add_query_arg( 'ver', $wp_scripts->registered[ $handle ]->ver, $this->get_absolute_url( $wp_scripts->registered[ $handle ]->src ) ) );
353 $src = array_merge( $src, $this->get_script_dependency_src_array( $wp_scripts->registered[ $handle ]->deps ) );
354 }
355 return $src;
356 },
357 array()
358 );
359 }
360
361 /**
362 * Returns an absolute url to relative links for WordPress core scripts.
363 *
364 * @param string $src Original src that can be relative.
365 * @return string Correct full path string.
366 */
367 private function get_absolute_url( $src ) {
368 $wp_scripts = wp_scripts();
369 if ( ! preg_match( '|^(https?:)?//|', $src ) && ! ( $wp_scripts->content_url && 0 === strpos( $src, $wp_scripts->content_url ) ) ) {
370 $src = $wp_scripts->base_url . $src;
371 }
372 return $src;
373 }
374
375 /**
376 * Skip Jetpack Boost minification on older versions of Jetpack Boost where it causes issues.
377 *
378 * @param mixed $do_concat Whether to concatenate the script or not.
379 * @param mixed $handle The script handle.
380 * @return mixed
381 */
382 public function skip_boost_minification_for_cart_checkout( $do_concat, $handle ) {
383 $boost_is_outdated = defined( 'JETPACK_BOOST_VERSION' ) && version_compare( JETPACK_BOOST_VERSION, '3.4.2', '<' );
384 $scripts_to_ignore = array(
385 'wc-cart-checkout-vendors',
386 'wc-cart-checkout-base',
387 );
388
389 return $boost_is_outdated && in_array( $handle, $scripts_to_ignore, true ) ? false : $do_concat;
390 }
391
392 /**
393 * Add body classes to the frontend and within admin.
394 *
395 * @param string|array $classes Array or string of CSS classnames.
396 * @return string|array Modified classnames.
397 */
398 public function add_theme_body_class( $classes ) {
399 $class = 'theme-' . get_template();
400
401 if ( is_array( $classes ) ) {
402 $classes[] = $class;
403 } else {
404 $classes .= ' ' . $class . ' ';
405 }
406
407 return $classes;
408 }
409
410 /**
411 * Get the file modified time as a cache buster if we're in dev mode.
412 *
413 * @param string $file Local path to the file.
414 * @return string The cache buster value to use for the given file.
415 */
416 protected function get_file_version( $file ) {
417 if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG && file_exists( \Automattic\WooCommerce\Blocks\Package::get_path() . $file ) ) {
418 return filemtime( \Automattic\WooCommerce\Blocks\Package::get_path() . $file );
419 }
420 return $this->api->wc_version;
421 }
422
423 /**
424 * Registers a style according to `wp_register_style`.
425 *
426 * @param string $handle Name of the stylesheet. Should be unique.
427 * @param string $src Full URL of the stylesheet, or path of the stylesheet relative to the WordPress root directory.
428 * @param array $deps Optional. An array of registered stylesheet handles this stylesheet depends on. Default empty array.
429 * @param string $media Optional. The media for which this stylesheet has been defined. Default 'all'. Accepts media types like
430 * 'all', 'print' and 'screen', or media queries like '(orientation: portrait)' and '(max-width: 640px)'.
431 * @param boolean $rtl Optional. Whether or not to register RTL styles.
432 */
433 protected function register_style( $handle, $src, $deps = array(), $media = 'all', $rtl = false ) {
434 $filename = str_replace( plugins_url( '/', dirname( __DIR__ ) ), '', $src );
435 $ver = self::get_file_version( $filename );
436
437 wp_register_style( $handle, $src, $deps, $ver, $media );
438
439 if ( $rtl ) {
440 wp_style_add_data( $handle, 'rtl', 'replace' );
441 }
442 }
443
444 /**
445 * Update block style dependencies after they have been registered.
446 */
447 public function update_block_style_dependencies() {
448 $wp_styles = wp_styles();
449 $style = $wp_styles->query( 'wc-blocks-style', 'registered' );
450
451 if ( ! $style ) {
452 return;
453 }
454
455 // In WC < 5.5, `woocommerce-general` is not registered in block editor
456 // screens, so we don't add it as a dependency if it's not registered.
457 // In WC >= 5.5, `woocommerce-general` is registered on `admin_enqueue_scripts`,
458 // so we need to check if it's registered here instead of on `init`.
459 if (
460 wp_style_is( 'woocommerce-general', 'registered' ) &&
461 ! in_array( 'woocommerce-general', $style->deps, true )
462 ) {
463 $style->deps[] = 'woocommerce-general';
464 }
465 }
466
467 /**
468 * Fix scripts with wc-settings dependency.
469 *
470 * The wc-settings script only works correctly when enqueued in the footer. This is to give blocks etc time to
471 * register their settings data before it's printed.
472 *
473 * This code will look at registered scripts, and if they have a wc-settings dependency, force them to print in the
474 * footer instead of the header.
475 *
476 * This only supports packages known to require wc-settings!
477 *
478 * @see https://github.com/woocommerce/woocommerce-gutenberg-products-block/issues/5052
479 */
480 public function update_block_settings_dependencies() {
481 $wp_scripts = wp_scripts();
482 $known_packages = array( 'wc-settings', 'wc-blocks-checkout', 'wc-price-format' );
483
484 foreach ( $wp_scripts->registered as $handle => $script ) {
485 // scripts that are loaded in the footer has extra->group = 1.
486 if ( array_intersect( $known_packages, $script->deps ) && ! isset( $script->extra['group'] ) ) {
487 // Append the script to footer.
488 $wp_scripts->add_data( $handle, 'group', 1 );
489 // Show a warning.
490 $error_handle = 'wc-settings-dep-in-header';
491 $used_deps = implode( ', ', array_intersect( $known_packages, $script->deps ) );
492 $error_message = "Scripts that have a dependency on [$used_deps] must be loaded in the footer, {$handle} was registered to load in the header, but has been switched to load in the footer instead. See https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5059";
493 // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NotInFooter,WordPress.WP.EnqueuedResourceParameters.MissingVersion
494 wp_register_script( $error_handle, '' );
495 wp_enqueue_script( $error_handle );
496 wp_add_inline_script(
497 $error_handle,
498 sprintf( 'console.warn( "%s" );', $error_message )
499 );
500
501 }
502 }
503 }
504 }
505