Skip to content

Commit 0f349bd

Browse files
committed
I18N: Fix JavaScript translations for subdirectory installations.
Fixes the `load_script_textdomain` function not resolving the md5 hash based on the relative path for WordPress installations in a subdirectory. Also adds a filter to allow sites using CDNs or other alternative asset locations to filter the relative path resolution. Props akirk, fierevere, swissspidy, mypacecreator, babaevan, tmatsuur, ocean90, herregroen. Merges [44209] to trunk. Fixes #45528. git-svn-id: https://develop.svn.wordpress.org/trunk@44310 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 80c1e36 commit 0f349bd

2 files changed

Lines changed: 65 additions & 6 deletions

File tree

src/wp-includes/l10n.php

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,10 @@ function load_child_theme_textdomain( $domain, $path = false ) {
912912
function load_script_textdomain( $handle, $domain, $path = null ) {
913913
global $wp_scripts;
914914

915+
if ( ! isset( $wp_scripts->registered[ $handle ] ) ) {
916+
return false;
917+
}
918+
915919
$path = untrailingslashit( $path );
916920
$locale = determine_locale();
917921

@@ -924,8 +928,12 @@ function load_script_textdomain( $handle, $domain, $path = null ) {
924928

925929
$obj = $wp_scripts->registered[ $handle ];
926930

931+
$src = $obj->src;
932+
if ( ! preg_match( '|^(https?:)?//|', $src ) && ! ( $wp_scripts->content_url && 0 === strpos( $src, $wp_scripts->content_url ) ) ) {
933+
$src = $wp_scripts->base_url . $src;
934+
}
927935
/** This filter is documented in wp-includes/class.wp-scripts.php */
928-
$src = esc_url( apply_filters( 'script_loader_src', $obj->src, $handle ) );
936+
$src = esc_url( apply_filters( 'script_loader_src', $src, $handle ) );
929937

930938
$relative = false;
931939
$languages_path = WP_LANG_DIR;
@@ -937,26 +945,36 @@ function load_script_textdomain( $handle, $domain, $path = null ) {
937945
// If the host is the same or it's a relative URL.
938946
if (
939947
strpos( $src_url['path'], $content_url['path'] ) === 0 &&
940-
( ! isset( $src_url['host'] ) || $src_url['host'] !== $content_url['host'] )
948+
( ! isset( $src_url['host'] ) || $src_url['host'] === $content_url['host'] )
941949
) {
942950
// Make the src relative the specific plugin or theme.
943-
$relative = trim( substr( $src, strlen( $content_url['path'] ) ), '/' );
951+
$relative = trim( substr( $src_url['path'], strlen( $content_url['path'] ) ), '/' );
944952
$relative = explode( '/', $relative );
945953

946954
$languages_path = WP_LANG_DIR . '/' . $relative[0];
947955

948956
$relative = array_slice( $relative, 2 );
949957
$relative = implode( '/', $relative );
950-
} elseif ( ! isset( $src_url['host'] ) || $src_url['host'] !== $site_url['host'] ) {
958+
} elseif ( ! isset( $src_url['host'] ) || $src_url['host'] === $site_url['host'] ) {
951959
if ( ! isset( $site_url['path'] ) ) {
952960
$relative = trim( $src_url['path'], '/' );
953-
} elseif ( ( strpos( $src_url['path'], $site_url['path'] ) === 0 ) ) {
961+
} elseif ( ( strpos( $src_url['path'], trailingslashit( $site_url['path'] ) ) === 0 ) ) {
954962
// Make the src relative to the WP root.
955-
$relative = substr( $src, strlen( $site_url['path'] ) );
963+
$relative = substr( $src_url['path'], strlen( $site_url['path'] ) );
956964
$relative = trim( $relative, '/' );
957965
}
958966
}
959967

968+
/**
969+
* Filters the relative path of scripts used for finding translation files.
970+
*
971+
* @since 5.0.2
972+
*
973+
* @param string $relative The relative path of the script. False if it could not be determined.
974+
* @param string $src The full source url of the script.
975+
*/
976+
$relative = apply_filters( 'load_script_textdomain_relative_path', $relative, $src );
977+
960978
// If the source is not from WP.
961979
if ( false === $relative ) {
962980
return false;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
/**
4+
* @group l10n
5+
* @group i18n
6+
*/
7+
class Tests_L10n_loadScriptTextdomain extends WP_UnitTestCase {
8+
public function site_url_subdirectory( $site_url ) {
9+
return $site_url . '/wp';
10+
}
11+
12+
public function relative_path_from_cdn( $relative, $src ) {
13+
if ( 0 === strpos( $src, 'https://my-cdn.com/wordpress/' ) ) {
14+
return substr( $src, strlen( 'https://my-cdn.com/wordpress/' ) );
15+
}
16+
17+
return $relative;
18+
}
19+
20+
/**
21+
* @ticket 45528
22+
*/
23+
public function test_resolve_relative_path() {
24+
$json_translations = file_get_contents( DIR_TESTDATA . '/languages/en_US-813e104eb47e13dd4cc5af844c618754.json' );
25+
26+
wp_enqueue_script( 'test-example-root', '/wp-includes/js/script.js', array(), null );
27+
$this->assertEquals( $json_translations, load_script_textdomain( 'test-example-root', 'default', DIR_TESTDATA . '/languages' ) );
28+
29+
// Assets on a CDN.
30+
add_filter( 'load_script_textdomain_relative_path', array( $this, 'relative_path_from_cdn' ), 10, 2 );
31+
wp_enqueue_script( 'test-example-cdn', 'https://my-cdn.com/wordpress/wp-includes/js/script.js', array(), null );
32+
$this->assertEquals( $json_translations, load_script_textdomain( 'test-example-cdn', 'default', DIR_TESTDATA . '/languages' ) );
33+
remove_filter( 'load_script_textdomain_relative_path', array( $this, 'relative_path_from_cdn' ) );
34+
35+
// Test for WordPress installs in a subdirectory.
36+
add_filter( 'site_url', array( $this, 'site_url_subdirectory' ) );
37+
wp_enqueue_script( 'test-example-subdir', '/wp/wp-includes/js/script.js', array(), null );
38+
$this->assertEquals( $json_translations, load_script_textdomain( 'test-example-subdir', 'default', DIR_TESTDATA . '/languages' ) );
39+
remove_filter( 'site_url', array( $this, 'site_url_subdirectory' ) );
40+
}
41+
}

0 commit comments

Comments
 (0)