/packages/Chat/Chat/Managers/ChatSessionManager.class.php
PHP | 334 lines | 258 code | 58 blank | 18 comment | 27 complexity | 8a6f558b2fef022467499577c74416f6 MD5 | raw file
1<?php
2class ChatSessionManager extends DbAccessor
3{
4 const TBL_CHAT_SESSIONS = 'chat_sessions';
5 const TBL_CHAT_SESSIONS_LOG = 'chat_sessions_log';
6
7 const CLOSED_STATUS_NO = 0;
8 const CLOSED_STATUS_YES = 1;
9
10 const CLOSED_REASON_CLOSE = 1;
11 const CLOSED_REASON_OFFLINE = 2;
12 const CLOSED_REASON_MONEY = 3;
13 const CLOSED_REASON_SYNC_UI = 4;
14
15 private $sessionClearTimeout = 10; // in minutes
16
17 public function __construct(Config $config, $instanceName = null){
18 parent::__construct($instanceName);
19
20 if(isset($config->sessionClearTimeout)){
21 $this->sessionClearTimeout = $config->sessionClearTimeout;
22 }
23 }
24
25 public static function getInterlocutorsFromSessions($chatSessions){
26 $interlocutorIds = array();
27 foreach($chatSessions as $chatSession){
28 array_push($interlocutorIds, $chatSession->interlocutorUser->userId);
29 }
30
31 return $interlocutorIds;
32 }
33
34 public static function fillSessionsWithMessages($chatSessions, $chatMessages){
35 foreach($chatMessages as $chatMessage){
36 foreach($chatSessions as &$chatSession){
37 // Check if this message belongs to this session.
38 if(
39 (
40 $chatMessage->senderUser->userId == $chatSession->interlocutorUser->userId
41 and
42 $chatMessage->receiverUser->userId == $chatSession->chatterUser->userId
43 )
44 or
45 (
46 $chatMessage->senderUser->userId == $chatSession->chatterUser->userId
47 and
48 $chatMessage->receiverUser->userId == $chatSession->interlocutorUser->userId
49 )
50 ){
51 array_push($chatSession->messages, $chatMessage);
52 }
53 }
54 }
55 return $chatSessions;
56 }
57
58 /**
59 * Sessions list
60 * @param ChatSessionFilter $filter
61 * @param unknown_type $myUserId
62 */
63 public function getChatSessions(ChatSessionFilter $filter = null, $myUserId = null){
64 $chatSessions = array();
65
66 if($filter == null){
67 $filter = new ChatSessionFilter();
68 }
69
70 $sqlQuery = $filter->getSQL();
71
72 $sessionRows = $this->query->exec($sqlQuery)->fetchRecords();
73
74 foreach ($sessionRows as $sessionRow){
75 array_push($chatSessions, $this->getChatSessionObject($sessionRow, $myUserId));
76 }
77
78 return $chatSessions;
79 }
80
81 /**
82 * Sessions count
83 * @param ProfileViewsFilter $filter
84 * @param Integer $cacheMinutes
85 * @return Integer
86 */
87 public function getChatSessionsCount(ChatSessionFilter $filter = null){
88
89 if($filter == null){
90 $filter = new ChatSessionFilter();
91 }
92 $filter->setSelectCount();
93
94 $sqlQuery = $filter->getSQL();
95
96 $this->query->exec($sqlQuery);
97 return $this->query->fetchField('cnt');
98 }
99
100 public function getChatSession(ChatSessionFilter $filter = null, $myUserId = null){
101 $sessions = $this->getChatSessions($filter, $myUserId);
102 if(count($sessions) !== 1){
103 throw new ChatSessionException("There is no such chat session or it is not unique.");
104 }
105 return $sessions[0];
106 }
107
108 public function getChatSessionById($sessionId, $myUserId = null){
109 $filter = new ChatSessionFilter();
110 $filter->setId($sessionId);
111 $session = $this->getChatSession($filter);
112 return $session;
113 }
114
115 protected function getChatSessionObject($sessionRow, $myUserId = null){
116 if(empty($sessionRow) or !is_array($sessionRow)){
117 throw new InvalidArgumentException("Invalid \$sessionRow specified!");
118 }
119
120 $chatSession = new ChatSession();
121
122 if($myUserId !== null){
123 if($sessionRow['inviter_user_id'] == $myUserId){
124 $interlocutorUserId = $sessionRow['invited_user_id'];
125 }
126 else{
127 $interlocutorUserId = $sessionRow['inviter_user_id'];
128 }
129
130 $chatSession->chatterUser = ChatUser::getObject($myUserId);
131 $chatSession->interlocutorUser = ChatUser::getObject($interlocutorUserId);
132 }
133 else{
134 $chatSession->chatterUser = ChatUser::getObject($sessionRow['inviter_user_id']);
135 $chatSession->interlocutorUser = ChatUser::getObject($sessionRow['invited_user_id']);
136 }
137
138 $chatSession->id = $sessionRow['id'];
139 $chatSession->startDate = $sessionRow['date'];
140 $chatSession->closed = $sessionRow['closed'];
141 $chatSession->closedBy = $sessionRow['closed_by'];
142 $chatSession->closedReason = $sessionRow['closed_reason'];
143 $chatSession->closedDate = $sessionRow['closed_date'];
144
145 return $chatSession;
146 }
147
148 public function getInterlocutorsIds($userId){
149 if(empty($userId) or !is_numeric($userId)){
150 throw new InvalidArgumentException("Invalid userId specified!");
151 }
152
153 $filter = new ChatSessionFilter();
154 $filter->setEitherUserId($userId);
155 $chatSessions = $this->getChatSessions($filter, $userId);
156
157 $interlocutorIds = array();
158 foreach($chatSessions as $chatSession){
159 array_push($interlocutorIds, $chatSession->interlocutorUser->userId);
160 }
161
162 return $interlocutorIds;
163 }
164
165 public function insertSession($inviterUserId, $invitedUserId){
166 if(empty($inviterUserId) or !is_numeric($inviterUserId)){
167 throw new InvalidArgumentException("Invalid inviterUser specified!");
168 }
169 if(empty($invitedUserId) or !is_numeric($invitedUserId)){
170 throw new InvalidArgumentException("Invalid invitedUser specified!");
171 }
172 $qb = new QueryBuilder();
173 $qb->insertIgnore(Tbl::get('TBL_CHAT_SESSIONS'))
174 ->values(array(
175 'inviter_user_id' => $inviterUserId,
176 'invited_user_id' => $invitedUserId
177 ));
178 $this->query->exec($qb->getSQL());
179
180 $newSessionId = $this->query->getLastInsertId();
181 //$this->insertSessionLog($inviterUserId, $invitedUserId);
182
183 return $newSessionId;
184 }
185
186 public function deleteSession($sessionId){
187 if(empty($sessionId) or !is_numeric($sessionId)){
188 throw new InvalidArgumentException("Invalid session ID specified!");
189 }
190 $qb = new QueryBuilder();
191 $qb->delete(Tbl::get('TBL_CHAT_SESSIONS'))
192 ->where($qb->expr()->equal(new Field('id'), $sessionId));
193 $this->query->exec($qb->getSQL());
194 }
195
196 public function closeSession(ChatSession $session, ChatUser $closerUser, $reason = null){
197
198 $qb = new QueryBuilder();
199 $qb->update(Tbl::get('TBL_CHAT_SESSIONS'))
200 ->set(new Field('closed'), static::CLOSED_STATUS_YES)
201 ->set(new Field('closed_date'), new Func('NOW'))
202 ->set(new Field('closed_by'), $closerUser->userId)
203 ->where($qb->expr()->equal(new Field('id'), $session->id));
204 if($reason !== null){
205 $qb->set(new Field('closed_reason'), $reason);
206 $session->closedReason = $reason;
207 }
208 $this->query->exec($qb->getSQL());
209
210 $session->closed = static::CLOSED_STATUS_YES;
211 $session->closedBy = $closerUser->userId;
212 }
213
214 public function clearTimedOutSessions(){
215 $qb = new QueryBuilder();
216 $qb->delete(Tbl::get('TBL_CHAT_SESSIONS'))
217 ->where($qb->expr()->equal(new Field('closed'), 1))
218 ->andWhere(
219 $qb->expr()->greaterEqual(
220 $qb->expr()->diff(new Func('NOW'), new Field('closed_date')),
221 $qb->expr()->prod($this->sessionClearTimeout, 60)
222 ));
223
224 $this->query->exec($qb->getSQL());
225 return $this->query->affected();
226 }
227
228 public function getChatSessionsLog(MysqlPager $pager = null, $myUserId = null, $cacheMinutes = 0){
229 $sessions = array();
230 $qb = new QueryBuilder();
231 $qb->select(new Field("*", "chat_sess_log"))->from(Tbl::get('TBL_CHAT_SESSIONS_LOG'), "chat_sess_log");
232
233 if($myUserId !== null){
234 $orClause = new Orx();
235 $orClause->add($qb->expr()->equal(new Field("user1_id", "chat_sess_log"), $myUserId));
236 $orClause->add($qb->expr()->equal(new Field("user2_id", "chat_sess_log"), $myUserId));
237 $qb->andWhere($orClause);
238 }
239
240 $qb->orderBy(new Field("datetime", "chat_sess_log"), MySqlDatabase::ORDER_DESC);
241 $sqlQuery = $qb->getSQL();
242
243 if($pager !== null){
244 $this->query = $pager->executePagedSQL($sqlQuery, $cacheMinutes);
245 }
246 else{
247 $this->query->exec($sqlQuery, $cacheMinutes);
248 }
249
250 if($this->query->countRecords()){
251 while(($sesLogRow = $this->query->fetchRecord()) != null){
252 $chatSession = new ChatSessionLog();
253
254 $chatSession->user1 = ChatUser::getObject($sesLogRow['user1_id']);
255 $chatSession->user2 = ChatUser::getObject($sesLogRow['user2_id']);
256
257 $chatSession->id = $sesLogRow['id'];
258 $chatSession->closedDate = $sesLogRow['datetime'];
259
260 array_push($sessions, $chatSession);
261 }
262 }
263
264 return $sessions;
265 }
266
267 public function getChatSessionsLogCount($myUserId = null){
268
269 $qb = new QueryBuilder();
270 $qb->select($qb->expr()->count(new Field('*'), 'cnt'))->from(Tbl::get('TBL_CHAT_SESSIONS_LOG'), "chat_sess_log");
271 if($myUserId !== null){
272 $orClause = new Orx();
273 $orClause->add($qb->expr()->equal(new Field("user1_id", "chat_sess_log"), $myUserId));
274 $orClause->add($qb->expr()->equal(new Field("user2_id", "chat_sess_log"), $myUserId));
275 $qb->andWhere($orClause);
276 }
277
278 $sqlQuery = $qb->getSQL();
279 $this->query->exec($sqlQuery);
280 return $this->query->fetchField('cnt');
281 }
282 /**
283 * @param integer $inviterUserId
284 * @param integer $invitedUserId
285 * @deprecated Sessions log insertd by mysql TRIGGER chat_sessions_log
286 */
287 protected function insertSessionLog($inviterUserId, $invitedUserId){
288 if($inviterUserId > $invitedUserId){
289 $userId1 = $inviterUserId;
290 $userId2 = $invitedUserId;
291 }
292 else{
293 $userId1 = $invitedUserId;
294 $userId2 = $inviterUserId;
295 }
296 $qb = new QueryBuilder();
297 $qb->select(new Field('id'))->from(Tbl::get('TBL_CHAT_SESSIONS_LOG'));
298
299 $andClause1 = new Andx();
300 $andClause1->add($qb->expr()->equal(new Field('user1_id', Tbl::get('TBL_CHAT_SESSIONS_LOG')), $userId1));
301 $andClause1->add($qb->expr()->equal(new Field('user2_id', Tbl::get('TBL_CHAT_SESSIONS_LOG')), $userId2));
302
303 $andClause2 = new Andx();
304 $andClause2->add($qb->expr()->equal(new Field('user1_id', Tbl::get('TBL_CHAT_SESSIONS_LOG')), $userId2));
305 $andClause2->add($qb->expr()->equal(new Field('user2_id', Tbl::get('TBL_CHAT_SESSIONS_LOG')), $userId1));
306
307 $orClause = new Orx();
308 $orClause->add($andClause1);
309 $orClause->add($andClause2);
310
311 $qb->andWhere($orClause);
312 $this->query->exec($qb->getSQL());
313
314 $qb = new QueryBuilder();
315 if($this->query->countRecords()){
316 $sesionId = $this->query->fetchField("id");
317 $qb->update(Tbl::get('TBL_CHAT_SESSIONS_LOG'))
318 ->set(new Field('datetime'), date(DEFAULT_DATETIME_FORMAT))
319 ->where($qb->expr()->equal(new Field('id'), $sesionId));
320
321 }
322 else{
323 $qb->insert(Tbl::get('TBL_CHAT_SESSIONS_LOG'))
324 ->values(array(
325 'user1_id' => $userId1,
326 'user2_id' => $userId2,
327 'datetime' => date(DEFAULT_DATETIME_FORMAT)
328 ));
329 }
330 $this->query->exec($qb->getSQL());
331
332 return $this->query->affected();
333 }
334}