gusucode.com > 同城苏州黄页系统php源码程序 > lib/field.class.php

    <?
if( !class_exists('base') )
	include_once($root_path."lib/base.class.php");
class field extends base
{
	var $name		= '';
	var $extend		= '';

	/**
	 * 欄位的類型
	 *
	 * var 枚舉形,text,mulText,select,list,radio,checkbox,group,*
	 */
	var $inputType			= '';
	var $groupType			= '';
	var $groupMember		= array();
	var $caption			= '';
	var $default			= '';
	var $value				= '';

	var $checkType			= '';
	var $alertName			= '';
	var $allowEmpty			= true;
	var $minValue			= '*';
	var $maxValue			= '*';

	var $inputName			= '';
	var $formName			= 'theform';
	var $column				= '*';

	var $lm_dbtable			= '';
	var $lm_indexFld		= '';
	var $lm_lower			= array();
	var $lm_loadAll			= false;
	var $lm_realname_link	= '';
	
	var $maxFileByte		= 100;
	var $maxPicWidth		= 400;
	var $maxPicHeight		= 300;
	var $allowFileType		= array();
	
	var $upload_pic_width	= 0;
	var $upload_pic_height	= 0;
	var $upload_file_byte	= 0;
	var $upload_file_extend	= '';

	var $input_maxlength	= '';
	var $input_size_type	= '';
	var $input_size_width	= '';
	var $input_size_height	= '';
	var $inputStyle			= '';
	var $innerInput			= '';

	var $options			= array();
	
	var $allowEmpty_true	= '<label style= "color:green">■</label>';
	var $allowEmpty_false	= '<label style= "color:red">■</label>';
	var $showTxt_separator	= '/';			// 多个值之间的分隔符

	var $parent				= null;

	var $timeFormat			= 'Y-m-d G:i:s';
	
	
#### 私有函數 #####################################################
	
	function reset_mulArray(&$arr,$columnCnt)
	{
		reset($arr);
		$a=$arr;
		$arr=array();
	
		$idx=0;
		while($item=current($a))
		{			
			for($i=0;$i<$columnCnt;$i++)
			{	
				if(!$item=current($a))
					break;
	
				$keyname = array_search( $item,$a );
				$arr[$idx][ $keyname ]=$item;
				next($a);
			}

			$idx++;
		}
	}

	/**
	 * 为 select,list 等类型的栏位 创建表单时, 初始化 空值选项
	 *
	 */
	function init_option( &$parameter )
	{
		(array)$this->options;

		// 从主模板传递的 预设项
		if( !empty($parameter['default']) )
			$this->options = array( ''=>$parameter['default'] ) + $this->options;


		// 栏位自身定义的 预设项				
		elseif( !empty($this->default) )
			$this->options = array( ''=>$this->default ) + $this->options;

		(array)$this->value;
	}

	/**
	 * 为 checkbox,radio 等类型的栏位 创建表单时, 初始化 预设选项
	 *
	 */
	function init_box( &$parameter )
	{
		(array)$this->value;
		if( empty($this->value) and !empty($this->default) )
			$this->value = array( ''=>$this->default );
		
		if( empty($parameter['row_end']) )
			$parameter['row_end'] 
				= ($this->inputType=='checkbox')?"<br />\r\n":null;
	}


#### 公有函數 #####################################################

	# 构造函数
	function field()
	{
		$this->base();
	}

	function set_input_size()
	{
		
	}

	function create_checkValue_js()
	{
		return $this->checkValueAttribute=" ALL=\"{$this->checkType},{$this->alertName},{$this->minValue},{$this->maxValue},{$this->allowEmpty}\"";
	}

	function outDefualt($value)
	{
		do{
			// 日期
			if( $this->inputType == 'date')
			{
				if( !is_array($this->value) and preg_match("/^\d{10}$/",$this->value) )
				{
					$this->value = array('timestamp'=>$this->value);
					list( $this->value['year'],$this->value['month'],$this->value['date'] ) = explode( '.',date("Y.n.j",$this->value['timestamp']) );
					$this->value['year'] = 'year'.$this->value['year'];
					$this->value['month'] = 'month'.$this->value['month'];
					$this->value['date'] = 'date'.$this->value['date'];
				}
	
				if( is_array($this->value) and in_array($value,$this->value) )
					$out = true;

				break;
			}
			
			
			// 多值
			if( is_array($this->value) )
			{
				if( in_array($value,$this->value) )
					$out = true;
				break;
			}

			// 单值
			if( $value == $this->value )
			{
				$out = true;
				break;
			}
	
		} while (0);

		if( $out )
		{
			if ( in_array($this->inputType,array('date','select','list')) )
				return " selected=\"true\"";
			elseif ( in_array($this->inputType,array('checkbox','radio')) )
				return " checked=\"true\"";
		}
	}


