1320 lines
48 KiB
PHP
1320 lines
48 KiB
PHP
<?php
|
|
class imChat extends model
|
|
{
|
|
/**
|
|
* Get a chat by gid.
|
|
*
|
|
* @param string $gid
|
|
* @param bool $getMembers
|
|
* @param bool $format format the chat or return its data as is.
|
|
* @param bool $getLastMessage
|
|
* @access public
|
|
* @return object
|
|
*/
|
|
public function getByGid($gid = '', $getMembers = false, $format = true, $getLastMessage = false)
|
|
{
|
|
$chat = $this->dao->select('*')->from(TABLE_IM_CHAT)->where('gid')->eq($gid)->fetch();
|
|
|
|
if($chat && $format)
|
|
{
|
|
$chat = $this->format($chat, $getLastMessage);
|
|
if($getMembers) $chat->members = $this->getMembers($gid);
|
|
}
|
|
|
|
return $chat;
|
|
}
|
|
|
|
/**
|
|
* Get public chat list that user not join.
|
|
*
|
|
* @param int $userID
|
|
* @access public
|
|
* @return array
|
|
*/
|
|
public function getPublicList($userID)
|
|
{
|
|
$joinedChats = $this->dao->select('cgid')->from(TABLE_IM_CHATUSER)
|
|
->where('user')->eq($userID)
|
|
->andWhere('quit')->eq('0000-00-00 00:00:00')
|
|
->fetchAll();
|
|
|
|
$joinedChats = array_map(function($chat) { return $chat->cgid; }, $joinedChats);
|
|
|
|
$chats = $this->dao->select('*')->from(TABLE_IM_CHAT)
|
|
->where('public')->eq(true)
|
|
->andWhere('dismissDate')->eq('0000-00-00 00:00:00')
|
|
->andWhere('mergedDate')->eq('0000-00-00 00:00:00')
|
|
->andWhere('archiveDate')->eq('0000-00-00 00:00:00')
|
|
->andWhere('gid')->notin($joinedChats)
|
|
->fetchAll();
|
|
|
|
return $this->format($chats);
|
|
}
|
|
|
|
/**
|
|
* Get chat gid list by userID.
|
|
*
|
|
* @param int $userID
|
|
* @param bool $includeMerged
|
|
* @access public
|
|
* @return array
|
|
*/
|
|
public function getGidListByUserID($userID = 0, $includeMerged = false)
|
|
{
|
|
$systemChatGidList = $this->dao->select('gid')->from(TABLE_IM_CHAT)
|
|
->where('type')->eq('system')
|
|
->fetchPairs('gid');
|
|
$gidList = $this->dao->select('t1.gid')->from(TABLE_IM_CHAT)->alias('t1')
|
|
->leftJoin(TABLE_IM_CHATUSER)->alias('t2')->on('t2.cgid=t1.gid')
|
|
->where('t2.user')->eq($userID)
|
|
->andWhere('t2.quit', $includeMerged)->eq('0000-00-00 00:00:00')
|
|
->beginIF($includeMerged)->orWhere('t1.mergedDate')->ne('0000-00-00 00:00:00')->markRight()->fi()
|
|
->fetchPairs('gid');
|
|
return array_merge($systemChatGidList, $gidList);
|
|
}
|
|
|
|
/**
|
|
* Get chat list by userID.
|
|
*
|
|
* @param int $userID
|
|
* @access public
|
|
* @return array
|
|
*/
|
|
public function getListByUserID($userID = 0)
|
|
{
|
|
$limit = isset($this->config->dismissedGroupLife) ? $this->config->dismissedGroupLife : 90;
|
|
$chats = $this->dao->select('chat.*, cu.star, cu.hide, cu.mute, cu.freeze, cu.category, cu.lastReadMessage, cu.lastReadMessageIndex')
|
|
->from(TABLE_IM_CHAT)->alias('chat')
|
|
->leftJoin(TABLE_IM_CHATUSER)->alias('cu')->on('chat.gid=cu.cgid')
|
|
->where('cu.user')->eq($userID)
|
|
->andWhere('cu.quit')->eq('0000-00-00 00:00:00')
|
|
->andWhere('chat.dismissDate', true)->eq('0000-00-00 00:00:00')
|
|
->orWhere('chat.dismissDate')->gt(date(DT_DATETIME1, strtotime("-{$limit} day")))
|
|
->markRight(1)
|
|
->fetchAll();
|
|
|
|
if(!isset($this->config->xuanxuan->disableSystemGroupChat) || $this->config->xuanxuan->disableSystemGroupChat == 'off')
|
|
{
|
|
$this->loadModel('setting');
|
|
$account = $this->dao->select('account')->from(TABLE_USER)->where('id')->eq($userID)->fetch('account');
|
|
$lastReadMessage = $this->setting->getItem("owner=$account&module=chat§ion=system&key=lastreadid");
|
|
if(empty($lastReadMessage)) $lastReadMessage = 0;
|
|
$lastReadMessageIndex = $this->setting->getItem("owner=$account&module=chat§ion=system&key=lastreadindex");
|
|
if(empty($lastReadMessageIndex)) $lastReadMessageIndex = 0;
|
|
$systemChat = $this->dao->select("*, 1 as star, 0 as hide, 0 as mute, 0 as freeze, 0 as category, $lastReadMessage as lastReadMessage, $lastReadMessageIndex as lastReadMessageIndex")
|
|
->from(TABLE_IM_CHAT)
|
|
->where('type')->eq('system')
|
|
->fetch();
|
|
if($systemChat->lastReadMessage == 0) $systemChat->lastReadMessage = $systemChat->lastMessage;
|
|
if($systemChat->lastReadMessageIndex == 0) $systemChat->lastReadMessageIndex = $systemChat->lastMessageIndex;
|
|
$chats[] = $systemChat;
|
|
}
|
|
return $this->format($chats, true);
|
|
}
|
|
|
|
/**
|
|
* Get chat by gid and verify if user is in the chat.
|
|
*
|
|
* @param string $gid
|
|
* @param int $userID
|
|
* @access public
|
|
* @return object|bool
|
|
*/
|
|
public function getByGidForUser($gid, $userID)
|
|
{
|
|
$chat = $this->getByGid($gid, true);
|
|
if(empty($chat)) return false;
|
|
if(!in_array($userID, $chat->members)) return false;
|
|
|
|
return $chat;
|
|
}
|
|
|
|
/**
|
|
* Get chats owned by given user.
|
|
*
|
|
* @param int $userID
|
|
* @param bool $format
|
|
* @access public
|
|
* @return array
|
|
*/
|
|
public function getOwnedListForUser($userID, $format = true)
|
|
{
|
|
$account = $this->dao->select('account')->from(TABLE_USER)->where('id')->eq($userID)->fetch('account');
|
|
$chats = $this->dao->select('*')->from(TABLE_IM_CHAT)
|
|
->where('type')->eq('group')
|
|
->andWhere('dismissDate')->eq('0000-00-00 00:00:00')
|
|
->andWhere('mergedDate')->eq('0000-00-00 00:00:00')
|
|
->andWhere('ownedBy', true)->eq($account)
|
|
->orWhere('ownedBy')->eq('')
|
|
->andWhere('createdBy')->eq($account)
|
|
->markRight(1)
|
|
->fetchAll();
|
|
return $format ? $this->format($chats) : $chats;
|
|
}
|
|
|
|
/**
|
|
* Check if user is committer of a chat.
|
|
*
|
|
* @param object $message
|
|
* @param int $userID
|
|
* @param object $chat
|
|
* @access public
|
|
* @return object|bool $output | true
|
|
*/
|
|
public function isCommitter($message, $userID, $chat)
|
|
{
|
|
$members = explode('&', $message->cgid);
|
|
|
|
$output = new stdclass();
|
|
$output->result = 'fail';
|
|
$output->users = $userID;
|
|
|
|
if(!$chat)
|
|
{
|
|
$output->data = new stdclass();
|
|
$output->data->gid = $message->cgid;
|
|
$output->data->messages = $this->lang->im->notExist;
|
|
return $output;
|
|
}
|
|
|
|
if(count($members) == 2 and !in_array($userID, $members))
|
|
{
|
|
$output->message = $this->lang->im->notInChat;
|
|
return $output;
|
|
}
|
|
|
|
if(!empty($chat->dismissDate))
|
|
{
|
|
$output->data = new stdclass();
|
|
$output->data->gid = $message->cgid;
|
|
$output->data->messages = $this->lang->im->chatHasDismissed;
|
|
return $output;
|
|
}
|
|
|
|
/* Check if user is in the group. */
|
|
if($chat->type == 'group' and $message->type == 'normal')
|
|
{
|
|
$members = $this->getMembers($chat->gid);
|
|
if(!in_array($message->user, $members))
|
|
{
|
|
$output->data = new stdclass();
|
|
$output->data->gid = $message->cgid;
|
|
$output->data->messages = $this->lang->im->notInGroup;
|
|
return $output;
|
|
}
|
|
}
|
|
|
|
/* Check if user is in committers. */
|
|
if(!empty($chat->committers))
|
|
{
|
|
if($chat->committers == '$ADMINS')
|
|
{
|
|
if(!$this->isAdmin($chat, $userID))
|
|
{
|
|
$output->data = new stdclass();
|
|
$output->data->gid = $message->cgid;
|
|
$output->data->messages = $this->lang->im->cantChat;
|
|
return $output;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$committers = explode(',', $chat->committers);
|
|
if(!in_array($userID, $committers))
|
|
{
|
|
$output->data = new stdclass();
|
|
$output->data->gid = $message->cgid;
|
|
$output->data->messages = $this->lang->im->cantChat;
|
|
return $output;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check if user is admin in a chat.
|
|
*
|
|
* @param string|object $chat
|
|
* @param int $userID
|
|
* @access public
|
|
* @return boolean
|
|
*/
|
|
public function isAdmin($chat, $userID)
|
|
{
|
|
if(strpos(is_string($chat) ? $chat : $chat->gid, '&') !== false) return true;
|
|
|
|
if(is_string($chat)) $chat = $this->getByGid($chat, false, false);
|
|
if(isset($chat->admins) && (is_array($chat->admins) ? in_array($userID, $chat->admins) : strpos($chat->admins, ",$userID,")) !== false) return true;
|
|
|
|
if($chat->createdBy === 'system')
|
|
{
|
|
$account = $this->loadModel('user')->getById($userID);
|
|
$admins = $this->dao->select('admins')->from(TABLE_COMPANY)->where('id')->eq($this->app->company->id)->fetch('admins');
|
|
$adminArray = explode(',', $admins);
|
|
return in_array($account, $adminArray);
|
|
|
|
return in_array($userID, $sysAdmins);
|
|
}
|
|
|
|
$creatorID = $this->dao->select('id')->from(TABLE_USER)
|
|
->where('account')->eq(empty($chat->ownedBy) ? $chat->createdBy : $chat->ownedBy)
|
|
->fetch('id');
|
|
return $userID == $creatorID;
|
|
}
|
|
|
|
/**
|
|
* Get group pairs of all chat.
|
|
*
|
|
* @access public
|
|
* @return array
|
|
*/
|
|
public function getGroupPairs()
|
|
{
|
|
return $this->dao->select('gid, name')->from(TABLE_IM_CHAT)
|
|
->where('type')->eq('group')
|
|
->andWhere('dismissDate')->eq('0000-00-00 00:00:00')
|
|
->fetchPairs();
|
|
}
|
|
|
|
/**
|
|
* Get user pairs of one chat group.
|
|
*
|
|
* @param string $gid
|
|
* @access public
|
|
* @return array
|
|
*/
|
|
public function getUserPairs($gid = '')
|
|
{
|
|
$userIdList = $this->dao->select('user')->from(TABLE_IM_CHATUSER)
|
|
->where('quit')->eq('0000-00-00 00:00:00')
|
|
->beginIF($gid)->andWhere('cgid')->eq($gid)->fi()
|
|
->fetchPairs();
|
|
|
|
return $this->dao->select('id, realname')->from(TABLE_USER)->where('id')->in($userIdList)->fetchPairs();
|
|
}
|
|
|
|
/**
|
|
* Create a chat.
|
|
*
|
|
* @param string $gid
|
|
* @param string $name
|
|
* @param string $type
|
|
* @param array $members
|
|
* @param int $subjectID
|
|
* @param bool $public
|
|
* @param int $userID
|
|
* @access public
|
|
* @return object
|
|
*/
|
|
public function create($gid = '', $name = '', $type = '', $members = array(), $subjectID = 0, $public = false, $userID = 0)
|
|
{
|
|
$user = $this->loadModel('im')->user->getByID($userID);
|
|
|
|
$chat = new stdclass();
|
|
$chat->gid = $gid;
|
|
$chat->name = $name;
|
|
if($type == 'bot' || ($type == 'one2one' && in_array('xuanbot', $members)))
|
|
{
|
|
$type = 'bot';
|
|
|
|
$avatar = new stdclass();
|
|
$avatar->type = 'image';
|
|
$avatar->data = new stdclass();
|
|
$avatar->data->imgUrl = $this->config->webRoot . 'data/image/xuanbot.png';
|
|
|
|
$chat->avatar = json_encode($avatar);
|
|
$chat->name = $this->lang->im->bot->commonName;
|
|
}
|
|
$chat->type = $type;
|
|
$chat->subject = $subjectID;
|
|
$chat->createdBy = !empty($user->account) ? $user->account : '';
|
|
$chat->ownedBy = $chat->createdBy;
|
|
$chat->createdDate = helper::now();
|
|
|
|
if($public) $chat->public = 1;
|
|
|
|
$this->dao->insert(TABLE_IM_CHAT)->data($chat)->exec();
|
|
|
|
/* Add members to chat. */
|
|
foreach($members as $member) $this->join($gid, $member);
|
|
|
|
return $this->getByGid($gid, true);
|
|
}
|
|
|
|
/**
|
|
* Update a chat.
|
|
*
|
|
* @param object $chat
|
|
* @param int $userID
|
|
* @access public
|
|
* @return object
|
|
*/
|
|
public function update($chat = null, $userID = 0)
|
|
{
|
|
if(isset($chat))
|
|
{
|
|
$user = $this->loadModel('im')->user->getByID($userID);
|
|
$chat->editedBy = !empty($user->account) ? $user->account : '';
|
|
$chat->editedDate = helper::now();
|
|
if(is_array($chat->admins)) $chat->admins = implode(',', $chat->admins);
|
|
if(is_array($chat->pinnedMessages)) $chat->pinnedMessages = implode(',', $chat->pinnedMessages);
|
|
if(is_array($chat->mergedChats)) $chat->mergedChats = implode(',', $chat->mergedChats);
|
|
|
|
if(is_bool($chat->public))
|
|
{
|
|
$chat->public = $chat->public ? '1' : '0';
|
|
}
|
|
if(is_bool($chat->adminInvite))
|
|
{
|
|
$chat->adminInvite = $chat->adminInvite ? '1' : '0';
|
|
}
|
|
|
|
foreach(array('createdDate', 'lastMessageInfo', 'avatar') as $dropProp) unset($chat->$dropProp);
|
|
|
|
$this->dao->update(TABLE_IM_CHAT)->data($chat)->where('gid')->eq($chat->gid)->batchCheck($this->config->im->require->edit, 'notempty')->exec();
|
|
}
|
|
|
|
/* Return the changed chat. */
|
|
return $this->getByGid($chat->gid, true);
|
|
}
|
|
|
|
/**
|
|
* Touch a chat (as on Linux), changes its editedDate to now.
|
|
*
|
|
* This method is currently meant to track members' join/leave events, which will not get synced during login.
|
|
*
|
|
* @param string $gid
|
|
* @return boolean
|
|
*/
|
|
public function touch($gid)
|
|
{
|
|
$this->dao->update(TABLE_IM_CHAT)->set('editedDate')->eq(helper::now())->where('gid')->eq($gid)->exec();
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Init the system chat.
|
|
*
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function initSystemChat()
|
|
{
|
|
if(!isset($this->config->disableSystemGroupChat) || !$this->config->disableSystemGroupChat)
|
|
{
|
|
$chat = $this->dao->select('*')->from(TABLE_IM_CHAT)->where('type')->eq('system')->fetch();
|
|
if(!$chat)
|
|
{
|
|
$chat = new stdclass();
|
|
$chat->gid = imModel::createGID();
|
|
$chat->name = $this->lang->im->systemGroup;
|
|
$chat->type = 'system';
|
|
$chat->createdBy = 'system';
|
|
$chat->createdDate = helper::now();
|
|
|
|
$this->dao->insert(TABLE_IM_CHAT)->data($chat)->exec();
|
|
}
|
|
return !dao::isError();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Join a chat.
|
|
*
|
|
* @param string $gid
|
|
* @param int $userID
|
|
* @access public
|
|
* @return bool|int return userID if already joined, else return result.
|
|
*/
|
|
public function join($gid = '', $userID = 0)
|
|
{
|
|
$this->touch($gid);
|
|
|
|
$lastMessageInfo = $this->dao->select('lastMessage, lastMessageIndex')->from(TABLE_IM_CHAT)->where('gid')->eq($gid)->fetch();
|
|
$data = $this->dao->select('*')->from(TABLE_IM_CHATUSER)->where('cgid')->eq($gid)->andWhere('user')->eq($userID)->fetch();
|
|
if($data)
|
|
{
|
|
/* If user hasn't quit the chat then return. */
|
|
if($data->quit == '0000-00-00 00:00:00') return $userID;
|
|
|
|
/* If user has quited the chat then update the record. */
|
|
$data = new stdclass();
|
|
$data->join = helper::now();
|
|
$data->quit = '0000-00-00 00:00:00';
|
|
$data->lastReadMessage = $lastMessageInfo->lastMessage;
|
|
$data->lastReadMessageIndex = $lastMessageInfo->lastMessageIndex;
|
|
$this->dao->update(TABLE_IM_CHATUSER)->data($data)->where('cgid')->eq($gid)->andWhere('user')->eq($userID)->exec();
|
|
|
|
return !dao::isError();
|
|
}
|
|
|
|
/* Create a new record of user's chat info. */
|
|
$data = new stdclass();
|
|
$data->cgid = $gid;
|
|
$data->user = $userID;
|
|
$data->join = helper::now();
|
|
$data->lastReadMessage = $lastMessageInfo->lastMessage;
|
|
$data->lastReadMessageIndex = $lastMessageInfo->lastMessageIndex;
|
|
$this->dao->insert(TABLE_IM_CHATUSER)->data($data)->exec();
|
|
|
|
/* Update order field. */
|
|
$id = $this->dao->lastInsertID();
|
|
$this->dao->update(TABLE_IM_CHATUSER)->set('`order`')->eq($id)->where('id')->eq($id)->exec();
|
|
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* leave a chat.
|
|
*
|
|
* @param int $gid
|
|
* @param int $userID
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function leave($gid, $userID)
|
|
{
|
|
$this->dao->update(TABLE_IM_CHATUSER)->set('quit')->eq(helper::now())->where('cgid')->eq($gid)->andWhere('user')->eq($userID)->exec();
|
|
$this->removeAdmins($gid, array($userID));
|
|
$this->loadModel('im')->conferenceRemoveUserFromChat($gid, $userID);
|
|
$this->touch($gid);
|
|
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Format chats.
|
|
*
|
|
* @param mixed $chats object | array
|
|
* @access public
|
|
* @return object | array
|
|
*/
|
|
public function format($chats, $getLastMessage = false)
|
|
{
|
|
$isObject = false;
|
|
if(is_object($chats))
|
|
{
|
|
$isObject = true;
|
|
$chats = array($chats);
|
|
}
|
|
|
|
$userID = $this->app->session->userID;
|
|
|
|
foreach($chats as $chat)
|
|
{
|
|
if(!$chat) continue;
|
|
$chat->id = (int)$chat->id;
|
|
$chat->subject = (int)$chat->subject;
|
|
$chat->createdDate = $chat->createdDate == '0000-00-00 00:00:00' ? 0 : strtotime($chat->createdDate);
|
|
$chat->editedDate = $chat->editedDate == '0000-00-00 00:00:00' ? 0 : strtotime($chat->editedDate);
|
|
$chat->lastActiveTime = $chat->lastActiveTime == '0000-00-00 00:00:00' ? 0 : strtotime($chat->lastActiveTime);
|
|
$chat->dismissDate = $chat->dismissDate == '0000-00-00 00:00:00' ? 0 : strtotime($chat->dismissDate);
|
|
$chat->mergedDate = $chat->mergedDate == '0000-00-00 00:00:00' ? 0 : strtotime($chat->mergedDate);
|
|
$chat->archiveDate = $chat->archiveDate == '0000-00-00 00:00:00' ? 0 : strtotime($chat->archiveDate);
|
|
$chat->lastMessage = (int)$chat->lastMessage;
|
|
$chat->admins = array_values(array_map('intval', array_filter(explode(',', $chat->admins))));
|
|
$chat->pinnedMessages = array_values(array_map('intval', array_filter(explode(',', $chat->pinnedMessages))));
|
|
$chat->mergedChats = array_values(array_filter(explode(',', $chat->mergedChats)));
|
|
$chat->avatar = json_decode($chat->avatar);
|
|
|
|
if(isset($chat->avatar) && $chat->avatar->type === 'image')
|
|
{
|
|
$chat->avatar->data->imgUrl = $this->loadModel('im')->getServer() . $chat->avatar->data->imgUrl;
|
|
}
|
|
|
|
if($getLastMessage && isset($chat->lastMessage)) $chat->lastMessageInfo = current($this->loadModel('im')->messageGetList($chat->gid, array($chat->lastMessage)));
|
|
if(empty($chat->lastMessageInfo)) $chat->lastMessageInfo = null;
|
|
if(!empty($chat->lastMessageInfo)) $chat->lastMessageInfo->senderId = intval($chat->lastMessageInfo->user);
|
|
if(isset($chat->lastReadMessageIndex)) $chat->lastReadMessageIndex = (int)$chat->lastReadMessageIndex;
|
|
|
|
if($chat->type == 'one2one' && $chat->gid != "$userID&$userID") $chat->name = '';
|
|
|
|
if(isset($chat->star)) $chat->star = (bool)$chat->star;
|
|
if(isset($chat->hide)) $chat->hide = (bool)$chat->hide;
|
|
if(isset($chat->mute)) $chat->mute = (bool)$chat->mute;
|
|
if(isset($chat->public)) $chat->public = (bool)$chat->public;
|
|
if(isset($chat->freeze)) $chat->freeze = (bool)$chat->freeze;
|
|
if(isset($chat->lastReadMessage)) $chat->lastReadMessage = (int)$chat->lastReadMessage;
|
|
if(isset($chat->adminInvite)) $chat->adminInvite = (bool)$chat->adminInvite;
|
|
|
|
if($chat->archiveDate) {
|
|
$chat->star = false;
|
|
$chat->hide = false;
|
|
$chat->mute = false;
|
|
$chat->freeze = false;
|
|
}
|
|
}
|
|
|
|
if($isObject) return reset($chats);
|
|
|
|
return $chats;
|
|
}
|
|
|
|
/**
|
|
* Add admins of a chat.
|
|
*
|
|
* @param string $gid
|
|
* @param array $admins
|
|
* @param int $userID
|
|
* @access public
|
|
* @return object
|
|
*/
|
|
public function addAdmins($gid = '', $admins = array())
|
|
{
|
|
$chat = $this->getByGid($gid);
|
|
$adminList = $chat->admins;
|
|
$adminList = array_filter(array_unique(array_merge($adminList, $admins)));
|
|
$adminList = implode(',', $adminList);
|
|
$this->dao->update(TABLE_IM_CHAT)->set('admins')->eq(',' . $adminList . ',')->where('gid')->eq($gid)->exec();
|
|
|
|
return $this->getByGid($gid, true);
|
|
}
|
|
|
|
/**
|
|
* Remove admins of a chat.
|
|
*
|
|
* @param string $gid
|
|
* @param array $users
|
|
* @access public
|
|
* @return object
|
|
*/
|
|
public function removeAdmins($gid = '', $users = array())
|
|
{
|
|
$chat = $this->getByGid($gid);
|
|
$adminList = $chat->admins;
|
|
$adminList = array_filter(array_diff($adminList, $users));
|
|
$adminList = implode(',', $adminList);
|
|
$this->dao->update(TABLE_IM_CHAT)->set('admins')->eq(',' . $adminList . ',')->where('gid')->eq($gid)->exec();
|
|
|
|
return $this->getByGid($gid, true);
|
|
}
|
|
|
|
/**
|
|
* Pin messages of a chat.
|
|
*
|
|
* @param string|object $chat
|
|
* @param array $messageIds
|
|
* @access public
|
|
* @return object
|
|
*/
|
|
public function pinMessages($chat, $messageIds)
|
|
{
|
|
if(is_string($chat)) $chat = $this->getByGid($chat);
|
|
$pinnedMessages = $chat->pinnedMessages;
|
|
|
|
if(!empty($pinnedMessages))
|
|
{
|
|
$pinnedMessagesData = $this->loadModel('im')->messageGetList('', $pinnedMessages);
|
|
foreach($pinnedMessagesData as $msg) if($msg->deleted) $pinnedMessages = array_diff($pinnedMessages, array($msg->id));
|
|
}
|
|
|
|
$pinnedMessagesLimit = isset($this->config->pinnedMessagesLimit) ? $this->config->pinnedMessagesLimit : 10;
|
|
if(count($pinnedMessages) >= $pinnedMessagesLimit) $pinnedMessages = array_slice($pinnedMessages, $pinnedMessagesLimit - count($pinnedMessages) + count($messageIds));
|
|
|
|
$pinnedMessages = array_filter(array_unique(array_merge($pinnedMessages, $messageIds)));
|
|
$pinnedMessages = implode(',', $pinnedMessages);
|
|
$this->dao->update(TABLE_IM_CHAT)->set('pinnedMessages')->eq(',' . $pinnedMessages . ',')->where('gid')->eq($chat->gid)->exec();
|
|
|
|
return $this->getByGid($chat->gid, true);
|
|
}
|
|
|
|
/**
|
|
* Unpin messages of a chat.
|
|
*
|
|
* @param string|object $chat
|
|
* @param array $messageIDs
|
|
* @access public
|
|
* @return object
|
|
*/
|
|
public function unpinMessages($chat, $messageIds)
|
|
{
|
|
if(is_string($chat)) $chat = $this->getByGid($chat);
|
|
$pinnedMessages = $chat->pinnedMessages;
|
|
$pinnedMessages = array_filter(array_diff($pinnedMessages, $messageIds));
|
|
$pinnedMessages = implode(',', $pinnedMessages);
|
|
$this->dao->update(TABLE_IM_CHAT)->set('pinnedMessages')->eq(',' . $pinnedMessages . ',')->where('gid')->eq($chat->gid)->exec();
|
|
|
|
return $this->getByGid($chat->gid, true);
|
|
}
|
|
|
|
/**
|
|
* Star or unstar a chat.
|
|
*
|
|
* @param string $star
|
|
* @param string $gid
|
|
* @param int $userID
|
|
* @access public
|
|
* @return object
|
|
*/
|
|
public function star($star = '1', $gid = '', $userID = 0)
|
|
{
|
|
$this->dao->update(TABLE_IM_CHATUSER)
|
|
->set('star')->eq($star)
|
|
->where('cgid')->eq($gid)
|
|
->andWhere('user')->eq($userID)
|
|
->exec();
|
|
|
|
return $this->getByGid($gid, true);
|
|
}
|
|
|
|
/**
|
|
* Hide or display a chat.
|
|
*
|
|
* @param string $hide
|
|
* @param string $gid
|
|
* @param int $userID
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function hide($hide = '1', $gid = '', $userID = 0)
|
|
{
|
|
$this->dao->update(TABLE_IM_CHATUSER)
|
|
->set('hide')->eq($hide)
|
|
->where('cgid')->eq($gid)
|
|
->andWhere('user')->eq($userID)
|
|
->exec();
|
|
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Mute or unmute a chat.
|
|
*
|
|
* @param string $mute
|
|
* @param string $gid
|
|
* @param int $userID
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function mute($mute = '1', $gid = '', $userID = 0)
|
|
{
|
|
$this->dao->update(TABLE_IM_CHATUSER)
|
|
->set('mute')->eq($mute)
|
|
->where('cgid')->eq($gid)
|
|
->andWhere('user')->eq($userID)
|
|
->exec();
|
|
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Freeze or unfreeze a chat.
|
|
*
|
|
* @param string $freeze
|
|
* @param string $gid
|
|
* @param int $userID
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function freeze($freeze = '1', $gid = '', $userID = 0)
|
|
{
|
|
$this->dao->update(TABLE_IM_CHATUSER)
|
|
->set('freeze')->eq($freeze)
|
|
->where('cgid')->eq($gid)
|
|
->andWhere('user')->eq($userID)
|
|
->exec();
|
|
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Set category for a chat
|
|
*
|
|
* @param array $gids
|
|
* @param string $category
|
|
* @param int $userID
|
|
* @access public
|
|
* @return boolean
|
|
*/
|
|
public function setCategory($gids = array(), $category = '', $userID = 0)
|
|
{
|
|
$this->dao->update(TABLE_IM_CHATUSER)
|
|
->set('category')->eq($category)
|
|
->where('cgid')->in($gids)
|
|
->andWhere('user')->eq($userID)
|
|
->exec();
|
|
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Get member list of one chat.
|
|
*
|
|
* @param string|object $chat chat gid or chat object.
|
|
* @param bool $trueOnSystemChat return true if chat type is system.
|
|
* @access public
|
|
* @return array
|
|
*/
|
|
public function getMembers($chat, $trueOnSystemChat = false)
|
|
{
|
|
if(is_string($chat)) $chat = $this->getByGid($chat);
|
|
if(!$chat) return array();
|
|
|
|
if($chat->type == 'system')
|
|
{
|
|
if($trueOnSystemChat) return true;
|
|
$memberList = $this->dao->select('id')->from(TABLE_USER)->where('deleted')->eq('0')->fetchPairs();
|
|
}
|
|
else
|
|
{
|
|
$memberList = $this->dao->select('user')->from(TABLE_IM_CHATUSER)->alias('tcu')
|
|
->leftJoin(TABLE_USER)->alias('tu')->on('tcu.user = tu.id')
|
|
->where('tcu.quit')->eq('0000-00-00 00:00:00')
|
|
->andWhere('tu.deleted')->eq('0')
|
|
->andWhere('cgid')->eq($chat->gid)
|
|
->fetchPairs();
|
|
}
|
|
|
|
$members = array();
|
|
foreach($memberList as $member) $members[] = (int)$member;
|
|
|
|
return $members;
|
|
}
|
|
|
|
/**
|
|
* Get detailed member list of chat.
|
|
*
|
|
* @param string $chat chat gid
|
|
* @param object $pager
|
|
* @param string $orderBy order by owner, admin, join date by default
|
|
* @param array $memberIDs only get details for members in memberIDs if provided
|
|
* @access public
|
|
* @return array
|
|
*/
|
|
public function getMemberDetails($cgid, $pager = null, $orderBy = '', $memberIDs = array())
|
|
{
|
|
$chat = $this->getByGid($cgid);
|
|
if(!$chat || $chat->type == 'system') return array();
|
|
|
|
/* Get join and last seen date of members, with some values which will be filled in later. */
|
|
$memberList = $this->dao->select('user as id, account, tcu.`join`, last as lastSeen, "0000-00-00 00:00:00" as lastPost, 0 as isOwner, 0 as isAdmin')->from(TABLE_IM_CHATUSER)->alias('tcu')
|
|
->leftJoin(TABLE_USER)->alias('tu')->on('tcu.user = tu.id')
|
|
->where('tcu.quit')->eq('0000-00-00 00:00:00')
|
|
->andWhere('tu.deleted')->eq('0')
|
|
->andWhere('cgid')->eq($cgid)
|
|
->fetchAll('id');
|
|
if(empty($memberList)) return array();
|
|
|
|
/* Filter members. */
|
|
if(!empty($memberIDs))
|
|
{
|
|
$memberList = array_filter($memberList, function($member) use ($memberIDs)
|
|
{
|
|
return in_array($member->id, $memberIDs);
|
|
});
|
|
}
|
|
|
|
/* Get date of members' last message in chat. */
|
|
$members = array_keys($memberList);
|
|
$lastMessageDates = $this->dao->select('user, MAX(date)')->from(TABLE_IM_MESSAGE)
|
|
->where('cgid')->eq($cgid)
|
|
->andWhere('user')->in($members)
|
|
->groupBy('user')
|
|
->fetchAll();
|
|
foreach($lastMessageDates as $messageDate) $memberList[$messageDate->user]->lastPost = $messageDate->{'MAX(date)'};
|
|
|
|
/* Set isAdmin for members. */
|
|
foreach($chat->admins as $admin)
|
|
{
|
|
if(isset($memberList[$admin])) $memberList[$admin]->isAdmin = 1;
|
|
}
|
|
|
|
/* Set isOwner. */
|
|
$ownerAccount = !empty($chat->ownedBy) ? $chat->ownedBy : $chat->createdBy;
|
|
$ownerIndex = false; // For reorder later.
|
|
foreach($memberList as $index => $member)
|
|
{
|
|
if($member->account == $ownerAccount)
|
|
{
|
|
$memberList[$index]->isOwner = 1;
|
|
$ownerIndex = $index;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Format data. */
|
|
$memberList = array_map(function($member)
|
|
{
|
|
$member->id = (int)$member->id;
|
|
$member->isOwner = (int)$member->isOwner;
|
|
$member->isAdmin = (int)$member->isAdmin;
|
|
$member->join = $member->join == '0000-00-00 00:00:00' ? 0 : strtotime($member->join);
|
|
$member->lastSeen = $member->lastSeen == '0000-00-00 00:00:00' ? 0 : strtotime($member->lastSeen);
|
|
$member->lastPost = $member->lastPost == '0000-00-00 00:00:00' ? 0 : strtotime($member->lastPost);
|
|
return $member;
|
|
}, $memberList);
|
|
|
|
/* Reorder data. */
|
|
$orderedMemberList = array();
|
|
if(empty($orderBy) || stripos($orderBy, 'member') === 0) // Default order: owner, admin, join date. Might reverse.
|
|
{
|
|
if($ownerIndex !== false) $orderedMemberList[] = $memberList[$ownerIndex];
|
|
if(!empty($chat->admins))
|
|
{
|
|
$adminList = array_filter($memberList, function($member)
|
|
{
|
|
return $member->isAdmin && !$member->isOwner;
|
|
});
|
|
usort($adminList, function($a, $b)
|
|
{
|
|
return ($a->join < $b->join) ? -1 : 1;
|
|
});
|
|
$orderedMemberList = array_merge($orderedMemberList, $adminList);
|
|
}
|
|
$normalMemberList = array_filter($memberList, function($member)
|
|
{
|
|
return !$member->isOwner && !$member->isAdmin;
|
|
});
|
|
usort($normalMemberList, function($a, $b)
|
|
{
|
|
return ($a->join < $b->join) ? -1 : 1;
|
|
});
|
|
$orderedMemberList = array_merge($orderedMemberList, $normalMemberList);
|
|
if(stripos($orderBy, 'desc') !== false) $orderedMemberList = array_reverse($orderedMemberList);
|
|
}
|
|
else
|
|
{
|
|
$orderByArgs = explode('_', $orderBy);
|
|
$property = $orderByArgs[0];
|
|
$direction = $orderByArgs[1] == 'asc' ? 1 : -1;
|
|
usort($memberList, function($a, $b) use ($property, $direction)
|
|
{
|
|
return ($a->$property < $b->$property) ? (-1 * $direction) : $direction;
|
|
});
|
|
$orderedMemberList = $memberList;
|
|
}
|
|
|
|
/* Slice data with pager. */
|
|
$recTotal = count($memberList);
|
|
if($pager->recPerPage * ($pager->pageID - 1) >= $recTotal)
|
|
{
|
|
$pager->pageID = ceil($recTotal / $pager->recPerPage);
|
|
}
|
|
$startIndex = $pager->recPerPage * ($pager->pageID - 1);
|
|
if($startIndex >= $recTotal || $startIndex < 0) return array();
|
|
|
|
$memberSlice = array_slice($orderedMemberList , $startIndex, $pager->recPerPage);
|
|
|
|
/* Assemble data. */
|
|
$details = new stdclass();
|
|
$details->data = $memberSlice;
|
|
$details->pager = new stdclass();
|
|
$details->pager->gid = $cgid;
|
|
$details->pager->recTotal = $recTotal;
|
|
$details->pager->recPerPage = $pager->recPerPage;
|
|
$details->pager->pageID = $pager->pageID;
|
|
$details->pager->data = array('orderBy' => $orderBy);
|
|
|
|
return $details;
|
|
}
|
|
|
|
/**
|
|
* Get count of messages for a chat.
|
|
*
|
|
* @param string $gid
|
|
* @access public
|
|
* @return int
|
|
*/
|
|
public function getMessageCount($gid)
|
|
{
|
|
$masterTableCount = $this->dao->select('count(*)')->from(TABLE_IM_MESSAGE)->where('cgid')->eq($gid)->fetch('count(*)');
|
|
$partitionsMessageCount = $this->dao->select('sum(`count`)')->from(TABLE_IM_CHAT_MESSAGE_INDEX)->where('gid')->eq($gid)->fetch('sum(`count`)');
|
|
|
|
return $masterTableCount + $partitionsMessageCount;
|
|
}
|
|
|
|
/**
|
|
* Add chat action.
|
|
*
|
|
* @param int $chatId
|
|
* @param string $action
|
|
* @param int $actionId
|
|
* @param string $result
|
|
* @param string $comment
|
|
*/
|
|
public function addAction($chatId, $action, $actorId, $result, $comment = '')
|
|
{
|
|
if(!$this->loadModel('action')->checkLogLevel('chat', $action)) return;
|
|
|
|
$account = $this->dao->select('account')
|
|
->from(TABLE_USER)
|
|
->where('id')->eq($actorId)
|
|
->fetch('account');
|
|
$actor = !empty($account) ? $account : '';
|
|
$extra = json_encode(array('actorId' => $actorId));
|
|
$this->loadModel('action')->create('chat', $chatId, $action, $result, $comment, $extra, $actor);
|
|
}
|
|
|
|
/**
|
|
* Set last read message for a chat.
|
|
*
|
|
* @param string $gid
|
|
* @param int $lastReadMessageID
|
|
* @param int $userID
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function setLastReadMessage($gid, $lastReadMessageID, $userID)
|
|
{
|
|
$messageIndex = $this->dao->select('`index`')->from(TABLE_IM_MESSAGE)
|
|
->where('id')->eq($lastReadMessageID)
|
|
->andWhere('cgid')->eq($gid)
|
|
->fetch('index');
|
|
$this->dao->update(TABLE_IM_CHATUSER)
|
|
->set('lastReadMessage')->eq($lastReadMessageID)
|
|
->set('lastReadMessageIndex')->eq($messageIndex)
|
|
->where('cgid')->eq($gid)
|
|
->andWhere('lastReadMessage')->lt($lastReadMessageID)
|
|
->andWhere('user')->eq($userID)
|
|
->exec();
|
|
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Set last read message for a chat.
|
|
*
|
|
* @param string $gid
|
|
* @param int $lastReadMessageIndex
|
|
* @param int $userID
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function setLastReadMessageByIndex($gid, $lastReadMessageIndex, $userID)
|
|
{
|
|
$messageID = $this->dao->select('id')->from(TABLE_IM_MESSAGE)
|
|
->where('`index`')->eq($lastReadMessageIndex)
|
|
->andWhere('cgid')->eq($gid)
|
|
->fetch('id');
|
|
$affected = $this->dao->update(TABLE_IM_CHATUSER)
|
|
->set('lastReadMessageIndex')->eq($lastReadMessageIndex)
|
|
->set('lastReadMessage')->eq($messageID)
|
|
->where('cgid')->eq($gid)
|
|
->andWhere('user')->eq($userID)
|
|
->exec();
|
|
|
|
if($affected === 0)
|
|
{
|
|
$systemChatGidList = $this->dao->select('gid')->from(TABLE_IM_CHAT)
|
|
->where('type')->eq('system')
|
|
->fetchPairs('gid');
|
|
if(in_array($gid, array_keys($systemChatGidList)))
|
|
{
|
|
$this->loadModel('setting');
|
|
$account = $this->dao->select('account')->from(TABLE_USER)->where('id')->eq($userID)->fetch('account');
|
|
$this->setting->setItem("$account.chat.system.lastreadid", $messageID);
|
|
$this->setting->setItem("$account.chat.system.lastreadindex", $lastReadMessageIndex);
|
|
}
|
|
}
|
|
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Change ownership of chat.
|
|
*
|
|
* @param object $chat
|
|
* @param int $ownerUserID new owner id
|
|
* @param int $userID
|
|
* @param bool $byAdmin true if is request by an admin, will bypass owner checking.
|
|
* @access public
|
|
* @return bool|object returns chat on success, returns false on fail
|
|
*/
|
|
public function changeOwnership($chat, $ownerUserID, $userID, $byAdmin = false)
|
|
{
|
|
if(!$byAdmin)
|
|
{
|
|
if($ownerUserID == $userID) return false;
|
|
|
|
$currentUserAccount = $this->dao->select('account')->from(TABLE_USER)->where('id')->eq($userID)->fetch('account');
|
|
if(empty($currentUserAccount) || (!empty($chat->ownedBy) && $chat->ownedBy != $currentUserAccount) || (empty($chat->ownedBy) && $chat->createdBy != $currentUserAccount)) return false;
|
|
}
|
|
|
|
$ownerAccount = $this->dao->select('account')->from(TABLE_USER)->where('id')->eq($ownerUserID)->fetch('account');
|
|
if(empty($ownerAccount)) return false;
|
|
|
|
$this->dao->update(TABLE_IM_CHAT)
|
|
->set('ownedBy')->eq($ownerAccount)
|
|
->where('gid')->eq($chat->gid)
|
|
->exec();
|
|
|
|
return dao::isError() ? false : $this->getByGid($chat->gid, true);
|
|
}
|
|
|
|
/**
|
|
* Merge chat into targetChat.
|
|
*
|
|
* @param object $chat
|
|
* @param object $targetChat
|
|
* @param int $userID
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function merge($chat, $targetChat, $userID)
|
|
{
|
|
/* Check if user is owner of both chats, and chat has not been merged. */
|
|
$accountAdmin = $this->dao->select('account')->from(TABLE_USER)->where('id')->eq($userID)->fetch();
|
|
$sysAdmins = $this->dao->select('admins')->from(TABLE_COMPANY)->where('id')->eq($this->app->company->id)->fetch('admins');
|
|
$sysAdminArray = explode(',', $sysAdmins);
|
|
$accountAdmin->admin = in_array($accountAdmin->account, $sysAdminArray) ? 'super' : '';
|
|
|
|
if((empty($accountAdmin) || (!empty($chat->ownedBy) && $chat->ownedBy != $accountAdmin->account) || (!empty($targetChat->ownedBy) && $targetChat->ownedBy != $accountAdmin->account) || (empty($chat->ownedBy) && $chat->createdBy != $accountAdmin->account) || (empty($targetChat->ownedBy) && $targetChat->createdBy != $accountAdmin->account)) && $accountAdmin->admin != 'super') return false;
|
|
if($chat->mergedDate != '0000-00-00 00:00:00') return false;
|
|
|
|
/* Mark chat as merged. */
|
|
$this->dao->update(TABLE_IM_CHAT)
|
|
->set('mergedDate')->eq(helper::now())
|
|
->where('gid')->eq($chat->gid)
|
|
->exec();
|
|
|
|
/* Merge previously merged chats. */
|
|
$prevMergedChats = $chat->mergedChats;
|
|
$currMergedChats = $targetChat->mergedChats;
|
|
$mergedChats = array_merge(array($chat->gid), $prevMergedChats, $currMergedChats);
|
|
$mergedChats = join(',', array_filter($mergedChats));
|
|
$this->dao->update(TABLE_IM_CHAT)
|
|
->set('mergedChats')->eq($mergedChats)
|
|
->where('gid')->eq($targetChat->gid)
|
|
->exec();
|
|
|
|
/* Merge members. */
|
|
foreach($chat->members as $memberID)
|
|
{
|
|
$this->leave($chat->gid, $memberID);
|
|
$this->join($targetChat->gid, $memberID);
|
|
}
|
|
|
|
return dao::isError() ? false : $this->getByGid($targetChat->gid, true);
|
|
}
|
|
|
|
/**
|
|
* Get next owner candidate for chat. (Seniormost user other than current owner)
|
|
*
|
|
* @param object $chat
|
|
* @param int $userID current owner user id
|
|
* @param bool $asAccount will return id if set to false
|
|
* @access public
|
|
* @return int|string
|
|
*/
|
|
public function getNextOwnerCandidate($chat, $userID, $asAccount = true)
|
|
{
|
|
if(!empty($chat->admins))
|
|
{
|
|
$seniormostAdmin = $this->dao->select($asAccount ? 'account' : 'user')->from(TABLE_IM_CHATUSER)->alias('tcu')
|
|
->leftJoin(TABLE_USER)->alias('tu')->on('tcu.user=tu.id')
|
|
->where('tcu.cgid')->eq($chat->gid)
|
|
->andWhere('tcu.quit')->eq('0000-00-00 00:00:00')
|
|
->andWhere('tcu.user')->in($chat->admins)
|
|
->andWhere('tcu.user')->ne($userID)
|
|
->andWhere('tu.deleted')->eq('0')
|
|
->orderBy('tcu.join_asc')
|
|
->limit(1)
|
|
->fetch($asAccount ? 'account' : 'user');
|
|
if(!empty($seniormostAdmin)) return $seniormostAdmin;
|
|
}
|
|
return $this->dao->select($asAccount ? 'account' : 'user')->from(TABLE_IM_CHATUSER)->alias('tcu')
|
|
->leftJoin(TABLE_USER)->alias('tu')->on('tcu.user=tu.id')
|
|
->where('tcu.cgid')->eq($chat->gid)
|
|
->andWhere('tcu.quit')->eq('0000-00-00 00:00:00')
|
|
->andWhere('tcu.user')->ne($userID)
|
|
->andWhere('tu.deleted')->eq('0')
|
|
->orderBy('tcu.join_asc')
|
|
->limit(1)
|
|
->fetch($asAccount ? 'account' : 'user');
|
|
}
|
|
|
|
/**
|
|
* Transfer all chats from user to next candidate if possible.
|
|
*
|
|
* @param int $userID
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function transferAllFromUser($userID)
|
|
{
|
|
$userChats = $this->getOwnedListForUser($userID);
|
|
|
|
$chatOwnerPairs = array();
|
|
foreach($userChats as $chat) $chatOwnerPairs[$chat->gid] = $this->getNextOwnerCandidate($chat, $userID);
|
|
$chatOwnerPairs = array_filter($chatOwnerPairs);
|
|
if(empty($chatOwnerPairs)) return true;
|
|
|
|
$queryData = array();
|
|
foreach($chatOwnerPairs as $cgid => $owner) $queryData[] = "WHEN '$cgid' THEN '$owner'";
|
|
$cgids = array_keys($chatOwnerPairs);
|
|
|
|
$query = "UPDATE " . TABLE_IM_CHAT . " SET `ownedBy` = (CASE `gid` " . join(' ', $queryData) . " END) WHERE `gid` IN('" . join('\',\'', $cgids) . "');";
|
|
$this->dao->query($query);
|
|
|
|
return !!dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Prune group data of the expired, including group information, group messages, group files, etc.
|
|
*
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function pruneExpired()
|
|
{
|
|
$groupLife = isset($this->config->dismissedGroupLife) ? $this->config->dismissedGroupLife : 90;
|
|
$expiredGroups = $this->dao->select('gid')
|
|
->from(TABLE_IM_CHAT)
|
|
->where('type')->eq('group')
|
|
->andWhere('dismissDate')->ne('0000-00-00 00:00:00')
|
|
->andWhere('dismissDate')->lt(date(DT_DATETIME1, strtotime("-{$groupLife} day")))
|
|
->fetchPairs();
|
|
$expiredGroups = array_keys($expiredGroups);
|
|
if(empty($expiredGroups)) return true;
|
|
|
|
$messageTables = $this->loadModel('im')->message->getAllTables();
|
|
foreach($messageTables as $table) $this->dao->delete()->from($table->tableName)->where('cgid')->in($expiredGroups)->exec();
|
|
|
|
$this->dao->delete()->from(TABLE_IM_CHAT_MESSAGE_INDEX)->where('gid')->in($expiredGroups)->exec();
|
|
$this->dao->delete()->from(TABLE_IM_CHAT)->where('gid')->in($expiredGroups)->exec();
|
|
$this->dao->delete()->from(TABLE_IM_CHATUSER)->where('cgid')->in($expiredGroups)->exec();
|
|
$this->dao->delete()->from(TABLE_IM_CONFERENCE)->where('cgid')->in($expiredGroups)->exec();
|
|
$this->dao->delete()->from(TABLE_IM_CONFERENCEACTION)->where('rid')->in($expiredGroups)->exec();
|
|
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Search chats with chat name or groupOwner's realname/account/pinyin.
|
|
*
|
|
* @param string $searchField
|
|
* @param object $pager
|
|
* @param string $orderBy
|
|
* @access public
|
|
* @return array
|
|
*/
|
|
public function search($searchField, $pager, $orderBy)
|
|
{
|
|
$accounts = array();
|
|
if(isset($searchField) && !empty($searchField))
|
|
{
|
|
$accounts = $this->dao->select('account')->from(TABLE_USER)
|
|
->beginIF($searchField)
|
|
->where('account')->like("%$searchField%")
|
|
->andWhere('deleted')->eq(0)
|
|
->orWhere('pinyin')->like("%$searchField%")
|
|
->orWhere('realname')->like("%$searchField%")
|
|
->fi()
|
|
->fetchPairs('account');
|
|
$accounts = array_keys($accounts);
|
|
}
|
|
|
|
$chatMemberCounts = $this->dao->select('tc.gid, COUNT(*) AS memberCount')
|
|
->from(TABLE_IM_CHATUSER)->alias('tcu')
|
|
->leftJoin(TABLE_IM_CHAT)->alias('tc')
|
|
->on('tcu.cgid=tc.gid')
|
|
->where('tc.type')->eq('group')
|
|
->andWhere('tc.dismissDate')->eq('0000-00-00 00:00:00')
|
|
->andWhere('tc.mergedDate')->eq('0000-00-00 00:00:00')
|
|
->beginIF($searchField)->andWhere('tc.name', true)->like("%$searchField%")
|
|
->orWhere('tc.ownedBy')->in($accounts)->markRight(1)
|
|
->fi()
|
|
->groupBy('tcu.cgid')
|
|
->fetchPairs();
|
|
$pagerGids = array();
|
|
if($orderBy == 'userCount_asc' || $orderBy == 'userCount_desc')
|
|
{
|
|
if($orderBy == 'userCount_asc')
|
|
{
|
|
asort($chatMemberCounts);
|
|
}
|
|
else
|
|
{
|
|
arsort($chatMemberCounts);
|
|
}
|
|
$pagerGids = array_slice(array_keys($chatMemberCounts), ($pager->pageID-1)*$pager->recPerPage, $pager->recPerPage);
|
|
}
|
|
|
|
$chats = $this->dao->select('tc.gid, tc.id, tc.name, tc.public, tu.id as groupOwner, tc.createdDate, tc.lastActiveTime, tc.archiveDate')
|
|
->from(TABLE_IM_CHAT)->alias('tc')
|
|
->leftJoin(TABLE_USER)->alias('tu')
|
|
->on('tc.ownedBy=tu.account')
|
|
->where('tc.type')->eq('group')
|
|
->andWhere('dismissDate')->eq('0000-00-00 00:00:00')
|
|
->andWhere('mergedDate')->eq('0000-00-00 00:00:00')
|
|
->beginIF($searchField)->andWhere('tc.name', true)->like("%$searchField%")
|
|
->orWhere('tc.ownedBy')->in($accounts)->markRight(1)
|
|
->fi()
|
|
->beginIF(!empty($pagerGids))->andWhere('tc.gid')->in($pagerGids)
|
|
->fi()
|
|
->beginIF(empty($pagerGids))
|
|
->orderBy($orderBy)
|
|
->fi()
|
|
->beginIF($pager)->page($pager, 'tc.gid')->fi()
|
|
->fetchAll();
|
|
foreach($chats as $chat) $chat->userCount = isset($chatMemberCounts[$chat->gid]) ? $chatMemberCounts[$chat->gid] : 0;
|
|
|
|
$sortedChats = array();
|
|
if($orderBy == 'userCount_asc' || $orderBy == 'userCount_desc')
|
|
{
|
|
foreach($pagerGids as $key => $gid)
|
|
{
|
|
foreach($chats as $key => $chat)
|
|
{
|
|
if($chat->gid == $gid)
|
|
{
|
|
$sortedChats[] = $chat;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
$chats = $sortedChats ? $sortedChats : $chats;
|
|
|
|
/* Format data. */
|
|
$chats = array_map(function($chat)
|
|
{
|
|
$chat->id = (int)$chat->id;
|
|
$chat->groupOwner = (int)$chat->groupOwner;
|
|
$chat->userCount = (int)$chat->userCount;
|
|
$chat->createdDate = $chat->createdDate == '0000-00-00 00:00:00' ? 0 : strtotime($chat->createdDate);
|
|
$chat->lastActiveTime = $chat->lastActiveTime == '0000-00-00 00:00:00' ? 0 : strtotime($chat->lastActiveTime);
|
|
$chat->public = empty($chat->public) ? 0 : 1;
|
|
$chat->archiveDate = $chat->archiveDate == '0000-00-00 00:00:00' ? 0 : strtotime($chat->archiveDate);
|
|
return $chat;
|
|
}, $chats);
|
|
|
|
return dao::isError() ? array() : $chats;
|
|
}
|
|
|
|
/**
|
|
* Update chat avatar.
|
|
*
|
|
* @param string $gid
|
|
* @param object $avatarData
|
|
* @access public
|
|
* @return object
|
|
*/
|
|
public function updateAvatar($gid, $avatarData)
|
|
{
|
|
$this->dao->update(TABLE_IM_CHAT)->set('avatar')->eq($avatarData)->where('gid')->eq($gid)->exec();
|
|
return $this->getByGid($gid, true);
|
|
}
|
|
|
|
/**
|
|
* Super admin get all chatGroups.
|
|
*
|
|
* @access public
|
|
* @return array
|
|
*/
|
|
public function adminGetChatGroups()
|
|
{
|
|
$chats = $this->dao->select('*')->from(TABLE_IM_CHAT)
|
|
->where('type')->eq('group')
|
|
->andWhere('mergedDate')->eq('0000-00-00 00:00:00')
|
|
->andWhere('dismissDate')->eq('0000-00-00 00:00:00')
|
|
->fetchAll();
|
|
return dao::isError() ? array() : $chats;
|
|
}
|
|
|
|
}
|