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

    <?
if( !class_exists('webPge') )
	include_once($root_path."lib/webPge.class.php");
if( !class_exists('Query') )
	include_once($root_path."lib/Query.class.php");

$events = array(
	'EVENT_BEFORE_QUERY',						// 查询数据库以前
	'EVENT_BEFORE_INIT_RECORD',					// 初始化一笔记录的时候
	'EVENT_INITIALIZED_RECORD',					// 一笔记录初始化完成

	'EVENT_BEFORE_ACTION',						// 任何操作开始以前
	'EVENT_AFTER_ACTION',						// 任何操作开始以后
	'EVENT_BEFORE_CHG_STATUS',					// 改变状态以前
	'EVENT_AFTER_CHG_STATUS',					// 改变状态以后
	'EVENT_BEFORE_DELETE',						// 删除一笔纪录以前
	'EVENT_AFTER_DELETE'						// 删除一笔记录以后
);
register_event($events);

class indexPge extends webPge
{

	var $list				= array();

	var $query_obj;
	var $query_list			= array();
	var $query_cnt			= array();
	//var $query_return_clms	= array();
	
	var $records_limit		= 20;					// 最大记录数
	var $first_record		= 0;					// 本页 第一条索引 的 id 
	var $current_page_num	= 1;
	var $first_record_tag 	= 'First_Record_ID';
	
	var $keywords_separater = ' ';					// 关键字搜索时 多个关键字之间的 分隔符
													// 默认是 空格
												
	var $upload_columns		= array();
	var $upload_fields		= array();
	
	var $chg_status_log		= array(
			// 'switch'	=> false,
			'admin_clm'	=> 'verify_admin',
			'time_clm'	=> 'verify_time',
			'ip_clm'	=> 'verify_ip'
	);



	function indexPge()
	{
		$this->webPge();

		// 初始化 数据库查询查询类
		$this->init_Query();
		
		// 计算当前页数
		$this->current_page_num = $this->firstIdx2pageNum($this->first_record);
	}
	
	
	function init_Query()
	{
		// 创建 一个数据库查询对象
		$this->query_obj = & new Query( $this->dbtable );
		$this->query_obj->primaryKey = $this->primary_key ;

		// 设置 用户提交的 起始记录
		if( !empty($_REQUEST['First_Record_ID']) )
			$this->first_record = $_REQUEST[ $this->first_record_tag ];
	}
	
	function query_REQUEST()
	{
		# 關鍵字
		if( !empty($_REQUEST['keywords']) )
		{
			foreach($_REQUEST['keywords'] as $fields=>$value)
			{
				if( empty($value) )
					continue ;
				$fields = explode(',',$fields);
				$this->query_obj->set_keyworld( explode($this->keywords_separater,$value),$fields );
			}
		}
		
		# 直接條件
		if(!empty($_REQUEST['directC']))
			$this->query_obj->directCondition((array)$_REQUEST['directC']);
		
		# 範圍條件
		if(!empty($_REQUEST['areaC']))
			$this->query_obj->areaCondition((array)$_REQUEST['areaC']);
		
		# 復選框條件
		if(!empty($_REQUEST['likeC']))
		{
			foreach((array)$_REQUEST['likeC'] as $key=>$fld)
			{
				if( empty($fld) )
					continue ;
				$this->query_obj->set_like((array)$fld,' or ',$key);
			}
		}

		// pp( $this->query_obj->make_sql() );
		
	}

	function mine_records( $parent = '' )
	{
		if( empty($this->parent_column_name) )
		{
			$this->create_msg(__CLASS__.'::'.__FUNCTION__.'() 函数遇到错误,没有设置 $this->parent_column_name 属性。此方法无效。');
			return false;
		}

		if( empty($parent) )
		{
			global $MySelf ;
			if( empty($MySelf['id']) )
			{
				$this->create_msg(__CLASS__.'::'.__FUNCTION__.'() 函数遇到错误,指定的 $parent 参数无效。');
				return false;
			}
			$parent = $MySelf['id'] ;
		}

		$this->query_obj->directCondition( array( $this->parent_column_name=>$parent ) );
	}
	function primary_order($order='desc')
	{
		$this->query_obj->set_order($this->primary_key,$order);
	}

