diff --git a/README.md b/README.md index 0ea2d3a..3a8a23d 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,7 @@ The command detects the following in your blade and application files: - `app('translator')->get('key')` any direct `get`method call on the `translator` - `App::make('translator')->get('key')` any direct `get` method call on the `translator` - `Lang::get('key')` any `get` static call on the `Lang` facade +- `<<<'blade'` incline components in nowdoc with `blade` label are compiled and their content is scanned. ## Implementation diff --git a/src/BladeNowdocFinder.php b/src/BladeNowdocFinder.php new file mode 100644 index 0000000..835a389 --- /dev/null +++ b/src/BladeNowdocFinder.php @@ -0,0 +1,51 @@ +parser = $parser ?? (new ParserFactory())->createForHostVersion(); + } + + /** + * Find occurrences of translations in a string. + * + * @param string $str + * @return \PhpParser\Node[] + */ + public function find(string $str): array + { + $nodes = $this->parser->parse($str); + + if (empty($nodes)) { + return []; + } + + $visitor = new FindingVisitor(function ($node) { + return $node instanceof String_ + && strtolower($node->getAttribute('docLabel', '')) === 'blade'; + }); + + $traverser = new NodeTraverser(); + $traverser->addVisitor($visitor); // For compatibility with ^4.10 + + $traverser->traverse($nodes); + + return $visitor->getFoundNodes(); + } +} \ No newline at end of file diff --git a/src/Console/Commands/FindMissingTranslationStrings.php b/src/Console/Commands/FindMissingTranslationStrings.php index 3616185..593413d 100644 --- a/src/Console/Commands/FindMissingTranslationStrings.php +++ b/src/Console/Commands/FindMissingTranslationStrings.php @@ -24,7 +24,8 @@ class FindMissingTranslationStrings extends Command */ protected $signature = 'lost-in-translation:find {locale : The locale to be checked} - {--sorted : Sort the values before printing}'; + {--sorted : Sort the values before printing} + {--no-progress : Do not show the progress bar}'; /** * The console command description. @@ -63,21 +64,9 @@ public function handle(LostInTranslation $lit) return Str::endsWith($file->getExtension(), 'php'); }); - $reported = []; + $missing = $this->trackProgress($files, $this->makeMissingTranslationFinderCallback($lit, $locale)); - $this->invalidArguments = []; - $this->trackProgress($files, function (SplFileInfo $file) use ($lit, $locale, &$reported) { - $nodes = $lit->findInFile($file); - - $translationKeys = $this->resolveFirstArgs($lit, $nodes); - - foreach ($translationKeys as $key) { - if (!Lang::has($key, $locale) && !array_key_exists($key, $reported)) { - // TODO: find a better way to check uniqueness - $reported[$key] = true; - } - } - })->clear(); + $missing = array_unique(array_merge(...$missing)); if ($this->output->getVerbosity() >= $this->parseVerbosity(OutputInterface::VERBOSITY_VERBOSE)) { $errOutput = $this->output->getErrorStyle(); @@ -87,13 +76,11 @@ public function handle(LostInTranslation $lit) } } - $keys = array_keys($reported); - if ($this->option('sorted')) { - sort($keys); + sort($missing); } - foreach ($keys as $key) { + foreach ($missing as $key) { $this->line(OutputFormatter::escape($key)); } } @@ -103,23 +90,38 @@ public function handle(LostInTranslation $lit) * * @param \Countable|array $totalSteps * @param \Closure $callback - * @return \Symfony\Component\Console\Helper\ProgressBar + * @return array */ protected function trackProgress(Countable|array $totalSteps, Closure $callback) { + $items = []; + + if ($this->option('no-progress')) { + foreach ($totalSteps as $value) { + if (($item = $callback($value)) && $item !== null) { + $items[] = $item; + } + } + + return $items; + } + $bar = $this->output->createProgressBar(count($totalSteps)); $bar->start(); foreach ($totalSteps as $value) { - $callback($value, $bar); + if (($item = $callback($value)) && $item !== null) { + $items[] = $item; + } $bar->advance(); } $bar->finish(); + $bar->clear(); - return $bar; + return $items; } /** @@ -141,4 +143,29 @@ protected function resolveFirstArgs(LostInTranslation $lit, array $nodes): array } return array_unique($translationKeys); } + + /** + * @param \CodingSocks\LostInTranslation\LostInTranslation $lit + * @param string|null $locale + * @return \Closure + */ + protected function makeMissingTranslationFinderCallback(LostInTranslation $lit, string|null $locale): Closure + { + return function (SplFileInfo $file) use ($lit, $locale) { + $nodes = $lit->findInFile($file); + + $translationKeys = $this->resolveFirstArgs($lit, $nodes); + + $missing = []; + + foreach ($translationKeys as $key) { + if (!Lang::has($key, $locale)) { + // TODO: find a better way to check uniqueness + $missing[] = $key; + } + } + + return $missing; + }; + } } \ No newline at end of file diff --git a/src/LostInTranslation.php b/src/LostInTranslation.php index a3a9d7f..e42e1b6 100644 --- a/src/LostInTranslation.php +++ b/src/LostInTranslation.php @@ -36,9 +36,20 @@ public function findInFile(SplFileInfo $file): array if ($this->isBladeFile($file)) { $str = $this->compiler->compileString($str); + + return $finder->find($str); + } + + $found = []; + $nowdocFinder = new BladeNowdocFinder(); + + foreach ($nowdocFinder->find($str) as $node) { + $str = $this->compiler->compileString($node->value); + + array_push($found, ...$finder->find($str)); } - return $finder->find($str); + return array_merge($found, $finder->find($str)); } /** diff --git a/src/TranslationFinder.php b/src/TranslationFinder.php index d0b8983..c339251 100644 --- a/src/TranslationFinder.php +++ b/src/TranslationFinder.php @@ -19,7 +19,6 @@ class TranslationFinder private $printer; /** - * @param \Illuminate\View\Compilers\BladeCompiler $compiler * @param array $detect * @param \PhpParser\Parser|null $parser * @param \PhpParser\PrettyPrinter $printer diff --git a/tests/BladeNowdocFinderTest.php b/tests/BladeNowdocFinderTest.php new file mode 100644 index 0000000..7a4ebe8 --- /dev/null +++ b/tests/BladeNowdocFinderTest.php @@ -0,0 +1,49 @@ + + + +eod; + } + + /** + * Get the view / contents that represent the component. + */ + public function keep(): string + { + return <<<'blade' +
+ +
+blade; + } +} +EOD; + + $finder = new BladeNowdocFinder(); + + $nodes = $finder->find($str); + + $this->assertCount(1, $nodes); + } +} \ No newline at end of file