Merge branch 'origin/master'

Conflicts:
	src/Fenom/Compiler.php
	src/Fenom/Template.php
	tests/cases/Fenom/TemplateTest.php
	tests/cases/Fenom/TokenizerTest.php
	tests/cases/FenomTest.php
This commit is contained in:
Ivan Shalganov 2013-09-15 16:39:29 +04:00
commit dcb91775ca
12 changed files with 87 additions and 19 deletions

5
.coveralls.yml Normal file
View File

@ -0,0 +1,5 @@
service_name: travis-ci
src_dir: src
coverage_clover: build/logs/clover.xml

View File

@ -5,6 +5,11 @@ php:
- 5.4
- 5.5
before_script: composer install
before_script:
- composer install --dev
script: phpunit
script:
- phpunit
after_script:
- php vendor/bin/coveralls

View File

@ -1,7 +1,26 @@
Changelog
=========
## 1.4.0
### 1.4.4
- Bug fixes
- Tests++
### 1.4.3
- Bug fixes
### 1.4.2 (2013-09-06)
- Added check the cache directory to record
### 1.4.1 (2013-09-05)
- Fix equating for {case} in {switch}
- Fix ternary operator when option `force_verify` is enabled
- Docs++
## 1.4.0 (2013-09-02)
- Redesign tag {switch}
- Add tag {insert}

View File