	function get_query_result()
	{
		# 设置 记录范围
		$this->query_obj->set_limit( $this->records_limit,$this->first_record );

		$query_return_clms = array('*') ;
		# $this->column 中的字段
		/*$query_return_clms = array();
		foreach ($this->columns as $item)
			$query_return_clms[] = $item->columnName;

		# 主键
		if( !in_array($this->primary_key,$query_return_clms) )
			$query_return_clms [] = $this->primary_key;

		# is_open 键
		if( !empty($this->status_column_name)
				and !in_array($this->status_column_name,$query_return_clms) )
			$query_return_clms [] = $this->status_column_name;*/

		# 获得 $this->query_obj 对象中的 查询结果
		//pp( $this->query_obj->make_sql() );
		$this->query_cnt
			= $this->query_obj->get_result( $this->query_list,$query_return_clms );
	}

	function reset_list()
	{
		$this->list = array();
	}

	function set_list()
	{
		$this->reset_list();
		$this->_touch_user_event( EVENT_BEFORE_QUERY );
		
		$this->get_query_result();				// 从数据库获得数据

		foreach ($this->query_list as $idx=>$theRecord)
		{
			$this->data = $theRecord;			// 将数据库返回的数据 传递给 索引对象

			$this->set_data();					// 用 data 中的数据 初始化索引对象中的栏位
	
			$this->_touch_user_event( EVENT_BEFORE_INIT_RECORD, $this );

			// 将栏位中的信息添加到 $this->list 变量中
			foreach ($this->fields as $fldName=>$fldInstance)
			{
				$this->list [$idx]['_'.$fldName] = $fldInstance->value;

				if( !in_array($fldInstance->inputType,$this->upload_fld_input_type) )
					$this->list [$idx][$fldName] = $fldInstance->show_txt();
				else
					$this->list [$idx][$fldName] = $fldInstance->show_pic();

			}

			# primary key
			if( isset($this->data[ $this->primary_key ]) and !isset($this->list [$idx][ $this->primary_key ]) )
				$this->list [$idx][ $this->primary_key ] = $this->data[ $this->primary_key ];
				
			# 状态
			if( isset($this->data[ $this->status_column_name ]) )
			{
				$this->list [$idx]['show_status'] = $this->show_status();
				$this->list [$idx]['_status'] = $this->data[ $this->status_column_name ];
			}
			
			# 源数据
			$this->list [$idx]['_data'] = $this->data ;
			
			
			$this->_touch_user_event( EVENT_INITIALIZED_RECORD, &$this->list [$idx] );
		}
		
		

	}

	function set_records_limit($cnt)
	{
		if( $this->records_limit == $cnt )
			return true;

		$this->records_limit = $cnt;
		
		// 重新计算当前页数
		$this->current_page_num = $this->firstIdx2pageNum($this->first_record);
	}
	
	function set_upload_column($clmName,$class_file='')
	{
		$clmInstance = $this->get_fld_clm_obj('column',$clmName,$class_file);
	
		$upload_flds = array();
		foreach ($clmInstance->fields as $fldName=>$theFld)
		{
			if( !is_object($theFld) )		// 如果尚未创建实例
				$theFld = $this->get_fld_clm_obj('field',$fldName);

			if( in_array($theFld->inputType,$this->upload_fld_input_type) )
				$upload_flds[$fldName] = $theFld;

		}

		if( count($upload_flds) )
		{

			# 加载 尚未实例化的 字段
			if( !isset($this->columns[$clmName]) )
				$this->columns[$clmName] = $clmInstance;
			
			# 标记为 上传字段
			$this->upload_columns[$clmName] = & $this->columns[$clmName];

			# 加载 尚未实例化的 栏位
			foreach ($upload_flds as $fldName=>$theFld)
			{
				# 加载 尚未实例化的 栏位
				if( !isset($this->fields[$fldName]) )
				{
					# 加入到 栏位容器中
					$this->fields[$fldName] = $theFld;
					
					# 引用为 相关 字段的来源来位
					$this->columns[$clmName]->fields[$fldName] = & $this->fields[$fldName];
				}
				
				# 标记为 上传栏位
				$this->upload_fields[$fldName] = & $this->fields[$fldName];			
			}

			return true;
		}
		else
		{
			$this->create_msg(__CLASS__.'::'.__FUNCTION__."()函数遇到异常,指定字段({$clmName})的来源栏位中并无上传类型。");
			return true;
		}
	}
	