	function show_input( &$creator,&$parameter )
	{
		# 异常处理 
		if( in_array($this->inputType,array('insertTime','updateTime','viewCount','group','*')) )
			return __CLASS__.'::'.__FUNCTION__."() 函数异常;遇到非表单输入(无表单)类型的栏位:{$this->inputType}。\r\n<br>";
		$control_name = $this->inputType;
		
		# 初始化 共同属性	
		$this->out_lm_innerInput();										// 创建联动菜单 js 事件	
		$this->create_checkValue_js();									// 用户输入检验

		if( !empty( $this->innerInput ) )								// 表单样式
			$this->innerInput=' '.stripslashes($this->innerInput);

		if( !empty( $parameter['innerInput'] ) )						// 由主模板传递的表单样式
			$creator->assign('innerInput',$parameter['innerInput']);	
	
		if( !empty( $parameter['optionStyle'] ) )						// 选项样式
			$this->optionStyle = $parameter['optionStyle'];

		
		# 初始化 个别属性
		if( in_array($this->inputType,array('list','checkbox')) )
		{
			if( $this->name == $this->inputName or empty($this->inputName) )
				$this->inputName = $this->name.'[]';
		}
		
		switch($this->inputType)
		{
			case 'text' :
				if( $creator->act == 'insert' and empty($this->value) and $this->default!='' )
					$this->value = $this->default ;
			case 'password':
				$control_name='text';				// 使用 text 类型相同的 模板文件 创建表单
				break;
			# 下拉菜单 --- ---
			case 'select':
				$this->init_option( $parameter );
				break;
			
			# 列表框 --- ---
			case 'list':
				$this->init_option( $parameter );				
				if( empty($this->input_size_height) )
					$this->input_size_height=1;				
				$control_name='select';
				break;

			# 单选按钮组 --- ---
			case 'radio':
				if( empty($this->options) )
					return "单选按钮组:{$this->caption}({$this->name})没有设置相应选项";

				if( !isset($parameter['num_per_row']) )
					$parameter['num_per_row']=6;
				$this->reset_mulArray($this->options,$parameter['num_per_row']);
				
				$this->init_box($parameter);

				$control_name='checkbox';
				break;
			
			# 复选按钮组 --- ---
			case 'checkbox':
				if( empty($this->options) )
					return "复选按钮组:{$this->caption}({$this->name})没有设置相应选项";

				$this->init_box($parameter);
				
				break;
			# 日期 --- ---
			case 'date':
				if( $creator->act=='insert' )
				{
					$this->default==='' ?
						$this->value = time() :
						$this->value = $this->default ;
				}
				break;
			# 年份菜单 --- ---
			case 'select_year':
				$start=date("Y",time()-31536000);		// 前一年
				$end=date("Y",time()+315360000);		// 后一年
				for ($idx=$start;$idx<=$end;$idx++)
					$this->options[$idx]=$idx;
				$this->init_option( $parameter );
				$control_name='select';
				break;
			
			# 当前年份菜单 --- ---
			case 'select_year_current':
				$start=date("Y",time()-31536000);		// 前一年
				$end=date("Y",time()+315360000);		// 后一年
				for ($idx=$start;$idx<=$end;$idx++)
					$this->options[$idx]=$idx;
				$this->value=date("Y");
				$this->init_option( $parameter );
				$control_name='select';
				break;
			
			# 月份菜单 --- ---
			case 'select_m':
				for($idx=1;$idx<=12;$idx++)
					$this->options[$idx]=$idx;
				$this->value=date("m");
				$this->init_option( $parameter );
				$control_name='select';
				break;
			
			# 日期菜单 --- ---
			case 'select_d':
				for($idx=1;$idx<=31;$idx++)
					$this->options[$idx]=$idx;
				$this->value=date("d");
				$this->init_option( $parameter );
				$control_name='select';
				break;
			
			# 小时菜单 --- ---
			case 'select_h':
				for($idx=1;$idx<=24;$idx++)
					$this->options[$idx]=$idx;
				$this->value=date("G");
				$this->init_option( $parameter );
				$control_name='select';
				break;
			
			# 分秒菜单 --- ---
			case 'select_ms':
				for($idx=1;$idx<=60;$idx++)
					$this->options[$idx]=$idx;
				$this->value=date("i");
				$this->init_option( $parameter );
				$control_name='select';
				break;
			
			# 文件 --- ---
			case 'file':
				break;
			# 文件 --- ---
			case 'picture':
				if( preg_match("/\.swf$/i",$this->value) )
				{
					$imginfo = @getimagesize( $this->show_src() );
					if( $imginfo[0] > 200 )
					{
						$this->pic_input_height = floor((200/$imginfo[0]) * $imginfo[1]) ;
						$this->pic_input_width = 200 ;
					}
					$this->pic_type = 'swf' ;
				}
				else
					$this->pic_type = 'pic' ;
				break;

			# 非表单输入类型 或 未知的表单类型 --- ---
			default:
				
		}


		# 创建表单 --- --- --- ---
		$control_template="{$creator->template_dir}/input_control_{$control_name}.html";		
		if( !file_exists($control_template) )
			return __CLASS__.'::'.__FUNCTION__."() 函数遇到错误:无法创建输入表单,文件 {$control_template} 不存在。";

		$creator->assign('this',$this);
		$creator->assign('main_template_parameter',$parameter);
		return $creator->fetch($control_template);

	}

