<?php

/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */

/**
 * 検索実行
 *
 * @package     NetCommons
 * @author      Noriko Arai,Ryuji Masukawa
 * @copyright   2006-2007 NetCommons Project
 * @license     http://www.netcommons.org/license.txt  NetCommons License
 * @project     NetCommons Project, supported by National Institute of Informatics
 * @access      public
 */
class User_Action_Main_Search extends Action
{
	// リクエストパラメータを受け取るため
	var $items = null;
	var $sel_room_id_list = null;
	var $refresh_flag = null;	//再表示時、使用(会員の削除)
	
	// フィルタによりセット
	var $room_id_arr = null;
	var $room_arr_flat = null;
	
	// 使用コンポーネントを受け取るため
	var $db = null;
	var $session = null;
	var $usersView = null;
	var $authoritiesView = null;
	
	// 値をセットするため
	var $count = null;
	var $authorities_str = "";
	
	/**
	 * execute実行
	 *
	 * @access  public
	 */
	function execute()
	{
		if($this->refresh_flag != _ON) {
			$auth_id = $this->session->getParameter("_auth_id");
			//if($auth_id >= _AUTH_CHIEF) $chief_flag = _ON;
			if($auth_id == _AUTH_ADMIN) $chief_flag = _ON;
			else $chief_flag = _OFF;
			// 会員管理の権限を用いるように修正
			if($this->session->getParameter("_user_auth_id") == _AUTH_ADMIN) {
	    		$user_auth_id = _AUTH_ADMIN;
	    	} else {
	    		$user_auth_id = $this->session->getParameter("_auth_id");
	    	}
	    	
	    	//$user_auth_id = $this->session->getParameter("_user_auth_id");
	    	//$this->user =& $this->usersView->getUserById($this->user_id);
	    	//if($this->user === false) return 'error';
	    	$where_params = array(
	    						"user_authority_id" => $user_auth_id
	    					);
	    	$result =& $this->usersView->getItems($where_params, null, null, null, array($this, "_getItemsFetchcallback"));
	    	if($result === false) return 'error';
	    	list($items, $tags_items) = $result;
	    	
			//
			// SQL文作成処理
			//
			$select_str = "SELECT {users}.*, {authorities}.role_authority_name, {authorities}.user_authority_id, ".
							"{authorities}.system_flag AS  auth_system_flag,".
							"email_users_items_link.content AS email, ".	//email_users_items_link.public_flag AS email_public_flag, ".
							"user_name_users_items_link.content AS user_name, user_name_users_items_link.public_flag AS user_name_public_flag ";
			$from_str = " FROM {authorities},{users} ".
						" LEFT JOIN {users_items_link} user_name_users_items_link ON {users}.user_id = user_name_users_items_link.user_id".
						" AND user_name_users_items_link.item_id=".$tags_items['user_name']['item_id'].
						" LEFT JOIN {users_items_link} email_users_items_link ON {users}.user_id = email_users_items_link.user_id ".
						" AND email_users_items_link.item_id=".$tags_items['email']['item_id'] ." ";
			$where_str = " WHERE {users}.role_authority_id={authorities}.role_authority_id";
			
			
			$where_params = array();
			$from_params = array();
			//初期化し設定
			$this->session->removeParameter(array("user", "search"));
			foreach($this->items as $item_id => $item_value) {
				if(isset($items[$item_id])) {
					if(is_array($item_value)) {
						//日付関連 何日以上前～何日以内 OR　チェックボックス
						foreach($item_value as $key => $value) {
							$this->_createWhereArray($from_str, $from_params, $where_str, $where_params, $items[$item_id], $value, "_".$key);
						}
					} else {
						$this->_createWhereArray($from_str, $from_params, $where_str, $where_params, $items[$item_id], $item_value);
					}
				}
			}
			//
			// 参加ルーム
			//	
			$not_enroll_flag = false;
			if($this->sel_room_id_list == "USER_NOT_ENROLL" && $user_auth_id == _AUTH_ADMIN) {
				// ルームに参加していない会員
				// 管理者の場合のみ
				// ルームに参加していない会員を求める
				$not_enroll_flag = true;
				// 検索条件をセッションに保存 item_id=0を使用
				$this->session->setParameter(array("user", "search", 0), "USER_NOT_ENROLL");
			} else if($this->sel_room_id_list != null && in_array( intval($this->sel_room_id_list), $this->room_id_arr )) {
				//参加ルーム指定あり
				$this->room_id_arr = array();
				$this->room_id_arr[] = intval($this->sel_room_id_list);
				// 検索条件をセッションに保存 item_id=0を使用
				$this->session->setParameter(array("user", "search", 0), $this->sel_room_id_list);
			} else if($user_auth_id == _AUTH_ADMIN) {
				// 管理者　すべての会員
				$this->room_id_arr = null;
			}
			//
			// グループスペースのみセット
			//
			$room_id_arr = null;
			if($this->room_id_arr != null){
				$room_id_arr = array();
				foreach($this->room_id_arr as $room_id) {
					if ($this->room_arr_flat[$room_id]['space_type'] == _SPACE_TYPE_GROUP &&
						$this->room_arr_flat[$room_id]['private_flag'] == _OFF) {
						$room_id_arr[] = $room_id;
					}
				}
			}
			if($room_id_arr != null){
				// 自分のルームに参加している会員を取得
				// デフォルトで参加するルームが１つでもあればすべての会員から検索
				// 但し、pages_users_link-authority_idが_AUTH_OTHER(不参加)されたものは引く
				$default_entry_room_arr = array();
				$default_entry_flag = false;
				if($this->sel_room_id_list != null && $this->sel_room_id_list != "USER_NOT_ENROLL") {
					// 参加ルーム指定あり
					if(isset($this->room_arr_flat[$this->sel_room_id_list]) && 
						$this->room_arr_flat[$this->sel_room_id_list]['default_entry_flag'] == _ON &&
						$this->room_arr_flat[$this->sel_room_id_list]['space_type'] == _SPACE_TYPE_GROUP &&
						$this->room_arr_flat[$this->sel_room_id_list]['private_flag'] == _OFF) {
						// デフォルトで参加しているグループルームあり
						$default_entry_room_arr[$this->room_arr_flat[$this->sel_room_id_list]['page_id']] = $this->room_arr_flat[$this->sel_room_id_list]['page_id'];
						$default_entry_flag = true;
					}
				} else {
					foreach($this->room_arr_flat as $room) {
						if($room['default_entry_flag'] == _ON && $room['space_type'] == _SPACE_TYPE_GROUP &&
							 $room['private_flag'] == _OFF) {
							// デフォルトで参加しているグループルーム
							$default_entry_room_arr[$room['page_id']] = $room['page_id'];
							$default_entry_flag = true;
						}
					}
				}
				
				$pages_users_id_arr =& $this->usersView->getPagesUsersLinkByRoom($room_id_arr, null,null,null, null, array($this, "_getPagesUsersLinkFetchcallback"), array($not_enroll_flag, $default_entry_flag, $default_entry_room_arr));
				if($pages_users_id_arr === false) {
					return 'error';
				}
				// ルームに参加していない会員
				$sel_default_entry_flag = $default_entry_flag;
				if($not_enroll_flag == true) {
					$sel_default_entry_flag = ($default_entry_flag == true) ? false : true;	
				}
				if($sel_default_entry_flag) {
					// 禁止者を省く	
					if($pages_users_id_arr != null) {
						$where_str .= " AND {users}.user_id NOT IN ('". implode("','", $pages_users_id_arr). "') ";
					}
				} else {
					// 自分のルームに参加している会員を取得
					// 自分自身は必ず検索結果に含める
					if($this->sel_room_id_list == null) {
						$pages_users_id_arr[] = $this->session->getParameter("_user_id");
					}
					$where_str .= " AND {users}.user_id IN ('". implode("','", $pages_users_id_arr). "') ";
				}
			}
		
			$params = array_merge($from_params, $where_params);
			
			// レコード数取得
			$count_sql = "SELECT COUNT(*) ";
			$count_sql .= $from_str.$where_str;
			$count_result =& $this->db->execute($count_sql, $params, null, null, false);
			if($count_result === false) {
				$this->db->addError();
				return 'error';
			}
			$this->count = intval($count_result[0][0]);
			////$sql = $select_str.$from_str.$where_str;
			
			//$sql = $select_str.$from_str.$where_str.$order_str;
			//$this->users =& $this->db->execute($sql, $params, intval($this->limit), intval($this->offset));
			//if($this->users === false) {
			//	$this->db->addError();
			//	return 'error';
			//}
			// 検索条件をセッションに保存
			$this->session->setParameter(array("user", "selected_select_str"), $select_str);
			$this->session->setParameter(array("user", "selected_where_str"), $from_str.$where_str);
			$this->session->setParameter(array("user", "selected_params"), $params);
			
			//
			// 表示項目-非表示項目
			//
			$loop_array = array(
				"handle",
				"login_id",
				"user_name",
				"role_authority_name",
				"active_flag",
				"insert_time",
				"last_login_time",
				"manage"
			);
			foreach($loop_array as $value) {
				if($value == "manage") {
					$display_flag = $chief_flag;
				} else if($tags_items[$value]['display_flag'] == _OFF) {
					$display_flag = _OFF;
				} else if($tags_items[$value]['under_public_flag'] >= USER_PUBLIC || $tags_items[$value]['over_public_flag'] >= USER_PUBLIC) {
					$display_flag = _ON;
				} else {
					$display_flag = _OFF;
				}
				// public_flagをセッションに保存
				$this->session->setParameter(array("user", "display_flag", $value), $display_flag);
			}
		} else {
			$params =& $this->session->getParameter(array("user", "selected_params"));
			$count_sql = "SELECT COUNT(*) ";
			$count_sql .= $this->session->getParameter(array("user", "selected_where_str"));
			$count_result =& $this->db->execute($count_sql, $params, null, null, false);
			if($count_result === false) {
				$this->db->addError();
				return 'error';
			}
			$this->count = intval($count_result[0][0]);
		}
		if($this->session->getParameter(array("user", "display_flag", "manage"))) {
			// エクスポートできない権限の一覧を文字列として取得
			$where_params = array("user_authority_id>=".$this->session->getParameter("_user_auth_id") => null);
			$order_params = array("hierarchy" => "DESC");
			$authorities = $this->authoritiesView->getAuthorities($where_params, $order_params);
			if($authorities === false) {
				return 'error';
			}
			foreach($authorities as $authority) {
				if($this->authorities_str != "") $this->authorities_str .= ",";
				$this->authorities_str .= $authority['role_authority_name'];
			}
		}
		return 'success';
	}
	/**
	 * Where配列作成処理
	 *
	 * @access  private
	 */
	function _createWhereArray(&$from_str, &$from_params, &$where_str, &$where_params, $item, $value, $rename_post_fix = "") {
		if($value != "") {
			if($item['tag_name'] != "" && $item['tag_name'] != "user_name" && $item['tag_name'] != "email") {
				$tag_name = "";
				switch ($item['tag_name']) {
					case "password":
					case "lang_dirname_lang":
						// 検索不可
						break;
					case "timezone_offset_lang":
						// タイムゾーン
						$from_str .= " INNER JOIN {users_items_link} users_items_link".$item['item_id'].$rename_post_fix." ON (users_items_link".$item['item_id'].".item_id=? && users_items_link".$item['item_id'].$rename_post_fix.".content = ? && {users}.user_id=users_items_link".$item['item_id'].$rename_post_fix.".user_id)";
						$from_params[] = $item['item_id'];
						$from_params[] = $value . "|";
						break;
					case "role_authority_name":
						$tag_name = "role_authority_id";
						$value_arr = explode("|", $value);
						$value = intval($value_arr[0]);
						
						$where_str .= " AND {users}.".$tag_name." = ?";
						$where_params[] = $value;
						break;
					case "active_flag_lang":
						$tag_name = "active_flag";
						$value_arr = explode("|", $value);
						$value = intval($value_arr[1]);
						
						$where_str .= " AND {users}.".$tag_name." = ?";
						$where_params[] = $value;
						break;
					case "insert_time":
					case "update_time":
					case "password_regist_time":
					case "last_login_time":
						$tag_name = $item['tag_name'];
						if($rename_post_fix == "_0") {
							// 日以上前 <=
							$operator = "<=";
						} else {
							// 日以内 >=
							$operator = ">=";
						}
						$value = intval($value);
						$time = timezone_date();
						$time = mktime(intval(substr($time, 8, 2)), intval(substr($time, 10, 2)), 
											intval(substr($time, 12, 2)), intval(substr($time, 4, 2)), 
											intval(substr($time, 6, 2)) - $value, intval(substr($time, 0, 4)));
						$time = date("YmdHis", $time);
						
						$where_str .= " AND {users}.".$tag_name." ".$operator." ?";
						$where_params[] = $time;
						
						break;
					default :
						$tag_name = $item['tag_name'];
						$where_str .= " AND {users}.".$tag_name." LIKE ?";
						$where_params[] = "%".$value."%";
				}
			} else {
				if($item['type'] == "select" || $item['type'] == "radio" || $item['type'] == "checkbox") {
					//デフォルト値取得
					
					//$default_selected_arr = explode("|", $item['default_selected']);
					//$options_arr = explode("|", $item['options']);
					//$default_flag = false;
					//$count= 0;
					//foreach($default_selected_arr as $default_selected) {
					//	if($options_arr[$count] == $value) {
					//		if($default_selected == _ON) $default_flag = true;
					//		break;
					//	}
					//	$count++;
					//}
					//if($default_flag) {
					//	$from_str .= " LEFT JOIN {users_items_link} users_items_link".$item['item_id'].$rename_post_fix." ON (users_items_link".$item['item_id'].$rename_post_fix.".item_id=? && {users}.user_id=users_items_link".$item['item_id'].$rename_post_fix.".user_id)";
					//	$from_params[] = $item['item_id'];
					//	$where_str .= " AND (users_items_link".$item['item_id'].$rename_post_fix.".content LIKE ? OR users_items_link".$item['item_id'].$rename_post_fix.".content IS NULL)";
					//	$where_params[] = "%".$value . "|" ."%";
					//} else {
						$from_str .= " INNER JOIN {users_items_link} users_items_link".$item['item_id'].$rename_post_fix." ON (users_items_link".$item['item_id'].$rename_post_fix.".item_id=? && users_items_link".$item['item_id'].$rename_post_fix.".content LIKE ? && {users}.user_id=users_items_link".$item['item_id'].$rename_post_fix.".user_id)";
						$from_params[] = $item['item_id'];
						$from_params[] = "%".$value . "|" ."%";
					//}				
				} else {
					$from_str .= " INNER JOIN {users_items_link} users_items_link".$item['item_id'].$rename_post_fix." ON (users_items_link".$item['item_id'].$rename_post_fix.".item_id=? && users_items_link".$item['item_id'].$rename_post_fix.".content LIKE ? && {users}.user_id=users_items_link".$item['item_id'].$rename_post_fix.".user_id)";
					$from_params[] = $item['item_id'];
					$from_params[] = "%".$value."%";
				}
			}
			// session登録処理
			// 検索条件をセッションに保存
			if($rename_post_fix == "") {
				$this->session->setParameter(array("user", "search", $item['item_id']), $value);
			} else {
				$this->session->setParameter(array("user", "search", $item['item_id'], substr($rename_post_fix, 1, strlen($rename_post_fix) - 1)), $value);
			}
		}
	}
	