	function get_upload_files()
	{
		if( empty($this->upload_columns) )
			# $this->bad(__CLASS__.'::'.__FUNCTION__.'() 函数遇到异常,已知字段中,没有上传类型的来源栏位。无法获得 上传文件');
			return false;


		foreach ($this->upload_columns as $key=>$theClm)
		{
			$data = $this->data[ $this->upload_columns[$key]->columnName ];
			if( empty($data) )
				continue;

			$this->upload_columns[$key]->set_data($data);
		}
		
		$files = array();
		foreach ($this->upload_fields as $key=>$theFld)
			$files[ $key ] = $this->upload_fields[$key]->value;
		
		return $files;
	}
	function delete_upload_files()
	{
		$files = $this->get_upload_files();
		if( !is_array($files) or count($files) == 0 )
			return false;
		
		foreach ($files as $key=>$filename)
		{
			if( empty($filename) )
				continue;
			
			$file_path = $this->upload_path.$filename;
			if( !file_exists( $file_path ) )
			{
				$this->bad("删除上传文件[ {$filename} ]取消:指定的文件不存在。");
				continue;
			}

			if( $this->debug < __DEBUG_NODELETE )
			{
				if( unlink( $file_path ) )
					$this->ok("上传文件[ {$filename} ]已经删除。");
				else
					$this->bad("删除上传文件[{$filename}]时失败了。");
			}
			else
			{
				$this->ok("上传文件[ {$filename} ]已经删除。");
				PP("Delete File:{$key}=>{$file_path}");
			}
		}
		
		return true;
	}

	function action( $if_log=false, $act_user='', $where='1' )
	{
		if( empty($_REQUEST['act']) )
			return false;

		$this->_touch_user_event( EVENT_BEFORE_ACTION, $this ) ;

		$this->query_obj->save();						// 保存查询条件
		$this->query_obj->clearCondition();				// 初始化 查询状态


		$this->query_obj->condition($where);			// 添加来自应用的 查询条件
		
		if( !empty($_REQUEST['act_id']) )
		{
			$this->query_obj->addGroup('record_id_condition');
														// 创建一个条件分组,用于容纳 id 条件
			$_REQUEST['act_id']=(array)$_REQUEST['act_id'];

			foreach ($_REQUEST['act_id'] as $id)
				$this->query_obj->directCondition( array($this->primary_key=>$id) );

			$opObj = '所选'.count($_REQUEST['act_id']).'条记录';
		}
		else
		{
			$opObj = '全部记录';
		}
		
		$where = $this->query_obj->make_where();		// 根据设置的条件,创建一个 where 子句,用于 后面的 update 和 delete 操作


		switch ($_REQUEST['act'])
		{
			case 'chg_status':			// 开启一个记录

				if( !$this->_touch_user_event( EVENT_BEFORE_CHG_STATUS, $this, $where ) )
					break ;
				
				# 纪录
				if( $if_log )
				{
					$now = time() ;
					$logdata = 
						",`{$this->chg_status_log['time_clm']}`=$now, " .
						"`{$this->chg_status_log['ip_clm']}`='{$_SERVER['REMOTE_ADDR']}'" ;
					if( $act_user!=='' )
						$logdata.= ", `{$this->chg_status_log['admin_clm']}`='{$act_user}' ";
				}
				else
					$logdata = '' ;
				$sql = "update `{$this->dbtable}` set `{$this->status_column_name}`='{$_REQUEST['set_status']}' {$logdata} where {$where}" ;
				$r = @mysql_query( $sql );
				$r ?	$this->ok	( "对 {$opObj} 进行操作:{$this->status[ $_REQUEST['set_status'] ]['act_word']} 执行成功。" ) 		:
						$this->bad	( "对 {$opObj} 进行操作:{$this->status[ $_REQUEST['set_status'] ]['act_word']} 执行遇到错误。\r\nError: ".mysql_error() ) 	;				
				
				$this->_touch_user_event( EVENT_AFTER_CHG_STATUS, $this ) ;
				break;

			case 'delete':			// 删除记录
				
				$this->get_query_result();
				if( $this->query_cnt['totalCnt'] == 0 )
				{
					$this->bad('没有可执行的记录。删除请求被取消。');
					break;
				}
				
				$upload_files = array();
				foreach ($this->query_list as $data)
				{
				 	$this->data = $data;
				 	$this->delete_upload_files();
				}
				
				$this->_touch_user_event( EVENT_BEFORE_DELETE, $this, $where ) ;
				$sql="delete from `{$this->dbtable}` where {$where}";
				
				if( $this->debug < __DEBUG_NODELETE )
				{
					$r = mysql_query($sql);
					$r ?	$this->ok	( $opObj.'已经被删除。' ) 		:
							$this->bad	( $opObj.'没有全部被删除。' ) 		;	
				}
				else
				{
					$this->ok($opObj.'已经被删除。');
					pp( $sql );
				}
				
				$this->_touch_user_event( EVENT_AFTER_DELETE, $this ) ;
				break;

			case 'save':			// 直接从索引页修改记录部分栏位
			
				break;


			default:
				
				break;
		}

		
		# 完成 -- --
		unset($_REQUEST['act']);
		unset($_REQUEST['act_id']);
		if( isset($_REQUEST['set_status']) )
			unset($_REQUEST['set_status']);
		
		$this->query_obj->revert();					// 恢复到函数开始时 的查询状态
		
		$this->_touch_user_event( EVENT_AFTER_ACTION, $this ) ;
	}
	
