diff --git a/src/wp-includes/l10n.php b/src/wp-includes/l10n.php index 4bcdc4fc4e..bd0110d780 100644 --- a/src/wp-includes/l10n.php +++ b/src/wp-includes/l10n.php @@ -948,20 +948,43 @@ function load_script_textdomain( $handle, $domain = 'default', $path = null ) { $src_url = wp_parse_url( $src ); $content_url = wp_parse_url( content_url() ); + $plugins_url = wp_parse_url( plugins_url() ); $site_url = wp_parse_url( site_url() ); // If the host is the same or it's a relative URL. if ( - strpos( $src_url['path'], $content_url['path'] ) === 0 && + ( ! isset( $content_url['path'] ) || strpos( $src_url['path'], $content_url['path'] ) === 0 ) && ( ! isset( $src_url['host'] ) || $src_url['host'] === $content_url['host'] ) ) { // Make the src relative the specific plugin or theme. - $relative = trim( substr( $src_url['path'], strlen( $content_url['path'] ) ), '/' ); + if ( isset( $content_url['path'] ) ) { + $relative = substr( $src_url['path'], strlen( $content_url['path'] ) ); + } else { + $relative = $src_url['path']; + } + $relative = trim( $relative, '/' ); $relative = explode( '/', $relative ); $languages_path = WP_LANG_DIR . '/' . $relative[0]; - $relative = array_slice( $relative, 2 ); + $relative = array_slice( $relative, 2 ); // Remove plugins/ or themes/. + $relative = implode( '/', $relative ); + } elseif ( + ( ! isset( $plugins_url['path'] ) || strpos( $src_url['path'], $plugins_url['path'] ) === 0 ) && + ( ! isset( $src_url['host'] ) || $src_url['host'] === $plugins_url['host'] ) + ) { + // Make the src relative the specific plugin. + if ( isset( $plugins_url['path'] ) ) { + $relative = substr( $src_url['path'], strlen( $plugins_url['path'] ) ); + } else { + $relative = $src_url['path']; + } + $relative = trim( $relative, '/' ); + $relative = explode( '/', $relative ); + + $languages_path = WP_LANG_DIR . '/plugins'; + + $relative = array_slice( $relative, 1 ); // Remove . $relative = implode( '/', $relative ); } elseif ( ! isset( $src_url['host'] ) || $src_url['host'] === $site_url['host'] ) { if ( ! isset( $site_url['path'] ) ) { diff --git a/tests/phpunit/tests/l10n/loadScriptTextdomain.php b/tests/phpunit/tests/l10n/loadScriptTextdomain.php index 73bc53b333..310cc72bea 100644 --- a/tests/phpunit/tests/l10n/loadScriptTextdomain.php +++ b/tests/phpunit/tests/l10n/loadScriptTextdomain.php @@ -17,6 +17,14 @@ class Tests_L10n_loadScriptTextdomain extends WP_UnitTestCase { return $relative; } + public function plugins_url_custom_domain() { + return 'https://plugins.example.com'; + } + + public function content_url_custom_domain_with_no_path() { + return 'https://content.example.com'; + } + /** * @ticket 45528 */ @@ -38,4 +46,28 @@ class Tests_L10n_loadScriptTextdomain extends WP_UnitTestCase { $this->assertEquals( $json_translations, load_script_textdomain( 'test-example-subdir', 'default', DIR_TESTDATA . '/languages' ) ); remove_filter( 'site_url', array( $this, 'site_url_subdirectory' ) ); } + + /** + * @ticket 46336 + */ + public function test_resolve_relative_path_custom_plugins_url() { + $json_translations = file_get_contents( DIR_TESTDATA . '/languages/plugins/internationalized-plugin-en_US-2f86cb96a0233e7cb3b6f03ad573be0b.json' ); + + add_filter( 'plugins_url', array( $this, 'plugins_url_custom_domain' ) ); + wp_enqueue_script( 'plugin-example-1', 'https://plugins.example.com/my-plugin/js/script.js', array(), null ); + $this->assertEquals( $json_translations, load_script_textdomain( 'plugin-example-1', 'internationalized-plugin', DIR_TESTDATA . '/languages' ) ); + remove_filter( 'plugins_url', array( $this, 'plugins_url_custom_domain' ) ); + } + + /** + * @ticket 46387 + */ + public function test_resolve_relative_path_custom_content_url() { + $json_translations = file_get_contents( DIR_TESTDATA . '/languages/plugins/internationalized-plugin-en_US-2f86cb96a0233e7cb3b6f03ad573be0b.json' ); + + add_filter( 'content_url', array( $this, 'content_url_custom_domain_with_no_path' ) ); + wp_enqueue_script( 'plugin-example-2', 'https://content.example.com/plugins/my-plugin/js/script.js', array(), null ); + $this->assertEquals( $json_translations, load_script_textdomain( 'plugin-example-2', 'internationalized-plugin', DIR_TESTDATA . '/languages' ) ); + remove_filter( 'content_url', array( $this, 'content_url_custom_domain_with_no_path' ) ); + } }