<?php
namespace imcat;

//缓存类
class extCache{

    protected 
$cache = NULL;
    
    function 
__construct($ucfg=array()) {
        
$cfg = glbConfig::read('cache', 'ex');
        if(!empty(
$ucfg)){
            
$cfg = array_merge($cfg, $ucfg);
        }
        
$driver = $cfg['type'];
        
$class = "\\imcat\\$driver";
        require_once 
DIR_IMCAT . '/adpt/cache/' . $driver . '.php';
        
$this->cache = new $class($cfg);
    }

    
//读取缓存
    
function get($key) {
        return 
$this->cache->get($key);   
    }
    
    
//设置缓存
    
function set($key, $value, $expire=1800) {
        return 
$this->cache->set($key, $value, $expire);
    }
    
    
//自增1
    
function inc($key, $value = 1) {
        return 
$this->cache->inc($key, $value);    
    }
    
    
//自减1
    
function des($key, $value = 1) {
        return 
$this->cache->des($key, $value);    
    }
    
    
//删除
    
function del($key) {
        return 
$this->cache->del($key);
    }
    
    
//清空缓存
    
function clear() {
        return 
$this->cache->clear();    
    }

    
// static-functions

    // cache-time : 30s,60m,12h,7d,4w,12M; 默认单位(m)min
    
static function CTime($ctime=30){ 
        if(
is_numeric($ctime) || strpos($ctime,'m')){
            
$ctime = intval($ctime)*60; 
        }elseif(
strpos($ctime,'h')){
            
$ctime = intval($ctime)*3600;
        }elseif(
strpos($ctime,'d')){
            
$ctime = intval($ctime)*86400;
        }elseif(
strpos($ctime,'w')){
            
$ctime = intval($ctime)*86400*7;
        }elseif(
strpos($ctime,'M')){ // 30天
            
$ctime = intval($ctime)*86400*30;
        }else{ 
            
$ctime = intval($ctime);
        }
        
$ctime<300 && $ctime = 86400; //最小300s
        
return $ctime;
    }
    
// cache-path, dir: /12/34/ab 
    
static function CPath($sKey, $mkdir=0, $base=''){
        
$file = $sKey; $kmd5 = md5($sKey); $aDir = array();
        for(
$i=0;$i<5;$i=$i+2){ $aDir[] = substr($kmd5,$i,2); }
        if(
$mkdir){
            
$base = $base ? $base : DIR_DTMP.'/cache';
            foreach(array(
0,1,2) as $k){
                
$tmp = $base.'/'.$aDir[$k];
                if(!
is_dir($tmp)){
                    
$flag = mkdir($tmp); // , 0666, 0777
                    
if(!$flag) return false;
                }
                
$base = $tmp;
            }
        }
        
$file = self::fName($file);
        
$dir = '/'.implode('/', $aDir);
        return array(
'dir'=>$dir, 'file'=>$file);
    }

    
// cache-file-set: Set,Get
    
static function cfSet($file, $data, $bdir='dtmp'){
        if(
is_array($data)) $data = json_encode($data);
        
comFiles::chkDirs($file, $bdir);
        
$bdir = comStore::cfgDirPath($bdir);
        
comFiles::put($bdir.$file, $data);
    }
    
// cache-file-get: re: 0=fp,str,arr,
    
static function cfGet($file, $ctime=30, $bdir='dtmp', $re=0){ 
        
$ctime = extCache::CTime($ctime);
        
$bdir = comStore::cfgDirPath($bdir);
        if(
file_exists($bdir.$file)){
            
$last = filemtime($bdir.$file);
            if(
$last + $ctime > $_SERVER["REQUEST_TIME"]){
                if(empty(
$re)) return $bdir.$file;  
                
$data = comFiles::get($bdir.$file);
                if(
$re=='str') return $data;
                if(empty(
$data) || is_numeric($data)) return $data;
                if(
substr($data,0,2)=='{"' || substr($data,0,1)=='"'){
                    
$data = json_decode($data, 1);
                }
                return 
$data;
            }
        }
        return 
false;
    }

    
// token-set:
    
static function tkSet($kid, $token, $exp='1d'){
        
$db = glbDBObj::dbObj();
        
$stamp = $_SERVER["REQUEST_TIME"];
        
$exp = $exp ? $stamp + extCache::CTime($exp) : 0;
        if(!empty(
$token)){
            if(
is_array($token)) $token = json_encode($token);
            
$data = array('token'=>$token,'exp'=>$exp);
        }else{ 
// empty:clear
            
$data = array('token'=>'','exp'=>$stamp-86400);
        }
        
$data['etime'] = $stamp;
        
$db->table("token_store")->data($data)->where("kid='$kid'")->update(0);
    }
    
// token-get:
    
static function tkGet($kid, $exp=1){
        
$db = glbDBObj::dbObj();
        
$stamp = $_SERVER["REQUEST_TIME"];
        
$row = $db->table("token_store")->where("kid='$kid'")->find();
        if(
$row){ 
            
$token = $row['token'];
            
$exp && $token = $row['exp']>=$stamp ? $token : '';
            if(empty(
$token) || is_numeric($token)) return $token;
            if(
substr($token,0,2)=='{"' || substr($token,0,1)=='"'){
                
$token = json_decode($token,1);
            }
            return 
$token;
        }else{
            
$data = array('kid'=>$kid,'token'=>'','exp'=>0,'etime'=>$stamp);
            
$db->table("token_store")->data($data)->insert(0);
            return 
'';
        }
    }

    static function 
fName($file, $max=90, $cut=70, $cnchar=1){
        if(
$cnchar){
            
$file = preg_replace_callback("/([\x{4e00}-\x{9fa5}]+)/u", function($matches){ 
                return 
urlencode($matches[1]);
            }, 
$file);
        }
        
$file = preg_replace("/https?\:\/\//i", '', $file);
        
$tb1 = ['/', '?', '&', '%', '#', '*', '|', ':'];
        
$tb2 = ['~', '@', '~', '^', '@', '.', '!', '.']; 
        
$tb3 = ['"', "'", '\\', '<', '>', '!', '+'];
        
// 《!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~》// All:32
        
$file = str_replace($tb1, $tb2, $file);
        
$file = str_replace($tb3, '', $file);
        
$file = preg_replace("/\s/", '', $file);
        if(
$max>$cut && strlen($file)>$max) $file = substr($file,0,$cut).'---'.md5($file);
        return 
$file;
    }

}