	/**
	 * 已知页数,计算起始记录的偏移量
	 *
	 * @param  int $page
	 */
	function pageNum2firstIdx($page)
	{
		return ($page - 1) * $this->records_limit ;
	}

	/**
	 * 已知起始记录的偏移量,计算页数
	 *
	 * @param  int $first_record_idx
	 */
	function firstIdx2pageNum($first_record_idx)
	{
		return ceil( $first_record_idx / $this->records_limit ) + 1;
	}

	## 页码
	/**
	 * 在模板上输出当前页码
	 *
	 * @param unknown_type $style_name
	 * @return unknown
	 */
	function this_page_num($style_name='pgeIdx_current_page_num')
	{
		$this->assign( 'link_url',false );
		$this->assign( 'link_style',$style_name );
		$this->assign( 'out_txt',(string)$this->current_page_num );		
		return $this->fetch( 'page_num.html' );
	}
	
	/**
	 * 在模板上输出当前页前面的多个页码
	 *
	 * @param unknown_type $cnt
	 * @param unknown_type $style_name
	 * @return unknown
	 */
	function before_page_nums($cnt=5,$style_name='pgeIdx_other_page')
	{
		$return_html	='';
		$start			= 											// 起始页
			( $this->current_page_num-1 > $cnt )?		
				$this->current_page_num - $cnt : 1;
		$end			= $this->current_page_num - 1;				// 终止页

		for($idx=$start;$idx<=$end;$idx++)
		{
			$this->assign( 'link_style',$style_name );
			$this->assign( 'out_txt',(string)$idx );
			$this->assign( 'link_url',$this->page_link($idx) );
			$return_html.= $this->fetch( 'page_num.html' );	
		}
		
		return $return_html;
	}

	/**
	 * 在模板上输出当前页后面的多个页码
	 *
	 * @param unknown_type $cnt
	 * @param unknown_type $style_name
	 * @return unknown
	 */
	function after_page_nums($cnt=5,$style_name='pgeIdx_other_page')
	{
		
		$return_html	 = '';
		$after_pages_cnt = $this->query_cnt['totalPgeCnt'] - $this->current_page_num;
		$start			 = $this->current_page_num + 1;		// 起始页
		$end			 = $this->current_page_num + (( $after_pages_cnt > $cnt )?
								$cnt: $after_pages_cnt);		// 终止页

		for($idx=$start;$idx<=$end;$idx++)
		{
			$this->assign( 'link_style',$style_name );
			$this->assign( 'out_txt',(string)$idx );
			$this->assign( 'link_url',$this->page_link($idx) );
			$return_html.= $this->fetch( 'page_num.html' );	
		}
		
		return $return_html;
	}