@ -3,7 +3,9 @@ Fenom - Template Engine for PHP
> Composer package: `{"fenom/fenom": "dev-master"}`. See on [Packagist.org](https://packagist.org/packages/fenom/fenom)
[![Latest Stable Version](https://poser.pugx.org/fenom/fenom/v/stable.png)](https://packagist.org/packages/fenom/fenom)
[![Build Status](https://travis-ci.org/bzick/fenom.png?branch=master)](https://travis-ci.org/bzick/fenom)
[![Coverage Status](https://coveralls.io/repos/bzick/fenom/badge.png?branch=master)](https://coveralls.io/r/bzick/fenom?branch=master)
## [Usage](./docs/usage.md) :: [Documentation](./docs/readme.md) :: [Benchmark](./docs/benchmark.md) :: [Articles](./docs/articles.md)
* Simple [syntax](./docs/syntax.md)

View File

@ -17,7 +17,8 @@
"require-dev": {
"phpunit/phpunit": "3.7.*",
"smarty/smarty": "3.*",
"twig/twig": "1.*"
"twig/twig": "1.*",
"satooshi/php-coveralls": "dev-master"
},
"autoload": {
"psr-0": { "Fenom\\": "src/" },

View File

@ -30,7 +30,6 @@ $fenom->setOptions($options);
* **auto_escape**, `Fenom::AUTO_ESCAPE`, все выводящие переменные и результаты функций будут экранироваться
* **auto_trim**, `Fenom::AUTO_TRIM`, при компиляции, все пробельные символы между тегами будут удлаены.
* **force_verify**, `Fenom::FORCE_VERIFY`, проверять обращение каждой переменной и возвращать NULL если переменной не существует.
* **deny_static_methods**, `Fenom::DENY_STATIC_METHODS`, отключает возможность вызова статичных методов в шаблоне.
```php
$fenom->setOptions(array(

View File

@ -1,6 +1,12 @@
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
{switch <condition>}
{case <value1>}
@ -9,7 +15,7 @@ Tag {switch}
...
{case <value3>}
...
{default}
{default case <value1>}
...
{/switch}
```
@ -24,14 +30,14 @@ For example,
It is new or current item
{case 'current'}
It is current item
{case 'new'}
{case 'new', $.const.NEW_STATUS}
It is new item, again
{default}
I don't know the type {$type}
{/switch}
```
set `$type = 'new'`, then template output
if `$type = 'new'` then template output
```
It is new item

View File

@ -34,8 +34,8 @@
<directory>./src/</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-clover" target="build/logs/clover.xml"/>
<!--<log type="coverage-php" target="build/cov/coverage.cov"/>-->
</logging>
</phpunit>

View File

@ -35,7 +35,7 @@ class Fenom
const FORCE_COMPILE = 0x100;
const AUTO_ESCAPE = 0x200;
const DISABLE_CACHE = 0x400;
const FORCE_VERIFY = 0x800; // reserved
const FORCE_VERIFY = 0x800;
const AUTO_TRIM = 0x1000; // reserved
const DENY_STATICS = 0x2000; // reserved
@ -288,10 +288,14 @@ class Fenom
* Set compile directory
*
* @param string $dir directory to store compiled templates in
* @throws LogicException
* @return Fenom
*/
public function setCompileDir($dir)
{
if(!is_writable($dir)) {
throw new LogicException("Cache directory $dir is not writable");
}
$this->_compile_dir = $dir;
return $this;
}
@ -796,7 +800,7 @@ class Fenom
fclose($tpl_fp);
$file_name = $this->_compile_dir . "/" . $cache;
if (!rename($tpl_tmp, $file_name)) {
throw new \RuntimeException("Can't to move $tpl_tmp to $tpl");
throw new \RuntimeException("Can't to move $tpl_tmp to $file_name");
}
}
return $template;

View File

@ -39,7 +39,8 @@ class Compiler
if ($name && ($tpl->getStorage()->getOptions() & \Fenom::FORCE_INCLUDE)) {
$inc = $tpl->getStorage()->compile($name, false);
$tpl->addDepend($inc);
return '$_tpl = (array)$tpl; $tpl->exchangeArray(' . self::toArray($p) . '+$_tpl); ?>' . $inc->getBody() . '<?php $tpl->exchangeArray($_tpl); unset($_tpl);';
$var = $tpl->tmpVar();
return $var.' = (array)$tpl; $tpl->exchangeArray(' . self::toArray($p) . '+'.$var.'); ?>' . $inc->getBody() . '<?php $tpl->exchangeArray('.$var.'); unset('.$var.');';
} else {
return '$tpl->getStorage()->getTemplate(' . $cname . ')->display(' . self::toArray($p) . '+(array)$tpl);';
}
@ -47,7 +48,8 @@ class Compiler
if ($name && ($tpl->getStorage()->getOptions() & \Fenom::FORCE_INCLUDE)) {
$inc = $tpl->getStorage()->compile($name, false);
$tpl->addDepend($inc);
return '$_tpl = (array)$tpl; ?>' . $inc->getBody() . '<?php $tpl->exchangeArray($_tpl); unset($_tpl);';
$var = $tpl->tmpVar();
return $var.' = (array)$tpl; ?>' . $inc->getBody() . '<?php $tpl->exchangeArray('.$var.'); unset('.$var.');';
} else {
return '$tpl->getStorage()->getTemplate(' . $cname . ')->display((array)$tpl);';
}
@ -332,10 +334,12 @@ class Compiler
*/
public static function switchOpen(Tokenizer $tokens, Scope $scope)
{
$scope["expr"] = $scope->tpl->parseExpr($tokens);
$expr = $scope->tpl->parseExpr($tokens);
$scope["case"] = array();
$scope["last"] = array();
$scope["default"] = '';
$scope["var"] = $scope->tpl->tmpVar();
$scope["expr"] = $scope["var"].' = strval('.$expr.')';
// lazy init
return '';
}
@ -409,13 +413,16 @@ class Compiler
public static function switchClose(Tokenizer $tokens, Scope $scope)
{
self::_caseResort($scope);
$expr = $scope["expr"];
$code = "";
$expr = $scope["var"];
$code = $scope["expr"].";\n";
$default = $scope["default"];
foreach ($scope["case"] as $case => $content) {
if(is_numeric($case)) {
$case = "'$case'";
}
$code .= "if($expr == $case) {\n?>$content<?php\n} else";
}
$code .= " {\n?>$default<?php\n}";
$code .= " {\n?>$default<?php\n}\nunset(".$scope["var"].")";
return $code;
}

View File

@ -1,6 +1,8 @@
<?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");

View File

@ -10,10 +10,14 @@ class TokenizerTest extends \PHPUnit_Framework_TestCase
{
$code = 'hello, please resolve this example: sin($x)+tan($x*$t) = {U|[0,1]}';
$tokens = new Tokenizer($code);
$this->assertSame($tokens, $tokens->back());
$this->assertSame(T_STRING, $tokens->key());
$this->assertSame("hello", $tokens->current());
$this->assertSame(1, $tokens->getLine());
$this->assertTrue($tokens->isNext(","));
$this->assertFalse($tokens->isNext("="));
$this->assertFalse($tokens->isNext(T_STRING));
$this->assertFalse($tokens->isNext($tokens::MACRO_UNARY));
@ -24,6 +28,13 @@ class TokenizerTest extends \PHPUnit_Framework_TestCase
$this->assertSame(",", $tokens->getNext());
$this->assertSame(",", $tokens->key());
$this->assertSame("please", $tokens->getNext(T_STRING));
$this->assertSame(array(
T_STRING,
'please',
' ',
1,
'T_STRING'
), $tokens->curr);
$this->assertSame("resolve", $tokens->getNext($tokens::MACRO_UNARY, T_STRING));
$tokens->next();
@ -51,6 +62,7 @@ class TokenizerTest extends \PHPUnit_Framework_TestCase
$this->assertSame($code, $tokens->getSnippetAsString(-100, 100));
$this->assertSame('+', $tokens->getSnippetAsString(100, -100));
$this->assertSame('sin($x)+tan($x*$t)', $tokens->getSnippetAsString(-4, 6));
}
public function testSkip()
@ -67,8 +79,14 @@ class TokenizerTest extends \PHPUnit_Framework_TestCase
}
$this->assertTrue($tokens->valid());
$this->assertSame("3", $tokens->current());
$this->assertSame(T_LNUMBER, $tokens->key());
$this->assertSame($tokens, $tokens->next());
$tokens->next();
$this->assertSame("double", $tokens->getAndNext());
$this->assertSame(")", $tokens->current());
$this->assertTrue($tokens->isLast());
$this->assertSame($tokens, $tokens->next());
}
}