Agentic
4 months ago
BlockTemplates
4 weeks ago
EmailImprovements
1 year ago
EmailPreview
4 weeks ago
Emails
1 year ago
ImportExport
1 year ago
Logging
1 year ago
Marketing
2 years ago
Notes
4 weeks ago
Onboarding
5 months ago
Orders
4 weeks ago
ProductForm
2 years ago
ProductReviews
4 weeks ago
RemoteFreeExtensions
4 weeks ago
Schedulers
4 weeks ago
Settings
2 weeks ago
Suggestions
4 weeks ago
WCPayPromotion
10 months ago
ActivityPanels.php
3 years ago
Analytics.php
4 weeks ago
CategoryLookup.php
4 years ago
Coupons.php
1 year ago
CouponsMovedTrait.php
5 months ago
CustomerEffortScoreTracks.php
7 months ago
Events.php
2 months ago
FeaturePlugin.php
4 months ago
Homescreen.php
1 month ago
Loader.php
4 weeks ago
Marketing.php
1 year ago
Marketplace.php
5 months ago
MobileAppBanner.php
4 years ago
OrderMilestoneEasterEgg.php
4 weeks ago
RemoteInboxNotifications.php
3 years ago
Settings.php
2 weeks ago
ShippingLabelBanner.php
1 year ago
ShippingLabelBannerDisplayRules.php
1 year ago
SiteHealth.php
3 years ago
Survey.php
4 years ago
SystemStatusReport.php
1 year ago
Translations.php
1 year ago
WCAdminAssets.php
2 weeks ago
WCAdminSharedSettings.php
1 year ago
WCAdminUser.php
9 months ago
WcPayWelcomePage.php
1 year ago
WCAdminAssets.php
569 lines
| 1 | <?php |
| 2 | /** |
| 3 | * Register the scripts, and styles used within WooCommerce Admin. |
| 4 | */ |
| 5 | |
| 6 | namespace Automattic\WooCommerce\Internal\Admin; |
| 7 | |
| 8 | use _WP_Dependency; |
| 9 | use Automattic\WooCommerce\Admin\Features\Features; |
| 10 | use Automattic\WooCommerce\Admin\PageController; |
| 11 | use Automattic\WooCommerce\Internal\Admin\Loader; |
| 12 | use Automattic\WooCommerce\Internal\Admin\Settings\SettingsUIRequestContext; |
| 13 | use Automattic\WooCommerce\Utilities\FeaturesUtil; |
| 14 | |
| 15 | /** |
| 16 | * WCAdminAssets Class. |
| 17 | */ |
| 18 | class WCAdminAssets { |
| 19 | |
| 20 | /** |
| 21 | * Class instance. |
| 22 | * |
| 23 | * @var WCAdminAssets instance |
| 24 | */ |
| 25 | protected static $instance = null; |
| 26 | |
| 27 | /** |
| 28 | * An array of dependencies that have been preloaded (to avoid duplicates). |
| 29 | * |
| 30 | * @var array |
| 31 | */ |
| 32 | protected $preloaded_dependencies; |
| 33 | |
| 34 | |
| 35 | /** |
| 36 | * Get class instance. |
| 37 | */ |
| 38 | public static function get_instance() { |
| 39 | if ( ! self::$instance ) { |
| 40 | self::$instance = new self(); |
| 41 | } |
| 42 | return self::$instance; |
| 43 | } |
| 44 | |
| 45 | /** |
| 46 | * Constructor. |
| 47 | * Hooks added here should be removed in `wc_admin_initialize` via the feature plugin. |
| 48 | */ |
| 49 | public function __construct() { |
| 50 | Features::get_instance(); |
| 51 | add_action( 'admin_enqueue_scripts', array( $this, 'register_scripts' ) ); |
| 52 | |
| 53 | add_action( 'admin_enqueue_scripts', array( $this, 'inject_wc_settings_dependencies' ), 14 ); |
| 54 | add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ), 15 ); |
| 55 | } |
| 56 | |
| 57 | /** |
| 58 | * Gets the path for the asset depending on file type. |
| 59 | * |
| 60 | * @param string $ext File extension. |
| 61 | * @return string Folder path of asset. |
| 62 | */ |
| 63 | public static function get_path( $ext ) { |
| 64 | return ( 'css' === $ext ) ? WC_ADMIN_DIST_CSS_FOLDER : WC_ADMIN_DIST_JS_FOLDER; |
| 65 | } |
| 66 | |
| 67 | /** |
| 68 | * Determines if a minified JS file should be served. |
| 69 | * |
| 70 | * @param boolean $script_debug Only serve unminified files if script debug is on. |
| 71 | * @return boolean If js asset should use minified version. |
| 72 | */ |
| 73 | public static function should_use_minified_js_file( $script_debug ) { |
| 74 | // minified files are only shipped in non-core versions of wc-admin, return false if minified files are not available. |
| 75 | if ( ! Features::exists( 'minified-js' ) ) { |
| 76 | return false; |
| 77 | } |
| 78 | |
| 79 | // Otherwise we will serve un-minified files if SCRIPT_DEBUG is on, or if anything truthy is passed in-lieu of SCRIPT_DEBUG. |
| 80 | return ! $script_debug; |
| 81 | } |
| 82 | |
| 83 | /** |
| 84 | * Gets the URL to an asset file. |
| 85 | * |
| 86 | * @param string $file File name (without extension). |
| 87 | * @param string $ext File extension. |
| 88 | * @return string URL to asset. |
| 89 | */ |
| 90 | public static function get_url( $file, $ext ) { |
| 91 | $suffix = ''; |
| 92 | |
| 93 | // Potentially enqueue minified JavaScript. |
| 94 | if ( 'js' === $ext ) { |
| 95 | $script_debug = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG; |
| 96 | $suffix = self::should_use_minified_js_file( $script_debug ) ? '.min' : ''; |
| 97 | } |
| 98 | |
| 99 | return plugins_url( self::get_path( $ext ) . $file . $suffix . '.' . $ext, WC_ADMIN_PLUGIN_FILE ); |
| 100 | } |
| 101 | |
| 102 | /** |
| 103 | * Gets the file modified time as a cache buster if we're in dev mode, |
| 104 | * or the asset version (file content hash) if exists, or the WooCommerce version. |
| 105 | * |
| 106 | * @param string $ext File extension. |
| 107 | * @param string|null $asset_version Optional. The version from the asset file. |
| 108 | * @return string The cache buster value to use for the given file. |
| 109 | */ |
| 110 | public static function get_file_version( $ext, $asset_version = null ) { |
| 111 | if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) { |
| 112 | return filemtime( WC_ADMIN_ABSPATH . self::get_path( $ext ) ); |
| 113 | } |
| 114 | |
| 115 | if ( ! empty( $asset_version ) ) { |
| 116 | return $asset_version; |
| 117 | } |
| 118 | |
| 119 | return WC_VERSION; |
| 120 | } |
| 121 | |
| 122 | /** |
| 123 | * Gets a script asset registry filename. The asset registry lists dependencies for the given script. |
| 124 | * |
| 125 | * @param string $script_path_name Path to where the script asset registry is contained. |
| 126 | * @param string $file File name (without extension). |
| 127 | * @return string complete asset filename. |
| 128 | * |
| 129 | * @throws \Exception Throws an exception when a readable asset registry file cannot be found. |
| 130 | */ |
| 131 | public static function get_script_asset_filename( $script_path_name, $file ) { |
| 132 | $minification_supported = Features::exists( 'minified-js' ); |
| 133 | $script_min_filename = $file . '.min.asset.php'; |
| 134 | $script_nonmin_filename = $file . '.asset.php'; |
| 135 | $script_asset_path = WC_ADMIN_ABSPATH . WC_ADMIN_DIST_JS_FOLDER . $script_path_name . '/'; |
| 136 | |
| 137 | // Check minification is supported first, to avoid multiple is_readable checks when minification is |
| 138 | // not supported. |
| 139 | if ( $minification_supported && is_readable( $script_asset_path . $script_min_filename ) ) { |
| 140 | return $script_min_filename; |
| 141 | } elseif ( is_readable( $script_asset_path . $script_nonmin_filename ) ) { |
| 142 | return $script_nonmin_filename; |
| 143 | } else { |
| 144 | // could not find an asset file, throw an error. |
| 145 | throw new \Exception( 'Could not find asset registry for ' . esc_html( $script_path_name ) ); |
| 146 | } |
| 147 | } |
| 148 | |
| 149 | /** |
| 150 | * Render a preload link tag for a dependency, optionally |
| 151 | * checked against a provided allowlist. |
| 152 | * |
| 153 | * See: https://macarthur.me/posts/preloading-javascript-in-wordpress |
| 154 | * |
| 155 | * @param WP_Dependency $dependency The WP_Dependency being preloaded. |
| 156 | * @param string $type Dependency type - 'script' or 'style'. |
| 157 | * @param array $allowlist Optional. List of allowed dependency handles. |
| 158 | */ |
| 159 | private function maybe_output_preload_link_tag( $dependency, $type, $allowlist = array() ) { |
| 160 | if ( |
| 161 | ( |
| 162 | ! empty( $allowlist ) && |
| 163 | ! in_array( $dependency->handle, $allowlist, true ) |
| 164 | ) || |
| 165 | ( ! empty( $this->preloaded_dependencies[ $type ] ) && |
| 166 | in_array( $dependency->handle, $this->preloaded_dependencies[ $type ], true ) ) |
| 167 | ) { |
| 168 | return; |
| 169 | } |
| 170 | |
| 171 | $this->preloaded_dependencies[ $type ][] = $dependency->handle; |
| 172 | |
| 173 | $source = $dependency->ver ? add_query_arg( 'ver', $dependency->ver, $dependency->src ) : $dependency->src; |
| 174 | |
| 175 | echo '<link rel="preload" href="', esc_url( $source ), '" as="', esc_attr( $type ), '" />', "\n"; |
| 176 | } |
| 177 | |
| 178 | /** |
| 179 | * Output a preload link tag for dependencies (and their sub dependencies) |
| 180 | * with an optional allowlist. |
| 181 | * |
| 182 | * See: https://macarthur.me/posts/preloading-javascript-in-wordpress |
| 183 | * |
| 184 | * @param string $type Dependency type - 'script' or 'style'. |
| 185 | * @param array $allowlist Optional. List of allowed dependency handles. |
| 186 | */ |
| 187 | private function output_header_preload_tags_for_type( $type, $allowlist = array() ) { |
| 188 | if ( $type === 'script' ) { |
| 189 | $dependencies_of_type = wp_scripts(); |
| 190 | } elseif ( $type === 'style' ) { |
| 191 | $dependencies_of_type = wp_styles(); |
| 192 | } else { |
| 193 | return; |
| 194 | } |
| 195 | |
| 196 | foreach ( $dependencies_of_type->queue as $dependency_handle ) { |
| 197 | $dependency = $dependencies_of_type->query( $dependency_handle, 'registered' ); |
| 198 | |
| 199 | if ( $dependency === false ) { |
| 200 | continue; |
| 201 | } |
| 202 | |
| 203 | // Preload the subdependencies first. |
| 204 | foreach ( $dependency->deps as $sub_dependency_handle ) { |
| 205 | $sub_dependency = $dependencies_of_type->query( $sub_dependency_handle, 'registered' ); |
| 206 | |
| 207 | if ( $sub_dependency ) { |
| 208 | $this->maybe_output_preload_link_tag( $sub_dependency, $type, $allowlist ); |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | $this->maybe_output_preload_link_tag( $dependency, $type, $allowlist ); |
| 213 | } |
| 214 | } |
| 215 | |
| 216 | /** |
| 217 | * Output preload link tags for all enqueued stylesheets and scripts. |
| 218 | * |
| 219 | * See: https://macarthur.me/posts/preloading-javascript-in-wordpress |
| 220 | */ |
| 221 | private function output_header_preload_tags() { |
| 222 | $wc_admin_scripts = array( |
| 223 | WC_ADMIN_APP, |
| 224 | 'wc-components', |
| 225 | ); |
| 226 | |
| 227 | $wc_admin_styles = array( |
| 228 | WC_ADMIN_APP, |
| 229 | 'wc-components', |
| 230 | 'wc-material-icons', |
| 231 | ); |
| 232 | |
| 233 | // Preload styles. |
| 234 | $this->output_header_preload_tags_for_type( 'style', $wc_admin_styles ); |
| 235 | |
| 236 | // Preload scripts. |
| 237 | $this->output_header_preload_tags_for_type( 'script', $wc_admin_scripts ); |
| 238 | } |
| 239 | |
| 240 | /** |
| 241 | * Loads the required scripts on the correct pages. |
| 242 | */ |
| 243 | public function enqueue_assets() { |
| 244 | if ( ! PageController::is_admin_or_embed_page() ) { |
| 245 | return; |
| 246 | } |
| 247 | |
| 248 | wp_enqueue_script( WC_ADMIN_APP ); |
| 249 | wp_enqueue_style( WC_ADMIN_APP ); |
| 250 | |
| 251 | wp_enqueue_style( 'wc-material-icons' ); |
| 252 | wp_enqueue_style( 'wc-onboarding' ); |
| 253 | |
| 254 | if ( PageController::is_settings_page() ) { |
| 255 | $this->register_script( 'wp-admin-scripts', 'settings-embed', true, $this->get_settings_ui_script_dependencies() ); |
| 256 | $this->register_style( 'settings-embed', 'style', array( 'wp-components' ) ); |
| 257 | } |
| 258 | |
| 259 | // Preload our assets. |
| 260 | $this->output_header_preload_tags(); |
| 261 | } |
| 262 | |
| 263 | /** |
| 264 | * Modify script dependencies based on various conditions to only load the necessary scripts. |
| 265 | * |
| 266 | * @param array $dependencies Array of script dependencies. |
| 267 | * @param string $script Script name. |
| 268 | * @return array Modified dependencies. |
| 269 | */ |
| 270 | private function modify_script_dependencies( $dependencies, $script ) { |
| 271 | $dependencies = array_map( |
| 272 | static function ( $dependency ) { |
| 273 | return 'wp-route' === $dependency ? 'wp-router' : $dependency; |
| 274 | }, |
| 275 | $dependencies |
| 276 | ); |
| 277 | |
| 278 | switch ( $script ) { |
| 279 | case WC_ADMIN_APP: |
| 280 | // Remove wp-editor dependency if we're not on a customize store page since we don't use wp-editor in other pages. |
| 281 | $is_customize_store_page = ( |
| 282 | PageController::is_admin_page() && |
| 283 | isset( $_GET['path'] ) && // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 284 | str_starts_with( wc_clean( wp_unslash( $_GET['path'] ) ), '/customize-store' ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 285 | ); |
| 286 | if ( ! $is_customize_store_page ) { |
| 287 | $dependencies = array_diff( $dependencies, array( 'wp-editor' ) ); |
| 288 | } |
| 289 | |
| 290 | // Remove product editor dependency from WC_ADMIN_APP when feature is disabled. |
| 291 | if ( ! FeaturesUtil::feature_is_enabled( 'product_block_editor' ) ) { |
| 292 | $dependencies = array_diff( $dependencies, array( 'wc-product-editor' ) ); |
| 293 | } |
| 294 | break; |
| 295 | case 'wc-product-editor': |
| 296 | // Remove wp-editor dependency if the product editor feature is disabled as we don't need it. |
| 297 | $is_product_data_view_page = \Automattic\WooCommerce\Admin\Features\ProductDataViews\Init::is_product_data_view_page(); |
| 298 | if ( ! ( FeaturesUtil::feature_is_enabled( 'product_block_editor' ) || $is_product_data_view_page ) ) { |
| 299 | $dependencies = array_diff( $dependencies, array( 'wp-editor' ) ); |
| 300 | } |
| 301 | break; |
| 302 | } |
| 303 | return $dependencies; |
| 304 | } |
| 305 | |
| 306 | /** |
| 307 | * Registers all the necessary scripts and styles to show the admin experience. |
| 308 | */ |
| 309 | public function register_scripts() { |
| 310 | if ( ! function_exists( 'wp_set_script_translations' ) ) { |
| 311 | return; |
| 312 | } |
| 313 | |
| 314 | // Register the JS scripts. |
| 315 | $scripts = array( |
| 316 | 'wc-admin-layout', |
| 317 | 'wc-explat', |
| 318 | 'wc-experimental', |
| 319 | 'wc-customer-effort-score', |
| 320 | // NOTE: This should be removed when Gutenberg is updated and the notices package is removed from WooCommerce Admin. |
| 321 | 'wc-notices', |
| 322 | 'wc-number', |
| 323 | 'wc-tracks', |
| 324 | 'wc-date', |
| 325 | 'wc-components', |
| 326 | WC_ADMIN_APP, |
| 327 | 'wc-csv', |
| 328 | 'wc-store-data', |
| 329 | 'wc-currency', |
| 330 | 'wc-navigation', |
| 331 | 'wc-block-templates', |
| 332 | 'wc-experimental-products-app', |
| 333 | 'wc-product-editor', |
| 334 | 'wc-settings-ui', |
| 335 | 'wc-remote-logging', |
| 336 | 'wc-sanitize', |
| 337 | ); |
| 338 | |
| 339 | $scripts_map = array( |
| 340 | WC_ADMIN_APP => PageController::is_embed_page() ? 'embed' : 'app', |
| 341 | 'wc-csv' => 'csv-export', |
| 342 | 'wc-store-data' => 'data', |
| 343 | ); |
| 344 | |
| 345 | $translated_scripts = array( |
| 346 | 'wc-currency', |
| 347 | 'wc-date', |
| 348 | 'wc-components', |
| 349 | 'wc-customer-effort-score', |
| 350 | 'wc-experimental-products-app', |
| 351 | 'wc-experimental', |
| 352 | 'wc-navigation', |
| 353 | 'wc-product-editor', |
| 354 | 'wc-settings-ui', |
| 355 | WC_ADMIN_APP, |
| 356 | ); |
| 357 | |
| 358 | foreach ( $scripts as $script ) { |
| 359 | $script_path_name = isset( $scripts_map[ $script ] ) ? $scripts_map[ $script ] : str_replace( 'wc-', '', $script ); |
| 360 | |
| 361 | try { |
| 362 | $script_assets_filename = self::get_script_asset_filename( $script_path_name, 'index' ); |
| 363 | $script_assets = require WC_ADMIN_ABSPATH . WC_ADMIN_DIST_JS_FOLDER . $script_path_name . '/' . $script_assets_filename; |
| 364 | $script_version = self::get_file_version( 'js', $script_assets['version'] ); |
| 365 | |
| 366 | $script_dependencies = $this->modify_script_dependencies( $script_assets['dependencies'], $script, $script_path_name ); |
| 367 | |
| 368 | wp_register_script( |
| 369 | $script, |
| 370 | self::get_url( $script_path_name . '/index', 'js' ), |
| 371 | $script_dependencies, |
| 372 | $script_version, |
| 373 | true |
| 374 | ); |
| 375 | |
| 376 | if ( in_array( $script, $translated_scripts, true ) ) { |
| 377 | wp_set_script_translations( $script, 'woocommerce' ); |
| 378 | } |
| 379 | |
| 380 | if ( WC_ADMIN_APP === $script ) { |
| 381 | wp_localize_script( |
| 382 | WC_ADMIN_APP, |
| 383 | 'wcAdminAssets', |
| 384 | array( |
| 385 | 'path' => plugins_url( self::get_path( 'js' ), WC_ADMIN_PLUGIN_FILE ), |
| 386 | 'version' => $script_version, |
| 387 | ) |
| 388 | ); |
| 389 | } |
| 390 | } catch ( \Exception $e ) { |
| 391 | // Avoid crashing WordPress if an asset file could not be loaded. |
| 392 | wc_caught_exception( $e, __CLASS__ . '::' . __FUNCTION__, $script_path_name ); |
| 393 | } |
| 394 | } |
| 395 | |
| 396 | // Register the CSS styles. |
| 397 | $styles = array( |
| 398 | array( |
| 399 | 'handle' => 'wc-admin-layout', |
| 400 | ), |
| 401 | array( |
| 402 | 'handle' => 'wc-components', |
| 403 | ), |
| 404 | array( |
| 405 | 'handle' => 'wc-block-templates', |
| 406 | ), |
| 407 | array( |
| 408 | 'handle' => 'wc-experimental-products-app', |
| 409 | ), |
| 410 | array( |
| 411 | 'handle' => 'wc-product-editor', |
| 412 | ), |
| 413 | array( |
| 414 | 'handle' => 'wc-customer-effort-score', |
| 415 | ), |
| 416 | array( |
| 417 | 'handle' => 'wc-experimental', |
| 418 | ), |
| 419 | array( |
| 420 | 'handle' => WC_ADMIN_APP, |
| 421 | 'dependencies' => array( 'wc-components', 'wc-admin-layout', 'wc-customer-effort-score', 'wp-components', 'wc-experimental' ), |
| 422 | ), |
| 423 | array( |
| 424 | 'handle' => 'wc-onboarding', |
| 425 | ), |
| 426 | ); |
| 427 | |
| 428 | $css_file_version = self::get_file_version( 'css' ); |
| 429 | foreach ( $styles as $style ) { |
| 430 | $handle = $style['handle']; |
| 431 | $style_path_name = isset( $scripts_map[ $handle ] ) ? $scripts_map[ $handle ] : str_replace( 'wc-', '', $handle ); |
| 432 | |
| 433 | try { |
| 434 | $style_assets_filename = self::get_script_asset_filename( $style_path_name, 'style' ); |
| 435 | $style_assets = require WC_ADMIN_ABSPATH . WC_ADMIN_DIST_JS_FOLDER . $style_path_name . '/' . $style_assets_filename; |
| 436 | $version = $style_assets['version']; |
| 437 | } catch ( \Throwable $e ) { |
| 438 | // Use the default version if the asset file could not be loaded. |
| 439 | $version = $css_file_version; |
| 440 | } |
| 441 | |
| 442 | $dependencies = isset( $style['dependencies'] ) ? $style['dependencies'] : array(); |
| 443 | wp_register_style( |
| 444 | $handle, |
| 445 | self::get_url( $style_path_name . '/style', 'css' ), |
| 446 | $dependencies, |
| 447 | self::get_file_version( 'css', $version ), |
| 448 | ); |
| 449 | wp_style_add_data( $handle, 'rtl', 'replace' ); |
| 450 | } |
| 451 | } |
| 452 | |
| 453 | /** |
| 454 | * Get extension script handles that must load before the settings embed app mounts. |
| 455 | * |
| 456 | * @return array |
| 457 | */ |
| 458 | private function get_settings_ui_script_dependencies(): array { |
| 459 | $context = SettingsUIRequestContext::get_current(); |
| 460 | if ( ! $context ) { |
| 461 | return array(); |
| 462 | } |
| 463 | |
| 464 | $dependencies = array_merge( |
| 465 | array( 'wc-settings-ui' ), |
| 466 | $context->get_script_handles() |
| 467 | ); |
| 468 | |
| 469 | return array_values( array_unique( $dependencies ) ); |
| 470 | } |
| 471 | |
| 472 | /** |
| 473 | * Injects wp-shared-settings as a dependency if it's present. |
| 474 | */ |
| 475 | public function inject_wc_settings_dependencies() { |
| 476 | $wp_scripts = wp_scripts(); |
| 477 | if ( wp_script_is( 'wc-settings', 'registered' ) ) { |
| 478 | $handles_for_injection = array( |
| 479 | 'wc-admin-layout', |
| 480 | 'wc-csv', |
| 481 | 'wc-currency', |
| 482 | 'wc-customer-effort-score', |
| 483 | 'wc-experimental-products-app', |
| 484 | 'wc-navigation', |
| 485 | // NOTE: This should be removed when Gutenberg is updated and |
| 486 | // the notices package is removed from WooCommerce Admin. |
| 487 | 'wc-notices', |
| 488 | 'wc-number', |
| 489 | 'wc-date', |
| 490 | 'wc-components', |
| 491 | 'wc-tracks', |
| 492 | 'wc-block-templates', |
| 493 | 'wc-product-editor', |
| 494 | ); |
| 495 | foreach ( $handles_for_injection as $handle ) { |
| 496 | $script = $wp_scripts->query( $handle, 'registered' ); |
| 497 | if ( $script instanceof _WP_Dependency ) { |
| 498 | $script->deps[] = 'wc-settings'; |
| 499 | $wp_scripts->add_data( $handle, 'group', 1 ); |
| 500 | } |
| 501 | } |
| 502 | foreach ( $wp_scripts->registered as $handle => $script ) { |
| 503 | // scripts that are loaded in the footer has extra->group = 1. |
| 504 | if ( array_intersect( $handles_for_injection, $script->deps ) && ! isset( $script->extra['group'] ) ) { |
| 505 | // Append the script to footer. |
| 506 | $wp_scripts->add_data( $handle, 'group', 1 ); |
| 507 | // Show a warning. |
| 508 | $error_handle = 'wc-settings-dep-in-header'; |
| 509 | $used_deps = implode( ', ', array_intersect( $handles_for_injection, $script->deps ) ); |
| 510 | $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"; |
| 511 | // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NotInFooter,WordPress.WP.EnqueuedResourceParameters.MissingVersion |
| 512 | wp_register_script( $error_handle, '' ); |
| 513 | wp_enqueue_script( $error_handle ); |
| 514 | wp_add_inline_script( |
| 515 | $error_handle, |
| 516 | sprintf( 'console.warn( "%s" );', $error_message ) |
| 517 | ); |
| 518 | |
| 519 | } |
| 520 | } |
| 521 | } |
| 522 | } |
| 523 | |
| 524 | /** |
| 525 | * Loads a script |
| 526 | * |
| 527 | * @param string $script_path_name The script path name. |
| 528 | * @param string $script_name Filename of the script to load. |
| 529 | * @param bool $need_translation Whether the script need translations. |
| 530 | * @param array $dependencies Array of any extra dependencies. Note wc-admin and any application JS dependencies are automatically added by Dependency Extraction Webpack Plugin. Use this parameter to designate any extra dependencies. |
| 531 | */ |
| 532 | public static function register_script( $script_path_name, $script_name, $need_translation = false, $dependencies = array() ) { |
| 533 | $script_assets_filename = self::get_script_asset_filename( $script_path_name, $script_name ); |
| 534 | $script_assets = require WC_ADMIN_ABSPATH . WC_ADMIN_DIST_JS_FOLDER . $script_path_name . '/' . $script_assets_filename; |
| 535 | |
| 536 | wp_enqueue_script( |
| 537 | 'wc-admin-' . $script_name, |
| 538 | self::get_url( $script_path_name . '/' . $script_name, 'js' ), |
| 539 | array_merge( array( WC_ADMIN_APP ), $script_assets ['dependencies'], $dependencies ), |
| 540 | self::get_file_version( 'js', $script_assets['version'] ), |
| 541 | true |
| 542 | ); |
| 543 | if ( $need_translation ) { |
| 544 | wp_set_script_translations( 'wc-admin-' . $script_name, 'woocommerce' ); |
| 545 | } |
| 546 | } |
| 547 | |
| 548 | /** |
| 549 | * Loads a style |
| 550 | * |
| 551 | * @param string $style_path_name The style path name. |
| 552 | * @param string $style_name Filename of the style to load. |
| 553 | * @param array $dependencies Array of any extra dependencies. |
| 554 | */ |
| 555 | public static function register_style( $style_path_name, $style_name, $dependencies = array() ) { |
| 556 | $style_assets_filename = self::get_script_asset_filename( $style_path_name, $style_name ); |
| 557 | $style_assets = require WC_ADMIN_ABSPATH . WC_ADMIN_DIST_CSS_FOLDER . $style_path_name . '/' . $style_assets_filename; |
| 558 | |
| 559 | $handle = 'wc-admin-' . $style_name; |
| 560 | wp_enqueue_style( |
| 561 | $handle, |
| 562 | self::get_url( $style_path_name . '/' . $style_name, 'css' ), |
| 563 | $dependencies, |
| 564 | self::get_file_version( 'css', $style_assets['version'] ), |
| 565 | ); |
| 566 | wp_style_add_data( $handle, 'rtl', 'replace' ); |
| 567 | } |
| 568 | } |
| 569 |