Skip to content

Commit

Permalink
Merge pull request #8285 from neznaika0/lang-find-show-bad-keys
Browse files Browse the repository at this point in the history
feat: [Commands] `lang:find` show bad keys when scanning (v2)
  • Loading branch information
kenjis authored Dec 8, 2023
2 parents a922030 + 9747d12 commit 778f18e
Show file tree
Hide file tree
Showing 6 changed files with 236 additions and 9 deletions.
48 changes: 39 additions & 9 deletions system/Commands/Translation/LocalizationFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public function run(array $params)
if (is_string($optionDir)) {
$tempCurrentDir = realpath($currentDir . $optionDir);

if (false === $tempCurrentDir) {
if ($tempCurrentDir === false) {
CLI::error('Error: Directory must be located in "' . $currentDir . '"');

return EXIT_USER_INPUT;
Expand Down Expand Up @@ -113,7 +113,12 @@ private function process(string $currentDir, string $currentLocale): void
$files = iterator_to_array($iterator, true);
ksort($files);

[$foundLanguageKeys, $countFiles] = $this->findLanguageKeysInFiles($files);
[
'foundLanguageKeys' => $foundLanguageKeys,
'badLanguageKeys' => $badLanguageKeys,
'countFiles' => $countFiles
] = $this->findLanguageKeysInFiles($files);

ksort($foundLanguageKeys);

$languageDiff = [];
Expand All @@ -137,7 +142,7 @@ private function process(string $currentDir, string $currentLocale): void
$newLanguageKeys = array_replace_recursive($foundLanguageKeys[$langFileName], $languageStoredKeys);

if ($languageDiff !== []) {
if (false === file_put_contents($languageFilePath, $this->templateFile($newLanguageKeys))) {
if (file_put_contents($languageFilePath, $this->templateFile($newLanguageKeys)) === false) {
$this->writeIsVerbose('Lang file ' . $langFileName . ' (error write).', 'red');
} else {
$this->writeIsVerbose('Lang file "' . $langFileName . '" successful updated!', 'green');
Expand All @@ -157,14 +162,30 @@ private function process(string $currentDir, string $currentLocale): void

$this->writeIsVerbose('Files found: ' . $countFiles);
$this->writeIsVerbose('New translates found: ' . $countNewKeys);
$this->writeIsVerbose('Bad translates found: ' . count($badLanguageKeys));

if ($this->verbose && $badLanguageKeys !== []) {
$tableBadRows = [];

foreach ($badLanguageKeys as $value) {
$tableBadRows[] = [$value[1], $value[0]];
}

ArrayHelper::sortValuesByNatural($tableBadRows, 0);

CLI::table($tableBadRows, ['Bad Key', 'Filepath']);
}
}

/**
* @param SplFileInfo|string $file
*
* @return array<string, array>
*/
private function findTranslationsInFile($file): array
{
$foundLanguageKeys = [];
$badLanguageKeys = [];

if (is_string($file) && is_file($file)) {
$file = new SplFileInfo($file);
Expand All @@ -174,14 +195,16 @@ private function findTranslationsInFile($file): array
preg_match_all('/lang\(\'([._a-z0-9\-]+)\'\)/ui', $fileContent, $matches);

if ($matches[1] === []) {
return [];
return compact('foundLanguageKeys', 'badLanguageKeys');
}

foreach ($matches[1] as $phraseKey) {
$phraseKeys = explode('.', $phraseKey);

// Language key not have Filename or Lang key
if (count($phraseKeys) < 2) {
$badLanguageKeys[] = [mb_substr($file->getRealPath(), mb_strlen(ROOTPATH)), $phraseKey];

continue;
}

Expand All @@ -191,6 +214,8 @@ private function findTranslationsInFile($file): array
|| ($languageFileName === '' && $phraseKeys[0] === '');

if ($isEmptyNestedArray) {
$badLanguageKeys[] = [mb_substr($file->getRealPath(), mb_strlen(ROOTPATH)), $phraseKey];

continue;
}

Expand All @@ -203,7 +228,7 @@ private function findTranslationsInFile($file): array
}
}

return $foundLanguageKeys;
return compact('foundLanguageKeys', 'badLanguageKeys');
}

private function isIgnoredFile(SplFileInfo $file): bool
Expand Down Expand Up @@ -336,12 +361,13 @@ private function isSubDirectory(string $directory, string $rootDirectory): bool
/**
* @param SplFileInfo[] $files
*
* @return array<int, array|int>
* @phpstan-return list{0: array<string, array<string, string>>, 1: int}
* @return array<string, array|int>
* @phpstan-return array{'foundLanguageKeys': array<string, array<string, string>>, 'badLanguageKeys': array<int, array<int, string>>, 'countFiles': int}
*/
private function findLanguageKeysInFiles(array $files): array
{
$foundLanguageKeys = [];
$badLanguageKeys = [];
$countFiles = 0;

foreach ($files as $file) {
Expand All @@ -351,9 +377,13 @@ private function findLanguageKeysInFiles(array $files): array

$this->writeIsVerbose('File found: ' . mb_substr($file->getRealPath(), mb_strlen(APPPATH)));
$countFiles++;
$foundLanguageKeys = array_replace_recursive($this->findTranslationsInFile($file), $foundLanguageKeys);

$findInFile = $this->findTranslationsInFile($file);

$foundLanguageKeys = array_replace_recursive($findInFile['foundLanguageKeys'], $foundLanguageKeys);
$badLanguageKeys = array_merge($findInFile['badLanguageKeys'], $badLanguageKeys);
}

return [$foundLanguageKeys, $countFiles];
return compact('foundLanguageKeys', 'badLanguageKeys', 'countFiles');
}
}
19 changes: 19 additions & 0 deletions system/Helpers/Array/ArrayHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
* If there are any methods that should be provided, make them
* public APIs via helper functions.
*
* @see \CodeIgniter\Helpers\Array\ArrayHelperDotKeyExistsTest
* @see \CodeIgniter\Helpers\Array\ArrayHelperRecursiveDiffTest
* @see \CodeIgniter\Helpers\Array\ArrayHelperSortValuesByNaturalTest
*/
final class ArrayHelper
{
Expand Down Expand Up @@ -299,4 +301,21 @@ public static function recursiveCount(array $array, int $counter = 0): int

return $counter;
}

/**
* Sorts array values in natural order
* If the value is an array, you need to specify the $sortByIndex of the key to sort
*
* @param int|string|null $sortByIndex
*/
public static function sortValuesByNatural(array &$array, $sortByIndex = null): bool
{
return usort($array, static function ($currentValue, $nextValue) use ($sortByIndex) {
if ($sortByIndex !== null) {
return strnatcmp($currentValue[$sortByIndex], $nextValue[$sortByIndex]);
}

return strnatcmp($currentValue, $nextValue);
});
}
}
7 changes: 7 additions & 0 deletions tests/_support/Services/Translation/TranslationTwo.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ public function list()
$translationError6 = lang('TranslationTwo...');
$translationError7 = lang('..invalid_nested_key..');

$copyTranslationError1 = lang('TranslationTwo');
$copyTranslationError2 = lang(' ');
$copyTranslationError3 = lang('');
$copyTranslationError4 = lang('.invalid_key');
$copyTranslationError5 = lang('TranslationTwo.');
$copyTranslationError6 = lang('TranslationTwo...');
$copyTranslationError7 = lang('..invalid_nested_key..');
// Empty in comments lang('') lang(' ')
}
}
29 changes: 29 additions & 0 deletions tests/system/Commands/Translation/LocalizationFinderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,15 @@ public function testShowNewTranslation(): void
$this->assertStringContainsString($this->getActualTableWithNewKeys(), $this->getStreamFilterBuffer());
}

