Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions src/BladeCodeExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ final class BladeCodeExtractor extends BladeGettextExtractor {
/**
* {@inheritdoc}
*/
public static function fromString( $text, Translations $translations, array $options = [] ) {
public static function fromString( $text, Translations $translations, array $options = [] ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid -- Using gettext scanner API.
WP_CLI::debug( "Parsing file {$options['file']}", 'make-pot' );

try {
self::fromStringMultiple( $text, [ $translations ], $options );
parent::fromString( $text, $translations, $options );
} catch ( Exception $exception ) {
WP_CLI::debug(
sprintf(
Expand Down
7 changes: 3 additions & 4 deletions src/BladeGettextExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace WP_CLI\I18n;

use eftec\bladeone\BladeOne;
use Gettext\Translations;

/**
* Class to get gettext strings from blade.php files returning arrays.
Expand Down Expand Up @@ -37,11 +38,9 @@ protected static function compileBladeToPhp( $text ) {

/**
* {@inheritdoc}
*
* Note: In the parent PhpCode class fromString() uses fromStringMultiple() (overriden here)
*/
public static function fromStringMultiple( $text, array $translations, array $options = [] ) {
public static function fromString( $text, Translations $translations, array $options = [] ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid -- Using gettext scanner API.
$php_string = static::compileBladeToPhp( $text );
return parent::fromStringMultiple( $php_string, $translations, $options );
return parent::fromString( $php_string, $translations, $options );
}
}
8 changes: 4 additions & 4 deletions src/JedGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ public function generateString( Translations $translations ): string {
}

public function generateArray( Translations $translations ): array {
$pluralForm = $translations->getHeaders()->getPluralForm();
$pluralSize = is_array( $pluralForm ) ? ( $pluralForm[0] - 1 ) : null;
$messages = [];
$plural_form = $translations->getHeaders()->getPluralForm();
$plural_size = is_array( $plural_form ) ? ( $plural_form[0] - 1 ) : null;
$messages = [];

foreach ( $translations as $translation ) {
if ( ! $translation->getTranslation() || $translation->isDisabled() ) {
Expand All @@ -61,7 +61,7 @@ public function generateArray( Translations $translations ): array {
}

if ( self::hasPluralTranslations( $translation ) ) {
$messages[ $context ][ $original ] = $translation->getPluralTranslations( $pluralSize );
$messages[ $context ][ $original ] = $translation->getPluralTranslations( $plural_size );
array_unshift( $messages[ $context ][ $original ], $translation->getTranslation() );
} else {
$messages[ $context ][ $original ] = $translation->getTranslation();
Expand Down
4 changes: 2 additions & 2 deletions src/JsCodeExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ final class JsCodeExtractor {
/**
* @inheritdoc
*/
public static function fromString( $text, Translations $translations, array $options = [] ) {
public static function fromString( $text, Translations $translations, array $options = [] ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid -- Using gettext scanner API.
WP_CLI::debug( "Parsing file {$options['file']}", 'make-pot' );

try {
$options += self::$options;

$scanner = new JsScanner( $translations );
$scanner->setFunctions( self::$options['functions'] );
$scanner->extractCommentsStartingWith( $options['extractComments'] );
$scanner->extractCommentsStartingWith( ...$options['extractComments'] );
$scanner->scanString( $text, $options['file'] );
} catch ( PeastException $exception ) {
WP_CLI::debug(
Expand Down
58 changes: 45 additions & 13 deletions src/JsFunctionsScanner.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@

namespace WP_CLI\I18n;

use Gettext\Utils\JsFunctionsScanner as GettextJsFunctionsScanner;
use Gettext\Utils\ParsedComment;
use Gettext\Translation;
use Peast\Peast;
use Peast\Syntax\Node;
use Peast\Traverser;

final class JsFunctionsScanner extends GettextJsFunctionsScanner {
final class JsFunctionsScanner {

/**
* The JavaScript code to parse.
*
* @var string
*/
protected $code;

/**
* If not false, comments will be extracted.
Expand All @@ -17,6 +23,15 @@ final class JsFunctionsScanner extends GettextJsFunctionsScanner {
*/
private $extract_comments = false;

/**
* Constructor.
*
* @param string $code JavaScript code to parse.
*/
public function __construct( $code ) {
$this->code = $code;
}

/**
* Holds a list of source code comments already added to a string.
*
Expand All @@ -31,21 +46,21 @@ final class JsFunctionsScanner extends GettextJsFunctionsScanner {
*
* @param mixed $tag
*/
public function enableCommentsExtraction( $tag = '' ) {
public function enableCommentsExtraction( $tag = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid -- Legacy method name for compatibility.
$this->extract_comments = $tag;
}

/**
* Disable comments extraction.
*/
public function disableCommentsExtraction() {
public function disableCommentsExtraction() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid -- Legacy method name for compatibility.
$this->extract_comments = false;
}

/**
* {@inheritdoc}
*/
public function saveGettextFunctions( $translations, array $options ) {
public function saveGettextFunctions( $translations, array $options ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid -- Legacy method name for compatibility.
// Ignore multiple translations for now.
// @todo Add proper support for multiple translations.
if ( is_array( $translations ) ) {
Expand Down Expand Up @@ -175,7 +190,11 @@ function ( $node ) use ( &$translations, $options, &$all_comments ) {
$line = $node->getLocation()->getStart()->getLine();
}

$translation = $translations->insert( $context, $original, $plural );
$translation = $translations->addOrMerge( Translation::create( $context, $original ) );

if ( $plural ) {
$translation->setPlural( $plural );
}

if ( $add_reference ) {
$translation->getReferences()->add( $file, $line );
Expand All @@ -199,11 +218,24 @@ function ( $node ) use ( &$translations, $options, &$all_comments ) {
continue;
}

$parsed_comment = ParsedComment::create( $comment->getRawText(), $comment->getLocation()->getStart()->getLine() );
$prefixes = array_filter( (array) $this->extract_comments );
$comment_text = $comment->getRawText();
$comment_text = preg_replace( '/^\/\*+|\*+\/$/', '', $comment_text );
$comment_text = preg_replace( '/^\s*\*\s?/m', '', $comment_text );
$comment_text = trim( $comment_text );

$prefixes = array_filter( (array) $this->extract_comments );

// Check if comment starts with any of the prefixes.
$has_prefix = false;
foreach ( $prefixes as $prefix ) {
if ( 0 === stripos( $comment_text, $prefix ) ) {
$has_prefix = true;
break;
}
}

if ( $parsed_comment->checkPrefixes( $prefixes ) ) {
$translation->getComments()->add( $parsed_comment->getComment() );
if ( $has_prefix || empty( $prefixes ) ) {
$translation->getComments()->add( $comment_text );

$this->comments_cache[] = $comment;
}
Expand Down Expand Up @@ -266,7 +298,7 @@ function ( $node ) use ( &$translations, $options, $scanner ) {
*
* @return array|bool Array containing the name and comments of the identifier if resolved. False if not.
*/
private function resolveExpressionCallee( Node\CallExpression $node ) {
private function resolveExpressionCallee( Node\CallExpression $node ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid -- Legacy method name for compatibility.
$callee = $node->getCallee();

// If the callee is a simple identifier it can simply be returned.
Expand Down Expand Up @@ -376,7 +408,7 @@ private function resolveExpressionCallee( Node\CallExpression $node ) {
*
* @return bool Whether or not the comment precedes the node.
*/
private function commentPrecedesNode( Node\Comment $comment, Node\Node $node ) {
private function commentPrecedesNode( Node\Comment $comment, Node\Node $node ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid -- Legacy method name for compatibility.
// Comments should be on the same or an earlier line than the translation.
if ( $node->getLocation()->getStart()->getLine() - $comment->getLocation()->getEnd()->getLine() > 1 ) {
return false;
Expand Down
2 changes: 1 addition & 1 deletion src/JsonSchemaExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ protected static function load_schema( $schema, $fallback ) {
/**
* @inheritdoc
*/
public static function fromString( $text, Translations $translations, array $options = [] ) {
public static function fromString( $text, Translations $translations, array $options = [] ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid -- Using gettext scanner API.
$file = $options['file'];
WP_CLI::debug( "Parsing file {$file}", 'make-pot' );

Expand Down
23 changes: 12 additions & 11 deletions src/MakePotCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
namespace WP_CLI\I18n;

use Gettext\Generator\PoGenerator;
use Gettext\Loader\PoLoader;
use Gettext\Merge;
use Gettext\Translation;
use Gettext\Translations;
use Gettext\Utils\ParsedComment;
use WP_CLI;
use WP_CLI_Command;
use WP_CLI\Utils;
Expand Down Expand Up @@ -428,8 +428,8 @@ function ( $file ) {

WP_CLI::debug( sprintf( 'Ignoring any string already existing in: %s', $file ), 'make-pot' );

$this->exceptions[ $file ] = Translations::create();
Po::fromFile( $file, $this->exceptions[ $file ] );
$loader = new PoLoader();
$this->exceptions[ $file ] = $loader->loadFile( $file );
}
}

Expand Down Expand Up @@ -592,9 +592,11 @@ protected function extract_strings() {

// Add existing strings first but don't keep headers.
if ( ! empty( $this->merge ) ) {
$existing_translations = Translations::create();
Po::fromFile( $this->merge, $existing_translations );
$translations->mergeWith( $existing_translations, Merge::TRANSLATIONS_OURS | Merge::HEADERS_OURS );
$loader = new PoLoader();
foreach ( (array) $this->merge as $file ) {
$existing_translations = $loader->loadFile( $file );
$translations->mergeWith( $existing_translations, Merge::TRANSLATIONS_OURS | Merge::HEADERS_OURS );
}
}

$translations->setDescription( $this->get_file_comment() );
Expand Down Expand Up @@ -785,13 +787,12 @@ protected function audit_strings( $translations ) {
$location = '';

// There might not be any file references.
foreach( $references as $file => $lines ) {
foreach ( $references as $file => $lines ) {
if ( count( $lines ) > 0 ) {
$location = "$file:$lines[0]";
}
}


// Check 1: Flag strings with placeholders that should have translator comments.
if (
$translation->getComments()->count() === 0 &&
Expand Down Expand Up @@ -831,12 +832,12 @@ function ( $comment ) {
$comments = array_filter(
$comments,
function ( $comment ) use ( &$unique_comments ) {
/** @var ParsedComment|string $comment */
if ( in_array( ( $comment instanceof ParsedComment ? $comment->getComment() : $comment ), $unique_comments, true ) ) {
/** @var string $comment */
if ( in_array( $comment, $unique_comments, true ) ) {
return null;
}

$unique_comments[] = ( $comment instanceof ParsedComment ? $comment->getComment() : $comment );
$unique_comments[] = $comment;

return $comment;
}
Expand Down
2 changes: 1 addition & 1 deletion src/MapCodeExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ final class MapCodeExtractor {
/**
* {@inheritdoc}
*/
public static function fromString( $text, Translations $translations, array $options = [] ) {
public static function fromString( $text, Translations $translations, array $options = [] ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid -- Using gettext scanner API.
if ( ! array_key_exists( 'file', $options ) || substr( $options['file'], -7 ) !== '.js.map' ) {
return;
}
Expand Down
2 changes: 1 addition & 1 deletion src/PhpCodeExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class PhpCodeExtractor {
/**
* {@inheritdoc}
*/
public static function fromString( $text, Translations $translations, array $options = [] ) {
public static function fromString( $text, Translations $translations, array $options = [] ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid -- Using gettext scanner API.
$options = static::$options + $options;

WP_CLI::debug( "Parsing file {$options['file']}", 'make-pot' );
Expand Down
65 changes: 59 additions & 6 deletions src/PhpFunctionsScanner.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,63 @@

namespace WP_CLI\I18n;

use Gettext\Utils\PhpFunctionsScanner as GettextPhpFunctionsScanner;
use Gettext\Translation;

class PhpFunctionsScanner extends GettextPhpFunctionsScanner {
class PhpFunctionsScanner {

/**
* The PHP code to parse.
*
* @var string
*/
protected $code;

/**
* Parsed PHP functions.
*
* @var array
*/
protected $functions = [];

/**
* Constructor.
*
* @param string $code PHP code to parse.
*/
public function __construct( $code ) {
$this->code = $code;
}

/**
* Get parsed functions from PHP code.
*
* @param array $constants Constants to replace.
* @return array
*/
public function getFunctions( array $constants = [] ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid -- Legacy method name for compatibility.
if ( empty( $this->functions ) ) {
$this->functions = $this->parseFunctions( $constants );
}
return $this->functions;
}

/**
* Parse PHP code to extract function calls.
*
* @param array $constants Constants to replace.
* @return array
*/
protected function parseFunctions( array $constants = [] ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid -- Legacy method name for compatibility.
// This is a simplified implementation.
// The actual parsing is done by PhpScanner in gettext v5.
unset( $constants ); // Unused parameter, kept for compatibility.
return [];
}

/**
* {@inheritdoc}
*/
public function saveGettextFunctions( $translations, array $options ) {
public function saveGettextFunctions( $translations, array $options ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid -- Legacy method name for compatibility.
// Ignore multiple translations for now.
// @todo Add proper support for multiple translations.
if ( is_array( $translations ) ) {
Expand Down Expand Up @@ -71,10 +120,14 @@ public function saveGettextFunctions( $translations, array $options ) {
continue;
}

$translation = $translations->insert( $context, $original, $plural );
$translation = $translations->addOrMerge( Translation::create( $context, $original ) );

if ( $plural ) {
$translation->setPlural( $plural );
}

if ( $add_reference ) {
$translation = $translation->getReferences()->add( $file, $line );
$translation->getReferences()->add( $file, $line );
}

if (
Expand All @@ -86,7 +139,7 @@ public function saveGettextFunctions( $translations, array $options ) {

if ( isset( $function[3] ) ) {
foreach ( $function[3] as $extracted_comment ) {
$translation = $translation->getComments()->add( $extracted_comment );
$translation->getComments()->add( $extracted_comment );
}
}
}
Expand Down
Loading