%PDF- %PDF-
| Direktori : /www/varak.net/losik.varak.net/vendor/latte/latte/src/Latte/Macros/ |
| Current File : /www/varak.net/losik.varak.net/vendor/latte/latte/src/Latte/Macros/MacroSet.php |
<?php
/**
* This file is part of the Latte (https://latte.nette.org)
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
*/
declare(strict_types=1);
namespace Latte\Macros;
use Latte;
use Latte\CompileException;
use Latte\MacroNode;
/**
* Base Macro implementation. Allows add multiple macros.
*/
class MacroSet implements Latte\Macro
{
use Latte\Strict;
/** @var Latte\Compiler */
private $compiler;
/** @var array<string, array{string|callable|null, string|callable|null, string|callable|null}> */
private $macros;
public function __construct(Latte\Compiler $compiler)
{
$this->compiler = $compiler;
}
/**
* @param string|callable|null $begin
* @param string|callable|null $end
* @param string|callable|null $attr
*/
public function addMacro(string $name, $begin, $end = null, $attr = null, ?int $flags = null): self
{
if (!$begin && !$end && !$attr) {
throw new \InvalidArgumentException("At least one argument must be specified for tag '$name'.");
}
foreach ([$begin, $end, $attr] as $arg) {
if ($arg && !is_string($arg)) {
Latte\Helpers::checkCallback($arg);
}
}
$this->macros[$name] = [$begin, $end, $attr];
$this->compiler->addMacro($name, $this, $flags);
return $this;
}
/**
* Initializes before template parsing.
* @return void
*/
public function initialize()
{
}
/**
* Finishes template parsing.
*/
public function finalize()
{
return null;
}
/**
* New node is found.
* @return bool|null
*/
public function nodeOpened(MacroNode $node)
{
[$begin, $end, $attr] = $this->macros[$node->name];
$node->empty = !$end;
if (
$node->modifiers
&& (!$begin || (is_string($begin) && strpos($begin, '%modify') === false))
&& (!$end || (is_string($end) && strpos($end, '%modify') === false))
&& (!$attr || (is_string($attr) && strpos($attr, '%modify') === false))
) {
throw new CompileException('Filters are not allowed in ' . $node->getNotation());
}
if (
$node->args !== ''
&& (!$begin || (is_string($begin) && strpos($begin, '%node') === false))
&& (!$end || (is_string($end) && strpos($end, '%node') === false))
&& (!$attr || (is_string($attr) && strpos($attr, '%node') === false))
) {
throw new CompileException('Arguments are not allowed in ' . $node->getNotation());
}
if ($attr && $node->prefix === $node::PREFIX_NONE) {
$node->empty = true;
$node->context[1] = Latte\Compiler::CONTEXT_HTML_ATTRIBUTE;
$res = $this->compile($node, $attr);
if ($res === false) {
return false;
} elseif (!$node->attrCode) {
$node->attrCode = "<?php $res ?>";
}
$node->context[1] = Latte\Compiler::CONTEXT_HTML_TEXT;
} elseif ($node->empty && $node->prefix) {
return false;
} elseif ($begin) {
$res = $this->compile($node, $begin);
if ($res === false) {
return false;
} elseif (!$node->openingCode && is_string($res) && $res !== '') {
$node->openingCode = "<?php $res ?>";
}
} elseif (!$end) {
return false;
}
return null;
}
/**
* Node is closed.
* @return void
*/
public function nodeClosed(MacroNode $node)
{
if (isset($this->macros[$node->name][1])) {
$res = $this->compile($node, $this->macros[$node->name][1]);
if (!$node->closingCode && is_string($res) && $res !== '') {
$node->closingCode = "<?php $res ?>";
}
}
}
/**
* Generates code.
* @param string|callable $def
* @return string|bool|null
*/
private function compile(MacroNode $node, $def)
{
$node->tokenizer->reset();
$writer = Latte\PhpWriter::using($node, $this->compiler);
return is_string($def)
? $writer->write($def)
: $def($node, $writer);
}
public function getCompiler(): Latte\Compiler
{
return $this->compiler;
}
/** @internal */
protected function checkExtraArgs(MacroNode $node): void
{
if ($node->tokenizer->isNext(...$node->tokenizer::SIGNIFICANT)) {
$args = Latte\Runtime\Filters::truncate($node->tokenizer->joinAll(), 20);
throw new CompileException("Unexpected arguments '$args' in " . $node->getNotation());
}
}
}