MDL-54687 core_message: created page for new messaging interface
authorMark Nelson <markn@moodle.com>
Tue, 31 May 2016 11:34:29 +0000 (19:34 +0800)
committerMark Nelson <markn@moodle.com>
Fri, 7 Oct 2016 08:20:51 +0000 (16:20 +0800)
This commit introduces the templates, renderer and initial API
that will be used for further development.

18 files changed:
lang/en/message.php
message/classes/api.php [new file with mode: 0644]
message/classes/helper.php [new file with mode: 0644]
message/classes/output/contact.php [new file with mode: 0644]
message/classes/output/contacts.php [new file with mode: 0644]
message/classes/output/message.php [new file with mode: 0644]
message/classes/output/message_area_page.php [new file with mode: 0644]
message/classes/output/messages.php [new file with mode: 0644]
message/classes/output/renderer.php [new file with mode: 0644]
message/index.php
message/lib.php
message/templates/contact.mustache [new file with mode: 0644]
message/templates/contacts.mustache [new file with mode: 0644]
message/templates/message.mustache [new file with mode: 0644]
message/templates/message_area.mustache [new file with mode: 0644]
message/templates/messages.mustache [new file with mode: 0644]
theme/bootstrapbase/less/moodle/message.less
theme/bootstrapbase/style/moodle.css

index 76264ed..6230e7b 100644 (file)
@@ -39,6 +39,7 @@ $string['blocknoncontacts'] = 'Prevent non-contacts from messaging me';
 $string['contactlistempty'] = 'Contact list empty';
 $string['contacts'] = 'Contacts';
 $string['context'] = 'context';
+$string['conversations'] = 'Conversations';
 $string['defaultmessageoutputs'] = 'Default message outputs';
 $string['defaults'] = 'Defaults';
 $string['deletemessage'] = 'Delete message';
@@ -129,6 +130,7 @@ $string['search'] = 'Search';
 $string['searchforperson'] = 'Search for a person';
 $string['searchmessages'] = 'Search messages';
 $string['searchcombined'] = 'Search people and messages';
+$string['send'] = 'Send';
 $string['sendingvia'] = 'Sending "{$a->provider}" via "{$a->processor}"';
 $string['sendingviawhen'] = 'Sending "{$a->provider}" via "{$a->processor}" when {$a->state}';
 $string['sendingmessage'] = 'Sending message';
@@ -151,4 +153,5 @@ $string['unreadnewmessage'] = 'New message from {$a}';
 $string['userisblockingyou'] = 'This user has blocked you from sending messages to them';
 $string['userisblockingyounoncontact'] = '{$a} only accepts messages from their contacts.';
 $string['userssearchresults'] = 'Users found: {$a}';
+$string['viewinganotherusersmessagearea'] = 'You are viewing another user\'s message area.';
 $string['viewconversation'] = 'View conversation';
