<?php
/**
 *  uri解析类
 *
 * @author		xz
 * @version		1.0  addtime	2013-08-16
 * @copyright	www.house365.com
 */
include_once('rewrite.conf.php');

class UriRewrite{

	 public $uri_string;        //请求参数字符串
	 public $dir;               //资源定位符
	 public $dir_value;         //一级资源定位符对应值
	 public $domain;            //域名
	 public $uri_params;        //各频道用到的URI参数，在各频道的base.inc中
	 public $uri;               //当前请求URI参数
	 public $split_dir;         //目录分隔符
	 public $split_param;       //参数分隔符
     public $split_mulit_param; //多选参数分隔符
     public $analy_param;       //是否解析当前页面参数


	/*构造函数，初始化类
	* $unique_str	全局唯一标识码
	* $analy_param  是否解析当前页面URI参数
	* $split_dir    目录级别分隔符
	* $split_param  参数分隔符
	*/
	public function UriRewrite($unique_str,$analy_param=true,$city='',$split_arr = array('split_dir'=>'/','split_param'=>'_','split_mulit_param'=>'|'))
	{
		GLOBAL $conf_uri_params,$conf_city;//配置文件全局URI参数

		//设置频道服务器定位符
		$this->set_dir($conf_uri_params[$unique_str]['dir']);

         //设置是否解析当前页面参数
		$this->set_analy_param($analy_param);

		//设置请求URI
		$this->set_uri_string();

		//频道URL配置
		$this->set_uri_params($conf_uri_params[$unique_str]);

		//设置频道域名
		if(!$city) $city = $conf_city;
		$this->set_domain($conf_uri_params[$unique_str]['domain'],$city);

		//设置目录分隔符
		$this->set_split_dir($split_arr['split_dir']);

		//设置参数分隔符
		$this->set_split_param($split_arr['split_param']);

        $this->set_split_mulit_param($split_arr['split_mulit_param']);

		//初始化当前URI
		$this->init_uri();
	}


	//设置频道服务器定位符
	public function set_dir($dir)
	{
		$this->dir  = array();
		//DIR赋值
		for( $i = 0 ; $i < count($dir) ; $i++){
			$this->dir[$i]	= $dir[$i].'_';
		}
	}


	//获取服务器定位符
	public function get_dir()
	{
		return $this->dir;
	}


	//设置是否解析当前页面参数
	function set_analy_param($analy_param){
		$this->analy_param  = $analy_param;
	}

	//设置请求URI字符串uri_string
	public function set_uri_string ()
	{
		if($this->analy_param)
		{
			$this->uri_string= preg_replace('#^/|.html(.*)|/$#','',$_SERVER['REQUEST_URI']);
		}
        else
		{
			$this->uri_string	= '';
		}
	}


	//获取请求URI
	public function get_uri_string()
	{
		return $this->uri_string;
	}


	//频道URL配置
	public function set_uri_params($conf_uri_params)
	{
		$this->uri_params = array();

		if(!empty($conf_uri_params))
		{
			$this->uri_params = array_merge($this->uri_params,$conf_uri_params);
		}
	}


	//获取频道URL配置的数组
	public function get_uri_params()
	{
		return $this->uri_params;
	}


	//获取频道URL配置的反转数组
	public function get_uri_params_asc($key='param')
	{
        $uri_params = $this->get_uri_params();

		if(is_array($uri_params[$key])){
			$uri_params_asc =  array_flip($uri_params[$key]);
		}
        else
        {
			$uri_params_asc = array();
		}

		return $uri_params_asc;
	}


	//设置一级资源定位符的值，必须为整数
	public function set_dir_value($dir_value){

		$this->dir_value = intval($dir_value);
	}


	//设置目录分隔符
	public function set_split_dir($split)
	{
		$this->split_dir = trim(strip_tags($split));
	}


	//设置参数分隔符
	public function set_split_param($split)
	{
		$this->split_param = trim(strip_tags($split));
	}


	//多选参数分隔符
    public function  set_split_mulit_param($split)
        {
		$this->split_mulit_param = trim(strip_tags($split));
	}


	//获取目录分隔符
	public function get_split_dir()
	{
		return $this->split_dir;
	}


	//获取参数分隔符
	public function get_split_param()
	{
		return $this->split_param;
	}

