first commit
This commit is contained in:
233
lib/old/libs/sysplugins/smarty_internal_runtime_inheritance.php
Normal file
233
lib/old/libs/sysplugins/smarty_internal_runtime_inheritance.php
Normal file
@ -0,0 +1,233 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Inheritance Runtime Methods processBlock, endChild, init
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsInternal
|
||||
* @author Uwe Tews
|
||||
*
|
||||
**/
|
||||
class Smarty_Internal_Runtime_Inheritance
|
||||
{
|
||||
|
||||
/**
|
||||
* State machine
|
||||
* - 0 idle next extends will create a new inheritance tree
|
||||
* - 1 processing child template
|
||||
* - 2 wait for next inheritance template
|
||||
* - 3 assume parent template, if child will loaded goto state 1
|
||||
* a call to a sub template resets the state to 0
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $state = 0;
|
||||
|
||||
/**
|
||||
* Array of block parameter of known {block} tags
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $blockParameter = array();
|
||||
|
||||
/**
|
||||
* inheritance template nesting level
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $inheritanceLevel = 0;
|
||||
|
||||
/**
|
||||
* inheritance template index
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $tplIndex = - 1;
|
||||
|
||||
/**
|
||||
* Array of compiled template file path
|
||||
* - key template index
|
||||
* only used when caching is enabled
|
||||
*
|
||||
* @var []string
|
||||
*/
|
||||
public $compiledFilePath = array();
|
||||
|
||||
/**
|
||||
* Current {block} nesting level
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $blockNesting = 0;
|
||||
|
||||
/**
|
||||
* Initialize inheritance
|
||||
*
|
||||
* @param \Smarty_Internal_Template $tpl template object of caller
|
||||
* @param bool $initChild if true init for child template
|
||||
* @param array $blockNames outer level block name
|
||||
*
|
||||
*/
|
||||
public function init(Smarty_Internal_Template $tpl, $initChild, $blockNames = array())
|
||||
{
|
||||
// if template was from an inner block or template is a parent template create new inheritance root
|
||||
if ($initChild && ($this->blockNesting || $this->state == 3)) {
|
||||
$tpl->ext->_inheritance = new Smarty_Internal_Runtime_Inheritance();
|
||||
$tpl->ext->_inheritance->init($tpl, $initChild, $blockNames);
|
||||
return;
|
||||
}
|
||||
// start of child sub template(s)
|
||||
if ($initChild) {
|
||||
$this->state = 1;
|
||||
if (!$this->inheritanceLevel) {
|
||||
//grab any output of child templates
|
||||
ob_start();
|
||||
}
|
||||
$this->inheritanceLevel ++;
|
||||
}
|
||||
// in parent state {include} will not increment template index
|
||||
if ($this->state != 3) {
|
||||
$this->tplIndex ++;
|
||||
}
|
||||
// if state was waiting for parent change state to parent
|
||||
if ($this->state == 2) {
|
||||
$this->state = 3;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* End of child template(s)
|
||||
* - if outer level is reached flush output buffer and switch to wait for parent template state
|
||||
*
|
||||
* @param \Smarty_Internal_Template $tpl template object of caller
|
||||
*/
|
||||
public function endChild(Smarty_Internal_Template $tpl)
|
||||
{
|
||||
$this->inheritanceLevel --;
|
||||
if (!$this->inheritanceLevel) {
|
||||
ob_end_clean();
|
||||
$this->state = 2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process inheritance {block} tag
|
||||
*
|
||||
* $type 0 = {block}:
|
||||
* - search in inheritance template hierarchy for child blocks
|
||||
* if found call it, otherwise call current block
|
||||
* - ignored for outer level blocks in child templates
|
||||
*
|
||||
* $type 1 = {block}:
|
||||
* - nested {block}
|
||||
* - search in inheritance template hierarchy for child blocks
|
||||
* if found call it, otherwise call current block
|
||||
*
|
||||
* $type 2 = {$smarty.block.child}:
|
||||
* - search in inheritance template hierarchy for child blocks
|
||||
* if found call it, otherwise ignore
|
||||
*
|
||||
* $type 3 = {block append} {block prepend}:
|
||||
* - call parent block
|
||||
*
|
||||
* $type 4 = {$smarty.block.parent}:
|
||||
* - call parent block
|
||||
*
|
||||
* @param \Smarty_Internal_Template $tpl template object of caller
|
||||
* @param int $type call type see above
|
||||
* @param string $name block name
|
||||
* @param array $block block parameter
|
||||
* @param array $callStack call stack with block parameters
|
||||
*
|
||||
* @throws \SmartyException
|
||||
*/
|
||||
public function processBlock(Smarty_Internal_Template $tpl, $type = 0, $name, $block, $callStack = array())
|
||||
{
|
||||
if (!isset($this->blockParameter[ $name ])) {
|
||||
$this->blockParameter[ $name ] = array();
|
||||
}
|
||||
if ($this->state == 1) {
|
||||
$block[ 2 ] = count($this->blockParameter[ $name ]);
|
||||
$block[ 3 ] = $this->tplIndex;
|
||||
$this->blockParameter[ $name ][] = $block;
|
||||
return;
|
||||
}
|
||||
if ($type == 3) {
|
||||
if (!empty($callStack)) {
|
||||
$block = array_shift($callStack);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} elseif ($type == 4) {
|
||||
if (!empty($callStack)) {
|
||||
array_shift($callStack);
|
||||
if (empty($callStack)) {
|
||||
throw new SmartyException("inheritance: tag {\$smarty.block.parent} used in parent template block '{$name}'");
|
||||
}
|
||||
$block = array_shift($callStack);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
$index = 0;
|
||||
$blockParameter = &$this->blockParameter[ $name ];
|
||||
if ($type == 0) {
|
||||
$index = $block[ 2 ] = count($blockParameter);
|
||||
$block[ 3 ] = $this->tplIndex;
|
||||
$callStack = array(&$block);
|
||||
} elseif ($type == 1) {
|
||||
$block[ 3 ] = $callStack[ 0 ][ 3 ];
|
||||
for ($i = 0; $i < count($blockParameter); $i ++) {
|
||||
if ($blockParameter[ $i ][ 3 ] <= $block[ 3 ]) {
|
||||
$index = $blockParameter[ $i ][ 2 ];
|
||||
}
|
||||
}
|
||||
$block[ 2 ] = $index;
|
||||
$callStack = array(&$block);
|
||||
} elseif ($type == 2) {
|
||||
$index = $callStack[ 0 ][ 2 ];
|
||||
if ($index == 0) {
|
||||
return;
|
||||
}
|
||||
$callStack = $block = array(1 => false);
|
||||
}
|
||||
$index --;
|
||||
// find lowest level child block
|
||||
while ($index >= 0 && ($type || !$block[ 1 ])) {
|
||||
$block = &$blockParameter[ $index ];
|
||||
array_unshift($callStack, $block);
|
||||
if ($block[ 1 ]) {
|
||||
break;
|
||||
}
|
||||
$index --;
|
||||
}
|
||||
if (isset($block[ 'hide' ]) && $index <= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
$this->blockNesting ++;
|
||||
// {block append} ?
|
||||
if (isset($block[ 'append' ])) {
|
||||
$appendStack = $callStack;
|
||||
if ($type == 0) {
|
||||
array_shift($appendStack);
|
||||
}
|
||||
$this->processBlock($tpl, 3, $name, null, $appendStack);
|
||||
}
|
||||
// call block of current stack level
|
||||
if (isset($block[6])) {
|
||||
$block[6]($tpl, $callStack);
|
||||
} else {
|
||||
$block[0]($tpl, $callStack);
|
||||
}
|
||||
// {block prepend} ?
|
||||
if (isset($block[ 'prepend' ])) {
|
||||
$prependStack = $callStack;
|
||||
if ($type == 0) {
|
||||
array_shift($prependStack);
|
||||
}
|
||||
$this->processBlock($tpl, 3, $name, null, $prependStack);
|
||||
}
|
||||
$this->blockNesting --;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user