mirror of
git://develop.git.wordpress.org/
synced 2025-03-14 17:09:47 +01:00
I18N: Actually add all the files for [58061], not just the test fixtures.
Improve support for using only PHP translation files. This builds on top of the PHP translation file support added in WordPress 6.5, improving the behavior for projects using solely `.l10n.php` translation files and no `.mo.` and `.po` files. Updates `wp_get_installed_translations()`, which is used when updating language packs and when uninstalling plugins/themes (to remove the translations again), to look for PHP translation files and read metadata from them. Additionally, the file lookup is now cached thanks to using `WP_Textdomain_Registry`. Updates `Language_Pack_Upgrader::check_package()` to allow language packs that only contain PHP translation files. While WordPress.org continues to serve `.mo` and `.po` files, third-party services might want to only use the PHP file format. See #60554. git-svn-id: https://develop.svn.wordpress.org/trunk@58062 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
22796f5869
commit
2f0d2dec4c
@ -332,26 +332,34 @@ class Language_Pack_Upgrader extends WP_Upgrader {
|
||||
// Check that the folder contains a valid language.
|
||||
$files = $wp_filesystem->dirlist( $remote_source );
|
||||
|
||||
// Check to see if a .po and .mo exist in the folder.
|
||||
$po = false;
|
||||
$mo = false;
|
||||
// Check to see if the expected files exist in the folder.
|
||||
$po = false;
|
||||
$mo = false;
|
||||
$php = false;
|
||||
foreach ( (array) $files as $file => $filedata ) {
|
||||
if ( str_ends_with( $file, '.po' ) ) {
|
||||
$po = true;
|
||||
} elseif ( str_ends_with( $file, '.mo' ) ) {
|
||||
$mo = true;
|
||||
} elseif ( str_ends_with( $file, '.l10n.php' ) ) {
|
||||
$php = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $php ) {
|
||||
return $source;
|
||||
}
|
||||
|
||||
if ( ! $mo || ! $po ) {
|
||||
return new WP_Error(
|
||||
'incompatible_archive_pomo',
|
||||
$this->strings['incompatible_archive'],
|
||||
sprintf(
|
||||
/* translators: 1: .po, 2: .mo */
|
||||
__( 'The language pack is missing either the %1$s or %2$s files.' ),
|
||||
/* translators: 1: .po, 2: .mo, 3: .l10n.php */
|
||||
__( 'The language pack is missing either the %1$s, %2$s, or %3$s files.' ),
|
||||
'<code>.po</code>',
|
||||
'<code>.mo</code>'
|
||||
'<code>.mo</code>',
|
||||
'<code>.l10n.php</code>'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -1505,25 +1505,25 @@ function get_available_languages( $dir = null ) {
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @global WP_Textdomain_Registry $wp_textdomain_registry WordPress Textdomain Registry.
|
||||
*
|
||||
* @param string $type What to search for. Accepts 'plugins', 'themes', 'core'.
|
||||
* @return array Array of language data.
|
||||
*/
|
||||
function wp_get_installed_translations( $type ) {
|
||||
global $wp_textdomain_registry;
|
||||
|
||||
if ( 'themes' !== $type && 'plugins' !== $type && 'core' !== $type ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$dir = 'core' === $type ? '' : "/$type";
|
||||
$dir = 'core' === $type ? WP_LANG_DIR : WP_LANG_DIR . "/$type";
|
||||
|
||||
if ( ! is_dir( WP_LANG_DIR ) ) {
|
||||
if ( ! is_dir( $dir ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if ( $dir && ! is_dir( WP_LANG_DIR . $dir ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$files = scandir( WP_LANG_DIR . $dir );
|
||||
$files = $wp_textdomain_registry->get_language_files_from_path( $dir );
|
||||
if ( ! $files ) {
|
||||
return array();
|
||||
}
|
||||
@ -1531,16 +1531,7 @@ function wp_get_installed_translations( $type ) {
|
||||
$language_data = array();
|
||||
|
||||
foreach ( $files as $file ) {
|
||||
if ( '.' === $file[0] || is_dir( WP_LANG_DIR . "$dir/$file" ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( ! str_ends_with( $file, '.po' ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( ! preg_match( '/(?:(.+)-)?([a-z]{2,3}(?:_[A-Z]{2})?(?:_[a-z0-9]+)?).po/', $file, $match ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( ! in_array( substr( $file, 0, -3 ) . '.mo', $files, true ) ) {
|
||||
if ( ! preg_match( '/(?:(.+)-)?([a-z]{2,3}(?:_[A-Z]{2})?(?:_[a-z0-9]+)?)\.(?:mo|l10n\.php)/', basename( $file ), $match ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1548,7 +1539,25 @@ function wp_get_installed_translations( $type ) {
|
||||
if ( '' === $textdomain ) {
|
||||
$textdomain = 'default';
|
||||
}
|
||||
$language_data[ $textdomain ][ $language ] = wp_get_pomo_file_data( WP_LANG_DIR . "$dir/$file" );
|
||||
|
||||
if ( str_ends_with( $file, '.mo' ) ) {
|
||||
$pofile = substr_replace( $file, '.po', - strlen( '.mo' ) );
|
||||
|
||||
if ( ! file_exists( $pofile ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$language_data[ $textdomain ][ $language ] = wp_get_pomo_file_data( $pofile );
|
||||
} else {
|
||||
$pofile = substr_replace( $file, '.po', - strlen( '.l10n.php' ) );
|
||||
|
||||
// If both a PO and a PHP file exist, prefer the PO file.
|
||||
if ( file_exists( $pofile ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$language_data[ $textdomain ][ $language ] = wp_get_l10n_php_file_data( $file );
|
||||
}
|
||||
}
|
||||
return $language_data;
|
||||
}
|
||||
@ -1578,6 +1587,41 @@ function wp_get_pomo_file_data( $po_file ) {
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts headers from a PHP translation file.
|
||||
*
|
||||
* @since 6.6.0
|
||||
*
|
||||
* @param string $php_file Path to a `.l10n.php` file.
|
||||
* @return string[] Array of file header values keyed by header name.
|
||||
*/
|
||||
function wp_get_l10n_php_file_data( $php_file ) {
|
||||
$data = (array) include $php_file;
|
||||
|
||||
unset( $data['messages'] );
|
||||
$headers = array(
|
||||
'POT-Creation-Date' => 'pot-creation-date',
|
||||
'PO-Revision-Date' => 'po-revision-date',
|
||||
'Project-Id-Version' => 'project-id-version',
|
||||
'X-Generator' => 'x-generator',
|
||||
);
|
||||
|
||||
$result = array(
|
||||
'POT-Creation-Date' => '',
|
||||
'PO-Revision-Date' => '',
|
||||
'Project-Id-Version' => '',
|
||||
'X-Generator' => '',
|
||||
);
|
||||
|
||||
foreach ( $headers as $po_header => $php_header ) {
|
||||
if ( isset( $data[ $php_header ] ) ) {
|
||||
$result[ $po_header ] = $data[ $php_header ];
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays or returns a Language selector.
|
||||
*
|
||||
|
@ -70,13 +70,25 @@ class Tests_L10n extends WP_UnitTestCase {
|
||||
$this->assertEmpty( $array );
|
||||
|
||||
$array = get_available_languages( DIR_TESTDATA . '/languages/' );
|
||||
$this->assertSame( array( 'de_DE', 'en_GB', 'es_ES', 'ja_JP' ), $array );
|
||||
$this->assertEqualSets(
|
||||
array(
|
||||
'de_DE',
|
||||
'en_GB',
|
||||
'es_ES',
|
||||
'ja_JP',
|
||||
'de_CH',
|
||||
),
|
||||
$array
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 35284
|
||||
* @ticket 60554
|
||||
*
|
||||
* @covers ::wp_get_installed_translations
|
||||
* @covers ::wp_get_pomo_file_data
|
||||
* @covers ::wp_get_l10n_php_file_data
|
||||
*/
|
||||
public function test_wp_get_installed_translations_for_core() {
|
||||
$installed_translations = wp_get_installed_translations( 'core' );
|
||||
@ -95,6 +107,12 @@ class Tests_L10n extends WP_UnitTestCase {
|
||||
$this->assertSame( '2016-10-25 18:29+0200', $data_es_es['PO-Revision-Date'] );
|
||||
$this->assertSame( 'Administration', $data_es_es['Project-Id-Version'] );
|
||||
$this->assertSame( 'Poedit 1.8.10', $data_es_es['X-Generator'] );
|
||||
|
||||
$this->assertNotEmpty( $installed_translations['default']['de_CH'] );
|
||||
$data_en_gb = $installed_translations['default']['de_CH'];
|
||||
$this->assertSame( '2024-01-31 19:08:22+0000', $data_en_gb['PO-Revision-Date'] );
|
||||
$this->assertSame( 'WordPress - 6.4.x - Development', $data_en_gb['Project-Id-Version'] );
|
||||
$this->assertSame( 'GlotPress/4.0.0-beta.2', $data_en_gb['X-Generator'] );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -9230,7 +9230,8 @@ mockedApiResponse.Schema = {
|
||||
"de_DE",
|
||||
"en_GB",
|
||||
"es_ES",
|
||||
"ja_JP"
|
||||
"ja_JP",
|
||||
"de_CH"
|
||||
],
|
||||
"required": false
|
||||
},
|
||||
@ -9361,7 +9362,8 @@ mockedApiResponse.Schema = {
|
||||
"de_DE",
|
||||
"en_GB",
|
||||
"es_ES",
|
||||
"ja_JP"
|
||||
"ja_JP",
|
||||
"de_CH"
|
||||
],
|
||||
"required": false
|
||||
},
|
||||
@ -9502,7 +9504,8 @@ mockedApiResponse.Schema = {
|
||||
"de_DE",
|
||||
"en_GB",
|
||||
"es_ES",
|
||||
"ja_JP"
|
||||
"ja_JP",
|
||||
"de_CH"
|
||||
],
|
||||
"required": false
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user