diff --git a/.gitignore b/.gitignore index a8c7be1..f0c75a9 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ composer.phar tests/resources/compile/* !.gitkeep tests/resources/template/* -sandbox/compiled/* \ No newline at end of file +sandbox/compiled/* +/.phpunit.result.cache diff --git a/README.md b/README.md index c385de4..70595d8 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Fenom - Template Engine for PHP * **Subject:** Template engine * **Syntax:** Smarty-like * **Documentation:** **[English](./docs/en/readme.md)**, **[Russian](./docs/ru/readme.md)** -* **PHP version:** 5.4+ +* **PHP version:** 8.0+ * **State:** [![Build Status](https://travis-ci.org/fenom-template/fenom.svg?branch=master)](https://travis-ci.org/fenom-template/fenom) [![Coverage Status](https://coveralls.io/repos/fenom-template/fenom/badge.svg?branch=master)](https://coveralls.io/r/fenom-template/fenom?branch=master) * **Version:** [![Latest Stable Version](https://poser.pugx.org/fenom/fenom/v/stable.png)](https://packagist.org/packages/fenom/fenom) * **Packagist:** [fenom/fenom](https://packagist.org/packages/fenom/fenom) [![Total Downloads](https://poser.pugx.org/fenom/fenom/downloads.png)](https://packagist.org/packages/fenom/fenom) @@ -22,16 +22,10 @@ Fenom - Template Engine for PHP ### Install If you use composer in your project then you can to install Fenom as package. -However, if you are not using composer you have to configure _autoloader_ to work with Fenom. -Fenom implements the `PSR-0` PHP standard to load classes which are located in the `src/` directory. -Templater already has own autoload-function, to register call method `Fenom::registerAutoload`: -```php -Fenom::registerAutoload(); -``` ### Setup -There is two way to create Fenom instance: +There is two-way to create Fenom instance: * Long way: use operator `new` * Shot way: use static factory-method diff --git a/src/Fenom.php b/src/Fenom.php index 80cb8da..328542f 100644 --- a/src/Fenom.php +++ b/src/Fenom.php @@ -751,7 +751,7 @@ class Fenom * @param Template|null $template * @return mixed */ - public function getModifier(string $modifier, Fenom\Template $template = null): static + public function getModifier(string $modifier, Fenom\Template $template = null): string { if (isset($this->_modifiers[$modifier])) { return $this->_modifiers[$modifier]; @@ -765,12 +765,12 @@ class Fenom /** * Modifier autoloader * @param string $modifier - * @param Fenom\Template $template - * @return bool + * @param Template $template + * @return string|null */ - protected function _loadModifier(string $modifier, Fenom\Template $template): bool + protected function _loadModifier(string $modifier, Fenom\Template $template): ?string { - return false; + return null; } /** diff --git a/src/Fenom/Accessor.php b/src/Fenom/Accessor.php index 7635253..23e05d5 100644 --- a/src/Fenom/Accessor.php +++ b/src/Fenom/Accessor.php @@ -9,6 +9,7 @@ */ namespace Fenom; +use Fenom\Error\CompileException; use Fenom\Error\UnexpectedTokenException; /** @@ -16,7 +17,7 @@ use Fenom\Error\UnexpectedTokenException; * @package Fenom */ class Accessor { - public static $vars = array( + public static array $vars = array( 'get' => '$_GET', 'post' => '$_POST', 'session' => '$_SESSION', @@ -32,10 +33,11 @@ class Accessor { * @param string $var variable expression on PHP ('App::get("storage")->user') * @param Tokenizer $tokens * @param Template $tpl - * @param $is_var + * @param bool $is_var * @return string + * @throws CompileException */ - public static function parserVar($var, Tokenizer $tokens, Template $tpl, &$is_var) + public static function parserVar(string $var, Tokenizer $tokens, Template $tpl, bool &$is_var): string { $is_var = true; return $tpl->parseVariable($tokens, $var); @@ -47,7 +49,7 @@ class Accessor { * @param Template $tpl * @return string */ - public static function parserCall($call, Tokenizer $tokens, Template $tpl) + public static function parserCall(string $call, Tokenizer $tokens, Template $tpl): string { return $call.$tpl->parseArgs($tokens); } @@ -56,10 +58,11 @@ class Accessor { * @param string $prop fenom's property name * @param Tokenizer $tokens * @param Template $tpl - * @param $is_var + * @param bool $is_var * @return string + * @throws CompileException */ - public static function parserProperty($prop, Tokenizer $tokens, Template $tpl, &$is_var) + public static function parserProperty(string $prop, Tokenizer $tokens, Template $tpl, bool &$is_var): string { $is_var = true; return self::parserVar('$tpl->getStorage()->'.$prop, $tokens, $tpl, $is_var); @@ -71,7 +74,7 @@ class Accessor { * @param Template $tpl * @return string */ - public static function parserMethod($method, Tokenizer $tokens, Template $tpl) + public static function parserMethod(string $method, Tokenizer $tokens, Template $tpl): string { return self::parserCall('$tpl->getStorage()->'.$method, $tokens, $tpl); } @@ -81,13 +84,14 @@ class Accessor { * @param Tokenizer $tokens * @param Template $tpl * @return string + * @throws CompileException */ - public static function getVar(Tokenizer $tokens, Template $tpl) + public static function getVar(Tokenizer $tokens, Template $tpl): string { $name = $tokens->prevToken()[Tokenizer::TEXT]; if(isset(self::$vars[$name])) { $var = $tpl->parseVariable($tokens, self::$vars[$name]); - return "(isset($var) ? $var : null)"; + return "(($var) ?? null)"; } else { throw new UnexpectedTokenException($tokens->back()); } @@ -98,7 +102,7 @@ class Accessor { * @param Tokenizer $tokens * @return string */ - public static function tpl(Tokenizer $tokens) + public static function tpl(Tokenizer $tokens): string { $method = $tokens->skip('.')->need(T_STRING)->getAndNext(); if(method_exists('Fenom\Render', 'get'.$method)) { @@ -111,7 +115,7 @@ class Accessor { /** * @return string */ - public static function version() + public static function version(): string { return 'Fenom::VERSION'; } @@ -120,9 +124,9 @@ class Accessor { * @param Tokenizer $tokens * @return string */ - public static function constant(Tokenizer $tokens) + public static function constant(Tokenizer $tokens): string { - $const = array($tokens->skip('.')->need(Tokenizer::MACRO_STRING)->getAndNext()); + $const = [$tokens->skip('.')->need(Tokenizer::MACRO_STRING)->getAndNext()]; while($tokens->is('.')) { $const[] = $tokens->next()->need(Tokenizer::MACRO_STRING)->getAndNext(); } @@ -139,9 +143,9 @@ class Accessor { * @param Template $tpl * @return string */ - public static function call(Tokenizer $tokens, Template $tpl) + public static function call(Tokenizer $tokens, Template $tpl): string { - $callable = array($tokens->skip('.')->need(Tokenizer::MACRO_STRING)->getAndNext()); + $callable = [$tokens->skip('.')->need(Tokenizer::MACRO_STRING)->getAndNext()]; while($tokens->is('.')) { $callable[] = $tokens->next()->need(Tokenizer::MACRO_STRING)->getAndNext(); } @@ -175,7 +179,7 @@ class Accessor { * @param Template $tpl * @return string */ - public static function fetch(Tokenizer $tokens, Template $tpl) + public static function fetch(Tokenizer $tokens, Template $tpl): string { $tokens->skip('('); $name = $tpl->parsePlainArg($tokens, $static); @@ -188,7 +192,7 @@ class Accessor { $tokens->next(); if($tokens->is('[')){ $vars = $tpl->parseArray($tokens) . ' + $var'; - }elseif($tokens->is(T_VARIABLE)){ + } elseif($tokens->is(T_VARIABLE)){ $vars = $tpl->parseExpr($tokens) . ' + $var'; } } else { @@ -202,9 +206,9 @@ class Accessor { * Accessor {$.block.NAME} * @param Tokenizer $tokens * @param Template $tpl - * @return mixed + * @return string */ - public static function block(Tokenizer $tokens, Template $tpl) + public static function block(Tokenizer $tokens, Template $tpl): string { if($tokens->is('.')) { $name = $tokens->next()->get(Tokenizer::MACRO_STRING); diff --git a/src/Fenom/Compiler.php b/src/Fenom/Compiler.php index dd48c52..082db5a 100644 --- a/src/Fenom/Compiler.php +++ b/src/Fenom/Compiler.php @@ -30,7 +30,7 @@ class Compiler * @throws \LogicException * @return string */ - public static function tagInclude(Tokenizer $tokens, Tag $tag) + public static function tagInclude(Tokenizer $tokens, Tag $tag): string { $tpl = $tag->tpl; $name = false; @@ -72,10 +72,10 @@ class Compiler * Tag {insert ...} * @param Tokenizer $tokens * @param Tag $tag - * @throws Error\InvalidUsageException * @return string + * @throws Error\InvalidUsageException|CompileException */ - public static function tagInsert(Tokenizer $tokens, Tag $tag) + public static function tagInsert(Tokenizer $tokens, Tag $tag): string { $tpl = $tag->tpl; $tpl->parsePlainArg($tokens, $name); @@ -95,8 +95,9 @@ class Compiler * @param Tokenizer $tokens * @param Tag $scope * @return string + * @throws \Exception */ - public static function ifOpen(Tokenizer $tokens, Tag $scope) + public static function ifOpen(Tokenizer $tokens, Tag $scope): string { $scope["else"] = false; return 'if(' . $scope->tpl->parseExpr($tokens) . ') {'; diff --git a/src/Fenom/Modifier.php b/src/Fenom/Modifier.php index b51c7d3..3550ce9 100644 --- a/src/Fenom/Modifier.php +++ b/src/Fenom/Modifier.php @@ -19,11 +19,11 @@ class Modifier /** * Date format * - * @param string|int $date + * @param int|string $date * @param string $format * @return string */ - public static function dateFormat($date, $format = "%b %e, %Y") + public static function dateFormat(int|string $date, string $format = "%b %e, %Y"): string { if (!is_numeric($date)) { $date = strtotime($date); @@ -39,7 +39,7 @@ class Modifier * @param string $format * @return string */ - public static function date($date, $format = "Y m d") + public static function date(string $date, string $format = "Y m d"): string { if (!is_numeric($date)) { $date = strtotime($date); @@ -55,18 +55,18 @@ class Modifier * * @param string $text * @param string $type - * @param string $charset + * @param string|null $charset * @return string */ - public static function escape($text, $type = 'html', $charset = null) + public static function escape(string $text, string $type = 'html', string $charset = null): string { switch (strtolower($type)) { case "url": return urlencode($text); case "html"; - return htmlspecialchars($text, ENT_COMPAT, $charset ? $charset : \Fenom::$charset); + return htmlspecialchars($text, ENT_COMPAT, $charset ?: \Fenom::$charset); case "js": - return json_encode($text, 64 | 256); // JSON_UNESCAPED_SLASHES = 64, JSON_UNESCAPED_UNICODE = 256 + return json_encode($text, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); default: return $text; } @@ -79,7 +79,7 @@ class Modifier * @param string $type * @return string */ - public static function unescape($text, $type = 'html') + public static function unescape(string $text, string $type = 'html'): string { switch (strtolower($type)) { case "url": @@ -96,12 +96,12 @@ class Modifier * * @param string $string text witch will be truncate * @param int $length maximum symbols of result string - * @param string $etc place holder truncated symbols + * @param string $etc placeholder truncated symbols * @param bool $by_words * @param bool $middle * @return string */ - public static function truncate($string, $length = 80, $etc = '...', $by_words = false, $middle = false) + public static function truncate(string $string, int $length = 80, string $etc = '...', bool $by_words = false, bool $middle = false): string { if ($middle) { if (preg_match('#^(.{' . $length . '}).*?(.{' . $length . '})?$#usS', $string, $match)) { @@ -134,7 +134,7 @@ class Modifier * @param bool $to_line strip line ends * @return string */ - public static function strip($str, $to_line = false) + public static function strip(string $str, bool $to_line = false): string { $str = trim($str); if ($to_line) { @@ -149,7 +149,7 @@ class Modifier * @param mixed $item * @return int */ - public static function length($item) + public static function length(mixed $item): int { if (is_string($item)) { return strlen(preg_replace('#[\x00-\x7F]|[\x80-\xDF][\x00-\xBF]|[\xE0-\xEF][\x00-\xBF]{2}#s', ' ', $item)); @@ -168,13 +168,13 @@ class Modifier * @param mixed $haystack * @return bool */ - public static function in($value, $haystack) + public static function in(mixed $value, mixed $haystack): bool { if(is_scalar($value)) { if (is_array($haystack)) { return in_array($value, $haystack) || array_key_exists($value, $haystack); } elseif (is_string($haystack)) { - return strpos($haystack, $value) !== false; + return str_contains($haystack, $value); } } return false; @@ -184,7 +184,7 @@ class Modifier * @param mixed $value * @return bool */ - public static function isIterable($value) + public static function isIterable(mixed $value): bool { return is_array($value) || ($value instanceof \Iterator); } @@ -196,7 +196,7 @@ class Modifier * @param string $replace The replacement value that replaces found search * @return mixed */ - public static function replace($value, $search, $replace) + public static function replace(string $value, string $search, string $replace): string { return str_replace($search, $replace, $value); } @@ -207,7 +207,7 @@ class Modifier * @param string $replacement * @return mixed */ - public static function ereplace($value, $pattern, $replacement) + public static function ereplace(string $value, string $pattern, string $replacement): string { return preg_replace($pattern, $replacement, $value); } @@ -217,7 +217,7 @@ class Modifier * @param string $pattern * @return bool */ - public static function match($string, $pattern) + public static function match(string $string, string $pattern): bool { return fnmatch($pattern, $string); } @@ -227,7 +227,7 @@ class Modifier * @param string $pattern * @return int */ - public static function ematch($string, $pattern) + public static function ematch(string $string, string $pattern): int { return preg_match($pattern, $string); } @@ -237,23 +237,23 @@ class Modifier * @param string $delimiter * @return array */ - public static function split($value, $delimiter = ",") + public static function split(mixed $value, string $delimiter = ","): array { if(is_string($value)) { return explode($delimiter, $value); } elseif(is_array($value)) { return $value; } else { - return array(); + return []; } } /** - * @param $value + * @param mixed $value * @param string $pattern * @return array */ - public static function esplit($value, $pattern = '/,\s*/S') + public static function esplit(mixed $value, string $pattern = '/,\s*/S'): array { if(is_string($value)) { return preg_split($pattern, $value); @@ -265,11 +265,11 @@ class Modifier } /** - * @param $value + * @param mixed $value * @param string $glue * @return string */ - public static function join($value, $glue = ",") + public static function join(mixed $value, string $glue = ","): string { if(is_array($value)) { return implode($glue, $value); @@ -281,12 +281,13 @@ class Modifier } /** - * @param string|int $from - * @param string|int $to + * @param int $from + * @param int $to * @param int $step * @return RangeIterator */ - public static function range($from, $to, $step = 1) { + public static function range(mixed $from, int $to, int $step = 1): RangeIterator + { if($from instanceof RangeIterator) { return $from->setStep($to); } else { diff --git a/src/Fenom/Render.php b/src/Fenom/Render.php index 4cfc2a3..d83a57c 100644 --- a/src/Fenom/Render.php +++ b/src/Fenom/Render.php @@ -26,9 +26,9 @@ class Render extends \ArrayObject "macros" => [] ]; /** - * @var \Closure + * @var \Closure|null */ - protected \Closure $_code; + protected ?\Closure $_code = null; /** * Template name * @var string @@ -38,7 +38,7 @@ class Render extends \ArrayObject * Provider's schema * @var string|null */ - protected ?string $_scm; + protected ?string $_scm = null; /** * Basic template name * @var string diff --git a/src/Fenom/Template.php b/src/Fenom/Template.php index 714773d..99885c3 100644 --- a/src/Fenom/Template.php +++ b/src/Fenom/Template.php @@ -52,77 +52,87 @@ class Template extends Render /** * @var int shared counter */ - public $i = 1; + public int $i = 1; /** * @var array of macros */ - public $macros = array(); + public array $macros = []; /** * @var array of blocks */ - public $blocks = array(); + public array $blocks = []; /** * @var string|null */ - public $extends; + public ?string $extends; /** * @var string|null */ - public $extended; + public ?string $extended; /** * Stack of extended templates * @var array */ - public $ext_stack = array(); + public array $ext_stack = []; - public $extend_body = false; + public bool $extend_body = false; /** * Parent template * @var Template */ - public $parent; + public ?Template $parent; /** * Template PHP code * @var string */ - private $_body; - private $_compile_stage = 0; + private string $_body = ""; + private int $_compile_stage = 0; /** * Call stack * @var Tag[] */ - private $_stack = array(); + private array $_stack = []; /** * Template source * @var string */ - private $_src; + private string $_src; /** * @var int */ - private $_line = 1; - private $_post = array(); + private int $_line = 1; /** - * @var bool|string + * @var callable[] */ - private $_ignore = false; + private array $_post = []; + /** + * @var string|null + */ + private ?string $_ignore = null; - private $_before = array(); + /** + * @var string[] + */ + private array $_before = []; - private $_filters = array(); + private array $_filters = []; /** * @var int crc32 of the template name */ - private $_crc = 0; + private int $_crc = 0; + /** + * @var callable[] + */ + private array $_tag_filters; /** * @param Fenom $fenom Template storage @@ -142,16 +152,16 @@ class Template extends Render * Get tag stack size * @return int */ - public function getStackSize() + public function getStackSize(): int { return count($this->_stack); } /** * @param string $tag - * @return bool|\Fenom\Tag + * @return Tag|null */ - public function getParentScope($tag) + public function getParentScope(string $tag): ?Tag { for ($i = count($this->_stack) - 1; $i >= 0; $i--) { if ($this->_stack[$i]->name == $tag) { @@ -159,7 +169,7 @@ class Template extends Render } } - return false; + return null; } /** @@ -167,8 +177,9 @@ class Template extends Render * @param string $name * @param bool $compile * @return self + * @throws CompileException */ - public function load($name, $compile = true) + public function load(string $name, bool $compile = true): static { $this->_name = $name; $this->_crc = crc32($this->_name); @@ -193,8 +204,9 @@ class Template extends Render * @param string $src template source * @param bool $compile * @return \Fenom\Template + * @throws CompileException */ - public function source($name, $src, $compile = true) + public function source(string $name, string $src, bool $compile = true): static { $this->_name = $name; $this->_src = $src; @@ -309,7 +321,8 @@ class Template extends Render $this->_compile_stage = self::COMPILE_STAGE_POST_FILTERED; } - public function isStageDone($stage_no) { + public function isStageDone(int $stage_no): bool + { return $this->_compile_stage >= $stage_no; } @@ -318,7 +331,7 @@ class Template extends Render * @param int $option * @param bool $value */ - public function setOption($option, $value) + public function setOption(int $option, bool $value) { if ($value) { $this->_options |= $option; @@ -329,21 +342,21 @@ class Template extends Render /** * Execute some code at loading cache - * @param $code + * @param string $code * @return void */ - public function before($code) + public function before(string $code): void { $this->_before[] = $code; } /** - * Generate name of temporary internal template variable (may be random) + * Generate name of temporary internal template variable (maybe random) * @return string */ - public function tmpVar() + public function tmpVar(): string { - return sprintf('$t%x_%x', $this->_crc ? $this->_crc : mt_rand(0, 0x7FFFFFFF), $this->i++); + return sprintf('$t%x_%x', $this->_crc ?: mt_rand(0, 0x7FFFFFFF), $this->i++); } /** @@ -351,12 +364,12 @@ class Template extends Render * * @param string $text */ - private function _appendText($text) + private function _appendText(string $text) { $this->_line += substr_count($text, "\n"); $strip = $this->_options & Fenom::AUTO_STRIP; if ($this->_filters) { - if (strpos($text, "_filters as $filter) { $text = call_user_func($filter, $this, $text); } @@ -385,9 +398,9 @@ class Template extends Render * Append PHP code to template body * * @param string $code - * @param $source + * @param string $source */ - private function _appendCode($code, $source) + private function _appendCode(string $code, string $source) { if (!$code) { return; @@ -398,17 +411,17 @@ class Template extends Render } /** - * @param $tag_name + * @param string $tag_name */ - public function ignore($tag_name) + public function ignore(string $tag_name) { $this->_ignore = $tag_name; } /** - * @param callable[] $cb + * @param callable $cb */ - public function addPostCompile($cb) + public function addPostCompile(callable $cb) { $this->_post[] = $cb; } @@ -418,7 +431,7 @@ class Template extends Render * * @return string */ - public function getBody() + public function getBody(): string { return $this->_body; } @@ -428,7 +441,7 @@ class Template extends Render * * @return string */ - public function getTemplateCode() + public function getTemplateCode(): string { $before = $this->_before ? implode("\n", $this->_before) . "\n" : ""; return "macros) { $macros = array(); @@ -468,7 +481,7 @@ class Template extends Render * Return closure code * @return string */ - private function _getClosureSource() + private function _getClosureSource(): string { return "function (\$var, \$tpl) {\n?>{$this->_body}_code) { + if (!$this->_code) { // TODO: remove // evaluate template's code eval("\$this->_code = " . $this->_getClosureSource() . ";\n\$this->_macros = " . $this->_getMacrosArray() . ';'); if (!$this->_code) { @@ -506,10 +519,10 @@ class Template extends Render * Output the value * * @param string $data - * @param null|bool $escape + * @param bool|null $escape * @return string */ - public function out($data, $escape = null) + public function out(string $data, ?bool $escape = null): string { if ($escape === null) { $escape = $this->_options & Fenom::AUTO_ESCAPE; @@ -524,8 +537,9 @@ class Template extends Render /** * Import block from another template * @param string $tpl + * @throws CompileException */ - public function importBlocks($tpl) + public function importBlocks(string $tpl) { $donor = $this->_fenom->compile($tpl, false); foreach ($donor->blocks as $name => $block) { @@ -541,8 +555,9 @@ class Template extends Render * Extends the template * @param string $tpl * @return \Fenom\Template parent + * @throws CompileException */ - public function extend($tpl) + public function extend(string $tpl): Template { if (!$this->isStageDone(self::COMPILE_STAGE_PARSED)) { $this->compile(); @@ -573,7 +588,7 @@ class Template extends Render * @throws CompileException * @return string executable PHP code */ - public function parseTag(Tokenizer $tokens) + public function parseTag(Tokenizer $tokens): string { try { if ($tokens->is(Tokenizer::MACRO_STRING)) { @@ -601,7 +616,7 @@ class Template extends Render * @return string * @throws TokenizeException */ - public function parseEndTag(Tokenizer $tokens) + public function parseEndTag(Tokenizer $tokens): string { $name = $tokens->getNext(Tokenizer::MACRO_STRING); $tokens->next(); @@ -626,12 +641,12 @@ class Template extends Render * @throws Error\TokenizeException * @return string */ - public function parseAct(Tokenizer $tokens) + public function parseAct(Tokenizer $tokens): string { $action = $tokens->get(Tokenizer::MACRO_STRING); $tokens->next(); - if ($tokens->is("(", T_DOUBLE_COLON, T_NS_SEPARATOR) && !$tokens->isWhiteSpaced() - ) { // just invoke function or static method + if ($tokens->is("(", T_DOUBLE_COLON, T_NS_SEPARATOR) && !$tokens->isWhiteSpaced()) { + // just invoke function or static method $tokens->back(); return $this->out($this->parseExpr($tokens)); } elseif ($tokens->is('.')) { @@ -652,7 +667,7 @@ class Template extends Render if ($tag->isClosed()) { $tag->restoreAll(); } else { - array_push($this->_stack, $tag); + $this->_stack[] = $tag; } return $code; } @@ -678,7 +693,7 @@ class Template extends Render * Get current template line * @return int */ - public function getLine() + public function getLine(): int { return $this->_line; } @@ -688,10 +703,9 @@ class Template extends Render * * @param Tokenizer $tokens * @param bool $is_var - * @throws \Exception * @return string */ - public function parseExpr(Tokenizer $tokens, &$is_var = false) + public function parseExpr(Tokenizer $tokens, bool &$is_var = false): string { $exp = array(); $var = false; // last term was: true - variable, false - mixed @@ -801,10 +815,9 @@ class Template extends Render * @param Tokenizer $tokens * @param bool $is_var is parsed term - plain variable * @param int $allows - * @throws \Exception - * @return bool|string + * @return string */ - public function parseTerm(Tokenizer $tokens, &$is_var = false, $allows = -1) + public function parseTerm(Tokenizer $tokens, ?bool &$is_var = false, int $allows = -1): string { $is_var = false; if ($tokens->is(Tokenizer::MACRO_UNARY)) { @@ -941,7 +954,7 @@ class Template extends Render * @param string $code start point (it is $var) * @return string */ - public function parseChain(Tokenizer $tokens, $code) + public function parseChain(Tokenizer $tokens, string $code): string { do { if ($tokens->is('(')) { @@ -962,11 +975,11 @@ class Template extends Render /** * Parse variable name: $a, $a.b, $a.b['c'], $a:index * @param Tokenizer $tokens - * @param $var - * @return string - * @throws Error\UnexpectedTokenException + * @param string|null $var + * @return string|null + * @throws CompileException */ - public function parseVariable(Tokenizer $tokens, $var = null) + public function parseVariable(Tokenizer $tokens, ?string $var = null): ?string { if (!$var) { if ($tokens->isNext('@')) { @@ -1037,7 +1050,7 @@ class Template extends Render * @param bool $is_var * @return string */ - public function parseAccessor(Tokenizer $tokens, &$is_var = false) + public function parseAccessor(Tokenizer $tokens, bool &$is_var = false): string { $accessor = $tokens->need('$')->next()->need('.')->next()->current(); $parser = $this->getStorage()->getAccessor($accessor); @@ -1050,16 +1063,16 @@ class Template extends Render ', "callback"), ' . var_export($accessor, true) . ', $tpl, $var)'; } else { return call_user_func_array( - $parser['parser'], array( - $parser['accessor'], - $tokens->next(), - $this, - &$is_var - ) + $parser['parser'], [ + $parser['accessor'], + $tokens->next(), + $this, + &$is_var + ] ); } } else { - return call_user_func_array($parser, array($tokens->next(), $this, &$is_var)); + return call_user_func_array($parser, [$tokens->next(), $this, &$is_var]); } } else { throw new \RuntimeException("Unknown accessor '\$.$accessor'"); @@ -1075,7 +1088,7 @@ class Template extends Render * @return string * @throws UnexpectedTokenException */ - public function parseTernary(Tokenizer $tokens, $var, $is_var) + public function parseTernary(Tokenizer $tokens, $var, $is_var): string { $empty = $tokens->is('?'); $tokens->next(); @@ -1094,12 +1107,7 @@ class Template extends Render 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 ($is_var) { return '!empty(' . $var . ')'; @@ -1135,14 +1143,14 @@ class Template extends Render /** * Parse 'is' and 'is not' operators - * @see _tests * @param Tokenizer $tokens * @param string $value * @param bool $variable - * @throws InvalidUsageException * @return string + * @throws InvalidUsageException + * @see _tests */ - public function parseIs(Tokenizer $tokens, $value, $variable = false) + public function parseIs(Tokenizer $tokens, string $value, bool $variable = false): string { $tokens->next(); if ($tokens->current() == 'not') { @@ -1180,11 +1188,11 @@ class Template extends Render * Parse 'in' and 'not in' operators * @param Tokenizer $tokens * @param string $value - * @throws InvalidUsageException - * @throws UnexpectedTokenException * @return string + * @throws UnexpectedTokenException + * @throws InvalidUsageException */ - public function parseIn(Tokenizer $tokens, $value) + public function parseIn(Tokenizer $tokens, string $value): string { $checkers = array( "string" => 'is_int(strpos(%2$s, %1$s))', @@ -1239,7 +1247,7 @@ class Template extends Render * @param Tokenizer $tokens * @return string */ - public function parseName(Tokenizer $tokens) + public function parseName(Tokenizer $tokens): string { $tokens->skipIf(T_NS_SEPARATOR); $name = ""; @@ -1260,7 +1268,7 @@ class Template extends Render * @throws Error\UnexpectedTokenException * @return string */ - public function parseScalar(Tokenizer $tokens) + public function parseScalar(Tokenizer $tokens): string { $token = $tokens->key(); switch ($token) { @@ -1284,7 +1292,7 @@ class Template extends Render * @throws UnexpectedTokenException * @return string */ - public function parseQuote(Tokenizer $tokens) + public function parseQuote(Tokenizer $tokens): string { if ($tokens->is('"')) { $stop = $tokens->current(); @@ -1352,7 +1360,7 @@ class Template extends Render * @throws \Exception * @return string */ - public function parseModifier(Tokenizer $tokens, $value) + public function parseModifier(Tokenizer $tokens, $value): string { while ($tokens->is("|")) { $modifier = $tokens->getNext(Tokenizer::MACRO_STRING); @@ -1392,11 +1400,11 @@ class Template extends Render * [1, 2.3, 5+7/$var, 'string', "str {$var+3} ing", $var2, []] * * @param Tokenizer $tokens - * @param int $count amount of elements - * @throws Error\UnexpectedTokenException + * @param int $count number of elements * @return string + * @throws Error\UnexpectedTokenException */ - public function parseArray(Tokenizer $tokens, &$count = 0) + public function parseArray(Tokenizer $tokens, int &$count = 0): string { if ($tokens->is("[")) { $arr = array(); @@ -1433,7 +1441,7 @@ class Template extends Render * @return string * @throws InvalidUsageException */ - public function parseMacroCall(Tokenizer $tokens, $name) + public function parseMacroCall(Tokenizer $tokens, $name): string { $recursive = false; $macro = false; @@ -1481,9 +1489,9 @@ class Template extends Render * @param Tokenizer $tokens * @throws \LogicException * @throws \RuntimeException - * @return string + * @return callable */ - public function parseStatic(Tokenizer $tokens) + public function parseStatic(Tokenizer $tokens): callable { if ($this->_options & Fenom::DENY_STATICS) { throw new \LogicException("Static methods are disabled"); @@ -1512,7 +1520,7 @@ class Template extends Render * @param Tokenizer $tokens * @return string */ - public function parseArgs(Tokenizer $tokens) + public function parseArgs(Tokenizer $tokens): string { $_args = "("; $tokens->next(); @@ -1558,7 +1566,7 @@ class Template extends Render * @param string $static * @return mixed|string */ - public function parsePlainArg(Tokenizer $tokens, &$static) + public function parsePlainArg(Tokenizer $tokens, string &$static): mixed { if ($tokens->is(T_CONSTANT_ENCAPSED_STRING)) { if ($tokens->isNext('|')) { @@ -1578,10 +1586,8 @@ class Template extends Render * Parse parameters as $key=$value * param1=$var param2=3 ... * - * @static * @param Tokenizer $tokens - * @param array $defaults - * @throws \Exception + * @param array|null $defaults * @return array */ public function parseParams(Tokenizer $tokens, array $defaults = null) diff --git a/src/Fenom/Tokenizer.php b/src/Fenom/Tokenizer.php index 834dcdf..a073ed4 100644 --- a/src/Fenom/Tokenizer.php +++ b/src/Fenom/Tokenizer.php @@ -92,6 +92,7 @@ class Tokenizer \T_INCLUDE => 1, \T_INCLUDE_ONCE => 1, \T_INSTANCEOF => 1, \T_INSTEADOF => 1, \T_INTERFACE => 1, \T_ISSET => 1, \T_LINE => 1, \T_LIST => 1, \T_LOGICAL_AND => 1, \T_LOGICAL_OR => 1, \T_LOGICAL_XOR => 1, \T_METHOD_C => 1, + \T_MATCH => 1, \T_NAMESPACE => 1, \T_NS_C => 1, \T_NEW => 1, \T_PRINT => 1, \T_PRIVATE => 1, \T_PUBLIC => 1, \T_PROTECTED => 1, \T_REQUIRE => 1, \T_REQUIRE_ONCE => 1, \T_RETURN => 1, \T_STRING => 1,