diff --git a/message/classes/api.php b/message/classes/api.php
new file mode 100644 (file)
index 0000000..5fc1017
--- /dev/null
@@ -0,0 +1,104 @@
+<?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 class used to return information to display for the message area.
+ *
+ * @package    core_message
+ * @copyright  2016 Mark Nelson <markn@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core_message;
+
+require_once($CFG->dirroot . '/lib/messagelib.php');
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Class used to return information to display for the message area.
+ *
+ * @copyright  2016 Mark Nelson <markn@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class api {
+
+    /**
+     * Returns the contacts and their conversation to display in the contacts area.
+     *
+     * @param int $userid The user id
+     * @param int $otheruserid The id of the user we have selected, 0 if none have been selected
+     * @param int $limitfrom
+     * @param int $limitnum
+     * @return \core_message\output\contacts
+     */
+    public static function get_conversations($userid, $otheruserid = 0, $limitfrom = 0, $limitnum = 0) {
+        $arrcontacts = array();
+        if ($conversations = message_get_recent_conversations($userid, $limitfrom, $limitnum)) {
+            foreach ($conversations as $conversation) {
+                $arrcontacts[] = \core_message\helper::create_contact($conversation);
+            }
+        }
+
+        return new \core_message\output\contacts($userid, $otheruserid, $arrcontacts);
+    }
+
+    /**
+     * Returns the contacts to display in the contacts area.
+     *
+     * @param int $userid The user id
+     * @param int $limitfrom
+     * @param int $limitnum
+     * @return \core_message\output\contacts
+     */
+    public static function get_contacts($userid, $limitfrom = 0, $limitnum = 0) {
+        global $DB;
+
+        $arrcontacts = array();
+        $sql = "SELECT u.*
+                  FROM {message_contacts} mc
+                  JOIN {user} u
+                    ON mc.contactid = u.id
+                 WHERE mc.userid = :userid
+                   AND u.deleted = 0
+              ORDER BY " . $DB->sql_fullname();
+        if ($contacts = $DB->get_records_sql($sql, array('userid' => $userid), $limitfrom, $limitnum)) {
+            foreach ($contacts as $contact) {
+                $arrcontacts[] = \core_message\helper::create_contact($contact);
+            }
+        }
+
+        return new \core_message\output\contacts($userid, 0, $arrcontacts, false);
+    }
+
+    /**
+     * Returns the messages to display in the message area.
+     *
+     * @param int $userid the current user
+     * @param int $otheruserid the other user
+     * @param int $limitfrom
+     * @param int $limitnum
+     * @return \core_message\output\messages
+     */
+    public static function get_messages($userid, $otheruserid, $limitfrom = 0, $limitnum = 0) {
+        $arrmessages = array();
+        if ($messages = \core_message\helper::get_messages($userid, $otheruserid, $limitfrom, $limitnum)) {
+            $arrmessages = \core_message\helper::create_messages($userid, $messages);
+        }
+
+        return new \core_message\output\messages($userid, $otheruserid, $arrmessages);
+    }
+}
diff --git a/message/classes/helper.php b/message/classes/helper.php
new file mode 100644 (file)
index 0000000..07c0a59
--- /dev/null
@@ -0,0 +1,147 @@
+<?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 helper class for the message area.
+ *
+ * @package    core_message
+ * @copyright  2016 Mark Nelson <markn@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core_message;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Helper class for the message area.
+ *
+ * @copyright  2016 Mark Nelson <markn@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class helper {
+
+    /**
+     * Helper function to retrieve the messages between two users
+     *
+     * @param int $userid the current user
+     * @param int $otheruserid the other user
+     * @param int $limitfrom
+     * @param int $limitnum
+     * @param string $sort
+     * @return array of messages
+     */
+    public static function get_messages($userid, $otheruserid, $limitfrom = 0, $limitnum = 0, $sort = 'timecreated ASC') {
+        global $DB;
+
+        $sql = "SELECT id, useridfrom, useridto, subject, fullmessage, fullmessagehtml, fullmessageformat,
+                       smallmessage, notification, timecreated, 0 as timeread
+                  FROM {message} m
+                 WHERE ((useridto = ? AND useridfrom = ? AND timeusertodeleted = 0)
+                    OR (useridto = ? AND useridfrom = ? AND timeuserfromdeleted = 0))
+                   AND notification = 0
+             UNION ALL
+                SELECT id, useridfrom, useridto, subject, fullmessage, fullmessagehtml, fullmessageformat,
+                       smallmessage, notification, timecreated, timeread
+                  FROM {message_read} mr
+                 WHERE ((useridto = ? AND useridfrom = ? AND timeusertodeleted = 0)
+                    OR (useridto = ? AND useridfrom = ? AND timeuserfromdeleted = 0))
+                   AND notification = 0
+              ORDER BY $sort";
+        $params = array($userid, $otheruserid, $otheruserid, $userid,
+                        $userid, $otheruserid, $otheruserid, $userid);
+
+        return $DB->get_records_sql($sql, $params, $limitfrom, $limitnum);
+    }
+
+    /**
+     * Helper function to return an array of messages renderables to display in the message area.
+     *
+     * @param int $userid
+     * @param array $messages
+     * @return \core_message\output\message[]
+     */
+    public static function create_messages($userid, $messages) {
+        // Store the messages.
+        $arrmessages = array();
+
+        // Keeps track of the last day, month and year combo we were viewing.
+        $day = '';
+        $month = '';
+        $year = '';
+        foreach ($messages as $message) {
+            // Check if we are now viewing a different block period.
+            $blocktime = null;
+            $date = usergetdate($message->timecreated);
+            if ($day != $date['mday'] || $month != $date['month'] || $year != $date['year']) {
+                $day = $date['mday'];
+                $month = $date['month'];
+                $year = $date['year'];
+                $blocktime = userdate($message->timecreated, get_string('strftimedaydate'));
+            }
+            // Store the message to pass to the renderable.
+            $msg = new \stdClass();
+            $msg->text = message_format_message_text($message);
+            $msg->currentuserid = $userid;
+            $msg->useridfrom = $message->useridfrom;
+            $msg->useridto = $message->useridto;
+            $msg->blocktime = $blocktime;
+            $msg->timecreated = $message->timecreated;
+            $arrmessages[] = new \core_message\output\message($msg);
+        }
+
+        return $arrmessages;
+    }
+
+    /**
+     * Helper function for creating a contact renderable.
+     *
+     * @param \stdClass $contact
+     * @return \core_message\output\contact
+     */
+    public static function create_contact($contact) {
+        global $CFG, $PAGE;
+
+        // Variables to check if we consider this user online or not.
+        $timetoshowusers = 300; // Seconds default.
+        if (isset($CFG->block_online_users_timetosee)) {
+            $timetoshowusers = $CFG->block_online_users_timetosee * 60;
+        }
+        $time = time() - $timetoshowusers;
+
+        // Create the data we are going to pass to the renderable.
+        $userfields = \user_picture::unalias($contact, array('lastaccess'));
+        $data = new \stdClass();
+        $data->userid = $userfields->id;
+        $data->fullname = fullname($userfields);
+        // Get the user picture data.
+        $userpicture = new \user_picture($userfields);
+        $userpicture->size = 1; // Size f1.
+        $data->profileimageurl = $userpicture->get_url($PAGE)->out(false);
+        $userpicture->size = 0; // Size f2.
+        $data->profileimageurlsmall = $userpicture->get_url($PAGE)->out(false);
+        // Store the message if we have it.
+        if (isset($contact->smallmessage)) {
+            $data->lastmessage = $contact->smallmessage;
+        } else {
+            $data->lastmessage = null;
+        }
+        // Check if the user is online.
+        $data->isonline = $userfields->lastaccess >= $time;
+
+        return new \core_message\output\contact($data);
+    }
+}
\ No newline at end of file
diff --git a/message/classes/output/contact.php b/message/classes/output/contact.php
new file mode 100644 (file)
index 0000000..199c2d6
--- /dev/null
@@ -0,0 +1,69 @@
+<?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 class used to prepare a contact for display.
+ *
+ * @package   core_message
+ * @copyright 2016 Mark Nelson <markn@moodle.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core_message\output;
+
+use renderable;
+use templatable;
+
+/**
+ * Class to prepare a contact for display.
+ *
+ * @package   core_message
+ * @copyright 2016 Mark Nelson <markn@moodle.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class contact implements templatable, renderable {
+
+    /**
+     * Maximum length of message to show in left panel.
+     */
+    const MAX_MSG_LENGTH = 60;
+
+    /**
+     * The contact.
+     */
+    protected $contact;
+
+    /**
+     * Constructor.
+     *
+     * @param \stdClass $contact
+     */
+    public function __construct($contact) {
+        $this->contact = $contact;
+    }
+
+    public function export_for_template(\renderer_base $output) {
+        $contact = new \stdClass();
+        $contact->userid = $this->contact->userid;
+        $contact->fullname = $this->contact->fullname;
+        $contact->profileimageurl = $this->contact->profileimageurl;
+        $contact->profileimageurlsmall = $this->contact->profileimageurlsmall;
+        $contact->lastmessage = shorten_text($this->contact->lastmessage, self::MAX_MSG_LENGTH);
+        $contact->isonline = $this->contact->isonline;
+
+        return $contact;
+    }
+}
diff --git a/message/classes/output/contacts.php b/message/classes/output/contacts.php
new file mode 100644 (file)
index 0000000..7c366b4
--- /dev/null
@@ -0,0 +1,91 @@
+<?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 class used to prepare the contacts for display.
+ *
+ * @package   core_message
+ * @copyright 2016 Mark Nelson <markn@moodle.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core_message\output;
+
+use renderable;
+use templatable;
+
+/**
+ * Class to prepare the contacts for display.
+ *
+ * @package   core_message
+ * @copyright 2016 Mark Nelson <markn@moodle.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class contacts implements templatable, renderable {
+
+    /**
+     * The id of the user that the contacts belong to.
+     */
+    protected $userid;
+
+    /**
+     * The id of the user that has been selected.
+     */
+    protected $otheruserid;
+
+    /**
+     * The contacts.
+     */
+    protected $contacts;
+
+    /**
+     * Determines if the conversations have been selected.
+     */
+    protected $conversationsselected;
+
+    /**
+     * Constructor.
+     *
+     * @param int $userid The id of the user the contacts belong to
+     * @param int $otheruserid The id of the user we are viewing
+     * @param \core_message\output\contact[] $contacts
+     * @param bool $conversationsselected
+     */
+    public function __construct($userid, $otheruserid, $contacts, $conversationsselected = true) {
+        $this->userid = $userid;
+        $this->otheruserid = $otheruserid;
+        $this->contacts = $contacts;
+        $this->conversationsselected = $conversationsselected;
+    }
+
+    public function export_for_template(\renderer_base $output) {
+        $data = new \stdClass();
+        $data->userid = $this->userid;
+        $data->otheruserid = $this->otheruserid;
+        $data->contacts = array();
+        foreach ($this->contacts as $contact) {
+            $contactdata = $contact->export_for_template($output);
+            // Check if the contact was selected.
+            if ($this->otheruserid == $contactdata->userid) {
+                $contactdata->selected = true;
+            }
+            $data->contacts[] = $contactdata;
+        }
+        $data->conversationsselected = $this->conversationsselected;
+
+        return $data;
+    }
+}
diff --git a/message/classes/output/message.php b/message/classes/output/message.php
new file mode 100644 (file)
index 0000000..257b373
--- /dev/null
@@ -0,0 +1,65 @@
+<?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 class used to prepare a message for display.
+ *
+ * @package   core_message
+ * @copyright 2016 Mark Nelson <markn@moodle.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core_message\output;
+
+use renderable;
+use templatable;
+
+/**
+ * Class to prepare a message for display.
+ *
+ * @package   core_message
+ * @copyright 2016 Mark Nelson <markn@moodle.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class message implements templatable, renderable {
+
+    /**
+     * The message.
+     */
+    protected $message;
+
+    /**
+     * Constructor.
+     *
+     * @param \stdClass $message
+     */
+    public function __construct($message) {
+        $this->message = $message;
+    }
+
+    public function export_for_template(\renderer_base $output) {
+        $message = new \stdClass();
+        $message->text = $this->message->text;
+        $message->blocktime = $this->message->blocktime;
+        $message->position = 'left';
+        if ($this->message->currentuserid == $this->message->useridfrom) {
+            $message->position = 'right';
+        }
+        $message->timesent = userdate($this->message->timecreated, get_string('strftimetime'));
+
+        return $message;
+    }
+}
diff --git a/message/classes/output/message_area_page.php b/message/classes/output/message_area_page.php
new file mode 100644 (file)
index 0000000..8dc65e3
--- /dev/null
@@ -0,0 +1,77 @@
+<?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 class used to prepare the message area for display.
+ *
+ * @package   core_message
+ * @copyright 2016 Mark Nelson <markn@moodle.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core_message\output;
+
+use renderable;
+use templatable;
+
+/**
+ * Class to prepare the message area for display.
+ *
+ * @package   core_message
+ * @copyright 2016 Mark Nelson <markn@moodle.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class message_area_page implements templatable, renderable {
+
+    /**
+     * The user id.
+     */
+    protected $userid;
+
+    /**
+     * The contacts for the users.
+     */
+    protected $contacts;
+
+    /**
+     * The messages for the user.
+     */
+    protected $messages;
+
+    /**
+     * Constructor.
+     *
+     * @param int $userid The ID of the user whose contacts and messages we are viewing
+     * @param \core_message\output\contacts $contacts
+     * @param \core_message\output\messages|null $messages
+     */
+    public function __construct($userid, $contacts, $messages) {
+        $this->userid = $userid;
+        $this->contacts = $contacts;
+        $this->messages = $messages;
+    }
+
+    public function export_for_template(\renderer_base $output) {
+        $data = new \stdClass();
+        $data->userid = $this->userid;
+        $data->contacts = $this->contacts->export_for_template($output);
+        if ($this->messages) {
+            $data->messages = $this->messages->export_for_template($output);
+        }
+
+        return $data;
+    }
+}
diff --git a/message/classes/output/messages.php b/message/classes/output/messages.php
new file mode 100644 (file)
index 0000000..1ed733b
--- /dev/null
@@ -0,0 +1,90 @@
+<?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 class used to prepare the messages for display.
+ *
+ * @package   core_message
+ * @copyright 2016 Mark Nelson <markn@moodle.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core_message\output;
+
+use renderable;
+use templatable;
+
+/**
+ * Class to prepare the messages for display.
+ *
+ * @package   core_message
+ * @copyright 2016 Mark Nelson <markn@moodle.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class messages implements templatable, renderable {
+
+    /**
+     * The messages.
+     */
+    protected $messages;
+
+    /**
+     * The current user id.
+     */
+    protected $currentuserid;
+
+    /**
+     * The other user id.
+     */
+    protected $otheruserid;
+
+    /**
+     * The other user.
+     */
+    protected $otheruser;
+
+    /**
+     * Constructor.
+     *
+     * @param int $currentuserid The current user we are wanting to view messages for
+     * @param int $otheruserid The other user we are wanting to view messages for
+     * @param \core_message\output\message[] $messages
+     */
+    public function __construct($currentuserid, $otheruserid, $messages) {
+        global $DB;
+
+        $this->currentuserid = $currentuserid;
+        $this->otheruserid = $otheruserid;
+        $this->otheruser = $DB->get_record('user', array('id' => $otheruserid));
+        $this->messages = $messages;
+    }
+
+    public function export_for_template(\renderer_base $output) {
+        global $USER;
+
+        $data = new \stdClass();
+        $data->iscurrentuser = $USER->id == $this->currentuserid;
+        $data->currentuserid = $this->currentuserid;
+        $data->otheruserid = $this->otheruserid;
+        $data->otheruserfullname = fullname($this->otheruser);
+        $data->messages = array();
+        foreach ($this->messages as $message) {
+            $data->messages[] = $message->export_for_template($output);
+        }
+
+        return $data;
+    }
+}
diff --git a/message/classes/output/renderer.php b/message/classes/output/renderer.php
new file mode 100644 (file)
index 0000000..51469c9
--- /dev/null
@@ -0,0 +1,52 @@
+<?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 class used to render the message area.
+ *
+ * @package    core_message
+ * @copyright  2016 Mark Nelson <markn@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core_message\output;
+
+defined('MOODLE_INTERNAL') || die();
+
+use plugin_renderer_base;
+
+/**
+ * Renderer class for the message area.
+ *
+ * @package    core_message
+ * @copyright  2016 Mark Nelson <markn@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class renderer extends plugin_renderer_base {
+
+    /**
+     * Renders the message area.
+     *
+     * Defer to template.
+     *
+     * @param message_area_page $page
+     * @return string html for the page
+     */
+    public function render_message_area_page(message_area_page $page) {
+        $data = $page->export_for_template($this);
+        return parent::render_from_template('core_message/message_area', $data);
+    }
+}
\ No newline at end of file
index 7777799..2a50bdb 100644 (file)
@@ -239,143 +239,26 @@ $usernode = $PAGE->navigation->find('users', null);
 $usernode->remove();
 
 $settings = $PAGE->settingsnav->find('messages', null);
