TranslationExtractor::__construct()   A
last analyzed

Complexity

Conditions 4
Paths 5

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 7
c 1
b 0
f 0
dl 0
loc 14
ccs 8
cts 8
cp 1
rs 10
cc 4
nc 5
nop 3
crap 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Translator\Extractor;
6
7
use RuntimeException;
8
use Yiisoft\Files\FileHelper;
9
use Yiisoft\Files\PathMatcher\PathMatcher;
10
11
/**
12
 * Extracts translator IDs from files within a given path.
13
 */
14
final class TranslationExtractor
15
{
16
    private string $path;
17
18
    /** @var string[] */
19
    private array $only = ['**.php'];
20
21
    private array $skippedLines = [];
22
23
    /** @var string[] */
24
    private array $except = [
25
        '.svn',
26
        '.git',
27
        '.gitignore',
28
        '.gitkeep',
29
        '.hgignore',
30
        '.hgkeep',
31
        '/messages',
32
    ];
33
34
    /**
35
     * `TranslationExtractor` constructor.
36
     *
37
     * @param string $path Path to start extraction at.
38
     * @param string[]|null $only List of patterns that the files or directories should match. See {@see PathMatcher}.
39
     * @param string[]|null $except List of patterns that the files or directories should not match. See
40
     * {@see PathMatcher}.
41
     */
42 7
    public function __construct(string $path, ?array $only = null, ?array $except = null)
43
    {
44 7
        if (!is_dir($path)) {
45 1
            throw new RuntimeException(sprintf('Directory "%s" does not exist.', $path));
46
        }
47
48 6
        $this->path = $path;
49
50 6
        if ($only !== null) {
51 2
            $this->only = $only;
52
        }
53
54 6
        if ($except !== null) {
55 2
            $this->except = $except;
56
        }
57
    }
58
59
    /**
60
     * Extract messages.
61
     *
62
     * @param string $defaultCategory Category to use if category isn't set in translation call.
63
     * @param string|null $translatorCall Translation call to look for.
64
     *
65
     * @return array Extracted messages.
66
     */
67 6
    public function extract(string $defaultCategory = 'app', ?string $translatorCall = null): array
68
    {
69 6
        $messages = [];
70 6
        $parser = new ContentParser($defaultCategory, $translatorCall);
71
72 6
        $files = FileHelper::findFiles($this->path, [
73 6
            'filter' => (new PathMatcher())
74 6
                ->only(...$this->only)
75 6
                ->except(...$this->except),
76 6
            'recursive' => true,
77 6
        ]);
78
79 6
        foreach ($files as $file) {
80 6
            $fileContent = file_get_contents($file);
81 6
            $messages = array_merge_recursive($messages, $parser->extract($fileContent));
82 6
            if ($parser->hasSkippedLines()) {
83 4
                $this->skippedLines[$file] = $parser->getSkippedLines();
84
            }
85
        }
86
87 6
        return $messages;
88
    }
89
90
    /**
91
     * @return bool Whether there are skipped lines.
92
     */
93 6
    public function hasSkippedLines(): bool
94
    {
95 6
        return !empty($this->skippedLines);
96
    }
97
98
    /**
99
     * @return array Lines that were skipped during parsing.
100
     *
101
     * The format is:
102
     *
103
     * ```php
104
     * return [
105
     *     'fileName' => [
106
     *         [
107
     *             int $numberOfLine,
108
     *             string $incorrectLine,
109
     *         ],
110
     *     ],
111
     * ]
112
     * ```
113
     */
114 4
    public function getSkippedLines(): array
115
    {
116 4
        return $this->skippedLines;
117
    }
118
}
119