ModCfg/Core/Twig/d3modcfgcheckTokenParser.php

102 regels
3.2 KiB
PHP

<?php
/**
* This Software is the property of Data Development and is protected
* by copyright law - it is NOT Freeware.
* Any unauthorized use of this software without a valid license
* is a violation of the license agreement and will be prosecuted by
* civil and criminal law.
* http://www.shopmodule.com
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @link http://www.oxidmodule.com
*/
// https://stackoverflow.com/questions/26170727/how-to-create-a-twig-custom-tag-that-executes-a-callback
// example: {% d3modcfgcheck modid="d3_ordermanager" optionvar="value1" optionvardefault="value3" %}
declare(strict_types=1);
namespace D3\ModCfg\Core\Twig;
use OxidEsales\Eshop\Core\Registry;
use Twig\Error\SyntaxError;
use Twig\Node\Node;
use Twig\Token;
use Twig\TokenParser\AbstractTokenParser;
class d3modcfgcheckTokenParser extends AbstractTokenParser
{
public function parse(Token $token): Node
{
$parser = $this->parser;
$stream = $parser->getStream();
$lineNo = $token->getLine();
$params = $this->getInlineParams();
$continue = true;
while ($continue) {
// create subtree until the decideMyTagFork() callback returns true
$body = $parser->subparse([ $this, 'decideTokenEnd' ]);
// I like to put a switch here, in case you need to add middle tags, such
// as: {% mytag %}, {% nextmytag %}, {% endmytag %}.
$tag = $stream->next()->getValue();
$continue = match ($tag) {
'endd3modcfgcheck' => false,
default => throw new SyntaxError(sprintf('Unexpected end of template. Twig was looking for the following tags "endd3modcfgcheck" to close the "d3modcfgcheck" block started at line %d)', $lineNo), -1),
};
// you want $body at the beginning of your arguments
$this->array_unshift_assoc($params, 'body', $body);
$stream->expect(Token::BLOCK_END_TYPE);
}
return new d3modcfgcheckNode(new Node($params), $lineNo, $this->getTag());
}
protected function array_unshift_assoc(&$arr, $key, $val): array
{
$arr = array_reverse($arr, true);
$arr[$key] = $val;
$arr = array_reverse($arr, true);
return $arr;
}
protected function getInlineParams(): array
{
$stream = $this->parser->getStream();
$params = [];
try {
while (! $stream->test(Token::BLOCK_END_TYPE)) {
// Read the attribute name
$name = $stream->next()->getValue();
// Read the "="
$stream->expect(Token::OPERATOR_TYPE, '=');
$params[ $name ] = $this->parser->getExpressionParser()->parseExpression();
}
$stream->expect(Token::BLOCK_END_TYPE);
} catch (SyntaxError $e) {
Registry::getLogger()->error($e->getMessage());
}
return $params;
}
public function decideTokenEnd(Token $token): bool
{
return $token->test('endd3modcfgcheck');
}
public function getTag(): string
{
return 'd3modcfgcheck';
}
}