<?php

require_once XOOPS_TRUST_PATH . '/libs/xoonips/class/core/BeanBase.class.php';
require_once XOOPS_TRUST_PATH . '/libs/xoonips/class/core/Utils.class.php';
require_once XOOPS_TRUST_PATH . '/libs/xoonips/class/Enum.class.php';
require_once XOOPS_ROOT_PATH . '/class/xoopsuser.php';
require_once dirname(dirname(__FILE__)) . '/core/UserFieldManager.class.php';

/**
 * @brief operate users table 
 *
 */
class User_UsersBean extends Xoonips_BeanBase {
	private static $userCache = array();
	private $linkTable = null;

	/**
	 * Constructor
	 **/
	public function User_UsersBean($dirname, $trustDirname) {
		$this->Xoonips_BeanBase($dirname, $trustDirname);
		$this->setTableName('users');
		$this->linkTable = $this->prefix('groups_users_link');
	}
	
	/**
	 * 
	 * get userBasicInfo
	 * 
	 * @param
	 * @return array
	 */
	public function getUserBasicInfo($id, $includeExtend = true) {
		if (isset($this->userCache[$id])) {
			return $this->userCache[$id];
		}
		$sql = 'SELECT * FROM ' . $this->table . ' WHERE uid=' . $id;
		$result = $this->execute($sql);
		if (!$result) {
			return false;
		}
		$row = $this->fetchArray($result);
		if (!$row) {
			return false;
		}
		$this->freeRecordSet($result);
		
		if (!$includeExtend) {
			return $row;
		}

		$values = array();
		
		$userFieldManager = User_UserFieldManager::getInstance(true);
    	foreach ($userFieldManager->getFields() as $field) {
    		if (strPos($field->getTableName(), $this->dirname . '_extend') !== false) {
    			if (!$field->getDataType()->isNumericSearch()) {
    				$row[$field->getXmlTag()] = '';
    			} else {
    				$row[$field->getXmlTag()] = 0;
    			}
    			$values = $this->getUserExtend($field->getTableName(),$id);	
    			foreach ($values as $value) {
					$row[$field->getXmlTag()] = $value['value'];
    			}
    		}
    	}
		$resources = array();
        XCube_DelegateUtils::call('Module.User.GetUserMaximumResources', new XCube_Ref($resources), new XoopsUser($id));
		if (count($resources) > 0) {
	        foreach ($resources as $limit) {
		        $row['index_number_limit'] = $limit['indexNumberLimit'];
				$row['item_number_limit'] = $limit['itemNumberLimit'];
				$row['item_storage_limit'] = $limit['itemStorageLimit'];
			}
		} else {
			$row['index_number_limit'] = 0;
			$row['item_number_limit'] = 0;
			$row['item_storage_limit'] = 0;
		}

		$this->userCache[$id] = $row;
		return $row;
	}
	
	/**
	 * 
	 * get userBasicInfo by name
	 * 
	 * @param  var $uname:uname
	 *          var $name:name
	 * @return array
	 */
	public function getUserBasicInfoByName($uname, $name) {
		$ret = array();
		$uname = Xoonips_Utils::convertSQLStrLike($uname);
		$name = Xoonips_Utils::convertSQLStrLike($name);
		$sql = 'SELECT * FROM ' . $this->table . " WHERE uname LIKE '%$uname%' and name LIKE '%$name%' order by uname";
		$result = $this->execute($sql);
		if (!$result) {
			return false;
		}
		
		while ($row = $this->fetchArray($result)) {
			$ret[] = $row;
			$this->userCache[$row['uid']] = $row;
		}
		$this->freeRecordSet($result);

		return $ret;
	}
	
	/**
	 * 
	 * is moderator
	 * 
	 * @param  int $uid:uid
	 * @return array
	 */
	public function isModerator($uid) {
		$ret = false;
		static $moderator_gid = false;
		if ($moderator_gid == false) {
			$moderators = array();
            XCube_DelegateUtils::call('Module.User.GetModerators', new XCube_Ref($moderators));
		    foreach ($moderators as $moderator) {
                $moderator_gid = $moderator->get('groupid');
            }
            if (!$moderator_gid) {
                $moderator_gid = 1;
            } 
		}		
        $linkBean = Xoonips_BeanFactory::getBean('GroupsUsersLinkBean', $this->dirname, $this->trustDirname);
        $linkInfo = $linkBean->getGroupUserLinkInfo($moderator_gid, $uid);
        if ($linkInfo && count($linkInfo) > 0) {
            $ret = true;
        }
	    return $ret;
	}
	
