<?php
/* * *********************************************************
 * [cml] (C)2012 - 3000 cml http://linhecheng.com
 * @Author  linhecheng<linhechengbush@live.com>
 * @Date: 13-6-26 上午11:23
 * @version  1.0 
 * cml框架 URL解析类
 * *********************************************************** */

defined('CML_PATH') || exit();

class CmlRoute
{
	/**
	 * 解析url
	 *
	 * @return void
	 */
	public static function parseUrl()
	{
		$urlModel = C('URL_MODEL');
		if($urlModel === 1 || $urlModel === 2) { //pathinfo模式(含显示、隐藏index.php两种)SCRIPT_NAME
			$requestUri = preg_replace('/(.*)\/(.*)\.php(.*)/i', '\\1\\3', $_SERVER['REQUEST_URI']);
			$scriptName =  preg_replace('/(.*)\/(.*)\.php/i', '\\1', $_SERVER['SCRIPT_NAME']);
			$requestUri = ltrim($requestUri, '?'.C('VAR_PATHINFO').'=');
			if(!empty($scriptName)) {
				$hasParam = strpos($requestUri, $scriptName);
				$param = ltrim(substr($requestUri, $hasParam + strlen($scriptName)), '/');
			} else {
				$param = ltrim($requestUri, '/');
			}

			if(!empty($param)) { //无参数时直接跳过取默认操作
				//获取参数
				$pathinfo = explode(C('URL_PATHINFO_DEPR'), trim(preg_replace(array('/\\'.C('URL_HTML_SUFFIX').'/', '/\&.*/', '/\?.*/'), '',  $param), C('URL_PATHINFO_DEPR')));
				//检测路由
				if(C('URL_ROUTER_ON')) {
					$isRoute = self::isRoute($pathinfo);
					if($isRoute[0]) {//匹配路由成功
						$routeArr = explode('/', $isRoute['route']);
						if(C('APP_MODULE')) {//开启分模块
							$_GET[C('VAR_MODULE')] = $routeArr[0];
							array_shift($routeArr);
						}
						$_GET[C('VAR_CONTROLLER')] = $routeArr[0];
						array_shift($routeArr);
						$_GET[C('VAR_ACTION')] = $routeArr[0];
						unset($routeArr);
					}
				}
				if(!isset($isRoute) || !$isRoute[0]) { //未开启路由 || 未匹配到路由
					if(C('APP_MODULE')) {//获取模块
						isset($pathinfo[0]) && $_GET[C('VAR_MODULE')] = $pathinfo[0];
						array_shift($pathinfo);
					}
					//获取控制器
					isset($pathinfo[0]) && $_GET[C('VAR_CONTROLLER')] = $pathinfo[0];
					array_shift($pathinfo);

					//获取action
					isset($pathinfo[0]) && $_GET[C('VAR_ACTION')] = $pathinfo[0];
					array_shift($pathinfo);

					for($i = 0; $i < count($pathinfo); $i += 2) {
						$_GET[$pathinfo[$i]] = $pathinfo[$i + 1];
					}
				}
			}
		} else if($urlModel === 3 && isset($_GET[C('VAR_PATHINFO')])) {//兼容模式
			$urlString = $_GET[C('VAR_PATHINFO')];
			unset($_GET);
			$urlArr = explode(C('URL_PATHINFO_DEPR'), trim(str_replace(C('URL_HTML_SUFFIX'), '', ltrim($urlString, '/')), C('URL_PATHINFO_DEPR')));

			if(C('APP_MODULE')) {//开启分模块
				$_GET[C('VAR_MODULE')] = $urlArr[0];
				array_shift($urlArr);               
			}
			isset($urlArr[0]) && $_GET[C('VAR_CONTROLLER')] = $urlArr[0];
			array_shift($urlArr);    

			isset($urlArr[0]) && $_GET[C('VAR_ACTION')] = $urlArr[0];
			array_shift($urlArr);

			for($i = 0; $i < count($urlArr); $i += 2) {
				$_GET[$urlArr[$i]] = $urlArr[$i + 1];
			}	 
		}

		$isCli = isset($_SERVER['argc']) ? true : false; //是否为命令行访问
		$isCli && array_shift($_SERVER['argv']);
		if(C('APP_MODULE') && !isset($_GET[C('VAR_MODULE')])) {//开启分模块
			if($isCli && isset($_SERVER['argv'][0])) {
				$_GET[C('VAR_MODULE')] = $_SERVER['argv'][0];
				array_shift($_SERVER['argv']);
			} else {
				$_GET[C('VAR_MODULE')] = C('URL_DEFAULT_MODULE'); //默认模块
			}
		}
		if(!isset($_GET[C('VAR_CONTROLLER')])) {
			if($isCli && isset($_SERVER['argv'][0])) {
				$_GET[C('VAR_CONTROLLER')] = $_SERVER['argv'][0];
				array_shift($_SERVER['argv']);
			} else {
				$_GET[C('VAR_CONTROLLER')] = C('URL_DEFAULT_CONTROLLER'); //默认控制器
			}
		}
		if(!isset($_GET[C('VAR_ACTION')])) {
			if($isCli && isset($_SERVER['argv'][0])) {
				$_GET[C('VAR_ACTION')] = $_SERVER['argv'][0];
				array_shift($_SERVER['argv']);
			} else {
				$_GET[C('VAR_ACTION')] = C('URL_DEFAULT_ACTION');// 默认操作
			}
		}

		C('URL_CASE_INSENSITIVE') && self::parseGet(); //url不区分大小写

		//定义URL常量
		$spath=dirname($_SERVER['SCRIPT_NAME']);
		if($spath == '/' || $spath == '\\') {$spath = '';}
		//定义项目根目录地址
		define('__ROOT__', $spath);
		// 当前项目地址
		define('__APP__', ($urlModel === 2) ? '' : strip_tags($_SERVER['SCRIPT_NAME'])); //为 ''或'index.php'

		if($urlModel === 3) {
			$deper = '?'.C('VAR_PATHINFO').'=/';
		} else if($urlModel === 0) {
			$deper = '?';
		} else {
			$deper = '/';
		}        

		$urlPathInfoDeper = $urlModel === 0 ?  '&' : C('URL_PATHINFO_DEPR'); //多个参数之间的分隔符

		//当前模块地址
		C('APP_MODULE') && define('__MODULE__', $urlModel === 0 ? __APP__.$deper.C('VAR_MODULE').'='.$_GET[C('VAR_MODULE')] : __APP__.$deper.$_GET[C('VAR_MODULE')]);
		$addModule = C('APP_MODULE') ? $urlModel === 0 ? C('VAR_MODULE').'='.$_GET[C('VAR_MODULE')].$urlPathInfoDeper : $_GET[C('VAR_MODULE')].$urlPathInfoDeper : '';
		// 当前控制器地址
		define('__CONTROLLER__', $urlModel === 0 ? __APP__.$deper.$addModule.C('VAR_CONTROLLER').'='.$_GET[C('VAR_CONTROLLER')] : __APP__.$deper.$addModule.$_GET[C('VAR_CONTROLLER')]);
		// 当前操作地址
		define('__ACTION__', $urlModel === 0 ? __CONTROLLER__.$urlPathInfoDeper.C('VAR_ACTION').'='.$_GET[C('VAR_ACTION')] : __CONTROLLER__.$urlPathInfoDeper.$_GET[C('VAR_ACTION')]);
		//当前url
		define('__SELF__', strip_tags($_SERVER['REQUEST_URI']));
		//项目public目录
		define('__PUBLIC__', __ROOT__.'/Public');

		define('CML_APP_NAME', trim(APP_PATH)); //当前应用常量
		C('APP_MODULE') && define('CML_MODULE_NAME',  $_GET[C('VAR_MODULE')]);//当前模块常量
		define('CML_CONTROLLER_NAME', $_GET[C('VAR_CONTROLLER')]);//当前控制器常量
		define('CML_ACTION_NAME', $_GET[C('VAR_ACTION')]); //当前操作常量         
		$_REQUEST = array_merge($_REQUEST, $_GET);
	}


