Skip to content

Commit 327098c

Browse files
committed
Create TemplateParser.php
1 parent abc0b61 commit 327098c

File tree

1 file changed

+171
-0
lines changed

1 file changed

+171
-0
lines changed
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
<?php
2+
3+
namespace Ubiquity\views\engine\twig;
4+
5+
use Ubiquity\utils\base\UString;
6+
use Ubiquity\views\engine\TemplateGenerator;
7+
8+
class TemplateParser {
9+
10+
private TemplateGenerator $generator;
11+
12+
private string $varPattern = '@\{\{\s?(.*?)\s?}}@';
13+
14+
private string $blockPattern = '@\{%\s?block\s(.*?)\s?%}@';
15+
16+
public function __construct(TemplateGenerator $generator) {
17+
$this->generator = $generator;
18+
}
19+
20+
private function parseVar(string $varStr): array {
21+
$parts = \explode('|', $varStr);
22+
return ['name' => trim($parts[0]), 'safe' => isset($parts[1])];
23+
}
24+
25+
private function parseForeach(string $foreachStr): array {
26+
$parts = \explode('in', $foreachStr);
27+
$kv = explode(',', $parts[0]);
28+
$v = \trim($parts[0]);
29+
$k = null;
30+
if (\count($kv) > 1) {
31+
$k = \trim($kv[0]);
32+
$v = \trim($kv[1]);
33+
}
34+
return ['array' => trim($parts[1]), 'value' => $v, 'key' => $k];
35+
}
36+
37+
private function getExpressionPattern(string $clause): string {
38+
return '@\{\%\s?' . $clause . '\s(.*?)\s?\%\}@';
39+
}
40+
41+
protected function parseAllVars(string $text): string {
42+
$result = $text;
43+
if (\preg_match_all($this->varPattern, $text, $matches)) {
44+
$originals = $matches[0];
45+
$vars = $matches[1];
46+
foreach ($vars as $index => $varStr) {
47+
$variableInfos = $this->parseVar($varStr);
48+
$result = \str_replace($originals[$index], $this->generator->insertVariable($variableInfos['name'], $variableInfos['safe']), $result);
49+
}
50+
}
51+
return $result;
52+
}
53+
54+
protected function parseEquality(string $text): string {
55+
$result = $text;
56+
if (\preg_match_all('@\{\{\s?(.*?)==(.*?)\s(.*?)\s?}}@', $text, $matches)) {
57+
$originals = $matches[0];
58+
$varsLeft = $matches[1];
59+
$varsRight = $matches[2];
60+
foreach ($originals as $index => $original) {
61+
$tmp = \str_replace($varsLeft[$index], $this->generator->asVariable($varsLeft[$index]), $original);
62+
$tmp = \str_replace($varsRight[$index], $this->generator->asVariable($varsRight[$index]), $tmp);
63+
$result = \str_replace($original, $tmp, $result);
64+
}
65+
}
66+
return $result;
67+
}
68+
69+
protected function parseAllConditions(string $text): string {
70+
$result = $text;
71+
if (\preg_match_all($this->getExpressionPattern('if'), $text, $matches)) {
72+
$originals = $matches[0];
73+
$conditions = $matches[1];
74+
foreach ($conditions as $index => $cond) {
75+
$result = \str_replace($originals[$index], $this->generator->condition($cond), $result);
76+
}
77+
}
78+
return $result;
79+
}
80+
81+
protected function parseAllForeachs(string $text): string {
82+
$result = $text;
83+
if (\preg_match_all($this->getExpressionPattern('for'), $text, $matches)) {
84+
$originals = $matches[0];
85+
$foreachs = $matches[1];
86+
foreach ($foreachs as $index => $foreach) {
87+
$foreachInfos = $this->parseForeach($foreach);
88+
$result = \str_replace($originals[$index], $this->generator->foreach($foreachInfos['array'], $foreachInfos['value'], $foreachInfos['key']), $result);
89+
}
90+
}
91+
return $result;
92+
}
93+
94+
protected function parseAllBlock(string $text): string {
95+
$result = $text;
96+
if (\preg_match_all($this->blockPattern, $text, $matches)) {
97+
$originals = $matches[0];
98+
$blocks = $matches[1];
99+
foreach ($blocks as $index => $block) {
100+
$blockName = \trim($block);
101+
$result = \str_replace($originals[$index], $this->generator->openBlock($blockName), $result);
102+
}
103+
}
104+
return $result;
105+
}
106+
107+
protected function parseCallback(string $text, string $pattern, $callback): string {
108+
$result = $text;
109+
if (\preg_match_all($pattern, $text, $matches)) {
110+
$originals = $matches[0];
111+
foreach ($originals as $elm) {
112+
$result = \str_replace($elm, $callback(), $result);
113+
}
114+
}
115+
return $result;
116+
}
117+
118+
protected function parseCallbackWithVar(string $text, string $pattern, $callback): string {
119+
$result = $text;
120+
if (\preg_match_all($pattern, $text, $matches)) {
121+
$originals = $matches[0];
122+
$vars = $matches[1];
123+
foreach ($vars as $index => $elm) {
124+
$elm = \trim($elm);
125+
$result = \str_replace($originals[$index], $callback($elm), $result);
126+
}
127+
}
128+
return $result;
129+
}
130+
131+
public function parseFileContent(string $fileContent): string {
132+
$result = $this->parseCallback($fileContent, '@\{\{\s?nonce\s?}}@', function () {
133+
return $this->generator->getNonce();
134+
});
135+
$result = $this->parseCallback($result, "@\{\s?nonce:\s?nonce\s?}@", function () {
136+
return $this->generator->getNonceArray();
137+
});
138+
$result = $this->parseCallback($result, '@\{\{\s?_self\s?}}@', function () {
139+
return $this->generator->getSelf();
140+
});
141+
$result = $this->parseAllVars($result);
142+
$result = $this->parseAllBlock($result);
143+
$result = $this->parseEquality($result);
144+
$result = $this->parseCallback($result, '@\{%\s?endblock\s?%}@', function () {
145+
return $this->generator->closeBlock();
146+
});
147+
$result = $this->parseAllForeachs($result);
148+
$result = $this->parseCallback($result, '@\{%\s?endfor\s?%}@', function () {
149+
return $this->generator->endForeach();
150+
});
151+
$result = $this->parseAllConditions($result);
152+
$result = $this->parseCallback($result, '@\{%\s?endif\s?%}@', function () {
153+
return $this->generator->endCondition();
154+
});
155+
$result = $this->parseCallbackWithVar($result, '@\{%\s?extends\s?(.*?)\s?%}@', function ($name) {
156+
$asVariable = !UString::containsValues(['"', "'"], $name);
157+
return $this->generator->extendsTemplate($name, $asVariable);
158+
});
159+
$result = $this->parseCallbackWithVar($result, '@\{%\s?include\s?(.*?)\s?%}@', function ($name) {
160+
$asVariable = !UString::containsValues(['"', "'"], $name);
161+
return $this->generator->includeFile($name, $asVariable);
162+
});
163+
$result = $this->parseCallbackWithVar($result, '@\{\{\s(.*?)\s?}}@', function ($content) {
164+
return $this->generator->getOpenVarTag() . $content . $this->generator->getCloseVarTag();
165+
});
166+
$result = $this->parseCallbackWithVar($result, '@\{%\s(.*?)\s?%}@', function ($content) {
167+
return $this->generator->getOpenExpressionTag() . $content . $this->generator->getCloseExpressionTag();
168+
});
169+
return $result;
170+
}
171+
}

0 commit comments

Comments
 (0)