/packages/Chat/Chat/Managers/ChatSessionManager.class.php

https://bitbucket.org/alexamiryan/stingle · PHP · 334 lines · 258 code · 58 blank · 18 comment · 27 complexity · 8a6f558b2fef022467499577c74416f6 MD5 · raw file

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