	/**
	 * url不区分大小写
	 *
	 * @return void
	 */
	public static function parseGet()
	{
		foreach ($_GET as $key => $val) {
			$_GET[$key] = strtolower($val);
		}      
	}

	/**
	 * 匹配路由
	 *
	 * @param $pathinfo
	 *
	 * @return mixed
	 */
	public static function isRoute($pathinfo)
	{
		$issuccess = array();
		$route = C('URL_ROUTE_RULES');
		foreach($route as $k => $v) {
			unset($v);
			$arr = explode('/', $k); 
			if($arr[0] == $pathinfo[0]) {
				array_shift($arr);
				foreach($arr as $key => $val) {
					if(strpos($val, '\d')) { //数字变量
						if(isset($pathinfo[$key + 1]) && !is_numeric($pathinfo[$key + 1])) {
							$route[$k] = 0;//匹配失败
							break 1;
						}
					} else {
						if(!isset($pathinfo[$key + 1])) {
							$route[$k] = 0;//匹配失败
							break 1;
						}
					}                            
				}                       
			} else {
				$route[$k] = 0;//匹配失败
			}

			if($route[$k] !== 0) {//匹配成功的路由              
				$issuccess[] = $k;                
			}            
		}

		if(!empty($issuccess)) {  
			//匹配到多条路由时 选择最长的一条（匹配更精确）
			if(!function_exists('mySort')) {
				function mySrot($item1, $item2)
				{
					return strlen($item1) >= strlen($item2) ? 0 : 1; 
				}
			}        
			usort($issuccess, "mySrot");

			$returnArr[0] = 1;          
			$tmp = explode('/', $issuccess[0]);
			array_shift($tmp);
			foreach($tmp as $key => $val) { 
				$t = explode('\d', ltrim($val, ':'));
				$_GET[$t[0]] = isset($pathinfo[$key + 1]) ? $pathinfo[$key + 1] : false;
			}           
			$returnArr['route'] = $route[$issuccess[0]];
		} else {
			$returnArr[0] = 0;
		}
		return $returnArr;
	}
	
}