<?php

/*
*	Copyright VeryIDE,2007-2010
*	http://www.veryide.com/
*
*	系统及模块缓存处理
*
*	$Id: cache.php,v2.0 12:25 2010-4-18 Lay $
*/

class Cached{

	public static function direct( $appid ){		
		return VI_ROOT.'cache/'.$appid.'/';		
	}
	
	public static function delete( $appid, $file ){		
		return unlink( self :: direct( $appid ) . $file );		
	}

	/*
		加载缓存
		$appid	目录名称
		$file		文件名称，不包括扩展名
		$url		不存在缓存时跳转的URL
	*/
	public static function loader( $appid, $file, $url="" ){
		global $_G;
		global $_CACHE;

		if( $appid ){
			$cache = VI_ROOT.$_G['project']['cache'].$appid."/".$file.".php";
		}else{
			$cache = VI_ROOT.$_G['project']['cache'].$file.".php";
		}

		if( file_exists($cache) ){
			require($cache);		
			return true;
			
		}elseif( $url ){
			
			if (strrpos($url,"=")>0 || strrpos($url,"%3d")>0){
				$url.="&jump=".GetCurUrl();
			}else{
				$url.="?jump=".GetCurUrl();
			}
			
			header("Location:".VI_BASE."veryide.error.php?action=cache&cache=".($id ? $file."/".$id : $file)."&url=".urlencode($url));
		}else{
			return false;
		}
        }
        
        /*
                缓存查询至JavaScript                
                $appid		模块ID
                $sql		查询语句
                $var		变量名
                $file		缓存文件名
                $option		选项模板
        */
        public static function script( $appid, $sql, $var, $file, $option = array() ){
                global $_G;
                
                //解码
                $option['entity'] = $option['entity'] ? $option['entity'] : array();
                
                //解码
                $option['unicode'] = $option['unicode'] ? $option['unicode'] : array();
                
                //记录
                $option['record'] = $option['record'];
                
                /////////////////////////

                //创建变量	
                $cache = "var $var=[];\n";
                
                //查询数据                
                $data = System :: $db -> getAll( $sql );

                foreach( $data as $row ){
                        
                        $temp = $option['record'];		
                        $temp = str_replace("#var",$var,$temp);
                        
                        foreach ($row as $key => $value) {
                                
                                // JSON 解码
                                if( in_array( $key, $option['entity'] ) ){                                        
                                        $temp = str_replace("{table:". $key ."}", entity_encode($value,$_G['product']['charset']), $temp );                                        
                                }elseif( in_array( $key, $option['unicode'] ) ){	// JSON 解码                                
                                        $temp = str_replace("{table:". $key ."}", unicode_encode($value,$_G['product']['charset'],'\u',''), $temp );                                        
                                }else{
                                        $temp = str_replace("{table:". $key ."}",$value,$temp);
                                }
                                
                        }
                        
                        $cache .= $temp;
                        
                        //函数处理
                        $cache = self :: exec_eval($cache);
                }
                
                //写入缓存
                create_file( self :: direct( $appid ) . str_replace(array('sys.','mod.'),array('script.','script.'),$file).".js", $cache );
        }

        /*
                缓存多条数据记录	
                $appid		模块ID
                $sql		        查询语句
                $file		        缓存名称
                $option		配置选项
        */
        public static function multi( $appid, $sql, $file, $option = array() ){
                global $_G;
                
		//别名
                $table = $option['alias'] ? $option['alias'] : self :: table_name( $sql );
                
                $quey = self :: table_query( $sql );
                
                $cache='<?php'.chr(13);
                $cache.=' /*'.date("Y-m-t H:i:s").'*/ '.chr(13);
                
                $data = System :: $db -> getAll( $quey );
                
                //忽略空数据
                //if( empty( $data ) ) return false;
                
                foreach( $data as $row ){                        
                        $cache.='$_CACHE[\''.$appid.'\'][\''.$table.'\'][\''.$row['id'].'\'] = ';
                        $cache .= self :: format( $row, $option );
                }
                
                $cache.="?>";
                
                //写入缓存
                create_file( self :: direct( $appid ) . $file.".php", $cache);
        }

