migrate to php8

This commit is contained in:
ivan shalganov 2023-02-06 23:49:54 +01:00
parent 4cdfd306d9
commit ba1bc18aba
9 changed files with 180 additions and 172 deletions

3
.gitignore vendored
View File

@ -5,4 +5,5 @@ composer.phar
tests/resources/compile/*
!.gitkeep
tests/resources/template/*
sandbox/compiled/*
sandbox/compiled/*
/.phpunit.result.cache

View File

@ -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

View File

@ -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;
}
/**

View File

@ -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);

View File

@ -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) . ') {';

View File

@ -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 {

View File

@ -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

View File

@ -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, "<?") === false) {
if (!str_contains($text, "<?")) {
foreach ($this->_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 "<?php \n" .
@ -449,7 +462,7 @@ class Template extends Render
* Make array with macros code
* @return string
*/
private function _getMacrosArray()
private function _getMacrosArray(): string
{
if ($this->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}<?php\n}";
}
@ -478,11 +491,11 @@ class Template extends Render
*
* @param array $values input values
* @throws CompileException
* @return Render
* @return array
*/
public function display(array $values)
public function display(array $values): array
{
if (!$this->_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)

View File

@ -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,