public function testShowBadTranslation(): void
{
$this->makeLocaleDirectory();

command('lang:find --dir Translation --verbose');

$this->assertStringContainsString($this->getActualTableWithBadKeys(), $this->getStreamFilterBuffer());
}

private function getActualTranslationOneKeys(): array
{
return [
Expand Down Expand Up @@ -195,6 +204,26 @@ private function getActualTableWithNewKeys(): string
TEXT_WRAP;
}

private function getActualTableWithBadKeys(): string
{
return <<<'TEXT_WRAP'
+------------------------+--------------------------------------------------------+
| Bad Key | Filepath |
+------------------------+--------------------------------------------------------+
| ..invalid_nested_key.. | tests/_support/Services/Translation/TranslationTwo.php |
| ..invalid_nested_key.. | tests/_support/Services/Translation/TranslationTwo.php |
| .invalid_key | tests/_support/Services/Translation/TranslationTwo.php |
| .invalid_key | tests/_support/Services/Translation/TranslationTwo.php |
| TranslationTwo | tests/_support/Services/Translation/TranslationTwo.php |
| TranslationTwo | tests/_support/Services/Translation/TranslationTwo.php |
| TranslationTwo. | tests/_support/Services/Translation/TranslationTwo.php |
| TranslationTwo. | tests/_support/Services/Translation/TranslationTwo.php |
| TranslationTwo... | tests/_support/Services/Translation/TranslationTwo.php |
| TranslationTwo... | tests/_support/Services/Translation/TranslationTwo.php |
+------------------------+--------------------------------------------------------+
TEXT_WRAP;
}

private function assertTranslationsExistAndHaveTranslatedKeys(): void
{
$this->assertFileExists(self::$languageTestPath . self::$locale . '/TranslationOne.php');
Expand Down
121 changes: 121 additions & 0 deletions tests/system/Helpers/Array/ArrayHelperSortValuesByNaturalTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<?php

/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace CodeIgniter\Helpers\Array;

use CodeIgniter\Test\CIUnitTestCase;

/**
* @group Others
*
* @internal
*/
final class ArrayHelperSortValuesByNaturalTest extends CIUnitTestCase
{
private array $arrayWithStringValues = [
'apple10',
'banana',
'apple1',
'банан',
'Banana',
'Apple',
100000,
'яблоко',
1200,
13000,
'Банан',
'Яблоко',
'apple',
];
private array $arrayWithArrayValues = [
['apple', 'Banana'],
['apple10', 'Apple'],
['Яблоко', 1200],
[13000, 'Банан'],
['Apple', 'apple1'],
['banana', 'банан'],
[100000, 13000],
['Banana', 'Яблоко'],
['Банан', 'banana'],
[1200, 'apple'],
['apple1', 'apple10'],
['яблоко', 100000],
['банан', 'яблоко'],
];

public function testSortWithStringValues(): void
{
shuffle($this->arrayWithStringValues);

ArrayHelper::sortValuesByNatural($this->arrayWithStringValues);

$this->assertSame([
1200,
13000,
100000,
'Apple',
'Banana',
'apple',
'apple1',
'apple10',
'banana',
'Банан',
'Яблоко',
'банан',
'яблоко',
], $this->arrayWithStringValues);
}

public function testSortWithArrayValues(): void
{
shuffle($this->arrayWithArrayValues);

// For first index
ArrayHelper::sortValuesByNatural($this->arrayWithArrayValues, 0);

$this->assertSame([
[1200, 'apple'],
[13000, 'Банан'],
[100000, 13000],
['Apple', 'apple1'],
['Banana', 'Яблоко'],
['apple', 'Banana'],
['apple1', 'apple10'],
['apple10', 'Apple'],
['banana', 'банан'],
['Банан', 'banana'],
['Яблоко', 1200],
['банан', 'яблоко'],
['яблоко', 100000],
], $this->arrayWithArrayValues);

shuffle($this->arrayWithArrayValues);

// For other index
ArrayHelper::sortValuesByNatural($this->arrayWithArrayValues, 1);

$this->assertSame([
['Яблоко', 1200],
[100000, 13000],
['яблоко', 100000],
['apple10', 'Apple'],
['apple', 'Banana'],
[1200, 'apple'],
['Apple', 'apple1'],
['apple1', 'apple10'],
['Банан', 'banana'],
[13000, 'Банан'],
['Banana', 'Яблоко'],
['banana', 'банан'],
['банан', 'яблоко'],
], $this->arrayWithArrayValues);
}
}
21 changes: 21 additions & 0 deletions user_guide_src/source/outgoing/localization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,27 @@ Before updating, it is possible to preview the translations found by the command
php spark lang:find --verbose --show-new
The detailed output of ``--verbose`` also shows a list of invalid keys. For example:

.. code-block:: console
...
Files found: 10
New translates found: 30
Bad translates found: 5
+------------------------+---------------------------------+
| Bad Key | Filepath |
+------------------------+---------------------------------+
| ..invalid_nested_key.. | app/Controllers/Translation.php |
| .invalid_key | app/Controllers/Translation.php |
| TranslationBad | app/Controllers/Translation.php |
| TranslationBad. | app/Controllers/Translation.php |
| TranslationBad... | app/Controllers/Translation.php |
+------------------------+---------------------------------+
All operations done!
For a more accurate search, specify the desired locale or directory to scan.

.. code-block:: console
Expand Down

0 comments on commit 778f18e

Please sign in to comment.