aboutsummaryrefslogtreecommitdiff
path: root/vendor/exTpl
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/exTpl')
-rw-r--r--vendor/exTpl/Context.php80
-rw-r--r--vendor/exTpl/Expression.php329
-rw-r--r--vendor/exTpl/Node.php234
-rw-r--r--vendor/exTpl/Scanner.php98
-rw-r--r--vendor/exTpl/Template.php535
-rw-r--r--vendor/exTpl/template_test.php215
6 files changed, 0 insertions, 1491 deletions
diff --git a/vendor/exTpl/Context.php b/vendor/exTpl/Context.php
deleted file mode 100644
index ea94b2f..0000000
--- a/vendor/exTpl/Context.php
+++ /dev/null
@@ -1,80 +0,0 @@
-<?php
-/*
- * Context.php - template parser symbol table
- *
- * Copyright (c) 2013 Elmar Ludwig
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- */
-
-namespace exTpl;
-
-/**
- * A Context object represents the symbol table used to resolve
- * symbol names to their values in the local scope. Each context
- * may inherit symbol definitions from its parent context.
- */
-class Context
-{
- private $bindings;
- private $escape;
- private $parent;
-
- /**
- * Initializes a new Context instance with the given bindings.
- *
- * @param array $bindings symbol table
- * @param Context $parent parent context (or NULL)
- */
- public function __construct($bindings, Context $parent = NULL)
- {
- $this->bindings = $bindings;
- $this->parent = $parent;
- }
-
- /**
- * Looks up the value of a symbol in this context and returns it.
- * The reserved symbol "this" is an alias for the current context.
- *
- * @param string $key symbol name
- */
- public function lookup($key)
- {
- if (isset($this->bindings[$key])) {
- return $this->bindings[$key];
- } else if ($this->parent) {
- return $this->parent->lookup($key);
- }
-
- return NULL;
- }
-
- /**
- * Enables or disables automatic escaping for template values.
- *
- * @param callable $escape escape callback or NULL
- */
- public function autoescape($escape)
- {
- $this->escape = $escape;
- }
-
- /**
- * Escapes the given value using the configured strategy.
- *
- * @param mixed $value expression value
- */
- public function escape($value)
- {
- if (isset($this->escape)) {
- $value = call_user_func($this->escape, $value);
- } else if ($this->parent) {
- $value = $this->parent->escape($value);
- }
-
- return $value;
- }
-}
diff --git a/vendor/exTpl/Expression.php b/vendor/exTpl/Expression.php
deleted file mode 100644
index 35ea458..0000000
--- a/vendor/exTpl/Expression.php
+++ /dev/null
@@ -1,329 +0,0 @@
-<?php
-/*
- * Expression.php - template parser expression interface and classes
- *
- * Copyright (c) 2013 Elmar Ludwig
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- */
-
-namespace exTpl;
-
-/**
- * Basic interface for expressions in the template parse tree. The
- * only required method is "value" to get the expression's value.
- */
-interface Expression
-{
- /**
- * Returns the value of this expression.
- *
- * @param Context $context symbol table
- */
- public function value($context);
-}
-
-/**
- * ConstantExpression represents a literal value.
- */
-class ConstantExpression implements Expression
-{
- protected $value;
-
- /**
- * Initializes a new Expression instance.
- *
- * @param mixed $value expression value
- */
- public function __construct($value)
- {
- $this->value = $value;
- }
-
- /**
- * Returns the value of this expression.
- *
- * @param Context $context symbol table
- */
- public function value($context)
- {
- return $this->value;
- }
-}
-
-/**
- * SymbolExpression represents a symbol (template variable).
- */
-class SymbolExpression implements Expression
-{
- protected $name;
-
- /**
- * Initializes a new Expression instance.
- *
- * @param string $name symbol name
- */
- public function __construct($name)
- {
- $this->name = $name;
- }
-
- /**
- * Returns the name of this symbol.
- */
- public function name()
- {
- return $this->name;
- }
-
- /**
- * Returns the value of this expression.
- *
- * @param Context $context symbol table
- */
- public function value($context)
- {
- return $context->lookup($this->name);
- }
-}
-
-/**
- * UnaryExpression represents a unary operator.
- */
-abstract class UnaryExpression implements Expression
-{
- protected $expr;
-
- /**
- * Initializes a new Expression instance.
- *
- * @param Expression $expr expression object
- */
- public function __construct(Expression $expr)
- {
- $this->expr = $expr;
- }
-}
-
-/**
- * MinusExpression represents the unary minus operator ('-').
- */
-class MinusExpression extends UnaryExpression
-{
- /**
- * Returns the value of this expression.
- *
- * @param Context $context symbol table
- */
- public function value($context)
- {
- return -$this->expr->value($context);
- }
-}
-
-/**
- * NotExpression represents the logical negation operator ('!').
- */
-class NotExpression extends UnaryExpression
-{
- /**
- * Returns the value of this expression.
- *
- * @param Context $context symbol table
- */
- public function value($context)
- {
- return !$this->expr->value($context);
- }
-}
-
-/**
- * RawExpression represents the "raw" filter function.
- */
-class RawExpression extends UnaryExpression
-{
- /**
- * Returns the value of this expression.
- *
- * @param Context $context symbol table
- */
- public function value($context)
- {
- return $this->expr->value($context);
- }
-}
-
-/**
- * BinaryExpression represents a binary operator.
- */
-abstract class BinaryExpression implements Expression
-{
- protected $left, $right;
- protected $operator;
-
- /**
- * Initializes a new Expression instance.
- *
- * @param Expression $left left operand
- * @param Expression $right right operand
- * @param mixed $operator operator token
- */
- public function __construct(Expression $left, Expression $right, $operator)
- {
- $this->left = $left;
- $this->right = $right;
- $this->operator = $operator;
- }
-}
-
-/**
- * ArithExpression represents an arithmetic operator.
- */
-class ArithExpression extends BinaryExpression
-{
- /**
- * Returns the value of this expression.
- *
- * @param Context $context symbol table
- */
- public function value($context)
- {
- $left = $this->left->value($context);
- $right = $this->right->value($context);
-
- switch ($this->operator) {
- case '+': return $left + $right;
- case '-': return $left - $right;
- case '*': return $left * $right;
- case '/': return $left / $right;
- case '%': return $left % $right;
- case '~': return $left . $right;
- }
- }
-}
-
-/**
- * IndexExpression represents the array index operator.
- */
-class IndexExpression extends BinaryExpression
-{
- /**
- * Returns the value of this expression.
- *
- * @param Context $context symbol table
- */
- public function value($context)
- {
- $left = $this->left->value($context);
- $right = $this->right->value($context);
-
- return $left[$right];
- }
-}
-
-/**
- * BooleanExpression represents a boolean operator.
- */
-class BooleanExpression extends BinaryExpression
-{
- /**
- * Returns the value of this expression.
- *
- * @param Context $context symbol table
- */
- public function value($context)
- {
- $left = $this->left->value($context);
- $right = $this->right->value($context);
-
- switch ($this->operator) {
- case T_IS_EQUAL : return $left == $right;
- case T_IS_NOT_EQUAL : return $left != $right;
- case '<' : return $left < $right;
- case T_IS_SMALLER_OR_EQUAL: return $left <= $right;
- case '>' : return $left > $right;
- case T_IS_GREATER_OR_EQUAL: return $left >= $right;
- case T_BOOLEAN_AND : return $left && $right;
- case T_BOOLEAN_OR : return $left || $right;
- }
- }
-}
-
-/**
- * ConditionExpression represents the conditional operator ('?:').
- */
-class ConditionExpression implements Expression
-{
- protected $condition;
- protected $left, $right;
-
- /**
- * Initializes a new Expression instance.
- *
- * @param Expression $condition expression
- * @param Expression $left left alternative
- * @param Expression $right right alternative
- */
- public function __construct($condition, $left, $right)
- {
- $this->condition = $condition;
- $this->left = $left;
- $this->right = $right;
- }
-
- /**
- * Returns the value of this expression.
- *
- * @param Context $context symbol table
- */
- public function value($context)
- {
- return $this->condition->value($context) ?
- $this->left->value($context) : $this->right->value($context);
- }
-}
-
-/**
- * FunctionExpression represents a function call.
- */
-class FunctionExpression implements Expression
-{
- protected $name;
- protected $arguments;
-
- /**
- * Initializes a new Expression instance.
- *
- * @param Expression $name function name
- * @param array $arguments function arguments
- */
- public function __construct(Expression $name, $arguments)
- {
- $this->name = $name;
- $this->arguments = $arguments;
- }
-
- /**
- * Returns the value of this expression.
- *
- * @param Context $context symbol table
- */
- public function value($context)
- {
- $callable = $this->name->value($context);
- $arguments = array();
-
- foreach ($this->arguments as $expr) {
- $arguments[] = $expr->value($context);
- }
-
- if ($callable instanceof \Closure) {
- return call_user_func_array($callable, $arguments);
- }
-
- return NULL;
- }
-}
diff --git a/vendor/exTpl/Node.php b/vendor/exTpl/Node.php
deleted file mode 100644
index 0dbd946..0000000
--- a/vendor/exTpl/Node.php
+++ /dev/null
@@ -1,234 +0,0 @@
-<?php
-/*
- * Node.php - template parser node interface and classes
- *
- * Copyright (c) 2013 Elmar Ludwig
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- */
-
-namespace exTpl;
-
-require_once 'Context.php';
-require_once 'Expression.php';
-
-/**
- * Basic interface for nodes in the template parse tree. The only
- * required method is "render" to render a node and its children.
- */
-interface Node
-{
- /**
- * Returns a string representation of this node.
- *
- * @param Context $context symbol table
- */
- public function render($context);
-}
-
-/**
- * TextNode represents a verbatim text segment.
- */
-class TextNode implements Node
-{
- protected $text;
-
- /**
- * Initializes a new Node instance with the given text.
- *
- * @param string $text verbatim text
- */
- public function __construct($text)
- {
- $this->text = $text;
- }
-
- /**
- * Returns a string representation of this node.
- *
- * @param Context $context symbol table
- */
- public function render($context)
- {
- return $this->text;
- }
-}
-
-/**
- * ExpressionNode represents an expression tag: "{...}".
- */
-class ExpressionNode implements Node
-{
- protected $expr;
-
- /**
- * Initializes a new Node instance with the given expression.
- *
- * @param Expression $expr expression object
- */
- public function __construct(Expression $expr)
- {
- $this->expr = $expr;
- }
-
- /**
- * Returns a string representation of this node.
- *
- * @param Context $context symbol table
- */
- public function render($context)
- {
- $value = $this->expr->value($context);
-
- if (!($this->expr instanceof RawExpression)) {
- $value = $context->escape($value);
- }
-
- return $value;
- }
-}
-
-/**
- * ArrayNode represents a sequence of arbitrary nodes.
- */
-class ArrayNode implements Node
-{
- protected $nodes = array();
-
- /**
- * Adds a child node to this sequence node.
- *
- * @param Node $node child node to add
- */
- public function addChild(Node $node)
- {
- $this->nodes[] = $node;
- }
-
- /**
- * Returns a string representation of this node.
- *
- * @param Context $context symbol table
- */
- public function render($context)
- {
- $result = '';
-
- foreach ($this->nodes as $node) {
- $result .= $node->render($context);
- }
-
- return $result;
- }
-}
-
-/**
- * IteratorNode represents a single iterator tag:
- * "{foreach ARRAY [as [KEY =>] VALUE]}...{endforeach}".
- */
-class IteratorNode extends ArrayNode
-{
- protected $expr;
- protected $key_name;
- protected $val_name;
-
- /**
- * Initializes a new Node instance with the given expression.
- *
- * @param Expression $expr expression object
- * @param string $key_name name of variable on each iteration
- * @param string $val_name name of variable on each iteration
- */
- public function __construct(Expression $expr, $key_name, $val_name)
- {
- $this->expr = $expr;
- $this->key_name = $key_name;
- $this->val_name = $val_name;
- }
-
- /**
- * Returns a string representation of this node. The IteratorNode
- * renders the node sequence for each value in the expression list.
- *
- * @param Context $context symbol table
- */
- public function render($context)
- {
- $values = $this->expr->value($context);
- $result = '';
-
- if (is_array($values) && is_int(key($values))) {
- $bindings = array($this->key_name => &$key, $this->val_name => &$value);
- $context = new Context($bindings, $context);
-
- foreach ($values as $key => $value) {
- $result .= parent::render(new Context($value, $context));
- }
- } else if (is_array($values) && count($values)) {
- return parent::render(new Context($values, $context));
- } else if ($values) {
- return parent::render($context);
- }
-
- return $result;
- }
-}
-
-/**
- * ConditionNode represents a single condition tag:
- * "{if CONDITION}...{else}...{endif}".
- */
-class ConditionNode extends ArrayNode
-{
- protected $condition;
- protected $else_node;
-
- /**
- * Initializes a new Node instance with the given expression.
- *
- * @param Expression $condition expression object
- */
- public function __construct(Expression $condition)
- {
- $this->condition = $condition;
- }
-
- /**
- * Adds an else block to this condition node.
- */
- public function addElse()
- {
- $this->else_node = new ArrayNode();
- }
-
- /**
- * Adds a child node to this condition node.
- *
- * @param Node $node child node to add
- */
- public function addChild(Node $node)
- {
- if ($this->else_node) {
- $this->else_node->addChild($node);
- } else {
- parent::addChild($node);
- }
- }
-
- /**
- * Returns a string representation of this node.
- *
- * @param Context $context symbol table
- */
- public function render($context)
- {
- if ($this->condition->value($context)) {
- return parent::render($context);
- }
-
- return $this->else_node ? $this->else_node->render($context) : '';
- }
-}
diff --git a/vendor/exTpl/Scanner.php b/vendor/exTpl/Scanner.php
deleted file mode 100644
index b2464fb..0000000
--- a/vendor/exTpl/Scanner.php
+++ /dev/null
@@ -1,98 +0,0 @@
-<?php
-/*
- * Scanner.php - template parser lexical scanner
- *
- * Copyright (c) 2013 Elmar Ludwig
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- */
-
-namespace exTpl;
-
-/**
- * Simple wrapper class around the Zend engine's lexical scanner. It
- * automatically skips whitespace and offers an interator interface.
- */
-class Scanner
-{
- private $tokens;
- private $token_type;
- private $token_value;
-
- /**
- * Initializes a new Scanner instance for the given text.
- *
- * @param string $text string to parse
- */
- public function __construct($text)
- {
- $this->tokens = token_get_all('<?php ' . $text);
- }
-
- /**
- * Advances the scanner to the next token and returns its token type.
- * The valid token types are those defined for token_get_all() in the
- * PHP documentation. Returns false when the end of input is reached.
- */
- public function nextToken()
- {
- do {
- $token = next($this->tokens);
- $key = key($this->tokens);
-
- // FIXME this workaround should be dropped
- while ($token && $token[0] === T_STRING &&
- isset($this->tokens[$key + 2]) &&
- $this->tokens[++$key] === '-' &&
- $this->tokens[++$key][0] === T_STRING) {
- $token[1] .= '-' . $this->tokens[$key][1];
- next($this->tokens);
- next($this->tokens);
- }
- } while (is_array($token) && $token[0] === T_WHITESPACE);
-
- if (is_string($token) || $token === false) {
- $this->token_type = $token;
- $this->token_value = NULL;
- } else {
- $this->token_type = $token[0];
-
- switch ($token[0]) {
- case T_CONSTANT_ENCAPSED_STRING:
- $this->token_value = stripcslashes(substr($token[1], 1, -1));
- break;
- case T_DNUMBER:
- $this->token_value = (double) $token[1];
- break;
- case T_LNUMBER:
- $this->token_value = (int) $token[1];
- break;
- default:
- $this->token_value = $token[1];
- }
- }
-
- return $this->token_type;
- }
-
- /**
- * Returns the current token type. The valid token types are
- * those defined for token_get_all() in the PHP documentation.
- */
- public function tokenType()
- {
- return $this->token_type;
- }
-
- /**
- * Returns the current token value if the token type supports
- * a value (T_STRING, T_LNUMBER etc.). Returns NULL otherwise.
- */
- public function tokenValue()
- {
- return $this->token_value;
- }
-}
diff --git a/vendor/exTpl/Template.php b/vendor/exTpl/Template.php
deleted file mode 100644
index 9d5be04..0000000
--- a/vendor/exTpl/Template.php
+++ /dev/null
@@ -1,535 +0,0 @@
-<?php
-/*
- * Template.php - expression template parser
- *
- * Copyright (c) 2013 Elmar Ludwig
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- */
-
-namespace exTpl;
-
-require_once 'Scanner.php';
-require_once 'Node.php';
-
-/**
- * The Template class is the only externally visible API of this
- * template implementation. It can be used to create and render
- * template objects.
- */
-class Template
-{
- private static $tag_start = '{';
- private static $tag_end = '}';
- private $escape;
- private $functions;
- private $template;
-
- /**
- * Sets the delimiter strings used for the template tags, the
- * default delimiters are: $tag_start = '{', $tag_end = '}'.
- *
- * @param string $tag_start tag start marker
- * @param string $tag_end tag end marker
- */
- public static function setTagMarkers($tag_start, $tag_end)
- {
- self::$tag_start = $tag_start;
- self::$tag_end = $tag_end;
- }
-
- /**
- * Initializes a new Template instance from the given string.
- *
- * @param string $string template text
- */
- public function __construct($string)
- {
- $this->template = new ArrayNode();
- $this->functions = array(
- 'count' => function($a) { return count($a); },
- 'strlen' => function($a) { return mb_strlen($a); }
- );
- self::parseTemplate($this->template, $string, 0);
- }
-
- /**
- * Enables or disables automatic escaping for template values.
- * Currently supported strategies: NULL, 'html', 'json', 'xml'
- *
- * @param string|callable $escape escape strategy or callback
- */
- public function autoescape($escape)
- {
- if ($escape === 'html' || $escape === 'xml') {
- $this->escape = 'htmlspecialchars';
- } else if ($escape === 'json') {
- $this->escape = 'json_encode';
- } else if (is_callable($escape)) {
- $this->escape = $escape;
- } else if ($escape === NULL) {
- $this->escape = NULL;
- } else {
- throw new InvalidArgumentException("invalid escape strategy: $escape");
- }
- }
-
- /**
- * Renders the template to a string using the given array of
- * bindings to resolve symbol references inside the template.
- *
- * @param array $bindings symbol table
- *
- * @return string string representation of the template
- */
- public function render(array $bindings)
- {
- $context = new Context($bindings + $this->functions);
- $context->autoescape($this->escape);
-
- return $this->template->render($context);
- }
-
- /**
- * Skips tokens until the end of the current tag is reached.
- *
- * @param string $string template text
- * @param int $pos offset in string
- *
- * @return int new offset in the string
- */
- private static function skipTokens($string, $pos)
- {
- for ($len = strlen($string); $pos < $len &&
- substr_compare($string, self::$tag_end, $pos, strlen(self::$tag_end)); ++$pos) {
- $chr = $string[$pos];
- if ($chr === '"' || $chr === "'") {
- while (++$pos < $len && $string[$pos] !== $chr) {
- if ($string[$pos] === '\\') {
- ++$pos;
- }
- }
- }
- }
-
- return $pos;
- }
-
- /**
- * Parses a template string into a template node tree, starting
- * at the specified offset. All created nodes are added to the
- * given sequence node.
- *
- * @param ArrayNode $node template node to build
- * @param string $string string to parse
- * @param int $pos offset in string
- *
- * @return int new offset in the string
- */
- private static function parseTemplate(ArrayNode $node, $string, $pos)
- {
- $len = strlen($string);
-
- while ($pos < $len) {
- $next_pos = strpos($string, self::$tag_start, $pos);
-
- if ($next_pos === false) {
- $child = new TextNode(substr($string, $pos));
- $node->addChild($child);
- break;
- }
-
- if ($next_pos > $pos) {
- $child = new TextNode(substr($string, $pos, $next_pos - $pos));
- $node->addChild($child);
- }
-
- $pos = $next_pos + strlen(self::$tag_start);
- $next_pos = self::skipTokens($string, $pos);
- $scanner = new Scanner(substr($string, $pos, $next_pos - $pos));
- $pos = $next_pos + strlen(self::$tag_end);
-
- switch ($scanner->nextToken()) {
- case T_FOREACH:
- $scanner->nextToken();
- $expr = self::parseExpr($scanner);
- $key_name = 'index';
- $val_name = 'this';
-
- if ($scanner->tokenType() === T_AS) {
- $scanner->nextToken();
-
- if ($scanner->tokenType() !== T_STRING) {
- throw new TemplateParserException('symbol expected', $scanner);
- }
-
- $val_name = $scanner->tokenValue();
- $scanner->nextToken();
-
- if ($scanner->tokenType() === T_DOUBLE_ARROW) {
- $scanner->nextToken();
-
- if ($scanner->tokenType() !== T_STRING) {
- throw new TemplateParserException('symbol expected', $scanner);
- }
-
- $key_name = $val_name;
- $val_name = $scanner->tokenValue();
- $scanner->nextToken();
- }
- }
-
- $child = new IteratorNode($expr, $key_name, $val_name);
- $pos = self::parseTemplate($child, $string, $pos);
- $node->addChild($child);
- break;
- case T_ENDFOREACH:
- return $pos;
- case T_IF:
- $scanner->nextToken();
- $child = new ConditionNode(self::parseExpr($scanner));
- $pos = self::parseTemplate($child, $string, $pos);
- $node->addChild($child);
- break;
- case T_ELSEIF:
- $scanner->nextToken();
- $child = new ConditionNode(self::parseExpr($scanner));
- $node->addElse();
- $node->addChild($child);
- return self::parseTemplate($child, $string, $pos);
- case T_ELSE:
- $scanner->nextToken();
- $node->addElse();
- break;
- case T_ENDIF:
- return $pos;
- default:
- $child = new ExpressionNode(self::parseExpr($scanner));
- $node->addChild($child);
- }
-
- if ($scanner->tokenType() !== false) {
- throw new TemplateParserException('syntax error', $scanner);
- }
- }
-
- return $pos;
- }
-
- /**
- * value: NUMBER | STRING | SYMBOL | '(' expr ')'
- */
- private static function parseValue(Scanner $scanner)
- {
- switch ($scanner->tokenType()) {
- case T_CONSTANT_ENCAPSED_STRING:
- case T_DNUMBER:
- case T_LNUMBER:
- $result = new ConstantExpression($scanner->tokenValue());
- break;
- case T_STRING:
- $result = new SymbolExpression($scanner->tokenValue());
- break;
- case '(':
- $scanner->nextToken();
- $result = self::parseExpr($scanner);
-
- if ($scanner->tokenType() !== ')') {
- throw new TemplateParserException('missing ")"', $scanner);
- }
- break;
- default:
- throw new TemplateParserException('syntax error', $scanner);
- }
-
- $scanner->nextToken();
- return $result;
- }
-
- /**
- * function: value | function '(' ')' | function '(' expr { ',' expr } ')'
- */
- private static function parseFunction(Scanner $scanner)
- {
- $result = self::parseValue($scanner);
- $type = $scanner->tokenType();
-
- while ($type === '(') {
- $scanner->nextToken();
- $arguments = array();
-
- if ($scanner->tokenType() !== ')') {
- $arguments[] = self::parseExpr($scanner);
-
- while ($scanner->tokenType() === ',') {
- $scanner->nextToken();
- $arguments[] = self::parseExpr($scanner);
- }
-
- if ($scanner->tokenType() !== ')') {
- throw new TemplateParserException('missing ")"', $scanner);
- }
- }
-
- $scanner->nextToken();
- $result = new FunctionExpression($result, $arguments);
- $type = $scanner->tokenType();
- }
-
- return $result;
- }
-
- /**
- * index: function | index '[' expr ']' | index '.' SYMBOL
- */
- private static function parseIndex(Scanner $scanner)
- {
- $result = self::parseFunction($scanner);
- $type = $scanner->tokenType();
-
- while ($type === '[' || $type === '.') {
- $scanner->nextToken();
-
- if ($type === '[') {
- $expr = self::parseExpr($scanner);
-
- if ($scanner->tokenType() !== ']') {
- throw new TemplateParserException('missing "]"', $scanner);
- }
- } else if ($scanner->tokenType() === T_STRING) {
- $expr = new ConstantExpression($scanner->tokenValue());
- } else {
- throw new TemplateParserException('symbol expected', $scanner);
- }
-
- $scanner->nextToken();
- $result = new IndexExpression($result, $expr, $type);
- $type = $scanner->tokenType();
- }
-
- return $result;
- }
-
- /**
- * filter: index | filter '|' SYMBOL | filter '|' SYMBOL '(' expr { ',' expr } ')'
- */
- private static function parseFilter(Scanner $scanner)
- {
- $result = self::parseIndex($scanner);
- $type = $scanner->tokenType();
-
- while ($type === '|') {
- $scanner->nextToken();
-
- if ($scanner->tokenType() !== T_STRING) {
- throw new TemplateParserException('symbol expected', $scanner);
- }
-
- $arguments = array($result);
- $symbol = new SymbolExpression($scanner->tokenValue());
- $scanner->nextToken();
-
- if ($scanner->tokenType() === '(') {
- $scanner->nextToken();
-
- if ($scanner->tokenType() !== ')') {
- $arguments[] = self::parseExpr($scanner);
-
- while ($scanner->tokenType() === ',') {
- $scanner->nextToken();
- $arguments[] = self::parseExpr($scanner);
- }
-
- if ($scanner->tokenType() !== ')') {
- throw new TemplateParserException('missing ")"', $scanner);
- }
- }
-
- $scanner->nextToken();
- }
-
- if ($symbol->name() === 'raw') {
- $result = new RawExpression($result);
- } else {
- $result = new FunctionExpression($symbol, $arguments);
- }
-
- $type = $scanner->tokenType();
- }
-
- return $result;
- }
-
- /**
- * sign: '!' sign | '+' sign | '-' sign | filter
- */
- private static function parseSign(Scanner $scanner)
- {
- switch ($scanner->tokenType()) {
- case '!':
- $scanner->nextToken();
- $result = new NotExpression(self::parseSign($scanner));
- break;
- case '+':
- $scanner->nextToken();
- $result = self::parseSign($scanner);
- break;
- case '-':
- $scanner->nextToken();
- $result = new MinusExpression(self::parseSign($scanner));
- break;
- default:
- $result = self::parseFilter($scanner);
- }
-
- return $result;
- }
-
- /**
- * product: sign | product '*' sign | product '/' sign | product '%' sign
- */
- private static function parseProduct(Scanner $scanner)
- {
- $result = self::parseSign($scanner);
- $type = $scanner->tokenType();
-
- while ($type === '*' || $type === '/' || $type === '%') {
- $scanner->nextToken();
- $result = new ArithExpression($result, self::parseSign($scanner), $type);
- $type = $scanner->tokenType();
- }
-
- return $result;
- }
-
- /**
- * sum: product | sum '+' product | sum '-' product | sum '~' product
- */
- private static function parseSum(Scanner $scanner)
- {
- $result = self::parseProduct($scanner);
- $type = $scanner->tokenType();
-
- while ($type === '+' || $type === '-' || $type === '~') {
- $scanner->nextToken();
- $result = new ArithExpression($result, self::parseProduct($scanner), $type);
- $type = $scanner->tokenType();
- }
-
- return $result;
- }
-
- /**
- * lt_gt: sum | lt_gt '<' concat | lt_gt IS_SMALLER_OR_EQUAL concat
- * | lt_gt '>' concat | lt_gt IS_GREATER_OR_EQUAL concat
- */
- private static function parseLtGt(Scanner $scanner)
- {
- $result = self::parseSum($scanner);
- $type = $scanner->tokenType();
-
- while ($type === '<' || $type === T_IS_SMALLER_OR_EQUAL ||
- $type === '>' || $type === T_IS_GREATER_OR_EQUAL) {
- $scanner->nextToken();
- $result = new BooleanExpression($result, self::parseSum($scanner), $type);
- $type = $scanner->tokenType();
- }
-
- return $result;
- }
-
- /**
- * cmp: lt_gt | cmp IS_EQUAL lt_gt | cmp IS_NOT_EQUAL lt_gt
- */
- private static function parseCmp(Scanner $scanner)
- {
- $result = self::parseLtGt($scanner);
- $type = $scanner->tokenType();
-
- while ($type === T_IS_EQUAL || $type === T_IS_NOT_EQUAL) {
- $scanner->nextToken();
- $result = new BooleanExpression($result, self::parseLtGt($scanner), $type);
- $type = $scanner->tokenType();
- }
-
- return $result;
- }
-
- /**
- * and: cmp | and BOOLEAN_AND cmp
- */
- private static function parseAnd(Scanner $scanner)
- {
- $result = self::parseCmp($scanner);
- $type = $scanner->tokenType();
-
- while ($type === T_BOOLEAN_AND) {
- $scanner->nextToken();
- $result = new BooleanExpression($result, self::parseCmp($scanner), $type);
- $type = $scanner->tokenType();
- }
-
- return $result;
- }
-
- /**
- * or: and | or BOOLEAN_OR and
- */
- private static function parseOr(Scanner $scanner)
- {
- $result = self::parseAnd($scanner);
- $type = $scanner->tokenType();
-
- while ($type === T_BOOLEAN_OR) {
- $scanner->nextToken();
- $result = new BooleanExpression($result, self::parseAnd($scanner), $type);
- $type = $scanner->tokenType();
- }
-
- return $result;
- }
-
- /**
- * expr: or | or '?' expr ':' expr | or '?' ':' expr
- */
- private static function parseExpr(Scanner $scanner)
- {
- $result = self::parseOr($scanner);
-
- if ($scanner->tokenType() === '?') {
- $scanner->nextToken();
-
- if ($scanner->tokenType() !== ':') {
- $expr = self::parseExpr($scanner);
- } else {
- $expr = $result;
- }
-
- if ($scanner->tokenType() !== ':') {
- throw new TemplateParserException('missing ":"', $scanner);
- }
-
- $scanner->nextToken();
- $result = new ConditionExpression($result, $expr, self::parseExpr($scanner));
- }
-
- return $result;
- }
-}
-
-/**
- * Exception class used to report template parse errors.
- */
-class TemplateParserException extends \Exception
-{
- public function __construct($message, $scanner)
- {
- $type = $scanner->tokenType();
- $value = is_int($type) ? $scanner->tokenValue() : $type;
-
- return parent::__construct("$message at \"$value\"");
- }
-}
diff --git a/vendor/exTpl/template_test.php b/vendor/exTpl/template_test.php
deleted file mode 100644
index 62aee1c..0000000
--- a/vendor/exTpl/template_test.php
+++ /dev/null
@@ -1,215 +0,0 @@
-<?php
-/*
- * template_test.php - expression template unit tests
- *
- * Copyright (c) 2013 Elmar Ludwig
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- */
-
-require 'Template.php';
-
-use exTpl\Template;
-
-class template_test extends PHPUnit\Framework\TestCase
-{
- public function testSimpleString()
- {
- $bindings = array();
- $template = 'The quick brown fox jumps over the layz dog.';
- $expected = $template;
- $tmpl_obj = new Template($template);
-
- $this->assertEquals($expected, $tmpl_obj->render($bindings));
- }
-
- public function testConstantExpression()
- {
- $bindings = array();
- $template = '17 + 4 = {"foo" != "bar" ? 17 + 4 : 42.0}';
- $expected = '17 + 4 = 21';
- $tmpl_obj = new Template($template);
-
- $this->assertEquals($expected, $tmpl_obj->render($bindings));
- }
-
- public function testConditionExpression()
- {
- $bindings = array('a' => 0, 'b' => 42);
- $template = 'answer is {"" ?: a ?: b}';
- $expected = 'answer is 42';
- $tmpl_obj = new Template($template);
-
- $this->assertEquals($expected, $tmpl_obj->render($bindings));
- }
-
- public function testStringEscapes()
- {
- $bindings = array();
- $template = '"{"\\tfoo\'\\"\\n"}{\'{"bar"}\'}"';
- $expected = "\"\tfoo'\"\n{\"bar\"}\"";
- $tmpl_obj = new Template($template);
-
- $this->assertEquals($expected, $tmpl_obj->render($bindings));
- }
-
- public function testOperatorPrecedence()
- {
- $bindings = array('val' => array(array(42)));
- $template = '{-val[0][0] / (17+4) + 8 > 6 && "foo" == "f"~"o"~"o" ? 1 : 2}';
- $expected = '2';
- $tmpl_obj = new Template($template);
-
- $this->assertEquals($expected, $tmpl_obj->render($bindings));
- }
-
- public function testSimpleBindings()
- {
- $bindings = array('foo' => 'bar', 'val' => array(17, 4), 'pi' => 3.14159);
- $template = 'foo = "{foo}", sum = {val[0] + val[1]}, pi^2 = {pi * pi}, x = {x}';
- $expected = 'foo = "bar", sum = 21, pi^2 = 9.8695877281, x = ';
- $tmpl_obj = new Template($template);
-
- $this->assertEquals($expected, $tmpl_obj->render($bindings));
- }
-
- public function testConditional()
- {
- $bindings = array('foo' => 'bar', 'pi' => 3.14159);
- $template = '{if foo == "foo"}NO{elseif foo == "bar"}pi = {pi}{else}NO{endif}';
- $expected = 'pi = 3.14159';
- $tmpl_obj = new Template($template);
-
- $this->assertEquals($expected, $tmpl_obj->render($bindings));
- }
-
- public function testConditionalIteration()
- {
- $bindings = array('foo' => 'bar', 'pi' => 3.14159);
- $template = '{foreach foo}{if foo}{foo}{endif}{endforeach}';
- $expected = 'bar';
- $tmpl_obj = new Template($template);
-
- $this->assertEquals($expected, $tmpl_obj->render($bindings));
- }
-
- public function testIteration()
- {
- $bindings = array('persons' => array(
- 1 => array('user' => 'jane', 'phone' => '555-81281'),
- 2 => array('user' => 'mike', 'phone' => '230-28382'),
- 3 => array('user' => 'john', 'phone' => '911-19212')
- ));
- $template = '<ul>{foreach persons as person}<li>{index~":"~person.user~":"~phone}</li>{endforeach}</ul>';
- $expected = '<ul>' .
- '<li>1:jane:555-81281</li>' .
- '<li>2:mike:230-28382</li>' .
- '<li>3:john:911-19212</li>' .
- '</ul>';
- $tmpl_obj = new Template($template);
-
- $this->assertEquals($expected, $tmpl_obj->render($bindings));
- }
-
- public function testEmptyIteration()
- {
- $bindings = array('foo' => array(), 'bar' => false);
- $template = '{foreach foo}foo{endforeach}:{foreach bar}bar{endforeach}';
- $expected = ':';
- $tmpl_obj = new Template($template);
-
- $this->assertEquals($expected, $tmpl_obj->render($bindings));
- }
-
- public function testVariableScope()
- {
- $bindings = array('value' => 42, 'test' => array(
- array(),
- array('value' => 17),
- array('test' => array(
- array(),
- array('value' => 4)
- ))
- ));
- $template = '{foreach test}{value}:{foreach test}{value}~{endforeach}{endforeach}';
- $expected = '42:42~17~42~17:17~17~17~42:42~4~';
- $tmpl_obj = new Template($template);
-
- $this->assertEquals($expected, $tmpl_obj->render($bindings));
- }
-
- public function testNestedStatements()
- {
- foreach (range(0, 9) as $i) {
- $bindings['loop'][$i]['i'] = "$i";
- }
- $template = '{foreach loop}' .
- '{if i+1>4 && i<(1+10/2)}{i==4*1 ? \'foo\'~i : "bar"}' .
- '{elseif !(i<=+4)}+{elseif i==""}..{else}{"-"}{endif}' .
- '{endforeach}';
- $expected = '----foo4bar++++';
- $tmpl_obj = new Template($template);
-
- $this->assertEquals($expected, $tmpl_obj->render($bindings));
- }
-
- public function testFunctionCall()
- {
- $bindings = array('val' => array(0, 1, 2, 3));
- $template = '{strlen("foobar") + count(val)}';
- $expected = '10';
- $tmpl_obj = new Template($template);
-
- $this->assertEquals($expected, $tmpl_obj->render($bindings));
- }
-
- public function testFilters()
- {
- $bindings = array(
- 'pi' => 3.14159,
- 'format' => function($a, $b) { return number_format($a, $b); },
- 'upper' => function($a) { return strtoupper($a); }
- );
- $template = '{pi|format(3) ~ ":" ~ "foobar"|upper}';
- $expected = '3.142:FOOBAR';
- $tmpl_obj = new Template($template);
-
- $this->assertEquals($expected, $tmpl_obj->render($bindings));
- }
-
- public function testRawFilter()
- {
- $bindings = array('foo' => '<img>', 'upper' => function($a) { return strtoupper($a); });
- $template = '{foo}:{foo|upper|raw}';
- $expected = '&lt;img&gt;:<IMG>';
- $tmpl_obj = new Template($template);
- $tmpl_obj->autoescape('html');
-
- $this->assertEquals($expected, $tmpl_obj->render($bindings));
- }
-
- public function testHtmlAutoEscape()
- {
- $bindings = array('foo' => '<img>', 'pi' => 3.14159);
- $template = '{foo}:{pi}';
- $expected = '&lt;img&gt;:3.14159';
- $tmpl_obj = new Template($template);
- $tmpl_obj->autoescape('html');
-
- $this->assertEquals($expected, $tmpl_obj->render($bindings));
- }
-
- public function testJsonAutoEscape()
- {
- $bindings = array('foo' => '<img>', 'pi' => 3.14159);
- $template = '{foo}:{pi}';
- $expected = '"<img>":3.14159';
- $tmpl_obj = new Template($template);
- $tmpl_obj->autoescape('json');
-
- $this->assertEquals($expected, $tmpl_obj->render($bindings));
- }
-}