* @package WooCommerce\Admin
use Automattic\Jetpack\Constants;
use Automattic\WooCommerce\Admin\Features\Features;
use Automattic\WooCommerce\Enums\OrderStatus;
use Automattic\WooCommerce\Enums\ProductType;
use Automattic\WooCommerce\Internal\Admin\Analytics;
use Automattic\WooCommerce\Internal\Admin\WCAdminAssets;
use Automattic\WooCommerce\Internal\CostOfGoodsSold\CostOfGoodsSoldController;
if ( ! defined( 'ABSPATH' ) ) {
if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
* These scripts are enqueued in the admin of the store. The registered script handles in this class
* can be used to enqueue the scripts in the admin by third party plugins and the handles will follow
* WooCommerce's L-1 support policy. Scripts registered outside of this class do not guarantee support
* and can be removed in future versions of WooCommerce.
public function __construct() {
add_action( 'admin_init', array( $this, 'register_scripts' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'admin_styles' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) );
add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ) );
public function admin_styles() {
$version = Constants::get_constant( 'WC_VERSION' );
$screen = get_current_screen();
$screen_id = $screen ? $screen->id : '';
// Register admin styles.
wp_register_style( 'woocommerce_admin_menu_styles', WC()->plugin_url() . '/assets/css/menu.css', array(), $version );
wp_register_style( 'woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css', array(), $version );
wp_register_style( 'jquery-ui-style', WC()->plugin_url() . '/assets/css/jquery-ui/jquery-ui.min.css', array(), $version );
wp_register_style( 'woocommerce_admin_dashboard_styles', WC()->plugin_url() . '/assets/css/dashboard.css', array(), $version );
wp_register_style( 'woocommerce_admin_print_reports_styles', WC()->plugin_url() . '/assets/css/reports-print.css', array(), $version, 'print' );
wp_register_style( 'woocommerce_admin_marketplace_styles', WC()->plugin_url() . '/assets/css/marketplace-suggestions.css', array(), $version );
wp_register_style( 'woocommerce_admin_privacy_styles', WC()->plugin_url() . '/assets/css/privacy.css', array(), $version );
// Add RTL support for admin styles.
wp_style_add_data( 'woocommerce_admin_menu_styles', 'rtl', 'replace' );
wp_style_add_data( 'woocommerce_admin_styles', 'rtl', 'replace' );
wp_style_add_data( 'woocommerce_admin_dashboard_styles', 'rtl', 'replace' );
wp_style_add_data( 'woocommerce_admin_print_reports_styles', 'rtl', 'replace' );
wp_style_add_data( 'woocommerce_admin_marketplace_styles', 'rtl', 'replace' );
wp_style_add_data( 'woocommerce_admin_privacy_styles', 'rtl', 'replace' );
if ( $screen && $screen->is_block_editor() ) {
if ( ! wp_is_block_theme() ) {
wp_register_style( 'woocommerce-classictheme-editor-fonts', WC()->plugin_url() . '/assets/css/woocommerce-classictheme-editor-fonts.css', array(), $version );
wp_enqueue_style( 'woocommerce-classictheme-editor-fonts' );
$styles = WC_Frontend_Scripts::get_styles();
foreach ( $styles as $handle => $args ) {
if ( ! isset( $args['has_rtl'] ) ) {
wp_style_add_data( $handle, 'rtl', 'replace' );
wp_enqueue_style( $handle );
wp_enqueue_style( 'woocommerce_admin_menu_styles' );
// Admin styles for WC pages only.
if ( in_array( $screen_id, wc_get_screen_ids() ) ) {
wp_enqueue_style( 'woocommerce_admin_styles' );
wp_enqueue_style( 'jquery-ui-style' );
wp_enqueue_style( 'wp-color-picker' );
if ( in_array( $screen_id, array( 'dashboard' ) ) ) {
wp_enqueue_style( 'woocommerce_admin_dashboard_styles' );
if ( in_array( $screen_id, array( 'woocommerce_page_wc-reports', 'toplevel_page_wc-reports' ) ) ) {
wp_enqueue_style( 'woocommerce_admin_print_reports_styles' );
// Privacy Policy Guide css for back-compat.
if ( isset( $_GET['wp-privacy-policy-guide'] ) || in_array( $screen_id, array( 'privacy-policy-guide' ) ) ) {
wp_enqueue_style( 'woocommerce_admin_privacy_styles' );
if ( has_action( 'woocommerce_admin_css' ) ) {
/* phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment */
do_action( 'woocommerce_admin_css' );
wc_deprecated_function( 'The woocommerce_admin_css action', '2.3', 'admin_enqueue_scripts' );
if ( WC_Marketplace_Suggestions::show_suggestions_for_screen( $screen_id ) ) {
wp_enqueue_style( 'woocommerce_admin_marketplace_styles' );
* Get the scripts used for registration.
private function get_scripts(): array {
$suffix = Constants::is_true( 'SCRIPT_DEBUG' ) ? '' : '.min';
$version = Constants::get_constant( 'WC_VERSION' );
$plugin_url = WC()->plugin_url();
'handle' => 'woocommerce_admin',
'path' => $plugin_url . '/assets/js/admin/woocommerce_admin' . $suffix . '.js',
'dependencies' => array( 'jquery', 'wc-jquery-blockui', 'jquery-ui-sortable', 'jquery-ui-widget', 'jquery-ui-core', 'wc-jquery-tiptip' ),
'legacy_handle' => 'jquery-blockui',
'handle' => 'wc-jquery-blockui',
'path' => $plugin_url . '/assets/js/jquery-blockui/jquery.blockUI' . $suffix . '.js',
'dependencies' => array( 'jquery' ),
'legacy_handle' => 'jquery-tiptip',
'handle' => 'wc-jquery-tiptip',
'path' => $plugin_url . '/assets/js/jquery-tiptip/jquery.tipTip' . $suffix . '.js',
'dependencies' => array( 'jquery', 'wc-dompurify' ),
'legacy_handle' => 'round',
'path' => $plugin_url . '/assets/js/round/round' . $suffix . '.js',
'dependencies' => array( 'jquery' ),
'handle' => 'wc-admin-meta-boxes',
'path' => $plugin_url . '/assets/js/admin/meta-boxes' . $suffix . '.js',
'dependencies' => array( 'jquery', 'jquery-ui-datepicker', 'jquery-ui-sortable', 'wc-accounting', 'wc-round', 'wc-enhanced-select', 'plupload-all', 'wc-stupidtable', 'wc-jquery-tiptip', 'wc-jquery-blockui' ),
'legacy_handle' => 'qrcode',
'path' => $plugin_url . '/assets/js/jquery-qrcode/jquery.qrcode' . $suffix . '.js',
'dependencies' => array( 'jquery' ),
'legacy_handle' => 'stupidtable',
'handle' => 'wc-stupidtable',
'path' => $plugin_url . '/assets/js/stupidtable/stupidtable' . $suffix . '.js',
'dependencies' => array( 'jquery' ),
'legacy_handle' => 'serializejson',
'handle' => 'wc-serializejson',
'path' => $plugin_url . '/assets/js/jquery-serializejson/jquery.serializejson' . $suffix . '.js',
'dependencies' => array( 'jquery' ),
'legacy_handle' => 'flot',
'path' => $plugin_url . '/assets/js/jquery-flot/jquery.flot' . $suffix . '.js',
'dependencies' => array( 'jquery' ),
'legacy_handle' => 'flot-resize',
'handle' => 'wc-flot-resize',
'path' => $plugin_url . '/assets/js/jquery-flot/jquery.flot.resize' . $suffix . '.js',
'dependencies' => array( 'jquery', 'wc-flot' ),
'legacy_handle' => 'flot-time',
'handle' => 'wc-flot-time',
'path' => $plugin_url . '/assets/js/jquery-flot/jquery.flot.time' . $suffix . '.js',
'dependencies' => array( 'jquery', 'wc-flot' ),
'legacy_handle' => 'flot-pie',
'handle' => 'wc-flot-pie',
'path' => $plugin_url . '/assets/js/jquery-flot/jquery.flot.pie' . $suffix . '.js',
'dependencies' => array( 'jquery', 'wc-flot' ),
'legacy_handle' => 'flot-stack',
'handle' => 'wc-flot-stack',
'path' => $plugin_url . '/assets/js/jquery-flot/jquery.flot.stack' . $suffix . '.js',
'dependencies' => array( 'jquery', 'wc-flot' ),
'handle' => 'wc-settings-tax',
'path' => $plugin_url . '/assets/js/admin/settings-views-html-settings-tax' . $suffix . '.js',
'dependencies' => array( 'jquery', 'wp-util', 'underscore', 'backbone', 'wc-jquery-blockui' ),
'handle' => 'wc-backbone-modal',
'path' => $plugin_url . '/assets/js/admin/backbone-modal' . $suffix . '.js',
'dependencies' => array( 'underscore', 'backbone', 'wp-util' ),
'handle' => 'wc-shipping-zones',
'path' => $plugin_url . '/assets/js/admin/wc-shipping-zones' . $suffix . '.js',
'dependencies' => array( 'jquery', 'wp-util', 'underscore', 'backbone', 'jquery-ui-sortable', 'wc-enhanced-select', 'wc-backbone-modal' ),
'handle' => 'wc-shipping-zone-methods',
'path' => $plugin_url . '/assets/js/admin/wc-shipping-zone-methods' . $suffix . '.js',
'dependencies' => array( 'jquery', 'wp-util', 'underscore', 'backbone', 'jquery-ui-sortable', 'wc-backbone-modal' ),
'handle' => 'wc-shipping-classes',
'path' => $plugin_url . '/assets/js/admin/wc-shipping-classes' . $suffix . '.js',
'dependencies' => array( 'jquery', 'wp-util', 'underscore', 'backbone', 'wc-backbone-modal' ),
'handle' => 'wc-clipboard',
'path' => $plugin_url . '/assets/js/admin/wc-clipboard' . $suffix . '.js',
'dependencies' => array( 'jquery' ),
'legacy_handle' => 'select2',
'handle' => 'wc-select2',
'path' => $plugin_url . '/assets/js/select2/select2.full' . $suffix . '.js',
'dependencies' => array( 'jquery' ),
'path' => $plugin_url . '/assets/js/selectWoo/selectWoo.full' . $suffix . '.js',
'dependencies' => array( 'jquery' ),
'handle' => 'wc-enhanced-select',
'path' => $plugin_url . '/assets/js/admin/wc-enhanced-select' . $suffix . '.js',
'dependencies' => array( 'jquery', 'selectWoo' ),
'legacy_handle' => 'js-cookie',
'handle' => 'wc-js-cookie',
'path' => $plugin_url . '/assets/js/js-cookie/js.cookie' . $suffix . '.js',
'dependencies' => array(),
'legacy_handle' => 'dompurify',
'handle' => 'wc-dompurify',
'path' => $plugin_url . '/assets/js/dompurify/purify' . $suffix . '.js',
'dependencies' => array(),
'legacy_handle' => 'accounting',
'handle' => 'wc-accounting',
'path' => $plugin_url . '/assets/js/accounting/accounting' . $suffix . '.js',
'dependencies' => array( 'jquery' ),
* These scripts are registered early to allow other
* plugins to take advantage of them by handle.
public function register_scripts() {
$scripts = $this->get_scripts();
foreach ( $scripts as $script ) {
$script['dependencies'] ?? array(),
$script['version'] ?? null,
$script['args'] ?? array( 'in_footer' => false )
if ( isset( $script['legacy_handle'] ) ) {
$script['legacy_handle'],
array( $script['handle'] ),
$script['version'] ?? null,
'wc_enhanced_select_params',
'i18n_no_matches' => _x( 'No matches found', 'enhanced select', 'woocommerce' ),
'i18n_ajax_error' => _x( 'Loading failed', 'enhanced select', 'woocommerce' ),
'i18n_input_too_short_1' => _x( 'Please enter 1 or more characters', 'enhanced select', 'woocommerce' ),
'i18n_input_too_short_n' => _x( 'Please enter %qty% or more characters', 'enhanced select', 'woocommerce' ),
'i18n_input_too_long_1' => _x( 'Please delete 1 character', 'enhanced select', 'woocommerce' ),
'i18n_input_too_long_n' => _x( 'Please delete %qty% characters', 'enhanced select', 'woocommerce' ),
'i18n_selection_too_long_1' => _x( 'You can only select 1 item', 'enhanced select', 'woocommerce' ),
'i18n_selection_too_long_n' => _x( 'You can only select %qty% items', 'enhanced select', 'woocommerce' ),
'i18n_load_more' => _x( 'Loading more results…', 'enhanced select', 'woocommerce' ),
'i18n_searching' => _x( 'Searching…', 'enhanced select', 'woocommerce' ),
'ajax_url' => admin_url( 'admin-ajax.php' ),
'search_products_nonce' => wp_create_nonce( 'search-products' ),
'search_customers_nonce' => wp_create_nonce( 'search-customers' ),
'search_categories_nonce' => wp_create_nonce( 'search-categories' ),
'search_taxonomy_terms_nonce' => wp_create_nonce( 'search-taxonomy-terms' ),
'search_product_attributes_nonce' => wp_create_nonce( 'search-product-attributes' ),
'search_pages_nonce' => wp_create_nonce( 'search-pages' ),
'search_order_metakeys_nonce' => wp_create_nonce( 'search-order-metakeys' ),
'mon_decimal_point' => wc_get_price_decimal_separator(),
public function admin_scripts() {
global $wp_query, $post, $theorder;
$screen = get_current_screen();
$screen_id = $screen ? $screen->id : '';
$wc_screen_id = 'woocommerce';
$suffix = Constants::is_true( 'SCRIPT_DEBUG' ) ? '' : '.min';
$version = Constants::get_constant( 'WC_VERSION' );
wp_register_script( 'wc-orders', WC()->plugin_url() . '/assets/js/admin/wc-orders' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone', 'wc-jquery-blockui' ), $version, array( 'in_footer' => false ) );
'ajax_url' => admin_url( 'admin-ajax.php' ),
'preview_nonce' => wp_create_nonce( 'woocommerce-preview-order' ),
// WooCommerce admin pages.
if ( in_array( $screen_id, wc_get_screen_ids() ) ) {
wp_enqueue_script( 'iris' );
wp_enqueue_script( 'woocommerce_admin' );
wp_enqueue_script( 'wc-enhanced-select' );
wp_enqueue_script( 'jquery-ui-sortable' );
wp_enqueue_script( 'jquery-ui-autocomplete' );
$decimal_point = isset( $locale['decimal_point'] ) ? $locale['decimal_point'] : '.';
$decimal = ( ! empty( wc_get_price_decimal_separator() ) ) ? wc_get_price_decimal_separator() : $decimal_point;
/* translators: %s: decimal */
'i18n_decimal_error' => sprintf( __( 'Please enter a value with one decimal point (%s) without thousand separators.', 'woocommerce' ), $decimal ),
/* translators: %s: price decimal separator */
'i18n_mon_decimal_error' => sprintf( __( 'Please enter a value with one monetary decimal point (%s) without thousand separators and currency symbols.', 'woocommerce' ), wc_get_price_decimal_separator() ),
'i18n_country_iso_error' => __( 'Please enter in country code with two capital letters.', 'woocommerce' ),
'i18n_sale_less_than_regular_error' => __( 'Please enter in a value less than the regular price.', 'woocommerce' ),
'i18n_delete_product_notice' => __( 'This product has produced sales and may be linked to existing orders. Are you sure you want to delete it?', 'woocommerce' ),
'i18n_remove_personal_data_notice' => __( 'This action cannot be reversed. Are you sure you wish to erase personal data from the selected orders?', 'woocommerce' ),
'i18n_confirm_delete' => __( 'Are you sure you wish to delete this item?', 'woocommerce' ),
'i18n_global_unique_id_error' => __( 'Please enter only numbers and hyphens (-).', 'woocommerce' ),
'decimal_point' => $decimal,
'mon_decimal_point' => wc_get_price_decimal_separator(),
'ajax_url' => admin_url( 'admin-ajax.php' ),
'import_products' => __( 'Import', 'woocommerce' ),
'export_products' => __( 'Export', 'woocommerce' ),
// translators: %d: number of selected products.
'export_selected_products' => __( 'Export %d selected', 'woocommerce' ),
'gateway_toggle' => current_user_can( 'manage_woocommerce' ) ? wp_create_nonce( 'woocommerce-toggle-payment-gateway-enabled' ) : null,
'export_selected_products_nonce' => current_user_can( 'export' ) ? wp_create_nonce( 'export-selected-products' ) : null,
'add_product' => \Automattic\WooCommerce\Utilities\FeaturesUtil::feature_is_enabled( 'product_block_editor' ) ? esc_url_raw( admin_url( 'admin.php?page=wc-admin&path=/add-product' ) ) : null,
'import_products' => current_user_can( 'import' ) ? esc_url_raw( admin_url( 'edit.php?post_type=product&page=product_importer' ) ) : null,
'export_products' => current_user_can( 'export' ) ? esc_url_raw( admin_url( 'edit.php?post_type=product&page=product_exporter' ) ) : null,
wp_localize_script( 'woocommerce_admin', 'woocommerce_admin', $params );
// Edit product category pages.
if ( in_array( $screen_id, array( 'edit-product_cat' ) ) ) {
if ( in_array( $screen_id, array( 'edit-product' ) ) ) {
wp_enqueue_script( 'woocommerce_quick-edit', WC()->plugin_url() . '/assets/js/admin/quick-edit' . $suffix . '.js', array( 'jquery', 'woocommerce_admin' ), $version );
'allow_reviews' => esc_js( __( 'Enable reviews', 'woocommerce' ) ),
wp_localize_script( 'woocommerce_quick-edit', 'woocommerce_quick_edit', $params );
if ( in_array( $screen_id, array( 'product' ), true ) ) {
wp_enqueue_script( 'wc-admin-product-editor', WC()->plugin_url() . '/assets/js/admin/product-editor' . $suffix . '.js', array( 'jquery' ), $version, false );
'wc-admin-product-editor',
'woocommerce_admin_product_editor',
'i18n_description' => esc_js( __( 'Product description', 'woocommerce' ) ),
if ( in_array( $screen_id, array( 'product', 'edit-product' ) ) ) {
wp_register_script( 'wc-admin-product-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-product' . $suffix . '.js', array( 'wc-admin-meta-boxes', 'media-models' ), $version );
wp_register_script( 'wc-admin-variation-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-product-variation' . $suffix . '.js', array( 'wc-admin-meta-boxes', 'wc-serializejson', 'media-models', 'backbone', 'jquery-ui-sortable', 'wc-backbone-modal', 'wp-data', 'wp-notices' ), $version );
wp_enqueue_script( 'wc-admin-product-meta-boxes' );
wp_enqueue_script( 'wc-admin-variation-meta-boxes' );
'post_id' => isset( $post->ID ) ? $post->ID : '',
'plugin_url' => WC()->plugin_url(),
'ajax_url' => admin_url( 'admin-ajax.php' ),
'woocommerce_placeholder_img_src' => wc_placeholder_img_src(),
'add_variation_nonce' => wp_create_nonce( 'add-variation' ),
'link_variation_nonce' => wp_create_nonce( 'link-variations' ),
'delete_variations_nonce' => wp_create_nonce( 'delete-variations' ),