Вход Регистрация
Файл: engine/classes/Fenom/Tag.php
Строк: 268
<?php
/*
 * This file is part of Fenom.
 *
 * (c) 2013 Ivan Shalganov
 *
 * For the full copyright and license information, please view the license.md
 * file that was distributed with this source code.
 */
namespace Fenom;


class 
Tag extends ArrayObject
{
    const 
COMPILER 1;
    const 
FUNC     2;
    const 
BLOCK    4;


    const 
LTRIM 1;
    const 
RTRIM 2;

    
/**
     * @var Template
     */
    
public $tpl;
    public 
$name;
    public 
$options = array();
    public 
$line 0;
    public 
$level 0;
    public 
$callback;
    public 
$escape;

    private 
$_offset 0;
    private 
$_closed true;
    private 
$_body;
    private 
$_type 0;
    private 
$_open;
    private 
$_close;
    private 
$_tags = array();
    private 
$_floats = array();
    private 
$_changed = array();

    
/**
     * Create tag entity
     * @param string $name the tag name
     * @param Template $tpl current template
     * @param string $info tag's information
     * @param string $body template's code
     */
    
public function __construct($nameTemplate $tpl$info, &$body)
    {
        
$this->tpl     $tpl;
        
$this->name    $name;
        
$this->line    $tpl->getLine();
        
$this->level   $tpl->getStackSize();
        
$this->_body   = & $body;
        
$this->_offset strlen($body);
        
$this->_type   $info["type"];
        
$this->escape  $tpl->getOptions() & Fenom::AUTO_ESCAPE;

        if (
$this->_type self::BLOCK) {
            
$this->_open   $info["open"];
            
$this->_close  $info["close"];
            
$this->_tags   = isset($info["tags"]) ? $info["tags"] : array();
            
$this->_floats = isset($info["float_tags"]) ? $info["float_tags"] : array();
            
$this->_closed false;
        } else {
            
$this->_open $info["parser"];
        }

        if (
$this->_type self::FUNC) {
            
$this->callback $info["function"];
        }
    }

    
/**
     * Set tag option
     * @param string $option
     * @throws RuntimeException
     */
    
public function tagOption($option)
    {
        if (
method_exists($this'opt' $option)) {
            
$this->options[] = $option;
        } else {
            throw new 
RuntimeException("Unknown tag option $option");
        }
    }

    
/**
     * Rewrite template option for tag. When tag will be closed option will be reverted.
     * @param int $option option constant
     * @param bool $value true — add option, false — remove option
     */
    
public function setOption($option$value)
    {
        
$actual = (bool)($this->tpl->getOptions() & $option);
        if (
$actual != $value) {
            
$this->_changed[$option] = $actual;
            
$this->tpl->setOption(Fenom::AUTO_ESCAPE$value);
        }
    }

    
/**
     * Restore the option
     * @param int $option
     */
    
public function restore($option)
    {
        if (isset(
$this->_changed[$option])) {
            
$this->tpl->setOption($option$this->_changed[$option]);
            unset(
$this->_changed[$option]);
        }
    }

    public function 
restoreAll()
    {
        foreach (
$this->_changed as $option => $value) {
            
$this->tpl->setOption($option$this->_changed[$option]);
            unset(
$this->_changed[$option]);
        }
    }

    
/**
     * Check, if the tag closed
     * @return bool
     */
    
public function isClosed()
    {
        return 
$this->_closed;
    }

    
/**
     * Open callback
     *
     * @param Tokenizer $tokenizer
     * @return mixed
     */
    
public function start($tokenizer)
    {
        foreach (
$this->options as $option) {
            
$option 'opt' $option;
            
$this->$option();
        }
        return 
call_user_func($this->_open$tokenizer$this);
    }

    
/**
     * Check, has the block this tag
     *
     * @param string $tag
     * @param int $level
     * @return bool
     */
    
public function hasTag($tag$level)
    {
        if (isset(
$this->_tags[$tag])) {
            if (
$level) {
                return isset(
$this->_floats[$tag]);
            } else {
                return 
true;
            }
        }
        return 
false;
    }


    
/**
     * Call tag callback
     *
     * @param string $tag
     * @param Tokenizer $tokenizer
     * @throws LogicException
     * @return string
     */
    
public function tag($tag$tokenizer)
    {
        if (isset(
$this->_tags[$tag])) {
            return 
call_user_func($this->_tags[$tag], $tokenizer$this);
        } else {
            throw new 
LogicException("The block tag {$this->name} no have tag {$tag}");
        }
    }

    
/**
     * Close callback
     *
     * @param Tokenizer $tokenizer
     * @throws LogicException
     * @return string
     */
    
public function end($tokenizer)
    {
        if (
$this->_closed) {
            throw new 
LogicException("Tag {$this->name} already closed");
        }
        if (
$this->_close) {
            foreach (
$this->options as $option) {
                
$option 'opt' $option 'end';
                if (
method_exists($this$option)) {
                    
$this->$option();
                }
            }
            
$code call_user_func($this->_close$tokenizer$this);
            
$this->restoreAll();
            return 
$code;
        } else {
            throw new 
LogicException("Can not use a inline tag {$this->name} as a block");
        }
    }

    
/**
     * Forcefully close the tag
     */
    
public function close()
    {
        
$this->_closed true;
    }

    
/**
     * Return content of block
     *
     * @throws LogicException
     * @return string
     */
    
public function getContent()
    {
        return 
substr($this->_body$this->_offset);
    }

    
/**
     * Cut scope content
     *
     * @return string
     * @throws LogicException
     */
    
public function cutContent()
    {
        
$content     substr($this->_body$this->_offset 1);
        
$this->_body substr($this->_body0$this->_offset);
        return 
$content;
    }

    
/**
     * Replace scope content
     *
     * @param $new_content
     */
    
public function replaceContent($new_content)
    {
        
$this->cutContent();
        
$this->_body .= $new_content;
    }

    
/**
     * Generate output code
     * @param string $code
     * @return string
     */
    
public function out($code)
    {
        return 
$this->tpl->out($code$this->escape);
    }

    
/**
     * Enable escape option for the tag
     */
    
public function optEscape()
    {
        
$this->escape true;
    }

    
/**
     * Disable escape option for the tag
     */
    
public function optRaw()
    {
        
$this->escape false;
    }

    
/**
     * Enable strip spaces option for the tag
     */
    
public function optStrip()
    {
        
$this->setOption(Fenom::AUTO_STRIPtrue);
    }

    
/**
     * Enable ignore for body of the tag
     */
    
public function optIgnore()
    {
        if(!
$this->isClosed()) {
            
$this->tpl->ignore($this->name);
        }
    }
}
Онлайн: 1
Реклама