<?php

/*
*	Copyright VeryIDE,2007-2010
*	http://www.veryide.com/
*
*	$Id: class.setting.php,v2 11:46 2009-9-10 Lay $
*/

/*
	*
	PHP解析XML模板
	获取和设置XML节点
	用于修改和读取站点配置文件
	注意 xml 最好使用 utf-8 编码，这里会自动转编码
	*2008-4-3 
	*LIQUAN
	*eg.get config
	
	*$c = new Setting('templet.xslt','config.xml');
	* $c->transform();
	* $c->save();
	* $c->save();
*/

class Setting{
	
	//配置文件
	private $xsl;
	
	//模板文件
	private $xml;
	
	//数组名称
	private $arr;
	
	//是否有错
	private $err = true;

	//构造函数
	function __construct( $data, $xml, $arr ){
		global $_G;
		
		$this->xsl = $data;
		$this->xml = $xml;
		$this->arr = $arr;
		
		//检查文件
		if( file_exists($this->xml) ){
			$this->err = false;
		}
		
		//加载缓存
		if( file_exists($this->xsl) ){
			include( $this->xsl );
		}else{
			$_G['setting'][$this->arr] = array();
		}
	}

	//转换成HTML表单
	function transform(){		
		global $_G;
		
		if($this->err) return 'File not found!';
		
		//临时数组
		$arr = $_G['setting'][$this->arr];
	
		//转编码，将缓存转为UTF-8
		if( $_G['product']['charset'] != "utf-8" ){			
			foreach( $arr as $key => $val ){				
				if( is_string($val) ){				
					$arr[$key] = iconv($_G['product']['charset'],"UTF-8",$val);
				}else{
					$arr[$key] = $val;
				}
			}
		}
							
		// Load the XML source
		$xml = new DOMDocument;
		$xml->load($this->xml);		
		
		$doc = $xml->getElementsByTagName('*');
		
		//表单
		$res = '';
		
		for ($i=0;$i<$doc->length;$i++){
			
			$ele = $doc->item($i);
			
			switch( $ele -> tagName ){
				
				//分组
				case "item":
				
					$res .= '<tr><td colspan="2" class="section"><span>'.$ele -> getAttribute("desc").'</span><strong>'.$ele -> getAttribute("label").'</strong></td></tr>';
				
				break;
				
				//选项
				case "key":
				
					$res .= '<tr text="'.$ele -> getAttribute("tip").'">';
						$res .= '<td width="'.$ele -> getAttribute("width").'" align="'.$ele -> getAttribute("align").'"><strong>'.$ele -> getAttribute("label").'</strong></td>';
						$res .= '<td>';
						
						//类型
						switch( $ele -> getAttribute("type") ){
							
							case "hidden":
								$res .= '<input name="'.$ele -> getAttribute("name").'" type="hidden" value="'.$arr[$ele -> getAttribute("name")].'" />';
								$res .= $arr[$ele -> getAttribute("name")];
							break;
							
							case "password":
								$res .= '<input name="'.$ele -> getAttribute("name").'" type="password" class="text" size="'.$ele -> getAttribute("size").'" value="'.$arr[$ele -> getAttribute("name")].'" />';
							break;
							
							case "input":
							case "text":
							
								//$this -> fixAttr( $ele );
				
								//$v = array('idcard'=>"fix_id='yes'",'email'=>"fix_email='yes'",'url'=>"fix_url='yes'",'number'=>"fix_number='yes'",'datetime'=>"fix_date='yes' readonly='true' onclick='return showCalendar(this.id,\"y-mm-dd\");' title='年-月-日'",''=>'');				
							
								//$res .= '<input name="'.$ele -> getAttribute("name").'" size="'.$ele -> getAttribute("size").'" class="text" value="'.stripcslashes($arr[$ele -> getAttribute("name")]).'" fix_name="'.$ele -> getAttribute("label").'" '.$v[$ele -> getAttribute("format")].'  fix_null="'.( $ele -> getAttribute("null") == "false" ? "yes" : "" ).'" />';
								
								if( $ele -> getAttribute("readonly") ){
									$res .= '<input name="'.$ele -> getAttribute("name").'" size="'.$ele -> getAttribute("size").'" class="text" value="'.$ele -> getAttribute("value").'" '. $this -> fixAttr( $ele ) .' readonly="true" />';	
								}else{
									$res .= '<input name="'.$ele -> getAttribute("name").'" size="'.$ele -> getAttribute("size").'" class="text" value="'.stripcslashes($arr[$ele -> getAttribute("name")]).'" '. $this -> fixAttr( $ele ) .' />';
								}
								
							break;
							
							case "textarea":
								$res .= '<textarea name="'.$ele -> getAttribute("name").'" rows="'.$ele -> getAttribute("rows").'" cols="'.$ele -> getAttribute("cols").'" '. $this -> fixAttr( $ele ) .'>'.stripcslashes($arr[$ele -> getAttribute("name")]).'</textarea>';							
							break;
							
							case "select":
								$res .= '<select name="'.$ele -> getAttribute("name").'" style="width:'.$ele -> getAttribute("size").'px;">';
								
								//遍历子选项
								$sub = $ele->getElementsByTagName('option');
								
								for ($s=0; $s<$sub->length; $s++){														
									$res .= '<option value="'.$sub ->item($s) -> getAttribute("value").'" '. ( $arr[$ele -> getAttribute("name")] == $sub ->item($s) -> getAttribute("value") ? 'selected="selected"' : '') .'>'.$sub ->item($s) -> nodeValue.'</option>';								
								}
								
								//////////////////////////
								
								//遍历文件夹
								if( $ele -> getAttribute("folder") ){
									
									//遍历皮肤目录
									$root = VI_ROOT.$ele -> getAttribute("folder");
									
									if ($handle = opendir($root)) {
										while (false !== ($file = readdir($handle))) {
											if( ($file  !=   ".") && ($file   !=   "..") && is_dir($root.$file) ){
												$res .= '<option value="'.$file.'" '. ( $arr[$ele -> getAttribute("name")] == $file ? 'selected="selected"' : '') .'>'.$file.'</option>';							
											}
										}
										closedir($handle);
									}	
									
								}
															
								$res .= '</select>';							
							break;
							
							case "radio":								
								
								//子选项
								$sub = $ele->getElementsByTagName('option');
								
								for ($s=0; $s<$sub->length; $s++){														
									$res .= '<label><input name="'.$ele -> getAttribute("name").'" value="'.$sub ->item($s) -> getAttribute("value").'" class="radio" type="radio" '. ( $arr[$ele -> getAttribute("name")] == $sub ->item($s) -> getAttribute("value") ? 'checked="checked"' : '') .' />'.$sub ->item($s) -> nodeValue.'</option></label>';
								}															
															
							break;
							
							case "checkbox":
								
								//子选项
								$sub = $ele->getElementsByTagName('option');
								
								for ($s=0; $s<$sub->length; $s++){														
									$res .= '<label><input name="'.$ele -> getAttribute("name").'[]" value="'.$sub ->item($s) -> getAttribute("value").'" class="checkbox" type="checkbox" '. ( in_array($sub ->item($s) -> getAttribute("value"),$arr[$ele -> getAttribute("name")]) ? 'checked="checked"' : '') .' />'.$sub ->item($s) -> nodeValue.'</option></label>';								
								}															
															
							break;
							
							case "notice":
							
								$res .= '<div class="highlight">'.$ele -> getAttribute("desc").'</div>';
								
								$ele -> setAttribute("desc",'');
								
							break;
							
							default:
								
								$res .= 'ERROR';								
															
							break;
							
						}						
						$res .= $ele -> getAttribute("desc");
						$res .= '</td>';					
					$res .= '</tr>';
				
				break;				
				
			}
			
		}
	
		//转编码，将UTF-8转为当前编码
		if( $_G['product']['charset'] != "utf-8" ){
			$res = iconv("UTF-8",$_G['product']['charset'],$res);
		}
		
		//输出表单
		return $res;
	
	}
	
