message MDLSITE-1042 fixed some messaging bugs
authorAndrew Davis <andrew@affinitysoftware.net>
Thu, 7 Oct 2010 03:59:07 +0000 (03:59 +0000)
committerAndrew Davis <andrew@affinitysoftware.net>
Thu, 7 Oct 2010 03:59:07 +0000 (03:59 +0000)
message/lib.php

index 80cda1b..e85ec6b 100644 (file)
@@ -1635,12 +1635,7 @@ function message_move_userfrom_unread2read($userid) {
     // move all unread messages from message table to message_read
     if ($messages = $DB->get_records_select('message', 'useridfrom = ?', array($userid), 'timecreated')) {
         foreach ($messages as $message) {
-            $message->timeread = 0; //the message was never read
-            $messageid = $message->id;
-            unset($message->id);
-            $DB->insert_record('message_read', $message);
-            $DB->delete_records('message', array('id' => $messageid));
-            $DB->delete_records('message_working', array('unreadmessageid' => $messageid));
+            message_mark_message_read($message, 0); //set timeread to 0 as the message was never read
         }
     }
     return true;
@@ -1670,35 +1665,49 @@ function message_get_popup_messages($destuserid, $fromuserid=NULL){
             //delete what we've processed and check if can move message
             $DB->delete_records('message_working', array('id' => $msgp->id));
             if ( $DB->count_records('message_working', array('unreadmessageid'=>$messageid)) == 0){
-                $DB->insert_record('message_read', $message);
-                $DB->delete_records('message', array('id' => $messageid));
+                message_mark_message_read($message, time(), true);
             }
         }
     }
     return $messages;
 }
 
-//marks ALL messages being sent from $fromuserid to $touserid as read
+/**
+* marks ALL messages being sent from $fromuserid to $touserid as read
+* @param int $touserid the id of the message recipient
+* @param int $fromuserid the id of the message sender
+* @return void
+*/
 function message_mark_messages_read($touserid, $fromuserid){
     global $DB;
 
-    $sql = 'SELECT m.*, mw.id AS mwid FROM {message} m JOIN {message_working} mw ON m.id=mw.unreadmessageid WHERE m.useridto=:useridto AND m.useridfrom=:useridfrom';
+    $sql = 'SELECT m.* FROM {message} m WHERE m.useridto=:useridto AND m.useridfrom=:useridfrom';
     $messages = $DB->get_recordset_sql($sql, array('useridto'=>$touserid,'useridfrom'=>$fromuserid));
 
-    //todo surely we can do this with one query rather than with a loop
-
     foreach ($messages as $message) {
-        $message->timeread = time();
-        $messageid = $message->id;
-        unset($message->id);//unset because it will get a new id on insert into message_read
+        message_mark_message_read($message, time());
+    }
+}
+
+/**
+* Mark a single message as read
+* @param message an object with an object property ie $message->id which is an id in the message table
+* @param int $timeread the timestamp for when the message should be marked read. Usually time().
+* @param bool $messageworkingempty Is the message_working table already confirmed empty for this message?
+* @return void
+*/
+function message_mark_message_read($message, $timeread, $messageworkingempty=false) {
+    global $DB;
+    
+    $message->timeread = $timeread;
 
-        //indicate the message is read
-        $DB->delete_records('message_working', array('id' => $message->mwid));
+    $messageid = $message->id;
+    unset($message->id);//unset because it will get a new id on insert into message_read
 
-        //have all message processors completed dealing with this message?
-        if ( $DB->count_records('message_working', array('unreadmessageid'=>$messageid)) == 0){
-            $DB->insert_record('message_read', $message);
-            $DB->delete_records('message', array('id' => $messageid));
-        }
+    //If any processors have pending actions abort them
+    if (!$messageworkingempty) {
+        $DB->delete_records('message_working', array('unreadmessageid' => $messageid));
     }
+    $DB->insert_record('message_read', $message);
+    $DB->delete_records('message', array('id' => $messageid));
 }