diff --git a/src/Handlebars/Context.php b/src/Handlebars/Context.php index 091e84f..3504cbc 100755 --- a/src/Handlebars/Context.php +++ b/src/Handlebars/Context.php @@ -30,38 +30,38 @@ class Context /** * @var array stack for context only top stack is available */ - protected $stack = []; + protected array $stack = []; /** * @var array index stack for sections */ - protected $index = []; + protected array $index = []; /** * @var array dataStack stack for data within sections */ - protected $dataStack = []; + protected array $dataStack = []; /** * @var array key stack for objects */ - protected $key = []; + protected array $key = []; /** * @var bool enableDataVariables true if @data variables should be used. */ - protected $enableDataVariables = false; + protected bool $enableDataVariables = false; /** * Mustache rendering Context constructor. * * @param mixed $context Default rendering context (default: null) * @param array $options Options for the context. It may contain the following: (default: empty array) - * enableDataVariables => Boolean, Enables @data variables (default: false) + * enableDataVariables => bool, Enables @data variables (default: false) * * @throws InvalidArgumentException when calling this method when enableDataVariables is not a boolean. */ - public function __construct($context = null, $options = []) + public function __construct($context = null, array $options = []) { if ($context !== null) { $this->stack = [$context]; @@ -81,24 +81,18 @@ public function __construct($context = null, $options = []) * Push a new Context frame onto the stack. * * @param mixed $value Object or array to use for context - * - * @return void */ - public function push($value) + public function push($value): void { - array_push($this->stack, $value); + $this->stack[] = $value; } /** * Push an Index onto the index stack - * - * @param integer $index Index of the current section item. - * - * @return void */ - public function pushIndex($index) + public function pushIndex(int $index): void { - array_push($this->index, $index); + $this->index[] = $index; } /** @@ -106,24 +100,20 @@ public function pushIndex($index) * @param array $data Associative array where key is the name of the @data variable and value is the value. * @throws LogicException when calling this method without having enableDataVariables. */ - public function pushData($data) + public function pushData(array $data): void { if (!$this->enableDataVariables) { throw new LogicException('Data variables are not supported due to the enableDataVariables configuration. Remove the call to data variables or change the setting.'); } - array_push($this->dataStack, $data); + $this->dataStack[] = $data; } /** * Push a Key onto the key stack - * - * @param string $key Key of the current object property. - * - * @return void */ - public function pushKey($key) + public function pushKey(string $key): void { - array_push($this->key, $key); + $this->key[] = $key; } /** @@ -138,21 +128,17 @@ public function pop() /** * Pop the last index from the stack. - * - * @return int Last index */ - public function popIndex() + public function popIndex(): int { return array_pop($this->index); } /** * Pop the last section data from the stack. - * - * @return array Last data * @throws LogicException when calling this method without having enableDataVariables. */ - public function popData() + public function popData(): array { if (!$this->enableDataVariables) { throw new LogicException('Data variables are not supported due to the enableDataVariables configuration. Remove the call to data variables or change the setting.'); @@ -162,10 +148,8 @@ public function popData() /** * Pop the last key from the stack. - * - * @return string Last key */ - public function popKey() + public function popKey(): string { return array_pop($this->key); } @@ -182,20 +166,16 @@ public function last() /** * Get the index of current section item. - * - * @return mixed Last index */ - public function lastIndex() + public function lastIndex(): int { return end($this->index); } /** * Get the key of current object property. - * - * @return mixed Last key */ - public function lastKey() + public function lastKey(): string { return end($this->key); } @@ -207,7 +187,7 @@ public function lastKey() * * @return mixed actual value */ - public function with($variableName) + public function with(string $variableName) { $value = $this->get($variableName); $this->push($value); @@ -216,17 +196,17 @@ public function with($variableName) } /** - * Get a avariable from current context + * Get a variable from current context * Supported types : * variable , ../variable , variable.variable , . * - * @param string $variableName variavle name to get from current context + * @param string $variableName variable name to get from current context * @param boolean $strict strict search? if not found then throw exception * * @throws InvalidArgumentException in strict mode and variable not found * @return mixed */ - public function get($variableName, $strict = false) + public function get(string $variableName, bool $strict = false) { //Need to clean up $variableName = trim($variableName); @@ -279,13 +259,10 @@ public function get($variableName, $strict = false) /** * Given a data variable, retrieves the value associated. - * - * @param $variableName - * @param bool $strict * @return mixed * @throws LogicException when calling this method without having enableDataVariables. */ - public function getDataVariable($variableName, $strict = false) + public function getDataVariable(string $variableName, bool $strict = false) { if (!$this->enableDataVariables) { throw new LogicException('Data variables are not supported due to the enableDataVariables configuration. Remove the call to data variables or change the setting.'); @@ -351,13 +328,13 @@ public function getDataVariable($variableName, $strict = false) * Check if $variable->$inside is available * * @param mixed $variable variable to check - * @param string $inside property/method to check + * @param string $inside property/method to check * @param boolean $strict strict search? if not found then throw exception * - * @throws \InvalidArgumentException in strict mode and variable not found - * @return boolean true if exist + * @return mixed + *@throws \InvalidArgumentException in strict mode and variable not found */ - private function findVariableInContext($variable, $inside, $strict = false) + private function findVariableInContext($variable, string $inside, bool $strict = false) { $value = ''; if (($inside !== '0' && empty($inside)) || ($inside == 'this')) { diff --git a/src/Handlebars/Handlebars.php b/src/Handlebars/Handlebars.php index b07bd6b..a112b4c 100755 --- a/src/Handlebars/Handlebars.php +++ b/src/Handlebars/Handlebars.php @@ -15,11 +15,11 @@ */ namespace Handlebars; + use Handlebars\Loader\StringLoader; use Handlebars\Cache\Dummy; use InvalidArgumentException; - class Handlebars { private static $instance = null; @@ -31,10 +31,8 @@ class Handlebars * factory method * * @param array $options see __construct's options parameter - * - * @return Handlebars */ - public static function factory($options = array()) + public static function factory(array $options = []): Handlebars { if (! self::$instance) { self::$instance = new self($options); @@ -43,35 +41,17 @@ public static function factory($options = array()) return self::$instance; } - /** - * @var Tokenizer - */ - private $tokenizer; + private Tokenizer $tokenizer; - /** - * @var Parser - */ - private $parser; + private Parser $parser; - /** - * @var Helpers - */ - private $helpers; + private Helpers $helpers; - /** - * @var Loader - */ - private $loader; + private Loader $loader; - /** - * @var Loader - */ - private $partialsLoader; + private Loader $partialsLoader; - /** - * @var Cache - */ - private $cache; + private Cache $cache; /** * @var callable escape function to use @@ -79,19 +59,16 @@ public static function factory($options = array()) private $escape = 'htmlspecialchars'; /** - * @var array parametes to pass to escape function + * @var array parameters to pass to escape function */ - private $escapeArgs = array( - ENT_COMPAT, - 'UTF-8' - ); + private array $escapeArgs = [ENT_COMPAT, 'UTF-8']; - private $aliases = array(); + private array $aliases = []; /** * @var bool Enable @data variables */ - private $enableDataVariables = false; + private bool $enableDataVariables = false; /** * Handlebars engine constructor @@ -158,18 +135,14 @@ public function __construct(Array $options = []) } } - - /** * Shortcut 'render' invocation. * * Equivalent to calling `$handlebars->loadTemplate($template)->render($data);` * - * @param string $template template name * @param mixed $data data to use as context - * @return string Rendered template */ - public function render($template, $data) + public function render(string $template, $data): string { return $this->loadTemplate($template)->render($data); } @@ -178,31 +151,24 @@ public function render($template, $data) * * @param string $template template name * @param mixed $data data to use as context - * @return string Rendered template */ - public function __invoke($template, $data) + public function __invoke(string $template, $data): string { return $this->render($template, $data); } /** - * Set helpers for current enfine - * - * @param Helpers $helpers handlebars helper - * - * @return void + * Set helpers for current engine */ - public function setHelpers(Helpers $helpers) + public function setHelpers(Helpers $helpers): void { $this->helpers = $helpers; } /** - * Get helpers, or create new one if ther is no helper - * - * @return Helpers + * Get helpers, or create new one if there is no helper */ - public function getHelpers() + public function getHelpers(): Helpers { if (!isset($this->helpers)) { $this->helpers = new Helpers(); @@ -212,67 +178,48 @@ public function getHelpers() /** * Add a new helper. - * - * @param string $name helper name - * @param mixed $helper helper callable - * - * @return void */ - public function addHelper($name, $helper) + public function addHelper(string $name, callable $helper): void { $this->getHelpers()->add($name, $helper); } /** * Get a helper by name. - * - * @param string $name helper name - * @return callable Helper */ - public function getHelper($name) + public function getHelper(string $name): callable { return $this->getHelpers()->__get($name); } /** * Check whether this instance has a helper. - * - * @param string $name helper name - * @return boolean True if the helper is present */ - public function hasHelper($name) + public function hasHelper(string $name): bool { return $this->getHelpers()->has($name); } /** * Remove a helper by name. - * - * @param string $name helper name - * @return void */ - public function removeHelper($name) + public function removeHelper(string $name): void { $this->getHelpers()->remove($name); } /** * Set current loader - * - * @param Loader $loader handlebars loader - * @return void */ - public function setLoader(Loader $loader) + public function setLoader(Loader $loader): void { $this->loader = $loader; } /** - * get current loader - * - * @return Loader + * Get current loader */ - public function getLoader() + public function getLoader(): Loader { if (! isset($this->loader)) { $this->loader = new StringLoader(); @@ -282,21 +229,16 @@ public function getLoader() /** * Set current partials loader - * - * @param Loader $loader handlebars loader - * @return void */ - public function setPartialsLoader(Loader $loader) + public function setPartialsLoader(Loader $loader): void { $this->partialsLoader = $loader; } /** - * get current partials loader - * - * @return Loader + * Get current partials loader */ - public function getPartialsLoader() + public function getPartialsLoader(): Loader { if (!isset($this->partialsLoader)) { $this->partialsLoader = new StringLoader(); @@ -305,22 +247,17 @@ public function getPartialsLoader() } /** - * Set cache for current engine - * - * @param Cache $cache handlebars cache - * @return void + * Set cache for current engine */ - public function setCache(Cache $cache) + public function setCache(Cache $cache): void { $this->cache = $cache; } /** * Get cache - * - * @return Cache */ - public function getCache() + public function getCache(): Cache { if (!isset($this->cache)) { $this->cache = new Dummy(); @@ -330,22 +267,17 @@ public function getCache() /** * Get current escape function - * - * @return callable */ - public function getEscape() + public function getEscape(): callable { return $this->escape; } /** * Set current escape function - * - * @param callable $escape function * @throws \InvalidArgumentException - * @return void */ - public function setEscape($escape) + public function setEscape(callable $escape): void { if (!is_callable($escape)) { throw new InvalidArgumentException( @@ -357,10 +289,8 @@ public function setEscape($escape) /** * Get current escape function - * - * @return array */ - public function getEscapeArgs() + public function getEscapeArgs(): array { return $this->escapeArgs; } @@ -369,24 +299,16 @@ public function getEscapeArgs() * Set current escape function * * @param array $escapeArgs arguments to pass as extra arg to function - * @return void */ - public function setEscapeArgs($escapeArgs) + public function setEscapeArgs(array $escapeArgs): void { - if (! is_array($escapeArgs)) { - $escapeArgs = array($escapeArgs); - } $this->escapeArgs = $escapeArgs; } - /** * Set the Handlebars Tokenizer instance. - * - * @param Tokenizer $tokenizer tokenizer - * @return void */ - public function setTokenizer(Tokenizer $tokenizer) + public function setTokenizer(Tokenizer $tokenizer): void { $this->tokenizer = $tokenizer; } @@ -396,12 +318,10 @@ public function setTokenizer(Tokenizer $tokenizer) * * If no Tokenizer instance has been explicitly specified, this method will * instantiate and return a new one. - * - * @return Tokenizer */ - public function getTokenizer() + public function getTokenizer(): Tokenizer { - if (! isset($this->tokenizer)) { + if (!isset($this->tokenizer)) { $this->tokenizer = new Tokenizer(); } @@ -410,11 +330,8 @@ public function getTokenizer() /** * Set the Handlebars Parser instance. - * - * @param Parser $parser parser object - * @return void */ - public function setParser(Parser $parser) + public function setParser(Parser $parser): void { $this->parser = $parser; } @@ -424,12 +341,10 @@ public function setParser(Parser $parser) * * If no Parser instance has been explicitly specified, this method will * instantiate and return a new one. - * - * @return Parser */ - public function getParser() + public function getParser(): Parser { - if (! isset($this->parser)) { + if (!isset($this->parser)) { $this->parser = new Parser(); } return $this->parser; @@ -437,21 +352,16 @@ public function getParser() /** * Determines if the @data variables are enabled. - * @return bool */ - public function isDataVariablesEnabled() + public function isDataVariablesEnabled(): bool { return $this->enableDataVariables; } /** * Load a template by name with current template loader - * - * @param string $name template name - * - * @return Template */ - public function loadTemplate($name) + public function loadTemplate(string $name): Template { $source = $this->getLoader()->load($name); $tree = $this->tokenize($source); @@ -460,12 +370,8 @@ public function loadTemplate($name) /** * Load a partial by name with current partial loader - * - * @param string $name partial name - * - * @return Template */ - public function loadPartial($name) + public function loadPartial(string $name): Template { if (isset($this->aliases[$name])) { $name = $this->aliases[$name]; @@ -477,23 +383,16 @@ public function loadPartial($name) /** * Register partial alias - * - * @param string $alias Partial alias - * @param string $content The real value - * @return void */ - public function registerPartial($alias, $content) + public function registerPartial(string $alias, string $content): void { $this->aliases[$alias] = $content; } /** * Un-register partial alias - * - * @param string $alias Partial alias - * @return void */ - public function unRegisterPartial($alias) + public function unRegisterPartial(string $alias): void { if (isset($this->aliases[$alias])) { unset($this->aliases[$alias]); @@ -502,23 +401,17 @@ public function unRegisterPartial($alias) /** * Load string into a template object - * - * @param string $source string to load - * @return Template */ - public function loadString($source) + public function loadString(string $source): Template { $tree = $this->tokenize($source); return new Template($this, $tree, $source); } /** - * try to tokenize source, or get them from cache if available - * - * @param string $source handlebars source code - * @return array handlebars parsed data into array + * Try to tokenize source, or get them from cache if available */ - private function tokenize($source) + private function tokenize(string $source): array { $hash = md5(sprintf('version: %s, data : %s', self::VERSION, $source)); $tree = $this->getCache()->get($hash); @@ -529,5 +422,4 @@ private function tokenize($source) } return $tree; } - -} \ No newline at end of file +} diff --git a/src/Handlebars/Helpers.php b/src/Handlebars/Helpers.php index ed97ec4..19cbe6e 100755 --- a/src/Handlebars/Helpers.php +++ b/src/Handlebars/Helpers.php @@ -30,9 +30,9 @@ class Helpers /** * @var array array of helpers */ - protected $helpers = []; - private $tpl = []; - protected $builtinHelpers = [ + protected array $helpers = []; + private array $tpl = []; + protected array $builtinHelpers = [ "if", "each", "with", @@ -49,30 +49,24 @@ class Helpers "truncate", // Truncate section "raw", // Return the source as is without converting "repeat", // Repeat a section - "define", // Define a block to be used using "invoke" + "define", // Define a block to be used with "invoke" "invoke", // Invoke a block that was defined with "define" ]; /** * Create new helper container class * - * @param array $helpers array of name=>$value helpers * @throws \InvalidArgumentException when $helpers is not an array * (or traversable) or helper is not a callable */ - public function __construct($helpers = null) + public function __construct(?array $helpers = null) { foreach($this->builtinHelpers as $helper) { $helperName = $this->underscoreToCamelCase($helper); $this->add($helper, [$this, "helper{$helperName}"]); } - if ($helpers != null) { - if (!is_array($helpers) && !$helpers instanceof Traversable) { - throw new InvalidArgumentException( - 'HelperCollection constructor expects an array of helpers' - ); - } + if ($helpers !== null) { foreach ($helpers as $name => $helper) { $this->add($name, $helper); } @@ -81,42 +75,25 @@ public function __construct($helpers = null) /** * Add a new helper to helpers - * - * @param string $name helper name - * @param callable $helper a function as a helper - * - * @throws \InvalidArgumentException if $helper is not a callable - * @return void */ - public function add($name, $helper) + public function add(string $name, callable $helper): void { - if (!is_callable($helper)) { - throw new InvalidArgumentException("$name Helper is not a callable."); - } $this->helpers[$name] = $helper; } /** * Check if $name helper is available - * - * @param string $name helper name - * - * @return boolean */ - public function has($name) + public function has(string $name): bool { return array_key_exists($name, $this->helpers); } /** * Get a helper. __magic__ method :) - * - * @param string $name helper name - * * @throws \InvalidArgumentException if $name is not available - * @return callable helper function */ - public function __get($name) + public function __get(string $name): callable { if (!$this->has($name)) { throw new InvalidArgumentException('Unknown helper :' . $name); @@ -126,50 +103,34 @@ public function __get($name) /** * Check if $name helper is available __magic__ method :) - * - * @param string $name helper name - * - * @return boolean * @see Handlebras_Helpers::has */ - public function __isset($name) + public function __isset(string $name) { return $this->has($name); } /** * Add a new helper to helpers __magic__ method :) - * - * @param string $name helper name - * @param callable $helper a function as a helper - * - * @return void */ - public function __set($name, $helper) + public function __set(string $name, callable $helper): void { $this->add($name, $helper); } - /** * Unset a helper - * - * @param string $name helper name to remove - * @return void */ - public function __unset($name) + public function __unset(string $name): void { unset($this->helpers[$name]); } /** * Check whether a given helper is present in the collection. - * - * @param string $name helper name * @throws \InvalidArgumentException if the requested helper is not present. - * @return void */ - public function remove($name) + public function remove(string $name): void { if (!$this->has($name)) { throw new InvalidArgumentException('Unknown helper: ' . $name); @@ -178,23 +139,17 @@ public function remove($name) } /** - * Clear the helper collection. - * - * Removes all helpers from this collection - * - * @return void + * Clear the helper collection. Removes all helpers from this collection. */ - public function clear() + public function clear(): void { $this->helpers = []; } /** * Check whether the helper collection is empty. - * - * @return boolean True if the collection is empty */ - public function isEmpty() + public function isEmpty(): bool { return empty($this->helpers); } @@ -212,15 +167,9 @@ public function isEmpty() * something else here * {{/if}} * - * @param \Handlebars\Template $template template that is being rendered - * @param \Handlebars\Context $context context object - * @param array $args passed arguments to helper - * @param string $source part of template that is wrapped - * within helper - * - * @return mixed + * @return string */ - public function helperIf($template, $context, $args, $source) + public function helperIf(Template $template, Context $context, string $args, string $source) { $tpl = $template->getEngine()->loadString('{{#if ' . $args . '}}' . $source . '{{/if}}'); $tree = $tpl->getTree(); @@ -273,7 +222,6 @@ public function helperIf($template, $context, $args, $source) } } - /** * Create handler for the 'each' helper. * example {{#each people}} {{name}} {{/each}} @@ -284,18 +232,10 @@ public function helperIf($template, $context, $args, $source) * {{else}} * Nothing found * {{/each}} - * - * @param \Handlebars\Template $template template that is being rendered - * @param \Handlebars\Context $context context object - * @param array $args passed arguments to helper - * @param string $source part of template that is wrapped - * within helper - * - * @return mixed */ - public function helperEach($template, $context, $args, $source) + public function helperEach(Template $template, Context $context, string $args, string $source): string { - list($keyname, $slice_start, $slice_end) = $this->extractSlice($args); + [$keyname, $slice_start, $slice_end] = $this->extractSlice($args); $tmp = $context->get($keyname); if (is_array($tmp) || $tmp instanceof Traversable) { @@ -360,11 +300,8 @@ public function helperEach($template, $context, $args, $source) /** * Applying the DRY principle here. * This method help us render {{else}} portion of a block - * @param \Handlebars\Template $template - * @param \Handlebars\Context $context - * @return string */ - private function renderElse($template, $context) + private function renderElse(Template $template, Context $context): string { $template->setStopToken('else'); $template->discard(); @@ -372,7 +309,6 @@ private function renderElse($template, $context) return $template->render($context); } - /** * Create handler for the 'unless' helper. * {{#unless condition}} @@ -380,15 +316,8 @@ private function renderElse($template, $context) * {{else}} * something else here * {{/unless}} - * @param \Handlebars\Template $template template that is being rendered - * @param \Handlebars\Context $context context object - * @param array $args passed arguments to helper - * @param string $source part of template that is wrapped - * within helper - * - * @return mixed */ - public function helperUnless($template, $context, $args, $source) + public function helperUnless(Template $template, Context $context, string $args, string $source): string { $tmp = $context->get($args); if (!$tmp) { @@ -404,18 +333,8 @@ public function helperUnless($template, $context, $args, $source) /** * Create handler for the 'with' helper. - * Needed for compatibility with PHP 5.2 since it doesn't support anonymous - * functions. - * - * @param \Handlebars\Template $template template that is being rendered - * @param \Handlebars\Context $context context object - * @param array $args passed arguments to helper - * @param string $source part of template that is wrapped - * within helper - * - * @return mixed */ - public function helperWith($template, $context, $args, $source) + public function helperWith(Template $template, Context $context, string $args, string $source): string { $tmp = $context->get($args); $context->push($tmp); @@ -429,16 +348,8 @@ public function helperWith($template, $context, $args, $source) * Create handler for the 'bindAttr' helper. * Needed for compatibility with PHP 5.2 since it doesn't support anonymous * functions. - * - * @param \Handlebars\Template $template template that is being rendered - * @param \Handlebars\Context $context context object - * @param array $args passed arguments to helper - * @param string $source part of template that is wrapped - * within helper - * - * @return mixed */ - public function helperBindAttr($template, $context, $args, $source) + public function helperBindAttr(Template $template, Context $context, string $args, string $source): string { return $args; } @@ -447,16 +358,8 @@ public function helperBindAttr($template, $context, $args, $source) * To uppercase string * * {{#upper data}} - * - * @param \Handlebars\Template $template template that is being rendered - * @param \Handlebars\Context $context context object - * @param array $args passed arguments to helper - * @param string $source part of template that is wrapped - * within helper - * - * @return string */ - public function helperUpper($template, $context, $args, $source) + public function helperUpper(Template $template, Context $context, string $args, string $source): string { return strtoupper($context->get($args)); } @@ -465,16 +368,8 @@ public function helperUpper($template, $context, $args, $source) * To lowercase string * * {{#lower data}} - * - * @param \Handlebars\Template $template template that is being rendered - * @param \Handlebars\Context $context context object - * @param array $args passed arguments to helper - * @param string $source part of template that is wrapped - * within helper - * - * @return string */ - public function helperLower($template, $context, $args, $source) + public function helperLower(Template $template, Context $context, string $args, string $source): string { return strtolower($context->get($args)); } @@ -483,16 +378,8 @@ public function helperLower($template, $context, $args, $source) * to capitalize first letter * * {{#capitalize}} - * - * @param \Handlebars\Template $template template that is being rendered - * @param \Handlebars\Context $context context object - * @param array $args passed arguments to helper - * @param string $source part of template that is wrapped - * within helper - * - * @return string */ - public function helperCapitalize($template, $context, $args, $source) + public function helperCapitalize(Template $template, Context $context, string $args, string $source): string { return ucfirst($context->get($args)); } @@ -501,16 +388,8 @@ public function helperCapitalize($template, $context, $args, $source) * To capitalize first letter in each word * * {{#capitalize_words data}} - * - * @param \Handlebars\Template $template template that is being rendered - * @param \Handlebars\Context $context context object - * @param array $args passed arguments to helper - * @param string $source part of template that is wrapped - * within helper - * - * @return string */ - public function helperCapitalizeWords($template, $context, $args, $source) + public function helperCapitalizeWords(Template $template, Context $context, string $args, string $source): string { return ucwords($context->get($args)); } @@ -519,16 +398,8 @@ public function helperCapitalizeWords($template, $context, $args, $source) * To reverse a string * * {{#reverse data}} - * - * @param \Handlebars\Template $template template that is being rendered - * @param \Handlebars\Context $context context object - * @param array $args passed arguments to helper - * @param string $source part of template that is wrapped - * within helper - * - * @return string */ - public function helperReverse($template, $context, $args, $source) + public function helperReverse(Template $template, Context $context, string $args, string $source): string { return strrev($context->get($args)); } @@ -537,16 +408,8 @@ public function helperReverse($template, $context, $args, $source) * Format a date * * {{#format_date date 'Y-m-d @h:i:s'}} - * - * @param \Handlebars\Template $template template that is being rendered - * @param \Handlebars\Context $context context object - * @param array $args passed arguments to helper - * @param string $source part of template that is wrapped - * within helper - * - * @return mixed */ - public function helperFormatDate($template, $context, $args, $source) + public function helperFormatDate(Template $template, Context $context, string $args, string $source): string { preg_match("/(.*?)\s+(?:(?:\"|\')(.*?)(?:\"|\'))/", $args, $m); $keyname = $m[1]; @@ -569,16 +432,8 @@ public function helperFormatDate($template, $context, $args, $source) /** * {{inflect count 'album' 'albums'}} * {{inflect count '%d album' '%d albums'}} - * - * @param \Handlebars\Template $template template that is being rendered - * @param \Handlebars\Context $context context object - * @param array $args passed arguments to helper - * @param string $source part of template that is wrapped - * within helper - * - * @return mixed */ - public function helperInflect($template, $context, $args, $source) + public function helperInflect(Template $template, Context $context, string $args, string $source): string { preg_match("/(.*?)\s+(?:(?:\"|\')(.*?)(?:\"|\'))\s+(?:(?:\"|\')(.*?)(?:\"|\'))/", $args, $m); $keyname = $m[1]; @@ -589,20 +444,12 @@ public function helperInflect($template, $context, $args, $source) return sprintf($inflect, $value); } - /** - * Provide a default fallback - * - * {{default title "No title available"}} - * - * @param \Handlebars\Template $template template that is being rendered - * @param \Handlebars\Context $context context object - * @param array $args passed arguments to helper - * @param string $source part of template that is wrapped - * within helper - * - * @return string - */ - public function helperDefault($template, $context, $args, $source) + /** + * Provide a default fallback + * + * {{default title "No title available"}} + */ + public function helperDefault(Template $template, Context $context, string $args, string $source): string { preg_match("/(.*?)\s+(?:(?:\"|\')(.*?)(?:\"|\'))/", trim($args), $m); $keyname = $m[1]; @@ -611,20 +458,11 @@ public function helperDefault($template, $context, $args, $source) return ($value) ?: $default; } - /** - * Truncate a string to a length, and append and ellipsis if provided - * {{#truncate content 5 "..."}} - * - * - * @param \Handlebars\Template $template template that is being rendered - * @param \Handlebars\Context $context context object - * @param array $args passed arguments to helper - * @param string $source part of template that is wrapped - * within helper - * - * @return string - */ - public function helperTruncate($template, $context, $args, $source) + /** + * Truncate a string to a length, and append and ellipsis if provided + * {{#truncate content 5 "..."}} + */ + public function helperTruncate(Template $template, Context $context, string $args, string $source): string { preg_match("/(.*?)\s+(.*?)\s+(?:(?:\"|\')(.*?)(?:\"|\'))/", trim($args), $m); $keyname = $m[1]; @@ -641,16 +479,8 @@ public function helperTruncate($template, $context, $args, $source) * Return the data source as is * * {{#raw}} {{/raw}} - * - * @param \Handlebars\Template $template template that is being rendered - * @param \Handlebars\Context $context context object - * @param array $args passed arguments to helper - * @param string $source part of template that is wrapped - * within helper - * - * @return mixed */ - public function helperRaw($template, $context, $args, $source) + public function helperRaw(Template $template, Context $context, string $args, string $source): string { return $source; } @@ -661,23 +491,13 @@ public function helperRaw($template, $context, $args, $source) * {{#repeat 10}} * This section will be repeated 10 times * {{/repeat}} - * - * - * @param \Handlebars\Template $template template that is being rendered - * @param \Handlebars\Context $context context object - * @param array $args passed arguments to helper - * @param string $source part of template that is wrapped - * within helper - * - * @return string */ - public function helperRepeat($template, $context, $args, $source) + public function helperRepeat(Template $template, Context $context, string $args, string $source): string { $buffer = $template->render($context); return str_repeat($buffer, intval($args)); } - /** * Define a section to be used later by using 'invoke' * @@ -690,19 +510,11 @@ public function helperRepeat($template, $context, $args, $source) * * --> This is how it is called * {{#invoke hello}} - * - * - * @param \Handlebars\Template $template template that is being rendered - * @param \Handlebars\Context $context context object - * @param array $args passed arguments to helper - * @param string $source part of template that is wrapped - * within helper - * - * @return null */ - public function helperDefine($template, $context, $args, $source) + public function helperDefine(Template $template, Context $context, string $args, string $source): string { $this->tpl["DEFINE"][$args] = clone($template); + return ''; } /** @@ -717,17 +529,8 @@ public function helperDefine($template, $context, $args, $source) * * --> This is how it is called * {{#invoke hello}} - * - * - * @param \Handlebars\Template $template template that is being rendered - * @param \Handlebars\Context $context context object - * @param array $args passed arguments to helper - * @param string $source part of template that is wrapped - * within helper - * - * @return null */ - public function helperInvoke($template, $context, $args, $source) + public function helperInvoke(Template $template, Context $context, string $args, string $source): string { if (! isset($this->tpl["DEFINE"][$args])) { throw new LogicException("Can't INVOKE '{$args}'. '{$args}' was not DEFINE "); @@ -735,14 +538,10 @@ public function helperInvoke($template, $context, $args, $source) return $this->tpl["DEFINE"][$args]->render($context); } - /** * Change underscore helper name to CamelCase - * - * @param string $string - * @return string */ - private function underscoreToCamelCase($string) + private function underscoreToCamelCase($string): string { return str_replace(' ', '', ucwords(str_replace('_', ' ', $string))); } @@ -750,7 +549,7 @@ private function underscoreToCamelCase($string) /** * slice * Allow to split the data that will be returned - * #loop[start:end] => starts at start trhough end -1 + * #loop[start:end] => starts at start through end -1 * #loop[start:] = Starts at start though the rest of the array * #loop[:end] = Starts at the beginning through end -1 * #loop[:] = A copy of the whole array @@ -758,16 +557,15 @@ private function underscoreToCamelCase($string) * #loop[-1] * #loop[-2:] = Last two items * #loop[:-2] = Everything except last two items - * - * @param string $string - * @return Array [tag_name, slice_start, slice_end] + + * @return array{string, int|null, int|null} */ - private function extractSlice($string) + private function extractSlice(string $string): array { preg_match("/^([\w\._\-]+)(?:\[([\-0-9]*?:[\-0-9]*?)\])?/i", $string, $m); $slice_start = $slice_end = null; if (isset($m[2])) { - list($slice_start, $slice_end) = explode(":", $m[2]); + [$slice_start, $slice_end] = explode(":", $m[2]); $slice_start = (int) $slice_start; $slice_end = $slice_end ? (int) $slice_end : null; } @@ -775,13 +573,9 @@ private function extractSlice($string) } /** - * Parse avariable from current args - * - * @param \Handlebars\Context $context context object - * @param array $args passed arguments to helper - * @return array + * Parse a variable from current args */ - private function parseArgs($context, $args) + private function parseArgs(Context $context, string $args): array { $args = preg_replace('/\s+/', ' ', trim($args)); $eles = explode(' ', $args); @@ -795,6 +589,7 @@ private function parseArgs($context, $args) } $eles[$key] = $val; } + return $eles; } } diff --git a/src/Handlebars/Parser.php b/src/Handlebars/Parser.php index a4cbf7e..62fa89f 100755 --- a/src/Handlebars/Parser.php +++ b/src/Handlebars/Parser.php @@ -18,6 +18,7 @@ */ namespace Handlebars; + use ArrayIterator; use LogicException; @@ -25,12 +26,8 @@ class Parser { /** * Process array of tokens and convert them into parse tree - * - * @param array $tokens Set of - * - * @return array Token parse tree */ - public function parse(Array $tokens = []) + public function parse(array $tokens = []): array { return $this->buildTree(new ArrayIterator($tokens)); } @@ -38,14 +35,9 @@ public function parse(Array $tokens = []) /** * Helper method for recursively building a parse tree. * - * @param \ArrayIterator $tokens Stream of tokens - * - * @throws \LogicException when nesting errors or mismatched section tags - * are encountered. - * @return array Token parse tree - * + * @throws \LogicException when nesting errors or mismatched section tags are encountered. */ - private function buildTree(ArrayIterator $tokens) + private function buildTree(ArrayIterator $tokens): array { $stack = []; @@ -55,8 +47,9 @@ private function buildTree(ArrayIterator $tokens) if ($token === null) { continue; - } else { - switch ($token[Tokenizer::TYPE]) { + } + + switch ($token[Tokenizer::TYPE]) { case Tokenizer::T_END_SECTION: $newNodes = []; do { @@ -73,22 +66,17 @@ private function buildTree(ArrayIterator $tokens) ) { $result[Tokenizer::NODES] = $newNodes; $result[Tokenizer::END] = $token[Tokenizer::INDEX]; - array_push($stack, $result); + $stack[] = $result; break 2; } else { array_unshift($newNodes, $result); } } while (true); - break; default: - array_push($stack, $token); - } + $stack[] = $token; } - } while ($tokens->valid()); return $stack; - } - } diff --git a/src/Handlebars/Template.php b/src/Handlebars/Template.php index d18205a..0f81afe 100755 --- a/src/Handlebars/Template.php +++ b/src/Handlebars/Template.php @@ -22,77 +22,53 @@ class Template { - /** - * @var Handlebars - */ - protected $handlebars; - - protected $tree = []; - - protected $source = ''; - - /** - * @var array Run stack - */ - private $stack = []; + protected Handlebars $handlebars; + protected array $tree = []; + protected string $source = ''; + private array $stack = []; - /** - * Handlebars template constructor - * - * @param Handlebars $engine handlebar engine - * @param array $tree Parsed tree - * @param string $source Handlebars source - */ - public function __construct(Handlebars $engine, $tree, $source) + public function __construct(Handlebars $engine, array $tree, string $source) { $this->handlebars = $engine; $this->tree = $tree; $this->source = $source; - array_push($this->stack, [0, $this->getTree(), false]); + $this->stack[] = [0, $tree, false]; } /** * Get current tree - * - * @return array */ - public function getTree() + public function getTree(): array { return $this->tree; } /** * Get current source - * - * @return string */ - public function getSource() + public function getSource(): string { return $this->source; } /** * Get current engine associated with this object - * - * @return Handlebars */ - public function getEngine() + public function getEngine(): Handlebars { return $this->handlebars; } /** - * set stop token for render and discard method + * Set stop token for render and discard method * * @param string|false $token token to set as stop token or false to remove - * - * @return void */ - public function setStopToken($token) + public function setStopToken($token): void { $topStack = array_pop($this->stack); $topStack[2] = $token; - array_push($this->stack, $topStack); + $this->stack[] = $topStack; } /** @@ -111,9 +87,8 @@ public function getStopToken() * @param mixed $context current context * * @throws \RuntimeException - * @return string */ - public function render($context) + public function render($context): string { if (!$context instanceof Context) { $context = new Context($context, [ @@ -121,7 +96,7 @@ public function render($context) ]); } $topTree = end($this->stack); // never pop a value from stack - list($index, $tree, $stop) = $topTree; + [$index, $tree, $stop] = $topTree; $buffer = ''; while (array_key_exists($index, $tree)) { @@ -136,16 +111,14 @@ public function render($context) } switch ($current[Tokenizer::TYPE]) { case Tokenizer::T_SECTION : - $newStack = isset($current[Tokenizer::NODES]) - ? $current[Tokenizer::NODES] : []; - array_push($this->stack, [0, $newStack, false]); + $newStack = $current[Tokenizer::NODES] ?? []; + $this->stack[] = [0, $newStack, false]; $buffer .= $this->section($context, $current); array_pop($this->stack); break; case Tokenizer::T_INVERTED : - $newStack = isset($current[Tokenizer::NODES]) ? - $current[Tokenizer::NODES] : []; - array_push($this->stack, [0, $newStack, false]); + $newStack = $current[Tokenizer::NODES] ?? []; + $this->stack[] = [0, $newStack, false]; $buffer .= $this->inverted($context, $current); array_pop($this->stack); break; @@ -177,7 +150,7 @@ public function render($context) $newStack = array_pop($this->stack); $newStack[0] = $index; $newStack[2] = false; //No stop token from now on - array_push($this->stack, $newStack); + $this->stack[] = $newStack; } return $buffer; @@ -185,13 +158,11 @@ public function render($context) /** * Discard top tree - * - * @return string */ - public function discard() + public function discard(): string { $topTree = end($this->stack); //This method never pop a value from stack - list($index, $tree, $stop) = $topTree; + [$index, $tree, $stop] = $topTree; while (array_key_exists($index, $tree)) { $current = $tree[$index]; $index++; @@ -208,7 +179,7 @@ public function discard() $newStack = array_pop($this->stack); $newStack[0] = $index; $newStack[2] = false; - array_push($this->stack, $newStack); + $this->stack[] = $newStack; } return ''; @@ -216,14 +187,9 @@ public function discard() /** * Process section nodes - * - * @param Context $context current context - * @param array $current section node data - * * @throws \RuntimeException - * @return string the result */ - private function section(Context $context, $current) + private function section(Context $context, array $current): string { $helpers = $this->handlebars->getHelpers(); $sectionName = $current[Tokenizer::NAME]; @@ -244,12 +210,7 @@ private function section(Context $context, $current) $source ]; - $return = call_user_func_array($helpers->$sectionName, $params); - if ($return instanceof String) { - return $this->handlebars->loadString($return)->render($context); - } else { - return $return; - } + return call_user_func_array($helpers->$sectionName, $params); } elseif (trim($current[Tokenizer::ARGS]) == '') { // fallback to mustache style each/with/for just if there is // no argument at all. @@ -288,13 +249,8 @@ private function section(Context $context, $current) /** * Process inverted section - * - * @param Context $context current context - * @param array $current section node data - * - * @return string the result */ - private function inverted(Context $context, $current) + private function inverted(Context $context, array $current): string { $sectionName = $current[Tokenizer::NAME]; $data = $context->get($sectionName); @@ -308,13 +264,8 @@ private function inverted(Context $context, $current) /** * Process partial section - * - * @param Context $context current context - * @param array $current section node data - * - * @return string the result */ - private function partial(Context $context, $current) + private function partial(Context $context, array $current): string { $partial = $this->handlebars->loadPartial($current[Tokenizer::NAME]); @@ -327,14 +278,8 @@ private function partial(Context $context, $current) /** * Process partial section - * - * @param Context $context current context - * @param array $current section node data - * @param boolean $escaped escape result or not - * - * @return string the result */ - private function variables(Context $context, $current, $escaped) + private function variables(Context $context, array $current, bool $escaped): string { $name = $current[Tokenizer::NAME]; $value = $context->get($name); @@ -370,9 +315,4 @@ private function variables(Context $context, $current, $escaped) return $value; } - - public function __clone() - { - return $this; - } } diff --git a/src/Handlebars/Tokenizer.php b/src/Handlebars/Tokenizer.php index 97b18b7..6d86a51 100644 --- a/src/Handlebars/Tokenizer.php +++ b/src/Handlebars/Tokenizer.php @@ -19,7 +19,6 @@ class Tokenizer { - // Finite state machine states const IN_TEXT = 0; const IN_TAG_TYPE = 1; @@ -40,7 +39,7 @@ class Tokenizer const T_TEXT = '_t'; // Valid token types - private $tagTypes = [ + private array $tagTypes = [ self::T_SECTION => true, self::T_INVERTED => true, self::T_END_SECTION => true, @@ -54,7 +53,7 @@ class Tokenizer ]; // Interpolated tags - private $interpolatedTags = [ + private array $interpolatedTags = [ self::T_ESCAPED => true, self::T_UNESCAPED => true, self::T_UNESCAPED_2 => true, @@ -72,34 +71,24 @@ class Tokenizer const VALUE = 'value'; const ARGS = 'args'; - protected $state; - protected $tagType; - protected $tag; - protected $buffer; - protected $tokens; - protected $seenTag; - protected $lineStart; - protected $otag; - protected $ctag; + protected int $state; + protected ?string $tagType; + protected string $buffer; + protected array $tokens; + protected int $seenTag; + protected int $lineStart; + protected string $otag; + protected string $ctag; /** - * Scan and tokenize template source. - * - * @param string $text Mustache template source to tokenize - * @param string $delimiters Optional, pass opening and closing delimiters - * - * @return array Set of Mustache tokens + * Scan and tokenize Mustache template source. */ - public function scan($text, $delimiters = null) + public function scan(string $text, ?string $delimiters = null): array { - if ($text instanceof HandlebarsString) { - $text = $text->getString(); - } - $this->reset(); if ($delimiters !== null && $delimiters = trim($delimiters)) { - list($otag, $ctag) = explode(' ', $delimiters); + [$otag, $ctag] = explode(' ', $delimiters); $this->otag = $otag; $this->ctag = $ctag; } @@ -223,17 +212,14 @@ public function scan($text, $delimiters = null) /** * Helper function to reset tokenizer internal state. - * - * @return void */ - protected function reset() + protected function reset(): void { $this->state = self::IN_TEXT; $this->tagType = null; - $this->tag = null; $this->buffer = ''; $this->tokens = []; - $this->seenTag = false; + $this->seenTag = 0; $this->lineStart = 0; $this->otag = '{{'; $this->ctag = '}}'; @@ -241,12 +227,10 @@ protected function reset() /** * Flush the current buffer to a token. - * - * @return void */ - protected function flushBuffer() + protected function flushBuffer(): void { - if (!empty($this->buffer)) { + if ($this->buffer !== '') { $this->tokens[] = [ self::TYPE => self::T_TEXT, self::VALUE => $this->buffer @@ -257,10 +241,8 @@ protected function flushBuffer() /** * Test whether the current line is entirely made up of whitespace. - * - * @return boolean True if the current line is all whitespace */ - protected function lineIsWhitespace() + protected function lineIsWhitespace(): bool { $tokensCount = count($this->tokens); for ($j = $this->lineStart; $j < $tokensCount; $j++) { @@ -281,12 +263,8 @@ protected function lineIsWhitespace() /** * Filter out whitespace-only lines and store indent levels for partials. - * - * @param bool $noNewLine Suppress the newline? (default: false) - * - * @return void */ - protected function filterLine($noNewLine = false) + protected function filterLine(bool $noNewLine = false): void { $this->flushBuffer(); if ($this->seenTag && $this->lineIsWhitespace()) { @@ -307,25 +285,20 @@ protected function filterLine($noNewLine = false) $this->tokens[] = [self::TYPE => self::T_TEXT, self::VALUE => "\n"]; } - $this->seenTag = false; + $this->seenTag = 0; $this->lineStart = count($this->tokens); } /** * Change the current Mustache delimiters. Set new `otag` and `ctag` values. - * - * @param string $text Mustache template source - * @param int $index Current tokenizer index - * - * @return int New index value */ - protected function changeDelimiters($text, $index) + protected function changeDelimiters(string $text, int $index): int { $startIndex = strpos($text, '=', $index) + 1; $close = '=' . $this->ctag; $closeIndex = strpos($text, $close, $index); - list($otag, $ctag) = explode( + [$otag, $ctag] = explode( ' ', trim(substr($text, $startIndex, $closeIndex - $startIndex)) ); @@ -337,15 +310,8 @@ protected function changeDelimiters($text, $index) /** * Test whether it's time to change tags. - * - * @param string $tag Current tag name - * @param string $text Mustache template source - * @param int $index Current tokenizer index - * @param int $tagLength Length of the opening/closing tag string - * - * @return boolean True if this is a closing section tag */ - protected function tagChange($tag, $text, $index, $tagLength) + protected function tagChange(string $tag, string $text, int $index, int $tagLength): bool { return substr($text, $index, $tagLength) === $tag; } diff --git a/tests/Handlebars/HandlebarsTest.php b/tests/Handlebars/HandlebarsTest.php index 6df0fa2..9e92db0 100644 --- a/tests/Handlebars/HandlebarsTest.php +++ b/tests/Handlebars/HandlebarsTest.php @@ -5,15 +5,9 @@ class HandlebarsTest extends PHPUnit\Framework\TestCase /** * Test basic tags * - * @param string $src handlebars source - * @param array $data data - * @param string $result expected data - * * @dataProvider simpleTagdataProvider - * - * @return void */ - public function testBasicTags($src, $data, $result) + public function testBasicTags(string $src, array $data, string $result): void { $loader = new \Handlebars\Loader\StringLoader(); $engine = new \Handlebars\Handlebars(array('loader' => $loader)); @@ -22,10 +16,8 @@ public function testBasicTags($src, $data, $result) /** * Simple tag provider - * - * @return array */ - public function simpleTagdataProvider() + public function simpleTagdataProvider(): array { return array( array( @@ -50,15 +42,9 @@ public function simpleTagdataProvider() /** * Test helpers (internal helpers) * - * @param string $src handlebars source - * @param array $data data - * @param string $result expected data - * * @dataProvider internalHelpersdataProvider - * - * @return void */ - public function testSimpleHelpers($src, $data, $result) + public function testSimpleHelpers(string $src, array $data, string $result): void { $loader = new \Handlebars\Loader\StringLoader(); $helpers = new \Handlebars\Helpers(); @@ -69,10 +55,8 @@ public function testSimpleHelpers($src, $data, $result) /** * Simple helpers provider - * - * @return array */ - public function internalHelpersdataProvider() + public function internalHelpersdataProvider(): array { return [ [ @@ -199,13 +183,9 @@ public function internalHelpersdataProvider() } /** - * @param string $src - * @param array $data - * @param string $result - * @param bool $enableDataVariables * @dataProvider internalDataVariablesDataProvider */ - public function testDataVariables($src, $data, $result, $enableDataVariables) + public function testDataVariables(string $src, array $data, string $result, bool $enableDataVariables): void { $loader = new \Handlebars\Loader\StringLoader(); $helpers = new \Handlebars\Helpers(); @@ -238,9 +218,8 @@ public function testDataVariables1() /** * Data provider for data variables - * @return array */ - public function internalDataVariablesDataProvider() + public function internalDataVariablesDataProvider(): array { // Build a standard set of objects to test against $keyPropertyName = '@key'; @@ -405,32 +384,26 @@ public function testCustomHelper() $this->assertEquals('Test helper is called', $engine->render('{{#test}}', [])); } - /** - * @param $dir - * - * @return bool - */ - private function delTree($dir) + private function delTree(string $dir): bool { $contents = scandir($dir); if ($contents === false) { - return; + return false; } $files = array_diff($contents, array('.', '..')); foreach ($files as $file) { - (is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file"); + (is_dir("$dir/$file")) ? $this->delTree("$dir/$file") : unlink("$dir/$file"); } return rmdir($dir); } /** - * Its not a good test :) but ok + * It's not a good test :) but ok */ public function testCacheSystem() { $path = sys_get_temp_dir() . '/__cache__handlebars'; - @$this->delTree($path); $dummy = new \Handlebars\Cache\Disk($path);