<?php
namespace imcat;

// Url 类
class vopUrl{    
    
    static 
$params = array('mkv','mod','key','view','type','hcfg','vcfg');
    static 
$keepmk = array('c','d','m','t','u','mhome','mtype','detail'); // mext

    // get/url初始mkv数据
    
static function iget(){
        
$re = self::route();
        
$mkv = $re[0]; $q = $re[1]; $ua = $re[2];
        
$re1 = preg_match("/^\w+(\-\-(so|list))?$/",$mkv); // modid, (--list)
        
$re2 = preg_match("/^\w+\-\w+\w*(\-\w+)?$/",$mkv); // modid-type, dop-a, (-v)
        
$re3 = preg_match("/^\w+\.[\w-]+(\.[\w-]+)?$/",$mkv); // mod.y-md-88, (-v)
        
if(!($re1 || $re2 || $re3)){
            
vopApp::msg("b:[$mkv]:".basLang::show('vop_parerr'));
        }
        
$re = array('q'=>$q, 'mkv'=>$mkv, 'ua'=>$ua);
        return 
$re;
    }
    
    
// mkv/mod初始分析
    
static function imkv($re, $remod=0){
        
$hcfg = glbConfig::vcfg('home');
        
$mkv = $re['mkv']; $type = ''; $vcfg = array();
        
// ?login -=>别名 ?uio-login // 都可访问
        
if(isset($hcfg[$mkv])){
            
$mkv = $re['mkv'] = "home-$mkv";
        }
        if(
strpos($mkv,'.')){ //mod.y-md-88.view
            
$a = explode('.',$mkv);
            
$type = 'detail';
        }elseif(
strpos($mkv,'-')){ //mod-type-view, --list, -awhua-v2
            
$a = explode('-',"$mkv"); 
            
$type = empty($a[1]) ? 'mext' : 'mtype';
        }else{ 
//mod
            
$a = array($mkv,'');    
            
$type = 'mhome';
        }
        if(
in_array($a[1],self::$keepmk)){
            
vopApp::msg("c:[$mkv]:".basLang::show('vop_parerr'));
        }
        
//$mod分析
        
$mod = $a[0]; $key = $a[1]; $view = empty($a[2]) ? '' : $a[2];
        if(
$remod) return $remod=='a' ? $a : $mod;
        foreach(
self::$params as $k) $re[$k] = $$k;
        return 
$re;
    }
    
    
// tpl/key分析
    
static function itpl($re){
        foreach(
self::$params as $k) $$k = $re[$k]; 
        
$dsub = $type; $cfg = "";
        if(
$type=='mtype'){
            
$dsub = $key;
            if(isset(
$vcfg[$key])){
                
$cfg = $vcfg[$key];
            }else{ 
                
$mcfg = glbConfig::read($mod);
                if(isset(
$mcfg['i'][$key])){
                    
$cfg = empty($vcfg['t']) ? '' : $vcfg['t'];
                    
$dsub = $type;
                }
            }
        }elseif(
$type=='detail'){
            
$cfg = empty($vcfg['d']) ? '' : $vcfg['d'];
            if(!empty(
$view) && isset($vcfg['d']['v'])){
                
$cfg[$view] = $vcfg['d']['v'];
            }
        }elseif(isset(
$vcfg['m'])){ // mext,mhome
            
$cfg = $vcfg['m'];
        }
        
$tpl = ($cfg && is_string($cfg)) ? $cfg : "$mod/$dsub";
        if(
$view){
            if(isset(
$cfg[$view])){
                
$tpl = $cfg[$view];
            }elseif(!
in_array($view,array('so','list'))){
                
$tpl = "$mod/$dsub-$view";
            }
        }else{
            if(
is_array($cfg) && isset($cfg[0])){ $tpl = $cfg[0]; }
        }
        
// 处理{mod}
        
$re['tplname'] = str_replace('{mod}',$mod,$tpl);
        return 
$re;
    }

    
// url分析
    
static function init(){
        
$re = self::iget();
        
$re = self::imkv($re);
        if(
$re['mkv']=='home'){
            
$re['vcfg'] = $re['hcfg'];
            
$re['tplname'] = $re['hcfg']['m'];
        }else{ 
            
$re['vcfg'] = glbConfig::vcfg($re['mod']); 
            if(
$re['type']=='mhome' && isset($re['vcfg']['m']) && $re['vcfg']['m']=='first')
                
self::ifirst($re['mod']); //first跳转
            
$re = self::itpl($re);
        }
        empty(
$re['hcfg']['u']) || $re['u'] = $re['hcfg']['u']; //自定义参数
        
$re['vcfg'] = isset($re['vcfg']['c']) ? $re['vcfg']['c'] : '';
        
$re['hcfg'] = $re['hcfg']['c'];
        return 
$re; 
    }
    
