Skip to content

Commit 2836947

Browse files
committed
feat: add extensive support for loops
1 parent 70477d9 commit 2836947

File tree

1 file changed

+57
-48
lines changed

1 file changed

+57
-48
lines changed

src/UI/Core.php

Lines changed: 57 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -128,14 +128,14 @@ protected static function buildComponent(Component $component, array $config, bo
128128
return [
129129
'responseType' => 'json',
130130
'html' => $withoutScripts ?
131-
static::compileTemplate($component->render()) :
131+
static::compileTemplate($component->render(), $pageState) :
132132
str_replace(
133133
'</body>',
134134
Core::createElement('script', [], ['
135135
window._leafUIConfig.methods = ' . json_encode(array_unique(static::$componentMethods)) . ';
136136
window._leafUIConfig.components = ' . json_encode(static::$components) . ';
137137
']) . Core::init() . '</body>',
138-
static::compileTemplate($component->render())
138+
static::compileTemplate($component->render(), $pageState)
139139
),
140140
'state' => $pageState,
141141
];
@@ -158,7 +158,7 @@ protected static function buildComponent(Component $component, array $config, bo
158158
el: document.querySelector("body"),
159159
component: "' . $component::class . '",
160160
components: ' . json_encode(static::$components) . ',
161-
data: ' . json_encode(array_unique($pageState)) . ',
161+
data: ' . json_encode(array_merge($pageState, ['key' => null])) . ',
162162
methods: ' . json_encode(array_unique(static::$componentMethods)) . ',
163163
path: "' . $_SERVER['REQUEST_URI'] . '",
164164
requestMethod: "' . $_SERVER['REQUEST_METHOD'] . '",
@@ -206,6 +206,58 @@ public static function compileTemplate(string $rawText, array $state = []): stri
206206
return eval("return $compiledWithVars;");
207207
}, $compiled);
208208

209+
$compiled = preg_replace_callback('/@loop\([\s\S]*?\)\s*[\s\S]*@endloop\s*/', function ($matches) use ($state) {
210+
$rendered = '';
211+
$loopMatches = null;
212+
213+
preg_match('/@loop\((.*?)\)/', $matches[0], $loopMatches);
214+
215+
$dataToLoop = "return $loopMatches[1];";
216+
217+
if (strpos($loopMatches[1], '$') !== false) {
218+
$loopMatches[1] = $state[ltrim(trim($loopMatches[1]), '$')] ?? trigger_error($loopMatches[1] . ' is not defined', E_USER_ERROR);
219+
$dataToLoop = 'return json_decode(\'' . json_encode($loopMatches[1]) . '\', true);';
220+
}
221+
222+
static::loop(eval($dataToLoop), function ($value, $key) use ($matches, &$rendered, $state) {
223+
$regex = '/@loop\((.*?)\)([\s\S]*?)@endloop/';
224+
preg_match($regex, $matches[0], $regexLoopMatches);
225+
226+
preg_match('/@key/', $regexLoopMatches[2], $keyMatches);
227+
preg_match('/@value/', $regexLoopMatches[2], $valueMatches);
228+
229+
$renderedString = str_replace(
230+
['@key', '@value', "\""],
231+
[$key, '$value', "'"],
232+
preg_replace(
233+
'/@value\[[\'"][^\'"]*[\'"]\]/',
234+
'{$0}',
235+
preg_replace_callback(
236+
'/@if\((.*?)\)/',
237+
function ($ifStatementMatches) {
238+
$compiledIf = '';
239+
240+
if (strpos($ifStatementMatches[1], '@value[') !== false) {
241+
$compiledIf = preg_replace('/@value\[[\'"]([^\'"]*)[\'"]\]/', '\'@value[\'$1\']\'', $ifStatementMatches[0]);
242+
}
243+
244+
if (strpos($compiledIf, '@key') !== false) {
245+
$compiledIf = str_replace('@key', '\'@key\'', $compiledIf);
246+
}
247+
248+
return $compiledIf;
249+
},
250+
$regexLoopMatches[2]
251+
)
252+
)
253+
);
254+
255+
$rendered .= eval("\$value = json_decode('" . json_encode($value) . "', true); return \"$renderedString\";");
256+
});
257+
258+
return $rendered;
259+
}, $compiled);
260+
209261
$compiled = preg_replace_callback('/@if\([\s\S]*?\)\s*[\s\S]*?(\s*@endif\s*)/', function ($matches) use ($state) {
210262
$renderedData = '';
211263
$compiledWithParsedConditions = preg_replace_callback('/\$([a-zA-Z0-9_]+)/', function ($matches) use ($state) {
@@ -223,6 +275,7 @@ public static function compileTemplate(string $rawText, array $state = []): stri
223275

224276
$renderedData = preg_replace('/@if\([\s\S]*?\)\s*[\s\S]*?/', '', $ifConditionMatches[0]);
225277
$renderedData = preg_replace('/\s*@elseif\([\s\S]*?\)\s*[\s\S]*?/', '', $renderedData);
278+
$renderedData = preg_replace('/\s*@else\s*[\s\S]*?/', '', $renderedData);
226279
} else {
227280
if (strpos($compiledWithParsedConditions, '@elseif') !== false) {
228281
preg_match('/@elseif\((.*?)\)/', $compiledWithParsedConditions, $elseifCondition);
@@ -251,50 +304,6 @@ public static function compileTemplate(string $rawText, array $state = []): stri
251304
return $renderedData;
252305
}, $compiled);
253306

254-
$compiled = preg_replace_callback('/@for\([\s\S]*?\)\s*[\s\S]*?(\s*@endfor\s*)/', function ($matches) {
255-
return "<?php for ($matches[1]): ?>";
256-
}, $compiled);
257-
258-
$compiled = preg_replace_callback('/@foreach\([\s\S]*?\)\s*[\s\S]*?(\s*@endforeach\s*)/', function ($matches) {
259-
return "<?php foreach ($matches[1]): ?>";
260-
}, $compiled);
261-
262-
$compiled = preg_replace_callback('/@switch\([\s\S]*?\)\s*[\s\S]*?(\s*@endswitch\s*)/', function ($matches) {
263-
return "<?php switch ($matches[1]): ?>";
264-
}, $compiled);
265-
266-
$compiled = preg_replace_callback('/@loop\([\s\S]*?\)\s*[\s\S]*@endloop\s*/', function ($matches) {
267-
$rendered = '';
268-
$loopMatches = null;
269-
270-
preg_match('/@loop\((.*?)\)/', $matches[0], $loopMatches);
271-
272-
static::loop(eval("return $loopMatches[1];"), function ($key, $value) use ($matches, &$rendered) {
273-
$regex = '/@loop\((.*?)\)([\s\S]*?)@endloop/';
274-
preg_match($regex, $matches[0], $regexLoopMatches);
275-
276-
$rendered .= str_replace(
277-
['@key', '@value'],
278-
[$key, $value],
279-
$regexLoopMatches[2]
280-
);
281-
});
282-
283-
return $rendered;
284-
}, $compiled);
285-
286-
$compiled = preg_replace_callback('/@case\((.*?)\)/', function ($matches) {
287-
return "<?php case $matches[1]: ?>";
288-
}, $compiled);
289-
290-
$compiled = preg_replace_callback('/@break/', function ($matches) {
291-
return "<?php break; ?>";
292-
}, $compiled);
293-
294-
$compiled = preg_replace_callback('/@continue/', function ($matches) {
295-
return "<?php continue; ?>";
296-
}, $compiled);
297-
298307
$compiled = preg_replace_callback('/@php\s*([\s\S]+?)\s*@endphp/', function ($matches) {
299308
return eval($matches[1]);
300309
}, $compiled);
@@ -338,7 +347,7 @@ public static function component(string $component, array $props = []): string
338347
$component->key = static::randomId($component::class);
339348
}
340349

341-
static::$state[$component->key] = array_unique(array_merge(get_class_vars($component::class), $props, static::$state[$component->key] ?? []));
350+
static::$state[$component->key] = array_merge(get_class_vars($component::class), $props, static::$state[$component->key] ?? []);
342351
static::$componentMethods = array_merge(static::$componentMethods, get_class_methods($component));
343352
static::$mappedComponentMethods = array_merge(static::$mappedComponentMethods, [$component->key => get_class_methods($component)]);
344353
static::$components = array_merge(static::$components, [$component->key => $component::class]);

0 commit comments

Comments
 (0)