state == 3 && (strpos($tpl->template_resource, 'extendsall') === false)) { $tpl->inheritance = new Smarty_Internal_Runtime_Inheritance(); $tpl->inheritance->init($tpl, $initChild, $blockNames); return; } $this->tplIndex ++; $this->sources[ $this->tplIndex ] = $tpl->source; // start of child sub template(s) if ($initChild) { $this->state = 1; if (!$this->inheritanceLevel) { //grab any output of child templates ob_start(); } $this->inheritanceLevel ++; // $tpl->startRenderCallbacks[ 'inheritance' ] = array($this, 'subTemplateStart'); // $tpl->endRenderCallbacks[ 'inheritance' ] = array($this, 'subTemplateEnd'); } // 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 * @param null|string $template optional name of inheritance parent template * @param null|string $uid uid of inline template * @param null|string $func function call name of inline template */ public function endChild(Smarty_Internal_Template $tpl, $template = null, $uid = null, $func = null) { $this->inheritanceLevel --; if (!$this->inheritanceLevel) { ob_end_clean(); $this->state = 2; } 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); } } /** * Smarty_Internal_Block constructor. * - if outer level {block} of child template ($state == 1) save it as child root block * - 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 */ public function instanceBlock(Smarty_Internal_Template $tpl, $className, $name, $tplIndex = null) { $block = new $className($name, isset($tplIndex) ? $tplIndex : $this->tplIndex); if (isset($this->childRoot[ $name ])) { $block->child = $this->childRoot[ $name ]; } if ($this->state == 1) { $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 */ public function process(Smarty_Internal_Template $tpl, Smarty_Internal_Block $block, 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))) { $this->callBlock($block, $tpl); } 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)) ) { $this->callBlock($block, $tpl); } else { $this->process($tpl, $block->child, $block); } } } $block->parent = null; } /** * Render child on {$smarty.block.child} * * @param \Smarty_Internal_Template $tpl * @param \Smarty_Internal_Block $block */ public function callChild(Smarty_Internal_Template $tpl, Smarty_Internal_Block $block) { if (isset($block->child)) { $this->process($tpl, $block->child, $block); } } /** * Render parent on {$smarty.block.parent} or {block append/prepend} * * * @param \Smarty_Internal_Template $tpl * @param \Smarty_Internal_Block $block * * @param null $name * * @throws \SmartyException */ public function callParent(Smarty_Internal_Template $tpl, Smarty_Internal_Block $block, $name = null) { if (isset($name)) { $block = $block->parent; while (isset($block)) { if (isset($block->subBlocks[ $name ])) { } else { $block = $block->parent; } } return; } else if (isset($block->parent)) { $this->callBlock($block->parent, $tpl); } else { 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}'"); } } /** * @param \Smarty_Internal_Block $block * @param \Smarty_Internal_Template $tpl */ public function callBlock(Smarty_Internal_Block $block, Smarty_Internal_Template $tpl) { $this->sourceStack[] = $tpl->source; $tpl->source = $this->sources[ $block->tplIndex ]; $block->callBlock($tpl); $tpl->source = array_pop($this->sourceStack); } }