diff options
Diffstat (limited to 'lib/exTpl/IteratorNode.php')
| -rw-r--r-- | lib/exTpl/IteratorNode.php | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/lib/exTpl/IteratorNode.php b/lib/exTpl/IteratorNode.php new file mode 100644 index 0000000..58dd593 --- /dev/null +++ b/lib/exTpl/IteratorNode.php @@ -0,0 +1,55 @@ +<?php + +namespace exTpl; + +/** + * IteratorNode represents a single iterator tag: + * "{foreach ARRAY [as [KEY =>] VALUE]}...{endforeach}". + */ +class IteratorNode extends ArrayNode +{ + protected Expression $expr; + protected string $key_name; + protected string $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, string $key_name, string $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 $context): string + { + $values = $this->expr->value($context); + $result = ''; + + if (is_array($values) && is_int(key($values))) { + $bindings = [$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; + } +} |