	/**
	 * 
	 * is groupmanger
	 * 
	 * @param  int $groupId:groupid
	 *          int $uid:uid
	 * @return array
	 */
	public function isGroupManager($groupId, $uid) {
		$ret = false;
		$sql = 'SELECT * FROM ' . $this->linkTable . " WHERE groupid=$groupId"
	        . " AND uid=${uid} AND is_admin=" . Xoonips_Enum::GRP_ADMINISTRATOR
	        . ' AND activate<>' . Xoonips_Enum::GRP_US_JOIN_REQUIRED;
	    if (($result = $this->execute($sql))
        		&& $this->getRowsNum($result) > 0) {
            $ret = true;
        } else {
            $ret = false;
        } 
		$this->freeRecordSet($result);
        return $ret;
	}
	
	/**
	 * 
	 * is groupmember
	 * 
	 * @param  int $groupId:groupid
	 *          int $uid:uid
	 * @return array
	 */
	public function isGroupMember($groupId, $uid) {
		$ret = false;
		$sql = 'SELECT * FROM ' . $this->linkTable
	    	. " WHERE groupid=$groupId"
	        . " AND uid=${uid} AND is_admin=" . Xoonips_Enum::GRP_USER
	        . ' AND activate<>' . Xoonips_Enum::GRP_US_JOIN_REQUIRED;
	    if (($result = $this->execute($sql))
	            && $this->getRowsNum($result) > 0) {
            $ret = true;
        } else {
            $ret = false;
        } 
		$this->freeRecordSet($result);
        return $ret;
	}
	
	/**
	 * 
	 * get all users
	 * 
	 * @param
	 * @return boolean
	 */
	public function getAllUsers() {
		$ret = array();
		$sql = "SELECT * FROM $this->table";
		$result = $this->execute($sql);
		if (!$result) {
			return false;
		}
		while ($row = $this->fetchArray($result)) {
			$ret[] = $row;
			$this->userCache[$row['uid']] = $row;
		}
		$this->freeRecordSet($result);
		return $ret;
	}

	public function insert($columns, $values, &$newId, $actkey, $userType) {
		//get system time
		$regtime = time();
		if ($userType == Xoonips_Enum::USER_TYPE_MODERATOR) {
			$columns = $columns . 'user_regdate';
			$values = $values . "'$regtime'";
		} else {
			$columns = $columns . 'actkey,user_regdate';
			$values = $values . "'$actkey','$regtime'";
			$myxoopsConfigUser = Xoonips_Utils::getXoopsConfigs(XOOPS_CONF_USER);
			if ($myxoopsConfigUser['activation_type'] != 1) {
				$columns = $columns . ',level';
				$values = $values . ',0';
			}
		}
		//execute sql
		$sql = "insert into $this->table ($columns) values ($values)";
		if (!$this->execute($sql)) {
			return false;
		} else {
			$newId = $this->getInsertId();
			return true;
		}
	}

	public function insertExtend($table, $uid, $value, $occurrence, $gid=0) {
		$tableName = $this->prefix($table);
		$sql = "insert into $tableName (uid,group_id,value,occurrence_number) values ($uid,$gid,$value,$occurrence)";
		if (!$this->execute($sql)) {
			return false;
		}
		return true;
	}

	public function update($uid, $values) {
		$sql = '';
		foreach ($values as $column => $v) {
			$sql = $sql . $column . '=' .$v[0] .  ',';
		}
		//remove last ','
		$sql = substr($sql, 0, strlen($sql) - 1);
		$sql = "update $this->table set $sql where uid=$uid";
		if (!$this->execute($sql)) {
			return false;
		}
		return true;
	}
	
	/**
	 * 
	 * activateuser
	 * 
	 * @param  $user
	 * @return boolean
	 */
    public function activateUser(&$user) {
		$uid = $user['uid'];
        if ($user['activate'] != Xoonips_Enum::USER_NOT_ACTIVATE && $user['level'] != Xoonips_Enum::USER_NOT_ACTIVATE) {
            return true;
        }
        	
		$sql = 'UPDATE ' . $this->table
	    	. ' set level = ' . Xoonips_Enum::USER_NOT_CERTIFIED
	        . " WHERE uid = $uid";
	            
   		$result = $this->execute($sql);
		if (!$result) {
			return false;
		}

		$sql = 'UPDATE ' . $this->prefix(self::getActivateTableName())
	    	. ' set value = ' . Xoonips_Enum::USER_NOT_CERTIFIED
	        . " WHERE uid = $uid";
	            
   		$result = $this->execute($sql);
		if (!$result) {
			return false;
		}		
		
		return true;
    }

