Seditio Source
Root |
./othercms/dotclear-2.22/inc/libs/clearbricks/template/class.tplnodeblockdef.php
<?php
/**
 * @class tplNodeBlockDefinition
 * @brief Block node, for all <tpl:Tag>...</tpl:Tag>
 *
 * @package Clearbricks
 * @subpackage Template
 *
 * @copyright Olivier Meunier & Association Dotclear
 * @copyright GPL-2.0-only
 */
class tplNodeBlockDefinition extends tplNodeBlock
{
    protected static
$stack         = [];
    protected static
$current_block = null;
    protected static
$c             = 1;

    protected
$name;

   
/**
     * Renders the parent block of currently being displayed block
     * @param  template $tpl the current template engine instance
     * @return string      the compiled parent block
     */
   
public static function renderParent(template $tpl)
    {
        return
self::getStackBlock(self::$current_block, $tpl);
    }

   
/**
     * resets blocks stack
     */
   
public static function reset()
    {
       
self::$stack         = [];
       
self::$current_block = null;
    }

   
/**
     * Retrieves block defined in call stack
     * @param  string $name the block name
     * @param  template $tpl  the template engine instance
     * @return string       the block (empty string if unavailable)
     */
   
public static function getStackBlock(string $name, template $tpl)
    {
       
$stack = &self::$stack[$name];
       
$pos   = $stack['pos'];
       
// First check if block position is correct
       
if (isset($stack['blocks'][$pos])) {
           
$saved_current_block = self::$current_block;
           
self::$current_block = $name;
            if (!
is_string($stack['blocks'][$pos])) {
               
// Not a string ==> need to compile the tree

                // Go deeper 1 level in stack, to enable calls to parent
               
$stack['pos']++;
               
$ret = '';
               
// Compile each and every children
               
foreach ($stack['blocks'][$pos] as $child) {
                   
$ret .= $child->compile($tpl);
                }
               
$stack['pos']--;
               
$stack['blocks'][$pos] = $ret;
            } else {
               
// Already compiled, nice ! Simply return string
               
$ret = $stack['blocks'][$pos];
            }

            return
$ret;
        }
       
// Not found => return empty
       
return '';
    }

   
/**
     * Block definition specific constructor : keep block name in mind
     * @param string $tag  Current tag (might be "Block")
     * @param array $attr Tag attributes (must contain "name" attribute)
     */
   
public function __construct(string $tag, array $attr)
    {
       
parent::__construct($tag, $attr);
       
$this->name = '';
        if (isset(
$attr['name'])) {
           
$this->name = $attr['name'];
        }
    }

   
/**
     * Override tag closing processing. Here we enrich the block stack to
     * keep block history.
     */
   
public function setClosing()
    {
        if (!isset(
self::$stack[$this->name])) {
           
self::$stack[$this->name] = [
               
'pos'    => 0, // pos is the pointer to the current block being rendered
               
'blocks' => [], ];
        }
       
parent::setClosing();
       
self::$stack[$this->name]['blocks'][] = $this->children;
       
$this->children                       = new ArrayObject();
    }

   
/**
     * Compile the block definition : grab latest block content being defined
     * @param  template $tpl current template engine instance
     * @return string      the compiled block
     */
   
public function compile(template $tpl): string
   
{
        return
$tpl->compileBlockNode(
           
$this->tag,
           
$this->attr,
           
self::getStackBlock($this->name, $tpl)
        );
    }
}