Skip to content

Commit

Permalink
Merge pull request #96 from kasimi/lang-keys
Browse files Browse the repository at this point in the history
Scan all array literals for language keys
  • Loading branch information
paul999 authored Sep 22, 2023
2 parents 459aebd + f15dd7c commit fc36bcd
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 54 deletions.
60 changes: 60 additions & 0 deletions src/Tests/ArrayKeyVisitor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php
/**
*
* EPV :: The phpBB Forum Extension Pre Validator.
*
* @copyright (c) 2014 phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
*/
namespace Phpbb\Epv\Tests;

use PhpParser\Node;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Scalar\String_;
use PhpParser\NodeVisitorAbstract;

class ArrayKeyVisitor extends NodeVisitorAbstract
{
/**
* @var array
*/
private $keys;

/**
* @param array $nodes
* @return void|null|Node[]
*/
public function beforeTraverse(array $nodes)
{
$this->keys = [];
}

/**
* @param Node $node
* @return void|null|int|Node
*/
public function enterNode(Node $node)
{
if ($node instanceof Array_)
{
foreach ($node->items as $item)
{
/** @var ArrayItem $item */
if ($item->key instanceof String_)
{
$this->keys[] = $item->key->value;
}
}
}
}

/**
* @return array
*/
public function get_array_keys()
{
return $this->keys;
}
}
72 changes: 20 additions & 52 deletions src/Tests/Tests/epv_test_validate_languages.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,30 @@
namespace Phpbb\Epv\Tests\Tests;

use Phpbb\Epv\Output\OutputInterface;
use Phpbb\Epv\Tests\ArrayKeyVisitor;
use Phpbb\Epv\Tests\BaseTest;
use PhpParser\Error;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Scalar\String_;
use PhpParser\NodeTraverser;
use PhpParser\Parser;
use PhpParser\ParserFactory;

class epv_test_validate_languages extends BaseTest
{
/**
* @var Parser
*/
* @var Parser
*/
private $parser;

/**
* @var ArrayKeyVisitor
*/
private $visitor;

/**
* @var NodeTraverser
*/
private $traverser;

/**
* @param bool $debug if debug is enabled
* @param OutputInterface $output
Expand All @@ -43,6 +50,9 @@ public function __construct($debug, OutputInterface $output, $basedir, $namespac

$this->directory = true;
$this->parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
$this->visitor = new ArrayKeyVisitor;
$this->traverser = new NodeTraverser;
$this->traverser->addVisitor($this->visitor);
}

/**
Expand Down Expand Up @@ -99,8 +109,7 @@ public function validateDirectory(array $files)
}

/**
* This method scans through all global-scoped calls to array_merge
* and extracts all string keys of all array arguments.
* This method scans through all array literals and collects all their string keys.
*
* @param string $filename File name to a phpBB language file
* @return array
Expand All @@ -109,50 +118,9 @@ public function validateDirectory(array $files)
protected function load_language_keys($filename)
{
$contents = @file_get_contents($filename);

$keys = [];

$nodes = $this->parser->parse($contents);

foreach ($nodes as $node)
{
if ($node instanceof Assign && $node->expr instanceof FuncCall)
{
/** @var FuncCall $expr */
$expr = $node->expr;

if ($expr->name->getFirst() === 'array_merge')
{
for ($i = 1; $i < sizeof($expr->args); $i++)
{
/** @var Array_ $array */
$array = $expr->args[$i]->value;

if ($array instanceof Array_)
{
foreach ($array->items as $item)
{
/** @var ArrayItem $item */
if ($item->key instanceof String_)
{
$keys[] = $item->key->value;
}
else
{
$this->output->addMessage(OutputInterface::NOTICE, 'Language key is not a string value in ' . substr($filename, strlen($this->basedir)) . ' on line ' . $item->key->getLine());
}
}
}
else
{
$this->output->addMessage(OutputInterface::ERROR, sprintf('Expected argument %d of array_merge() to be %s, got %s on line %d', $i + 1, Array_::class, get_class($array), $array->getLine()));
}
}
}
}
}

return $keys;
$this->traverser->traverse($nodes);
return $this->visitor->get_array_keys();
}

/**
Expand Down
4 changes: 4 additions & 0 deletions tests/testFiles/language/en/common.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@
$lang = array_merge($lang, array(
'A' => 'First language string',
'B' => 'Second language string',
'C' => [
1 => 'Singular',
2 => 'Plural',
],
));
11 changes: 9 additions & 2 deletions tests/testFiles/language/en_complete/common.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@
'A' => 'First language string',
));

$lang = array_merge($lang, array(
$b = array(
'B' => 'Second language string',
));
);

$lang = array_merge($lang, $b, [
'C' => [
// Missing plural should not generate an error
1 => 'Singular',
],
]);
4 changes: 4 additions & 0 deletions tests/testFiles/language/en_incomplete/common.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@

$lang = array_merge($lang, array(
'A' => 'First language string',
'C' => [
1 => 'Singular',
2 => 'Plural',
],
));

0 comments on commit fc36bcd

Please sign in to comment.