    /**
	 * 
	 * activateuser
	 * 
	 * @param  $user
	 * @return boolean
	 */
    public function inactivateUser(&$user) {
		$uid = $user['uid'];
        if ($user['activate'] != Xoonips_Enum::USER_NOT_ACTIVATE && $user['level'] != Xoonips_Enum::USER_NOT_ACTIVATE) {
            return true;
        }
        	
		$sql = 'UPDATE ' . $this->table
	    	. ' set level = ' . Xoonips_Enum::USER_NOT_ACTIVATE
	        . " WHERE uid = $uid";
	            
   		$result = $this->execute($sql);
		if (!$result) {
			return false;
		}

		$sql = 'UPDATE ' . $this->prefix(self::getActivateTableName())
	    	. ' set value = ' . Xoonips_Enum::USER_NOT_ACTIVATE
	        . " WHERE uid = $uid";
	            
   		$result = $this->execute($sql);
		if (!$result) {
			return false;
		}		
		
		return true;
    }

    /**
	 * 
	 * count activated users
	 * 
	 * @param  $isActivate
	 * @return int count
	 */
    public function getCountActivateUsers($isActivate) {
		$sql = 'select count(uid) as cnt from ' . $this->prefix(self::getActivateTableName()) . ' WHERE value';
		if ($isActivate) {
			$sql .= '=' . Xoonips_Enum::USER_CERTIFIED;
		} else {
			$sql .= '<>' . Xoonips_Enum::USER_CERTIFIED;
		}

   		$result = $this->execute($sql);
		if (!$result) {
			return false;
		}
		$ret = $this->fetchArray($result);

		$this->freeRecordSet($result);
		return $ret['cnt'];
    }

    /**
	 * 
	 * count activated users
	 * 
	 * @param  $isActivate
	 * @return int count
	 */
    public function getCountUsedFieldValue($table, $column, $value) {
		$sql = 'select count(uid) as cnt from ' . $this->prefix($table) . ' WHERE value=' . Xoonips_Utils::convertSQLStr($value);

   		$result = $this->execute($sql);
		if (!$result) {
			return false;
		}
		$ret = $this->fetchArray($result);

		$this->freeRecordSet($result);
		return $ret['cnt'];
    }

    /**
	 * 
	 * pickupUser
	 * 
	 * @param  $user
	 * @return boolean
	 */
    public function pickupUser($user) {
		$uid = $user['uid'];
    	$userFieldManager = User_UserFieldManager::getInstance(true);
    	foreach ($userFieldManager->getFields() as $field) {
    		if (strPos($field->getTableName(), $this->dirname . '_extend') !== false) {
    			if (isset($user[$field->getXmlTag()])) {
    				if(!is_null($field->getFieldGroupId())) $gid = $field->getFieldGroupId();
    				if(!$this->setUserExtend($field->getTableName(),$uid,$user[$field->getXmlTag()], $field->getDataType()->getName(), $gid)){
						return false;
					}
    			}
    		}
    	}
		return true;
    }
    
    public function setUserExtend($tableName, $uid, $value, $dataType, $gid=0) {  
    	$table = $this->prefix($tableName);
    	// delete data  	
    	if(!$this->deleteUserExtend($tableName,$uid)){
    		return false;
    	}    	
    	// insert data
    	if ($dataType == 'int' || $dataType == 'float' || $dataType == 'double' || $dataType == 'date' || $dataType == 'datetype') {
	    	$sql = "insert into $table (uid,group_id,value,occurrence_number) values($uid,$gid,$value,1)";
	    } else {
	    	$sql = "insert into $table (uid,group_id,value,occurrence_number) values($uid,$gid," . Xoonips_Utils::convertSQLStr($value) . ",1)";
	    }
    	$result = $this->execute($sql);
		if (!$result) {
			return false;
		}
		return true;
    }
    
    public function getUserExtend($tableName, $uid) {
    	$ret = array();
    	$table = $this->prefix($tableName);
    	$sql = "select * from $table where uid=$uid order by occurrence_number";
    	$result = $this->execute($sql);
    	if (!$result) {
			return false;
		}
		while ($row = $this->fetchArray($result)) {
			$ret[] = $row;
		}
		$this->freeRecordSet($result);
		return $ret;
    }
    