	//缓存写入权限测试
	function writable(){
		return is_writable( $this->xsl );
	}
	
	function fixAttr( $ele ){
		$ext = '';		
		foreach( $ele -> attributes as $att ){
			if( strpos( $att -> name,  'fix_' ) !== FALSE ){
				$ext .= $att -> name.'="'.$att -> value.'" ';
			}
		}
		return $ext;
	}
	

	//读取XML配置
	function get(){		
		global $_G;
		
		if($this->err) return 'File not found!';
							
		//读取插件
		$xml = simplexml_load_file($this->xml);
		$dom = simplexml_import_dom($xml);
		
		$array = array();
		
		//遍历节点
		foreach ($dom->xpath('//key') as $key) {
			$name = $key['name'];
			$type = $key["type"];
			$format = $key["format"];
			
			switch($type){
				case "input":
				case "radio":
				case "hidden":
				case "select":
					$value = $key['value'];					
				break;
				
				case "checkbox":				
					$value = "";
					//遍历子元素
					foreach ($key->xpath('option') as $input) {
						if( $input["checked"] == "true" ){
							$value .= $input["value"].",";
						}						
					}
					$value = substr($value,0,-1);
				break;
				
				case "textarea":
					$value = $key;
				break;
			}
			
			//转编码
			if( $_G['product']['charset'] && $_G['product']['charset'] != "utf-8" ){
				$value = iconv("UTF-8",$_G['product']['charset'],$value);
			}
			
			$array[(string) $key['name']] = (string) $value;
			
		}
		
		return $array;		
	}
	
