<?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();
}
}
}
/*
*/