        /*
                缓存单条数据记录                
                $appid		模块ID
                $sql		        查询语句
                $option		配置选项
        */
        public static function rows( $appid, $sql, $option = array() ){
                global $_G;          
                                
                $table = self :: table_name( $sql );
                
                $quey = self :: table_query( $sql );
                
                $data = System :: $db -> getAll( $quey );
               
                foreach( $data as $row ){
                        
                        $cache ='<?php'.chr(13);
                        $cache.=' /*'.date("Y-m-t H:i:s").'*/ '.chr(13);
                        $cache.='$_CACHE[\''.$appid.'\'][\''.$table.'\']=';
                        
                        //$n = 1;
                        //$temp=$option;
                        
                        //
                        $cache .= self :: format( $row, $option );
                        
                        /*
                        foreach ($row as $key => $value) {
                                //$temp  = str_replace("{table:". $key ."}",$value,$temp);
                                //$cache .= '"'.$key.'" => '.'"'.str_replace('$','\$',addslashes($value)).'"'.($n!=count($row)?',':'');
                                
                                // JSON 解码
                                if( in_array( $key, $option['jsonde'] ) ){
                                        $cache .= "'".$key."' => ". var_export( fix_json( $value ), true );
                                }else{
                                        $cache .= "'".$key."' => '".str_replace('$','\$',addslashes($value))."'";
                                }
                                
                                $cache .= ($n!=count($row)?',':'');
                                
                                $n++;
                        }
                        
                        //$items .= $temp;
                        
                        $cache.=");".chr(13).chr(13);
                        */
                        
                        $cache.="?>";
                        
                        //写入缓存
                        create_file( self :: direct( $appid ) . $table.'.'.$row['id'].'.php', $cache );
                }
        }

        /*
                缓存整张数据表
                $appid		模块ID
                $mysql		数据库连接
                $table		表名
                $option		选项模板
                $sort		排序方式
                $index		索引键
        */
        public static function table( $appid, $table, $option = array() ){
                global $_G;
                
                //排序
                $option['order'] = $option['order'] ? $option['order'] : '';
                
                //主键
                $option['index'] = $option['index'] ? $option['index'] : 'id';
                        
                /////////////////////////
                
                $sql="SELECT * FROM `$table`";
                
                if( $option['order'] ){
                        $sql.=" ORDER BY ".$option['order'];
                }else{
                        $sql.=" ORDER BY ".$option['index'];
                }
                
                $table = self :: table_name( $sql );
                
                $quey = self :: table_query( $sql );
                
                $cache ='<?php'.chr(13);
                $cache.=' /*'.date("Y-m-t H:i:s").'*/ '.chr(13);									 
                
                $x = 1;
                
                $data = System :: $db -> getAll( $quey );
                
                foreach( $data as $row ){
                        
                        $cache.='	$_CACHE[\''.$appid.'\'][\''.$table.'\'][\''.$row[ $option['index'] ].'\'] = ';

                        $cache .= self :: format( $row, $option );

                }
                
                $cache.="?>";
                
                //写入缓存
                create_file(  self :: direct( $appid ) . 'table.'.$table.'.php', $cache );
        }
        
        /*
                格式化数据集
                $row           数据行
                $option         配置选项
        */
        public static function format( $row, $option ){
        
                //解码
                $option['jsonde'] = $option['jsonde'] ? $option['jsonde'] : array();
                
                //分隔
                $option['split'] = $option['split'] ? $option['split'] : array();	
                
                //解码
                $option['serialize'] = $option['serialize'] ? $option['serialize'] : array();
                
                ///////////////////////////////
                        
                $cache.="array(".chr(13);
                
                $n = 1;
                foreach ($row as $key => $value) {
                        
                        // JSON 解码
                        if( in_array( $key, $option['jsonde'] ) ){
                                $cache .= "'".$key."' => ". var_export( fix_json( $value ), true );
                                
                        }elseif( in_array( $key, $option['split'] ) ){
                                
                                $cache .= "'".$key."' => ". var_export( explode( ',', $value ), true );
                                
                        }elseif( in_array( $key, $option['serialize'] ) ){	// JSON 解码
                        
                                $cache .= "'".$key."' => ". var_export( unserialize( $value ), true );
                                
                        }else{
                                $cache .= "'".$key."' => '".str_replace('$','\$',addslashes($value))."'";
                        }
                        
                        $cache .= ($n!=count($row)?',':'');
                        
                        $n++;
                }
                
                $cache.=');'.($x<$rows?',':'').chr(13).chr(13);                        
                $x++;
                
                return $cache;

        }
        