	function show_pic()
	{
		// 无图片
		if( empty($this->value) )
			return false;

		// 图片不存在
		if( !file_exists($this->upload_path.$this->value) )
			return false;

		if( !preg_match("/\.swf$/i",$this->value) )
		{
			$html = '<img src="';	
			
			if( !empty($this->maxPicWidth) and !empty($this->maxPicHeight) )
			{
				$html.= '/mod.php/piczoom.php?';
				$html.= "w={$this->maxPicWidth}&h={$this->maxPicHeight}";
				$html.= '&type=mini&pic=';
				$html.= urlencode($this->upload_path.$this->value);
				$html.= '"';
			}
			else 
			{
				$html.= $this->upload_url.$this->value;
				$html.= '"';
			}
			$html.= '>';
		}
		else
		{
			$imginfo = @getimagesize( $this->show_src() );
			$html = "<embed width='{$imginfo[0]}' height='{$imginfo[1]}' src='".$this->show_src()."' type='application/x-shockwave-flash' PLAY='1'></embed>" ;
		}

		return $html;
	}
	
	function show_src()
	{
		return $this->upload_url.$this->value ;
	}
	
	function show_file()
	{
	}

	function show_caption()
	{
		return $this->caption;
	}

	function show_txt()
	{
		$value='';

		# 时间栏位
		if( in_array($this->inputType,array('insertTime','updateTime','date')) )
		{
			if( empty($this->value) )
				$value='-- --';
			else
				$value=date($this->timeFormat,$this->value);

		}

		# 菜单,复选,单选栏位
		elseif( in_array($this->inputType,array('list','select','checkbox','radio')) )
		{

			// 多个值
			if( is_array($this->value) )
			{
				foreach ($this->value as $key=>$item)
					$value[$key] = $this->options_code2txt( $item );
			}
			// 单个值
			else
				$value = $this->options_code2txt( $this->value );
		}
		# 普通
		else
			$value=$this->value;
		
		if( is_array($value) )
			$value=implode($this->showTxt_separator,$value);
		return $value;
	}

	function options_code2txt($code)
	{
		if( $code==='' )
			return '';

		# 从 $this->options 结构中获得 数据
		$options=array();
		foreach ($this->options as $key=>$value)
		{
			if( !is_array($value) )
				$options[$key]=$value;
			else
			{
				foreach ($value as $k=>$v)
					$options[$k]=$v;
			}
		}

		# 开始
		if( !isset($options[$code]) )
		{
			$this->bad("field::options_code2txt() 遇到异常,{$this->name}栏位的选项表中,没有代码为 {$code}的项。");
			return $code;
		}
		else
			return $options[$code];
	}

	function show_icon()
	{
		if( $this->allowEmpty )
			return $this->allowEmpty_true;
		else
			return $this->allowEmpty_false;		
	}
	
	function show_Option_name( $code )
	{
		$arr = cutdownArr($this->options);
		return @$arr[ $code ];
	}