	/**
	 * 在模板上输出上一页的链接
	 *
	 * @param unknown_type $txt
	 * @param unknown_type $style_name
	 */
	function prev_page_num($txt='上一页',$style_name='')
	{
		if( $this->current_page_num > 1 )								// 有上一页  -- --
		{
			empty($style_name)?$style_name='pgeIdx_other_page':null;	// 默认样式
			$this->assign( 'link_url',$this->page_link($this->current_page_num - 1) );
																		// 链接url
		}
		else															// 无上一页  -- --
		{
			empty($style_name)?$style_name='pgeIdx_none_link':null;	// 默认样式
			$this->assign( 'link_url',false );							// 链接url
		}

		$this->assign( 'out_txt',(string)$txt );
		$this->assign( 'link_style',$style_name );
		return $this->fetch( 'page_num.html' );	
	}
	
	/**
	 * 在模板上输出下一页的链接
	 *
	 * @param unknown_type $txt
	 * @param unknown_type $style_name
	 */
	function next_page_num($txt='下一页',$style_name='')
	{
		if( $this->query_cnt['totalPgeCnt'] > $this->current_page_num )	// 有下一页  -- --
		{
			empty($style_name)?$style_name='pgeIdx_other_page':null;	// 默认样式
			$this->assign( 'link_url',$this->page_link($this->current_page_num + 1) );
																		// 链接url
		}
		else															// 无下一页  -- --
		{
			empty($style_name)?$style_name='pgeIdx_none_link':null;	// 默认样式
			$this->assign( 'link_url',false );							// 链接url
		}

		$this->assign( 'out_txt',(string)$txt );
		$this->assign( 'link_style',$style_name );
		return $this->fetch( 'page_num.html' );	
	}
	
	/**
	 * 在模板上输出第一页的链接
	 *
	 * @param unknown_type $txt
	 * @param unknown_type $style_name
	 */
	function first_page_num($txt='第一页',$style_name='')
	{
		if($this->current_page_num > 1 )
		{
			$this->assign( 'link_url',$this->page_link(1) );
			empty($style_name)?
				$style_name = 'pgeIdx_other_page':null;
		}
		else
		{
			$this->assign( 'link_url',false );
			empty($style_name)?
				$style_name = 'pgeIdx_current_page':null;
		}

		$this->assign( 'out_txt',(string)$txt );
		$this->assign( 'link_style',$style_name );
		return $this->fetch( 'page_num.html' );	
	}
	
	/**
	 * 在模板上输出最终页的链接
	 *
	 * @param unknown_type $txt
	 * @param unknown_type $style_name
	 */
	function last_page_num($txt='最终页',$style_name='')
	{
		
		if( $this->current_page_num < $this->query_cnt['totalPgeCnt'] )
		{
			$this->assign( 'link_url',$this->page_link($this->query_cnt['totalPgeCnt']) );
			empty($style_name)?
				$style_name = 'pgeIdx_other_page':null;
		}
		else
		{
			$this->assign( 'link_url',false );
			empty($style_name)?
				$style_name = 'pgeIdx_current_page':null;
		}

		
		$this->assign( 'out_txt',(string)$txt );
		$this->assign( 'link_style',$style_name );
		return $this->fetch( 'page_num.html' );	
	}

	function page_link($page_num)
	{
		$query=array();
		if( preg_match_all("/([^=&]+)((=)?([^&=]+))?/",$_SERVER['QUERY_STRING'],$re) )
		{
			foreach ($re[1] as $idx=>$key)
			{
				if( $key == $this->first_record_tag )
					continue;

				/*if( !isset($_REQUEST[$key]) )			// 有些会影响到 数据库操作的 get 参数在使用后,会被立即删除
					continue;*/

				$query[]= "{$key}={$re[4][$idx]}";
			}
		}

		$first_idx = $this->pageNum2firstIdx($page_num);
		$query[]="{$this->first_record_tag}=$first_idx";

		return $_SERVER['PHP_SELF'].'?'.implode('&',$query);
	}
	
	function set_cols($cols,$list=array())
	{
		if( empty($list) )
			$list = & $this->list;

		if( empty($list) )
			return false;		

		reset($list);
		$a = $list;
		$list = array();

		$idx=0;
		while($item=current($a))
		{
			
			for($i=0;$i<$cols;$i++)
			{	
				if(!$item=current($a))
					break;
	
				$list[$idx][$i]=$item;
				next($a);
			}
	
			$idx++;
		}
		
		return $list;
	}
}
?>