    /**
	 * 
	 * get usertype
	 * 
	 * @param  int $uid:uid
	 * @return array
	 */
    public function getUserType($uid) {
    	$ret = Xoonips_Enum::USER_TYPE_USER;
    	if ($uid == 0) {
    		$ret = Xoonips_Enum::USER_TYPE_GUEST;
    	}
    	return $ret;
    }
    
    /**
	 * 
	 * is groupadmin
	 * 
	 * @param  int $uid:uid
	 * @return boolean
	 */
    public function isGroupAdmin($uid) {
    	$ret = false;
    	$sql = 'SELECT COUNT(a.uid) AS count '
    		. "FROM $this->linkTable a "
    		. "WHERE a.uid=$uid "
    		. 'AND a.is_admin=' . Xoonips_Enum::GRP_ADMINISTRATOR;
    	$result = $this->execute($sql);	
    	if (!$result) {
    		return false;
    	}
    	$row = $this->fetchArray($result);
    	if ($row && $row['count'] != 0) {
    		$ret = true;
    	}
    	$this->freeRecordSet($result);
    	return $ret;
    }
    
    /**
	 * 
	 * get groupsuser
	 * 
	 * @param  int $uid:uid
	 *          $activate
	 * @return array
	 */
    public function getGroupsUsers($uid, $activate) {
    	$ret = array();
    	$sql = "SELECT groupid FROM $this->linkTable "
	    	. "WHERE uid=$uid AND activate=$activate";
    	$result = $this->execute($sql);
    	if (!$result) {
    		return false;
    	}
    	while ($row = $this->fetchArray($result)) {
    		$ret[] = $row['groupid'];
    	}
    	$this->freeRecordSet($result);
    	return $ret;
    }
    
    /**
	 * 
	 * delete groupsuser
	 * 
	 * @param  int $uid:uid
	 *          $activate
	 * @return boolean
	 */
    public function deleteGroupsUsers($uid, $activate) {
    	$sql = "DELETE FROM $this->linkTable WHERE uid=$uid AND activate=$activate";
    	$result = $this->execute($sql);
    	if (!$result) {
    		return false;
    	}
    	
    	return true;
    }
    
    /**
	 * 
	 * delete groupsuser
	 * 
	 * @param  int $uid:uid
	 *         
	 * @return boolean
	 */
    public function deleteGroupsUsersByUid($uid) {
    	$sql = "DELETE FROM $this->linkTable WHERE uid=$uid";
    	$result = $this->execute($sql);
    	if (!$result) {
    		return false;
    	}
    	
    	return true;
    }
	
    /**
	 * 
	 * get user
	 * 
	 * @param  int $uid:uid
	 * @return boolean
	 */
    public function deleteUsers($uid) {
    	$sql = "DELETE FROM $this->table WHERE uid=$uid";
    	$result = $this->execute($sql);
    	if (!$result) {
    		return false;
    	}
    	
    	return true;
    }
    
    /**
	 *
	 * delete userextend
	 * 
	 * @param  var $tablename:tablename
	 *          int $uid:uid
	 * @return array
	 */
    public function deleteUserExtend($tableName, $uid) {
    	$table = $this->prefix($tableName);
    	$sql = "DELETE FROM $table WHERE uid=$uid";
    	$result = $this->execute($sql);
    	if (!$result) {
    		return false;
    	}
    	
    	return true;
    }
    
    public function getUserExtendTable() {
    	$ret = array();
    	$table = $this->prefix($this->dirname . '_field_detail');
    	$sql = "SELECT DISTINCT table_name FROM $table";
    	$result = $this->execute($sql);
   		if (!$result) {
    		return false;
    	}
    	while ($row = $this->fetchArray($result)) {
    		if (strPos($row['table_name'], $this->dirname . '_extend') !== false) {
    			$ret[] = $row['table_name'];
    		}
    	}
    	$this->freeRecordSet($result);
    	return $ret;
    }
    
    public function getGroupsUsersLinkByUid($uid) {
    	$ret = array();
    	$sql = "SELECT * FROM $this->linkTable WHERE uid=$uid";
    	$result = $this->execute($sql);
    	if (!$result) {
    		return false;
    	}
    	while ($row = $this->fetchArray($result)) {
    		$ret[] = $row;
    	}
    	$this->freeRecordSet($result);
    	return $ret;
    }
    