        /////////////////////////////////

        /*
                缓存页面查询
                $mysql		数据库连接
                $sql		查询语句
                $temp		缓存模板
                $time		缓存有效期，分钟
                $debug		调试模式
        */
        public static function query( $sql, $time, $temp='', $debug=false ){
                global $_G;

                // 创建目录
                $base = create_dir( VI_ROOT.$_G['project']['cache']."sql/" );

                // 缓存地址
                $file = $base .md5( $sql.$temp ). ".php";
                
                //检查缓存是否有效
                if( !file_exists($file) || time() - filemtime( $file ) >= ( $time*60 ) ){
                        $action = true;
                }else{
                        $action = false;
                        $cache = unserialize( file_get_contents($file) );
                }
                
                //////////////////////
                
                //更新缓存
                if( $action ){
                
                        $cache = System :: $db -> getAll( $sql );
                        
                        //保存缓存
                        if( !$debug ){
                                create_file( $file, serialize( $cache ) );
                        }

                }
                
                //////////////////////
                
                //编译模板
                if( $temp && $cache ){
                        
                        $i = 1;
                        $content = '';
                        
                        foreach( $cache as $row ){
                        
                                $tmp = $temp;			
                                foreach ($row as $key => $value) {
                                   $tmp=str_replace("{table:". $key ."}",$value,$tmp);
                                }
                                
                                //index
                                $tmp=str_replace("{table:#}",$i,$tmp);			
                                $content .= $tmp;
                                
                                $i++;
                        }
                        
                        //函数处理
                        return self :: exec_eval( $content );
                        
                }
                
                return $cache;
        }

        /*
                对字符进行函数格式化                
                $str	模板	
                        DEMO	{fun:urlencode("{#t_name}"):end}
        */
        public static function exec_eval($str){
                preg_match_all("{fun:([\S\s]+?):end}", $str, $matches,PREG_SET_ORDER);	
                
                for( $i=0; $i<count($matches); $i++ ){
                        
                        $tmp_str = '{'.$matches[$i][0].'}';
                        $tmp_val = eval('return '.$matches[$i][1].';');
                        
                        $str = str_replace($tmp_str,$tmp_val,$str);
                        
                }
                return $str;
        }
        
        /*
                将查询中的变量转换
                $sql    查询语句
        */
        public static function table_query( $sql ){
                
                $sql = str_replace('mod:',VI_DBMODPRE,$sql);
                $sql = str_replace('sys:',VI_DBMANPRE,$sql);
                
                return $sql;
                
        }
        
        /*
                提取查询中的数据表名
                $sql    查询语句
        */
        public static function table_name( $sql ){
                
                $pat = '/SELECT(.*?)FROM `(.*?)`/i';
                preg_match ( $pat, $sql, $match );
                
                if( empty( $match ) ){
                        return str_replace( 'table.', '', $sql );                        
                }else{                        
                        return str_replace( array('sys:','mod:','table.'), array('','',''), $match[2] );
                }
        }
        
        /////////////////////////////////
        
