Вход Регистрация
Файл: framework/web/renderers/CPradoViewRenderer.php
Строк: 273
<?php
/**
 * CPradoViewRenderer class file.
 *
 * @author Steve Heyns http://customgothic.com/
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @link http://www.yiiframework.com/
 * @copyright 2008-2013 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

/**
 * CPradoViewRenderer implements a view renderer that allows users to use a template syntax similar to PRADO templates.
 *
 * To use CPradoViewRenderer, configure it as an application component named "viewRenderer" in the application configuration:
 * <pre>
 * array(
 *     'components'=>array(
 *         ......
 *         'viewRenderer'=>array(
 *             'class'=>'CPradoViewRenderer',
 *         ),
 *     ),
 * )
 * </pre>
 *
 * CPradoViewRenderer allows you to write view files with the following syntax:
 * <pre>
 * // PHP tags:
 * <%= expression %>
 * // <?php echo expression ?>
 * <% statement %>
 * // <?php statement ?></li>
 *
 * // component tags:
 * <com:WigetClass name1="value1" name2='value2' name3={value3} >
 * // <?php $this->beginWidget('WigetClass',
 * // array('name1'=>"value1", 'name2'=>'value2', 'name3'=>value3)); ?>
 * </com:WigetClass >
 * // <?php $this->endWidget('WigetClass'); ?>
 * <com:WigetClass name1="value1" name2='value2' name3={value3} />
 * // <?php $this->widget('WigetClass',
 * // array('name1'=>"value1", 'name2'=>'value2', 'name3'=>value3)); ?>
 *
 * // cache tags:
 * <cache:fragmentID name1="value1" name2='value2' name3={value3} >
 * // <?php if($this->beginCache('fragmentID',
 * // array('name1'=>"value1", 'name2'=>'value2', 'name3'=>value3))): ?>
 * </cache:fragmentID >
 * // <?php $this->endCache('fragmentID'); endif; ?>
 *
 * // clip tags:
 * <clip:clipID >
 * // <?php $this->beginClip('clipID'); ?>
 * </clip:clipID >
 * // <?php $this->endClip('clipID'); ?>
 *
 * // comment tags:
 * <!--- comments --->
 * // the whole tag will be stripped off
 * </pre>
 *
 * @author Steve Heyns http://customgothic.com/
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @package system.web.renderers
 * @since 1.0
 */
