<?php
/**
 * 数据标签类
 * @copyright reginx.com
 * $Id$
 */
class block{
    
    /**
     * 标签内容 安全检查
     *
     * @param unknown_type $str
     * @return unknown
     */
    public static function secchk($str){
        return !preg_match('/(\;|system|eval|unset|unlink|exec|save|del|replace)/i' , str_replace('&#039;' , '\'' , htmlspecialchars_decode($str , ENT_QUOTES)));
    }

    /**
     * 模板
     *
     * @var unknown_type
     */
    public static $tpl = "    public function get%s(%s){
            \$key = 'block#' . md5('tag-%s-' . func_num_args() . (strval(isset(\$param0)?\$param0 : 'reginx')));
            \$ret = \$GLOBALS['_CACHE']->get(\$key);
            if(empty(\$ret) || IS_DEBUG){
                \$ret = %s;
                if(!empty(\$ret)){
                    \$GLOBALS['_CACHE']->set(\$key , \$ret , %d);
                }
            }
            return \$ret;\r\n    }";



    /**
     * 默认调用
     *
     * @param unknown_type $p0
     * @param unknown_type $p1
     */
    public function __call($p0 , $p1){
        core::error(LANG('no-block' , $p0) , 'block' , 1 );
    }

    /**
     * 获取标签运行时对象
     *
     * @return unknown
     */
    public final static function getobj(){
        static $obj = null;
        if(empty($obj)){
            $blockfile = CACHE_PATH . '~block.php';
            if(!file_exists($blockfile)){
                self::mklist();
            }
            include_once($blockfile);
            $obj = new block_runtime();
        }
        return $obj;
    }
    
    /**
     * 缓存更新
     *
     */
    public final static function rebuild(){
        $blockfile = CACHE_PATH . '~block.php';
        if(file_exists($blockfile)){
            unlink($blockfile);
        }
        self::mklist();
    }

    /**
     * 生成 block 文件列表
     *
     */
    private final static function mklist(){
        $str  = '<?php' . PHP_EOL .'/** ' . PHP_EOL .' * block tag list'. PHP_EOL;
        $str .= ' * @copright ReGinx.Com'. PHP_EOL;
        $str .= ' * ' . PHP_EOL;
        $str .= ' */' . PHP_EOL;
        $str .= 'class block_runtime extends block{' . PHP_EOL;
        $str .= '}' . PHP_EOL . '?>';
        $blockfile = CACHE_PATH . '~block.php';
        $obj = OBJ('block_tab');
        $query = $obj->exec("select * from block_tab order by adate asc");
        while($row = db_extra::getobj()->fetch_array($query)){
            $pre  = '/*------------- block ' . $row['skey'] . ' --------------------*/';
            $suf  = '/*------------- end ' . $row['skey'] . ' --------------------*/';
            $str  = preg_replace('/\s*' . preg_quote($pre, '/') .'.+?' . preg_quote($suf, '/')  .'/is' , '' , $str);
            $code = str_replace('&#039;' , '\'' , htmlspecialchars_decode($row['extra'] , ENT_QUOTES));
            $code = str_replace(array("\r", "\r\n", "\n") , '' , $code);
            if(substr($code , -1) == ';'){
                $code = substr($code , 0 , strlen($code) - 1);
            }
            $mts  = array();
            preg_match_all('/\{?\$(\d+)\}?/' , $code , $mts);
            $paramstr = '';
            if(isset($mts[0]) && !empty($mts[0])){
                $nums = array_unique($mts[1]);
                rsort($nums);
                foreach ($nums as $k => $v){
                    $code = str_replace('$' . $v , '$param' . $v , $code);
                    $paramstr = empty($paramstr) ? ('$param' . $v . ' = \'\'') : ('$param' . $v . ' = \'\' , ' . $paramstr);
                }
            }
            $tpl  = '    ' . $pre . PHP_EOL;
            $tpl .= sprintf(self::$tpl , $row['skey'] , $paramstr , $row['skey'] , $code , $row['ttl']) . PHP_EOL;
            $tpl .= '    '.$suf;
            $str  = str_replace('class block_runtime extends block{' , 'class block_runtime extends block{' .PHP_EOL . $tpl , $str);
        }
        file_put_contents($blockfile , $str , LOCK_EX);
        $str = null; unset($str);
    }
}
?>