     public function getUsersGroups($groupId, $is_admin = false) {
    	$ret = array();
    	$tblUser = $this->prefix('users');
    	if ($is_admin) {
    		$sql = "select b.* from $this->linkTable a inner join $tblUser b on a.uid=b.uid where a.groupid=$groupId AND a.is_admin=" . Xoonips_Enum::GRP_ADMINISTRATOR;
    	} else {
    		$sql = "select b.* from $this->linkTable a inner join $tblUser b on a.uid=b.uid where a.groupid=$groupId AND a.is_admin=" . Xoonips_Enum::GRP_USER;
    	}
    	$result = $this->execute($sql);
    	if (!$result) {
    		return false;
    	}
    	while ($row = $this->fetchArray($result)) {
    		$ret[] = $row;
    	}
    	$this->freeRecordSet($result);
    	return $ret;
    }
    
    public function getUsersInfoByGroupId($groupId) {
    	$ret = array();
    	$tblUser = $this->prefix('users');
    	$sql = "select b.* from $this->linkTable a inner join $tblUser b on a.uid=b.uid where a.groupid=$groupId";
    	$result = $this->execute($sql);
    	if (!$result) {
    		return false;
    	}
    	while ($row = $this->fetchArray($result)) {
    		$ret[] = $row;
    	}
    	$this->freeRecordSet($result);
    	return $ret;
    }
    
    /**
	 * 
	 * is user Certified
	 * 
	 * @param  int $uid:uid
	 * @return bool true:yes,false:no
	 */
    public function isCertified($uid) {
    	$user = $this->getUserBasicInfo($uid);
    	if ($user!= false && $user['activate'] == Xoonips_Enum::USER_CERTIFIED) {
    		return true;
    	} else {
    		return false;
    	}
    }

    private static function getActivateTableName() {
    	$userFieldManager = User_UserFieldManager::getInstance(true);
    	foreach ($userFieldManager->getFields() as $field) {
    		if ($field->getXmlTag() == 'activate') {
				return $field->getTableName();    		
    		}
    	}
    	return $this->dirname . '_extend35';
    }

    /**
	 * 
	 * certify user
	 * 
	 * @param  $user
	 * @return bool true:yes,false:no
	 */
    public function certifiyUser(&$user) {
		$uid = $user['uid'];
        if ($user['activate'] == Xoonips_Enum::USER_CERTIFIED) {
            return true;
        }

		$sql = 'UPDATE ' . $this->prefix(self::getActivateTableName())
	    	. ' set value = ' . Xoonips_Enum::USER_CERTIFIED
	    	. " WHERE uid = $uid";

	    $result = $this->execute($sql);
		if (!$result) {
			return false;
		}
		
    	$sql = 'UPDATE ' . $this->table	. ' set level=' . Xoonips_Enum::USER_CERTIFIED . " WHERE uid = $uid";

	    $result = $this->execute($sql);
		if (!$result) {
			return false;
		}
		return true;
    }
    
    /**
	 * 
	 * recountPost
	 * 
	 * @param  int $posts
	 * @param  obj $xoopsUser
	 * @return bool true:yes,false:no
	 */
    public function recountPost($posts, $xoopsUser) {
		$uid = $xoopsUser->get('uid');
		$sql = 'UPDATE ' . $this->table
	    	. " set posts = $posts"
	    	. " WHERE uid = $uid";
	            
   		$result = $this->execute($sql);
		if (!$result) {
			return false;
		}
		return true;
    }

    /**
	 * 
	 * addPost
	 * 
	 * @param  int $uid:uid
	 * @return bool true:yes,false:no
	 */
    public function addPost($uid) {
		$sql = 'UPDATE ' . $this->table
	    	. " set posts = posts + 1"
	    	. " WHERE uid = $uid";
	            
   		$result = $this->execute($sql);
		if (!$result) {
			return false;
		}
		return true;
    }

    /**
	 * 
	 * subtractPost
	 * 
	 * @param  int $uid:uid
	 * @return bool true:yes,false:no
	 */
    public function subtractPost($uid) {
		$sql = 'UPDATE ' . $this->table
	    	. " set posts = posts - 1"
	    	. " WHERE uid = $uid";
	            
   		$result = $this->execute($sql);
		if (!$result) {
			return false;
		}
		return true;
    }
}