    static function 
ifirst($mod, $re=''){
        
$minfo = glbConfig::read($mod); 
        
$key = empty($minfo['i']) ? '' : key($minfo['i']); 
        if(
$re=='key'){
            return 
$key;
        }elseif(
defined('RUN_STATIC')){
            return 
"[301]-[$mod-$key]".basLang::show('core.vop_st301dir');
        }else{
            if(!
$key){
                
$url = "Error:[$mod-$key]";
            }else{
                
$url = self::fout("$mod-$key");
                
header("Location:$url");
            }
            die(
$url);
        }
    }

    
// url格式化输出, 处理静态,伪静态,url优化(只在前台或生成静态,后台用跳转...)
    // paras: array, string 
    
static function fout($mkv='', $type='', $host=0){ //,$ext=array()
        
if(strpos($mkv,':')) return self::gtpl($mkv, $type, $host);
        global 
$_cbase;
        
$tcfg = empty($_cbase['run']['tplcfg']) ? [] : $_cbase['run']['tplcfg'];
        
$burl = self::burl($host); 
        
//mkv分析
        
if(!$mkv) return self::bind($burl,$tcfg); //首页
        
$type || $type = strpos($mkv,'.') ? '.' : '-';
        
$a = explode($type,"$mkv$type$type");
        
$mod = $a[0]; $key = $a[1]; $view = $a[2];
        
$mcfg = glbConfig::vcfg($mod);
        
$vmode = @$mcfg['c']['vmode']; $url = '';
        if(empty(
$key) && empty($view) && isset($mcfg['m']) && $mcfg['m']=='first'){
            
$key = self::ifirst($mod,'key');
            
$mkv .= "-$key";
        }
        
//close,static
        
if($vmode=='close') return '#close#'.$mkv;
        if(
$vmode=='static'){
            
$vext = empty($view) ? '' : ".$view";
            
$ust = '/'.vopStatic::getPath($mod,$key.$vext,0);
            
$url = file_exists(DIR_HTML.$ust) ? PATH_HTML.$ust : '';
        }
        
//动态
        
if(empty($url)){
            
$url = $burl.'?'.$mkv;
            
// 处理伪静态
            
if(!empty($tcfg[2])){
                if(
$tcfg[2]=='?'){
                    
$url = str_replace('?', '/', $url);
                }else{
                    
$rp = empty($tcfg[4]) ? '.php?' : $tcfg[1].'?';
                    
$url = str_replace($rp, $tcfg[2], $url);
                }
            }
            if(!empty(
$tcfg[3])){ $url .= $tcfg[3]; }
        }
        
$url = self::bind($url,$tcfg);
        return 
$url;
    }
    
    
//base-url
    
static function burl($host=0){ 
        
$type = $host ? 1 : 0;
        
$burl = vopTpls::etr1($type);
        if(
$host){ $burl = (basEnv::isHttps() ? 'https:' : 'http:') . $burl; }
        return 
$burl;
    }
    
    
//还原root路径
    
static function root($val){
        
$re = comStore::revSaveDir($val);
        
$re = str_replace('{PATH_PROJ}',PATH_PROJ,$re);
        return 
$re;
    }
    
//指定分组(tpl)下的url
    
static function gtpl($str, $type='', $host=0){
        global 
$_cbase;
        
$tplold = $_cbase['tpl']['vdir'];
        
$a = explode(':',$str);
        
$a[0] && vopTpls::set($a[0]);
        
$path = self::fout($a[1], $type, $host);
        
$a[0] && vopTpls::set($tplold);
        return 
$path;
    }
    
//format指定mod下的第一个类别的url
    
static function f1st($mod, $re='(key)'){
        
$key = self::ifirst($mod, 'key');
        
$url = self::fout("$mod-$key");
        if(
$re) $url = str_replace(array("/$key.","-$key"),array("/$re.","-$re"),$url);
        return 
$url;
    }

    
// 绑定域名
    
static function bind($url, $tcfg=array()){
        global 
$_cbase;
        if(!empty(
$tcfg[5])){
            
$rfp = $tcfg[5]['0'];
            if(
substr($url,-1*strlen($rfp))==$rfp){
                
$url = str_replace($rfp,$tcfg[5]['1'],$url);
            }
        }
        
$binds = $_cbase['ucfg']['dbind']; 
        if(empty(
$binds)) return $url;
        
$na = glbConfig::read('dmbind','sy');
        if(empty(
$na)) return $url;
        foreach(
$na as $v){
            
$vbak = $v[0];
            
$v[0] = str_replace('{html}',PATH_HTML,$v[0]);
            if(empty(
$v[2])){
                
$url = str_replace($v[0],$v[1],$url);
            }else{ 
                if(
$v[2]==1){
                    
$v[0] = "/^".preg_quote($v[0],"/")."/i";
                    
$v[0] = str_replace(array("`d","`w","#`"),array("(\\d","(\\w","+)"),$v[0]);
                }else{ 
//自由写正则
                    
$v[0] = str_replace('{html}',preg_quote(PATH_HTML,"/"),"/^$vbak/i");
                }
                
$nurl = @preg_replace($v[0],$v[1],$url);
                
$url = $nurl ? $nurl : $url;    
            }
        }
        return 
$url;
    }

    
// mkv路由
    
static function route($def=''){
        global 
$_cbase;
        
$tcfg = empty($_cbase['run']['tplcfg']) ? [] : $_cbase['run']['tplcfg'];
        
$q = basEnv::serval('QUERY_STRING'); $mkv = '';
        if(!empty(
$_SERVER['PATH_INFO'])){
            
$mkv = substr($_SERVER['PATH_INFO'],1);
            if(!
$mkv){ 
                
vopApp::msg("a:[/]:".basLang::show('vop_parerr')); 
            }
        }elseif(!empty(
IS_CLI)){ // mob.php news--list stype:;keywd:php5.4
            
$mkv = empty($_SERVER['argv'][1]) ? '' : $_SERVER['argv'][1];
            
$q = empty($_SERVER['argv'][2]) ? '' : str_replace([':',';'], ['=','&'], $_SERVER['argv'][2]);
            
$_SERVER["REQUEST_URI"] = $_SERVER['argv'][0].'?'.$q;
            
$_SERVER['QUERY_STRING'] = $q; 
            
$q ? parse_str($q, $_GET) : $_GET=[]; 
        }else{
            
$tmp = explode('&', $q); 
            
$mkv = (empty($tmp[0])||preg_match("/^\w+\=[^\n]+/",$tmp[0])) ? ($def?$def:'home') : $tmp[0];
            if(!empty(
$tmp[1]) && $p=strpos($mkv,'=')){ // 'file.php?news=&p=wx', 修正分享参数
                
$uri = str_replace("?$tmp[0]&", "?".substr($tmp[0],0,$p)."&", $_SERVER["REQUEST_URI"]); 
                
header("Location:$uri"); 
                die(
"dir(1):`$q`");
            }
            if(!empty(
$tcfg[2]) && $tcfg[2]=='?'){ self::jumpr(); }
        }
        
// 去掉末尾的的`.htm`(伪静态)
        
if(!empty($tcfg[3])){ $mkv = str_replace($tcfg[3], '', $mkv); }
        
parse_str($q,$ua); //dump("$q, $mkv");
        
return [$mkv, $q, $ua];
    }

    
// 跳转: entry.php?mkv -=> entry.php/mkv
    // /?home-cn 未跳转
    
static function jumpr(){
        
$uri = $_SERVER["REQUEST_URI"];
        if(
preg_match("/(\.php|\/)\?([\w\-\.]{3,36})$/i",$uri)){ 
            
preg_match("/(\.php|\/)\?([\w\-\.]{3,36})$/i", $uri, $p);
            
$uf = $_SERVER["SCRIPT_NAME"];
            
header("Location:$uf/{$p[2]}"); 
            die();
        }
    }
}

/*

*/