From b9169bef2d7b46c58432a2a5cb76b3436f1ede42 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 27 Aug 2026 16:25:07 +0000 Subject: [PATCH 1/2] Write the revision date under both header keys in make-php GlotPress exports the revision date of a `.l10n.php` file as `translation-revision-date`. That is what the language packs on WordPress.org ship, and what `make-json` in this package already emits for the same value. `make-php` wrote only `po-revision-date`, so its output diverged from the reference format. WordPress reads `po-revision-date` in `wp_get_l10n_php_file_data()`, so swapping the key outright would leave the revision date empty in `wp_get_installed_translations()` on every released version, and an up-to-date language pack would be offered again on each update check. Write both keys instead: existing readers keep working, and the file matches what GlotPress produces. --- features/makephp.feature | 34 +++++++++++++++++++++++++++++++++- src/PhpArrayGenerator.php | 18 +++++++++++++----- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/features/makephp.feature b/features/makephp.feature index eda279c..f9cc452 100644 --- a/features/makephp.feature +++ b/features/makephp.feature @@ -153,7 +153,39 @@ Feature: Generate PHP files from PO files And STDERR should be empty And the foo-plugin/foo-plugin-de_DE.l10n.php file should contain: """ - return ['domain'=>NULL,'plural-forms'=>'nplurals=2; plural=n != 1;','language'=>'de_DE','project-id-version'=>'Development (5.2.x)','pot-creation-date'=>'','po-revision-date'=>'2019-03-28 19:42+0300','x-generator'=>'Poedit 2.2.1','messages'=>['html_lang_attribute'=>'de-DE','text directionltr'=>'ltr','number_format_decimal_point'=>',','number_format_thousands_sep'=>'.','Update %s now'=>'Jetzt %s aktualisieren','[%1$s] Confirm Action: %2$s'=>'[%1$s] Aktion bestätigen: %2$s','[%s] Erasure Request Fulfilled'=>'[%s] Löschauftrag ausgeführt','[%s] Personal Data Export'=>'[%s] Export personenbezogener Daten']]; + return ['domain'=>NULL,'plural-forms'=>'nplurals=2; plural=n != 1;','language'=>'de_DE','project-id-version'=>'Development (5.2.x)','pot-creation-date'=>'','translation-revision-date'=>'2019-03-28 19:42+0300','po-revision-date'=>'2019-03-28 19:42+0300','x-generator'=>'Poedit 2.2.1','messages'=>['html_lang_attribute'=>'de-DE','text directionltr'=>'ltr','number_format_decimal_point'=>',','number_format_thousands_sep'=>'.','Update %s now'=>'Jetzt %s aktualisieren','[%1$s] Confirm Action: %2$s'=>'[%1$s] Aktion bestätigen: %2$s','[%s] Erasure Request Fulfilled'=>'[%s] Löschauftrag ausgeführt','[%s] Personal Data Export'=>'[%s] Export personenbezogener Daten']]; + """ + + Scenario: Writes the revision date under both header keys + Given an empty foo-plugin directory + And a foo-plugin/foo-plugin-de_DE.po file: + """ + # Copyright (C) 2018 Foo Plugin + # This file is distributed under the same license as the Foo Plugin package. + msgid "" + msgstr "" + "Project-Id-Version: Foo Plugin\n" + "Language: de_DE\n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" + "PO-Revision-Date: 2018-05-02T22:06:24+00:00\n" + "Plural-Forms: nplurals=2; plural=(n != 1);\n" + + #: foo-plugin.php:15 + msgid "Foo Plugin" + msgstr "Bar Plugin" + """ + + When I run `wp i18n make-php foo-plugin` + Then the return code should be 0 + And the foo-plugin/foo-plugin-de_DE.l10n.php file should contain: + """ + 'translation-revision-date'=>'2018-05-02T22:06:24+00:00' + """ + And the foo-plugin/foo-plugin-de_DE.l10n.php file should contain: + """ + 'po-revision-date'=>'2018-05-02T22:06:24+00:00' """ Scenario: Does include translations diff --git a/src/PhpArrayGenerator.php b/src/PhpArrayGenerator.php index 2c8a320..9883e1c 100644 --- a/src/PhpArrayGenerator.php +++ b/src/PhpArrayGenerator.php @@ -72,16 +72,24 @@ protected static function toArray( Translations $translations, $include_headers, $result['language'] = $language; } + /* + * `PO-Revision-Date` maps onto two keys. GlotPress exports the revision date as + * `translation-revision-date`, which is what the language packs on WordPress.org + * ship and what `make-json` already emits, while WordPress reads `po-revision-date` + * in `wp_get_l10n_php_file_data()`. Writing both keeps the file readable either way. + */ $headers_allowlist = [ - 'POT-Creation-Date' => 'pot-creation-date', - 'PO-Revision-Date' => 'po-revision-date', - 'Project-Id-Version' => 'project-id-version', - 'X-Generator' => 'x-generator', + 'POT-Creation-Date' => [ 'pot-creation-date' ], + 'PO-Revision-Date' => [ 'translation-revision-date', 'po-revision-date' ], + 'Project-Id-Version' => [ 'project-id-version' ], + 'X-Generator' => [ 'x-generator' ], ]; foreach ( $translations->getHeaders() as $name => $value ) { if ( isset( $headers_allowlist[ $name ] ) ) { - $result[ $headers_allowlist[ $name ] ] = $value; + foreach ( $headers_allowlist[ $name ] as $key ) { + $result[ $key ] = $value; + } } } From 07e4e2dde1006ba00357fc3e4a0003a3bfc177f8 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 27 Aug 2026 16:50:10 +0000 Subject: [PATCH 2/2] Write only translation-revision-date, matching GlotPress GlotPress writes `translation-revision-date` as the only revision date key in a `.l10n.php` file; `po-revision-date` appears nowhere in its exporter. Every language pack on WordPress.org therefore carries just the one key, so emitting both from `make-php` still diverged from the reference format. Drop `po-revision-date` and write only the GlotPress key. Note that `wp_get_l10n_php_file_data()` reads `po-revision-date`, so the revision date it reports for a file generated by `make-php` is empty until core reads the GlotPress key as well. That is already the case for every GlotPress-generated language pack. --- features/makephp.feature | 8 ++++---- src/PhpArrayGenerator.php | 19 ++++++------------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/features/makephp.feature b/features/makephp.feature index f9cc452..0095922 100644 --- a/features/makephp.feature +++ b/features/makephp.feature @@ -153,10 +153,10 @@ Feature: Generate PHP files from PO files And STDERR should be empty And the foo-plugin/foo-plugin-de_DE.l10n.php file should contain: """ - return ['domain'=>NULL,'plural-forms'=>'nplurals=2; plural=n != 1;','language'=>'de_DE','project-id-version'=>'Development (5.2.x)','pot-creation-date'=>'','translation-revision-date'=>'2019-03-28 19:42+0300','po-revision-date'=>'2019-03-28 19:42+0300','x-generator'=>'Poedit 2.2.1','messages'=>['html_lang_attribute'=>'de-DE','text directionltr'=>'ltr','number_format_decimal_point'=>',','number_format_thousands_sep'=>'.','Update %s now'=>'Jetzt %s aktualisieren','[%1$s] Confirm Action: %2$s'=>'[%1$s] Aktion bestätigen: %2$s','[%s] Erasure Request Fulfilled'=>'[%s] Löschauftrag ausgeführt','[%s] Personal Data Export'=>'[%s] Export personenbezogener Daten']]; + return ['domain'=>NULL,'plural-forms'=>'nplurals=2; plural=n != 1;','language'=>'de_DE','project-id-version'=>'Development (5.2.x)','pot-creation-date'=>'','translation-revision-date'=>'2019-03-28 19:42+0300','x-generator'=>'Poedit 2.2.1','messages'=>['html_lang_attribute'=>'de-DE','text directionltr'=>'ltr','number_format_decimal_point'=>',','number_format_thousands_sep'=>'.','Update %s now'=>'Jetzt %s aktualisieren','[%1$s] Confirm Action: %2$s'=>'[%1$s] Aktion bestätigen: %2$s','[%s] Erasure Request Fulfilled'=>'[%s] Löschauftrag ausgeführt','[%s] Personal Data Export'=>'[%s] Export personenbezogener Daten']]; """ - Scenario: Writes the revision date under both header keys + Scenario: Writes the revision date as translation-revision-date Given an empty foo-plugin directory And a foo-plugin/foo-plugin-de_DE.po file: """ @@ -183,9 +183,9 @@ Feature: Generate PHP files from PO files """ 'translation-revision-date'=>'2018-05-02T22:06:24+00:00' """ - And the foo-plugin/foo-plugin-de_DE.l10n.php file should contain: + And the foo-plugin/foo-plugin-de_DE.l10n.php file should not contain: """ - 'po-revision-date'=>'2018-05-02T22:06:24+00:00' + 'po-revision-date' """ Scenario: Does include translations diff --git a/src/PhpArrayGenerator.php b/src/PhpArrayGenerator.php index 9883e1c..a4c931d 100644 --- a/src/PhpArrayGenerator.php +++ b/src/PhpArrayGenerator.php @@ -72,24 +72,17 @@ protected static function toArray( Translations $translations, $include_headers, $result['language'] = $language; } - /* - * `PO-Revision-Date` maps onto two keys. GlotPress exports the revision date as - * `translation-revision-date`, which is what the language packs on WordPress.org - * ship and what `make-json` already emits, while WordPress reads `po-revision-date` - * in `wp_get_l10n_php_file_data()`. Writing both keeps the file readable either way. - */ + // GlotPress exports the revision date as `translation-revision-date`, so use that name here too. $headers_allowlist = [ - 'POT-Creation-Date' => [ 'pot-creation-date' ], - 'PO-Revision-Date' => [ 'translation-revision-date', 'po-revision-date' ], - 'Project-Id-Version' => [ 'project-id-version' ], - 'X-Generator' => [ 'x-generator' ], + 'POT-Creation-Date' => 'pot-creation-date', + 'PO-Revision-Date' => 'translation-revision-date', + 'Project-Id-Version' => 'project-id-version', + 'X-Generator' => 'x-generator', ]; foreach ( $translations->getHeaders() as $name => $value ) { if ( isset( $headers_allowlist[ $name ] ) ) { - foreach ( $headers_allowlist[ $name ] as $key ) { - $result[ $key ] = $value; - } + $result[ $headers_allowlist[ $name ] ] = $value; } }