MAPG-89 add classes that can link views into one PHP
This commit is contained in:
3 files changed
+263
No files matched your search
@@ -0,0 +1,128 @@
|
||||
<?php namespace MapGuesser\View;
|
||||
|
||||
class Parser
|
||||
{
|
||||
private string $file;
|
||||
|
||||
public function __construct(string $file)
|
||||
{
|
||||
$this->file = $file;
|
||||
}
|
||||
|
||||
public function parse(): ParsedFragment
|
||||
{
|
||||
|
||||
$sectionOpen = null;
|
||||
$extraOpen = false;
|
||||
|
||||
$extends = null;
|
||||
$sections = [];
|
||||
$extra = ['', ''];
|
||||
|
||||
$fileHandle = fopen($this->file, 'r');
|
||||
if (!$fileHandle) {
|
||||
throw new \Exception('Cannot open file ' . $this->file);
|
||||
}
|
||||
|
||||
$lineNumber = 0;
|
||||
while (($line = fgets($fileHandle)) !== false) {
|
||||
++$lineNumber;
|
||||
|
||||
if (($extendsMatched = $this->matchExtends($line)) !== null) {
|
||||
if ($extends !== null) {
|
||||
throw new \Exception('Error in file ' . $this->file . ' in line ' . $lineNumber . ' - There is already an \'@extends\' declared.');
|
||||
}
|
||||
|
||||
$extends = $extendsMatched;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (($sectionMatched = $this->matchSection($line)) !== null) {
|
||||
if ($extends === null) {
|
||||
throw new \Exception('Error in file ' . $this->file . ' in line ' . $lineNumber . ' - \'@section\' has no meaning if view extends nothing.');
|
||||
}
|
||||
if ($sectionOpen !== null) {
|
||||
throw new \Exception('Parse error in file ' . $this->file . ' in line ' . $lineNumber . ' - A \'@section\' is already open (no \'@endsection\' found).');
|
||||
}
|
||||
|
||||
$sectionOpen = $sectionMatched;
|
||||
$sections[$sectionOpen] = '';
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->matchEndSection($line)) {
|
||||
if ($sectionOpen === null) {
|
||||
throw new \Exception('Parse error in file ' . $this->file . ' in line ' . $lineNumber . ' - Cannot end section until no \'@section\' is open.');
|
||||
}
|
||||
|
||||
$sectionOpen = null;
|
||||
}
|
||||
|
||||
if ($this->matchExtra($line)) {
|
||||
if ($extraOpen) {
|
||||
throw new \Exception('Parse error in file ' . $this->file . ' in line ' . $lineNumber . ' - An \'@extra\' is already open (no \'@endextra\' found).');
|
||||
}
|
||||
|
||||
$extraOpen = true;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->matchEndExtra($line)) {
|
||||
if (!$extraOpen) {
|
||||
throw new \Exception('Parse error in file ' . $this->file . ' in line ' . $lineNumber . ' - Cannot end extra until no \'@extra\' is open.');
|
||||
}
|
||||
|
||||
$extraOpen = false;
|
||||
}
|
||||
|
||||
if ($sectionOpen !== null) {
|
||||
$sections[$sectionOpen] .= $line;
|
||||
}
|
||||
|
||||
if ($extraOpen) {
|
||||
$offset = $extends === null ? 0 : 1;
|
||||
$extra[$offset] .= $line;
|
||||
}
|
||||
}
|
||||
|
||||
fclose($fileHandle);
|
||||
|
||||
return new ParsedFragment($extends, $sections, $extra);
|
||||
}
|
||||
|
||||
private function matchExtends(string $line): ?string
|
||||
{
|
||||
if (preg_match('/^\s*@extends\(\'([\w\/]+)\'\)\s*$/', $line, $matches)) {
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function matchSection(string $line): ?string
|
||||
{
|
||||
if (preg_match('/^\s*@section\(\'(\w+)\'\)\s*$/', $line, $matches)) {
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function matchEndSection(string $line): bool
|
||||
{
|
||||
return preg_match('/^\s*@endsection(?:\(\))?\s*$/', $line);
|
||||
}
|
||||
|
||||
private function matchExtra(string $line): bool
|
||||
{
|
||||
return preg_match('/^\s*@extra(?:\(\))?\s*$/', $line);
|
||||
}
|
||||
|
||||
private function matchEndExtra(string $line): bool
|
||||
{
|
||||
return preg_match('/^\s*@endextra(?:\(\))?\s*$/', $line);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user