2015-10-18 04:46:05 +02:00
< ? php
/**
2015-10-21 02:02:42 +02:00
* Inheritance Runtime Methods processBlock , endChild , init
2015-10-18 04:46:05 +02:00
*
* @ 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 ;
/**
2015-12-27 04:02:21 +01:00
* Array of root child { block } objects
2015-10-18 04:46:05 +02:00
*
2015-12-27 04:02:21 +01:00
* @ var Smarty_Internal_Block []
2015-10-18 04:46:05 +02:00
*/
2015-12-27 04:02:21 +01:00
public $childRoot = array ();
2015-10-18 04:46:05 +02:00
/**
* inheritance template nesting level
*
* @ var int
*/
public $inheritanceLevel = 0 ;
/**
* inheritance template index
*
* @ var int
*/
2017-10-12 08:21:12 +02:00
public $tplIndex = - 1 ;
2015-10-18 04:46:05 +02:00
2016-01-27 04:51:02 +01:00
/**
2016-04-24 11:04:36 +02:00
* Array of template source objects
* - key template index
2016-01-27 04:51:02 +01:00
*
2016-04-24 11:04:36 +02:00
* @ var Smarty_Template_Source []
2016-01-27 04:51:02 +01:00
*/
2016-04-24 11:04:36 +02:00
public $sources = array ();
2016-01-27 04:51:02 +01:00
2015-10-18 04:46:05 +02:00
/**
2016-07-19 03:37:01 +02:00
* Stack of source objects while executing block code
2015-10-18 04:46:05 +02:00
*
2016-07-19 03:37:01 +02:00
* @ var Smarty_Template_Source []
2015-10-18 04:46:05 +02:00
*/
2016-07-19 03:37:01 +02:00
public $sourceStack = array ();
2015-10-18 04:46:05 +02:00
/**
* 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 ())
{
2015-12-27 04:02:21 +01:00
// if called while executing parent template it must be a sub-template with new inheritance root
2017-11-06 01:02:56 +01:00
if ( $initChild && $this -> state === 3 && ( strpos ( $tpl -> template_resource , 'extendsall' ) === false )) {
2016-05-10 03:54:56 +02:00
$tpl -> inheritance = new Smarty_Internal_Runtime_Inheritance ();
$tpl -> inheritance -> init ( $tpl , $initChild , $blockNames );
2015-10-18 04:46:05 +02:00
return ;
}
2017-10-12 08:21:12 +02:00
$this -> tplIndex ++ ;
2016-07-19 03:37:01 +02:00
$this -> sources [ $this -> tplIndex ] = $tpl -> source ;
2015-10-18 04:46:05 +02:00
// start of child sub template(s)
if ( $initChild ) {
$this -> state = 1 ;
if ( ! $this -> inheritanceLevel ) {
//grab any output of child templates
ob_start ();
}
2017-10-12 08:21:12 +02:00
$this -> inheritanceLevel ++ ;
2016-07-19 03:37:01 +02:00
// $tpl->startRenderCallbacks[ 'inheritance' ] = array($this, 'subTemplateStart');
// $tpl->endRenderCallbacks[ 'inheritance' ] = array($this, 'subTemplateEnd');
2015-10-18 04:46:05 +02:00
}
// if state was waiting for parent change state to parent
2017-11-06 01:02:56 +01:00
if ( $this -> state === 2 ) {
2015-10-18 04:46:05 +02:00
$this -> state = 3 ;
}
}
/**
* End of child template ( s )
* - if outer level is reached flush output buffer and switch to wait for parent template state
*
2016-09-29 04:22:20 +02:00
* @ param \Smarty_Internal_Template $tpl
2017-04-08 12:10:39 +02:00
* @ param null | string $template optional name of inheritance parent template
2016-09-29 04:22:20 +02:00
* @ param null | string $uid uid of inline template
* @ param null | string $func function call name of inline template
2017-10-26 10:25:41 +02:00
*
* @ throws \Exception
* @ throws \SmartyException
2015-10-18 04:46:05 +02:00
*/
2016-09-29 04:22:20 +02:00
public function endChild ( Smarty_Internal_Template $tpl , $template = null , $uid = null , $func = null )
2015-10-18 04:46:05 +02:00
{
2017-10-12 08:21:12 +02:00
$this -> inheritanceLevel -- ;
2015-10-18 04:46:05 +02:00
if ( ! $this -> inheritanceLevel ) {
ob_end_clean ();
$this -> state = 2 ;
}
2017-10-12 08:21:12 +02:00
if ( isset ( $template ) && (( $tpl -> parent -> _isTplObj () && $tpl -> parent -> source -> type !== 'extends' ) ||
$tpl -> smarty -> extends_recursion )) {
$tpl -> _subTemplateRender ( $template ,
$tpl -> cache_id ,
$tpl -> compile_id ,
$tpl -> caching ? 9999 : 0 ,
$tpl -> cache_lifetime ,
array (),
2 ,
false ,
$uid ,
$func );
2016-09-29 04:22:20 +02:00
}
2015-10-18 04:46:05 +02:00
}
2016-04-24 11:04:36 +02:00
2016-05-10 03:54:56 +02:00
/**
* Smarty_Internal_Block constructor .
2017-11-06 01:02:56 +01:00
* - if outer level { block } of child template ( $state === 1 ) save it as child root block
2016-05-10 03:54:56 +02:00
* - otherwise process inheritance and render
*
* @ param \Smarty_Internal_Template $tpl
* @ param $className
* @ param string $name
* @ param int | null $tplIndex index of outer level { block } if nested
2017-10-26 10:25:41 +02:00
*
* @ throws \SmartyException
2016-05-10 03:54:56 +02:00
*/
public function instanceBlock ( Smarty_Internal_Template $tpl , $className , $name , $tplIndex = null )
{
2016-11-19 07:34:06 +01:00
$block = new $className ( $name , isset ( $tplIndex ) ? $tplIndex : $this -> tplIndex );
2016-05-10 03:54:56 +02:00
if ( isset ( $this -> childRoot [ $name ])) {
$block -> child = $this -> childRoot [ $name ];
}
2017-11-06 01:02:56 +01:00
if ( $this -> state === 1 ) {
2016-05-10 03:54:56 +02:00
$this -> childRoot [ $name ] = $block ;
return ;
}
// make sure we got child block of child template of current block
while ( $block -> child && $block -> tplIndex <= $block -> child -> tplIndex ) {
$block -> child = $block -> child -> child ;
}
$this -> process ( $tpl , $block );
}
/**
* Goto child block or render this
*
* @ param \Smarty_Internal_Template $tpl
* @ param \Smarty_Internal_Block $block
* @ param \Smarty_Internal_Block | null $parent
*
* @ throws \SmartyException
*/
2017-10-12 08:21:12 +02:00
public function process ( Smarty_Internal_Template $tpl ,
Smarty_Internal_Block $block ,
2016-05-10 03:54:56 +02:00
Smarty_Internal_Block $parent = null )
{
if ( $block -> hide && ! isset ( $block -> child )) {
return ;
}
if ( isset ( $block -> child ) && $block -> child -> hide && ! isset ( $block -> child -> child )) {
$block -> child = null ;
}
$block -> parent = $parent ;
if ( $block -> append && ! $block -> prepend && isset ( $parent )) {
$this -> callParent ( $tpl , $block );
}
if ( $block -> callsChild || ! isset ( $block -> child ) || ( $block -> child -> hide && ! isset ( $block -> child -> child ))) {
2016-07-19 03:37:01 +02:00
$this -> callBlock ( $block , $tpl );
2016-05-10 03:54:56 +02:00
} else {
$this -> process ( $tpl , $block -> child , $block );
}
if ( $block -> prepend && isset ( $parent )) {
$this -> callParent ( $tpl , $block );
if ( $block -> append ) {
if ( $block -> callsChild || ! isset ( $block -> child ) ||
( $block -> child -> hide && ! isset ( $block -> child -> child ))
) {
2016-07-19 03:37:01 +02:00
$this -> callBlock ( $block , $tpl );
2016-05-10 03:54:56 +02:00
} else {
$this -> process ( $tpl , $block -> child , $block );
}
}
}
$block -> parent = null ;
}
/**
2017-10-12 08:21:12 +02:00
* Render child on $smarty . block . child
2016-05-10 03:54:56 +02:00
*
* @ param \Smarty_Internal_Template $tpl
* @ param \Smarty_Internal_Block $block
2017-10-12 08:21:12 +02:00
* @ param boolean $returnContent flag if content shall be returned
*
2017-10-26 10:25:41 +02:00
* @ return null | string null or block content dependent on $returnContent
* @ throws \SmartyException
2016-05-10 03:54:56 +02:00
*/
2017-10-12 08:21:12 +02:00
public function callChild ( Smarty_Internal_Template $tpl , Smarty_Internal_Block $block , $returnContent = false )
2016-05-10 03:54:56 +02:00
{
2017-10-12 08:21:12 +02:00
if ( $returnContent ) {
ob_start ();
}
2016-05-10 03:54:56 +02:00
if ( isset ( $block -> child )) {
$this -> process ( $tpl , $block -> child , $block );
}
2017-10-12 08:21:12 +02:00
if ( $returnContent ) {
return ob_get_clean ();
}
return ;
2016-05-10 03:54:56 +02:00
}
/**
2017-11-06 01:02:56 +01:00
* Render parent block on $smarty . block . parent or { block append / prepend }
2016-05-10 03:54:56 +02:00
*
* @ param \Smarty_Internal_Template $tpl
* @ param \Smarty_Internal_Block $block
2017-10-12 08:21:12 +02:00
* @ param null | string $name
* @ param boolean $returnContent flag if content shall be returned
2016-05-10 03:54:56 +02:00
*
2017-10-12 08:21:12 +02:00
* @ return null | string null or block content dependent on $returnContent
2016-05-10 03:54:56 +02:00
* @ throws \SmartyException
*/
2017-10-12 08:21:12 +02:00
public function callParent ( Smarty_Internal_Template $tpl ,
Smarty_Internal_Block $block ,
$name = null ,
$returnContent = false )
2016-05-10 03:54:56 +02:00
{
2017-10-12 08:21:12 +02:00
if ( $returnContent ) {
ob_start ();
}
2016-09-29 04:22:20 +02:00
if ( isset ( $name )) {
$block = $block -> parent ;
while ( isset ( $block )) {
if ( isset ( $block -> subBlocks [ $name ])) {
} else {
$block = $block -> parent ;
}
}
return ;
} else if ( isset ( $block -> parent )) {
2016-07-19 03:37:01 +02:00
$this -> callBlock ( $block -> parent , $tpl );
2016-05-10 03:54:56 +02:00
} else {
2017-10-12 08:21:12 +02:00
throw new SmartyException ( " inheritance: illegal ' \$ smarty.block.parent' or { block append/prepend} used in parent template ' { $tpl -> inheritance -> sources [ $block -> tplIndex ] -> filepath } ' block ' { $block -> name } ' " );
}
if ( $returnContent ) {
return ob_get_clean ();
2016-05-10 03:54:56 +02:00
}
2017-10-12 08:21:12 +02:00
return ;
2016-05-10 03:54:56 +02:00
}
2016-04-24 11:04:36 +02:00
/**
2017-10-12 08:21:12 +02:00
* redender block
*
2016-07-19 03:37:01 +02:00
* @ param \Smarty_Internal_Block $block
* @ param \Smarty_Internal_Template $tpl
2016-04-24 11:04:36 +02:00
*/
2016-07-19 03:37:01 +02:00
public function callBlock ( Smarty_Internal_Block $block , Smarty_Internal_Template $tpl )
2016-04-24 11:04:36 +02:00
{
2016-07-19 03:37:01 +02:00
$this -> sourceStack [] = $tpl -> source ;
$tpl -> source = $this -> sources [ $block -> tplIndex ];
$block -> callBlock ( $tpl );
$tpl -> source = array_pop ( $this -> sourceStack );
2016-04-24 11:04:36 +02:00
}
2015-10-18 04:46:05 +02:00
}