Skip to content

Commit 9fef42e

Browse files
I18N: Read the revision date key that GlotPress writes into .l10n.php files.
wp_get_l10n_php_file_data() maps `PO-Revision-Date` onto `po-revision-date`, but GlotPress writes that value under `translation-revision-date`. The key core looks for is absent from every language pack currently served, so the function returns an empty revision date. The name changed upstream. The `de_CH.l10n.php` fixture already in core reports `GlotPress/4.0.0-beta.2` and uses `po-revision-date`, while packs generated by `GlotPress/4.0.3` use `translation-revision-date`. The mapping was correct when the function was added in 6.6 and stopped matching later. `Project-Id-Version` and `X-Generator` still resolve, which is why nothing looked broken. This matters because wp_get_installed_translations() falls back to this reader when a translation has no sibling `.po` file, and the result is sent to api.wordpress.org to decide which language packs are stale. An empty revision date means an installed, current pack is offered again on every check. Accept both spellings, preferring the current one, so files written before and after the rename resolve. `POT-Creation-Date` maps to `pot-creation-date`, which appears in neither format, and is left alone rather than guessed at. The existing coverage did not catch this because the only `.l10n.php` fixture it asserts against predates the rename. Add a fixture in the current format and a test that fails on trunk with an empty string. Props bejignesh. Fixes #65809.
1 parent a105958 commit 9fef42e

3 files changed

Lines changed: 49 additions & 7 deletions

File tree

src/wp-includes/l10n.php

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1682,11 +1682,18 @@ function wp_get_l10n_php_file_data( $php_file ) {
16821682
$data = (array) include $php_file;
16831683

16841684
unset( $data['messages'] );
1685+
1686+
/*
1687+
* Each PO header maps to the keys a `.l10n.php` file may store it under, in
1688+
* order of preference. GlotPress writes the revision date as
1689+
* 'translation-revision-date'; files generated before that renaming use
1690+
* 'po-revision-date', so both are accepted.
1691+
*/
16851692
$headers = array(
1686-
'POT-Creation-Date' => 'pot-creation-date',
1687-
'PO-Revision-Date' => 'po-revision-date',
1688-
'Project-Id-Version' => 'project-id-version',
1689-
'X-Generator' => 'x-generator',
1693+
'POT-Creation-Date' => array( 'pot-creation-date' ),
1694+
'PO-Revision-Date' => array( 'translation-revision-date', 'po-revision-date' ),
1695+
'Project-Id-Version' => array( 'project-id-version' ),
1696+
'X-Generator' => array( 'x-generator' ),
16901697
);
16911698

16921699
$result = array(
@@ -1696,9 +1703,12 @@ function wp_get_l10n_php_file_data( $php_file ) {
16961703
'X-Generator' => '',
16971704
);
16981705

1699-
foreach ( $headers as $po_header => $php_header ) {
1700-
if ( isset( $data[ $php_header ] ) ) {
1701-
$result[ $po_header ] = $data[ $php_header ];
1706+
foreach ( $headers as $po_header => $php_headers ) {
1707+
foreach ( $php_headers as $php_header ) {
1708+
if ( isset( $data[ $php_header ] ) ) {
1709+
$result[ $po_header ] = $data[ $php_header ];
1710+
break;
1711+
}
17021712
}
17031713
}
17041714

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?php
2+
return ['x-generator'=>'GlotPress/4.0.3','translation-revision-date'=>'2026-06-26 08:56:45+0000','plural-forms'=>'nplurals=2; plural=n != 1;','project-id-version'=>'Themes - Twenty Twenty-Five','language'=>'nl','messages'=>['Update %s now'=>'Werk %s nu bij']];

tests/phpunit/tests/l10n.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,36 @@ public function test_wp_get_pomo_file_data() {
154154
$this->assertNotEmpty( $array['X-Generator'] );
155155
}
156156

157+
/**
158+
* Ensures the revision date is read from both spellings a `.l10n.php` file may use.
159+
*
160+
* GlotPress writes the revision date as `translation-revision-date`. Files generated
161+
* before that renaming use `po-revision-date`, so both have to resolve.
162+
*
163+
* @ticket 65809
164+
*
165+
* @covers ::wp_get_l10n_php_file_data
166+
*/
167+
public function test_wp_get_l10n_php_file_data_reads_revision_date() {
168+
$current = wp_get_l10n_php_file_data( DIR_TESTDATA . '/l10n/translation-revision-date.l10n.php' );
169+
170+
$this->assertSame(
171+
'2026-06-26 08:56:45+0000',
172+
$current['PO-Revision-Date'],
173+
'The revision date was not read from the translation-revision-date key.'
174+
);
175+
$this->assertSame( 'Themes - Twenty Twenty-Five', $current['Project-Id-Version'] );
176+
$this->assertSame( 'GlotPress/4.0.3', $current['X-Generator'] );
177+
178+
$legacy = wp_get_l10n_php_file_data( DIR_TESTDATA . '/languages/de_CH.l10n.php' );
179+
180+
$this->assertSame(
181+
'2024-01-31 19:08:22+0000',
182+
$legacy['PO-Revision-Date'],
183+
'The revision date was not read from the legacy po-revision-date key.'
184+
);
185+
}
186+
157187
/**
158188
* @ticket 44541
159189
*

0 commit comments

Comments
 (0)