AutorÃa | Ultima modificación | Ver Log |
<?php/** This file is part of Mustache.php.** (c) 2010-2017 Justin Hileman** For the full copyright and license information, please view the LICENSE* file that was distributed with this source code.*//*** Mustache Template rendering Context.*/class Mustache_Context{private $stack = array();private $blockStack = array();/*** Mustache rendering Context constructor.** @param mixed $context Default rendering context (default: null)*/public function __construct($context = null){if ($context !== null) {$this->stack = array($context);}}/*** Push a new Context frame onto the stack.** @param mixed $value Object or array to use for context*/public function push($value){array_push($this->stack, $value);}/*** Push a new Context frame onto the block context stack.** @param mixed $value Object or array to use for block context*/public function pushBlockContext($value){array_push($this->blockStack, $value);}/*** Pop the last Context frame from the stack.** @return mixed Last Context frame (object or array)*/public function pop(){return array_pop($this->stack);}/*** Pop the last block Context frame from the stack.** @return mixed Last block Context frame (object or array)*/public function popBlockContext(){return array_pop($this->blockStack);}/*** Get the last Context frame.** @return mixed Last Context frame (object or array)*/public function last(){return end($this->stack);}/*** Find a variable in the Context stack.** Starting with the last Context frame (the context of the innermost section), and working back to the top-level* rendering context, look for a variable with the given name:** * If the Context frame is an associative array which contains the key $id, returns the value of that element.* * If the Context frame is an object, this will check first for a public method, then a public property named* $id. Failing both of these, it will try `__isset` and `__get` magic methods.* * If a value named $id is not found in any Context frame, returns an empty string.** @param string $id Variable name** @return mixed Variable value, or '' if not found*/public function find($id){return $this->findVariableInStack($id, $this->stack);}/*** Find a 'dot notation' variable in the Context stack.** Note that dot notation traversal bubbles through scope differently than the regular find method. After finding* the initial chunk of the dotted name, each subsequent chunk is searched for only within the value of the previous* result. For example, given the following context stack:** $data = array(* 'name' => 'Fred',* 'child' => array(* 'name' => 'Bob'* ),* );** ... and the Mustache following template:** {{ child.name }}** ... the `name` value is only searched for within the `child` value of the global Context, not within parent* Context frames.** @param string $id Dotted variable selector** @return mixed Variable value, or '' if not found*/public function findDot($id){$chunks = explode('.', $id);$first = array_shift($chunks);$value = $this->findVariableInStack($first, $this->stack);foreach ($chunks as $chunk) {if ($value === '') {return $value;}$value = $this->findVariableInStack($chunk, array($value));}return $value;}/*** Find an 'anchored dot notation' variable in the Context stack.** This is the same as findDot(), except it looks in the top of the context* stack for the first value, rather than searching the whole context stack* and starting from there.** @see Mustache_Context::findDot** @throws Mustache_Exception_InvalidArgumentException if given an invalid anchored dot $id** @param string $id Dotted variable selector** @return mixed Variable value, or '' if not found*/public function findAnchoredDot($id){$chunks = explode('.', $id);$first = array_shift($chunks);if ($first !== '') {throw new Mustache_Exception_InvalidArgumentException(sprintf('Unexpected id for findAnchoredDot: %s', $id));}$value = $this->last();foreach ($chunks as $chunk) {if ($value === '') {return $value;}$value = $this->findVariableInStack($chunk, array($value));}return $value;}/*** Find an argument in the block context stack.** @param string $id** @return mixed Variable value, or '' if not found*/public function findInBlock($id){foreach ($this->blockStack as $context) {if (array_key_exists($id, $context)) {return $context[$id];}}return '';}/*** Helper function to find a variable in the Context stack.** @see Mustache_Context::find** @param string $id Variable name* @param array $stack Context stack** @return mixed Variable value, or '' if not found*/private function findVariableInStack($id, array $stack){for ($i = count($stack) - 1; $i >= 0; $i--) {$frame = &$stack[$i];switch (gettype($frame)) {case 'object':if (!($frame instanceof Closure)) {// Note that is_callable() *will not work here*// See https://github.com/bobthecow/mustache.php/wiki/Magic-Methodsif (method_exists($frame, $id)) {return $frame->$id();}if (isset($frame->$id)) {return $frame->$id;}if ($frame instanceof ArrayAccess && isset($frame[$id])) {return $frame[$id];}}break;case 'array':if (array_key_exists($id, $frame)) {return $frame[$id];}break;}}return '';}}