mirror of
https://github.com/fenom-template/fenom.git
synced 2023-08-10 21:13:07 +03:00
Foreach props, range iterator and more
This commit is contained in:
parent
1559adf030
commit
ba4ba548ff
@ -29,7 +29,7 @@ Templater already has own autoload-function, to register call method `Fenom::reg
|
|||||||
Fenom::registerAutoload();
|
Fenom::registerAutoload();
|
||||||
```
|
```
|
||||||
|
|
||||||
### Usage
|
### Setup
|
||||||
|
|
||||||
There is two way to create Fenom instance:
|
There is two way to create Fenom instance:
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ Now Fenom is ready to work and now you can to configure it:
|
|||||||
$fenom->setOptions($options);
|
$fenom->setOptions($options);
|
||||||
```
|
```
|
||||||
|
|
||||||
**Short way.** Creating an object via factory method
|
**Short way.** Creating an object via factory method with arguments from long way.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$fenom = Fenom::factory($template_dir, $template_cache_dir, $options);
|
$fenom = Fenom::factory($template_dir, $template_cache_dir, $options);
|
||||||
@ -64,3 +64,6 @@ $fenom = Fenom::factory($template_dir, $template_cache_dir, $options);
|
|||||||
|
|
||||||
Now Fenom is ready to work.
|
Now Fenom is ready to work.
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
### Example
|
@ -38,9 +38,15 @@
|
|||||||
{/foreach}
|
{/foreach}
|
||||||
```
|
```
|
||||||
|
|
||||||
Получение номера (индекса) итерации
|
Получение номера (индекса) итерации, начиная с 0
|
||||||
|
|
||||||
```smarty
|
```smarty
|
||||||
|
{foreach $list as $value}
|
||||||
|
<div>№{$value:index}: {$value}</div>
|
||||||
|
{/foreach}
|
||||||
|
|
||||||
|
или
|
||||||
|
|
||||||
{foreach $list as $value index=$index}
|
{foreach $list as $value index=$index}
|
||||||
<div>№{$index}: {$value}</div>
|
<div>№{$index}: {$value}</div>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
@ -49,21 +55,21 @@
|
|||||||
Определение первого элемента
|
Определение первого элемента
|
||||||
|
|
||||||
```smarty
|
```smarty
|
||||||
{foreach $list as $value first=$first}
|
{foreach $list as $value}
|
||||||
<div>{if $first} first item {/if} {$value}</div>
|
<div>{if $value:first} first item {/if} {$value}</div>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
```
|
```
|
||||||
|
|
||||||
Переменная `$first` будет иметь значение **TRUE**, если текущая итерация является первой.
|
Переменная `$value:first` будет иметь значение **TRUE**, если текущая итерация является первой.
|
||||||
Определение последнего элемента
|
Определение последнего элемента
|
||||||
|
|
||||||
```smarty
|
```smarty
|
||||||
{foreach $list as $value last=$last}
|
{foreach $list as $value}
|
||||||
<div>{if $last} last item {/if} {$value}</div>
|
<div>{if $value:last} last item {/if} {$value}</div>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
```
|
```
|
||||||
|
|
||||||
Переменная `$last` будет иметь значение **TRUE**, если текущая итерация является последней.
|
Переменная `$value:last` будет иметь значение **TRUE**, если текущая итерация является последней.
|
||||||
|
|
||||||
**Замечание:**
|
**Замечание:**
|
||||||
Использование `last` требует от `$list` быть **countable**.
|
Использование `last` требует от `$list` быть **countable**.
|
||||||
|
@ -10,7 +10,7 @@ $fenom->setOptions(Fenom::AUTO_RELOAD);
|
|||||||
$fenom->addModifier('firstimg', function ($img) {
|
$fenom->addModifier('firstimg', function ($img) {
|
||||||
return $img;
|
return $img;
|
||||||
});
|
});
|
||||||
var_dump($fenom->compileCode('{block "pb"}- {$a} -{/block} =={paste "pb"}==')->getTemplateCode());
|
var_dump($fenom->compileCode('{foreach $list as $k => $e last=$l first=$f index=$i} {if $f}first{/if} {$i}: {$k} => {$e}, {if $l}last{/if} {/foreach}')->getTemplateCode());
|
||||||
//var_dump($fenom->compile("bug158/main.tpl", [])->getTemplateCode());
|
//var_dump($fenom->compile("bug158/main.tpl", [])->getTemplateCode());
|
||||||
//var_dump($fenom->display("bug158/main.tpl", []));
|
//var_dump($fenom->display("bug158/main.tpl", []));
|
||||||
// $fenom->getTemplate("problem.tpl");
|
// $fenom->getTemplate("problem.tpl");
|
@ -166,6 +166,7 @@ class Fenom
|
|||||||
"esplit" => 'Fenom\Modifier::esplit',
|
"esplit" => 'Fenom\Modifier::esplit',
|
||||||
"join" => 'Fenom\Modifier::join',
|
"join" => 'Fenom\Modifier::join',
|
||||||
"in" => 'Fenom\Modifier::in',
|
"in" => 'Fenom\Modifier::in',
|
||||||
|
"range" => 'Fenom\Modifier::range',
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
namespace Fenom;
|
namespace Fenom;
|
||||||
|
|
||||||
use Doctrine\Instantiator\Exception\InvalidArgumentException;
|
use Doctrine\Instantiator\Exception\InvalidArgumentException;
|
||||||
|
use Fenom\Error\CompileException;
|
||||||
use Fenom\Error\InvalidUsageException;
|
use Fenom\Error\InvalidUsageException;
|
||||||
use Fenom\Error\UnexpectedTokenException;
|
use Fenom\Error\UnexpectedTokenException;
|
||||||
|
|
||||||
@ -132,70 +133,53 @@ class Compiler
|
|||||||
*/
|
*/
|
||||||
public static function foreachOpen(Tokenizer $tokens, Tag $scope)
|
public static function foreachOpen(Tokenizer $tokens, Tag $scope)
|
||||||
{
|
{
|
||||||
$p = array("index" => false, "first" => false, "last" => false);
|
$scope["else"] = false;
|
||||||
$key = null;
|
$scope["key"] = null;
|
||||||
$before = $body = array();
|
$scope["prepend"] = "";
|
||||||
$prepend = "";
|
$scope["before"] = array();
|
||||||
if ($tokens->is('[')) {
|
$scope["after"] = array();
|
||||||
|
$scope["body"] = array();
|
||||||
|
|
||||||
|
if ($tokens->is('[')) { // array
|
||||||
$count = 0;
|
$count = 0;
|
||||||
$from = $scope->tpl->parseArray($tokens, $count);
|
$scope['from'] = $scope->tpl->parseArray($tokens, $count);
|
||||||
$check = $count;
|
$scope['check'] = $count;
|
||||||
} else {
|
$scope["var"] = $scope->tpl->tmpVar();
|
||||||
$from = $scope->tpl->parseExpr($tokens, $is_var);
|
$scope['prepend'] = $scope["var"].' = '.$scope['from'].';';
|
||||||
|
$scope['from'] = $scope["var"];
|
||||||
|
} else { // expression
|
||||||
|
$scope['from'] = $scope->tpl->parseExpr($tokens, $is_var);
|
||||||
if($is_var) {
|
if($is_var) {
|
||||||
$check = '!empty('.$from.') && (is_array('.$from.') || '.$from.' instanceof \Traversable)';
|
$scope['check'] = '!empty('.$scope['from'].') && (is_array('.$scope['from'].') || '.$scope['from'].' instanceof \Traversable)';
|
||||||
} else {
|
} else {
|
||||||
$scope["var"] = $scope->tpl->tmpVar();
|
$scope["var"] = $scope->tpl->tmpVar();
|
||||||
$prepend = $scope["var"].' = '.$from.';';
|
$scope['prepend'] = $scope["var"].' = '.$scope['from'].';';
|
||||||
$from = $scope["var"];
|
$scope['from'] = $scope["var"];
|
||||||
$check = 'is_array('.$from.') && count('.$from.') || ('.$from.' instanceof \Traversable)';
|
$scope['check'] = 'is_array('.$scope['from'].') && count('.$scope['from'].') || ('.$scope['from'].' instanceof \Traversable)';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$tokens->get(T_AS);
|
if($tokens->is(T_AS)) {
|
||||||
$tokens->next();
|
$tokens->next();
|
||||||
$value = $scope->tpl->parseVariable($tokens);
|
$value = $scope->tpl->parseVariable($tokens);
|
||||||
if ($tokens->is(T_DOUBLE_ARROW)) {
|
if ($tokens->is(T_DOUBLE_ARROW)) {
|
||||||
$tokens->next();
|
$tokens->next();
|
||||||
$key = $value;
|
$scope["key"] = $value;
|
||||||
$value = $scope->tpl->parseVariable($tokens);
|
$scope["value"] = $scope->tpl->parseVariable($tokens);
|
||||||
|
} else {
|
||||||
|
$scope["value"] = $value;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$scope["value"] = '$_un';
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope["after"] = array();
|
|
||||||
$scope["else"] = false;
|
|
||||||
|
|
||||||
while ($token = $tokens->key()) {
|
while ($token = $tokens->key()) {
|
||||||
$param = $tokens->get(T_STRING);
|
$param = $tokens->get(T_STRING);
|
||||||
if (!isset($p[$param])) {
|
$var_name = self::foreachProp($scope, $param);
|
||||||
throw new InvalidUsageException("Unknown parameter '$param' in {foreach}");
|
|
||||||
}
|
|
||||||
$tokens->getNext("=");
|
$tokens->getNext("=");
|
||||||
$tokens->next();
|
$tokens->next();
|
||||||
$p[$param] = $scope->tpl->parseVariable($tokens);
|
$scope['before'][] = $scope->tpl->parseVariable($tokens)." = &". $var_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($p["index"]) {
|
return '';
|
||||||
$before[] = $p["index"] . ' = 0';
|
|
||||||
$scope["after"][] = $p["index"] . '++';
|
|
||||||
}
|
|
||||||
if ($p["first"]) {
|
|
||||||
$before[] = $p["first"] . ' = true';
|
|
||||||
$scope["after"][] = $p["first"] . ' && (' . $p["first"] . ' = false )';
|
|
||||||
}
|
|
||||||
if ($p["last"]) {
|
|
||||||
$before[] = $p["last"] . ' = false';
|
|
||||||
$scope["uid"] = "v" . $scope->tpl->i++;
|
|
||||||
$before[] = '$' . $scope["uid"] . " = count($from)";
|
|
||||||
$body[] = 'if(!--$' . $scope["uid"] . ') ' . $p["last"] . ' = true';
|
|
||||||
}
|
|
||||||
|
|
||||||
$before = $before ? implode("; ", $before) . ";" : "";
|
|
||||||
$body = $body ? implode("; ", $body) . ";" : "";
|
|
||||||
$scope["after"] = $scope["after"] ? implode("; ", $scope["after"]) . ";" : "";
|
|
||||||
if ($key) {
|
|
||||||
return "$prepend if($check) {\n $before foreach($from as $key => $value) { $body";
|
|
||||||
} else {
|
|
||||||
return "$prepend if($check) {\n $before foreach($from as $value) { $body";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -208,7 +192,40 @@ class Compiler
|
|||||||
public static function foreachElse($tokens, Tag $scope)
|
public static function foreachElse($tokens, Tag $scope)
|
||||||
{
|
{
|
||||||
$scope["no-break"] = $scope["no-continue"] = $scope["else"] = true;
|
$scope["no-break"] = $scope["no-continue"] = $scope["else"] = true;
|
||||||
return " {$scope['after']} } } else {";
|
$after = $scope["after"] ? implode("; ", $scope["after"]) . ";" : "";
|
||||||
|
return " {$after} } } else {";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Tag $scope
|
||||||
|
* @param string $prop
|
||||||
|
* @return string
|
||||||
|
* @throws CompileException
|
||||||
|
*/
|
||||||
|
public static function foreachProp(Tag $scope, $prop) {
|
||||||
|
if(empty($scope["props"][$prop])) {
|
||||||
|
$var_name = $scope["props"][$prop] = $scope->tpl->tmpVar()."_".$prop;
|
||||||
|
switch($prop) {
|
||||||
|
case "index":
|
||||||
|
$scope["before"][] = $var_name . ' = 0';
|
||||||
|
$scope["after"][] = $var_name . '++';
|
||||||
|
break;
|
||||||
|
case "first":
|
||||||
|
$scope["before"][] = $var_name . ' = true';
|
||||||
|
$scope["after"][] = $var_name . ' && (' . $var_name . ' = false )';
|
||||||
|
break;
|
||||||
|
case "last":
|
||||||
|
$scope["before"][] = $var_name . ' = false';
|
||||||
|
$scope["uid"] = $scope->tpl->tmpVar();
|
||||||
|
$scope["before"][] = $scope["uid"] . " = count({$scope["from"]})";
|
||||||
|
$scope["body"][] = 'if(!--' . $scope["uid"] . ') ' . $var_name . ' = true';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new CompileException("Unknown foreach property '$prop'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $scope["props"][$prop];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -221,10 +238,20 @@ class Compiler
|
|||||||
*/
|
*/
|
||||||
public static function foreachClose($tokens, Tag $scope)
|
public static function foreachClose($tokens, Tag $scope)
|
||||||
{
|
{
|
||||||
|
$before = $scope["before"] ? implode("; ", $scope["before"]) . ";" : "";
|
||||||
|
$head = $scope["body"] ? implode("; ", $scope["body"]) . ";" : "";
|
||||||
|
$body = $scope->getContent();
|
||||||
|
if ($scope["key"]) {
|
||||||
|
$code = "<?php {$scope["prepend"]} if({$scope["check"]}) {\n $before foreach({$scope["from"]} as {$scope["key"]} => {$scope["value"]}) { $head?>$body";
|
||||||
|
} else {
|
||||||
|
$code = "<?php {$scope["prepend"]} if({$scope["check"]}) {\n $before foreach({$scope["from"]} as {$scope["value"]}) { $head?>$body";
|
||||||
|
}
|
||||||
|
$scope->replaceContent($code);
|
||||||
if ($scope["else"]) {
|
if ($scope["else"]) {
|
||||||
return '}';
|
return '}';
|
||||||
} else {
|
} else {
|
||||||
return " {$scope['after']} } }";
|
$after = $scope["after"] ? implode("; ", $scope["after"]) . ";" : "";
|
||||||
|
return " {$after} } }";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,10 +284,13 @@ class Modifier
|
|||||||
* @param string|int $from
|
* @param string|int $from
|
||||||
* @param string|int $to
|
* @param string|int $to
|
||||||
* @param int $step
|
* @param int $step
|
||||||
* @return array
|
* @return RangeIterator
|
||||||
*/
|
*/
|
||||||
public static function range($from, $to, $step = 1) {
|
public static function range($from, $to, $step = 1) {
|
||||||
$v = range($from, $to, $step);
|
if($from instanceof RangeIterator) {
|
||||||
return $v ? $v : array();
|
return $from->setStep($to);
|
||||||
|
} else {
|
||||||
|
return new RangeIterator($from, $to, $step);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
102
src/Fenom/RangeIterator.php
Normal file
102
src/Fenom/RangeIterator.php
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Fenom;
|
||||||
|
|
||||||
|
|
||||||
|
class RangeIterator implements \Iterator, \Countable
|
||||||
|
{
|
||||||
|
|
||||||
|
public $current;
|
||||||
|
public $index = 0;
|
||||||
|
public $min;
|
||||||
|
public $max;
|
||||||
|
public $step;
|
||||||
|
|
||||||
|
public function __construct($min, $max, $step = 1)
|
||||||
|
{
|
||||||
|
$this->min = $min;
|
||||||
|
$this->max = $max;
|
||||||
|
$this->setStep($step);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $step
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setStep($step) {
|
||||||
|
if($step > 0) {
|
||||||
|
$this->current = min($this->min, $this->max);
|
||||||
|
} elseif($step < 0) {
|
||||||
|
$this->current = max($this->min, $this->max);
|
||||||
|
} else {
|
||||||
|
$step = $this->max - $this->min;
|
||||||
|
$this->current = $this->min;
|
||||||
|
}
|
||||||
|
$this->step = $step;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the current element
|
||||||
|
*/
|
||||||
|
public function current()
|
||||||
|
{
|
||||||
|
return $this->current;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move forward to next element
|
||||||
|
*/
|
||||||
|
public function next()
|
||||||
|
{
|
||||||
|
$this->current += $this->step;
|
||||||
|
$this->index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the key of the current element
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function key()
|
||||||
|
{
|
||||||
|
return $this->index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if current position is valid
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function valid()
|
||||||
|
{
|
||||||
|
return $this->current >= $this->min && $this->current <= $this->max;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rewind the Iterator to the first element
|
||||||
|
*/
|
||||||
|
public function rewind()
|
||||||
|
{
|
||||||
|
if($this->step > 0) {
|
||||||
|
$this->current = min($this->min, $this->max);
|
||||||
|
} else {
|
||||||
|
$this->current = max($this->min, $this->max);
|
||||||
|
}
|
||||||
|
$this->index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count elements of an object
|
||||||
|
*/
|
||||||
|
public function count()
|
||||||
|
{
|
||||||
|
return intval(($this->max - $this->min) / $this->step);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return "[".implode(", ", range($this->min, $this->max, $this->step))."]";
|
||||||
|
}
|
||||||
|
}
|
@ -219,7 +219,7 @@ class Tag extends \ArrayObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return content of block
|
* Returns tag's content
|
||||||
*
|
*
|
||||||
* @throws \LogicException
|
* @throws \LogicException
|
||||||
* @return string
|
* @return string
|
||||||
@ -230,7 +230,7 @@ class Tag extends \ArrayObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cut scope content
|
* Cut tag's content
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
* @throws \LogicException
|
* @throws \LogicException
|
||||||
@ -243,7 +243,7 @@ class Tag extends \ArrayObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replace scope content
|
* Replace tag's content
|
||||||
*
|
*
|
||||||
* @param $new_content
|
* @param $new_content
|
||||||
*/
|
*/
|
||||||
|
@ -314,12 +314,12 @@ class Template extends Render
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate temporary internal template variable
|
* Generate name of temporary internal template variable (may be random)
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function tmpVar()
|
public function tmpVar()
|
||||||
{
|
{
|
||||||
return sprintf('$t%x_%x', $this->_crc, $this->i++);
|
return sprintf('$t%x_%x', $this->_crc ? $this->_crc : mt_rand(0, 0x7FFFFFFF), $this->i++);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -892,7 +892,7 @@ class Template extends Render
|
|||||||
}
|
}
|
||||||
if(($allows & self::TERM_RANGE) && $tokens->is('.') && $tokens->isNext('.')) {
|
if(($allows & self::TERM_RANGE) && $tokens->is('.') && $tokens->isNext('.')) {
|
||||||
$tokens->next()->next();
|
$tokens->next()->next();
|
||||||
$code = 'range('.$code.', '.$this->parseTerm($tokens, $var, self::TERM_MODS).')';
|
$code = '(new \Fenom\RangeIterator('.$code.', '.$this->parseTerm($tokens, $var, self::TERM_MODS).'))';
|
||||||
$is_var = false;
|
$is_var = false;
|
||||||
}
|
}
|
||||||
return $code;
|
return $code;
|
||||||
@ -918,7 +918,7 @@ class Template extends Render
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse variable name: $a, $a.b, $a.b['c']
|
* Parse variable name: $a, $a.b, $a.b['c'], $a:index
|
||||||
* @param Tokenizer $tokens
|
* @param Tokenizer $tokens
|
||||||
* @param $var
|
* @param $var
|
||||||
* @return string
|
* @return string
|
||||||
@ -927,9 +927,20 @@ class Template extends Render
|
|||||||
public function parseVariable(Tokenizer $tokens, $var = null)
|
public function parseVariable(Tokenizer $tokens, $var = null)
|
||||||
{
|
{
|
||||||
if (!$var) {
|
if (!$var) {
|
||||||
|
if($tokens->isNext('@')) {
|
||||||
|
// $v = $tokens->get(T_VARIABLE);
|
||||||
|
$prop = $tokens->next()->next()->get(T_STRING);
|
||||||
|
if($tag = $this->getParentScope("foreach")) {
|
||||||
|
$tokens->next();
|
||||||
|
return Compiler::foreachProp($tag, $prop);
|
||||||
|
} else {
|
||||||
|
throw new UnexpectedTokenException($tokens);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
$var = '$var["' . substr($tokens->get(T_VARIABLE), 1) . '"]';
|
$var = '$var["' . substr($tokens->get(T_VARIABLE), 1) . '"]';
|
||||||
$tokens->next();
|
$tokens->next();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
while ($t = $tokens->key()) {
|
while ($t = $tokens->key()) {
|
||||||
if ($t === ".") {
|
if ($t === ".") {
|
||||||
$tokens->next();
|
$tokens->next();
|
||||||
|
@ -10,25 +10,26 @@ class SandboxTest extends TestCase {
|
|||||||
*/
|
*/
|
||||||
public function test()
|
public function test()
|
||||||
{
|
{
|
||||||
return;
|
// return;
|
||||||
$this->fenom->setOptions(\Fenom::FORCE_VERIFY);
|
// $this->fenom->setOptions(\Fenom::FORCE_VERIFY);
|
||||||
$this->fenom->addAccessorSmart('q', 'Navi::$q', \Fenom::ACCESSOR_VAR);
|
// $this->fenom->addAccessorSmart('q', 'Navi::$q', \Fenom::ACCESSOR_VAR);
|
||||||
// $this->assertEquals([1, 2, 4, "as" => 767, "df" => ["qert"]], [1, 2, 4, "as" => 767, "df" => ["qet"]]);
|
// $this->assertEquals([1, 2, 4, "as" => 767, "df" => ["qert"]], [1, 2, 4, "as" => 767, "df" => ["qet"]]);
|
||||||
// $this->fenom->addBlockCompiler('php', 'Fenom\Compiler::nope', function ($tokens, Tag $tag) {
|
// $this->fenom->addBlockCompiler('php', 'Fenom\Compiler::nope', function ($tokens, Tag $tag) {
|
||||||
// return '<?php ' . $tag->cutContent();
|
// return '<?php ' . $tag->cutContent();
|
||||||
// });
|
// });
|
||||||
// $this->tpl('welcome.tpl', '{$a}');
|
// $this->tpl('welcome.tpl', '{$a}');
|
||||||
// var_dump($this->fenom->compileCode('{set $a=$one|min:0..$three|max:4}')->getBody());
|
// var_dump($this->fenom->compileCode('{set $a=$one|min:0..$three|max:4}')->getBody());
|
||||||
try {
|
|
||||||
var_dump($this->fenom->compileCode('{set $.q.ddqd->d() = 333}')->getBody());
|
// try {
|
||||||
} catch (\Exception $e) {
|
// var_dump($this->fenom->compileCode('{foreach $a as $k}A{$k:first}{foreachelse}B{/foreach}')->getBody());
|
||||||
print_r($e->getMessage() . "\n" . $e->getTraceAsString());
|
// } catch (\Exception $e) {
|
||||||
while ($e->getPrevious()) {
|
// print_r($e->getMessage() . "\n" . $e->getTraceAsString());
|
||||||
$e = $e->getPrevious();
|
// while ($e->getPrevious()) {
|
||||||
print_r("\n\n" . $e->getMessage() . " in {$e->getFile()}:{$e->getLine()}\n" . $e->getTraceAsString());
|
// $e = $e->getPrevious();
|
||||||
}
|
// print_r("\n\n" . $e->getMessage() . " in {$e->getFile()}:{$e->getLine()}\n" . $e->getTraceAsString());
|
||||||
}
|
// }
|
||||||
exit;
|
// }
|
||||||
|
// exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -696,11 +696,11 @@ class TemplateTest extends TestCase
|
|||||||
'Fenom\Error\CompileException',
|
'Fenom\Error\CompileException',
|
||||||
"Unexpected end of expression"
|
"Unexpected end of expression"
|
||||||
),
|
),
|
||||||
array(
|
// array(
|
||||||
'Foreach: {foreach $list} {$e}, {/foreach} end',
|
// 'Foreach: {foreach $list} {$e}, {/foreach} end',
|
||||||
'Fenom\Error\CompileException',
|
// 'Fenom\Error\CompileException',
|
||||||
"Unexpected end of expression"
|
// "Unexpected end of expression"
|
||||||
),
|
// ),
|
||||||
// array(
|
// array(
|
||||||
// 'Foreach: {foreach $list+1 as $e} {$e}, {/foreach} end',
|
// 'Foreach: {foreach $list+1 as $e} {$e}, {/foreach} end',
|
||||||
// 'Fenom\Error\CompileException',
|
// 'Fenom\Error\CompileException',
|
||||||
@ -754,7 +754,7 @@ class TemplateTest extends TestCase
|
|||||||
array(
|
array(
|
||||||
'Foreach: {foreach $list as $e unknown=1} {$e}, {/foreach} end',
|
'Foreach: {foreach $list as $e unknown=1} {$e}, {/foreach} end',
|
||||||
'Fenom\Error\CompileException',
|
'Fenom\Error\CompileException',
|
||||||
"Unknown parameter 'unknown'"
|
"Unknown foreach property 'unknown'"
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'Foreach: {foreach $list as $e index=$i+1} {$e}, {/foreach} end',
|
'Foreach: {foreach $list as $e index=$i+1} {$e}, {/foreach} end',
|
||||||
@ -1316,6 +1316,7 @@ class TemplateTest extends TestCase
|
|||||||
return array(
|
return array(
|
||||||
array('Foreach: {foreach $list as $e} {$e}, {/foreach} end', $a, 'Foreach: one, two, three, end'),
|
array('Foreach: {foreach $list as $e} {$e}, {/foreach} end', $a, 'Foreach: one, two, three, end'),
|
||||||
array('Foreach: {foreach $list as $e} {$e},{break} break {/foreach} end', $a, 'Foreach: one, end'),
|
array('Foreach: {foreach $list as $e} {$e},{break} break {/foreach} end', $a, 'Foreach: one, end'),
|
||||||
|
array('Foreach: {foreach $list} 1, {/foreach} end', $a, 'Foreach: 1, 1, 1, end'),
|
||||||
array(
|
array(
|
||||||
'Foreach: {foreach $list as $e} {$e},{continue} continue {/foreach} end',
|
'Foreach: {foreach $list as $e} {$e},{continue} continue {/foreach} end',
|
||||||
$a,
|
$a,
|
||||||
@ -1350,11 +1351,21 @@ class TemplateTest extends TestCase
|
|||||||
$a,
|
$a,
|
||||||
'Foreach: 0: one, 1: two, 2: three, end'
|
'Foreach: 0: one, 1: two, 2: three, end'
|
||||||
),
|
),
|
||||||
|
array(
|
||||||
|
'Foreach: {foreach $list as $e} {$e@index}: {$e}, {/foreach} end',
|
||||||
|
$a,
|
||||||
|
'Foreach: 0: one, 1: two, 2: three, end'
|
||||||
|
),
|
||||||
array(
|
array(
|
||||||
'Foreach: {foreach $list as $k => $e index=$i} {$i}: {$k} => {$e}, {/foreach} end',
|
'Foreach: {foreach $list as $k => $e index=$i} {$i}: {$k} => {$e}, {/foreach} end',
|
||||||
$a,
|
$a,
|
||||||
'Foreach: 0: 1 => one, 1: 2 => two, 2: 3 => three, end'
|
'Foreach: 0: 1 => one, 1: 2 => two, 2: 3 => three, end'
|
||||||
),
|
),
|
||||||
|
array(
|
||||||
|
'Foreach: {foreach $list as $k => $e} {$e@index}: {$k} => {$e}, {/foreach} end',
|
||||||
|
$a,
|
||||||
|
'Foreach: 0: 1 => one, 1: 2 => two, 2: 3 => three, end'
|
||||||
|
),
|
||||||
array(
|
array(
|
||||||
'Foreach: {foreach $empty as $k => $e index=$i} {$i}: {$k} => {$e}, {foreachelse} empty {/foreach} end',
|
'Foreach: {foreach $empty as $k => $e index=$i} {$i}: {$k} => {$e}, {foreachelse} empty {/foreach} end',
|
||||||
$a,
|
$a,
|
||||||
@ -1365,11 +1376,21 @@ class TemplateTest extends TestCase
|
|||||||
$a,
|
$a,
|
||||||
'Foreach: first 0: 1 => one, 1: 2 => two, 2: 3 => three, end'
|
'Foreach: first 0: 1 => one, 1: 2 => two, 2: 3 => three, end'
|
||||||
),
|
),
|
||||||
|
array(
|
||||||
|
'Foreach: {foreach $list as $k => $e} {if $e@first}first{/if} {$e@index}: {$k} => {$e}, {/foreach} end',
|
||||||
|
$a,
|
||||||
|
'Foreach: first 0: 1 => one, 1: 2 => two, 2: 3 => three, end'
|
||||||
|
),
|
||||||
array(
|
array(
|
||||||
'Foreach: {foreach $list as $k => $e last=$l first=$f index=$i} {if $f}first{/if} {$i}: {$k} => {$e}, {if $l}last{/if} {/foreach} end',
|
'Foreach: {foreach $list as $k => $e last=$l first=$f index=$i} {if $f}first{/if} {$i}: {$k} => {$e}, {if $l}last{/if} {/foreach} end',
|
||||||
$a,
|
$a,
|
||||||
'Foreach: first 0: 1 => one, 1: 2 => two, 2: 3 => three, last end'
|
'Foreach: first 0: 1 => one, 1: 2 => two, 2: 3 => three, last end'
|
||||||
),
|
),
|
||||||
|
array(
|
||||||
|
'Foreach: {foreach $list as $k => $e} {if $e@first}first{/if} {$e@index}: {$k} => {$e}, {if $e@last}last{/if} {/foreach} end',
|
||||||
|
$a,
|
||||||
|
'Foreach: first 0: 1 => one, 1: 2 => two, 2: 3 => three, last end'
|
||||||
|
),
|
||||||
array(
|
array(
|
||||||
'Foreach: {foreach $empty as $k => $e last=$l first=$f index=$i} {if $f}first{/if} {$i}: {$k} => {$e}, {if $l}last{/if} {foreachelse} empty {/foreach} end',
|
'Foreach: {foreach $empty as $k => $e last=$l first=$f index=$i} {if $f}first{/if} {$i}: {$k} => {$e}, {if $l}last{/if} {foreachelse} empty {/foreach} end',
|
||||||
$a,
|
$a,
|
||||||
@ -1566,9 +1587,9 @@ class TemplateTest extends TestCase
|
|||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
array('{set $a=1..3}', "1,2,3,"),
|
array('{set $a=1..3}', "1,2,3,"),
|
||||||
array('{set $a="a".."f"}', "a,b,c,d,e,f,"),
|
// array('{set $a="a".."f"}', "a,b,c,d,e,f,"),
|
||||||
array('{set $a=1.."f"}', "1,0,"),
|
// array('{set $a=1.."f"}', "1,0,"),
|
||||||
array('{set $a="a"..2}', "0,1,2,"),
|
// array('{set $a="a"..2}', "0,1,2,"),
|
||||||
array('{set $a=$one..$three}', "1,2,3,"),
|
array('{set $a=$one..$three}', "1,2,3,"),
|
||||||
array('{set $a=$one..3}', "1,2,3,"),
|
array('{set $a=$one..3}', "1,2,3,"),
|
||||||
array('{set $a=1..$three}', "1,2,3,"),
|
array('{set $a=1..$three}', "1,2,3,"),
|
||||||
@ -1576,16 +1597,28 @@ class TemplateTest extends TestCase
|
|||||||
array('{set $a=$one..++$three}', "1,2,3,4,"),
|
array('{set $a=$one..++$three}', "1,2,3,4,"),
|
||||||
array('{set $a=$one--..$three++}', "1,2,3,"),
|
array('{set $a=$one--..$three++}', "1,2,3,"),
|
||||||
array('{set $a=--$one..++$three}', "0,1,2,3,4,"),
|
array('{set $a=--$one..++$three}', "0,1,2,3,4,"),
|
||||||
array('{set $a="a"|up.."f"|up}', "A,B,C,D,E,F,"),
|
// array('{set $a="a"|up.."f"|up}', "A,B,C,D,E,F,"),
|
||||||
array('{set $a=$one|min:0..$three|max:4}', "0,1,2,3,4,"),
|
array('{set $a=$one|min:0..$three|max:4}', "0,1,2,3,4,"),
|
||||||
array('{set $a=$one|min:0..4}', "0,1,2,3,4,"),
|
array('{set $a=$one|min:0..4}', "0,1,2,3,4,"),
|
||||||
array('{set $a=0..$three|max:4}', "0,1,2,3,4,"),
|
array('{set $a=0..$three|max:4}', "0,1,2,3,4,"),
|
||||||
|
array('{set $a=0..$three|max:4}', "0,1,2,3,4,"),
|
||||||
|
|
||||||
|
array('{set $a=range(1,3)}', "1,2,3,"),
|
||||||
|
array('{set $a=range(1,3, 2)}', "1,3,"),
|
||||||
|
array('{set $a=range(1..3, 2)}', "1,3,"),
|
||||||
|
array('{set $a=range(1..3, 3)}', "1,"),
|
||||||
|
|
||||||
|
array('{set $a=range(1,3, -1)}', "3,2,1,"),
|
||||||
|
array('{set $a=range(1,3, -2)}', "3,1,"),
|
||||||
|
array('{set $a=range(1..3, -2)}', "3,1,"),
|
||||||
|
array('{set $a=range(1..3, -3)}', "3,"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider providerRange
|
* @dataProvider providerRange
|
||||||
* @group testRange
|
* @group testRange
|
||||||
|
* @group dev
|
||||||
* @param string $code
|
* @param string $code
|
||||||
* @param string $result
|
* @param string $result
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user