Merge branch 'MDL-64017_master' of git://github.com/markn86/moodle
authorAdrian Greeve <abgreeve@gmail.com>
Thu, 18 Apr 2019 08:14:57 +0000 (16:14 +0800)
committerAdrian Greeve <abgreeve@gmail.com>
Thu, 18 Apr 2019 08:18:22 +0000 (16:18 +0800)
1  2 
lib/classes/message/manager.php
lib/tests/messagelib_test.php
message/amd/build/message_drawer.min.js
message/amd/src/message_drawer.js
message/classes/helper.php
message/index.php
message/output/email/classes/task/send_email_task.php

@@@ -109,11 -109,7 +109,12 @@@ class manager 
          // Get conversation type and name. We'll use this to determine which message subject to generate, depending on type.
          $conv = $DB->get_record('message_conversations', ['id' => $eventdata->convid], 'id, type, name');
  
 +        // For now Self conversations are not processed because users are aware of the messages sent by themselves, so we
 +        // can return early.
 +        if ($conv->type == \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF) {
 +            return $savemessage->id;
 +        }
+         $localisedeventdata->conversationtype = $conv->type;
  
          // We treat individual conversations the same as any direct message with 'userfrom' and 'userto' specified.
          // We know the other user, so set the 'userto' field so that the event code will get access to this field.
Simple merge
index 9f89d03,867cb43..4c5809e
Binary files differ
Simple merge
Simple merge
Simple merge
index 0000000,33c4238..d3bf848
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,173 +1,173 @@@
 -                    ON mem.conversationid = mc.id  
+ <?php
+ // This file is part of Moodle - http://moodle.org/
+ //
+ // Moodle is free software: you can redistribute it and/or modify
+ // it under the terms of the GNU General Public License as published by
+ // the Free Software Foundation, either version 3 of the License, or
+ // (at your option) any later version.
+ //
+ // Moodle is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ // GNU General Public License for more details.
+ //
+ // You should have received a copy of the GNU General Public License
+ // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+ /**
+  * Contains the class responsible for sending emails as a digest.
+  *
+  * @package    message_email
+  * @copyright  2019 Mark Nelson <markn@moodle.com>
+  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+  */
+ namespace message_email\task;
+ use core\task\scheduled_task;
+ use moodle_recordset;
+ defined('MOODLE_INTERNAL') || die();
+ /**
+  * Class responsible for sending emails as a digest.
+  *
+  * @package    message_email
+  * @copyright  2019 Mark Nelson <markn@moodle.com>
+  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+  */
+ class send_email_task extends scheduled_task {
+     /**
+      * @var int $maxid This is the maximum id of the message in 'message_email_messages'.
+      *                 We use this so we know what records to process, as more records may be added
+      *                 while this task runs.
+      */
+     private $maxid;
+     /**
+      * Get a descriptive name for this task (shown to admins).
+      *
+      * @return string
+      */
+     public function get_name() {
+         return get_string('tasksendemail', 'message_email');
+     }
+     /**
+      * Send out emails.
+      */
+     public function execute() {
+         global $DB, $PAGE;
+         // Get the maximum id we are going to use.
+         // We use this as records may be added to the table while this task runs.
+         $this->maxid = $DB->get_field_sql("SELECT MAX(id) FROM {message_email_messages}");
+         // We are going to send these emails from 'noreplyaddress'.
+         $noreplyuser = \core_user::get_noreply_user();
+         // The renderers used for sending emails.
+         $htmlrenderer = $PAGE->get_renderer('message_email', 'email', 'htmlemail');
+         $textrenderer = $PAGE->get_renderer('message_email', 'email', 'textemail');
+         // Keep track of which emails failed to send.
+         $users = $this->get_unique_users();
+         foreach ($users as $user) {
+             $hascontent = false;
+             $renderable = new \message_email\output\email_digest($user);
+             $conversations = $this->get_conversations_for_user($user->id);
+             foreach ($conversations as $conversation) {
+                 $renderable->add_conversation($conversation);
+                 $messages = $this->get_users_messages_for_conversation($conversation->id, $user->id);
+                 if ($messages->valid()) {
+                     $hascontent = true;
+                     foreach ($messages as $message) {
+                         $renderable->add_message($message);
+                     }
+                 }
+                 $messages->close();
+             }
+             $conversations->close();
+             if ($hascontent) {
+                 $subject = get_string('emaildigestsubject', 'message_email');
+                 $message = $textrenderer->render($renderable);
+                 $messagehtml = $htmlrenderer->render($renderable);
+                 if (email_to_user($user, $noreplyuser, $subject, $message, $messagehtml)) {
+                     $DB->delete_records_select('message_email_messages', 'useridto = ? AND id <= ?', [$user->id, $this->maxid]);
+                 }
+             }
+         }
+         $users->close();
+     }
+     /**
+      * Returns an array of users in the given conversation.
+      *
+      * @return moodle_recordset A moodle_recordset instance.
+      */
+     private function get_unique_users() : moodle_recordset {
+         global $DB;
+         $subsql = 'SELECT DISTINCT(useridto) as id
+                      FROM {message_email_messages}
+                     WHERE id <= ?';
+         $sql = "SELECT *
+                   FROM {user} u
+                  WHERE id IN ($subsql)";
+         return $DB->get_recordset_sql($sql, [$this->maxid]);
+     }
+     /**
+      * Returns an array of unique conversations that require processing.
+      *
+      * @param int $userid The ID of the user we are sending a digest to.
+      * @return moodle_recordset A moodle_recordset instance.
+      */
+     private function get_conversations_for_user(int $userid) : moodle_recordset {
+         global $DB;
+         // We shouldn't be joining directly on the group table as group
+         // conversations may (in the future) be something created that
+         // isn't related to an actual group in a course. However, for
+         // now this will have to do before 3.7 code freeze.
+         // See related MDL-63814.
+         $sql = "SELECT mc.id, mc.name, c.id as courseid, c.fullname as coursename, g.id as groupid, g.picture, g.hidepicture
+                   FROM {message_conversations} mc
+                   JOIN {groups} g
+                     ON mc.itemid = g.id
+                   JOIN {course} c
+                     ON g.courseid = c.id
+                   JOIN {message_email_messages} mem
++                    ON mem.conversationid = mc.id
+                  WHERE mem.useridto = ?
+                    AND mem.id <= ?";
+         return $DB->get_recordset_sql($sql, [$userid, $this->maxid]);
+     }
+     /**
+      * Returns the messages to send to a user for a given conversation
+      *
+      * @param int $conversationid
+      * @param int $userid
+      * @return moodle_recordset A moodle_recordset instance.
+      */
+     protected function get_users_messages_for_conversation(int $conversationid, int $userid) : moodle_recordset {
+         global $DB;
+         $usernamefields = \user_picture::fields('u');
+         $sql = "SELECT $usernamefields, m.*
+                   FROM {messages} m
+                   JOIN {user} u
+                     ON u.id = m.useridfrom
+                   JOIN {message_email_messages} mem
+                     ON mem.messageid = m.id
+                  WHERE mem.useridto = ?
+                    AND mem.conversationid = ?
+                    AND mem.id <= ?";
+         return $DB->get_recordset_sql($sql, [$userid, $conversationid, $this->maxid]);
+     }
+ }