MDL-54687 core_message: remove contact from DOM if no messages remain
[moodle.git] / message / classes / api.php
CommitLineData
879e2bef
MN
1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * Contains class used to return information to display for the message area.
19 *
20 * @package core_message
21 * @copyright 2016 Mark Nelson <markn@moodle.com>
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
25namespace core_message;
26
27require_once($CFG->dirroot . '/lib/messagelib.php');
28
29defined('MOODLE_INTERNAL') || die();
30
31/**
32 * Class used to return information to display for the message area.
33 *
34 * @copyright 2016 Mark Nelson <markn@moodle.com>
35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36 */
37class api {
38
39 /**
40 * Returns the contacts and their conversation to display in the contacts area.
41 *
42 * @param int $userid The user id
43 * @param int $otheruserid The id of the user we have selected, 0 if none have been selected
44 * @param int $limitfrom
45 * @param int $limitnum
1e5f751f 46 * @return \core_message\output\messagearea\contacts
879e2bef
MN
47 */
48 public static function get_conversations($userid, $otheruserid = 0, $limitfrom = 0, $limitnum = 0) {
49 $arrcontacts = array();
50 if ($conversations = message_get_recent_conversations($userid, $limitfrom, $limitnum)) {
51 foreach ($conversations as $conversation) {
52 $arrcontacts[] = \core_message\helper::create_contact($conversation);
53 }
54 }
55
1e5f751f 56 return new \core_message\output\messagearea\contacts($userid, $otheruserid, $arrcontacts);
879e2bef
MN
57 }
58
59 /**
60 * Returns the contacts to display in the contacts area.
61 *
62 * @param int $userid The user id
63 * @param int $limitfrom
64 * @param int $limitnum
1e5f751f 65 * @return \core_message\output\messagearea\contacts
879e2bef
MN
66 */
67 public static function get_contacts($userid, $limitfrom = 0, $limitnum = 0) {
68 global $DB;
69
70 $arrcontacts = array();
71 $sql = "SELECT u.*
72 FROM {message_contacts} mc
73 JOIN {user} u
74 ON mc.contactid = u.id
75 WHERE mc.userid = :userid
76 AND u.deleted = 0
77 ORDER BY " . $DB->sql_fullname();
78 if ($contacts = $DB->get_records_sql($sql, array('userid' => $userid), $limitfrom, $limitnum)) {
79 foreach ($contacts as $contact) {
80 $arrcontacts[] = \core_message\helper::create_contact($contact);
81 }
82 }
83
ef735275 84 return new \core_message\output\messagearea\contacts($userid, 0, $arrcontacts);
879e2bef
MN
85 }
86
87 /**
88 * Returns the messages to display in the message area.
89 *
90 * @param int $userid the current user
91 * @param int $otheruserid the other user
92 * @param int $limitfrom
93 * @param int $limitnum
8ec78c48 94 * @param string $sort
1e5f751f 95 * @return \core_message\output\messagearea\messages
879e2bef 96 */
8ec78c48 97 public static function get_messages($userid, $otheruserid, $limitfrom = 0, $limitnum = 0, $sort = 'timecreated ASC') {
879e2bef 98 $arrmessages = array();
8ec78c48 99 if ($messages = \core_message\helper::get_messages($userid, $otheruserid, 0, $limitfrom, $limitnum, $sort)) {
879e2bef
MN
100 $arrmessages = \core_message\helper::create_messages($userid, $messages);
101 }
102
1e5f751f 103 return new \core_message\output\messagearea\messages($userid, $otheruserid, $arrmessages);
879e2bef 104 }
c060cd49
MN
105
106 /**
107 * Returns the most recent message between two users.
108 *
109 * @param int $userid the current user
110 * @param int $otheruserid the other user
1e5f751f 111 * @return \core_message\output\messagearea\message|null
c060cd49
MN
112 */
113 public static function get_most_recent_message($userid, $otheruserid) {
114 // We want two messages here so we get an accurate 'blocktime' value.
dec0cd99 115 if ($messages = \core_message\helper::get_messages($userid, $otheruserid, 0, 0, 2, 'timecreated DESC')) {
c060cd49
MN
116 // Swap the order so we now have them in historical order.
117 $messages = array_reverse($messages);
118 $arrmessages = \core_message\helper::create_messages($userid, $messages);
119 return array_pop($arrmessages);
120 }
121
122 return null;
123 }
c6e97f54
MN
124
125 /**
126 * Returns the profile information for a contact for a user.
127 *
128 * @param int $userid The user id
129 * @param int $otheruserid The id of the user whose profile we want to view.
1e5f751f 130 * @return \core_message\output\messagearea\profile
c6e97f54
MN
131 */
132 public static function get_profile($userid, $otheruserid) {
133 global $CFG, $DB;
134
135 require_once($CFG->dirroot . '/user/lib.php');
136
137 if ($user = \core_user::get_user($otheruserid)) {
138 // Create the data we are going to pass to the renderable.
139 $userfields = user_get_user_details($user, null, array('city', 'country', 'email',
140 'profileimageurl', 'profileimageurlsmall'));
141 $data = new \stdClass();
142 $data->userid = $userfields['id'];
143 $data->fullname = $userfields['fullname'];
144 $data->city = isset($userfields['city']) ? $userfields['city'] : '';
145 $data->country = isset($userfields['country']) ? $userfields['country'] : '';
146 $data->email = isset($userfields['email']) ? $userfields['email'] : '';
147 $data->profileimageurl = isset($userfields['profileimageurl']) ? $userfields['profileimageurl'] : '';
148 $data->profileimageurlsmall = isset($userfields['profileimageurlsmall']) ?
149 $userfields['profileimageurlsmall'] : '';
150 // Check if the contact has been blocked.
151 $contact = $DB->get_record('message_contacts', array('userid' => $userid, 'contactid' => $otheruserid));
152 if ($contact) {
153 $data->isblocked = $contact->blocked;
154 $data->iscontact = true;
155 } else {
156 $data->isblocked = false;
157 $data->iscontact = false;
158 }
159
1e5f751f 160 return new \core_message\output\messagearea\profile($userid, $data);
c6e97f54
MN
161 }
162 }
dec0cd99
MN
163
164 /**
165 * Checks if a user can delete messages they have either received or sent.
166 *
167 * @param int $userid The user id of who we want to delete the messages for (this may be done by the admin
168 * but will still seem as if it was by the user)
169 * @return bool Returns true if a user can delete the message, false otherwise.
170 */
171 public static function can_delete_conversation($userid) {
172 global $USER;
173
174 $systemcontext = \context_system::instance();
175
176 // Let's check if the user is allowed to delete this message.
177 if (has_capability('moodle/site:deleteanymessage', $systemcontext) ||
178 ((has_capability('moodle/site:deleteownmessage', $systemcontext) &&
179 $USER->id == $userid))) {
180 return true;
181 }
182
183 return false;
184 }
185
186 /**
187 * Deletes a conversation.
188 *
189 * This function does not verify any permissions.
190 *
191 * @param int $userid The user id of who we want to delete the messages for (this may be done by the admin
192 * but will still seem as if it was by the user)
193 * @param int $otheruserid The id of the other user in the conversation
194 * @return bool
195 */
196 public static function delete_conversation($userid, $otheruserid) {
197 global $DB, $USER;
198
199 // We need to update the tables to mark all messages as deleted from and to the other user. This seems worse than it
200 // is, that's because our DB structure splits messages into two tables (great idea, huh?) which causes code like this.
201 // This won't be a particularly heavily used function (at least I hope not), so let's hope MDL-36941 gets worked on
202 // soon for the sake of any developers' sanity when dealing with the messaging system.
203 $now = time();
204 $sql = "UPDATE {message}
205 SET timeuserfromdeleted = :time
206 WHERE useridfrom = :userid
207 AND useridto = :otheruserid
208 AND notification = 0";
209 $DB->execute($sql, array('time' => $now, 'userid' => $userid, 'otheruserid' => $otheruserid));
210
211 $sql = "UPDATE {message}
212 SET timeusertodeleted = :time
213 WHERE useridto = :userid
214 AND useridfrom = :otheruserid
215 AND notification = 0";
216 $DB->execute($sql, array('time' => $now, 'userid' => $userid, 'otheruserid' => $otheruserid));
217
218 $sql = "UPDATE {message_read}
219 SET timeuserfromdeleted = :time
220 WHERE useridfrom = :userid
221 AND useridto = :otheruserid
222 AND notification = 0";
223 $DB->execute($sql, array('time' => $now, 'userid' => $userid, 'otheruserid' => $otheruserid));
224
225 $sql = "UPDATE {message_read}
226 SET timeusertodeleted = :time
227 WHERE useridto = :userid
228 AND useridfrom = :otheruserid
229 AND notification = 0";
230 $DB->execute($sql, array('time' => $now, 'userid' => $userid, 'otheruserid' => $otheruserid));
231
232 // Now we need to trigger events for these.
233 if ($messages = \core_message\helper::get_messages($userid, $otheruserid, $now)) {
234 // Loop through and trigger a deleted event.
235 foreach ($messages as $message) {
236 $messagetable = 'message';
237 if (!empty($message->timeread)) {
238 $messagetable = 'message_read';
239 }
240
241 // Trigger event for deleting the message.
242 \core\event\message_deleted::create_from_ids($message->useridfrom, $message->useridto,
243 $USER->id, $messagetable, $message->id)->trigger();
244 }
245 }
246
247 return true;
248 }
879e2bef 249}