/message/lib.php
PHP | 2540 lines | 1557 code | 389 blank | 594 comment | 359 complexity | 8574035bd86cb2b217b9ea7f19ffeedb MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-3.0, GPL-3.0, LGPL-2.1, Apache-2.0, BSD-3-Clause, AGPL-3.0
Large files files are truncated, but you can click here to view the full file
- <?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/>.
- /**
- * Library functions for messaging
- *
- * @package core_message
- * @copyright 2008 Luis Rodrigues
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
- require_once($CFG->libdir.'/eventslib.php');
- define ('MESSAGE_SHORTLENGTH', 300);
- define ('MESSAGE_DISCUSSION_WIDTH',600);
- define ('MESSAGE_DISCUSSION_HEIGHT',500);
- define ('MESSAGE_SHORTVIEW_LIMIT', 8);//the maximum number of messages to show on the short message history
- define('MESSAGE_HISTORY_SHORT',0);
- define('MESSAGE_HISTORY_ALL',1);
- define('MESSAGE_VIEW_UNREAD_MESSAGES','unread');
- define('MESSAGE_VIEW_RECENT_CONVERSATIONS','recentconversations');
- define('MESSAGE_VIEW_RECENT_NOTIFICATIONS','recentnotifications');
- define('MESSAGE_VIEW_CONTACTS','contacts');
- define('MESSAGE_VIEW_BLOCKED','blockedusers');
- define('MESSAGE_VIEW_COURSE','course_');
- define('MESSAGE_VIEW_SEARCH','search');
- define('MESSAGE_SEARCH_MAX_RESULTS', 200);
- define('MESSAGE_CONTACTS_PER_PAGE',10);
- define('MESSAGE_MAX_COURSE_NAME_LENGTH', 30);
- /**
- * Define contants for messaging default settings population. For unambiguity of
- * plugin developer intentions we use 4-bit value (LSB numbering):
- * bit 0 - whether to send message when user is loggedin (MESSAGE_DEFAULT_LOGGEDIN)
- * bit 1 - whether to send message when user is loggedoff (MESSAGE_DEFAULT_LOGGEDOFF)
- * bit 2..3 - messaging permission (MESSAGE_DISALLOWED|MESSAGE_PERMITTED|MESSAGE_FORCED)
- *
- * MESSAGE_PERMITTED_MASK contains the mask we use to distinguish permission setting
- */
- define('MESSAGE_DEFAULT_LOGGEDIN', 0x01); // 0001
- define('MESSAGE_DEFAULT_LOGGEDOFF', 0x02); // 0010
- define('MESSAGE_DISALLOWED', 0x04); // 0100
- define('MESSAGE_PERMITTED', 0x08); // 1000
- define('MESSAGE_FORCED', 0x0c); // 1100
- define('MESSAGE_PERMITTED_MASK', 0x0c); // 1100
- /**
- * Set default value for default outputs permitted setting
- */
- define('MESSAGE_DEFAULT_PERMITTED', 'permitted');
- /**
- * Print the selector that allows the user to view their contacts, course participants, their recent
- * conversations etc
- *
- * @param int $countunreadtotal how many unread messages does the user have?
- * @param int $viewing What is the user viewing? ie MESSAGE_VIEW_UNREAD_MESSAGES, MESSAGE_VIEW_SEARCH etc
- * @param object $user1 the user whose messages are being viewed
- * @param object $user2 the user $user1 is talking to
- * @param array $blockedusers an array of users blocked by $user1
- * @param array $onlinecontacts an array of $user1's online contacts
- * @param array $offlinecontacts an array of $user1's offline contacts
- * @param array $strangers an array of users who have messaged $user1 who aren't contacts
- * @param bool $showactionlinks show action links (add/remove contact etc)
- * @param int $page if there are so many users listed that they have to be split into pages what page are we viewing
- * @return void
- */
- function message_print_contact_selector($countunreadtotal, $viewing, $user1, $user2, $blockedusers, $onlinecontacts, $offlinecontacts, $strangers, $showactionlinks, $page=0) {
- global $PAGE;
- echo html_writer::start_tag('div', array('class' => 'contactselector mdl-align'));
- //if 0 unread messages and they've requested unread messages then show contacts
- if ($countunreadtotal == 0 && $viewing == MESSAGE_VIEW_UNREAD_MESSAGES) {
- $viewing = MESSAGE_VIEW_CONTACTS;
- }
- //if they have no blocked users and they've requested blocked users switch them over to contacts
- if (count($blockedusers) == 0 && $viewing == MESSAGE_VIEW_BLOCKED) {
- $viewing = MESSAGE_VIEW_CONTACTS;
- }
- $onlyactivecourses = true;
- $courses = enrol_get_users_courses($user1->id, $onlyactivecourses);
- $coursecontexts = message_get_course_contexts($courses);//we need one of these again so holding on to them
- $strunreadmessages = null;
- if ($countunreadtotal>0) { //if there are unread messages
- $strunreadmessages = get_string('unreadmessages','message', $countunreadtotal);
- }
- message_print_usergroup_selector($viewing, $courses, $coursecontexts, $countunreadtotal, count($blockedusers), $strunreadmessages, $user1);
- if ($viewing == MESSAGE_VIEW_UNREAD_MESSAGES) {
- message_print_contacts($onlinecontacts, $offlinecontacts, $strangers, $PAGE->url, 1, $showactionlinks,$strunreadmessages, $user2);
- } else if ($viewing == MESSAGE_VIEW_CONTACTS || $viewing == MESSAGE_VIEW_SEARCH || $viewing == MESSAGE_VIEW_RECENT_CONVERSATIONS || $viewing == MESSAGE_VIEW_RECENT_NOTIFICATIONS) {
- message_print_contacts($onlinecontacts, $offlinecontacts, $strangers, $PAGE->url, 0, $showactionlinks, $strunreadmessages, $user2);
- } else if ($viewing == MESSAGE_VIEW_BLOCKED) {
- message_print_blocked_users($blockedusers, $PAGE->url, $showactionlinks, null, $user2);
- } else if (substr($viewing, 0, 7) == MESSAGE_VIEW_COURSE) {
- $courseidtoshow = intval(substr($viewing, 7));
- if (!empty($courseidtoshow)
- && array_key_exists($courseidtoshow, $coursecontexts)
- && has_capability('moodle/course:viewparticipants', $coursecontexts[$courseidtoshow])) {
- message_print_participants($coursecontexts[$courseidtoshow], $courseidtoshow, $PAGE->url, $showactionlinks, null, $page, $user2);
- } else {
- //shouldn't get here. User trying to access a course they're not in perhaps.
- add_to_log(SITEID, 'message', 'view', 'index.php', $viewing);
- }
- }
- // Only show the search button if we're viewing our own messages.
- // Search isn't currently able to deal with user A wanting to search user B's messages.
- if ($showactionlinks) {
- echo html_writer::start_tag('form', array('action' => 'index.php','method' => 'GET'));
- echo html_writer::start_tag('fieldset');
- $managebuttonclass = 'visible';
- if ($viewing == MESSAGE_VIEW_SEARCH) {
- $managebuttonclass = 'hiddenelement';
- }
- $strmanagecontacts = get_string('search','message');
- echo html_writer::empty_tag('input', array('type' => 'hidden','name' => 'viewing','value' => MESSAGE_VIEW_SEARCH));
- echo html_writer::empty_tag('input', array('type' => 'submit','value' => $strmanagecontacts,'class' => $managebuttonclass));
- echo html_writer::end_tag('fieldset');
- echo html_writer::end_tag('form');
- }
- echo html_writer::end_tag('div');
- }
- /**
- * Print course participants. Called by message_print_contact_selector()
- *
- * @param object $context the course context
- * @param int $courseid the course ID
- * @param string $contactselecturl the url to send the user to when a contact's name is clicked
- * @param bool $showactionlinks show action links (add/remove contact etc) next to the users
- * @param string $titletodisplay Optionally specify a title to display above the participants
- * @param int $page if there are so many users listed that they have to be split into pages what page are we viewing
- * @param object $user2 the user $user1 is talking to. They will be highlighted if they appear in the list of participants
- * @return void
- */
- function message_print_participants($context, $courseid, $contactselecturl=null, $showactionlinks=true, $titletodisplay=null, $page=0, $user2=null) {
- global $DB, $USER, $PAGE, $OUTPUT;
- if (empty($titletodisplay)) {
- $titletodisplay = get_string('participants');
- }
- $countparticipants = count_enrolled_users($context);
- list($esql, $params) = get_enrolled_sql($context);
- $params['mcuserid'] = $USER->id;
- $ufields = user_picture::fields('u');
- $sql = "SELECT $ufields, mc.id as contactlistid, mc.blocked
- FROM {user} u
- JOIN ($esql) je ON je.id = u.id
- LEFT JOIN {message_contacts} mc ON mc.contactid = u.id AND mc.userid = :mcuserid
- WHERE u.deleted = 0";
- $participants = $DB->get_records_sql($sql, $params, $page * MESSAGE_CONTACTS_PER_PAGE, MESSAGE_CONTACTS_PER_PAGE);
- $pagingbar = new paging_bar($countparticipants, $page, MESSAGE_CONTACTS_PER_PAGE, $PAGE->url, 'page');
- echo $OUTPUT->render($pagingbar);
- echo html_writer::start_tag('table', array('id' => 'message_participants', 'class' => 'boxaligncenter', 'cellspacing' => '2', 'cellpadding' => '0', 'border' => '0'));
- echo html_writer::start_tag('tr');
- echo html_writer::tag('td', $titletodisplay, array('colspan' => 3, 'class' => 'heading'));
- echo html_writer::end_tag('tr');
- foreach ($participants as $participant) {
- if ($participant->id != $USER->id) {
- $iscontact = false;
- $isblocked = false;
- if ( $participant->contactlistid ) {
- if ($participant->blocked == 0) {
- // Is contact. Is not blocked.
- $iscontact = true;
- $isblocked = false;
- } else {
- // Is blocked.
- $iscontact = false;
- $isblocked = true;
- }
- }
- $participant->messagecount = 0;//todo it would be nice if the course participant could report new messages
- message_print_contactlist_user($participant, $iscontact, $isblocked, $contactselecturl, $showactionlinks, $user2);
- }
- }
- echo html_writer::end_tag('table');
- }
- /**
- * Retrieve users blocked by $user1
- *
- * @param object $user1 the user whose messages are being viewed
- * @param object $user2 the user $user1 is talking to. If they are being blocked
- * they will have a variable called 'isblocked' added to their user object
- * @return array the users blocked by $user1
- */
- function message_get_blocked_users($user1=null, $user2=null) {
- global $DB, $USER;
- if (empty($user1)) {
- $user1 = $USER;
- }
- if (!empty($user2)) {
- $user2->isblocked = false;
- }
- $blockedusers = array();
- $userfields = user_picture::fields('u', array('lastaccess'));
- $blockeduserssql = "SELECT $userfields, COUNT(m.id) AS messagecount
- FROM {message_contacts} mc
- JOIN {user} u ON u.id = mc.contactid
- LEFT OUTER JOIN {message} m ON m.useridfrom = mc.contactid AND m.useridto = :user1id1
- WHERE mc.userid = :user1id2 AND mc.blocked = 1
- GROUP BY $userfields
- ORDER BY u.firstname ASC";
- $rs = $DB->get_recordset_sql($blockeduserssql, array('user1id1' => $user1->id, 'user1id2' => $user1->id));
- foreach($rs as $rd) {
- $blockedusers[] = $rd;
- if (!empty($user2) && $user2->id == $rd->id) {
- $user2->isblocked = true;
- }
- }
- $rs->close();
- return $blockedusers;
- }
- /**
- * Print users blocked by $user1. Called by message_print_contact_selector()
- *
- * @param array $blockedusers the users blocked by $user1
- * @param string $contactselecturl the url to send the user to when a contact's name is clicked
- * @param bool $showactionlinks show action links (add/remove contact etc) next to the users
- * @param string $titletodisplay Optionally specify a title to display above the participants
- * @param object $user2 the user $user1 is talking to. They will be highlighted if they appear in the list of blocked users
- * @return void
- */
- function message_print_blocked_users($blockedusers, $contactselecturl=null, $showactionlinks=true, $titletodisplay=null, $user2=null) {
- global $DB, $USER;
- $countblocked = count($blockedusers);
- echo html_writer::start_tag('table', array('id' => 'message_contacts', 'class' => 'boxaligncenter'));
- if (!empty($titletodisplay)) {
- echo html_writer::start_tag('tr');
- echo html_writer::tag('td', $titletodisplay, array('colspan' => 3, 'class' => 'heading'));
- echo html_writer::end_tag('tr');
- }
- if ($countblocked) {
- echo html_writer::start_tag('tr');
- echo html_writer::tag('td', get_string('blockedusers', 'message', $countblocked), array('colspan' => 3, 'class' => 'heading'));
- echo html_writer::end_tag('tr');
- $isuserblocked = true;
- $isusercontact = false;
- foreach ($blockedusers as $blockeduser) {
- message_print_contactlist_user($blockeduser, $isusercontact, $isuserblocked, $contactselecturl, $showactionlinks, $user2);
- }
- }
- echo html_writer::end_tag('table');
- }
- /**
- * Retrieve $user1's contacts (online, offline and strangers)
- *
- * @param object $user1 the user whose messages are being viewed
- * @param object $user2 the user $user1 is talking to. If they are a contact
- * they will have a variable called 'iscontact' added to their user object
- * @return array containing 3 arrays. array($onlinecontacts, $offlinecontacts, $strangers)
- */
- function message_get_contacts($user1=null, $user2=null) {
- global $DB, $CFG, $USER;
- if (empty($user1)) {
- $user1 = $USER;
- }
- if (!empty($user2)) {
- $user2->iscontact = false;
- }
- $timetoshowusers = 300; //Seconds default
- if (isset($CFG->block_online_users_timetosee)) {
- $timetoshowusers = $CFG->block_online_users_timetosee * 60;
- }
- // time which a user is counting as being active since
- $timefrom = time()-$timetoshowusers;
- // people in our contactlist who are online
- $onlinecontacts = array();
- // people in our contactlist who are offline
- $offlinecontacts = array();
- // people who are not in our contactlist but have sent us a message
- $strangers = array();
- $userfields = user_picture::fields('u', array('lastaccess'));
- // get all in our contactlist who are not blocked in our contact list
- // and count messages we have waiting from each of them
- $contactsql = "SELECT $userfields, COUNT(m.id) AS messagecount
- FROM {message_contacts} mc
- JOIN {user} u ON u.id = mc.contactid
- LEFT OUTER JOIN {message} m ON m.useridfrom = mc.contactid AND m.useridto = ?
- WHERE mc.userid = ? AND mc.blocked = 0
- GROUP BY $userfields
- ORDER BY u.firstname ASC";
- $rs = $DB->get_recordset_sql($contactsql, array($user1->id, $user1->id));
- foreach ($rs as $rd) {
- if ($rd->lastaccess >= $timefrom) {
- // they have been active recently, so are counted online
- $onlinecontacts[] = $rd;
- } else {
- $offlinecontacts[] = $rd;
- }
- if (!empty($user2) && $user2->id == $rd->id) {
- $user2->iscontact = true;
- }
- }
- $rs->close();
- // get messages from anyone who isn't in our contact list and count the number
- // of messages we have from each of them
- $strangersql = "SELECT $userfields, count(m.id) as messagecount
- FROM {message} m
- JOIN {user} u ON u.id = m.useridfrom
- LEFT OUTER JOIN {message_contacts} mc ON mc.contactid = m.useridfrom AND mc.userid = m.useridto
- WHERE mc.id IS NULL AND m.useridto = ?
- GROUP BY $userfields
- ORDER BY u.firstname ASC";
- $rs = $DB->get_recordset_sql($strangersql, array($USER->id));
- // Add user id as array index, so supportuser and noreply user don't get duplicated (if they are real users).
- foreach ($rs as $rd) {
- $strangers[$rd->id] = $rd;
- }
- $rs->close();
- // Add noreply user and support user to the list, if they don't exist.
- $supportuser = core_user::get_support_user();
- if (!isset($strangers[$supportuser->id])) {
- $supportuser->messagecount = message_count_unread_messages($USER, $supportuser);
- if ($supportuser->messagecount > 0) {
- $strangers[$supportuser->id] = $supportuser;
- }
- }
- $noreplyuser = core_user::get_noreply_user();
- if (!isset($strangers[$noreplyuser->id])) {
- $noreplyuser->messagecount = message_count_unread_messages($USER, $noreplyuser);
- if ($noreplyuser->messagecount > 0) {
- $strangers[$noreplyuser->id] = $noreplyuser;
- }
- }
- return array($onlinecontacts, $offlinecontacts, $strangers);
- }
- /**
- * Print $user1's contacts. Called by message_print_contact_selector()
- *
- * @param array $onlinecontacts $user1's contacts which are online
- * @param array $offlinecontacts $user1's contacts which are offline
- * @param array $strangers users which are not contacts but who have messaged $user1
- * @param string $contactselecturl the url to send the user to when a contact's name is clicked
- * @param int $minmessages The minimum number of unread messages required from a user for them to be displayed
- * Typically 0 (show all contacts) or 1 (only show contacts from whom we have a new message)
- * @param bool $showactionlinks show action links (add/remove contact etc) next to the users
- * @param string $titletodisplay Optionally specify a title to display above the participants
- * @param object $user2 the user $user1 is talking to. They will be highlighted if they appear in the list of contacts
- * @return void
- */
- function message_print_contacts($onlinecontacts, $offlinecontacts, $strangers, $contactselecturl=null, $minmessages=0, $showactionlinks=true, $titletodisplay=null, $user2=null) {
- global $CFG, $PAGE, $OUTPUT;
- $countonlinecontacts = count($onlinecontacts);
- $countofflinecontacts = count($offlinecontacts);
- $countstrangers = count($strangers);
- $isuserblocked = null;
- if ($countonlinecontacts + $countofflinecontacts == 0) {
- echo html_writer::tag('div', get_string('contactlistempty', 'message'), array('class' => 'heading'));
- }
- echo html_writer::start_tag('table', array('id' => 'message_contacts', 'class' => 'boxaligncenter'));
- if (!empty($titletodisplay)) {
- message_print_heading($titletodisplay);
- }
- if($countonlinecontacts) {
- // Print out list of online contacts.
- if (empty($titletodisplay)) {
- message_print_heading(get_string('onlinecontacts', 'message', $countonlinecontacts));
- }
- $isuserblocked = false;
- $isusercontact = true;
- foreach ($onlinecontacts as $contact) {
- if ($minmessages == 0 || $contact->messagecount >= $minmessages) {
- message_print_contactlist_user($contact, $isusercontact, $isuserblocked, $contactselecturl, $showactionlinks, $user2);
- }
- }
- }
- if ($countofflinecontacts) {
- // Print out list of offline contacts.
- if (empty($titletodisplay)) {
- message_print_heading(get_string('offlinecontacts', 'message', $countofflinecontacts));
- }
- $isuserblocked = false;
- $isusercontact = true;
- foreach ($offlinecontacts as $contact) {
- if ($minmessages == 0 || $contact->messagecount >= $minmessages) {
- message_print_contactlist_user($contact, $isusercontact, $isuserblocked, $contactselecturl, $showactionlinks, $user2);
- }
- }
- }
- // Print out list of incoming contacts.
- if ($countstrangers) {
- message_print_heading(get_string('incomingcontacts', 'message', $countstrangers));
- $isuserblocked = false;
- $isusercontact = false;
- foreach ($strangers as $stranger) {
- if ($minmessages == 0 || $stranger->messagecount >= $minmessages) {
- message_print_contactlist_user($stranger, $isusercontact, $isuserblocked, $contactselecturl, $showactionlinks, $user2);
- }
- }
- }
- echo html_writer::end_tag('table');
- if ($countstrangers && ($countonlinecontacts + $countofflinecontacts == 0)) { // Extra help
- echo html_writer::tag('div','('.get_string('addsomecontactsincoming', 'message').')',array('class' => 'note'));
- }
- }
- /**
- * Print a select box allowing the user to choose to view new messages, course participants etc.
- *
- * Called by message_print_contact_selector()
- * @param int $viewing What page is the user viewing ie MESSAGE_VIEW_UNREAD_MESSAGES, MESSAGE_VIEW_RECENT_CONVERSATIONS etc
- * @param array $courses array of course objects. The courses the user is enrolled in.
- * @param array $coursecontexts array of course contexts. Keyed on course id.
- * @param int $countunreadtotal how many unread messages does the user have?
- * @param int $countblocked how many users has the current user blocked?
- * @param stdClass $user1 The user whose messages we are viewing.
- * @param string $strunreadmessages a preconstructed message about the number of unread messages the user has
- * @return void
- */
- function message_print_usergroup_selector($viewing, $courses, $coursecontexts, $countunreadtotal, $countblocked, $strunreadmessages, $user1 = null) {
- $options = array();
- if ($countunreadtotal>0) { //if there are unread messages
- $options[MESSAGE_VIEW_UNREAD_MESSAGES] = $strunreadmessages;
- }
- $str = get_string('contacts', 'message');
- $options[MESSAGE_VIEW_CONTACTS] = $str;
- $options[MESSAGE_VIEW_RECENT_CONVERSATIONS] = get_string('mostrecentconversations', 'message');
- $options[MESSAGE_VIEW_RECENT_NOTIFICATIONS] = get_string('mostrecentnotifications', 'message');
- if (!empty($courses)) {
- $courses_options = array();
- foreach($courses as $course) {
- if (has_capability('moodle/course:viewparticipants', $coursecontexts[$course->id])) {
- //Not using short_text() as we want the end of the course name. Not the beginning.
- $shortname = format_string($course->shortname, true, array('context' => $coursecontexts[$course->id]));
- if (core_text::strlen($shortname) > MESSAGE_MAX_COURSE_NAME_LENGTH) {
- $courses_options[MESSAGE_VIEW_COURSE.$course->id] = '...'.core_text::substr($shortname, -MESSAGE_MAX_COURSE_NAME_LENGTH);
- } else {
- $courses_options[MESSAGE_VIEW_COURSE.$course->id] = $shortname;
- }
- }
- }
- if (!empty($courses_options)) {
- $options[] = array(get_string('courses') => $courses_options);
- }
- }
- if ($countblocked>0) {
- $str = get_string('blockedusers','message', $countblocked);
- $options[MESSAGE_VIEW_BLOCKED] = $str;
- }
- echo html_writer::start_tag('form', array('id' => 'usergroupform','method' => 'get','action' => ''));
- echo html_writer::start_tag('fieldset');
- if ( !empty($user1) && !empty($user1->id) ) {
- echo html_writer::empty_tag('input', array('type' => 'hidden','name' => 'user1','value' => $user1->id));
- }
- echo html_writer::label(get_string('messagenavigation', 'message'), 'viewing');
- echo html_writer::select($options, 'viewing', $viewing, false, array('id' => 'viewing','onchange' => 'this.form.submit()'));
- echo html_writer::end_tag('fieldset');
- echo html_writer::end_tag('form');
- }
- /**
- * Load the course contexts for all of the users courses
- *
- * @param array $courses array of course objects. The courses the user is enrolled in.
- * @return array of course contexts
- */
- function message_get_course_contexts($courses) {
- $coursecontexts = array();
- foreach($courses as $course) {
- $coursecontexts[$course->id] = context_course::instance($course->id);
- }
- return $coursecontexts;
- }
- /**
- * strip off action parameters like 'removecontact'
- *
- * @param moodle_url/string $moodleurl a URL. Typically the current page URL.
- * @return string the URL minus parameters that perform actions (like adding/removing/blocking a contact).
- */
- function message_remove_url_params($moodleurl) {
- $newurl = new moodle_url($moodleurl);
- $newurl->remove_params('addcontact','removecontact','blockcontact','unblockcontact');
- return $newurl->out();
- }
- /**
- * Count the number of messages with a field having a specified value.
- * if $field is empty then return count of the whole array
- * if $field is non-existent then return 0
- *
- * @param array $messagearray array of message objects
- * @param string $field the field to inspect on the message objects
- * @param string $value the value to test the field against
- */
- function message_count_messages($messagearray, $field='', $value='') {
- if (!is_array($messagearray)) return 0;
- if ($field == '' or empty($messagearray)) return count($messagearray);
- $count = 0;
- foreach ($messagearray as $message) {
- $count += ($message->$field == $value) ? 1 : 0;
- }
- return $count;
- }
- /**
- * Returns the count of unread messages for user. Either from a specific user or from all users.
- *
- * @param object $user1 the first user. Defaults to $USER
- * @param object $user2 the second user. If null this function will count all of user 1's unread messages.
- * @return int the count of $user1's unread messages
- */
- function message_count_unread_messages($user1=null, $user2=null) {
- global $USER, $DB;
- if (empty($user1)) {
- $user1 = $USER;
- }
- if (!empty($user2)) {
- return $DB->count_records_select('message', "useridto = ? AND useridfrom = ?",
- array($user1->id, $user2->id), "COUNT('id')");
- } else {
- return $DB->count_records_select('message', "useridto = ?",
- array($user1->id), "COUNT('id')");
- }
- }
- /**
- * Count the number of users blocked by $user1
- *
- * @param object $user1 user object
- * @return int the number of blocked users
- */
- function message_count_blocked_users($user1=null) {
- global $USER, $DB;
- if (empty($user1)) {
- $user1 = $USER;
- }
- $sql = "SELECT count(mc.id)
- FROM {message_contacts} mc
- WHERE mc.userid = :userid AND mc.blocked = 1";
- $params = array('userid' => $user1->id);
- return $DB->count_records_sql($sql, $params);
- }
- /**
- * Print the search form and search results if a search has been performed
- *
- * @param boolean $advancedsearch show basic or advanced search form
- * @param object $user1 the current user
- * @return boolean true if a search was performed
- */
- function message_print_search($advancedsearch = false, $user1=null) {
- $frm = data_submitted();
- $doingsearch = false;
- if ($frm) {
- if (confirm_sesskey()) {
- $doingsearch = !empty($frm->combinedsubmit) || !empty($frm->keywords) || (!empty($frm->personsubmit) and !empty($frm->name));
- } else {
- $frm = false;
- }
- }
- if (!empty($frm->combinedsearch)) {
- $combinedsearchstring = $frm->combinedsearch;
- } else {
- //$combinedsearchstring = get_string('searchcombined','message').'...';
- $combinedsearchstring = '';
- }
- if ($doingsearch) {
- if ($advancedsearch) {
- $messagesearch = '';
- if (!empty($frm->keywords)) {
- $messagesearch = $frm->keywords;
- }
- $personsearch = '';
- if (!empty($frm->name)) {
- $personsearch = $frm->name;
- }
- include('search_advanced.html');
- } else {
- include('search.html');
- }
- $showicontext = false;
- message_print_search_results($frm, $showicontext, $user1);
- return true;
- } else {
- if ($advancedsearch) {
- $personsearch = $messagesearch = '';
- include('search_advanced.html');
- } else {
- include('search.html');
- }
- return false;
- }
- }
- /**
- * 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 int $limitfrom can be used for paging
- * @param int $limitto can be used for paging
- * @return array
- */
- function message_get_recent_conversations($user, $limitfrom=0, $limitto=100) {
- global $DB;
- $userfields = user_picture::fields('otheruser', array('lastaccess'));
- // This query retrieves the most recent message received from or sent to
- // seach other user.
- //
- // If two messages have the same timecreated, we take the one with the
- // larger id.
- //
- // There is a separate query for read and unread messages as they are stored
- // in different tables. They were originally retrieved in one query but it
- // was so large that it was difficult to be confident in its correctness.
- $sql = "SELECT $userfields,
- message.id as mid, message.notification, message.smallmessage, message.fullmessage,
- message.fullmessagehtml, message.fullmessageformat, message.timecreated,
- contact.id as contactlistid, contact.blocked
- FROM {message_read} message
- JOIN {user} otheruser ON otheruser.id = CASE
- WHEN message.useridto = :userid1 THEN message.useridfrom
- ELSE message.useridto END
- LEFT JOIN {message_contacts} contact ON contact.userid = :userid2 AND contact.contactid = otheruser.id
- WHERE otheruser.deleted = 0
- AND (message.useridto = :userid3 OR message.useridfrom = :userid4)
- AND message.notification = 0
- AND NOT EXISTS (
- SELECT 1
- FROM {message_read} othermessage
- WHERE ((othermessage.useridto = :userid5 AND othermessage.useridfrom = otheruser.id) OR
- (othermessage.useridfrom = :userid6 AND othermessage.useridto = otheruser.id))
- AND (othermessage.timecreated > message.timecreated OR (
- othermessage.timecreated = message.timecreated AND othermessage.id > message.id))
- )
- ORDER BY message.timecreated DESC";
- $params = array('userid1' => $user->id, 'userid2' => $user->id, 'userid3' => $user->id,
- 'userid4' => $user->id, 'userid5' => $user->id, 'userid6' => $user->id);
- $read = $DB->get_records_sql($sql, $params, $limitfrom, $limitto);
- // We want to get the messages that have not been read. These are stored in the 'message' table. It is the
- // exact same query as the one above, except for the table we are querying. So, simply replace references to
- // the 'message_read' table with the 'message' table.
- $sql = str_replace('{message_read}', '{message}', $sql);
- $unread = $DB->get_records_sql($sql, $params, $limitfrom, $limitto);
- $conversations = array();
- // Union the 2 result sets together looking for the message with the most
- // recent timecreated for each other user.
- // $conversation->id (the array key) is the other user's ID.
- $conversation_arrays = array($unread, $read);
- foreach ($conversation_arrays as $conversation_array) {
- foreach ($conversation_array as $conversation) {
- if (empty($conversations[$conversation->id]) || $conversations[$conversation->id]->timecreated < $conversation->timecreated ) {
- $conversations[$conversation->id] = $conversation;
- }
- }
- }
- // Sort the conversations by $conversation->timecreated, newest to oldest
- // There may be multiple conversations with the same timecreated
- // The conversations array contains both read and unread messages (different tables) so sorting by ID won't work
- $result = core_collator::asort_objects_by_property($conversations, 'timecreated', core_collator::SORT_NUMERIC);
- $conversations = array_reverse($conversations);
- return $conversations;
- }
- /**
- * Get the users recent event notifications
- *
- * @param object $user the current user
- * @param int $limitfrom can be used for paging
- * @param int $limitto can be used for paging
- * @return array
- */
- function message_get_recent_notifications($user, $limitfrom=0, $limitto=100) {
- global $DB;
- $userfields = user_picture::fields('u', array('lastaccess'));
- $sql = "SELECT mr.id AS message_read_id, $userfields, mr.notification, mr.smallmessage, mr.fullmessage, mr.fullmessagehtml, mr.fullmessageformat, mr.timecreated as timecreated, mr.contexturl, mr.contexturlname
- FROM {message_read} mr
- JOIN {user} u ON u.id=mr.useridfrom
- WHERE mr.useridto = :userid1 AND u.deleted = '0' AND mr.notification = :notification
- ORDER BY mr.timecreated DESC";
- $params = array('userid1' => $user->id, 'notification' => 1);
- $notifications = $DB->get_records_sql($sql, $params, $limitfrom, $limitto);
- return $notifications;
- }
- /**
- * Print the user's recent conversations
- *
- * @param stdClass $user the current user
- * @param bool $showicontext flag indicating whether or not to show text next to the action icons
- */
- function message_print_recent_conversations($user1 = null, $showicontext = false, $showactionlinks = true) {
- global $USER;
- echo html_writer::start_tag('p', array('class' => 'heading'));
- echo get_string('mostrecentconversations', 'message');
- echo html_writer::end_tag('p');
- if (empty($user1)) {
- $user1 = $USER;
- }
- $conversations = message_get_recent_conversations($user1);
- // Attach context url information to create the "View this conversation" type links
- foreach($conversations as $conversation) {
- $conversation->contexturl = new moodle_url("/message/index.php?user1={$user1->id}&user2={$conversation->id}");
- $conversation->contexturlname = get_string('thisconversation', 'message');
- }
- $showotheruser = true;
- message_print_recent_messages_table($conversations, $user1, $showotheruser, $showicontext, false, $showactionlinks);
- }
- /**
- * Print the user's recent notifications
- *
- * @param stdClass $user the current user
- */
- function message_print_recent_notifications($user=null) {
- global $USER;
- echo html_writer::start_tag('p', array('class' => 'heading'));
- echo get_string('mostrecentnotifications', 'message');
- echo html_writer::end_tag('p');
- if (empty($user)) {
- $user = $USER;
- }
- $notifications = message_get_recent_notifications($user);
- $showicontext = false;
- $showotheruser = false;
- message_print_recent_messages_table($notifications, $user, $showotheruser, $showicontext, true);
- }
- /**
- * Print a list of recent messages
- *
- * @access private
- *
- * @param array $messages the messages to display
- * @param stdClass $user the current user
- * @param bool $showotheruser display information on the other user?
- * @param bool $showicontext show text next to the action icons?
- * @param bool $forcetexttohtml Force text to go through @see text_to_html() via @see format_text()
- * @param bool $showactionlinks
- * @return void
- */
- function message_print_recent_messages_table($messages, $user = null, $showotheruser = true, $showicontext = false, $forcetexttohtml = false, $showactionlinks = true) {
- global $OUTPUT;
- static $dateformat;
- if (empty($dateformat)) {
- $dateformat = get_string('strftimedatetimeshort');
- }
- echo html_writer::start_tag('div', array('class' => 'messagerecent'));
- foreach ($messages as $message) {
- echo html_writer::start_tag('div', array('class' => 'singlemessage'));
- if ($showotheruser) {
- $strcontact = $strblock = $strhistory = null;
- if ($showactionlinks) {
- if ( $message->contactlistid ) {
- if ($message->blocked == 0) { // The other user isn't blocked.
- $strcontact = message_contact_link($message->id, 'remove', true, null, $showicontext);
- $strblock = message_contact_link($message->id, 'block', true, null, $showicontext);
- } else { // The other user is blocked.
- $strcontact = message_contact_link($message->id, 'add', true, null, $showicontext);
- $strblock = message_contact_link($message->id, 'unblock', true, null, $showicontext);
- }
- } else {
- $strcontact = message_contact_link($message->id, 'add', true, null, $showicontext);
- $strblock = message_contact_link($message->id, 'block', true, null, $showicontext);
- }
- //should we show just the icon or icon and text?
- $histicontext = 'icon';
- if ($showicontext) {
- $histicontext = 'both';
- }
- $strhistory = message_history_link($user->id, $message->id, true, '', '', $histicontext);
- }
- echo html_writer::start_tag('span', array('class' => 'otheruser'));
- echo html_writer::start_tag('span', array('class' => 'pix'));
- echo $OUTPUT->user_picture($message, array('size' => 20, 'courseid' => SITEID));
- echo html_writer::end_tag('span');
- echo html_writer::start_tag('span', array('class' => 'contact'));
- $link = new moodle_url("/message/index.php?user1={$user->id}&user2=$message->id");
- $action = null;
- echo $OUTPUT->action_link($link, fullname($message), $action, array('title' => get_string('sendmessageto', 'message', fullname($message))));
- echo html_writer::end_tag('span');//end contact
- if ($showactionlinks) {
- echo $strcontact.$strblock.$strhistory;
- }
- echo html_writer::end_tag('span');//end otheruser
- }
- $messagetext = message_format_message_text($message, $forcetexttohtml);
- echo html_writer::tag('span', userdate($message->timecreated, $dateformat), array('class' => 'messagedate'));
- echo html_writer::tag('span', $messagetext, array('class' => 'themessage'));
- echo message_format_contexturl($message);
- echo html_writer::end_tag('div');//end singlemessage
- }
- echo html_writer::end_tag('div');//end messagerecent
- }
- /**
- * Try to guess how to convert the message to html.
- *
- * @access private
- *
- * @param stdClass $message
- * @param bool $forcetexttohtml
- * @return string html fragment
- */
- function message_format_message_text($message, $forcetexttohtml = false) {
- // Note: this is a very nasty hack that tries to work around the weird messaging rules and design.
- $options = new stdClass();
- $options->para = false;
- $format = $message->fullmessageformat;
- if ($message->smallmessage !== '') {
- if ($message->notification == 1) {
- if ($message->fullmessagehtml !== '' or $message->fullmessage !== '') {
- $format = FORMAT_PLAIN;
- }
- }
- $messagetext = $message->smallmessage;
- } else if ($message->fullmessageformat == FORMAT_HTML) {
- if ($message->fullmessagehtml !== '') {
- $messagetext = $message->fullmessagehtml;
- } else {
- $messagetext = $message->fullmessage;
- $format = FORMAT_MOODLE;
- }
- } else {
- if ($message->fullmessage !== '') {
- $messagetext = $message->fullmessage;
- } else {
- $messagetext = $message->fullmessagehtml;
- $format = FORMAT_HTML;
- }
- }
- if ($forcetexttohtml) {
- // This is a crazy hack, why not set proper format when creating the notifications?
- if ($format === FORMAT_PLAIN) {
- $format = FORMAT_MOODLE;
- }
- }
- return format_text($messagetext, $format, $options);
- }
- /**
- * Add the selected user as a contact for the current user
- *
- * @param int $contactid the ID of the user to add as a contact
- * @param int $blocked 1 if you wish to block the contact
- * @return bool/int false if the $contactid isnt a valid user id. True if no changes made.
- * Otherwise returns the result of update_record() or insert_record()
- */
- function message_add_contact($contactid, $blocked=0) {
- global $USER, $DB;
- if (!$DB->record_exists('user', array('id' => $contactid))) { // invalid userid
- return false;
- }
- if (($contact = $DB->get_record('message_contacts', array('userid' => $USER->id, 'contactid' => $contactid))) !== false) {
- // A record already exists. We may be changing blocking status.
- if ($contact->blocked !== $blocked) {
- // Blocking status has been changed.
- $contact->blocked = $blocked;
- return $DB->update_record('message_contacts', $contact);
- } else {
- // No change to blocking status.
- return true;
- }
- } else {
- // New contact record.
- $contact = new stdClass();
- $contact->userid = $USER->id;
- $contact->contactid = $contactid;
- $contact->blocked = $blocked;
- return $DB->insert_record('message_contacts', $contact, false);
- }
- }
- /**
- * remove a contact
- *
- * @param int $contactid the user ID of the contact to remove
- * @return bool returns the result of delete_records()
- */
- function message_remove_contact($contactid) {
- global $USER, $DB;
- return $DB->delete_records('message_contacts', array('userid' => $USER->id, 'contactid' => $contactid));
- }
- /**
- * Unblock a contact. Note that this reverts the previously blocked user back to a non-contact.
- *
- * @param int $contactid the user ID of the contact to unblock
- * @return bool returns the result of delete_records()
- */
- function message_unblock_contact($contactid) {
- global $USER, $DB;
- return $DB->delete_records('message_contacts', array('userid' => $USER->id, 'contactid' => $contactid));
- }
- /**
- * block a user
- *
- * @param int $contactid the user ID of the user to block
- */
- function message_block_contact($contactid) {
- return message_add_contact($contactid, 1);
- }
- /**
- * Load a user's contact record
- *
- * @param int $contactid the user ID of the user whose contact record you want
- * @return array message contacts
- */
- function message_get_contact($contactid) {
- global $USER, $DB;
- return $DB->get_record('message_contacts', array('userid' => $USER->id, 'contactid' => $contactid));
- }
- /**
- * Print the results of a message search
- *
- * @param mixed $frm submitted form data
- * @param bool $showicontext show text next to action icons?
- * @param object $currentuser the current user
- * @return void
- */
- function message_print_search_results($frm, $showicontext=false, $currentuser=null) {
- global $USER, $DB, $OUTPUT;
- if (empty($currentuser)) {
- $currentuser = $USER;
- }
- echo html_writer::start_tag('div', array('class' => 'mdl-left'));
- $personsearch = false;
- $personsearchstring = null;
- if (!empty($frm->personsubmit) and !empty($frm->name)) {
- $personsearch = true;
- $personsearchstring = $frm->name;
- } else if (!empty($frm->combinedsubmit) and !empty($frm->combinedsearch)) {
- $personsearch = true;
- $personsearchstring = $frm->combinedsearch;
- }
- // Search for person.
- if ($personsearch) {
- if (optional_param('mycourses', 0, PARAM_BOOL)) {
- $users = array();
- $mycourses = enrol_get_my_courses('id');
- $mycoursesids = array();
- foreach ($mycourses as $mycourse) {
- $mycoursesids[] = $mycourse->id;
- }
- $susers = message_search_users($mycoursesids, $personsearchstring);
- foreach ($susers as $suser) {
- $users[$suser->id] = $suser;
- }
- } else {
- $users = message_search_users(SITEID, $personsearchstring);
- }
- if (!empty($users)) {
- echo html_writer::start_tag('p', array('class' => 'heading searchresultcount'));
- echo get_string('userssearchresults', 'message', count($users));
- echo html_writer::end_tag('p');
- echo html_writer::start_tag('table', array('class' => 'messagesearchresults'));
- foreach ($users as $user) {
- if ( $user->contactlistid ) {
- if ($user->blocked == 0) { // User is not blocked.
- $strcontact = message_contact_link($user->id, 'remove', true, null, $showicontext);
- $strblock = message_contact_link($user->id, 'block', true, null, $showicontext);
- } else { // blocked
- $strcontact = message_contact_link($user->id, 'add', true, null, $showicontext);
- $strblock = message_contact_link($user->id, 'unblock', true, null, $showicontext);
- }
- } else {
- $strcontact = message_contact_link($user->id, 'add', true, null, $showicontext);
- $strblock = message_contact_link($user->id, 'block', true, null, $showicontext);
- }
- // Should we show just the icon or icon and text?
- $histicontext = 'icon';
- if ($showicontext) {
- $histicontext = 'both';
- }
- $strhistory = message_history_link($USER->id, $user->id, true, '', '', $histicontext);
- echo html_writer::start_tag('tr');
- echo html_writer::start_tag('td', array('class' => 'pix'));
- echo $OUTPUT->user_picture($user, array('size' => 20, 'courseid' => SITEID));
- echo html_writer::end_tag('td');
- echo html_writer::start_tag('td',array('class' => 'contact'));
- $action = null;
- $link = new moodle_url("/message/index.php?id=$user->id");
- echo $OUTPUT->action_link($link, fullname($user), $action, array('title' => get_string('sendmessageto', 'message', fullname($user))));
- echo html_writer::end_tag('td');
- echo html_writer::tag('td', $strcontact, array('class' => 'link'));
- echo html_writer::tag('td', $strblock, array('class' => 'link'));
- echo html_writer::tag('td', $strhistory, array('class' => 'link'));
- echo html_writer::end_tag('tr');
- }
- echo html_writer::end_tag('table');
- } else {
- echo html_writer::start_tag('p', array('class' => 'heading searchresultcount'));
- echo get_string('userssearchresults', 'message', 0).'<br /><br />';
- echo html_writer::end_tag('p');
- }
- }
- // search messages for keywords
- $messagesearch = false;
- $messagesearchstring = null;
- if (!empty($frm->keywords)) {
- $messagesearch = true;
- $messagesearchstring = clean_text(trim($frm->keywords));
- } else if (!empty($frm->combinedsubmit) and !empty($frm->combinedsearch)) {
- $messagesearch = true;
- $messagesearchstring = clean_text(trim($frm->combinedsearch));
- }
- if ($messagesearch) {
- if ($messagesearchstring) {
- $keywords = explode(' ', $messagesearchstring);
- } else {
- $keywords = array();
- }
- $tome = false;
- $fromme = false;
- $courseid = 'none';
- if (empty($frm->keywordsoption)) {
- $frm->keywordsoption = 'allmine';
- }
- switch ($frm->keywordsoption) {
- case 'tome':
- $tome = true;
- break;
- case 'fromme':
- $fromme = true;
- break;
- case 'allmine':
- $tome = true;
- $fromme = true;
- break;
- case 'allusers':
- $courseid = SITEID;
- break;
- case 'courseusers':
- $courseid = $frm->courseid;
- break;
- default:
- $tome = true;
- $fromme = true;
- }
- if (($messages = message_search($keywords, $fromme, $tome, $courseid)) !== false) {
- // Get a list of contacts.
- if (($contacts = $DB->get_records('message_contacts', array('userid' => $USER->id), '', 'contactid, blocked') ) === false) {
- $contacts = array();
- }
- // Print heading with number of results.
- echo html_writer::start_tag('p', array('class' => 'heading searchresultcount'));
- $countresults = count($messages);
- if ($countresults == MESSAGE_SEARCH_MAX_RESULTS) {
- echo get_string('keywordssearchresultstoomany', 'message', $countresults).' ("'.s($messagesearchstring).'")';
- } else {
- echo get_string('keywordssearchresults', 'message', $countresults);
- }
- echo html_writer::end_tag('p');
- // Print table headings.
- echo html_writer::start_tag('table', array('class' => 'messagesearchresults', 'cellspacing' => '0'));
- $headertdstart = html_writer::start_tag('td', array('class' => 'messagesearchresultscol'));
- $headertdend = html_writer::end_tag('td');
- echo html_writer::start_tag('tr');
- echo $headertdstart.get_string('from').$headertdend;
- echo $headertdstart.get_string('to').$headertdend;
- echo $headertdstart.get_string('message', 'message').$headertdend;
- echo $headertdstart.get_string('timesent', 'message').$headertdend;
- echo html_writer::end_t…
Large files files are truncated, but you can click here to view the full file