        //获取多选参数分隔符
	public function get_split_mulit_param()
	{
		return $this->split_mulit_param;
	}


	//设置频道域名
	public function set_domain($domain,$city='hz')
	{
		if(in_array($domain,array('rent','sell')))
		{
			$this->domain = 'http://'.$city.'.'.strip_tags(trim($domain)).'.house365.com';
		}
		else
		{
			$this->domain = 'http://'.$city.'.sell.house365.com';
		}
	}


	//获得频道域名
	public function get_domain()
	{
		return $this->domain;
	}


	//获取当前页面的URI参数
	public function get_uri()
	{
		return $this->uri;
	}


	//根据key返回value
	public function getValueByName($name)
	{
		$uri = $this->uri;

		return $uri[strip_tags($name)];
	}


	/**
	 * 返回真实URI参数数组
	 *
	 * @return array
	**/
	private function init_uri()
	{
		$arguments = array();

		if(empty($this->uri_string))
		{
			return $arguments;
		}

		/**分割参数字符串，
		 * /xq_1538/esf_a1-b2-c3.html
		 * => array('0'=>'xq_1538','1'=>'esf_a1-b2-c3')
		**/
		$direct	= explode($this->split_dir,$this->uri_string);

		//目录级别-(1代表只有一级/，2代表有二级/)
		$direct_level	= count($direct);

		//循环解析每一级目录的参数
		for( $i = 0, $j = 0; $i < $direct_level ; $i++)
		{
			/**使用分隔符'_'，分离定位符与URI参数
			*	esf_a1-b2-c3
			*	=> array('0'=>'esf','1'=>'a1-b2-c3')
			**/
			$uri_child_arr	= explode($this->split_param,trim($direct[$i]));

			//如果分离后的数组的第二个元素不为空，则说明第一个元素为定位符
			if( !empty($uri_child_arr['1']))
			{
				//根据URI定位符重新赋值第($i+1)级目录标识符
				//$this->dir[$i]	= $uri_child_arr['0'].'_';

				//URI参数字符串
				$periods[$j]	= $uri_child_arr['1'];
                $j++;

				//如果第一个元素为纯数字，则代表为一级定位符的值。(根据现有规则执行，不太灵活)
				if($i == 0 && $this->is_num($uri_child_arr['1']))
				{
					$this->dir_value = $uri_child_arr['1'];
				}
			}
		}

		$len_prams = count($periods);

		//解析各级目录的子URI字母和数值
		for($i = 0 ; $i < $len_prams ; $i++)
		{
			$value	= trim($periods[$i]);

			//解析非空参数
			if(!empty($value))
			{
				$arguments	= array_merge($this->get_Parameters($value),$arguments);
			}

		}

		$this->uri	= $arguments;
	}


	/**
	 * 解析请求参数，获取页面原始的参数数组。
	 *
	 * @param none
	 * return array
	**/
	public function get_Parameters($str)
	{
		$arguments	= array();
		$periods	= explode('-',$str);

		//参数个数
		$periods_mum	= count($periods);

		if($periods_mum == 0)
		{
			return $arguments;
		}

		//分离参数和值
		foreach($periods as $k => $v)
		{
			//关键词
			if( preg_match('#^kw(.+)#',$v,$matchs))
			{
				$arguments['keyword'] = trim($matchs['1']);

				continue;
			}

			//分离
			list($key,$value) = preg_split('#^([a-z]{1,2})#',$v,-1,PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);

			//非法参数过滤
			if(!isset($this->uri_params['params'][$key]))
			{
				continue;
			}

			//学区特色多选特殊处理
			if($this->uri_params['params'][$key] == 'features')
			{
			   $value = explode($this->split_mulit_param,$value);
			}

			$arguments[$this->uri_params['params'][$key]] = $value;
		}

		//分页过滤
		if( isset($arguments['page']) && $arguments['page'] <=1 )
		{
			unset($arguments['page']);
		}

		return $arguments;
	}

	/**
	* 根据数组参数生成伪静态链接地址(提供旧版本转换新版本URL使用)
	*
	* @param $param2 数组参数以键值对形式提供
	* @param int 数值
	* @return string
	*/
	public function getUrlByParam($param2,$value2=0)
	{

		if(is_array($param2))
		{
			$arguments = $param2;
		}
		else
		{
			$arguments = array($param2 => $value2);
		}

		$url = $this->get_url('','',$arguments,'');

		return $url;
	}