        /*
                生成表单结构缓存
                $list			列表
                $appid		模块ID
        */
        function form( $appid, $list ){
                global $_G;
		
                $sql="SELECT * FROM `mod:form` WHERE appid='".$appid."' ";
                
                //读取表单信息
                $list && $sql .=" and id in(".$list.")";
                        
                //创建子文件夹
                $folder = create_dir( self :: direct( $appid ) );
                
                $result = System :: $db -> getAll( $sql );

                foreach( $result as $row ){
                        
                        $file = $folder."/form.".$row['id'].".php";
                        
                        $cache ='<?php'.chr(13);
                        $cache.='/*'.date("Y-m-t H:i:s").'*/'.chr(13);
                        
                        /********表单主体********/                        
                        $cache.='$_CACHE[\''.$appid.'\'][\'form\'] = array('.chr(13);
                        
                        $n = 1;
                        foreach ($row as $key => $value) {
                                
                                // JSON 解码
                                if( $key == 'config' ){
                                        $cache .= "'".$key."' => ". var_export( fix_json( $value ), true );
                                }else{
                                        $cache .= "'".$key."' => '".str_replace('$','\$',addslashes($value))."'";
                                }
                                
                                $cache .= ($n!=count($row)?',':'');
                                
                                $n++;
                        }
                        $cache.=");".chr(13).chr(13);
                        
                        /********选项组********/

                        $sql="SELECT * FROM `mod:group` WHERE fid=".$row['id']." and `state`>0 order BY sort asc,id asc";
                        
                        $groups = System :: $db -> getAll( $sql );
                        $rows = count($groups);
                        
                        $cache.='$_CACHE[\''.$appid.'\'][\'group\'] = array('.chr(13);
                                                                                                                                        
                        $x = 1;
                        foreach( $groups as $group ){
                                
                                $cache.='	"'.$group["id"].'" => array('.chr(13);
                                
                                $n = 1;
                                foreach ($group as $key => $value) {
                                        
                                        // JSON 解码
                                        if( $key == 'config' ){
                                                $cache .= "'".$key."' => ". var_export( fix_json( $value ), true );
                                        }else{
                                                $cache .= "'".$key."' => '".str_replace('$','\$',addslashes($value))."'";
                                        }
                                        
                                        $cache .= ($n!=count($group)?',':'');
                                        
                                        $n++;
                                }
                                
                                $cache.=')'.($x<$rows?',':'').chr(13).chr(13);
                                $x++;
                        }
                        $cache.=");".chr(13).chr(13);
                        
                        /********子选项********/
                
                        $sql="SELECT * FROM `mod:option` WHERE fid=".$row['id']." and `state`>0 order BY sort asc,id asc";
                        
                        $options = System :: $db -> getAll( $sql );
                        $rows = count($options);
                        
                        ///////////

                        foreach( $options as $option ){
                                
                                $cache.='$_CACHE[\''.$appid.'\'][\'option\'][\''.$option["gid"].'\'][\''.$option["id"].'\'] = array('.chr(13);
                                
                                $n = 1;
                                foreach ($option as $key => $value) {
                                        
                                        // JSON 解码
                                        if( $key == 'config' ){
                                                $cache .= "'".$key."' => ". var_export( fix_json( $value ), true );
                                        }else{
                                                $cache .= "'".$key."' => '".str_replace('$','\$',addslashes($value))."'";
                                        }
                                        
                                        $cache .= ($n!=count($option)?',':'');
                                        
                                        $n++;
                                }
                                $cache.=');'.chr(13);
                        }
                        
                        /*
                        $cache.='$_CACHE[\''.$appid.'\'][\'option\'] = array('.chr(13);
                                                                                                                                         
                        $x = 1;
                        foreach( $options as $option ){
                                
                                $cache.='	"'.$option["id"].'" => array('.chr(13);
                                
                                $n = 1;
                                foreach ($option as $key => $value) {
                                        
                                        // JSON 解码
                                        if( $key == 'config' ){
                                                $cache .= "'".$key."' => ". var_export( fix_json( $value ), true );
                                        }else{
                                                $cache .= "'".$key."' => '".str_replace('$','\$',addslashes($value))."'";
                                        }
                                        
                                        $cache .= ($n!=count($option)?',':'');
                                        
                                        $n++;
                                }
                                $cache.=')'.($x<$rows?',':'').chr(13).chr(13);
                                $x++;
                        }
                
                        $cache.=");".chr(13).chr(13);
                        */
                        $cache.="?>";
                        
                        $cache = str_replace($item,str_replace('),',')',$item),$cache);
                        
                        //写入缓存
                        create_file($file,$cache);
                }
        }
        
}

?>