-// Add the user we are contacting to the breadcrumb.
-if (!empty($user2realuser)) {
-    $usernode = $settings->add(fullname($user2), $url);
-    $usernode->make_active();
+$settings->make_active();
+
+// Get the renderer and the information we are going to be use.
+$renderer = $PAGE->get_renderer('core_message');
+if (!$user2realuser) {
+    $conversations = \core_message\api::get_conversations($user1->id);
+    $messages = null;
 } else {
-    $settings->make_active();
+    $conversations = \core_message\api::get_conversations($user1->id, $user2->id);
+    $messages = \core_message\api::get_messages($user1->id, $user2->id);
 }
+$messagearea = new \core_message\output\message_area_page($user1->id, $conversations, $messages);
 
-//now the page contents
+// Now the page contents.
 echo $OUTPUT->header();
-
-echo $OUTPUT->box_start('message');
-
-$countunread = 0; //count of unread messages from $user2
-$countunreadtotal = 0; //count of unread messages from all users
-
-//we're dealing with unread messages early so the contact list will accurately reflect what is read/unread
-$viewingnewmessages = false;
-if (!empty($user2)) {
-    //are there any unread messages from $user2
-    $countunread = message_count_unread_messages($user1, $user2);
-    if ($countunread>0) {
-        //mark the messages we're going to display as read
-        message_mark_messages_read($user1->id, $user2->id);
-         if($viewing == MESSAGE_VIEW_UNREAD_MESSAGES) {
-             $viewingnewmessages = true;
-         }
-    }
+// Display a message that the user is viewing someone else's messages.
+if (!$currentuser) {
+    $notify = new \core\output\notification(get_string('viewinganotherusersmessagearea', 'message'),
+        \core\output\notification::NOTIFY_WARNING);
+    echo $OUTPUT->render($notify);
 }
-$countunreadtotal = message_count_unread_messages($user1);
-
-if ($currentuser && $countunreadtotal == 0 && $viewing == MESSAGE_VIEW_UNREAD_MESSAGES && empty($user2)) {
-    // If the user has no unread messages, show the search box.
-    // We don't do this when a user is viewing another user's messages as search doesn't
-    // handle user A searching user B's messages properly.
-    $viewing = MESSAGE_VIEW_SEARCH;
-}
-
-$blockedusers = message_get_blocked_users($user1, $user2);
-$countblocked = count($blockedusers);
-
-list($onlinecontacts, $offlinecontacts, $strangers) = message_get_contacts($user1, $user2);
-
-message_print_contact_selector($countunreadtotal, $viewing, $user1, $user2, $blockedusers, $onlinecontacts, $offlinecontacts, $strangers, $showactionlinks, $page);
-
-echo html_writer::start_tag('div', array('class' => 'messagearea mdl-align'));
-    if (!empty($user2)) {
-
-        echo html_writer::start_tag('div', array('class' => 'mdl-left messagehistory'));
-
-            $visible = 'visible';
-            $hidden = 'hiddenelement'; //cant just use hidden as mform adds that class to its fieldset for something else
-
-            $recentlinkclass = $recentlabelclass = $historylinkclass = $historylabelclass = $visible;
-            if ($history == MESSAGE_HISTORY_ALL) {
-                $displaycount = 0;
-
-                $recentlabelclass = $historylinkclass = $hidden;
-            } else if($viewingnewmessages) {
-                //if user is viewing new messages only show them the new messages
-                $displaycount = $countunread;
-
-                $recentlabelclass = $historylabelclass = $hidden;
-            } else {
-                //default to only showing the last few messages
-                $displaycount = MESSAGE_SHORTVIEW_LIMIT;
-
-                if ($countunread>MESSAGE_SHORTVIEW_LIMIT) {
-                    $displaycount = $countunread;
-                }
-
-                $recentlinkclass = $historylabelclass = $hidden;
-            }
-
-            $messagehistorylink =  html_writer::start_tag('div', array('class' => 'mdl-align messagehistorytype'));
-                $messagehistorylink .= html_writer::link($PAGE->url->out(false).'&history='.MESSAGE_HISTORY_ALL,
-                    get_string('messagehistoryfull','message'),
-                    array('class' => $historylinkclass));
-
-                $messagehistorylink .=  html_writer::start_tag('span', array('class' => $historylabelclass));
-                    $messagehistorylink .= get_string('messagehistoryfull','message');
-                $messagehistorylink .= html_writer::end_tag('span');
-
-                $messagehistorylink .= '&nbsp;|&nbsp;'.html_writer::link($PAGE->url->out(false).'&history='.MESSAGE_HISTORY_SHORT,
-                    get_string('mostrecent','message'),
-                    array('class' => $recentlinkclass));
-
-                $messagehistorylink .=  html_writer::start_tag('span', array('class' => $recentlabelclass));
-                    $messagehistorylink .= get_string('mostrecent','message');
-                $messagehistorylink .= html_writer::end_tag('span');
-
-                if ($viewingnewmessages) {
-                    $messagehistorylink .=  '&nbsp;|&nbsp;'.html_writer::start_tag('span');//, array('class' => $historyclass)
-                        $messagehistorylink .= get_string('unreadnewmessages','message',$displaycount);
-                    $messagehistorylink .= html_writer::end_tag('span');
-                }
-
-            $messagehistorylink .= html_writer::end_tag('div');
-
-            message_print_message_history($user1, $user2, $search, $displaycount, $messagehistorylink, $viewingnewmessages, $showactionlinks);
-        echo html_writer::end_tag('div');
-
-        //send message form
-        if ($currentuser && has_capability('moodle/site:sendmessage', $systemcontext) && $user2realuser) {
-            echo html_writer::start_tag('div', array('class' => 'mdl-align messagesend'));
-                if (!empty($messageerror)) {
-                    echo html_writer::tag('span', $messageerror, array('id' => 'messagewarning'));
-                } else {
-                    // Display a warning if the current user is blocking non-contacts and is about to message to a non-contact
-                    // Otherwise they may wonder why they never get a reply
-                    if (message_is_user_non_contact_blocked($user1, $user2)) {
-                        $msg = get_string('messagingblockednoncontact', 'message', fullname($user2));
-                        echo html_writer::tag('span', $msg, array('id' => 'messagewarning'));
-                    }
-
-                    $mform = new send_form();
-                    $defaultmessage = new stdClass;
-                    $defaultmessage->id = $user2->id;
-                    $defaultmessage->viewing = $viewing;
-                    $defaultmessage->message = '';
-                    //$defaultmessage->messageformat = FORMAT_MOODLE;
-                    $mform->set_data($defaultmessage);
-                    $mform->display();
-                }
-            echo html_writer::end_tag('div');
-        }
-    } else if ($viewing == MESSAGE_VIEW_SEARCH) {
-        message_print_search($advancedsearch, $user1);
-    } else if ($viewing == MESSAGE_VIEW_RECENT_CONVERSATIONS) {
-        message_print_recent_conversations($user1, false, $showactionlinks);
-    } else if ($viewing == MESSAGE_VIEW_RECENT_NOTIFICATIONS) {
-        message_print_recent_notifications($user1);
-    }
-echo html_writer::end_tag('div');
-
-echo $OUTPUT->box_end();
-
+echo $renderer->render($messagearea);
 echo $OUTPUT->footer();
-
-
index 9f48844..2fbe914 100644 (file)
@@ -308,7 +308,7 @@ function message_count_blocked_users($user1=null) {
  * Get the users recent conversations meaning all the people they've recently
  * sent or received a message from plus the most recent message sent to or received from each other user
  *
- * @param object $user the current user
+ * @param object|int $user the current user
  * @param int $limitfrom can be used for paging
  * @param int $limitto can be used for paging
  * @return array
@@ -316,6 +316,12 @@ function message_count_blocked_users($user1=null) {
 function message_get_recent_conversations($user, $limitfrom=0, $limitto=100) {
     global $DB;
 
+    if (is_numeric($user)) {
+        $userid = $user;
+        $user = new stdClass();
+        $user->id = $userid;
+    }
+
     $userfields = user_picture::fields('otheruser', array('lastaccess'));
 
     // This query retrieves the most recent message received from or sent to
diff --git a/message/templates/contact.mustache b/message/templates/contact.mustache
new file mode 100644 (file)
index 0000000..7ac7d26
--- /dev/null
@@ -0,0 +1,11 @@
+<div class="row-fluid contact {{#selected}}selected{{/selected}}">
+    <div class="span2 picture">
+        <img height="64" src="{{profileimageurl}}" alt="" />
+    </div>
+    <div class="span10 information">
+        <div class="name">{{fullname}} {{#isonline}}*{{/isonline}}</div>
+        {{#lastmessage}}
+            <p class="lastmessage">{{.}}</p>
+        {{/lastmessage}}
+    </div>
+</div>
diff --git a/message/templates/contacts.mustache b/message/templates/contacts.mustache
new file mode 100644 (file)
index 0000000..abba679
--- /dev/null
@@ -0,0 +1,21 @@
+<div class="searcharea">
+    <form>
+        <label class="accesshide" for="filter{{uniqid}}">{{#str}}search{{/str}}</label>
+        <input type="text" id="filter{{uniqid}}" placeholder="{{#str}}search{{/str}}" value="{{search}}">
+    </form>
+</div>
+<div class="contacts">
+    {{#contacts}}
+        {{> core_message/contact }}
+    {{/contacts}}
+</div>
+<div class="row-fluid tabs">
+    <div class="span6 tab tabconversations {{#conversationsselected}}selected{{/conversationsselected}}">
+        <div>{{#pix}}t/message, moodle{{/pix}}</div>
+        <div>{{#str}}conversations, message{{/str}}</div>
+    </div>
+    <div class="span6 tab tabcontacts {{^conversationsselected}}selected{{/conversationsselected}}">
+        <div>{{#pix}}i/cohort, moodle{{/pix}}</div>
+        <div>{{#str}}contacts, message{{/str}}</div>
+    </div>
+</div>
\ No newline at end of file
diff --git a/message/templates/message.mustache b/message/templates/message.mustache
new file mode 100644 (file)
index 0000000..3908797
--- /dev/null
@@ -0,0 +1,11 @@
+{{#blocktime}}
+    <div class="blocktime">
+        {{.}}
+    </div>
+{{/blocktime}}
+<div class="message {{position}}">
+    {{{text}}}
+    <span class="timesent">
+        {{timesent}}
+    </span>
+</div>
\ No newline at end of file
diff --git a/message/templates/message_area.mustache b/message/templates/message_area.mustache
new file mode 100644 (file)
index 0000000..b266941
--- /dev/null
@@ -0,0 +1,14 @@
+<div class="messaging-area">
+    <div class="row-fluid">
+        <div class="span4 contacts-area">
+            {{#contacts}}
+                {{> core_message/contacts }}
+            {{/contacts}}
+        </div>
+        <div class="span8 messages-area">
+            {{#messages}}
+                {{> core_message/messages }}
+            {{/messages}}
+        </div>
+    </div>
+</div>
\ No newline at end of file
diff --git a/message/templates/messages.mustache b/message/templates/messages.mustache
new file mode 100644 (file)
index 0000000..dcfb28f
--- /dev/null
@@ -0,0 +1,14 @@
+<div class="messages">
+    <div class="name">
+        {{otheruserfullname}}
+    </div>
+    {{#messages}}
+        {{> core_message/message }}
+    {{/messages}}
+</div>
+{{#iscurrentuser}}
+    <div class="response">
+        <textarea id="sendmessagetxt"></textarea>
+        <input class="sendmessagebtn" type="button" value="{{#str}}send, message{{/str}}">
+    </div>
+{{/iscurrentuser}}
index 7f2ca57..1259f4a 100644 (file)
@@ -1,3 +1,118 @@
+/** The message area **/
+.messaging-area {
+    border: 1px solid black;
+
+    .setSelected() {
+        background-color: #CCF2FF;
+    }
+
+    .contacts-area {
+        border-right: 1px solid black;
+        height: 800px;
+
+        .searcharea {
+            padding: 5px;
+            text-align: center;
+        }
+
+        .contacts {
+            height: 705px;
+            overflow-y: scroll;
+
+            .contact.selected {
+                .setSelected();
+            }
+
+            .contact {
+                &:hover {
+                    .setSelected();
+                    cursor: pointer;
+                }
+
+                .information {
+                    padding-left: 8px;
+                    padding-right: 8px;
+
+                    .name {
+                        font-weight: bold;
+                    }
+
+                    .lastmessage {
+                        word-wrap: break-word;
+                    }
+                }
+            }
+        }
+
+        .tabs {
+            border-top: 1px solid black;
+
+            .tab {
+                &:hover {
+                    .setSelected();
+                    cursor: pointer;
+                }
+            }
+
+            .tab.selected {
+                .setSelected();
+            }
+
+            .tabconversations {
+                text-align: center;
+                border-right: 1px solid black;
+            }
+
+            .tabcontacts {
+                text-align: center;
+            }
+        }
+    }
+
+    .messages-area {
+
+        .messages {
+            height: 720px;
+            overflow-y: auto;
+
+            .name {
+                font-weight: bold;
+            }
+
+            .blocktime {
+                clear: both;
+                font-weight: bold;
+                text-align: center;
+            }
+
+            .left {
+                float: left;
+                width: 80%;
+            }
+
+            .right {
+                float: right;
+                padding-right: 5px;
+                margin-right: 5px;
+                max-width: 80%;
+            }
+
+            .message {
+                border: 1px solid black;
+                padding-left: 5px;
+                margin-bottom: 5px;
+                clear: both;
+                font-size: 10px;
+                word-wrap: break-word;
+            }
+        }
+
+        .response textarea {
+            width: 80%;
+        }
+    }
+}
+
 #newmessageoverlay {
     .well;
     margin: 0 1em;
index 289d54f..3a29f31 100644 (file)
@@ -5765,6 +5765,89 @@ a.ygtvspacer:hover {
   display: inline-block;
   padding-left: 5px;
 }
+/** The message area **/
+.messaging-area {
+  border: 1px solid black;
+}
+.messaging-area .contacts-area {
+  border-right: 1px solid black;
+  height: 800px;
+}
+.messaging-area .contacts-area .searcharea {
+  padding: 5px;
+  text-align: center;
+}
+.messaging-area .contacts-area .contacts {
+  height: 705px;
+  overflow-y: scroll;
+}
+.messaging-area .contacts-area .contacts .contact.selected {
+  background-color: #CCF2FF;
+}
+.messaging-area .contacts-area .contacts .contact:hover {
+  background-color: #CCF2FF;
+  cursor: pointer;
+}
+.messaging-area .contacts-area .contacts .contact .information {
+  padding-left: 8px;
+  padding-right: 8px;
+}
+.messaging-area .contacts-area .contacts .contact .information .name {
+  font-weight: bold;
+}
+.messaging-area .contacts-area .contacts .contact .information .lastmessage {
+  word-wrap: break-word;
+}
+.messaging-area .contacts-area .tabs {
+  border-top: 1px solid black;
+}
+.messaging-area .contacts-area .tabs .tab:hover {
+  background-color: #CCF2FF;
+  cursor: pointer;
+}
+.messaging-area .contacts-area .tabs .tab.selected {
+  background-color: #CCF2FF;
+}
+.messaging-area .contacts-area .tabs .tabconversations {
+  text-align: center;
+  border-right: 1px solid black;
+}
+.messaging-area .contacts-area .tabs .tabcontacts {
+  text-align: center;
+}
+.messaging-area .messages-area .messages {
+  height: 720px;
+  overflow-y: auto;
+}
+.messaging-area .messages-area .messages .name {
+  font-weight: bold;
+}
+.messaging-area .messages-area .messages .blocktime {
+  clear: both;
+  font-weight: bold;
+  text-align: center;
+}
+.messaging-area .messages-area .messages .left {
+  float: left;
+  width: 80%;
+}
+.messaging-area .messages-area .messages .right {
+  float: right;
+  padding-right: 5px;
+  margin-right: 5px;
+  max-width: 80%;
+}
+.messaging-area .messages-area .messages .message {
+  border: 1px solid black;
+  padding-left: 5px;
+  margin-bottom: 5px;
+  clear: both;
+  font-size: 10px;
+  word-wrap: break-word;
+}
+.messaging-area .messages-area .response textarea {
+  width: 80%;
+}
 #newmessageoverlay {
   min-height: 20px;
   padding: 19px;