	/**
	* 生成伪静态链接地址(适合类似tab页切换的操作)
	*
	* @param mixed 参数(若为数组，value无需赋值)
	* @param int 数值
	* @return string
	*/
	public function get_tab_url($param='',$value=0,$analy_param=false)
	{
		//当前频道域名
		$domain	= $this->get_domain();
		$uri_params = $this->get_uri_params();

		$arguments = array();
		//参数处理
		if(!empty($param))
		{
			if(is_array($param))
			{
				$arguments = $param;
			}
			else
			{
				$arguments = array($param => $value);
			}
		}

		$url = $this->get_url($arguments,'','','',$analy_param);

		return $url;
	}


	/**
	* 生成伪静态链接地址
	*
	* @param mixed 参数(若为数组，value无需赋值)
	* @param int 数值(若param为参数名称时赋值)
	* @param mixed 参数(若为数组，value无需赋值)
	* @param int 数值(若param2为参数名称时赋值)
        * @parmam boolean $analy_param 是否解析当前页面的参数
	* @return string
	*/
	public function get_url($param='',$value=0,$param2='',$value2=0,$analy_param='')
	{
		//当前频道域名
		$domain	= $this->get_domain();
		$uri_params = $this->get_uri_params();

		//当前页面的URI参数
		$arguments = array();

		if( !is_array( $uri_params) || empty($uri_params) )
		{
			return $domain;
		}

		//是否要忽略页面其他参数，适合与各个页面的TAB页类似操作
                $analy_param = $analy_param === '' ? $this->analy_param : $analy_param;
		if($analy_param)
                    $arguments = $this->get_uri();

		//拼接参数和请求的URI
		if( is_array($param) )
		{
			//其他条件提交，分页清空
			if( !array_key_exists('page',$param) ) unset($arguments['page']);

			if(is_array($arguments) && !empty($arguments))
			{
				$temp	= array_merge($arguments,$param);
			}
			else
			{
				$temp	= $param;
			}
		}
		else if( !empty($arguments[$param]) )
		{
			if(!$value)
			{
				unset( $arguments[$param] );
				$temp	= array();
			}
			else
			{
                //其他条件提交，分页清空
				if($param != 'page') unset($arguments['page']);
				$temp	= array( $param => $value );
			}
		}
		else
		{
            //其他条件提交，分页清空
			if($param != 'page') unset($arguments['page']);
			$temp	= array( $param => $value );
		}


		if(is_array($arguments))
		{
			$arguments = array_merge($arguments,$temp);
		}
		else
		{
			$arguments = $temp;
		}

		//参数拼接
		if(!empty($param2))
		{
			if(is_array($param2))
			{
                if( !array_key_exists('page',$param2)) unset($arguments['page']);
				$arguments = array_merge($arguments,$param2);
			}
			else
			{
				$arguments = array_merge($arguments,array($param2 => $value2));
			}
		}

		if(is_array($arguments) && !empty($arguments))
		{
			//过滤函数，过滤掉无效的参数，排除互斥的参数
			$arguments	= $this->uri_filter($arguments);

            //循环配置数组，按数序拼装一级目录URI字符串
			if(is_array($uri_params['dir_params']) && !empty($uri_params['dir_params']) )
			{
				foreach($uri_params['dir_params'] as $k => $v)
				{
					if(!empty($arguments[$v]))
					{
						$arguments[$k] = strip_tags(trim($arguments[$v]));
						//循环拼装子URI参数
						$dir_child	.= $k.$arguments[$k].'-';

						unset($arguments[$v]);
					}
				}
			}

			//循环配置数组，按顺序把参数放到数组
			foreach($uri_params['params'] as $k => $v) {

				if(!empty($arguments[$v]))
				{
					//各个频道关键字的默认值不同，如何处理？
					if( $v == 'keyword' && ($arguments['keyword'] == '请输入您的问题' ) )
					{
						unset($arguments[$v]);
						continue;
					}
					else
					{
						if( $v == 'keyword')
						{
							$arguments[$k] = strip_tags(trim($arguments[$v]));
						}else if( is_array($arguments[$v]) &&!empty($arguments[$v]) ) {
							$arguments[$v] = implode($this->split_mulit_param, $arguments[$v]);
							$arguments[$k] = strip_tags(trim($arguments[$v]));
						}else if(!empty($arguments[$v])) {
							$arguments[$k] = strip_tags(trim($arguments[$v]));
						}

						if( $v == 'page' && isset($arguments[$k]) && $arguments[$k] <= 1)
						{
							unset($arguments[$v]);
							continue;
						}

						//循环拼装子URI参数
						$uri_child	.= $k.$arguments[$k].'-';
					}
				}
			}
		}

        //目录参数处理
		$dir	= !empty($dir_child) ? substr($dir_child,0,-1) : '';

		//URI参数处理
		$uri	= !empty($uri_child) ? substr($uri_child,0,-1).'.html' : '';

		$dir_level	= count($this->get_dir());

		$init_url = $uri_params['default_url'];

		for($i = 0 ;$i < $dir_level ; $i++ )
		{
			//当一级目录的值不为空
			if($i == 0 && $dir_level == 2)
			{
				if( $dir != '')
				{
					$uri_sub .= '/'.$this->dir["$i"] . $dir;
				}
				else if( $this->dir_value != '')
				{
					$uri_sub .= '/'.$this->dir["$i"] . $this->dir_value;
				}
				else
				{
					$init_dir = $uri_params['default_dir_url'];

					if($init_dir != '')
					{
						$uri_sub .= '/'.$init_dir;
					}
				}
			}
            else
            {
				if($uri	!='')
				{
					$uri_sub .= '/'.$this->dir["$i"];
				}
				else
				{
					$init_url = $uri_params['default_url'];

					if($init_url !='')
					{
						$uri_sub .= '/'.$init_url;
					}else
					{
						$uri_sub .= '/';
					}
				}
			}
		}

		//拼接URL
		$url	= !empty($uri) ? $domain.$uri_sub.$uri : $domain.$uri_sub;

		return $url;
	}


