From d7b236fa5ec45c34bb1e145d729ed58815ab16a0 Mon Sep 17 00:00:00 2001 From: Jun Pataleta Date: Thu, 22 Mar 2018 17:14:55 +0800 Subject: [PATCH] MDL-61484 mod_chat: Fix chat_get_sessions logic --- mod/chat/lib.php | 88 ++++++++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 41 deletions(-) diff --git a/mod/chat/lib.php b/mod/chat/lib.php index 20d6de05936..9c4f050a9d6 100644 --- a/mod/chat/lib.php +++ b/mod/chat/lib.php @@ -1486,58 +1486,64 @@ function mod_chat_core_calendar_provide_event_action(calendar_event $event, /** * Given a set of messages for a chat, return the completed chat sessions (including optionally not completed ones). * - * @param array $messages list of messages from a chat + * @param array $messages list of messages from a chat. It is assumed that these are sorted by timestamp in DESCENDING order. * @param bool $showall whether to include incomplete sessions or not * @return array the list of sessions - * @since Moodle 3.4 + * @since Moodle 3.5 */ function chat_get_sessions($messages, $showall = false) { - $sessions = array(); + $sessions = []; $sessiongap = 5 * 60; // 5 minutes silence means a new session. - $sessionend = 0; - $sessionstart = 0; - $sessionusers = array(); - $lasttime = 0; - - $messagesleft = count($messages); - - foreach ($messages as $message) { // We are walking BACKWARDS through the messages. - - $messagesleft --; // Countdown. + $start = 0; + $end = 0; + $sessiontimes = []; + + // Group messages by session times. + foreach ($messages as $message) { + // Initialise values start-end times if necessary. + if (empty($start)) { + $start = $message->timestamp; + } + if (empty($end)) { + $end = $message->timestamp; + } - if (!$lasttime) { - $lasttime = $message->timestamp; + // If this message's timestamp has been more than the gap, it means it's been idle. + if ($start - $message->timestamp > $sessiongap) { + // Mark this as the session end of the next session. + $end = $message->timestamp; } - if (!$sessionend) { - $sessionend = $message->timestamp; + // Use this time as the session's start (until it gets overwritten on the next iteration, if needed). + $start = $message->timestamp; + + // Set this start-end pair in our list of session times. + $sessiontimes[$end]['sessionstart'] = $start; + if (!isset($sessiontimes[$end]['sessionend'])) { + $sessiontimes[$end]['sessionend'] = $end; } - if ((($lasttime - $message->timestamp) < $sessiongap) and $messagesleft) { // Same session. - if ($message->userid and !$message->issystem) { // Remember user and count messages. - if (empty($sessionusers[$message->userid])) { - $sessionusers[$message->userid] = 1; - } else { - $sessionusers[$message->userid] ++; - } - } - } else { - $sessionstart = $lasttime; - - $iscomplete = ($sessionend - $sessionstart > 60 and count($sessionusers) > 1); - if ($showall or $iscomplete) { - $sessions[] = (object) array( - 'sessionstart' => $sessionstart, - 'sessionend' => $sessionend, - 'sessionusers' => $sessionusers, - 'iscomplete' => $iscomplete, - ); + if ($message->userid && !$message->issystem) { + if (!isset($sessiontimes[$end]['sessionusers'][$message->userid])) { + $sessiontimes[$end]['sessionusers'][$message->userid] = 1; + } else { + $sessiontimes[$end]['sessionusers'][$message->userid]++; } + } + } + + // Go through each session time and prepare the session data to be returned. + foreach ($sessiontimes as $sessionend => $sessiondata) { + if (!isset($sessiondata['sessionusers'])) { + $sessiondata['sessionusers'] = []; + } + $sessionusers = $sessiondata['sessionusers']; + $sessionstart = $sessiondata['sessionstart']; - $sessionend = $message->timestamp; - $sessionusers = array(); - $sessionusers[$message->userid] = 1; + $iscomplete = $sessionend - $sessionstart > 60 && count($sessionusers) > 1; + if ($showall || $iscomplete) { + $sessions[] = (object) ($sessiondata + ['iscomplete' => $iscomplete]); } - $lasttime = $message->timestamp; } + return $sessions; } @@ -1550,7 +1556,7 @@ function chat_get_sessions($messages, $showall = false) { * @param int $end the session end timestamp (0 to not filter by time) * @param string $sort an order to sort the results in (optional, a valid SQL ORDER BY parameter) * @return array session messages - * @since Moodle 3.4 + * @since Moodle 3.5 */ function chat_get_session_messages($chatid, $group = false, $start = 0, $end = 0, $sort = '') { global $DB; -- 2.43.0