vendor/smarty/smarty/libs/sysplugins/smarty_internal_runtime_inheritance.php line 142

  1. <?php
  2. /**
  3.  * Inheritance Runtime Methods processBlock, endChild, init
  4.  *
  5.  * @package    Smarty
  6.  * @subpackage PluginsInternal
  7.  * @author     Uwe Tews
  8.  **/
  9. class Smarty_Internal_Runtime_Inheritance
  10. {
  11.     /**
  12.      * State machine
  13.      * - 0 idle next extends will create a new inheritance tree
  14.      * - 1 processing child template
  15.      * - 2 wait for next inheritance template
  16.      * - 3 assume parent template, if child will loaded goto state 1
  17.      *     a call to a sub template resets the state to 0
  18.      *
  19.      * @var int
  20.      */
  21.     public $state 0;
  22.     /**
  23.      * Array of root child {block} objects
  24.      *
  25.      * @var Smarty_Internal_Block[]
  26.      */
  27.     public $childRoot = array();
  28.     /**
  29.      * inheritance template nesting level
  30.      *
  31.      * @var int
  32.      */
  33.     public $inheritanceLevel 0;
  34.     /**
  35.      * inheritance template index
  36.      *
  37.      * @var int
  38.      */
  39.     public $tplIndex = -1;
  40.     /**
  41.      * Array of template source objects
  42.      *
  43.      * @var Smarty_Template_Source[]
  44.      */
  45.     public $sources = array();
  46.     /**
  47.      * Stack of source objects while executing block code
  48.      *
  49.      * @var Smarty_Template_Source[]
  50.      */
  51.     public $sourceStack = array();
  52.     /**
  53.      * Initialize inheritance
  54.      *
  55.      * @param \Smarty_Internal_Template $tpl        template object of caller
  56.      * @param bool                      $initChild  if true init for child template
  57.      * @param array                     $blockNames outer level block name
  58.      */
  59.     public function init(Smarty_Internal_Template $tpl$initChild$blockNames = array())
  60.     {
  61.         // if called while executing parent template it must be a sub-template with new inheritance root
  62.         if ($initChild && $this->state === && (strpos($tpl->template_resource'extendsall') === false)) {
  63.             $tpl->inheritance = new Smarty_Internal_Runtime_Inheritance();
  64.             $tpl->inheritance->init($tpl$initChild$blockNames);
  65.             return;
  66.         }
  67.         ++$this->tplIndex;
  68.         $this->sources$this->tplIndex ] = $tpl->source;
  69.         // start of child sub template(s)
  70.         if ($initChild) {
  71.             $this->state 1;
  72.             if (!$this->inheritanceLevel) {
  73.                 //grab any output of child templates
  74.                 ob_start();
  75.             }
  76.             ++$this->inheritanceLevel;
  77.             //           $tpl->startRenderCallbacks[ 'inheritance' ] = array($this, 'subTemplateStart');
  78.             //           $tpl->endRenderCallbacks[ 'inheritance' ] = array($this, 'subTemplateEnd');
  79.         }
  80.         // if state was waiting for parent change state to parent
  81.         if ($this->state === 2) {
  82.             $this->state 3;
  83.         }
  84.     }
  85.     /**
  86.      * End of child template(s)
  87.      * - if outer level is reached flush output buffer and switch to wait for parent template state
  88.      *
  89.      * @param \Smarty_Internal_Template $tpl
  90.      * @param null|string               $template optional name of inheritance parent template
  91.      * @param null|string               $uid      uid of inline template
  92.      * @param null|string               $func     function call name of inline template
  93.      *
  94.      * @throws \Exception
  95.      * @throws \SmartyException
  96.      */
  97.     public function endChild(Smarty_Internal_Template $tpl$template null$uid null$func null)
  98.     {
  99.         --$this->inheritanceLevel;
  100.         if (!$this->inheritanceLevel) {
  101.             ob_end_clean();
  102.             $this->state 2;
  103.         }
  104.         if (isset($template) && (($tpl->parent->_isTplObj() && $tpl->parent->source->type !== 'extends')
  105.                                  || $tpl->smarty->extends_recursion)
  106.         ) {
  107.             $tpl->_subTemplateRender(
  108.                 $template,
  109.                 $tpl->cache_id,
  110.                 $tpl->compile_id,
  111.                 $tpl->caching 9999 0,
  112.                 $tpl->cache_lifetime,
  113.                 array(),
  114.                 2,
  115.                 false,
  116.                 $uid,
  117.                 $func
  118.             );
  119.         }
  120.     }
  121.     /**
  122.      * Smarty_Internal_Block constructor.
  123.      * - if outer level {block} of child template ($state === 1) save it as child root block
  124.      * - otherwise process inheritance and render
  125.      *
  126.      * @param \Smarty_Internal_Template $tpl
  127.      * @param                           $className
  128.      * @param string                    $name
  129.      * @param int|null                  $tplIndex index of outer level {block} if nested
  130.      *
  131.      * @throws \SmartyException
  132.      */
  133.     public function instanceBlock(Smarty_Internal_Template $tpl$className$name$tplIndex null)
  134.     {
  135.         $block = new $className($name, isset($tplIndex) ? $tplIndex $this->tplIndex);
  136.         if (isset($this->childRoot$name ])) {
  137.             $block->child $this->childRoot$name ];
  138.         }
  139.         if ($this->state === 1) {
  140.             $this->childRoot$name ] = $block;
  141.             return;
  142.         }
  143.         // make sure we got child block of child template of current block
  144.         while ($block->child && $block->child->child && $block->tplIndex <= $block->child->tplIndex) {
  145.             $block->child $block->child->child;
  146.         }
  147.         $this->process($tpl$block);
  148.     }
  149.     /**
  150.      * Goto child block or render this
  151.      *
  152.      * @param \Smarty_Internal_Template   $tpl
  153.      * @param \Smarty_Internal_Block      $block
  154.      * @param \Smarty_Internal_Block|null $parent
  155.      *
  156.      * @throws \SmartyException
  157.      */
  158.     public function process(
  159.         Smarty_Internal_Template $tpl,
  160.         Smarty_Internal_Block $block,
  161.         Smarty_Internal_Block $parent null
  162.     ) {
  163.         if ($block->hide && !isset($block->child)) {
  164.             return;
  165.         }
  166.         if (isset($block->child) && $block->child->hide && !isset($block->child->child)) {
  167.             $block->child null;
  168.         }
  169.         $block->parent $parent;
  170.         if ($block->append && !$block->prepend && isset($parent)) {
  171.             $this->callParent($tpl$block'\'{block append}\'');
  172.         }
  173.         if ($block->callsChild || !isset($block->child) || ($block->child->hide && !isset($block->child->child))) {
  174.             $this->callBlock($block$tpl);
  175.         } else {
  176.             $this->process($tpl$block->child$block);
  177.         }
  178.         if ($block->prepend && isset($parent)) {
  179.             $this->callParent($tpl$block'{block prepend}');
  180.             if ($block->append) {
  181.                 if ($block->callsChild || !isset($block->child)
  182.                     || ($block->child->hide && !isset($block->child->child))
  183.                 ) {
  184.                     $this->callBlock($block$tpl);
  185.                 } else {
  186.                     $this->process($tpl$block->child$block);
  187.                 }
  188.             }
  189.         }
  190.         $block->parent null;
  191.     }
  192.     /**
  193.      * Render child on \$smarty.block.child
  194.      *
  195.      * @param \Smarty_Internal_Template $tpl
  196.      * @param \Smarty_Internal_Block    $block
  197.      *
  198.      * @return null|string block content
  199.      * @throws \SmartyException
  200.      */
  201.     public function callChild(Smarty_Internal_Template $tplSmarty_Internal_Block $block)
  202.     {
  203.         if (isset($block->child)) {
  204.             $this->process($tpl$block->child$block);
  205.         }
  206.     }
  207.     /**
  208.      * Render parent block on \$smarty.block.parent or {block append/prepend}
  209.      *
  210.      * @param \Smarty_Internal_Template $tpl
  211.      * @param \Smarty_Internal_Block    $block
  212.      * @param string                    $tag
  213.      *
  214.      * @return null|string  block content
  215.      * @throws \SmartyException
  216.      */
  217.     public function callParent(Smarty_Internal_Template $tplSmarty_Internal_Block $block$tag)
  218.     {
  219.         if (isset($block->parent)) {
  220.             $this->callBlock($block->parent$tpl);
  221.         } else {
  222.             throw new SmartyException("inheritance: illegal '{$tag}' used in child template '{$tpl->inheritance->sources[$block->tplIndex]->filepath}' block '{$block->name}'");
  223.         }
  224.     }
  225.     /**
  226.      * render block
  227.      *
  228.      * @param \Smarty_Internal_Block    $block
  229.      * @param \Smarty_Internal_Template $tpl
  230.      */
  231.     public function callBlock(Smarty_Internal_Block $blockSmarty_Internal_Template $tpl)
  232.     {
  233.         $this->sourceStack[] = $tpl->source;
  234.         $tpl->source $this->sources$block->tplIndex ];
  235.         $block->callBlock($tpl);
  236.         $tpl->source array_pop($this->sourceStack);
  237.     }
  238. }