	//处理互斥参数
	public function uri_filter(&$arguments){

		//根据定位符来过滤参数
		$dir = $this->get_dir();

		if( in_array('asklist_' , $dir ) ){
			//关键字与类型互斥
			if( !empty($arguments['keyword']) )
			{
				unset($arguments['type']);
			}
			else if( !empty($arguments['type']) )
			{
				unset($arguments['keyword']);
			}

			$arguments['is_best'] = !empty($arguments['is_best']) ? $arguments['is_best'] : 1;
		}
		else if (in_array('xl_',$dir ))
		{
			//如果没有区属就清掉街道
			if( !isset($arguments['district']) )
			{
				unset($arguments['streetid']);
			}
		}else if(in_array('community_',$dir )){
			if($arguments['price'] != 99) {
				unset($arguments['price1']);
				unset($arguments['price2']);
			}

			if($arguments['buildarea'] != 99) {
				unset($arguments['buildarea1']);
				unset($arguments['buildarea2']);
			}

			if($arguments['roomtype'] != 99) {
				unset($arguments['room']);
				unset($arguments['toilet']);
				unset($arguments['hall']);
			}
		} else if( in_array('dl_',$dir) && strpos($this->domain,'rent.house365.com')!==false) {
			if($arguments['price'] != 99)
			{
				unset($arguments['price1']);
				unset($arguments['price2']);
			}
			if($arguments['infofrom'] == 1) {
				unset($arguments['istag']);
			}
		}
		else if(  in_array('dl_',$dir ) || in_array('wl_',$dir ) || in_array('sl_',$dir )|| in_array('brt_',$dir ) )
		{
			if($arguments['roomtype'] != 99)
			{
				unset($arguments['room']);
				unset($arguments['hall']);
				unset($arguments['toilet']);
				unset($arguments['kitchen']);
			}

			if($arguments['price_sell'] != 99)
			{
				unset($arguments['price1']);
                unset($arguments['price_price1']);
				unset($arguments['price2']);
                unset($arguments['price_price2']);
			}

			if($arguments['buildarea'] != 99)
			{
				unset($arguments['buildarea1']);
                unset($arguments['buildarea_buildarea1']);
				unset($arguments['buildarea2']);
                unset($arguments['buildarea_buildarea2']);
			}

		}

		return $arguments;
	}

	/**
	 * 数值过滤
	 *
	 * @param string
	 * @return mixed
	 */
	private function is_num($value)
	{
		if(preg_match("#^[0-9]+$#",$value)) {
			return $value;
		} else {
			return '';
		}
	}

}