	/**
	 * fetch時コールバックメソッド
	 * @param result adodb object
	 * @return array items
	 * @access	private
	 */
	function _getItemsFetchcallback($result) {
		$ret = array();
		$ret_tags = array();
		while ($row = $result->fetchRow()) {
			$ret[$row['item_id']] = $row;
			if(isset($row['tag_name']) && $row['tag_name'] !="") {
				switch ($row['tag_name']) {
					case "active_flag_lang":
						$tag_name = "active_flag";
						break;
					case "timezone_offset_lang":
						$tag_name = "timezone_offset";
						break;
					default :
						$tag_name = $row['tag_name'];
				}
				$ret_tags[$tag_name] = $row;
			}
		}
		return array($ret, $ret_tags);
	}
	
	/**
	 * fetch時コールバックメソッド-getPagesUsersLinkByRoom
	 * @param result adodb object
	 * @return array items
	 * @access	private
	 */
	function &_getPagesUsersLinkFetchcallback($result, $func_params) {
		$not_enroll_flag = $func_params[0];
		$default_entry_flag = $func_params[1];
		$default_entry_room_arr =& $func_params[2];
		//if(count($default_entry_room_arr) == 0) {
		//	$default_entry_flag = false;
		//} else {
		//	$default_entry_flag = true;
		//}
		
		$absence_user_arr = array();	//不参加会員
		$ret = array();
		while ($row = $result->fetchRow()) {
			if($row['role_authority_id'] == _ROLE_AUTH_OTHER) {
				//不参加会員
				$absence_user_arr[$row['room_id']][] = $row['user_id'];
			} else {
				$ret[$row['user_id']] = $row['user_id'];
			}
		}
		$user_intersect_arr = null;
		if($default_entry_flag) {
			foreach($default_entry_room_arr as $room_id) {
				if(isset($absence_user_arr[$room_id])) {
					if($user_intersect_arr == null) {
						$user_intersect_arr = $absence_user_arr[$room_id];
					} else {
						// 共通項を求める
						$user_intersect_arr = array_intersect($user_intersect_arr, $absence_user_arr[$room_id]);
					}
				} else {
					// 禁止者が誰もいないデフォルトで参加するルームあり
					// すべての会員から検索する
					$user_intersect_arr = null;
					
					break;
				}
			}
		}
		if($default_entry_flag == false) {
			// 参加者を求める
			return $ret;
		} else if($not_enroll_flag) {
			$ret_user_intersect_arr = array();
			if(is_array($user_intersect_arr)) {
				foreach($user_intersect_arr as $user_intersect) {
					if(!isset($ret[$user_intersect])) {
						$ret_user_intersect_arr[] = $user_intersect;
					}
				}
			}
			return $ret_user_intersect_arr;
		} else {
			// 禁止者を求める
			return $user_intersect_arr;
		}
	}
}
?>