diff --git a/composer.json b/composer.json index ace6b72..ca40167 100644 --- a/composer.json +++ b/composer.json @@ -37,6 +37,9 @@ "openai-php/client": "^0.10.1", "deeplcom/deepl-php": "^1.9" }, + "scripts": { + "test": "vendor/bin/phpunit tests" + }, "config": { "allow-plugins": { "php-http/discovery": true diff --git a/src/Extractor/RegexExtractor.php b/src/Extractor/RegexExtractor.php index 8d8eef9..39c1060 100644 --- a/src/Extractor/RegexExtractor.php +++ b/src/Extractor/RegexExtractor.php @@ -2,35 +2,59 @@ namespace Bottelet\TranslationChecker\Extractor; +use Illuminate\Support\Collection; +use Illuminate\Support\Str; use SplFileInfo; class RegexExtractor implements ExtractorContract { - /** - * @var array - */ - private array $patterns = [ - 'doubleUnderscoreSyntax' => '/(__\()([\'"])(.*?)\2/', - 'tSyntax' => '/(? '/\$_\([\'"]([^\'"]+)[\'"]\)/', - ]; + /** @var Collection */ + private Collection $patterns; + + public function __construct() + { + $this->patterns = collect([ + [ + 'regex' => '/(__\()([\'"])(.*?)\2/', + 'matchIndex' => 3, + 'group' => 'doubleUnderscoreSyntax', + ], + [ + 'regex' => '/(? 2, + 'group' => 'tSyntax', + ], + [ + 'regex' => '/\$_\([\'"]([^\'"]+)[\'"]\)/', + 'matchIndex' => 1, + 'group' => 'dollarUnderscorePattern', + ], + ]); + } + + public function addPattern(string $regex, int $matchIndex, ?string $group = null): void + { + $this->patterns->push([ + 'regex' => $regex, + 'matchIndex' => $matchIndex, + 'group' => $group ?? Str::random(10), + ]); + } public function extractFromFile(SplFileInfo $file): array { - $found = []; $contents = file_get_contents($file->getRealPath()); if (!$contents) { return []; } - if (preg_match_all($this->patterns['doubleUnderscoreSyntax'], $contents, $matches)) { - $found = array_merge($found, $matches[3]); - } - if (preg_match_all($this->patterns['tSyntax'], $contents, $matches)) { - $found = array_merge($found, $matches[2]); - } - if (preg_match_all($this->patterns['dollarUnderscorePattern'], $contents, $matches)) { - $found = array_merge($found, $matches[1]); + $found = []; + + /** @var array{regex: string, matchIndex: int, group: string} $pattern */ + foreach ($this->patterns as $pattern) { + if (preg_match_all($pattern['regex'], $contents, $matches)) { + $found = array_merge($found, $matches[$pattern['matchIndex']]); + } } return $found; diff --git a/tests/Extractors/RegexExtractorTest.php b/tests/Extractors/RegexExtractorTest.php index 6950b5f..2c9255a 100644 --- a/tests/Extractors/RegexExtractorTest.php +++ b/tests/Extractors/RegexExtractorTest.php @@ -76,4 +76,55 @@ public function should_not_find_emit_request_etc(): void $this->assertNotContains('request', $translationKeys); $this->assertNotContains('target', $translationKeys); } + + #[Test] + public function it_accepts_a_new_added_pattern(): void + { + $testPhpContent = <<<'TEXT' + mytranslatefunction('simple_string'); + mytranslatefunction('String with "double quotes"'); + mytranslatefunction('with :variable test', ['variable' => 'test']); + TEXT; + + file_put_contents($this->tempDir . '/test.php', $testPhpContent); + + $file = new SplFileInfo($this->tempDir . '/test.php'); + $extractor = new RegexExtractor; + + $extractor->addPattern('/(mytranslatefunction\()([\'"])(.*?)\2/', 3, 'mytranslatefunction'); + + $translationKeys = $extractor->extractFromFile($file); + + $this->assertCount(3, $translationKeys); + $this->assertContains('simple_string', $translationKeys); + $this->assertContains('String with "double quotes"', $translationKeys); + $this->assertContains('with :variable test', $translationKeys); + } + + #[Test] + public function it_accepts_a_new_added_pattern_that_matches_specific_cases(): void + { + $testPhpContent = <<<'TEXT' + mytranslatefunction('simple_string'); + mytranslatefunction('String with "double quotes"'); + mytranslatefunction('with :variable test', ['variable' => 'test']); + TEXT; + + file_put_contents($this->tempDir . '/test.php', $testPhpContent); + + $file = new SplFileInfo($this->tempDir . '/test.php'); + $extractor = new RegexExtractor; + + // Pattern that does not match translations with variables + $extractor->addPattern('/mytranslatefunction\((["\'])(.*?)\1\)/', 2, 'mytranslatefunction'); + + $translationKeys = $extractor->extractFromFile($file); + + $this->assertCount(2, $translationKeys); + $this->assertContains('simple_string', $translationKeys); + $this->assertContains('String with "double quotes"', $translationKeys); + + // Assert that the pattern does not match translations with variables + $this->assertNotContains('with :variable test', $translationKeys); + } }