Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,9 @@ wp i18n make-php <source> [<destination>]
[<destination>]
Path to the destination directory for the resulting PHP files. Defaults to the source directory.

[--pretty-print]
Pretty-print resulting PHP files.

**EXAMPLES**

# Create PHP files for all PO files in the current directory.
Expand Down
60 changes: 60 additions & 0 deletions features/makephp.feature
Original file line number Diff line number Diff line change
Expand Up @@ -259,3 +259,63 @@ Feature: Generate PHP files from PO files
"""
new message
"""

Scenario: Should create pretty-printed PHP files
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"
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/foo-plugin\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: de_DE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"POT-Creation-Date: 2018-05-02T22:06:24+00:00\n"
"PO-Revision-Date: 2018-05-02T22:06:24+00:00\n"
"X-Domain: foo-plugin\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#: foo-plugin.js:15
msgid "Foo Plugin"
msgstr "Foo Plugin"

#: foo-plugin.js:16
msgid "Hello"
msgstr "Hallo"

#: foo-plugin.js:17
msgid "You have %d new message"
msgid_plural "You have %d new messages"
msgstr[0] "Du hast %d neue Nachricht"
msgstr[1] "Du hast %d neue Nachrichten"
"""

When I run `wp i18n make-php foo-plugin --pretty-print`
Then STDOUT should contain:
"""
Success: Created 1 file.
"""
And the return code should be 0
And the foo-plugin/foo-plugin-de_DE.l10n.php file should contain:
"""
<?php
return [
'domain' => 'foo-plugin',
'plural-forms' => 'nplurals=2; plural=(n != 1);',
'language' => 'de_DE',
'project-id-version' => 'Foo Plugin',
'pot-creation-date' => '2018-05-02T22:06:24+00:00',
'po-revision-date' => '2018-05-02T22:06:24+00:00',
'messages' => [
'Foo Plugin' => 'Foo Plugin',
'Hello' => 'Hallo',
'You have %d new message' => 'Du hast %d neue Nachricht' . "\0" . 'Du hast %d neue Nachrichten',
],
];
"""
7 changes: 6 additions & 1 deletion src/MakePhpCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ class MakePhpCommand extends WP_CLI_Command {
* [<destination>]
* : Path to the destination directory for the resulting PHP files. Defaults to the source directory.
*
* [--pretty-print]
* : Pretty-print resulting PHP files.
*
* ## EXAMPLES
*
* # Create PHP files for all PO files in the current directory.
Expand Down Expand Up @@ -58,6 +61,8 @@ public function __invoke( $args, $assoc_args ) {
}

$result_count = 0;
$pretty_print = Utils\get_flag_value( $assoc_args, 'pretty-print', false );

/** @var DirectoryIterator $file */
foreach ( $files as $file ) {
if ( 'po' !== $file->getExtension() ) {
Expand All @@ -73,7 +78,7 @@ public function __invoke( $args, $assoc_args ) {
$destination_file = "{$destination}/{$file_basename}.l10n.php";

$translations = Translations::fromPoFile( $file->getPathname() );
if ( ! PhpArrayGenerator::toFile( $translations, $destination_file ) ) {
if ( ! PhpArrayGenerator::toFile( $translations, $destination_file, [ 'prettyPrint' => $pretty_print ] ) ) {
WP_CLI::warning( sprintf( 'Could not create file %s', $destination_file ) );
continue;
}
Expand Down
43 changes: 42 additions & 1 deletion src/PhpArrayGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
class PhpArrayGenerator extends PhpArray {
public static $options = [
'includeHeaders' => false,
'prettyPrint' => false,
];

/**
Expand All @@ -22,7 +23,15 @@ class PhpArrayGenerator extends PhpArray {
public static function toString( Translations $translations, array $options = [] ) {
$array = static::generate( $translations, $options );

return '<?php' . PHP_EOL . 'return ' . static::var_export( $array ) . ';';
$pretty_print = isset( $options['prettyPrint'] ) ? $options['prettyPrint'] : false;

if ( true === $pretty_print ) {
$exported_array = static::pretty_export( $array );
} else {
$exported_array = static::var_export( $array );
}

return '<?php' . PHP_EOL . ' return ' . $exported_array . ';';
}

/**
Expand Down Expand Up @@ -163,4 +172,36 @@ private static function var_export( $value ) {

return '[' . implode( ',', $entries ) . ']';
}

/**
* Outputs or returns a parsable string representation of a variable.
* @since 4.0.0
*
* @param mixed $value The variable you want to export.
* @param int $level The current indentation level.
* @param int $indentation The number of spaces for indentation. Default is 4.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do tabs instead?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like using tabs for my own projects, but here as it is something which will be used on other developers IDE, I prefer to use spaces, because tabs configuration depends on the configuration of user. A space will be every time a space, but tab not. Some resources not related to this subject but still on the same issue:

https://medium.com/@peey/what-is-the-inconsistent-use-of-tabs-and-spaces-in-indentation-error-and-why-is-it-caused-f3bbb8b2568b
https://stackoverflow.com/questions/5685406/inconsistent-use-of-tabs-and-spaces-in-indentation

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to use spaces, because tabs configuration depends on the configuration of user

That's actually an advantage of tabs :-) But I don't wanna start yet another tabs vs spaces discussion here.

I am mainly suggesting using tabs because that's the WordPress coding standard and IMHO we should be consistent with that.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, in this case I will try to change it to tabs to respect the standards, thanks!

* @return string The variable representation.
*/
private static function pretty_export( $values, $indentation = 2 ) {
$result = '[' . PHP_EOL;
$indent = str_repeat( ' ', $indentation );

foreach ( $values as $key => $value ) {
$result .= $indent . str_repeat( ' ', $indentation ) . "'$key' => ";

if ( is_array( $value ) ) {
$result .= self::pretty_export( $value, $indentation + $indentation );
} elseif ( strpos( $value, "\0" ) !== false ) {
$parts = explode( "\0", $value );
$result .= "'" . implode( "' . \"\\0\" . '", array_map( 'addslashes', $parts ) ) . "'";
} else {
$result .= "'$value'";
}

$result .= ',' . PHP_EOL;
}

$result .= $indent . ']';
return $result;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole function is a bit hard to grasp. What's with the\0 checks here for example, why do we need that? 🤔

Copy link
Author

@sovetski sovetski Apr 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without that, instead of getting

'You have %d new message' => 'Du hast %d neue Nachricht' . "\0" . 'Du hast %d neue Nachrichten',

we will get

'You have %d new message' => 'Du hast %d neue NachrichtDu hast %d neue Nachrichten',

You explained it on this article: https://make.wordpress.org/core/2024/02/27/i18n-improvements-6-5-performant-translations/#:~:text=Note%3A%20EOT%20here%20stands%20for%20the%20%E2%80%9CEnd%20of%20Transmission%E2%80%9D%20character%20(U%2B0004%2C%20or%20%22%5C4%22%20in%20PHP).%20It%E2%80%99s%20the%20same%20delimiter%20as%20in%20gettext%20used%20to%20glue%20the%20context%20with%20the%20singular%E2%80%82string.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My question is why is it doing this here and why is this not needed for the existing, non-pretty var_export() method?

}