class CPradoViewRenderer extends CViewRenderer
{
    private 
$_input;
    private 
$_output;
    private 
$_sourceFile;

    
/**
     * Parses the source view file and saves the results as another file.
     * This method is required by the parent class.
     * @param string $sourceFile the source view file path
     * @param string $viewFile the resulting view file path
     */
    
protected function generateViewFile($sourceFile,$viewFile)
    {
        static 
$regexRules=array(
            
'<%=?s*(.*?)s*%>',        // PHP statements or expressions
            
'</?(com|cache|clip):([w.]+)s*((?:s*w+s*=s*'.*?(?<!\\)'|s*w+s*=s*".*?(?<!\\)"|s*w+s*=s*{.*?})*)s*/?>'// component tags
            
'<!---.*?--->',    // template comments
        
);
        
$this->_sourceFile=$sourceFile;
        
$this->_input=file_get_contents($sourceFile);
        
$n=preg_match_all('/'.implode('|',$regexRules).'/msS',$this->_input,$matches,PREG_SET_ORDER|PREG_OFFSET_CAPTURE);
        
$textStart=0;
        
$this->_output="<?php /* source file: $sourceFile */ ?>n";
        for(
$i=0;$i<$n;++$i)
        {
            
$match=&$matches[$i];
            
$str=$match[0][0];
            
$matchStart=$match[0][1];
            
$matchEnd=$matchStart+strlen($str)-1;

            if(
$matchStart>$textStart)
                
$this->_output.=substr($this->_input,$textStart,$matchStart-$textStart);
            
$textStart=$matchEnd+1;

            if(
strpos($str,'<com:')===0)    // opening component tag
            
{
                
$type=$match[3][0];
                if(
$str[strlen($str)-2]!=='/')  // open tag
                    
$this->_output.=$this->processBeginWidget($type,$match[4][0],$match[2][1]);
                else
                    
$this->_output.=$this->processWidget($type,$match[4][0],$match[2][1]);
            }
            elseif(
strpos($str,'</com:')===0)    // closing component tag
                
$this->_output.=$this->processEndWidget($match[3][0],$match[2][1]);
            elseif(
strpos($str,'<cache:')===0)    // opening cache tag
            
{
                
$id=$match[3][0];
                if(
$str[strlen($str)-2]!=='/')  // open tag
                    
$this->_output.=$this->processBeginCache($id,$match[4][0],$match[2][1]);
                else
                    
$this->_output.=$this->processCache($id,$match[4][0],$match[2][1]);
            }
            elseif(
strpos($str,'</cache:')===0)    // closing cache tag
                
$this->_output.=$this->processEndCache($match[3][0],$match[2][1]);
            elseif(
strpos($str,'<clip:')===0)    // opening clip tag
            
{
                
$id=$match[3][0];
                if(
$str[strlen($str)-2]!=='/')  // open tag
                    
$this->_output.=$this->processBeginClip($id,$match[4][0],$match[2][1]);
                else
                    
$this->_output.=$this->processClip($id,$match[4][0],$match[2][1]);
            }
            elseif(
strpos($str,'</clip:')===0)    // closing clip tag
                
$this->_output.=$this->processEndClip($match[3][0],$match[2][1]);
            elseif(
strpos($str,'<%=')===0)    // expression
                
$this->_output.=$this->processExpression($match[1][0],$match[1][1]);
            elseif(
strpos($str,'<%')===0)    // statement
                
$this->_output.=$this->processStatement($match[1][0],$match[1][1]);
        }
        if(
$textStart<strlen($this->_input))
            
$this->_output.=substr($this->_input,$textStart);

        
file_put_contents($viewFile,$this->_output);
    }

    
/*
     * @param string $type type
     * @param string $attributes attributes
     * @param string $offset offset
     */
    
private function processWidget($type,$attributes,$offset)
    {
        
$attrs=$this->processAttributes($attributes);
        if(empty(
$attrs))
            return 
$this->generatePhpCode("$this->widget('$type');",$offset);
        else
            return 
$this->generatePhpCode("$this->widget('$type', array($attrs));",$offset);
    }

    
/*
     * @param string $type type
     * @param string $attributes attributes
     * @param string $offset offset
     */
    
private function processBeginWidget($type,$attributes,$offset)
    {
        
$attrs=$this->processAttributes($attributes);
        if(empty(
$attrs))
            return 
$this->generatePhpCode("$this->beginWidget('$type');",$offset);
        else
            return 
$this->generatePhpCode("$this->beginWidget('$type', array($attrs));",$offset);
    }

    
/*
     * @param string $type type
     * @param string $offset offset
     */
    
private function processEndWidget($type,$offset)
    {
        return 
$this->generatePhpCode("$this->endWidget('$type');",$offset);
    }

    
/*
     * @param string $id id
     * @param string $attributes attributes
     * @param string $offset offset
     */
    
private function processCache($id,$attributes,$offset)
    {
        return 
$this->processBeginCache($id,$attributes,$offset) . $this->processEndCache($id,$offset);
    }

    
/*
     * @param string $id id
     * @param string $attributes attributes
     * @param string $offset offset
     */
    
private function processBeginCache($id,$attributes,$offset)
    {
        
$attrs=$this->processAttributes($attributes);
        if(empty(
$attrs))
            return 
$this->generatePhpCode("if($this->beginCache('$id')):",$offset);
        else
            return 
$this->generatePhpCode("if($this->beginCache('$id', array($attrs))):",$offset);
    }

    
/*
     * @param string $id id
     * @param string $offset offset
     */
    
private function processEndCache($id,$offset)
    {
        return 
$this->generatePhpCode("$this->endCache('$id'); endif;",$offset);
    }

    
/*
     * @param string $id id
     * @param string $attributes attributes
     * @param string $offset offset
     */
    
private function processClip($id,$attributes,$offset)
    {
        return 
$this->processBeginClip($id,$attributes,$offset) . $this->processEndClip($id,$offset);
    }

    
/*
     * @param string $id id
     * @param string $attributes attributes
     * @param string $offset offset
     */
    
private function processBeginClip($id,$attributes,$offset)
    {
        
$attrs=$this->processAttributes($attributes);
        if(empty(
$attrs))
            return 
$this->generatePhpCode("$this->beginClip('$id');",$offset);
        else
            return 
$this->generatePhpCode("$this->beginClip('$id', array($attrs));",$offset);
    }

    
/*
     * @param string $id id
     * @param string $offset offset
     */
    
private function processEndClip($id,$offset)
    {
        return 
$this->generatePhpCode("$this->endClip('$id');",$offset);
    }

    
/*
     * @param string $expression expression
     * @param string $offset offset
     */
    
private function processExpression($expression,$offset)
    {
        return 
$this->generatePhpCode('echo '.$expression,$offset);
    }

    
/*
     * @param string $statement statement
     * @param string $offset offset
     */
    
private function processStatement($statement,$offset)
    {
        return 
$this->generatePhpCode($statement,$offset);
    }

    
/*
     * @param string $code code
     * @param string $offset offset
     */
    
private function generatePhpCode($code,$offset)
    {
        
$line=$this->getLineNumber($offset);
        
$code=str_replace('__FILE__',var_export($this->_sourceFile,true),$code);
        return 
"<?php /* line $line */ $code ?>";
    }

    
/*
     * @param string $str str
     */
    
private function processAttributes($str)
    {
        static 
$pattern='/(w+)s*=s*('.*?(?<!\\)'|".*?(?<!\\)"|{.*?})/msS';
        
$attributes=array();
        
$n=preg_match_all($pattern,$str,$matches,PREG_SET_ORDER);
        for(
$i=0;$i<$n;++$i)
        {
            
$match=&$matches[$i];
            
$name=$match[1];
            
$value=$match[2];
            if(
$value[0]==='{')
                
$attributes[]="'$name'=>".str_replace('__FILE__',$this->_sourceFile,substr($value,1,-1));
            else
                
$attributes[]="'$name'=>$value";
        }
        return 
implode(', ',$attributes);
    }

    
/*
     * @param string $offset offset
     */
    
private function getLineNumber($offset)
    {
        return 
count(explode("n",substr($this->_input,0,$offset)));
    }
}
Онлайн: 2
Реклама