From e1a8c929b521e692f4648878e47afea11d55950d Mon Sep 17 00:00:00 2001 From: Deepak Prajapati Date: Mon, 24 Nov 2025 17:04:56 +0530 Subject: [PATCH 01/15] Script Modules: Add warning when enqueued with missing dependencies. --- src/wp-includes/class-wp-script-modules.php | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-script-modules.php b/src/wp-includes/class-wp-script-modules.php index 6a919e2625125..403b5e672745a 100644 --- a/src/wp-includes/class-wp-script-modules.php +++ b/src/wp-includes/class-wp-script-modules.php @@ -722,7 +722,26 @@ private function sort_item_dependencies( string $id, array $import_types, array } // If the item requires dependencies that do not exist, fail. - if ( count( array_diff( $dependency_ids, array_keys( $this->registered ) ) ) > 0 ) { + $missing_dependencies = array_diff( $dependency_ids, array_keys( $this->registered ) ); + if ( count( $missing_dependencies ) > 0 ) { + // Prevent duplicate notices. + static $reported = array(); + + if ( ! isset( $reported[ $id ] ) ) { + $reported[ $id ] = true; + + _doing_it_wrong( + __METHOD__, + sprintf( + /* translators: 1: Script module ID, 2: Comma-separated list of missing dependency IDs. */ + __( 'The script module %1$s was enqueued with dependencies that are not registered: %2$s.' ), + $id, + implode( ', ', $missing_dependencies ) + ), + '7.0.0' + ); + } + return false; } From bc18fd010a3e44440be8c6adf158a451d6ac14ee Mon Sep 17 00:00:00 2001 From: Deepak Prajapati Date: Mon, 24 Nov 2025 17:06:37 +0530 Subject: [PATCH 02/15] Scripts: Add warning when enqueued with missing dependencies. --- src/wp-includes/class-wp-dependencies.php | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-dependencies.php b/src/wp-includes/class-wp-dependencies.php index f0c1aaa371ed0..adb9f35a2a037 100644 --- a/src/wp-includes/class-wp-dependencies.php +++ b/src/wp-includes/class-wp-dependencies.php @@ -200,9 +200,27 @@ public function all_deps( $handles, $recursion = false, $group = false ) { } $keep_going = true; + $missing_dependencies = ( isset( $this->registered[ $handle ] ) && $this->registered[ $handle ]->deps ) ? array_diff( $this->registered[ $handle ]->deps, array_keys( $this->registered ) ) : array(); if ( ! isset( $this->registered[ $handle ] ) ) { $keep_going = false; // Item doesn't exist. - } elseif ( $this->registered[ $handle ]->deps && array_diff( $this->registered[ $handle ]->deps, array_keys( $this->registered ) ) ) { + } elseif ( $missing_dependencies ) { + // Prevent duplicate notices. + static $reported = array(); + + if ( ! isset( $reported[ $handle ] ) ) { + $reported[ $handle ] = true; + + _doing_it_wrong( + __METHOD__, + sprintf( + /* translators: 1: Script module ID, 2: Comma-separated list of missing dependency IDs. */ + __( 'The script with the handle %1$s was enqueued with dependencies that are not registered: %2$s.' ), + $handle, + implode( ', ', $missing_dependencies ) + ), + '7.0.0' + ); + } $keep_going = false; // Item requires dependencies that don't exist. } elseif ( $this->registered[ $handle ]->deps && ! $this->all_deps( $this->registered[ $handle ]->deps, true, $new_group ) ) { $keep_going = false; // Item requires dependencies that don't exist. From 29772afcd3557dce85252946e10eee7da56714d7 Mon Sep 17 00:00:00 2001 From: Deepak Prajapati Date: Tue, 25 Nov 2025 15:14:23 +0530 Subject: [PATCH 03/15] Tests: Add doing_it_wrong() check for missing classic script dependencies --- tests/phpunit/tests/dependencies/scripts.php | 29 ++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/phpunit/tests/dependencies/scripts.php b/tests/phpunit/tests/dependencies/scripts.php index cf6960099cb6c..43e258c782bc7 100644 --- a/tests/phpunit/tests/dependencies/scripts.php +++ b/tests/phpunit/tests/dependencies/scripts.php @@ -4093,4 +4093,33 @@ public function test_print_translations_no_display_no_sourceurl() { $translations_script_data = $wp_scripts->print_translations( 'test-example', false ); $this->assertStringNotContainsStringIgnoringCase( 'sourceURL=', $translations_script_data ); } + + /** + * Tests that WP_Scripts emits a _doing_it_wrong() notice for missing dependencies. + * + * @ticket 64229 + * @covers WP_Dependencies::all_deps + */ + public function test_wp_scripts_doing_it_wrong_for_missing_dependencies() { + $expected_key = 'WP_Dependencies::all_deps'; + $this->setExpectedIncorrectUsage( $expected_key ); + + wp_register_script( 'registered-dep', '/registered-dep.js' ); + wp_register_script( 'main', '/main.js', array( 'registered-dep', 'missing-dep' ) ); + wp_enqueue_script( 'main' ); + + get_echo( 'wp_print_scripts' ); + + $this->assertArrayHasKey( + $expected_key, + $this->caught_doing_it_wrong, + 'Expected WP_Dependencies::all_deps to trigger a _doing_it_wrong() notice for missing dependency.' + ); + + $this->assertStringContainsString( + 'The script with the handle main was enqueued with dependencies that are not registered: missing-dep', + $this->caught_doing_it_wrong[ $expected_key ], + 'Expected _doing_it_wrong() notice to indicate missing dependencies for enqueued script.' + ); + } } From 5c80d7990761139eb611fcd51f7eeb747fc5db40 Mon Sep 17 00:00:00 2001 From: Deepak Prajapati Date: Tue, 25 Nov 2025 15:57:32 +0530 Subject: [PATCH 04/15] Tests: Add doing_it_wrong() test for missing script module dependencies --- .../tests/script-modules/wpScriptModules.php | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/phpunit/tests/script-modules/wpScriptModules.php b/tests/phpunit/tests/script-modules/wpScriptModules.php index f253dec49fc7d..94640b6c7973c 100644 --- a/tests/phpunit/tests/script-modules/wpScriptModules.php +++ b/tests/phpunit/tests/script-modules/wpScriptModules.php @@ -1965,6 +1965,9 @@ public function test_script_module_printing_and_dependency_ordering( bool $use_g global $wp_version; $wp_version = '99.9.9'; + if ( $use_global_function && $only_enqueue ) { + $this->setExpectedIncorrectUsage( 'WP_Script_Modules::sort_item_dependencies' ); + } $register = static function ( ...$args ) use ( $use_global_function ) { if ( $use_global_function ) { wp_register_script_module( ...$args ); @@ -2312,4 +2315,31 @@ public function test_static_import_dependency_with_dynamic_imports_depending_on_ "Expected script modules to match snapshot:\n$script_modules" ); } + + /** + * Tests that a missing script module dependency triggers a _doing_it_wrong() notice. + * + * @ticket 64229 + * @covers WP_Script_Modules::sort_item_dependencies + */ + public function test_missing_script_module_dependency_triggers_incorrect_usage() { + $this->setExpectedIncorrectUsage( 'WP_Script_Modules::sort_item_dependencies' ); + + $this->script_modules->register( 'main-module', '/main-module.js', array( 'missing-mod-dep' ) ); + $this->script_modules->enqueue( 'main-module' ); + + get_echo( array( $this->script_modules, 'print_enqueued_script_modules' ) ); + + $this->assertArrayHasKey( + 'WP_Script_Modules::sort_item_dependencies', + $this->caught_doing_it_wrong, + 'Expected WP_Script_Modules::sort_item_dependencies to be reported via doing_it_wrong().' + ); + + // Assert the message mentions the missing dependency handle. + $this->assertStringContainsString( + 'The script module main-module was enqueued with dependencies that are not registered: missing-mod-dep', + $this->caught_doing_it_wrong['WP_Script_Modules::sort_item_dependencies'] + ); + } } From 7a688c78deb7bf52d09c2bdad57a09e8d0a6a2da Mon Sep 17 00:00:00 2001 From: Deepak Prajapati Date: Tue, 25 Nov 2025 16:03:37 +0530 Subject: [PATCH 05/15] Refactor missing-dependencies check for readability --- src/wp-includes/class-wp-dependencies.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/class-wp-dependencies.php b/src/wp-includes/class-wp-dependencies.php index adb9f35a2a037..03d4a6ddcacba 100644 --- a/src/wp-includes/class-wp-dependencies.php +++ b/src/wp-includes/class-wp-dependencies.php @@ -199,8 +199,11 @@ public function all_deps( $handles, $recursion = false, $group = false ) { continue; } - $keep_going = true; - $missing_dependencies = ( isset( $this->registered[ $handle ] ) && $this->registered[ $handle ]->deps ) ? array_diff( $this->registered[ $handle ]->deps, array_keys( $this->registered ) ) : array(); + $keep_going = true; + $missing_dependencies = array(); + if ( isset( $this->registered[ $handle ] ) && $this->registered[ $handle ]->deps ) { + $missing_dependencies = array_diff( $this->registered[ $handle ]->deps, array_keys( $this->registered ) ); + } if ( ! isset( $this->registered[ $handle ] ) ) { $keep_going = false; // Item doesn't exist. } elseif ( $missing_dependencies ) { From 92959701944979de323bbe748427140ee5b9fba0 Mon Sep 17 00:00:00 2001 From: Deepak Prajapati Date: Tue, 25 Nov 2025 16:25:16 +0530 Subject: [PATCH 06/15] fix phpcs error --- tests/phpunit/tests/script-modules/wpScriptModules.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/phpunit/tests/script-modules/wpScriptModules.php b/tests/phpunit/tests/script-modules/wpScriptModules.php index 94640b6c7973c..9b7c77e7229c0 100644 --- a/tests/phpunit/tests/script-modules/wpScriptModules.php +++ b/tests/phpunit/tests/script-modules/wpScriptModules.php @@ -2337,9 +2337,9 @@ public function test_missing_script_module_dependency_triggers_incorrect_usage() ); // Assert the message mentions the missing dependency handle. - $this->assertStringContainsString( - 'The script module main-module was enqueued with dependencies that are not registered: missing-mod-dep', - $this->caught_doing_it_wrong['WP_Script_Modules::sort_item_dependencies'] + $this->assertStringContainsString( + 'The script module main-module was enqueued with dependencies that are not registered: missing-mod-dep', + $this->caught_doing_it_wrong['WP_Script_Modules::sort_item_dependencies'] ); } } From 4d06b0f2153dfea2fd920258c468097fc59d9948 Mon Sep 17 00:00:00 2001 From: Deepak Prajapati Date: Wed, 26 Nov 2025 14:58:04 +0530 Subject: [PATCH 07/15] Tests: Add doing_it_wrong() test for missing wp_styles dependencies --- tests/phpunit/tests/dependencies/styles.php | 33 +++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/phpunit/tests/dependencies/styles.php b/tests/phpunit/tests/dependencies/styles.php index c9aed449da139..1ebb39b492d48 100644 --- a/tests/phpunit/tests/dependencies/styles.php +++ b/tests/phpunit/tests/dependencies/styles.php @@ -814,4 +814,37 @@ public function test_source_url_with_concat() { $this->assertEqualHTML( $expected, $printed ); } + + /** + * Tests that WP_Styles emits a _doing_it_wrong() notice for missing dependencies. + * + * @ticket 64229 + * @covers WP_Dependencies::all_deps + */ + public function test_wp_style_doing_it_wrong_for_missing_dependencies() { + $expected_key = 'WP_Dependencies::all_deps'; + $this->setExpectedIncorrectUsage( $expected_key ); + + wp_register_style( + 'main-style', + '/main-style.css', + array( 'missing-style-dep' ) + ); + + wp_enqueue_style( 'main-style' ); + + get_echo( 'wp_print_styles' ); + + $this->assertArrayHasKey( + $expected_key, + $this->caught_doing_it_wrong, + 'Expected WP_Dependencies::all_deps to trigger a _doing_it_wrong() notice for missing dependency.' + ); + + $this->assertStringContainsString( + 'The style with the handle main-style was enqueued with dependencies that are not registered: missing-style-dep', + $this->caught_doing_it_wrong[ $expected_key ], + 'Expected _doing_it_wrong() notice to indicate missing dependencies for enqueued styles.' + ); + } } From f5cc8d16564756895a31dcaa692f8da4cf739f62 Mon Sep 17 00:00:00 2001 From: Deepak Prajapati Date: Wed, 26 Nov 2025 14:58:53 +0530 Subject: [PATCH 08/15] add get_dependency_warning_message() helper to WP_Dependencies, override in WP_Scripts/WP_Styles --- src/wp-includes/class-wp-dependencies.php | 44 +++++++++++++---------- src/wp-includes/class-wp-scripts.php | 18 ++++++++++ src/wp-includes/class-wp-styles.php | 18 ++++++++++ 3 files changed, 61 insertions(+), 19 deletions(-) diff --git a/src/wp-includes/class-wp-dependencies.php b/src/wp-includes/class-wp-dependencies.php index 03d4a6ddcacba..b315a75def967 100644 --- a/src/wp-includes/class-wp-dependencies.php +++ b/src/wp-includes/class-wp-dependencies.php @@ -201,29 +201,17 @@ public function all_deps( $handles, $recursion = false, $group = false ) { $keep_going = true; $missing_dependencies = array(); - if ( isset( $this->registered[ $handle ] ) && $this->registered[ $handle ]->deps ) { + if ( isset( $this->registered[ $handle ] ) && count( $this->registered[ $handle ]->deps ) > 0 ) { $missing_dependencies = array_diff( $this->registered[ $handle ]->deps, array_keys( $this->registered ) ); } if ( ! isset( $this->registered[ $handle ] ) ) { $keep_going = false; // Item doesn't exist. - } elseif ( $missing_dependencies ) { - // Prevent duplicate notices. - static $reported = array(); - - if ( ! isset( $reported[ $handle ] ) ) { - $reported[ $handle ] = true; - - _doing_it_wrong( - __METHOD__, - sprintf( - /* translators: 1: Script module ID, 2: Comma-separated list of missing dependency IDs. */ - __( 'The script with the handle %1$s was enqueued with dependencies that are not registered: %2$s.' ), - $handle, - implode( ', ', $missing_dependencies ) - ), - '7.0.0' - ); - } + } elseif ( count( $missing_dependencies ) > 0 ) { + _doing_it_wrong( + __METHOD__, + $this->get_dependency_warning_message( $handle, $missing_dependencies ), + '7.0.0' + ); $keep_going = false; // Item requires dependencies that don't exist. } elseif ( $this->registered[ $handle ]->deps && ! $this->all_deps( $this->registered[ $handle ]->deps, true, $new_group ) ) { $keep_going = false; // Item requires dependencies that don't exist. @@ -556,4 +544,22 @@ public function get_etag( $load ) { */ return 'W/"' . md5( $etag ) . '"'; } + + /** + * Gets a dependency warning message for a handle. + * + * @since 7.0.0 + * + * @param string $handle Handle with missing dependencies. + * @param string[] $missing_dependency_handles Missing dependency handles. + * @return string Formatted, localized warning message. + */ + protected function get_dependency_warning_message( $handle, $missing_dependency_handles ) { + return sprintf( + /* translators: 1: Handle, 2: Comma-separated list of missing dependency handles. */ + __( 'The handle %1$s was enqueued with dependencies that are not registered: %2$s.' ), + $handle, + implode( ', ', $missing_dependency_handles ) + ); + } } diff --git a/src/wp-includes/class-wp-scripts.php b/src/wp-includes/class-wp-scripts.php index b15bd3f8e904e..114e9ce980664 100644 --- a/src/wp-includes/class-wp-scripts.php +++ b/src/wp-includes/class-wp-scripts.php @@ -1164,4 +1164,22 @@ public function reset() { $this->ext_version = ''; $this->ext_handles = ''; } + + /** + * Gets a script-specific dependency warning message. + * + * @since 7.0.0 + * + * @param string $handle Script handle with missing dependencies. + * @param string[] $missing_dependency_handles Missing dependency handles. + * @return string Formatted, localized warning message. + */ + protected function get_dependency_warning_message( $handle, $missing_dependency_handles ) { + return sprintf( + /* translators: 1: Script handle, 2: Comma-separated list of missing dependency handles. */ + __( 'The script with the handle %1$s was enqueued with dependencies that are not registered: %2$s.' ), + $handle, + implode( ', ', $missing_dependency_handles ) + ); + } } diff --git a/src/wp-includes/class-wp-styles.php b/src/wp-includes/class-wp-styles.php index 9d6d5b5dd2460..4df72cd1d6d95 100644 --- a/src/wp-includes/class-wp-styles.php +++ b/src/wp-includes/class-wp-styles.php @@ -493,4 +493,22 @@ public function reset() { $this->concat_version = ''; $this->print_html = ''; } + + /** + * Gets a style-specific dependency warning message. + * + * @since 7.0.0 + * + * @param string $handle Style handle with missing dependencies. + * @param string[] $missing_dependency_handles Missing dependency handles. + * @return string Formatted, localized warning message. + */ + protected function get_dependency_warning_message( $handle, $missing_dependency_handles ) { + return sprintf( + /* translators: 1: Style handle, 2: Comma-separated list of missing dependency handles. */ + __( 'The style with the handle %1$s was enqueued with dependencies that are not registered: %2$s.' ), + $handle, + implode( ', ', $missing_dependency_handles ) + ); + } } From 3706e96f3fe45c48710539625b784fe763ddd3cc Mon Sep 17 00:00:00 2001 From: Deepak Prajapati Date: Wed, 26 Nov 2025 15:15:25 +0530 Subject: [PATCH 09/15] Remove logic that suppressed duplicate dependency warnings --- src/wp-includes/class-wp-script-modules.php | 27 +++++++------------ .../tests/script-modules/wpScriptModules.php | 4 +-- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/src/wp-includes/class-wp-script-modules.php b/src/wp-includes/class-wp-script-modules.php index 403b5e672745a..2b70b1bd15298 100644 --- a/src/wp-includes/class-wp-script-modules.php +++ b/src/wp-includes/class-wp-script-modules.php @@ -724,23 +724,16 @@ private function sort_item_dependencies( string $id, array $import_types, array // If the item requires dependencies that do not exist, fail. $missing_dependencies = array_diff( $dependency_ids, array_keys( $this->registered ) ); if ( count( $missing_dependencies ) > 0 ) { - // Prevent duplicate notices. - static $reported = array(); - - if ( ! isset( $reported[ $id ] ) ) { - $reported[ $id ] = true; - - _doing_it_wrong( - __METHOD__, - sprintf( - /* translators: 1: Script module ID, 2: Comma-separated list of missing dependency IDs. */ - __( 'The script module %1$s was enqueued with dependencies that are not registered: %2$s.' ), - $id, - implode( ', ', $missing_dependencies ) - ), - '7.0.0' - ); - } + _doing_it_wrong( + __METHOD__, + sprintf( + /* translators: 1: Script module ID, 2: Comma-separated list of missing dependency IDs. */ + __( 'The script module %1$s was enqueued with dependencies that are not registered: %2$s.' ), + $id, + implode( ', ', $missing_dependencies ) + ), + '7.0.0' + ); return false; } diff --git a/tests/phpunit/tests/script-modules/wpScriptModules.php b/tests/phpunit/tests/script-modules/wpScriptModules.php index 9b7c77e7229c0..1463f1eafadd6 100644 --- a/tests/phpunit/tests/script-modules/wpScriptModules.php +++ b/tests/phpunit/tests/script-modules/wpScriptModules.php @@ -1965,9 +1965,7 @@ public function test_script_module_printing_and_dependency_ordering( bool $use_g global $wp_version; $wp_version = '99.9.9'; - if ( $use_global_function && $only_enqueue ) { - $this->setExpectedIncorrectUsage( 'WP_Script_Modules::sort_item_dependencies' ); - } + $this->setExpectedIncorrectUsage( 'WP_Script_Modules::sort_item_dependencies' ); $register = static function ( ...$args ) use ( $use_global_function ) { if ( $use_global_function ) { wp_register_script_module( ...$args ); From 0d28424c32fe49c161731f886f035130134c8310 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 29 Nov 2025 15:03:22 -0800 Subject: [PATCH 10/15] Add double quotes around handle/ID in warning --- src/wp-includes/class-wp-dependencies.php | 2 +- src/wp-includes/class-wp-script-modules.php | 2 +- src/wp-includes/class-wp-scripts.php | 2 +- src/wp-includes/class-wp-styles.php | 2 +- tests/phpunit/tests/dependencies/scripts.php | 5 +++-- tests/phpunit/tests/dependencies/styles.php | 5 +++-- tests/phpunit/tests/script-modules/wpScriptModules.php | 5 +++-- 7 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/wp-includes/class-wp-dependencies.php b/src/wp-includes/class-wp-dependencies.php index 6a826271eae26..f8a26ff05b64c 100644 --- a/src/wp-includes/class-wp-dependencies.php +++ b/src/wp-includes/class-wp-dependencies.php @@ -557,7 +557,7 @@ public function get_etag( $load ) { protected function get_dependency_warning_message( $handle, $missing_dependency_handles ) { return sprintf( /* translators: 1: Handle, 2: Comma-separated list of missing dependency handles. */ - __( 'The handle %1$s was enqueued with dependencies that are not registered: %2$s.' ), + __( 'The handle "%1$s" was enqueued with dependencies that are not registered: %2$s.' ), $handle, implode( ', ', $missing_dependency_handles ) ); diff --git a/src/wp-includes/class-wp-script-modules.php b/src/wp-includes/class-wp-script-modules.php index 2b70b1bd15298..5ade9dfb6ac0f 100644 --- a/src/wp-includes/class-wp-script-modules.php +++ b/src/wp-includes/class-wp-script-modules.php @@ -728,7 +728,7 @@ private function sort_item_dependencies( string $id, array $import_types, array __METHOD__, sprintf( /* translators: 1: Script module ID, 2: Comma-separated list of missing dependency IDs. */ - __( 'The script module %1$s was enqueued with dependencies that are not registered: %2$s.' ), + __( 'The script module "%1$s" was enqueued with dependencies that are not registered: %2$s.' ), $id, implode( ', ', $missing_dependencies ) ), diff --git a/src/wp-includes/class-wp-scripts.php b/src/wp-includes/class-wp-scripts.php index 114e9ce980664..a30b09249fd52 100644 --- a/src/wp-includes/class-wp-scripts.php +++ b/src/wp-includes/class-wp-scripts.php @@ -1177,7 +1177,7 @@ public function reset() { protected function get_dependency_warning_message( $handle, $missing_dependency_handles ) { return sprintf( /* translators: 1: Script handle, 2: Comma-separated list of missing dependency handles. */ - __( 'The script with the handle %1$s was enqueued with dependencies that are not registered: %2$s.' ), + __( 'The script with the handle "%1$s" was enqueued with dependencies that are not registered: %2$s.' ), $handle, implode( ', ', $missing_dependency_handles ) ); diff --git a/src/wp-includes/class-wp-styles.php b/src/wp-includes/class-wp-styles.php index 4df72cd1d6d95..67fb3a0fd40e1 100644 --- a/src/wp-includes/class-wp-styles.php +++ b/src/wp-includes/class-wp-styles.php @@ -506,7 +506,7 @@ public function reset() { protected function get_dependency_warning_message( $handle, $missing_dependency_handles ) { return sprintf( /* translators: 1: Style handle, 2: Comma-separated list of missing dependency handles. */ - __( 'The style with the handle %1$s was enqueued with dependencies that are not registered: %2$s.' ), + __( 'The style with the handle "%1$s" was enqueued with dependencies that are not registered: %2$s.' ), $handle, implode( ', ', $missing_dependency_handles ) ); diff --git a/tests/phpunit/tests/dependencies/scripts.php b/tests/phpunit/tests/dependencies/scripts.php index 43e258c782bc7..40d1b28e0599b 100644 --- a/tests/phpunit/tests/dependencies/scripts.php +++ b/tests/phpunit/tests/dependencies/scripts.php @@ -4108,7 +4108,8 @@ public function test_wp_scripts_doing_it_wrong_for_missing_dependencies() { wp_register_script( 'main', '/main.js', array( 'registered-dep', 'missing-dep' ) ); wp_enqueue_script( 'main' ); - get_echo( 'wp_print_scripts' ); + $markup = get_echo( 'wp_print_scripts' ); + $this->assertStringNotContainsString( 'main.js', $markup, 'Expected script to be absent.' ); $this->assertArrayHasKey( $expected_key, @@ -4117,7 +4118,7 @@ public function test_wp_scripts_doing_it_wrong_for_missing_dependencies() { ); $this->assertStringContainsString( - 'The script with the handle main was enqueued with dependencies that are not registered: missing-dep', + 'The script with the handle "main" was enqueued with dependencies that are not registered: missing-dep', $this->caught_doing_it_wrong[ $expected_key ], 'Expected _doing_it_wrong() notice to indicate missing dependencies for enqueued script.' ); diff --git a/tests/phpunit/tests/dependencies/styles.php b/tests/phpunit/tests/dependencies/styles.php index 1ebb39b492d48..cc5f3efc17f17 100644 --- a/tests/phpunit/tests/dependencies/styles.php +++ b/tests/phpunit/tests/dependencies/styles.php @@ -833,7 +833,8 @@ public function test_wp_style_doing_it_wrong_for_missing_dependencies() { wp_enqueue_style( 'main-style' ); - get_echo( 'wp_print_styles' ); + $markup = get_echo( 'wp_print_styles' ); + $this->assertStringNotContainsString( 'main-style.css', $markup, 'Expected style to be absent.' ); $this->assertArrayHasKey( $expected_key, @@ -842,7 +843,7 @@ public function test_wp_style_doing_it_wrong_for_missing_dependencies() { ); $this->assertStringContainsString( - 'The style with the handle main-style was enqueued with dependencies that are not registered: missing-style-dep', + 'The style with the handle "main-style" was enqueued with dependencies that are not registered: missing-style-dep', $this->caught_doing_it_wrong[ $expected_key ], 'Expected _doing_it_wrong() notice to indicate missing dependencies for enqueued styles.' ); diff --git a/tests/phpunit/tests/script-modules/wpScriptModules.php b/tests/phpunit/tests/script-modules/wpScriptModules.php index 1463f1eafadd6..793b586ccb3ea 100644 --- a/tests/phpunit/tests/script-modules/wpScriptModules.php +++ b/tests/phpunit/tests/script-modules/wpScriptModules.php @@ -2326,7 +2326,8 @@ public function test_missing_script_module_dependency_triggers_incorrect_usage() $this->script_modules->register( 'main-module', '/main-module.js', array( 'missing-mod-dep' ) ); $this->script_modules->enqueue( 'main-module' ); - get_echo( array( $this->script_modules, 'print_enqueued_script_modules' ) ); + $markup = get_echo( array( $this->script_modules, 'print_enqueued_script_modules' ) ); + $this->assertStringNotContainsString( 'main-module.js', $markup, 'Expected script module to be absent.' ); $this->assertArrayHasKey( 'WP_Script_Modules::sort_item_dependencies', @@ -2336,7 +2337,7 @@ public function test_missing_script_module_dependency_triggers_incorrect_usage() // Assert the message mentions the missing dependency handle. $this->assertStringContainsString( - 'The script module main-module was enqueued with dependencies that are not registered: missing-mod-dep', + 'The script module "main-module" was enqueued with dependencies that are not registered: missing-mod-dep', $this->caught_doing_it_wrong['WP_Script_Modules::sort_item_dependencies'] ); } From 1070c33d2a35ebce865f19c805ec774400058e06 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 29 Nov 2025 15:27:24 -0800 Subject: [PATCH 11/15] Avoid duplicate warnings --- src/wp-includes/class-wp-dependencies.php | 25 ++++++++++++---- src/wp-includes/class-wp-script-modules.php | 32 +++++++++++++++------ 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/wp-includes/class-wp-dependencies.php b/src/wp-includes/class-wp-dependencies.php index f8a26ff05b64c..7d2e124126ce5 100644 --- a/src/wp-includes/class-wp-dependencies.php +++ b/src/wp-includes/class-wp-dependencies.php @@ -104,6 +104,18 @@ class WP_Dependencies { */ private $queued_before_register = array(); + /** + * List of IDs for dependencies encountered which themselves have missing dependencies. + * + * A dependency handle is added to this list when it is discovered to have missing dependencies. At this time, a + * warning is emitted with {@see _doing_it_wrong()}. The handle is then added to this list, so that duplicate + * warnings don't occur. + * + * @since 7.0.0 + * @var string[] + */ + private $dependencies_with_missing_dependencies = array(); + /** * Processes the items and dependencies. * @@ -207,11 +219,14 @@ public function all_deps( $handles, $recursion = false, $group = false ) { if ( ! isset( $this->registered[ $handle ] ) ) { $keep_going = false; // Item doesn't exist. } elseif ( count( $missing_dependencies ) > 0 ) { - _doing_it_wrong( - __METHOD__, - $this->get_dependency_warning_message( $handle, $missing_dependencies ), - '7.0.0' - ); + if ( ! in_array( $handle, $this->dependencies_with_missing_dependencies, true ) ) { + _doing_it_wrong( + __METHOD__, + $this->get_dependency_warning_message( $handle, $missing_dependencies ), + '7.0.0' + ); + $this->dependencies_with_missing_dependencies[] = $handle; + } $keep_going = false; // Item requires dependencies that don't exist. } elseif ( $this->registered[ $handle ]->deps && ! $this->all_deps( $this->registered[ $handle ]->deps, true, $new_group ) ) { $keep_going = false; // Item requires dependencies that don't exist. diff --git a/src/wp-includes/class-wp-script-modules.php b/src/wp-includes/class-wp-script-modules.php index 5ade9dfb6ac0f..e32baf022eae2 100644 --- a/src/wp-includes/class-wp-script-modules.php +++ b/src/wp-includes/class-wp-script-modules.php @@ -70,6 +70,17 @@ class WP_Script_Modules { 'high', ); + /** + * List of IDs for script modules encountered which have missing dependencies. + * + * An ID is added to this list when it is discovered to have missing dependencies. At this time, a warning is + * emitted with {@see _doing_it_wrong()}. The ID is then added to this list, so that duplicate warnings don't occur. + * + * @since 7.0.0 + * @var string[] + */ + private $modules_with_missing_dependencies = array(); + /** * Registers the script module if no script module with that script module * identifier has already been registered. @@ -724,16 +735,19 @@ private function sort_item_dependencies( string $id, array $import_types, array // If the item requires dependencies that do not exist, fail. $missing_dependencies = array_diff( $dependency_ids, array_keys( $this->registered ) ); if ( count( $missing_dependencies ) > 0 ) { - _doing_it_wrong( - __METHOD__, - sprintf( + if ( ! in_array( $id, $this->modules_with_missing_dependencies, true ) ) { + _doing_it_wrong( + __METHOD__, + sprintf( /* translators: 1: Script module ID, 2: Comma-separated list of missing dependency IDs. */ - __( 'The script module "%1$s" was enqueued with dependencies that are not registered: %2$s.' ), - $id, - implode( ', ', $missing_dependencies ) - ), - '7.0.0' - ); + __( 'The script module "%1$s" was enqueued with dependencies that are not registered: %2$s.' ), + $id, + implode( ', ', $missing_dependencies ) + ), + '7.0.0' + ); + $this->modules_with_missing_dependencies[] = $id; + } return false; } From 69eaceb54a44b476c910d7639fc0dda5f28b3ed3 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 29 Nov 2025 15:37:08 -0800 Subject: [PATCH 12/15] Use more appropriate methods in _doing_it_wrong() calls --- src/wp-includes/class-wp-dependencies.php | 2 +- src/wp-includes/class-wp-script-modules.php | 4 ++-- tests/phpunit/tests/dependencies/scripts.php | 13 ++++++------- tests/phpunit/tests/dependencies/styles.php | 14 ++++++-------- .../tests/script-modules/wpScriptModules.php | 12 ++++++------ 5 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/wp-includes/class-wp-dependencies.php b/src/wp-includes/class-wp-dependencies.php index 7d2e124126ce5..e0cb8b3ce7a92 100644 --- a/src/wp-includes/class-wp-dependencies.php +++ b/src/wp-includes/class-wp-dependencies.php @@ -221,7 +221,7 @@ public function all_deps( $handles, $recursion = false, $group = false ) { } elseif ( count( $missing_dependencies ) > 0 ) { if ( ! in_array( $handle, $this->dependencies_with_missing_dependencies, true ) ) { _doing_it_wrong( - __METHOD__, + get_class( $this ) . '::add', $this->get_dependency_warning_message( $handle, $missing_dependencies ), '7.0.0' ); diff --git a/src/wp-includes/class-wp-script-modules.php b/src/wp-includes/class-wp-script-modules.php index e32baf022eae2..0c4e3088b3396 100644 --- a/src/wp-includes/class-wp-script-modules.php +++ b/src/wp-includes/class-wp-script-modules.php @@ -737,9 +737,9 @@ private function sort_item_dependencies( string $id, array $import_types, array if ( count( $missing_dependencies ) > 0 ) { if ( ! in_array( $id, $this->modules_with_missing_dependencies, true ) ) { _doing_it_wrong( - __METHOD__, + get_class( $this ) . '::register', sprintf( - /* translators: 1: Script module ID, 2: Comma-separated list of missing dependency IDs. */ + /* translators: 1: Script module ID, 2: Comma-separated list of missing dependency IDs. */ __( 'The script module "%1$s" was enqueued with dependencies that are not registered: %2$s.' ), $id, implode( ', ', $missing_dependencies ) diff --git a/tests/phpunit/tests/dependencies/scripts.php b/tests/phpunit/tests/dependencies/scripts.php index 40d1b28e0599b..a3c8b92695f4f 100644 --- a/tests/phpunit/tests/dependencies/scripts.php +++ b/tests/phpunit/tests/dependencies/scripts.php @@ -4101,25 +4101,24 @@ public function test_print_translations_no_display_no_sourceurl() { * @covers WP_Dependencies::all_deps */ public function test_wp_scripts_doing_it_wrong_for_missing_dependencies() { - $expected_key = 'WP_Dependencies::all_deps'; - $this->setExpectedIncorrectUsage( $expected_key ); + $expected_incorrect_usage = 'WP_Scripts::add'; + $this->setExpectedIncorrectUsage( $expected_incorrect_usage ); wp_register_script( 'registered-dep', '/registered-dep.js' ); - wp_register_script( 'main', '/main.js', array( 'registered-dep', 'missing-dep' ) ); - wp_enqueue_script( 'main' ); + wp_enqueue_script( 'main', '/main.js', array( 'registered-dep', 'missing-dep' ) ); $markup = get_echo( 'wp_print_scripts' ); $this->assertStringNotContainsString( 'main.js', $markup, 'Expected script to be absent.' ); $this->assertArrayHasKey( - $expected_key, + $expected_incorrect_usage, $this->caught_doing_it_wrong, - 'Expected WP_Dependencies::all_deps to trigger a _doing_it_wrong() notice for missing dependency.' + "Expected $expected_incorrect_usage to trigger a _doing_it_wrong() notice for missing dependency." ); $this->assertStringContainsString( 'The script with the handle "main" was enqueued with dependencies that are not registered: missing-dep', - $this->caught_doing_it_wrong[ $expected_key ], + $this->caught_doing_it_wrong[ $expected_incorrect_usage ], 'Expected _doing_it_wrong() notice to indicate missing dependencies for enqueued script.' ); } diff --git a/tests/phpunit/tests/dependencies/styles.php b/tests/phpunit/tests/dependencies/styles.php index cc5f3efc17f17..74e4db47330b4 100644 --- a/tests/phpunit/tests/dependencies/styles.php +++ b/tests/phpunit/tests/dependencies/styles.php @@ -822,29 +822,27 @@ public function test_source_url_with_concat() { * @covers WP_Dependencies::all_deps */ public function test_wp_style_doing_it_wrong_for_missing_dependencies() { - $expected_key = 'WP_Dependencies::all_deps'; - $this->setExpectedIncorrectUsage( $expected_key ); + $expected_incorrect_usage = 'WP_Styles::add'; + $this->setExpectedIncorrectUsage( $expected_incorrect_usage ); - wp_register_style( + wp_enqueue_style( 'main-style', '/main-style.css', array( 'missing-style-dep' ) ); - wp_enqueue_style( 'main-style' ); - $markup = get_echo( 'wp_print_styles' ); $this->assertStringNotContainsString( 'main-style.css', $markup, 'Expected style to be absent.' ); $this->assertArrayHasKey( - $expected_key, + $expected_incorrect_usage, $this->caught_doing_it_wrong, - 'Expected WP_Dependencies::all_deps to trigger a _doing_it_wrong() notice for missing dependency.' + "Expected $expected_incorrect_usage to trigger a _doing_it_wrong() notice for missing dependency." ); $this->assertStringContainsString( 'The style with the handle "main-style" was enqueued with dependencies that are not registered: missing-style-dep', - $this->caught_doing_it_wrong[ $expected_key ], + $this->caught_doing_it_wrong[ $expected_incorrect_usage ], 'Expected _doing_it_wrong() notice to indicate missing dependencies for enqueued styles.' ); } diff --git a/tests/phpunit/tests/script-modules/wpScriptModules.php b/tests/phpunit/tests/script-modules/wpScriptModules.php index 793b586ccb3ea..67c8fb135186b 100644 --- a/tests/phpunit/tests/script-modules/wpScriptModules.php +++ b/tests/phpunit/tests/script-modules/wpScriptModules.php @@ -2321,24 +2321,24 @@ public function test_static_import_dependency_with_dynamic_imports_depending_on_ * @covers WP_Script_Modules::sort_item_dependencies */ public function test_missing_script_module_dependency_triggers_incorrect_usage() { - $this->setExpectedIncorrectUsage( 'WP_Script_Modules::sort_item_dependencies' ); + $expected_incorrect_usage = 'WP_Script_Modules::register'; + $this->setExpectedIncorrectUsage( $expected_incorrect_usage ); - $this->script_modules->register( 'main-module', '/main-module.js', array( 'missing-mod-dep' ) ); - $this->script_modules->enqueue( 'main-module' ); + $this->script_modules->enqueue( 'main-module', '/main-module.js', array( 'missing-mod-dep' ) ); $markup = get_echo( array( $this->script_modules, 'print_enqueued_script_modules' ) ); $this->assertStringNotContainsString( 'main-module.js', $markup, 'Expected script module to be absent.' ); $this->assertArrayHasKey( - 'WP_Script_Modules::sort_item_dependencies', + $expected_incorrect_usage, $this->caught_doing_it_wrong, - 'Expected WP_Script_Modules::sort_item_dependencies to be reported via doing_it_wrong().' + 'Expected WP_Script_Modules::register to be reported via doing_it_wrong().' ); // Assert the message mentions the missing dependency handle. $this->assertStringContainsString( 'The script module "main-module" was enqueued with dependencies that are not registered: missing-mod-dep', - $this->caught_doing_it_wrong['WP_Script_Modules::sort_item_dependencies'] + $this->caught_doing_it_wrong[ $expected_incorrect_usage ] ); } } From a5532442caea7a425b0489dd1e3e04e8165e3402 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 29 Nov 2025 16:13:09 -0800 Subject: [PATCH 13/15] Remove expected deprecation notice by fixing module deregistration --- tests/phpunit/tests/script-modules/wpScriptModules.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/phpunit/tests/script-modules/wpScriptModules.php b/tests/phpunit/tests/script-modules/wpScriptModules.php index 67c8fb135186b..f6c81100f2545 100644 --- a/tests/phpunit/tests/script-modules/wpScriptModules.php +++ b/tests/phpunit/tests/script-modules/wpScriptModules.php @@ -1965,7 +1965,6 @@ public function test_script_module_printing_and_dependency_ordering( bool $use_g global $wp_version; $wp_version = '99.9.9'; - $this->setExpectedIncorrectUsage( 'WP_Script_Modules::sort_item_dependencies' ); $register = static function ( ...$args ) use ( $use_global_function ) { if ( $use_global_function ) { wp_register_script_module( ...$args ); @@ -2060,7 +2059,7 @@ public function test_script_module_printing_and_dependency_ordering( bool $use_g "Snapshot:\n" . var_export( $actual, true ) ); - $deregister( array( 'b', 'c ' ) ); + $deregister( array( 'b', 'c' ) ); // Test that registered dependency in footer doesn't place dependant in footer. $register( 'd', '/d.js', array(), '1.0.0', array( 'in_footer' => true ) ); From b52c39cc5459ed63ae1618956b9acd1bccbcff41 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 29 Nov 2025 16:36:52 -0800 Subject: [PATCH 14/15] Fix reference to handles --- src/wp-includes/class-wp-dependencies.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-dependencies.php b/src/wp-includes/class-wp-dependencies.php index e0cb8b3ce7a92..60c117d2f67b4 100644 --- a/src/wp-includes/class-wp-dependencies.php +++ b/src/wp-includes/class-wp-dependencies.php @@ -105,7 +105,7 @@ class WP_Dependencies { private $queued_before_register = array(); /** - * List of IDs for dependencies encountered which themselves have missing dependencies. + * List of handles for dependencies encountered which themselves have missing dependencies. * * A dependency handle is added to this list when it is discovered to have missing dependencies. At this time, a * warning is emitted with {@see _doing_it_wrong()}. The handle is then added to this list, so that duplicate From 925f49bfe5f9df89fa79ae3ac0503bba492bfa82 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 29 Nov 2025 16:45:06 -0800 Subject: [PATCH 15/15] Improve message consistency --- src/wp-includes/class-wp-script-modules.php | 2 +- tests/phpunit/tests/script-modules/wpScriptModules.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/class-wp-script-modules.php b/src/wp-includes/class-wp-script-modules.php index 0c4e3088b3396..e05e1900a2b49 100644 --- a/src/wp-includes/class-wp-script-modules.php +++ b/src/wp-includes/class-wp-script-modules.php @@ -740,7 +740,7 @@ private function sort_item_dependencies( string $id, array $import_types, array get_class( $this ) . '::register', sprintf( /* translators: 1: Script module ID, 2: Comma-separated list of missing dependency IDs. */ - __( 'The script module "%1$s" was enqueued with dependencies that are not registered: %2$s.' ), + __( 'The script module with the ID "%1$s" was enqueued with dependencies that are not registered: %2$s.' ), $id, implode( ', ', $missing_dependencies ) ), diff --git a/tests/phpunit/tests/script-modules/wpScriptModules.php b/tests/phpunit/tests/script-modules/wpScriptModules.php index f6c81100f2545..c80d1e745779c 100644 --- a/tests/phpunit/tests/script-modules/wpScriptModules.php +++ b/tests/phpunit/tests/script-modules/wpScriptModules.php @@ -2336,7 +2336,7 @@ public function test_missing_script_module_dependency_triggers_incorrect_usage() // Assert the message mentions the missing dependency handle. $this->assertStringContainsString( - 'The script module "main-module" was enqueued with dependencies that are not registered: missing-mod-dep', + 'The script module with the ID "main-module" was enqueued with dependencies that are not registered: missing-mod-dep', $this->caught_doing_it_wrong[ $expected_incorrect_usage ] ); }