mirror of
https://github.com/fenom-template/fenom.git
synced 2023-08-10 21:13:07 +03:00
Fix {switch} and ternary operator
This commit is contained in:
@ -5,6 +5,4 @@ php:
|
|||||||
- 5.4
|
- 5.4
|
||||||
- 5.5
|
- 5.5
|
||||||
|
|
||||||
before_script: composer install
|
|
||||||
|
|
||||||
script: phpunit
|
script: phpunit
|
@ -30,7 +30,6 @@ $fenom->setOptions($options);
|
|||||||
* **auto_escape**, `Fenom::AUTO_ESCAPE`, все выводящие переменные и результаты функций будут экранироваться
|
* **auto_escape**, `Fenom::AUTO_ESCAPE`, все выводящие переменные и результаты функций будут экранироваться
|
||||||
* **auto_trim**, `Fenom::AUTO_TRIM`, при компиляции, все пробельные символы между тегами будут удлаены.
|
* **auto_trim**, `Fenom::AUTO_TRIM`, при компиляции, все пробельные символы между тегами будут удлаены.
|
||||||
* **force_verify**, `Fenom::FORCE_VERIFY`, проверять обращение каждой переменной и возвращать NULL если переменной не существует.
|
* **force_verify**, `Fenom::FORCE_VERIFY`, проверять обращение каждой переменной и возвращать NULL если переменной не существует.
|
||||||
* **deny_static_methods**, `Fenom::DENY_STATIC_METHODS`, отключает возможность вызова статичных методов в шаблоне.
|
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$fenom->setOptions(array(
|
$fenom->setOptions(array(
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
Tag {switch}
|
Tag {switch}
|
||||||
============
|
============
|
||||||
|
|
||||||
|
The `{switch}` tag is similar to a series of `{if}` statements on the same expression.
|
||||||
|
In many occasions, you may want to compare the same variable (or expression) with many different values,
|
||||||
|
and execute a different piece of code depending on which value it equals to. This is exactly what the `{switch}` tag is for.
|
||||||
|
|
||||||
|
Tag `{switch}` accepts any expression. But `{case}` accepts only static scalar values or constants.
|
||||||
|
|
||||||
```smarty
|
```smarty
|
||||||
{switch <condition>}
|
{switch <condition>}
|
||||||
{case <value1>}
|
{case <value1>}
|
||||||
@ -9,7 +15,7 @@ Tag {switch}
|
|||||||
...
|
...
|
||||||
{case <value3>}
|
{case <value3>}
|
||||||
...
|
...
|
||||||
{default}
|
{default case <value1>}
|
||||||
...
|
...
|
||||||
{/switch}
|
{/switch}
|
||||||
```
|
```
|
||||||
@ -24,14 +30,14 @@ For example,
|
|||||||
It is new or current item
|
It is new or current item
|
||||||
{case 'current'}
|
{case 'current'}
|
||||||
It is current item
|
It is current item
|
||||||
{case 'new'}
|
{case 'new', $.const.NEW_STATUS}
|
||||||
It is new item, again
|
It is new item, again
|
||||||
{default}
|
{default}
|
||||||
I don't know the type {$type}
|
I don't know the type {$type}
|
||||||
{/switch}
|
{/switch}
|
||||||
```
|
```
|
||||||
|
|
||||||
set `$type = 'new'`, then template output
|
if `$type = 'new'` then template output
|
||||||
|
|
||||||
```
|
```
|
||||||
It is new item
|
It is new item
|
||||||
|
@ -332,10 +332,12 @@ class Compiler
|
|||||||
*/
|
*/
|
||||||
public static function switchOpen(Tokenizer $tokens, Scope $scope)
|
public static function switchOpen(Tokenizer $tokens, Scope $scope)
|
||||||
{
|
{
|
||||||
$scope["expr"] = $scope->tpl->parseExpr($tokens);
|
$expr = $scope->tpl->parseExpr($tokens);
|
||||||
$scope["case"] = array();
|
$scope["case"] = array();
|
||||||
$scope["last"] = array();
|
$scope["last"] = array();
|
||||||
$scope["default"] = '';
|
$scope["default"] = '';
|
||||||
|
$scope["var"] = $scope->tpl->tmpVar();
|
||||||
|
$scope["expr"] = $scope["var"].' = strval('.$expr.')';
|
||||||
// lazy init
|
// lazy init
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@ -409,13 +411,16 @@ class Compiler
|
|||||||
public static function switchClose(Tokenizer $tokens, Scope $scope)
|
public static function switchClose(Tokenizer $tokens, Scope $scope)
|
||||||
{
|
{
|
||||||
self::_caseResort($scope);
|
self::_caseResort($scope);
|
||||||
$expr = $scope["expr"];
|
$expr = $scope["var"];
|
||||||
$code = "";
|
$code = $scope["expr"].";\n";
|
||||||
$default = $scope["default"];
|
$default = $scope["default"];
|
||||||
foreach ($scope["case"] as $case => $content) {
|
foreach ($scope["case"] as $case => $content) {
|
||||||
|
if(is_numeric($case)) {
|
||||||
|
$case = "'$case'";
|
||||||
|
}
|
||||||
$code .= "if($expr == $case) {\n?>$content<?php\n} else";
|
$code .= "if($expr == $case) {\n?>$content<?php\n} else";
|
||||||
}
|
}
|
||||||
$code .= " {\n?>$default<?php\n}";
|
$code .= " {\n?>$default<?php\n}\nunset(".$scope["var"].")";
|
||||||
return $code;
|
return $code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,7 +622,7 @@ class Template extends Render
|
|||||||
$var = false;
|
$var = false;
|
||||||
}
|
}
|
||||||
if ($tokens->is('?', '!')) {
|
if ($tokens->is('?', '!')) {
|
||||||
$term = $this->parseTernary($tokens, $term, $tokens->current());
|
$term = $this->parseTernary($tokens, $term, $var);
|
||||||
$var = false;
|
$var = false;
|
||||||
}
|
}
|
||||||
$exp[] = $term;
|
$exp[] = $term;
|
||||||
@ -873,35 +873,59 @@ class Template extends Render
|
|||||||
*
|
*
|
||||||
* @param Tokenizer $tokens
|
* @param Tokenizer $tokens
|
||||||
* @param $var
|
* @param $var
|
||||||
* @param $type
|
* @param $is_var
|
||||||
* @return string
|
* @return string
|
||||||
* @throws UnexpectedTokenException
|
* @throws UnexpectedTokenException
|
||||||
*/
|
*/
|
||||||
public function parseTernary(Tokenizer $tokens, $var, $type)
|
public function parseTernary(Tokenizer $tokens, $var, $is_var)
|
||||||
{
|
{
|
||||||
$empty = ($type === "?");
|
$empty = $tokens->is('?');
|
||||||
$tokens->next();
|
$tokens->next();
|
||||||
if ($tokens->is(":")) {
|
if ($tokens->is(":")) {
|
||||||
$tokens->next();
|
$tokens->next();
|
||||||
if ($empty) {
|
if ($empty) {
|
||||||
return '(empty(' . $var . ') ? (' . $this->parseExpr($tokens) . ') : ' . $var . ')';
|
if($is_var) {
|
||||||
|
return '(empty(' . $var . ') ? (' . $this->parseExpr($tokens) . ') : ' . $var . ')';
|
||||||
|
} else {
|
||||||
|
return '(' . $var . ' ?: (' . $this->parseExpr($tokens) . ')';
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return '(isset(' . $var . ') ? ' . $var . ' : (' . $this->parseExpr($tokens) . '))';
|
if($is_var) {
|
||||||
|
return '(isset(' . $var . ') ? ' . $var . ' : (' . $this->parseExpr($tokens) . '))';
|
||||||
|
} else {
|
||||||
|
return '((' . $var . ' !== null) ? ' . $var . ' : (' . $this->parseExpr($tokens) . '))';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} elseif ($tokens->is(Tokenizer::MACRO_BINARY, Tokenizer::MACRO_BOOLEAN, Tokenizer::MACRO_MATH) || !$tokens->valid()) {
|
} elseif ($tokens->is(Tokenizer::MACRO_BINARY, Tokenizer::MACRO_BOOLEAN, Tokenizer::MACRO_MATH) || !$tokens->valid()) {
|
||||||
if ($empty) {
|
if ($empty) {
|
||||||
return '!empty(' . $var . ')';
|
if($is_var) {
|
||||||
|
return '!empty(' . $var . ')';
|
||||||
|
} else {
|
||||||
|
return '(' . $var . ')';
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return 'isset(' . $var . ')';
|
if($is_var) {
|
||||||
|
return 'isset(' . $var . ')';
|
||||||
|
} else {
|
||||||
|
return '(' . $var . ' !== null)';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$expr1 = $this->parseExpr($tokens);
|
$expr1 = $this->parseExpr($tokens);
|
||||||
$tokens->need(':')->skip();
|
$tokens->need(':')->skip();
|
||||||
$expr2 = $this->parseExpr($tokens);
|
$expr2 = $this->parseExpr($tokens);
|
||||||
if ($empty) {
|
if ($empty) {
|
||||||
return '(empty(' . $var . ') ? ' . $expr2 . ' : ' . $expr1 . ')';
|
if($is_var) {
|
||||||
|
return '(empty(' . $var . ') ? ' . $expr2 . ' : ' . $expr1 . ')';
|
||||||
|
} else {
|
||||||
|
return '(' . $var . ' ? ' . $expr1 . ' : ' . $expr2 . ')';
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return '(isset(' . $var . ') ? ' . $expr1 . ' : ' . $expr2 . ')';
|
if($is_var) {
|
||||||
|
return '(isset(' . $var . ') ? ' . $expr1 . ' : ' . $expr2 . ')';
|
||||||
|
} else {
|
||||||
|
return '((' . $var . ' !== null) ? ' . $expr1 . ' : ' . $expr2 . ')';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1035,22 +1059,23 @@ class Template extends Render
|
|||||||
*/
|
*/
|
||||||
public function parseScalar(Tokenizer $tokens)
|
public function parseScalar(Tokenizer $tokens)
|
||||||
{
|
{
|
||||||
$_scalar = "";
|
|
||||||
$token = $tokens->key();
|
$token = $tokens->key();
|
||||||
switch ($token) {
|
switch ($token) {
|
||||||
case T_CONSTANT_ENCAPSED_STRING:
|
case T_CONSTANT_ENCAPSED_STRING:
|
||||||
case T_LNUMBER:
|
case T_LNUMBER:
|
||||||
case T_DNUMBER:
|
case T_DNUMBER:
|
||||||
$_scalar .= $tokens->getAndNext();
|
return $tokens->getAndNext();
|
||||||
break;
|
break;
|
||||||
case T_ENCAPSED_AND_WHITESPACE:
|
case T_ENCAPSED_AND_WHITESPACE:
|
||||||
case '"':
|
case '"':
|
||||||
$_scalar .= $this->parseQuote($tokens);
|
return $this->parseQuote($tokens);
|
||||||
break;
|
break;
|
||||||
|
case '$':
|
||||||
|
$tokens->next()->need('.')->next()->need(T_CONST)->next();
|
||||||
|
return 'constant('.$this->parseName($tokens).')';
|
||||||
default:
|
default:
|
||||||
throw new UnexpectedTokenException($tokens);
|
throw new UnexpectedTokenException($tokens);
|
||||||
}
|
}
|
||||||
return $_scalar;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once __DIR__ . "/../vendor/autoload.php";
|
$loader = include(__DIR__ . "/../vendor/autoload.php");
|
||||||
|
/* @var Composer\Autoload\ClassLoader $loader */
|
||||||
|
$loader->add('Fenom', __DIR__.'/cases');
|
||||||
|
|
||||||
|
|
||||||
define('FENOM_RESOURCES', __DIR__ . "/resources");
|
define('FENOM_RESOURCES', __DIR__ . "/resources");
|
||||||
|
Reference in New Issue
Block a user