	/**
	 * 从用户提交的表单中获取栏位数据
	 *
	 * 获取的值储存在类成员 field::value 中,并返回此值
	 *
	 * @return mixed
	 */
	function get_data($act='')
	{
		if( empty($act) )
		{
			$this->bad('field::get_data()遇到错误:$act 必须存在。');
			return false;
		}


		if(	 in_array($this->inputType,array('viewCount','*'))			 // 无需通过 用户表单提交 获得数据的栏位
			 or	 $this->inputType=='updateTime'							 // 更新日期栏位
			 or	 ($act=='update' and $this->inputType=='insertTime') )	 // 修改记录 无需更新 刊登日期
		{
			$this->value='--null--';
			return false;
		}
	
		
		# -- 组合栏位,从成员栏位中获得
		if( $this->inputType=='group' )
		{
			foreach ($this->groupMember as $item)
				$arr[]=$item->value;
			switch ($this->groupType)
			{
				case 'serialize':
					$this->value=serialize($arr);
					break;
				default:
					$this->value=implode($this->groupType,$arr);
					break;
			}
			
		}

		# -- 时间栏位
		elseif ( in_array($this->inputType,array('insertTime','update')) )
		{
			$this->value = time();
		}
		
		# -- 联动菜单实名 栏位
		elseif( $this->inputType=='lm_name' )
		{
			if( empty($this->lm_dbtable) or empty($this->lm_realname_link) )
			{
				$this->bad(__CLASS__.'::'.__FUNCTION__."()函数 遇到错误:“联动菜单实名”类型的栏位缺少 “使用数据表” 或 关联字段。");
				return false;
			}

			$sql = "select `name` from `{$this->lm_dbtable}` where `id`={$this->lm_realname_link->value}";
			$r = mysql_query($sql);
			$arr = mysql_fetch_assoc($r);

			$this->value=$arr['name'];
		}

		# -- 文件、图片上传
		elseif ( in_array($this->inputType,array('file','picture')) )
			$this->upload_file($act);
		
		# -- 可直接从 $_REQUEST 变量中获取 用户提交数据 的栏位
		elseif( isset($_REQUEST[$this->inputName]) )
			$this->value=$_REQUEST[$this->inputName];

		# -- 表单名中有 [] 的特殊 数组变量
		elseif ( preg_match("/([_\w]+)([_\w\[\]]*?)(\[\])?$/",$this->inputName,$r) )
		{
			$r[2]=str_replace('[',"[\"",$r[2]);
			$r[2]=str_replace(']',"\"]",$r[2]);

			$valueName="\$_REQUEST['{$r[1]}']{$r[2]}";
			$this->value=eval("if( isset({$valueName}) )return {$valueName};");	

		}
		if( $this->inputType == 'date' )
		{
			$this->value = mktime( 0, 0, 0, 
					isset($this->value['month']) ? str_replace('month', '', $this->value['month']) : 0, 
					isset($this->value['date']) ? str_replace('date', '', $this->value['date']) : 0, 
					isset($this->value['year']) ? str_replace('year', '', $this->value['year']) : 0	);
		}

		# 多值输入表单
		if( in_array($this->inputType,array('checkbox','list')) and is_array($this->value) )
		{
			if( empty($this->groupType) )
				$this->groupType=',';
			$this->value=implode($this->groupType,$this->value);
		}

		return $this->value;
	}

	function set_data($value)
	{
		
		# 组合栏位
		if($this->inputType=='group')
		{
			// 还原数据
			switch ($this->groupType)
			{
				case 'serialize':
					$arr=unserialize($value);
					break;
				default:
					$arr=explode($this->groupType,$value);
					break;
			}
			
			// 将数据 传递给 成员栏位
			$idx=0;
			foreach ($this->groupMember as $key=>$item)
			{
				if( !isset($arr[$idx]) )
				{
					continue;
				}

				$this->groupMember[$key]->set_data($arr[$idx]);
				$idx++;
			}
			
			//完成
			return $this->value=$value;

		}
		# 其它 多值栏位
		elseif( in_array($this->inputType,array('list','checkbox')) )
		{
			if( empty($this->groupType) )
				$this->groupType = ',';

			$this->value=explode($this->groupType,$value);
		}
		# 普通栏位
		else
			$this->value=$value;
	}

	function delete_file()
	{
		if( file_exists( $this->upload_path . $this->value ) )
			@unlink( $this->upload_path . $this->value );
		
		if( !file_exists( $this->upload_path . $this->value ) )
		{
			$this->ok("{$this->caption} 原有文件已经成功删除。");
			$this->value = '';
		}
		else
			$this->bad("删除 {$this->caption} 原有文件失败。");
	}

