Completed
Push — nln-php7 ( 6680df...1a6b54 )
by Nicolas
02:06
created

Parser::parseFromMasterFile()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 21
ccs 10
cts 10
cp 1
rs 9.584
c 0
b 0
f 0
cc 4
nc 5
nop 1
crap 4
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Karma\Configuration;
6
7
use Gaufrette\Filesystem;
8
use Karma\Configuration\Collections\SectionParserCollection;
9
use Karma\Configuration\Parser\NullParser;
10
use Karma\Configuration\Parser\SectionParser;
11
use Psr\Log\NullLogger;
12
13
class Parser implements FileParser
14
{
15
    use \Karma\Logging\LoggerAware;
16
17
    private SectionParserCollection
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_STRING, expecting T_FUNCTION or T_CONST
Loading history...
18
        $parsers;
19
    private ?SectionParser
20
        $currentParser;
21
    private array
22
        $parsedFiles;
23
    private Filesystem
24
        $fs;
25
    private string
26
        $eol;
27
28 280
    public function __construct(Filesystem $fs)
29
    {
30 280
        $this->logger = new NullLogger();
31 280
        $this->parsers = new SectionParserCollection();
32
33 280
        $this->parsedFiles = [];
34 280
        $this->fs = $fs;
35 280
        $this->eol = "\n";
36 280
    }
37
38 49
    public function setEOL(string $eol): self
39
    {
40 49
        $this->eol = $eol;
41
42 49
        return $this;
43
    }
44
45 280
    public function enableIncludeSupport(): self
46
    {
47 280
        $this->parsers->enableIncludeSupport();
48
49 280
        return $this;
50
    }
51
52 280
    public function enableExternalSupport(): self
53
    {
54 280
       $this->parsers->enableExternalSupport($this->fs);
55
56 280
        return $this;
57
    }
58
59 270
    public function enableGroupSupport(): self
60
    {
61 270
        $this->parsers->enableGroupSupport();
62
63 270
        return $this;
64
    }
65
66 280
    public function parse(string $masterFilePath): array
67
    {
68
        try
69
        {
70 280
            $this->parseFromMasterFile($masterFilePath);
71
72 247
            $variables = $this->getVariables();
73 247
            $this->printExternalFilesStatus();
74
75 247
            $this->postParse();
76
77 245
            return $variables;
78
        }
79 36
        catch(\RuntimeException $e)
80
        {
81 36
            $this->error($e->getMessage());
82
83 36
            throw $e;
84
        }
85
    }
86
87 280
    private function parseFromMasterFile(string $masterFilePath): void
88
    {
89 280
        $files = [$masterFilePath];
90
91 280
        while(! empty($files))
92
        {
93 280
            foreach($files as $file)
94
            {
95 280
                $this->parseFile($file);
96
            }
97
98 249
            $parser = $this->parsers->includes();
99 249
            if($parser !== null)
100
            {
101 248
                $files = $parser->getCollectedFiles();
102
            }
103
104
            // Avoid loop
105 249
            $files = array_diff($files, $this->parsedFiles);
106
        }
107 247
    }
108
109 280
    private function parseFile(string $filePath): void
110
    {
111 280
        $this->parsedFiles[] = $filePath;
112 280
        $lines = $this->extractLines($filePath);
113 280
        $this->changeCurrentFile($filePath);
114
115 280
        $this->currentParser = new NullParser();
116 280
        $currentLineNumber = 0;
117
118 280
        foreach($lines as $line)
119
        {
120 280
            $currentLineNumber++;
121
122 280
            if(empty($line))
123
            {
124 217
                continue;
125
            }
126
127 275
            $sectionName = $this->extractSectionName($line);
128 275
            if($sectionName !== null)
129
            {
130 273
                $this->switchSectionParser($sectionName);
131
132 272
                continue;
133
            }
134
135 274
            $this->currentParser->parse($line, $currentLineNumber);
136
        }
137
138 250
        $this->parsers->variables()->endOfFileCheck();
139 249
    }
140
141 280
    private function extractLines(string $filePath): array
142
    {
143 280
        if(! $this->fs->has($filePath))
144
        {
145 1
            throw new \RuntimeException("$filePath does not exist");
146
        }
147
148 280
        $content = $this->fs->read($filePath);
149
150 280
        $lines = explode($this->eol, $content ?? '');
151 280
        $lines = $this->trimLines($lines);
152
153 280
        if(empty($lines))
154
        {
155
            $this->warning("Empty file ($filePath)");
156
        }
157
158 280
        return $lines;
159
    }
160
161 280
    private function trimLines(array $lines): array
162
    {
163 280
        return array_map('trim', $lines);
164
    }
165
166 280
    private function changeCurrentFile(string $filePath): void
167
    {
168 280
        $this->info("Reading $filePath");
169
170 280
        foreach($this->parsers as $parser)
171
        {
172 280
            $parser->setCurrentFile($filePath);
173
        }
174 280
    }
175
176 275
    private function extractSectionName(string $line): ?string
177
    {
178 275
        $sectionName = null;
179
180
        // [.*]
181 275
        if(preg_match('~^\[(?P<sectionName>[^\]]+)\]$~', $line, $matches))
182
        {
183 273
            $sectionName = strtolower(trim($matches['sectionName']));
184
        }
185
186 275
        return $sectionName;
187
    }
188
189 273
    private function switchSectionParser(string $sectionName): void
190
    {
191 273
        $this->currentParser = $this->parsers->get($sectionName);
192 272
    }
193
194 247
    public function getVariables(): array
195
    {
196 247
        return $this->parsers->variables()->getVariables();
197
    }
198
199 209
    public function getFileSystem(): Filesystem
200
    {
201 209
        return $this->fs;
202
    }
203
204 184
    public function getExternalVariables(): array
205
    {
206 184
        $variables = [];
207
208 184
        $parser = $this->parsers->externals();
209 184
        if($parser !== null)
210
        {
211 184
            $variables = $parser->getExternalVariables();
212
        }
213
214 184
        return $variables;
215
    }
216
217 247
    private function printExternalFilesStatus(): void
218
    {
219 247
        $files = $this->getExternalFilesStatus();
220
221 247
        foreach($files as $file => $status)
222
        {
223 209
            if($status['found'] === false)
224
            {
225 198
                $this->warning(sprintf(
226 198
                   'External file %s was not found',
227
                   $file
228
                ));
229
            }
230
        }
231 247
    }
232
233 247
    private function getExternalFilesStatus(): array
234
    {
235 247
        $files = [];
236
237 247
        $parser = $this->parsers->externals();
238 247
        if($parser !== null)
239
        {
240 246
            $files = $parser->getExternalFilesStatus();
241
        }
242
243 247
        return $files;
244
    }
245
246 46
    public function getGroups(): array
247
    {
248 46
        $groups = [];
249
250 46
        $parser = $this->parsers->groups();
251 46
        if($parser !== null)
252
        {
253 38
            $groups = $parser->getCollectedGroups();
254
        }
255
256 46
        return $groups;
257
    }
258
259 247
    private function postParse(): void
260
    {
261 247
        foreach($this->parsers as $parser)
262
        {
263 247
            $parser->postParse();
264
        }
265 245
    }
266
267 4
    public function isSystem(string $variableName): bool
268
    {
269 4
        $system = false;
270
271 4
        $variables = $this->getVariables();
272 4
        if(isset($variables[$variableName]))
273
        {
274 4
            $system = $variables[$variableName]['system'];
275
        }
276
277 4
        return $system;
278
    }
279
280 41
    public function getDefaultEnvironmentsForGroups(): array
281
    {
282 41
        $defaultEnvironments = [];
283
284 41
        $parser = $this->parsers->groups();
285 41
        if($parser !== null)
286
        {
287 33
            $defaultEnvironments = $parser->getDefaultEnvironmentsForGroups();
288
        }
289
290 41
        return $defaultEnvironments;
291
    }
292
}
293