diff --git a/CHANGELOG.md b/CHANGELOG.md index 95aba6a..3c580c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,17 @@ CHANGELOG ========= +## 1.0.5 + +### Add `Fenom::AUTO_ESCAPE` support (feature #2) +### Update documentation + +## 1.0.4 (2013-06-27) + +### Add nested level for {extends} and {use} +### Small bug fix +### Update documentation + ## 1.0.3 (2013-06-20) ### Allow any callable for modifier (instead string) diff --git a/docs/develop.md b/docs/develop.md new file mode 100644 index 0000000..c84934c --- /dev/null +++ b/docs/develop.md @@ -0,0 +1,6 @@ +Develop +======= + +If you want to discuss the enhancement of the Fenom, create an issue on Github or submit a pull request. + +For questions: a.cobest@gmail.com (English, Russian languages) \ No newline at end of file diff --git a/docs/main.md b/docs/main.md index b20d256..845a52d 100644 --- a/docs/main.md +++ b/docs/main.md @@ -5,6 +5,7 @@ Documentation * [Install](./install.md) * [Usage](./usage.md) +* [Develop](./develop.md) * [Syntax](./syntax.md) * [Settings](./settings.md) * [Callbacks and filters](./callbacks.md) diff --git a/src/Fenom.php b/src/Fenom.php index 712074a..22e61ab 100644 --- a/src/Fenom.php +++ b/src/Fenom.php @@ -12,6 +12,8 @@ use Fenom\Template, /** * Fenom Template Engine + * + * @author Ivan Shalganov */ class Fenom { const VERSION = '1.0'; @@ -24,12 +26,13 @@ class Fenom { const MODIFIER = 5; /* Options */ - const DENY_METHODS = 0x10; - const DENY_INLINE_FUNCS = 0x20; - const FORCE_INCLUDE = 0x40; - const AUTO_RELOAD = 0x80; - const FORCE_COMPILE = 0xF0; + const DENY_METHODS = 0x10; + const DENY_INLINE_FUNCS = 0x20; + const FORCE_INCLUDE = 0x40; + const AUTO_RELOAD = 0x80; + const FORCE_COMPILE = 0xF0; const DISABLE_CACHE = 0x1F0; + const AUTO_ESCAPE = 0x200; /* Default parsers */ const DEFAULT_CLOSE_COMPILER = 'Fenom\Compiler::stdClose'; diff --git a/src/Fenom/Compiler.php b/src/Fenom/Compiler.php index 6856bda..7918761 100644 --- a/src/Fenom/Compiler.php +++ b/src/Fenom/Compiler.php @@ -15,6 +15,7 @@ use Fenom\Scope; /** * Compilers collection * @package Fenom + * @author Ivan Shalganov */ class Compiler { /** diff --git a/src/Fenom/Modifier.php b/src/Fenom/Modifier.php index 06af1ec..35b675a 100644 --- a/src/Fenom/Modifier.php +++ b/src/Fenom/Modifier.php @@ -11,7 +11,7 @@ namespace Fenom; /** * Collection of modifiers - * + * @author Ivan Shalganov */ class Modifier { diff --git a/src/Fenom/Provider.php b/src/Fenom/Provider.php index 17abc10..f99e158 100644 --- a/src/Fenom/Provider.php +++ b/src/Fenom/Provider.php @@ -11,7 +11,7 @@ namespace Fenom; use Fenom\ProviderInterface; /** - * Templates provider + * Base template provider * @author Ivan Shalganov */ class Provider implements ProviderInterface { @@ -110,10 +110,14 @@ class Provider implements ProviderInterface { * @param string $tpl * @return bool */ - public function isTemplateExists($tpl) { + public function templateExists($tpl) { return file_exists($this->_path."/".$tpl); } + /** + * @param array $tpls + * @return array + */ public function getLastModifiedBatch($tpls) { $tpls = array_flip($tpls); foreach($tpls as $tpl => &$time) { diff --git a/src/Fenom/ProviderInterface.php b/src/Fenom/ProviderInterface.php index ffd20d8..a8f2978 100644 --- a/src/Fenom/ProviderInterface.php +++ b/src/Fenom/ProviderInterface.php @@ -9,12 +9,17 @@ */ namespace Fenom; +/** + * Template provider interface + * @package Fenom + * @author Ivan Shalganov + */ interface ProviderInterface { /** * @param string $tpl * @return bool */ - public function isTemplateExists($tpl); + public function templateExists($tpl); /** * @param string $tpl * @param int $time diff --git a/src/Fenom/Render.php b/src/Fenom/Render.php index 89d9f22..f92d69a 100644 --- a/src/Fenom/Render.php +++ b/src/Fenom/Render.php @@ -12,6 +12,7 @@ use Fenom; /** * Primitive template + * @author Ivan Shalganov */ class Render extends \ArrayObject { private static $_props = array( diff --git a/src/Fenom/Scope.php b/src/Fenom/Scope.php index 69ea05a..8480f81 100644 --- a/src/Fenom/Scope.php +++ b/src/Fenom/Scope.php @@ -11,6 +11,8 @@ namespace Fenom; /** * Scope for blocks tags + * + * @author Ivan Shalganov */ class Scope extends \ArrayObject { diff --git a/src/Fenom/Template.php b/src/Fenom/Template.php index ad15102..686eb87 100644 --- a/src/Fenom/Template.php +++ b/src/Fenom/Template.php @@ -14,7 +14,7 @@ use Fenom; * Template compiler * * @package Fenom - * @author Ivan Shalganov + * @author Ivan Shalganov */ class Template extends Render { @@ -391,6 +391,13 @@ class Template extends Render { return parent::fetch($values); } + private function _print($data) { + if($this->_options & Fenom::AUTO_ESCAPE) { + return "echo htmlspecialchars($data, ENT_COMPAT, 'UTF-8')"; + } else { + return "echo $data"; + } + } /** * Internal tags router * @param Tokenizer $tokens @@ -412,9 +419,9 @@ class Template extends Render { } elseif ($tokens->is('/')) { return $this->_end($tokens); } elseif ($tokens->is('#')) { - return "echo ".$this->parseConst($tokens).';'; + return $this->_print($this->parseConst($tokens)).';'; } else { - return $code = "echo ".$this->parseExp($tokens).";"; + return $code = $this->_print($this->parseExp($tokens)).";"; } } catch (InvalidUsageException $e) { throw new CompileException($e->getMessage()." in {$this} line {$this->_line}", 0, E_ERROR, $this->_name, $this->_line, $e); @@ -460,12 +467,12 @@ class Template extends Render { if($tokens->is(Tokenizer::MACRO_STRING)) { $action = $tokens->getAndNext(); } else { - return 'echo '.$this->parseExp($tokens).';'; // may be math and/or boolean expression + return $this->_print($this->parseExp($tokens)).';'; // may be math and/or boolean expression } if($tokens->is("(", T_NAMESPACE, T_DOUBLE_COLON)) { // just invoke function or static method $tokens->back(); - return "echo ".$this->parseExp($tokens).";"; + return $this->_print($this->parseExp($tokens)).";"; } elseif($tokens->is('.')) { $name = $tokens->skip()->get(Tokenizer::MACRO_STRING); if($action !== "macro") { @@ -1110,4 +1117,5 @@ class Template extends Render { class CompileException extends \ErrorException {} class SecurityException extends CompileException {} -class InvalidUsageException extends \LogicException {} \ No newline at end of file +class InvalidUsageException extends \LogicException {} +class TokenizeException extends \RuntimeException {} \ No newline at end of file diff --git a/src/Fenom/Tokenizer.php b/src/Fenom/Tokenizer.php index 72098c0..f4a0621 100644 --- a/src/Fenom/Tokenizer.php +++ b/src/Fenom/Tokenizer.php @@ -33,6 +33,7 @@ defined('T_YIELD') || define('T_YIELD', 370); * @property array $next the next token * * @package Fenom + * @author Ivan Shalganov */ class Tokenizer { const TOKEN = 0; @@ -244,13 +245,13 @@ class Tokenizer { /** * If the next token is a valid one, move the position of cursor one step forward. Otherwise throws an exception. * @param array $tokens - * @throws TokenizeException + * @throws UnexpectedTokenException * @return mixed */ public function _next($tokens) { $this->next(); if(!$this->curr) { - throw new TokenizeException("Unexpected end of expression"); + throw new UnexpectedTokenException($this, $tokens); } if($tokens) { if($this->_valid($tokens, $this->key())) { @@ -259,12 +260,7 @@ class Tokenizer { } else { return; } - if(count($tokens) == 1 && is_string($tokens[0])) { - $expect = ", expect '".$tokens[0]."'"; - } else { - $expect = ""; - } - throw new TokenizeException("Unexpected token '".$this->current()."'$expect"); + throw new UnexpectedTokenException($this, $tokens); } /** @@ -560,15 +556,10 @@ class Tokenizer { } } -/** - * Tokenize error - */ -class TokenizeException extends \RuntimeException {} - /** * Unexpected token */ -class UnexpectedTokenException extends TokenizeException { +class UnexpectedTokenException extends \RuntimeException { public function __construct(Tokenizer $tokens, $expect = null, $where = null) { if($expect && count($expect) == 1 && is_string($expect[0])) { $expect = ", expect '".$expect[0]."'"; diff --git a/tests/cases/Fenom/ProviderTest.php b/tests/cases/Fenom/ProviderTest.php index c62fb16..fcd336a 100644 --- a/tests/cases/Fenom/ProviderTest.php +++ b/tests/cases/Fenom/ProviderTest.php @@ -16,8 +16,8 @@ class FSProviderTest extends \Fenom\TestCase { } public function testIsTemplateExists() { - $this->assertTrue($this->provider->isTemplateExists("template1.tpl")); - $this->assertFalse($this->provider->isTemplateExists("unexists.tpl")); + $this->assertTrue($this->provider->templateExists("template1.tpl")); + $this->assertFalse($this->provider->templateExists("unexists.tpl")); } public function testGetSource() {