	/**
	 * 处理上传文件、图片
	 *
	 * @version  因使用$ _FILES  需要 4.1.0 以上版本 php
	 */
	function upload_file($act)
	{
		if( !isset($_FILES[$this->inputName]) )
		{
			$this->bad(__CLASS__.'::'.__FUNCTION__."() 函数遇到异常,没有发现\$_FILES['{$this->inputName}']变量。");
			return false;
		}
		
		# 用户勾选 删除文件 box
		if( !empty($_REQUEST["DeletePictureMessage_for_{$this->name}"]) )
			$this->delete_file();
		
		
		# 用户没有上传文件
		if( empty($_FILES[$this->inputName]['tmp_name']) )
			return false;
		
		# 字节数 限制
		$this->upload_file_byte = $_FILES[$this->inputName]['size'] ;
		if( !empty($this->maxFileByte) and $_FILES[$this->inputName]['size']>$this->maxFileByte )
		{
			$this->bad("上传文件不能大于 {$this->maxFileByte} Byte, {$this->caption} 已经超出({$_FILES[$this->inputName]['size']} Bity)。上传被取消。");
			return false;
		}
		
		$fileinfo=pathinfo($_FILES[$this->inputName]['name']);
		# 文件类型限制(依据扩展名)
		if( !empty($this->allowFileType) )
		{			
			$ex = empty($fileinfo['extension'])?'未知':$fileinfo['extension'];
			$this->upload_file_extend = $ex ;
			if( !in_array($fileinfo['extension'],$this->allowFileType) )
			{
				$this->bad("上传文件必须为下列格式: ".implode(',',$this->allowFileType).", {$this->caption} 上传文件格式为:{$ex}。上传被取消。");
				return false;
			}
		}		
		
		# 图片长宽限制
		if( $this->inputType=='picture' )
		{
			$picinfo = getimagesize($_FILES[$this->inputName]['tmp_name']);
			$this->upload_pic_width = $picinfo[0] ;
			$this->upload_pic_height = $picinfo[1] ;
			
			// 超过宽度
			if( !empty($this->maxPicWidth) and $picinfo[0] > $this->maxPicWidth )
			{
				$this->bad("上传图片宽度必须限定在 {$this->maxPicWidth} pix以内, {$this->caption} 上传图片的宽度为:{$picinfo[0]} pix。上传被取消。");
				return false;
			}

			// 超过高度
			if( !empty($this->maxPicHeight) and $picinfo[1] > $this->maxPicHeight )
			{
				$this->bad("上传图片宽度必须限定在 {$this->maxPicHeight} pix以内, {$this->caption} 上传图片的宽度为:{$picinfo[1]} pix。上传被取消。");
				return false;
			}
		}
		
		# 若update 时,文件文件已经存在,则首先删除 久的文件
		if( $act=='update' and !empty($this->value) )
			$this->delete_file();
			
		# 新的文件名
		if( !empty($fileinfo['extension']) )
			$fileinfo['extension']='.'.$fileinfo['extension'];
		$newname=time().'.'.rand(0,999) * rand(0,999).$fileinfo['extension'];

		# 保存文件
		if( !copy($_FILES[$this->inputName]['tmp_name'],$this->upload_path.$newname) )
		{
			$this->bad("保存文件 {$this->caption} 因服务器原因失败。");
			return false;
		}

		$this->ok("文件 {$this->caption} 上传成功。");
		$this->value = $newname;
		return true;
	}


	/**
	 * 对用户提交的数据,进行合法性检验
	 *
	 */
	function check_data_validity()
	{
		switch ($this->checkType)
		{
			case 'char':
				break;
			case 'text':
				break;
			case 'number':
				break;
			case 'email':
				break;
			case 'checkbox':
				break;
			case 'select':
				break;
			case 'char':
				break;
			case 'char':
				break;
		}
	}
	
	function out_lm_innerInput()
	{
		if( empty($this->lm_dbtable) )
			return false;
		
		foreach( $this->lm_lower as $key=>$item )
		{
			# +n 格式的表单名
			if( preg_match("/^\+\d+$/",$item) )
				$this->lm_lower[$key]="'{$item}'";
		}

		$this->innerInput.=" onChange=\"with(document.{$this->formName}){";
		$this->innerInput.="getOption(this,new Array(";
		$this->innerInput.=implode(',',$this->lm_lower);
		$this->innerInput.="),'{$this->lm_dbtable}'";

		if( !empty($this->lm_indexFld) )					// 检索字段
			$this->innerInput.=",'{$this->lm_indexFld}'";
		if( $this->lm_loadAll )						// 装载所有下级选项到最近菜单
			$this->innerInput.=",true";

		$this->innerInput.=");}\"";
	}
}
?>