85 lines
3.4 KiB
PHP
85 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace Picea\ControlStructure;
|
|
|
|
enum PrintActionEnum : string {
|
|
case prepend = "prepend";
|
|
case default = "default";
|
|
case append = "append";
|
|
# case both = "both";
|
|
}
|
|
|
|
class SectionToken implements ControlStructure {
|
|
|
|
public array $token = [ "section", "endsection" ];
|
|
|
|
protected PrintActionEnum $action = PrintActionEnum::default;
|
|
|
|
public function parse(\Picea\Compiler\Context &$context, ?string $arguments, string $token, array $options = []) : string
|
|
{
|
|
if (in_array('prepend', $options)) {
|
|
$this->action = PrintActionEnum::prepend;
|
|
}
|
|
elseif (in_array('append', $options)) {
|
|
$this->action = PrintActionEnum::append;
|
|
}
|
|
|
|
switch($token) {
|
|
case "section":
|
|
return $this->printSection($context, $arguments);
|
|
|
|
case "endsection":
|
|
if ( empty($context->sections) ) {
|
|
throw new \RuntimeException("A section closing tag {% endsection %} was found without an opening {% section %} tag");
|
|
}
|
|
|
|
return $this->printEndSection($context);
|
|
}
|
|
}
|
|
|
|
protected function printSection($context, ? string $arguments) : string
|
|
{
|
|
list($name, $options) = array_pad(explode(',', $arguments, 2), 2, null);
|
|
|
|
if ( $options ?? false ) {
|
|
$options = eval("return $options;");
|
|
}
|
|
|
|
if ( ! ctype_alnum(str_replace([".", "\"", "'", "-", "_", ":"], "", $name)) ) {
|
|
throw new \RuntimeException("Your section named `{$name}` contains invalid character. Allowed are only letters, numbers, dashes, underscores and dots");
|
|
}
|
|
|
|
$context->sections[] = [
|
|
'name' => $name,
|
|
'options' => $options,
|
|
];
|
|
|
|
$action = $options['action'] ?? $this->action->value;
|
|
|
|
if (! in_array($action, ['prepend', 'append', 'default'])) {
|
|
throw new \RuntimeException("An unsupported action `$action` was given as an option of a {% section %} tag");
|
|
}
|
|
|
|
$order = $options['order'] ?? "count(\$___class__template->sectionList[$name]['$action'])";
|
|
|
|
return "<?php \$___class__template->sectionList[$name] ??= [ 'prepend' => [], 'append' => [], 'default' => [] ];" .
|
|
"\$___class__template->sectionList[$name]['$action'][] = [
|
|
'order' => $order,
|
|
'callback' => function() use (\$picea, \$___class__template, \$___global_variables, \$___variables, \$__event) {" .
|
|
"extract(\$___global_variables); extract(\$___variables, \EXTR_OVERWRITE);" .
|
|
"\$___class__template->sectionStack[] = $name;" .
|
|
"\$__event->eventExecute(\Picea\Event\Builder\ClassTemplateRenderSection::class, $name);?>";
|
|
}
|
|
|
|
protected function printEndSection($context) : string
|
|
{
|
|
$section = array_pop($context->sections);
|
|
$build = $context->extendFrom ? "!empty(\$___class__template->sectionStack) && \$___class__template->renderSection({$section['name']}, false);" : "\$___class__template->renderSection({$section['name']}, false);";
|
|
|
|
return "<?php \$__event->eventExecute(\Picea\Event\Builder\ClassTemplateRenderSectionDone::class, {$section['name']});" .
|
|
"array_pop(\$___class__template->sectionStack); }];" .
|
|
$build .
|
|
"?>";
|
|
|
|
}
|
|
} |