	/*
		保存配置
	
		make	重写
	*/
	function save( $method , $make = TRUE ){		
		global $_G;
		
		if($this->err) return 'File not found!';
		
		$query = ( $method=='POST'? $_POST : $_GET ) ;
		
		//只更新部分
		if( !$make ){
		
			//临时数组
			$arr = $_G['setting'][$this->arr];
			
			//重写缓存中提交的值
			foreach( $query as $key => $val ){				
				$arr[$key] = $val;
			}
			
			$query = $arr ;			
		}
		
		//清除转义字符
		foreach( $query as $key => $val ){				
			if( is_string($val) ){				
				$query[$key] = stripcslashes($val);
			}else{
				$query[$key] = $val;
			}
			if( $key == 'platform' ) $this -> rewrite( $val, $query['domain'] );
		}
		
		$str = '<?php'.chr(13);
		$str .= ' /*'.date("Y-m-t H:i:s").'*/ '.chr(13);		
		$str .= '$_G[\'setting\'][\''.$this->arr.'\'] = ';		
		$str .= var_export( $query , TRUE );		
		$str .= ';?>';
		
		//写入缓存
		return create_file($this->xsl,$str);
		
	}
	
	/*
		生成伪静态规则
		
	*/
	function rewrite( $mode, $domain ){
		global $_G;
		
		//当前目录
		$base = dirname( $this->xml );
		
		//XML 地址
		$data = $base . '/rewrite.xml';
		
		//存储目录
		$save = $base . '/content/.htaccess';
		
		// Load the XML source
		$xml = new DOMDocument;
		$xml->load( $data );		
		$doc = $xml->getElementsByTagName('key');		
		for ($i=0;$i<$doc->length;$i++){			
			$ele = $doc->item($i);			
			if( $ele -> getAttribute("name") == $mode ){
				$text = trim( $ele -> nodeValue );
				
				//如果有绑定域名
				if( $domain ){
					$text = str_replace( '{BASE}', '/', $text );
				}else{					
					$text = str_replace( '{BASE}', VI_BASE.'module/'.$this->arr.'/content/', $text );
				}
				
				//转编码（Linux 主机必需为 ANSI 格式）
				$text = iconv('UTF-8','GBK',$text);
				
				return create_file( $save , $text );
				break;
			}
			
		}
	
	}

}
?>