// Check if the interface is deprecated.
if (!$manager->is_empty_subsystem($component)) {
$classname = $manager->get_provider_classname_for_component($component);
- $componentclass = new $classname();
- if ($componentclass instanceof \core_privacy\local\deprecated) {
- $internaldata['deprecated'] = true;
+ if (class_exists($classname)) {
+ $componentclass = new $classname();
+ if ($componentclass instanceof \core_privacy\local\deprecated) {
+ $internaldata['deprecated'] = true;
+ }
}
}
$data = $page->export_for_template($this);
return parent::render_from_template('tool_dataprivacy/data_deletion', $data);
}
+
+ /**
+ * Render the user data retention summary page.
+ *
+ * @param summary_page $page
+ * @return string html for the page.
+ */
+ public function render_summary_page(summary_page $page) {
+ $data = $page->export_for_template($this);
+ return parent::render_from_template('tool_dataprivacy/summary', $data);
+ }
}
--- /dev/null
+<?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/>.
+
+/**
+ * Summary page renderable.
+ *
+ * @package tool_dataprivacy
+ * @copyright 2018 Adrian Greeve
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace tool_dataprivacy\output;
+defined('MOODLE_INTERNAL') || die();
+
+use renderable;
+use renderer_base;
+use templatable;
+
+
+/**
+ * Class containing the summary page renderable.
+ *
+ * @copyright 2018 Adrian Greeve
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class summary_page implements renderable, templatable {
+
+ /**
+ * Export this data so it can be used as the context for a mustache template.
+ *
+ * @param renderer_base $output
+ * @return array
+ */
+ public function export_for_template(renderer_base $output) {
+ $contextlevels = [
+ 'contextlevelname10' => CONTEXT_SYSTEM,
+ 'contextlevelname30' => CONTEXT_USER,
+ 'contextlevelname40' => CONTEXT_COURSECAT,
+ 'contextlevelname50' => CONTEXT_COURSE,
+ 'contextlevelname70' => CONTEXT_MODULE,
+ 'contextlevelname80' => CONTEXT_BLOCK
+ ];
+
+ $data = [];
+ $context = \context_system::instance();
+
+ foreach ($contextlevels as $levelname => $level) {
+ $classname = \context_helper::get_class_for_level($level);
+ list($purposevar, $categoryvar) = \tool_dataprivacy\data_registry::var_names_from_context($classname);
+ $purposeid = get_config('tool_dataprivacy', $purposevar);
+ $categoryid = get_config('tool_dataprivacy', $categoryvar);
+
+ $section = [];
+ $section['contextname'] = get_string($levelname, 'tool_dataprivacy');
+
+ if (empty($purposeid)) {
+ list($purposeid, $categoryid) =
+ \tool_dataprivacy\data_registry::get_effective_default_contextlevel_purpose_and_category($level);
+ }
+ if ($purposeid == -1) {
+ $purposeid = 0;
+ }
+ $purpose = new \tool_dataprivacy\purpose($purposeid);
+ $export = new \tool_dataprivacy\external\purpose_exporter($purpose, ['context' => $context]);
+ $purposedata = $export->export($output);
+ $section['purpose'] = $purposedata;
+
+ if (empty($categoryid)) {
+ list($purposeid, $categoryid) =
+ \tool_dataprivacy\data_registry::get_effective_default_contextlevel_purpose_and_category($level);
+ }
+ if ($categoryid == -1) {
+ $categoryid = 0;
+ }
+ $category = new \tool_dataprivacy\category($categoryid);
+ $export = new \tool_dataprivacy\external\category_exporter($category, ['context' => $context]);
+ $categorydata = $export->export($output);
+ $section['category'] = $categorydata;
+ $data['contexts'][] = $section;
+ }
+
+ // Get activity module plugin info.
+ $pluginmanager = \core_plugin_manager::instance();
+ $modplugins = $pluginmanager->get_enabled_plugins('mod');
+
+ foreach ($modplugins as $name) {
+ $classname = \context_helper::get_class_for_level($contextlevels['contextlevelname70']);
+ list($purposevar, $categoryvar) = \tool_dataprivacy\data_registry::var_names_from_context($classname, $name);
+ $categoryid = get_config('tool_dataprivacy', $categoryvar);
+ $purposeid = get_config('tool_dataprivacy', $purposevar);
+ if ($categoryid === false && $purposeid === false) {
+ // If no purpose and category has been set for this plugin, then there's no need to show this on the list.
+ continue;
+ }
+
+ $section = [];
+ $section['contextname'] = $pluginmanager->plugin_name('mod_' . $name);
+
+ if ($purposeid == -1) {
+ $purposeid = 0;
+ }
+ $purpose = new \tool_dataprivacy\purpose($purposeid);
+ $export = new \tool_dataprivacy\external\purpose_exporter($purpose, ['context' => $context]);
+ $purposedata = $export->export($output);
+ $section['purpose'] = $purposedata;
+
+ if ($categoryid == -1) {
+ $categoryid = 0;
+ }
+ $category = new \tool_dataprivacy\category($categoryid);
+ $export = new \tool_dataprivacy\external\category_exporter($category, ['context' => $context]);
+ $categorydata = $export->export($output);
+ $section['category'] = $categorydata;
+
+ $data['contexts'][] = $section;
+ }
+
+ return $data;
+ }
+}
$string['dataprivacy:downloadallrequests'] = 'Download exported data for everyone';
$string['dataregistry'] = 'Data registry';
$string['dataregistryinfo'] = 'The data registry enables categories (types of data) and purposes (the reasons for processing data) to be set for all content on the site - from users and courses down to activities and blocks. For each purpose, a retention period may be set. When a retention period has expired, the data is flagged and listed for deletion, awaiting admin confirmation.';
+$string['dataretentionexplanation'] = 'This summary shows the default categories and purposes for retaining user\'s information on this system. Certain areas of the system may have more specific categories and purposes than those listed here.';
+$string['dataretentionsummary'] = 'Data retention summary';
$string['datarequestcreatedforuser'] = 'Data request created for {$a}';
$string['datarequestemailsubject'] = 'Data request: {$a}';
$string['datarequests'] = 'Data requests';
$string['statusrejected'] = 'Rejected';
$string['subjectscope'] = 'Subject scope';
$string['subjectscope_help'] = 'The subject scope lists the roles which may be assigned in this context.';
+$string['summary'] = 'Registry configuration summary';
$string['user'] = 'User';
$string['viewrequest'] = 'View the request';
$string['visible'] = 'Expand all';
$category->add_node($node);
}
+ $summaryurl = new moodle_url('/admin/tool/dataprivacy/summary.php');
+ $summarynode = new core_user\output\myprofile\node('privacyandpolicies', 'retentionsummary',
+ get_string('dataretentionsummary', 'tool_dataprivacy'), null, $summaryurl);
+ $category->add_node($summarynode);
+
// Add the Privacy category to the tree if it's not empty and it doesn't exist.
$nodes = $category->nodes;
if (!empty($nodes)) {
return false;
}
+/**
+ * Callback to add footer elements.
+ *
+ * @return string HTML footer content
+ */
+function tool_dataprivacy_standard_footer_html() {
+
+ $url = new moodle_url('/admin/tool/dataprivacy/summary.php');
+ $output = html_writer::link($url, get_string('dataretentionsummary', 'tool_dataprivacy'));
+ $output = html_writer::div($output, 'summaryfooter');
+
+ return $output;
+}
+
/**
* Fragment to add a new purpose.
*
--- /dev/null
+<?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/>.
+
+/**
+ * Prints the compliance data registry main page.
+ *
+ * @copyright 2018 onwards Adrian Greeve <adriangreeve.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package tool_dataprivacy
+ */
+
+require_once(__DIR__ . '/../../../config.php');
+require_once($CFG->dirroot . '/' . $CFG->admin . '/tool/dataprivacy/lib.php');
+
+$url = new moodle_url('/' . $CFG->admin . '/tool/dataprivacy/summary.php');
+$title = get_string('summary', 'tool_dataprivacy');
+
+$context = \context_system::instance();
+$PAGE->set_url($url);
+$PAGE->set_context($context);
+$PAGE->set_title($title);
+$PAGE->set_heading($SITE->fullname);
+
+$output = $PAGE->get_renderer('tool_dataprivacy');
+echo $output->header();
+$summarypage = new \tool_dataprivacy\output\summary_page();
+echo $output->render($summarypage);
+echo $output->footer();
--- /dev/null
+{{!
+ 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/>.
+}}
+{{!
+ @template tool_dataprivacy/summary
+
+ Summary
+
+ Classes required for JS:
+
+ Data attributes required for JS:
+
+ Context variables required for this template:
+
+ Example context (json):
+ {
+
+ "contexts": [
+ {
+ "contextname": "Site",
+ "category":
+ {
+ "name": "Test category",
+ "description": "<p>Description for category</p>"
+ },
+ "purpose":
+ {
+ "name": "Test purpose",
+ "description": "<p>Description for purpose</p>",
+ "lawfulbases": "gdpr_art_6_1_c",
+ "sensitivedatareasons": "gdpr_art_9_2_f",
+ "formattedlawfulbases": [
+ {
+ "name": "Lawful base 1(a)",
+ "description": "We need your information"
+ },
+ {
+ "name": "Lawful base 1(b)",
+ "description": "We really do need your information"
+ }
+ ],
+ "formattedsensitivedatareasons": [
+ {
+ "name": "Sensitive data reason number 1",
+ "description": "Number 1"
+ },
+ {
+ "name": "Sensitive data reason number 1",
+ "description": "Number 2"
+ }
+ ],
+ "formattedretentionperiod": "10 Years"
+ }
+ }
+ ]
+ }
+}}
+<h2>{{#str}}dataretentionsummary, tool_dataprivacy{{/str}}</h2>
+<p>{{#str}}dataretentionexplanation, tool_dataprivacy{{/str}}</p>
+<div>
+ {{#contexts}}
+ <div class="card mb-3">
+ <div class="card-header"><h3>{{contextname}}</h3></div>
+ <div class="card-body p-l-2 p-r-2">
+
+ {{#category.name}}
+ <h4>{{#str}}category, tool_dataprivacy{{/str}}</h4>
+ <dl>
+ <dt>{{category.name}}</dt>
+ <dd>{{{category.description}}}</dd>
+ </dl>
+ <hr />
+ {{/category.name}}
+ <h4>{{#str}}purpose, tool_dataprivacy{{/str}}</h4>
+ <dl>
+ <dt>{{purpose.name}}</dt>
+ <dd>{{{purpose.description}}}</dd>
+ <dt>{{#str}}retentionperiod, tool_dataprivacy{{/str}}</dt>
+ <dd>{{purpose.formattedretentionperiod}}</dd>
+ </dl>
+ {{#purpose.lawfulbases}}
+ <table class="table table-bordered">
+ <thead><tr><th colspan="2">{{#str}}lawfulbases, tool_dataprivacy{{/str}}</th></tr></thead>
+ <tbody>
+ {{#purpose.formattedlawfulbases}}
+ <tr>
+ <td>{{name}}</td>
+ <td>{{description}}</td>
+ </tr>
+ {{/purpose.formattedlawfulbases}}
+ </tbody>
+ </table>
+ {{/purpose.lawfulbases}}
+ {{#purpose.sensitivedatareasons}}
+ <table class="table table-bordered">
+ <thead><tr><th colspan="2">{{#str}}sensitivedatareasons, tool_dataprivacy{{/str}}</th></tr></thead>
+ <tbody>
+ {{#purpose.formattedsensitivedatareasons}}
+ <tr>
+ <td>{{name}}</td>
+ <td>{{description}}</td>
+ </tr>
+ {{/purpose.formattedsensitivedatareasons}}
+ </tbody>
+ </table>
+ {{/purpose.sensitivedatareasons}}
+ </div>
+ </div>
+ {{/contexts}}
+</div>
\ No newline at end of file
And I should see "Test feedback 3 closes" in the "Timeline" "block"
And I should not see "Test choice 2 closes" in the "Timeline" "block"
And I should not see "Test feedback 2 closes" in the "Timeline" "block"
- And I click on "[data-region='paging-bar'] [data-control='next']" "css_element" in the "Timeline" "block"
+ And I click on "[data-region='paging-bar'] [data-control='next'] [data-region='page-link']" "css_element" in the "Timeline" "block"
And I should see "Test feedback 2 closes" in the "Timeline" "block"
And I should not see "Test assign 1 is due" in the "Timeline" "block"
And I should not see "Test feedback 1 closes" in the "Timeline" "block"
$object = $element['object'];
$eid = $element['eid'];
- $object->name = format_string($this->gtree->get_element_header($element, true, true, true, true, true),
- false, array("context" => context_course::instance($COURSE->id)));
+ $object->name = $this->gtree->get_element_header($element, true, true, true, true, true);
$object->stripped_name = $this->gtree->get_element_header($element, false, false, false);
-
$is_category_item = false;
if ($element['type'] == 'categoryitem' || $element['type'] == 'courseitem') {
$is_category_item = true;
allfieldsrequired,core
previewhtml,core
messagedselecteduserfailed,core
+eventmessagecontactblocked,core_message
+eventmessagecontactunblocked,core_message
$string['allusers'] = 'All messages from all users';
$string['backupmessageshelp'] = 'If enabled, then instant messages will be included in SITE automated backups';
$string['blockcontact'] = 'Block contact';
+$string['blockedusers'] = 'Blocked users';
$string['blocknoncontacts'] = 'Prevent non-contacts from messaging me';
$string['canceledit'] = 'Cancel editing messages';
$string['contactblocked'] = 'Contact blocked';
+$string['contactrequests'] = 'Contact requests';
$string['contacts'] = 'Contacts';
$string['defaultmessageoutputs'] = 'Default message outputs';
$string['defaults'] = 'Defaults';
$string['eventnotificationviewed'] = 'Notification viewed';
$string['eventnotificationsent'] = 'Notification sent';
$string['eventmessagecontactadded'] = 'Message contact added';
-$string['eventmessagecontactblocked'] = 'Message contact blocked';
$string['eventmessagecontactremoved'] = 'Message contact removed';
-$string['eventmessagecontactunblocked'] = 'Message contact unblocked';
$string['eventmessagedeleted'] = 'Message deleted';
+$string['eventmessageuserblocked'] = 'User blocked';
+$string['eventmessageuserunblocked'] = 'User unblocked';
$string['eventmessageviewed'] = 'Message viewed';
$string['eventmessagesent'] = 'Message sent';
$string['forced'] = 'Locked';
$string['messageoutputs'] = 'Message outputs';
$string['messagepreferences'] = 'Message preferences';
$string['message'] = 'Message';
+$string['messagecontactrequestsnotification'] = '{$a} wants to be added as a contact';
+$string['messagecontactrequestsnotificationsubject'] = '{$a} wants to be added as a contact';
$string['messagepreferences'] = 'Message preferences';
$string['messages'] = 'Messages';
$string['messagingdatahasnotbeenmigrated'] = 'Your messages are temporarily unavailable due to upgrades in the messaging infrastructure. Please wait for them to be migrated.';
$string['privacy:metadata:messages:subject'] = 'The subject of the message';
$string['privacy:metadata:messages:timecreated'] = 'The time when the message was created';
$string['privacy:metadata:message_contacts'] = 'The list of contacts';
-$string['privacy:metadata:message_contacts:blocked'] = 'Flag whether or not the user is blocked';
$string['privacy:metadata:message_contacts:contactid'] = 'The ID of the user who is a contact';
+$string['privacy:metadata:message_contacts:timecreated'] = 'The time when the contact was created';
$string['privacy:metadata:message_contacts:userid'] = 'The ID of the user whose contact list we are viewing';
+$string['privacy:metadata:message_contact_requests'] = 'The list of contact requests';
+$string['privacy:metadata:message_contact_requests:requesteduserid'] = 'The ID of the user who received the contact request';
+$string['privacy:metadata:message_contact_requests:timecreated'] = 'The time when the contact request was created';
+$string['privacy:metadata:message_contact_requests:userid'] = 'The ID of the user who sent the contact request';
$string['privacy:metadata:message_conversation_members'] = 'The list of users in a conversation';
$string['privacy:metadata:message_conversation_members:conversationid'] = 'The ID of the conversation';
$string['privacy:metadata:message_conversation_members:timecreated'] = 'The time when the member was created';
$string['privacy:metadata:message_user_actions:messageid'] = 'The ID of the message this action belongs to';
$string['privacy:metadata:message_user_actions:timecreated'] = 'The time when the action was created';
$string['privacy:metadata:message_user_actions:userid'] = 'The ID of the user who performed this action';
+$string['privacy:metadata:message_users_blocked'] = 'The list of blocked users';
+$string['privacy:metadata:message_users_blocked:blockeduserid'] = 'The ID of the user who was blocked';
+$string['privacy:metadata:message_users_blocked:timecreated'] = 'The time when the blocked action was created';
+$string['privacy:metadata:message_users_blocked:userid'] = 'The ID of the user who performed the blocked action';
$string['privacy:metadata:notifications'] = 'Notifications';
$string['privacy:metadata:notifications:component'] = 'The component responsible for sending the notification';
$string['privacy:metadata:notifications:contexturl'] = 'The URL related to this notification';
$string['you'] = 'You:';
// Deprecated since Moodle 3.6.
+$string['eventmessagecontactblocked'] = 'Message contact blocked';
+$string['eventmessagecontactunblocked'] = 'Message contact unblocked';
$string['messagingdisabled'] = 'Messaging is disabled on this site, emails will be sent instead';
$string['messageprovider:courserequestrejected'] = 'Course creation request rejection notification';
$string['messageprovider:errors'] = 'Important errors with the site';
$string['messageprovider:errors_help'] = 'These are important errors that an administrator should know about.';
+$string['messageprovider:messagecontactrequests'] = 'Message contact requests notification';
$string['messageprovider:notices'] = 'Notices about minor problems';
$string['messageprovider:notices_help'] = 'These are notices that an administrator might be interested in seeing.';
$string['messageprovider:insights'] = 'Insights generated by prediction models';
$fs = get_file_storage();
if (!$fs->file_exists($user_context->id, 'badges', 'userbadge', $badge->id, '/', $hash . '.png')) {
- if ($file = $fs->get_file($badge_context->id, 'badges', 'badgeimage', $badge->id, '/', 'f1.png')) {
+ if ($file = $fs->get_file($badge_context->id, 'badges', 'badgeimage', $badge->id, '/', 'f3.png')) {
$contents = $file->get_content();
$filehandler = new PNG_MetaDataHandler($contents);
defined('MOODLE_INTERNAL') || die();
+debugging('core\\event\\message_contact_blocked has been deprecated. Please use
+ core\\event\\message_user_blocked instead', DEBUG_DEVELOPER);
+
/**
* Message contact blocked event class.
*
// Messaging contacts are not backed up, so no need to map them on restore.
return array('db' => 'message_contacts', 'restore' => base::NOT_MAPPED);
}
+
+ /**
+ * This event has been deprecated.
+ *
+ * @return boolean
+ */
+ public static function is_deprecated() {
+ return true;
+ }
}
defined('MOODLE_INTERNAL') || die();
+debugging('core\\event\\message_contact_unblocked has been deperecated. Please use
+ core\\event\\message_user_unblocked instead', DEBUG_DEVELOPER);
+
/**
* Message contact unblocked event class.
*
// Messaging contacts are not backed up, so no need to map them on restore.
return array('db' => 'message_contacts', 'restore' => base::NOT_MAPPED);
}
+
+ /**
+ * This event has been deprecated.
+ *
+ * @return boolean
+ */
+ public static function is_deprecated() {
+ return true;
+ }
}
--- /dev/null
+<?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/>.
+
+/**
+ * Message user blocked event.
+ *
+ * @package core
+ * @copyright 2018 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\event;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Message user blocked event class.
+ *
+ * @package core
+ * @since Moodle 3.6
+ * @copyright 2018 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class message_user_blocked extends base {
+
+ /**
+ * Init method.
+ */
+ protected function init() {
+ $this->data['objecttable'] = 'message_users_blocked';
+ $this->data['crud'] = 'c';
+ $this->data['edulevel'] = self::LEVEL_OTHER;
+ }
+
+ /**
+ * Returns localised general event name.
+ *
+ * @return string
+ */
+ public static function get_name() {
+ return get_string('eventmessageusersblocked', 'message');
+ }
+
+ /**
+ * Returns description of what happened.
+ *
+ * @return string
+ */
+ public function get_description() {
+ return "The user with id '$this->userid' blocked the user with id '$this->relateduserid'.";
+ }
+
+ /**
+ * Custom validation.
+ *
+ * @throws \coding_exception
+ */
+ protected function validate_data() {
+ parent::validate_data();
+
+ if (!isset($this->relateduserid)) {
+ throw new \coding_exception('The \'relateduserid\' must be set.');
+ }
+ }
+
+ public static function get_objectid_mapping() {
+ // Blocked users are not backed up, so no need to map them on restore.
+ return array('db' => 'message_users_blocked', 'restore' => base::NOT_MAPPED);
+ }
+}
--- /dev/null
+<?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/>.
+
+/**
+ * Message users unblocked event.
+ *
+ * @package core
+ * @copyright 2018 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\event;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Message users unblocked event class.
+ *
+ * @package core
+ * @since Moodle 3.6
+ * @copyright 2018 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class message_user_unblocked extends base {
+
+ /**
+ * Init method.
+ */
+ protected function init() {
+ $this->data['objecttable'] = 'message_users_blocked';
+ $this->data['crud'] = 'd';
+ $this->data['edulevel'] = self::LEVEL_OTHER;
+ }
+
+ /**
+ * Returns localised general event name.
+ *
+ * @return string
+ */
+ public static function get_name() {
+ return get_string('eventmessageusersunblocked', 'message');
+ }
+
+ /**
+ * Returns description of what happened.
+ *
+ * @return string
+ */
+ public function get_description() {
+ return "The user with id '$this->userid' unblocked the user with id '$this->relateduserid'.";
+ }
+
+ /**
+ * Custom validation.
+ *
+ * @throws \coding_exception
+ */
+ protected function validate_data() {
+ parent::validate_data();
+
+ if (!isset($this->relateduserid)) {
+ throw new \coding_exception('The \'relateduserid\' must be set.');
+ }
+ }
+
+ public static function get_objectid_mapping() {
+ // Messaging contacts are not backed up, so no need to map them on restore.
+ return array('db' => 'message_users_blocked', 'restore' => base::NOT_MAPPED);
+ }
+}
<KEY NAME="useridto" TYPE="foreign" FIELDS="useridto" REFTABLE="user" REFFIELDS="id"/>
</KEYS>
</TABLE>
- <TABLE NAME="message_contacts" COMMENT="Maintains lists of relationships between users">
+ <TABLE NAME="message_contacts" COMMENT="Maintains lists of contacts between users">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
- <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
- <FIELD NAME="contactid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
- <FIELD NAME="blocked" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
+ <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
+ <FIELD NAME="contactid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
+ <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
+ <KEY NAME="userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id"/>
+ <KEY NAME="contactid" TYPE="foreign" FIELDS="contactid" REFTABLE="user" REFFIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="userid-contactid" UNIQUE="true" FIELDS="userid, contactid"/>
</INDEXES>
</TABLE>
+ <TABLE NAME="message_contact_requests" COMMENT="Maintains list of contact requests between users">
+ <FIELDS>
+ <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
+ <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
+ <FIELD NAME="requesteduserid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
+ <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
+ </FIELDS>
+ <KEYS>
+ <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
+ <KEY NAME="userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id"/>
+ <KEY NAME="requesteduserid" TYPE="foreign" FIELDS="requesteduserid" REFTABLE="user" REFFIELDS="id"/>
+ </KEYS>
+ <INDEXES>
+ <INDEX NAME="userid-requesteduserid" UNIQUE="true" FIELDS="userid, requesteduserid"/>
+ </INDEXES>
+ </TABLE>
+ <TABLE NAME="message_users_blocked" COMMENT="Maintains lists of blocked users">
+ <FIELDS>
+ <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
+ <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
+ <FIELD NAME="blockeduserid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
+ <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
+ </FIELDS>
+ <KEYS>
+ <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
+ <KEY NAME="userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id"/>
+ <KEY NAME="blockeduserid" TYPE="foreign" FIELDS="blockeduserid" REFTABLE="user" REFFIELDS="id"/>
+ </KEYS>
+ <INDEXES>
+ <INDEX NAME="userid-blockeduserid" UNIQUE="true" FIELDS="userid, blockeduserid"/>
+ </INDEXES>
+ </TABLE>
<TABLE NAME="modules" COMMENT="modules available in the site">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
// User insights.
'insights' => array (
'capability' => 'moodle/analytics:listinsights'
- )
+ ),
+
+ // Message contact requests.
+ 'messagecontactrequests' => [
+ 'defaults' => [
+ 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF,
+ 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDOFF,
+ ]
+ ],
);
'description' => 'Updates existing groupings',
'type' => 'write',
),
+ 'core_message_block_user' => array(
+ 'classname' => 'core_message_external',
+ 'methodname' => 'block_user',
+ 'classpath' => 'message/externallib.php',
+ 'description' => 'Blocks a user',
+ 'type' => 'write',
+ 'ajax' => true,
+ 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
+ ),
'core_message_block_contacts' => array(
'classname' => 'core_message_external',
'methodname' => 'block_contacts',
'classpath' => 'message/externallib.php',
- 'description' => 'Block contacts',
+ 'description' => '** DEPRECATED ** Please do not call this function any more.
+ Block contacts',
'type' => 'write',
'ajax' => true,
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
'classname' => 'core_message_external',
'methodname' => 'create_contacts',
'classpath' => 'message/externallib.php',
- 'description' => 'Add contacts to the contact list',
+ 'description' => '** DEPRECATED ** Please do not call this function any more.
+ Add contacts to the contact list',
'type' => 'write',
'ajax' => true,
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
+ ),
+ 'core_message_get_contact_requests' => array(
+ 'classname' => 'core_message_external',
+ 'methodname' => 'get_contact_requests',
+ 'classpath' => 'message/externallib.php',
+ 'description' => 'Returns contact requests for a user',
+ 'type' => 'read',
+ 'ajax' => true,
+ 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
+ ),
+ 'core_message_create_contact_request' => array(
+ 'classname' => 'core_message_external',
+ 'methodname' => 'create_contact_request',
+ 'classpath' => 'message/externallib.php',
+ 'description' => 'Creates a contact request',
+ 'type' => 'write',
'ajax' => true,
+ 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
+ ),
+ 'core_message_confirm_contact_request' => array(
+ 'classname' => 'core_message_external',
+ 'methodname' => 'confirm_contact_request',
+ 'classpath' => 'message/externallib.php',
+ 'description' => 'Confirms a contact request',
+ 'type' => 'write',
+ 'ajax' => true,
+ 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
+ ),
+ 'core_message_decline_contact_request' => array(
+ 'classname' => 'core_message_external',
+ 'methodname' => 'decline_contact_request',
+ 'classpath' => 'message/externallib.php',
+ 'description' => 'Declines a contact request',
+ 'type' => 'write',
+ 'ajax' => true,
+ 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),
'core_message_delete_contacts' => array(
'classname' => 'core_message_external',
'type' => 'write',
'ajax' => true,
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
- 'ajax' => true,
),
'core_message_delete_conversation' => array(
'classname' => 'core_message_external',
'ajax' => true,
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),
+ 'core_message_unblock_user' => array(
+ 'classname' => 'core_message_external',
+ 'methodname' => 'unblock_user',
+ 'classpath' => 'message/externallib.php',
+ 'description' => 'Unblocks a user',
+ 'type' => 'write',
+ 'ajax' => true,
+ 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
+ ),
'core_message_unblock_contacts' => array(
'classname' => 'core_message_external',
'methodname' => 'unblock_contacts',
'classpath' => 'message/externallib.php',
- 'description' => 'Unblock contacts',
+ 'description' => '** DEPRECATED ** Please do not call this function any more.
+ Unblock contacts',
'type' => 'write',
'ajax' => true,
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
$table = new xmldb_table('message_user_actions');
// Conditionally launch add index.
- $index = new xmldb_index('userid_messageid_action', XMLDB_INDEX_UNIQUE, array('userid, messageid, action'));
+ $index = new xmldb_index('userid_messageid_action', XMLDB_INDEX_UNIQUE, array('userid', 'messageid', 'action'));
if (!$dbman->index_exists($table, $index)) {
$dbman->add_index($table, $index);
}
$table = new xmldb_table('messages');
// Conditionally launch add index.
- $index = new xmldb_index('conversationid_timecreated', XMLDB_INDEX_NOTUNIQUE, array('conversationid, timecreated'));
+ $index = new xmldb_index('conversationid_timecreated', XMLDB_INDEX_NOTUNIQUE, array('conversationid', 'timecreated'));
if (!$dbman->index_exists($table, $index)) {
$dbman->add_index($table, $index);
}
if ($oldversion < 2018040500.01) {
- // Define field indexpriority to be added to search_index_requests. Allow null initially.
+ // Define field cohort to be added to theme. Allow null initially.
$table = new xmldb_table('cohort');
$field = new xmldb_field('theme', XMLDB_TYPE_CHAR, '50',
null, null, null, null, 'timemodified');
$DB->delete_records('blog_association', ['contextid' => $module->modcontextid]);
}
}
+
// Main savepoint reached.
upgrade_main_savepoint(true, 2018083100.01);
}
if ($oldversion < 2018092100.02) {
$table = new xmldb_table('question');
- $index = new xmldb_index('categoryidnumber', XMLDB_INDEX_UNIQUE, array('category, idnumber'));
+ $index = new xmldb_index('categoryidnumber', XMLDB_INDEX_UNIQUE, array('category', 'idnumber'));
if (!$dbman->index_exists($table, $index)) {
$dbman->add_index($table, $index);
}
if ($oldversion < 2018092100.04) {
$table = new xmldb_table('question_categories');
- $index = new xmldb_index('contextididnumber', XMLDB_INDEX_UNIQUE, array('contextid, idnumber'));
+ $index = new xmldb_index('contextididnumber', XMLDB_INDEX_UNIQUE, array('contextid', 'idnumber'));
if (!$dbman->index_exists($table, $index)) {
$dbman->add_index($table, $index);
}
upgrade_main_savepoint(true, 2018092100.04);
}
+ if ($oldversion < 2018092800.00) {
+ // Alter the table 'message_contacts'.
+ $table = new xmldb_table('message_contacts');
+
+ // Remove index so we can alter the fields.
+ $index = new xmldb_index('userid-contactid', XMLDB_INDEX_UNIQUE, ['userid', 'contactid']);
+ if ($dbman->index_exists($table, $index)) {
+ $dbman->drop_index($table, $index);
+ }
+
+ // Remove defaults of '0' from the 'userid' and 'contactid' fields.
+ $field = new xmldb_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id');
+ $dbman->change_field_default($table, $field);
+
+ $field = new xmldb_field('contactid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'userid');
+ $dbman->change_field_default($table, $field);
+
+ // Add the missing FKs that will now be added to new installs.
+ $key = new xmldb_key('userid', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']);
+ $dbman->add_key($table, $key);
+
+ $key = new xmldb_key('contactid', XMLDB_KEY_FOREIGN, ['contactid'], 'user', ['id']);
+ $dbman->add_key($table, $key);
+
+ // Re-add the index.
+ if (!$dbman->index_exists($table, $index)) {
+ $dbman->add_index($table, $index);
+ }
+
+ // Add the field 'timecreated'. Allow null, since existing records won't have an accurate value we can use.
+ $field = new xmldb_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'blocked');
+ if (!$dbman->field_exists($table, $field)) {
+ $dbman->add_field($table, $field);
+ }
+
+ // Create new 'message_contact_requests' table.
+ $table = new xmldb_table('message_contact_requests');
+ $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
+ $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id');
+ $table->add_field('requesteduserid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'userid');
+ $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'requesteduserid');
+
+ $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id'], null, null);
+ $table->add_key('userid', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']);
+ $table->add_key('requesteduserid', XMLDB_KEY_FOREIGN, ['requesteduserid'], 'user', ['id']);
+
+ $table->add_index('userid-requesteduserid', XMLDB_INDEX_UNIQUE, ['userid', 'requesteduserid']);
+
+ if (!$dbman->table_exists($table)) {
+ $dbman->create_table($table);
+ }
+
+ // Create new 'message_users_blocked' table.
+ $table = new xmldb_table('message_users_blocked');
+ $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
+ $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id');
+ $table->add_field('blockeduserid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'userid');
+ // Allow NULLs in the 'timecreated' field because we will be moving existing data here that has no timestamp.
+ $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'blockeduserid');
+
+ $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id'], null, null);
+ $table->add_key('userid', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']);
+ $table->add_key('blockeduserid', XMLDB_KEY_FOREIGN, ['blockeduserid'], 'user', ['id']);
+
+ $table->add_index('userid-blockeduserid', XMLDB_INDEX_UNIQUE, ['userid', 'blockeduserid']);
+
+ if (!$dbman->table_exists($table)) {
+ $dbman->create_table($table);
+ }
+
+ upgrade_main_savepoint(true, 2018092800.00);
+ }
+
+ if ($oldversion < 2018092800.01) {
+ // Move all the 'blocked' contacts to the new table 'message_users_blocked'.
+ $updatesql = "INSERT INTO {message_users_blocked} (userid, blockeduserid, timecreated)
+ SELECT userid, contactid, null as timecreated
+ FROM {message_contacts}
+ WHERE blocked = :blocked";
+ $DB->execute($updatesql, ['blocked' => 1]);
+
+ // Removed the 'blocked' column from 'message_contacts'.
+ $table = new xmldb_table('message_contacts');
+ $field = new xmldb_field('blocked');
+ $dbman->drop_field($table, $field);
+
+ upgrade_main_savepoint(true, 2018092800.01);
+ }
+
+ if ($oldversion < 2018092800.02) {
+ // Delete any contacts that are not mutual (meaning they both haven't added each other).
+ $sql = "SELECT c1.id
+ FROM {message_contacts} c1
+ LEFT JOIN {message_contacts} c2
+ ON c1.userid = c2.contactid
+ AND c1.contactid = c2.userid
+ WHERE c2.id IS NULL";
+ if ($contacts = $DB->get_records_sql($sql)) {
+ list($insql, $inparams) = $DB->get_in_or_equal(array_keys($contacts));
+ $DB->delete_records_select('message_contacts', "id $insql", $inparams);
+ }
+
+ upgrade_main_savepoint(true, 2018092800.02);
+ }
+
+ if ($oldversion < 2018092800.03) {
+ // Remove any duplicate rows - from now on adding contacts just requires 1 row.
+ // The person who made the contact request (userid) and the person who approved
+ // it (contactid). Upgrade the table so that the first person to add the contact
+ // was the one who made the request.
+ $sql = "SELECT c1.id
+ FROM {message_contacts} c1
+ INNER JOIN {message_contacts} c2
+ ON c1.userid = c2.contactid
+ AND c1.contactid = c2.userid
+ WHERE c1.id > c2.id";
+ if ($contacts = $DB->get_records_sql($sql)) {
+ list($insql, $inparams) = $DB->get_in_or_equal(array_keys($contacts));
+ $DB->delete_records_select('message_contacts', "id $insql", $inparams);
+ }
+
+ upgrade_main_savepoint(true, 2018092800.03);
+ }
+
return true;
}
return get_roles_used_in_context($context, false);
}
+
+/**
+ * Add the selected user as a contact for the current user
+ *
+ * @deprecated since Moodle 3.6
+ * @param int $contactid the ID of the user to add as a contact
+ * @param int $blocked 1 if you wish to block the contact
+ * @param int $userid the user ID of the user we want to add the contact for, defaults to current user if not specified.
+ * @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, $userid = 0) {
+ debugging('message_add_contact() is deprecated. Please use \core_message\api::create_contact_request() instead. ' .
+ 'If you wish to block or unblock a user please use \core_message\api::is_blocked() and ' .
+ '\core_message\api::block_user() or \core_message\api::unblock_user() respectively.', DEBUG_DEVELOPER);
+
+ global $USER, $DB;
+
+ if (!$DB->record_exists('user', array('id' => $contactid))) {
+ return false;
+ }
+
+ if (empty($userid)) {
+ $userid = $USER->id;
+ }
+
+ // Check if a record already exists as we may be changing blocking status.
+ if (\core_message\api::is_contact($userid, $contactid)) {
+ $isblocked = \core_message\api::is_blocked($userid, $contactid);
+ // Check if blocking status has been changed.
+ if ($isblocked != $blocked) {
+ if ($blocked == 1) {
+ if (!$isblocked) {
+ \core_message\api::block_user($userid, $contactid);
+ }
+ } else {
+ \core_message\api::unblock_user($userid, $contactid);
+ }
+
+ return true;
+ } else {
+ // No change to blocking status.
+ return true;
+ }
+ } else {
+ if ($blocked == 1) {
+ if (!\core_message\api::is_blocked($userid, $contactid)) {
+ \core_message\api::block_user($userid, $contactid);
+ }
+ } else {
+ \core_message\api::unblock_user($userid, $contactid);
+ if (!\core_message\api::does_contact_request_exist($userid, $contactid)) {
+ \core_message\api::create_contact_request($userid, $contactid);
+ }
+ }
+
+ return true;
+ }
+}
+
+/**
+ * Remove a contact.
+ *
+ * @deprecated since Moodle 3.6
+ * @param int $contactid the user ID of the contact to remove
+ * @param int $userid the user ID of the user we want to remove the contacts for, defaults to current user if not specified.
+ * @return bool returns the result of delete_records()
+ */
+function message_remove_contact($contactid, $userid = 0) {
+ debugging('message_remove_contact() is deprecated. Please use \core_message\api::remove_contact() instead.',
+ DEBUG_DEVELOPER);
+
+ global $USER;
+
+ if (empty($userid)) {
+ $userid = $USER->id;
+ }
+
+ \core_message\api::remove_contact($userid, $contactid);
+
+ return true;
+}
+
+/**
+ * Unblock a contact.
+ *
+ * @deprecated since Moodle 3.6
+ * @param int $contactid the user ID of the contact to unblock
+ * @param int $userid the user ID of the user we want to unblock the contact for, defaults to current user
+ * if not specified.
+ * @return bool returns the result of delete_records()
+ */
+function message_unblock_contact($contactid, $userid = 0) {
+ debugging('message_unblock_contact() is deprecated. Please use \core_message\api::unblock_user() instead.',
+ DEBUG_DEVELOPER);
+
+ global $DB, $USER;
+
+ if (!$DB->record_exists('user', array('id' => $contactid))) {
+ return false;
+ }
+
+ if (empty($userid)) {
+ $userid = $USER->id;
+ }
+
+ \core_message\api::unblock_user($userid, $contactid);
+
+ return true;
+}
+
+/**
+ * Block a user.
+ *
+ * @deprecated since Moodle 3.6
+ * @param int $contactid the user ID of the user to block
+ * @param int $userid the user ID of the user we want to unblock the contact for, defaults to current user
+ * if not specified.
+ * @return bool
+ */
+function message_block_contact($contactid, $userid = 0) {
+ debugging('message_block_contact() is deprecated. Please use \core_message\api::is_blocked() and ' .
+ '\core_message\api::block_user() instead.', DEBUG_DEVELOPER);
+
+ global $DB, $USER;
+
+ if (!$DB->record_exists('user', array('id' => $contactid))) {
+ return false;
+ }
+
+ if (empty($userid)) {
+ $userid = $USER->id;
+ }
+
+ if (!\core_message\api::is_blocked($userid, $contactid)) {
+ \core_message\api::block_user($userid, $contactid);
+ }
+
+ return true;
+}
+
+/**
+ * Load a user's contact record
+ *
+ * @deprecated since Moodle 3.6
+ * @param int $contactid the user ID of the user whose contact record you want
+ * @return array message contacts
+ */
+function message_get_contact($contactid) {
+ debugging('message_get_contact() is deprecated. Please use \core_message\api::get_contact() instead.',
+ DEBUG_DEVELOPER);
+
+ global $USER;
+
+ return \core_message\api::get_contact($USER->id, $contactid);
+}
// Check to see if we should be displaying a message button.
if (!empty($CFG->messaging) && $USER->id != $user->id && has_capability('moodle/site:sendmessage', $context)) {
- $iscontact = !empty(message_get_contact($user->id));
+ $iscontact = \core_message\api::is_contact($USER->id, $user->id);
$contacttitle = $iscontact ? 'removefromyourcontacts' : 'addtoyourcontacts';
$contacturlaction = $iscontact ? 'removecontact' : 'addcontact';
$contactimage = $iscontact ? 'removecontact' : 'addcontact';
the groupid field.
* Added $CFG->conversionattemptlimit setting to config.php allowing a maximum number of retries before giving up conversion
of a given document by the assignfeedback_editpdf\task\convert_submissions task. Default value: 3.
+* The following events have been deprecated and should not be used any more:
+ - message_contact_blocked
+ - message_contact_unblocked
+ The reason for this is because you can now block/unblock users without them necessarily being a contact. These events
+ have been replaced with message_user_blocked and message_user_unblocked respectively.
=== 3.5 ===
* @private
*/
Profile.prototype._blockContact = function() {
- var action = this._performAction('core_message_block_contacts', 'unblockcontact', 'profile-block-contact',
+ var action = this._performAction('core_message_block_user', 'unblockcontact', 'profile-block-contact',
'profile-unblock-contact', '');
return action.then(function() {
this.messageArea.trigger(Events.CONTACTBLOCKED, this._getUserId());
* @private
*/
Profile.prototype._unblockContact = function() {
- var action = this._performAction('core_message_unblock_contacts', 'blockcontact', 'profile-unblock-contact',
+ var action = this._performAction('core_message_unblock_user', 'blockcontact', 'profile-unblock-contact',
'profile-block-contact', 'danger');
return action.then(function() {
this.messageArea.trigger(Events.CONTACTUNBLOCKED, this._getUserId());
* @private
*/
Profile.prototype._addContact = function() {
- var action = this._performAction('core_message_create_contacts', 'removecontact', 'profile-add-contact',
+ var action = this._performAction('core_message_create_contact_request', 'removecontact', 'profile-add-contact',
'profile-remove-contact', 'danger');
return action.then(function() {
this.messageArea.trigger(Events.CONTACTADDED, this._getUserId());
* @private
*/
Profile.prototype._performAction = function(service, string, oldaction, newaction, newclass) {
+ // This is a temporary hack as we are getting rid of this UI.
+ var userargs = '';
+ switch (service) {
+ case 'core_message_block_user':
+ userargs = {
+ userid: this.messageArea.getCurrentUserId(),
+ blockeduserid: this._getUserId()
+ };
+ break;
+ case 'core_message_unblock_user':
+ userargs = {
+ userid: this.messageArea.getCurrentUserId(),
+ unblockeduserid: this._getUserId()
+ };
+ break;
+ case 'core_message_create_contact_request':
+ userargs = {
+ userid: this.messageArea.getCurrentUserId(),
+ requesteduserid: this._getUserId()
+ };
+ break;
+ default:
+ userargs = {
+ userid: this.messageArea.getCurrentUserId(),
+ userids: [
+ this._getUserId()
+ ]
+ };
+ }
+
+
var promises = Ajax.call([{
methodname: service,
- args: {
- userid: this.messageArea.getCurrentUserId(),
- userids: [
- this._getUserId()
- ]
- }
+ args: userargs
}]);
return promises[0].then(function() {
$ufields2 = \user_picture::fields('u2', array('lastaccess'), 'userto_id', 'userto_');
$sql = "SELECT m.id, m.useridfrom, mcm.userid as useridto, m.subject, m.fullmessage, m.fullmessagehtml, m.fullmessageformat,
- m.smallmessage, m.timecreated, 0 as isread, $ufields, mcont.blocked as userfrom_blocked, $ufields2,
- mcont2.blocked as userto_blocked
+ m.smallmessage, m.timecreated, 0 as isread, $ufields, mub.id as userfrom_blocked, $ufields2,
+ mub2.id as userto_blocked
FROM {messages} m
INNER JOIN {user} u
ON u.id = m.useridfrom
ON mcm.conversationid = m.conversationid
INNER JOIN {user} u2
ON u2.id = mcm.userid
- LEFT JOIN {message_contacts} mcont
- ON (mcont.contactid = u.id AND mcont.userid = ?)
- LEFT JOIN {message_contacts} mcont2
- ON (mcont2.contactid = u2.id AND mcont2.userid = ?)
+ LEFT JOIN {message_users_blocked} mub
+ ON (mub.blockeduserid = u.id AND mub.userid = ?)
+ LEFT JOIN {message_users_blocked} mub2
+ ON (mub2.blockeduserid = u2.id AND mub2.userid = ?)
LEFT JOIN {message_user_actions} mua
ON (mua.messageid = m.id AND mua.userid = ? AND mua.action = ?)
WHERE (m.useridfrom = ? OR mcm.userid = ?)
$message->isread = true;
}
$blockedcol = $prefix . 'blocked';
- $message->blocked = $message->$blockedcol;
+ $message->blocked = $message->$blockedcol ? 1 : 0;
$message->messageid = $message->id;
$conversations[] = helper::create_contact($message, $prefix);
// Get all the users in the course.
list($esql, $params) = get_enrolled_sql(\context_course::instance($courseid), '', 0, true);
- $sql = "SELECT u.*, mc.blocked
+ $sql = "SELECT u.*, mub.id as isblocked
FROM {user} u
JOIN ($esql) je
ON je.id = u.id
- LEFT JOIN {message_contacts} mc
- ON (mc.contactid = u.id AND mc.userid = :userid)
+ LEFT JOIN {message_users_blocked} mub
+ ON (mub.blockeduserid = u.id AND mub.userid = :userid)
WHERE u.deleted = 0";
// Add more conditions.
$fullname = $DB->sql_fullname();
$contacts = array();
if ($users = $DB->get_records_sql($sql, $params, $limitfrom, $limitnum)) {
foreach ($users as $user) {
+ $user->blocked = $user->isblocked ? 1 : 0;
$contacts[] = helper::create_contact($user);
}
}
// Ok, let's search for contacts first.
$contacts = array();
- $sql = "SELECT $ufields, mc.blocked
+ $sql = "SELECT $ufields, mub.id as isuserblocked
FROM {user} u
JOIN {message_contacts} mc
ON u.id = mc.contactid
+ LEFT JOIN {message_users_blocked} mub
+ ON (mub.userid = :userid2 AND mub.blockeduserid = u.id)
WHERE mc.userid = :userid
AND u.deleted = 0
AND u.confirmed = 1
AND " . $DB->sql_like($fullname, ':search', false) . "
AND u.id $exclude
ORDER BY " . $DB->sql_fullname();
- if ($users = $DB->get_records_sql($sql, array('userid' => $userid, 'search' => '%' . $search . '%') + $excludeparams,
- 0, $limitnum)) {
+ if ($users = $DB->get_records_sql($sql, array('userid' => $userid, 'userid2' => $userid,
+ 'search' => '%' . $search . '%') + $excludeparams, 0, $limitnum)) {
foreach ($users as $user) {
+ $user->blocked = $user->isuserblocked ? 1 : 0;
$contacts[] = helper::create_contact($user);
}
}
WHERE userid = :userid)
ORDER BY " . $DB->sql_fullname();
if ($users = $DB->get_records_sql($sql, array('userid' => $userid, 'search' => '%' . $search . '%') + $excludeparams,
- 0, $limitnum)) {
+ 0, $limitnum)) {
foreach ($users as $user) {
$noncontacts[] = helper::create_contact($user);
}
return [];
}
- $contactssql = "SELECT contactid, blocked
+ $contactssql = "SELECT contactid
FROM {message_contacts}
WHERE userid = ?
AND contactid $useridsql";
public static function get_contacts($userid, $limitfrom = 0, $limitnum = 0) {
global $DB;
- $arrcontacts = array();
- $sql = "SELECT u.*, mc.blocked
+ $contactids = [];
+ $sql = "SELECT mc.*
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)) {
+ WHERE mc.userid = ? OR mc.contactid = ?
+ ORDER BY timecreated DESC";
+ if ($contacts = $DB->get_records_sql($sql, [$userid, $userid], $limitfrom, $limitnum)) {
foreach ($contacts as $contact) {
- $arrcontacts[] = helper::create_contact($contact);
+ if ($userid == $contact->userid) {
+ $contactids[] = $contact->contactid;
+ } else {
+ $contactids[] = $contact->userid;
+ }
+ }
+ }
+
+ if (!empty($contactids)) {
+ list($insql, $inparams) = $DB->get_in_or_equal($contactids);
+
+ $sql = "SELECT u.*, mub.id as isblocked
+ FROM {user} u
+ LEFT JOIN {message_users_blocked} mub
+ ON u.id = mub.blockeduserid
+ WHERE u.id $insql";
+ if ($contacts = $DB->get_records_sql($sql, $inparams)) {
+ $arrcontacts = [];
+ foreach ($contacts as $contact) {
+ $contact->blocked = $contact->isblocked ? 1 : 0;
+ $arrcontacts[] = helper::create_contact($contact);
+ }
+
+ return $arrcontacts;
}
}
- return $arrcontacts;
+ return [];
}
/**
$unreadcountssql = "SELECT $userfields, count(m.id) as messagecount
FROM {message_contacts} mc
INNER JOIN {user} u
- ON u.id = mc.contactid
+ ON (u.id = mc.contactid OR u.id = mc.userid)
LEFT JOIN {messages} m
- ON m.useridfrom = mc.contactid
+ ON ((m.useridfrom = mc.contactid OR m.useridfrom = mc.userid) AND m.useridfrom != ?)
LEFT JOIN {message_conversation_members} mcm
ON mcm.conversationid = m.conversationid AND mcm.userid = ? AND mcm.userid != m.useridfrom
LEFT JOIN {message_user_actions} mua
ON (mua.messageid = m.id AND mua.userid = ? AND mua.action = ?)
+ LEFT JOIN {message_users_blocked} mub
+ ON (mub.userid = ? AND mub.blockeduserid = u.id)
WHERE mua.id is NULL
- AND mc.userid = ?
- AND mc.blocked = 0
+ AND mub.id is NULL
+ AND (mc.userid = ? OR mc.contactid = ?)
+ AND u.id != ?
AND u.deleted = 0
GROUP BY $userfields";
- return $DB->get_records_sql($unreadcountssql, [$userid, $userid, self::MESSAGE_ACTION_READ,
- $userid, $userid], $limitfrom, $limitnum);
+ return $DB->get_records_sql($unreadcountssql, [$userid, $userid, $userid, self::MESSAGE_ACTION_READ,
+ $userid, $userid, $userid, $userid], $limitfrom, $limitnum);
}
/**
ON (mua.messageid = m.id AND mua.userid = ? AND mua.action = ?)
LEFT JOIN {message_contacts} mc
ON (mc.userid = ? AND mc.contactid = u.id)
+ LEFT JOIN {message_users_blocked} mub
+ ON (mub.userid = ? AND mub.blockeduserid = u.id)
WHERE mcm.userid = ?
AND mcm.userid != m.useridfrom
AND mua.id is NULL
+ AND mub.id is NULL
AND mc.id is NULL
AND u.deleted = 0
GROUP BY $userfields";
- return $DB->get_records_sql($unreadcountssql, [$userid, self::MESSAGE_ACTION_READ, $userid, $userid],
+ return $DB->get_records_sql($unreadcountssql, [$userid, self::MESSAGE_ACTION_READ, $userid, $userid, $userid],
$limitfrom, $limitnum);
}
* @return \stdClass
*/
public static function get_profile($userid, $otheruserid) {
- global $CFG, $DB, $PAGE;
+ global $CFG, $PAGE;
require_once($CFG->dirroot . '/user/lib.php');
}
}
- // Check if the contact has been blocked.
- $contact = $DB->get_record('message_contacts', array('userid' => $userid, 'contactid' => $otheruserid));
- if ($contact) {
- $data->isblocked = (bool) $contact->blocked;
- $data->iscontact = true;
- } else {
- $data->isblocked = false;
- $data->iscontact = false;
- }
+ $data->isblocked = self::is_blocked($userid, $otheruserid);
+ $data->iscontact = self::is_contact($userid, $otheruserid);
return $data;
}
$user = $USER;
}
- $sql = "SELECT count(mc.id)
- FROM {message_contacts} mc
- WHERE mc.userid = :userid AND mc.blocked = 1";
+ $sql = "SELECT count(mub.id)
+ FROM {message_users_blocked} mub
+ WHERE mub.userid = :userid";
return $DB->count_records_sql($sql, array('userid' => $user->id));
}
if ($sender !== null && isset($sender->id)) {
$senderid = $sender->id;
}
+
+ $systemcontext = \context_system::instance();
+ if (has_capability('moodle/site:readallmessages', $systemcontext, $senderid)) {
+ return true;
+ }
+
// The recipient has specifically blocked this sender.
- if (self::is_user_blocked($recipient->id, $senderid)) {
+ if (self::is_blocked($recipient->id, $senderid)) {
return false;
}
* @return bool true if $sender is blocked, false otherwise.
*/
public static function is_user_non_contact_blocked($recipient, $sender = null) {
- global $USER, $DB;
+ global $USER;
if (is_null($sender)) {
// The message is from the logged in user, unless otherwise specified.
$blockednoncontacts = get_user_preferences('message_blocknoncontacts', '', $recipient->id);
if (!empty($blockednoncontacts)) {
// Confirm the sender is a contact of the recipient.
- $exists = $DB->record_exists('message_contacts', array('userid' => $recipient->id, 'contactid' => $sender->id));
- if ($exists) {
+ if (self::is_contact($sender->id, $recipient->id)) {
// All good, the recipient is a contact of the sender.
return false;
} else {
* Note: This function will always return false if the sender has the
* readallmessages capability at the system context level.
*
+ * @deprecated since 3.6
* @param int $recipientid User ID of the recipient.
* @param int $senderid User ID of the sender.
* @return bool true if $sender is blocked, false otherwise.
*/
public static function is_user_blocked($recipientid, $senderid = null) {
- global $USER, $DB;
+ debugging('\core_message\api::is_user_blocked is deprecated and should not be used.',
+ DEBUG_DEVELOPER);
+
+ global $USER;
if (is_null($senderid)) {
// The message is from the logged in user, unless otherwise specified.
return false;
}
- if ($DB->get_field('message_contacts', 'blocked', ['userid' => $recipientid, 'contactid' => $senderid])) {
+ if (self::is_blocked($recipientid, $senderid)) {
return true;
}
$userfields = \user_picture::fields('u', array('lastaccess'));
$blockeduserssql = "SELECT $userfields
- FROM {message_contacts} mc
+ FROM {message_users_blocked} mub
INNER JOIN {user} u
- ON u.id = mc.contactid
+ ON u.id = mub.blockeduserid
WHERE u.deleted = 0
- AND mc.userid = ?
- AND mc.blocked = 1
+ AND mub.userid = ?
GROUP BY $userfields
ORDER BY u.firstname ASC";
return $DB->get_records_sql($blockeduserssql, [$userid]);
return $conversation->id;
}
+
+ /**
+ * Checks if a user can create a contact request.
+ *
+ * @param int $userid The id of the user who is creating the contact request
+ * @param int $requesteduserid The id of the user being requested
+ * @return bool
+ */
+ public static function can_create_contact(int $userid, int $requesteduserid) : bool {
+ global $CFG;
+
+ // If we can't message at all, then we can't create a contact.
+ if (empty($CFG->messaging)) {
+ return false;
+ }
+
+ // If we can message anyone on the site then we can create a contact.
+ if ($CFG->messagingallusers) {
+ return true;
+ }
+
+ // We need to check if they are in the same course.
+ return enrol_sharing_course($userid, $requesteduserid);
+ }
+
+ /**
+ * Handles creating a contact request.
+ *
+ * @param int $userid The id of the user who is creating the contact request
+ * @param int $requesteduserid The id of the user being requested
+ */
+ public static function create_contact_request(int $userid, int $requesteduserid) {
+ global $DB;
+
+ $request = new \stdClass();
+ $request->userid = $userid;
+ $request->requesteduserid = $requesteduserid;
+ $request->timecreated = time();
+
+ $DB->insert_record('message_contact_requests', $request);
+
+ // Send a notification.
+ $userfrom = \core_user::get_user($userid);
+ $userfromfullname = fullname($userfrom);
+ $userto = \core_user::get_user($requesteduserid);
+ $url = new \moodle_url('/message/pendingcontactrequests.php');
+
+ $subject = get_string('messagecontactrequestsnotificationsubject', 'core_message', $userfromfullname);
+ $fullmessage = get_string('messagecontactrequestsnotification', 'core_message', $userfromfullname);
+
+ $message = new \core\message\message();
+ $message->courseid = SITEID;
+ $message->component = 'moodle';
+ $message->name = 'messagecontactrequests';
+ $message->notification = 1;
+ $message->userfrom = $userfrom;
+ $message->userto = $userto;
+ $message->subject = $subject;
+ $message->fullmessage = text_to_html($fullmessage);
+ $message->fullmessageformat = FORMAT_HTML;
+ $message->fullmessagehtml = $fullmessage;
+ $message->smallmessage = '';
+ $message->contexturl = $url->out(false);
+
+ message_send($message);
+ }
+
+
+ /**
+ * Handles confirming a contact request.
+ *
+ * @param int $userid The id of the user who created the contact request
+ * @param int $requesteduserid The id of the user confirming the request
+ */
+ public static function confirm_contact_request(int $userid, int $requesteduserid) {
+ global $DB;
+
+ if ($request = $DB->get_record('message_contact_requests', ['userid' => $userid,
+ 'requesteduserid' => $requesteduserid])) {
+ self::add_contact($userid, $requesteduserid);
+
+ $DB->delete_records('message_contact_requests', ['id' => $request->id]);
+ }
+ }
+
+ /**
+ * Handles declining a contact request.
+ *
+ * @param int $userid The id of the user who created the contact request
+ * @param int $requesteduserid The id of the user declining the request
+ */
+ public static function decline_contact_request(int $userid, int $requesteduserid) {
+ global $DB;
+
+ if ($request = $DB->get_record('message_contact_requests', ['userid' => $userid,
+ 'requesteduserid' => $requesteduserid])) {
+ $DB->delete_records('message_contact_requests', ['id' => $request->id]);
+ }
+ }
+
+ /**
+ * Handles returning the contact requests for a user.
+ *
+ * This also includes the user data necessary to display information
+ * about the user.
+ *
+ * It will not include blocked users.
+ *
+ * @param int $userid
+ * @return array The list of contact requests
+ */
+ public static function get_contact_requests(int $userid) : array {
+ global $DB;
+
+ // Used to search for contacts.
+ $ufields = \user_picture::fields('u');
+
+ $sql = "SELECT $ufields, mcr.id as contactrequestid
+ FROM {user} u
+ JOIN {message_contact_requests} mcr
+ ON u.id = mcr.userid
+ LEFT JOIN {message_users_blocked} mub
+ ON (mub.userid = ? AND mub.blockeduserid = u.id)
+ WHERE mcr.requesteduserid = ?
+ AND u.deleted = 0
+ AND mub.id is NULL
+ ORDER BY mcr.timecreated DESC";
+
+ return $DB->get_records_sql($sql, [$userid, $userid]);
+ }
+
+ /**
+ * Handles adding a contact.
+ *
+ * @param int $userid The id of the user who requested to be a contact
+ * @param int $contactid The id of the contact
+ */
+ public static function add_contact(int $userid, int $contactid) {
+ global $DB;
+
+ $messagecontact = new \stdClass();
+ $messagecontact->userid = $userid;
+ $messagecontact->contactid = $contactid;
+ $messagecontact->timecreated = time();
+ $messagecontact->id = $DB->insert_record('message_contacts', $messagecontact);
+
+ $eventparams = [
+ 'objectid' => $messagecontact->id,
+ 'userid' => $userid,
+ 'relateduserid' => $contactid,
+ 'context' => \context_user::instance($userid)
+ ];
+ $event = \core\event\message_contact_added::create($eventparams);
+ $event->add_record_snapshot('message_contacts', $messagecontact);
+ $event->trigger();
+ }
+
+ /**
+ * Handles removing a contact.
+ *
+ * @param int $userid The id of the user who is removing a user as a contact
+ * @param int $contactid The id of the user to be removed as a contact
+ */
+ public static function remove_contact(int $userid, int $contactid) {
+ global $DB;
+
+ if ($contact = self::get_contact($userid, $contactid)) {
+ $DB->delete_records('message_contacts', ['id' => $contact->id]);
+
+ $event = \core\event\message_contact_removed::create(array(
+ 'objectid' => $contact->id,
+ 'userid' => $userid,
+ 'relateduserid' => $contactid,
+ 'context' => \context_user::instance($userid)
+ ));
+ $event->add_record_snapshot('message_contacts', $contact);
+ $event->trigger();
+ }
+ }
+
+ /**
+ * Handles blocking a user.
+ *
+ * @param int $userid The id of the user who is blocking
+ * @param int $usertoblockid The id of the user being blocked
+ */
+ public static function block_user(int $userid, int $usertoblockid) {
+ global $DB;
+
+ $blocked = new \stdClass();
+ $blocked->userid = $userid;
+ $blocked->blockeduserid = $usertoblockid;
+ $blocked->timecreated = time();
+ $blocked->id = $DB->insert_record('message_users_blocked', $blocked);
+
+ // Trigger event for blocking a contact.
+ $event = \core\event\message_user_blocked::create(array(
+ 'objectid' => $blocked->id,
+ 'userid' => $userid,
+ 'relateduserid' => $usertoblockid,
+ 'context' => \context_user::instance($userid)
+ ));
+ $event->add_record_snapshot('message_users_blocked', $blocked);
+ $event->trigger();
+ }
+
+ /**
+ * Handles unblocking a user.
+ *
+ * @param int $userid The id of the user who is unblocking
+ * @param int $usertounblockid The id of the user being unblocked
+ */
+ public static function unblock_user(int $userid, int $usertounblockid) {
+ global $DB;
+
+ if ($blockeduser = $DB->get_record('message_users_blocked',
+ ['userid' => $userid, 'blockeduserid' => $usertounblockid])) {
+ $DB->delete_records('message_users_blocked', ['id' => $blockeduser->id]);
+
+ // Trigger event for unblocking a contact.
+ $event = \core\event\message_user_unblocked::create(array(
+ 'objectid' => $blockeduser->id,
+ 'userid' => $userid,
+ 'relateduserid' => $usertounblockid,
+ 'context' => \context_user::instance($userid)
+ ));
+ $event->add_record_snapshot('message_users_blocked', $blockeduser);
+ $event->trigger();
+ }
+ }
+
+ /**
+ * Checks if users are already contacts.
+ *
+ * @param int $userid The id of one of the users
+ * @param int $contactid The id of the other user
+ * @return bool Returns true if they are a contact, false otherwise
+ */
+ public static function is_contact(int $userid, int $contactid) : bool {
+ global $DB;
+
+ $sql = "SELECT id
+ FROM {message_contacts} mc
+ WHERE (mc.userid = ? AND mc.contactid = ?)
+ OR (mc.userid = ? AND mc.contactid = ?)";
+ return $DB->record_exists_sql($sql, [$userid, $contactid, $contactid, $userid]);
+ }
+
+ /**
+ * Returns the row in the database table message_contacts that represents the contact between two people.
+ *
+ * @param int $userid The id of one of the users
+ * @param int $contactid The id of the other user
+ * @return mixed A fieldset object containing the record, false otherwise
+ */
+ public static function get_contact(int $userid, int $contactid) {
+ global $DB;
+
+ $sql = "SELECT mc.*
+ FROM {message_contacts} mc
+ WHERE (mc.userid = ? AND mc.contactid = ?)
+ OR (mc.userid = ? AND mc.contactid = ?)";
+ return $DB->get_record_sql($sql, [$userid, $contactid, $contactid, $userid]);
+ }
+
+ /**
+ * Checks if a user is already blocked.
+ *
+ * @param int $userid
+ * @param int $blockeduserid
+ * @return bool Returns true if they are a blocked, false otherwise
+ */
+ public static function is_blocked(int $userid, int $blockeduserid) : bool {
+ global $DB;
+
+ return $DB->record_exists('message_users_blocked', ['userid' => $userid, 'blockeduserid' => $blockeduserid]);
+ }
+
+ /**
+ * Checks if a contact request already exists between users.
+ *
+ * @param int $userid The id of the user who is creating the contact request
+ * @param int $requesteduserid The id of the user being requested
+ * @return bool Returns true if a contact request exists, false otherwise
+ */
+ public static function does_contact_request_exist(int $userid, int $requesteduserid) : bool {
+ global $DB;
+
+ $sql = "SELECT id
+ FROM {message_contact_requests} mcr
+ WHERE (mcr.userid = ? AND mcr.requesteduserid = ?)
+ OR (mcr.userid = ? AND mcr.requesteduserid = ?)";
+ return $DB->record_exists_sql($sql, [$userid, $requesteduserid, $requesteduserid, $userid]);
+ }
}
$data->messages[] = $message->export_for_template($output);
}
- $data->isblocked = api::is_user_blocked($this->currentuserid, $this->otheruserid);
+ $blockeduserid = $this->otheruserid ?? $USER->id;
+ $data->isblocked = api::is_blocked($this->currentuserid, $blockeduserid);
return $data;
}
[
'userid' => 'privacy:metadata:message_contacts:userid',
'contactid' => 'privacy:metadata:message_contacts:contactid',
- 'blocked' => 'privacy:metadata:message_contacts:blocked',
+ 'timecreated' => 'privacy:metadata:message_contacts:timecreated',
],
'privacy:metadata:message_contacts'
);
+ $items->add_database_table(
+ 'message_contact_requests',
+ [
+ 'userid' => 'privacy:metadata:message_contact_requests:userid',
+ 'requesteduserid' => 'privacy:metadata:message_contact_requests:requesteduserid',
+ 'timecreated' => 'privacy:metadata:message_contact_requests:timecreated',
+ ],
+ 'privacy:metadata:message_contact_requests'
+ );
+
+ $items->add_database_table(
+ 'message_users_blocked',
+ [
+ 'userid' => 'privacy:metadata:message_users_blocked:userid',
+ 'blockeduserid' => 'privacy:metadata:message_users_blocked:blockeduserid',
+ 'timecreated' => 'privacy:metadata:message_users_blocked:timecreated',
+ ],
+ 'privacy:metadata:message_users_blocked'
+ );
+
$items->add_database_table(
'notifications',
[
// Export the contacts.
self::export_user_data_contacts($userid);
+ // Export the contact requests.
+ self::export_user_data_contact_requests($userid);
+
+ // Export the blocked users.
+ self::export_user_data_blocked_users($userid);
+
// Export the notifications.
self::export_user_data_notifications($userid);
$DB->delete_records('message_user_actions');
$DB->delete_records('message_conversation_members');
$DB->delete_records('message_contacts');
+ $DB->delete_records('message_contact_requests');
+ $DB->delete_records('message_users_blocked');
$DB->delete_records('notifications');
}
$DB->delete_records('message_user_actions', ['userid' => $userid]);
$DB->delete_records('message_conversation_members', ['userid' => $userid]);
$DB->delete_records_select('message_contacts', 'userid = ? OR contactid = ?', [$userid, $userid]);
+ $DB->delete_records_select('message_contact_requests', 'userid = ? OR requesteduserid = ?', [$userid, $userid]);
+ $DB->delete_records_select('message_users_blocked', 'userid = ? OR blockeduserid = ?', [$userid, $userid]);
$DB->delete_records_select('notifications', 'useridfrom = ? OR useridto = ?', [$userid, $userid]);
}
$context = \context_system::instance();
// Get the user's contacts.
- if ($contacts = $DB->get_records('message_contacts', ['userid' => $userid], 'id ASC')) {
+ if ($contacts = $DB->get_records_select('message_contacts', 'userid = ? OR contactid = ?', [$userid, $userid], 'id ASC')) {
$contactdata = [];
foreach ($contacts as $contact) {
$contactdata[] = (object) [
- 'contact' => transform::user($contact->contactid),
- 'blocked' => transform::yesno($contact->blocked)
+ 'contact' => transform::user($contact->contactid)
];
}
writer::with_context($context)->export_data([get_string('contacts', 'core_message')], (object) $contactdata);
}
}
+ /**
+ * Export the messaging contact requests data.
+ *
+ * @param int $userid
+ */
+ protected static function export_user_data_contact_requests(int $userid) {
+ global $DB;
+
+ $context = \context_system::instance();
+
+ if ($contactrequests = $DB->get_records_select('message_contact_requests', 'userid = ? OR requesteduserid = ?',
+ [$userid, $userid], 'id ASC')) {
+ $contactrequestsdata = [];
+ foreach ($contactrequests as $contactrequest) {
+ if ($userid == $contactrequest->requesteduserid) {
+ $maderequest = false;
+ $contactid = $contactrequest->userid;
+ } else {
+ $maderequest = true;
+ $contactid = $contactrequest->requesteduserid;
+ }
+
+ $contactrequestsdata[] = (object) [
+ 'contactrequest' => transform::user($contactid),
+ 'maderequest' => transform::yesno($maderequest)
+ ];
+ }
+ writer::with_context($context)->export_data([get_string('contactrequests', 'core_message')],
+ (object) $contactrequestsdata);
+ }
+ }
+
+ /**
+ * Export the messaging blocked users data.
+ *
+ * @param int $userid
+ */
+ protected static function export_user_data_blocked_users(int $userid) {
+ global $DB;
+
+ $context = \context_system::instance();
+
+ if ($blockedusers = $DB->get_records('message_users_blocked', ['userid' => $userid], 'id ASC')) {
+ $blockedusersdata = [];
+ foreach ($blockedusers as $blockeduser) {
+ $blockedusersdata[] = (object) [
+ 'blockeduser' => transform::user($blockeduser->blockeduserid)
+ ];
+ }
+ writer::with_context($context)->export_data([get_string('blockedusers', 'core_message')], (object) $blockedusersdata);
+ }
+ }
+
/**
* Export the messaging data.
*
foreach($params['messages'] as $message) {
$receivers[] = $message['touserid'];
}
- list($sqluserids, $sqlparams) = $DB->get_in_or_equal($receivers, SQL_PARAMS_NAMED, 'userid_');
+ list($sqluserids, $sqlparams) = $DB->get_in_or_equal($receivers);
$tousers = $DB->get_records_select("user", "id " . $sqluserids . " AND deleted = 0", $sqlparams);
$blocklist = array();
$contactlist = array();
- $sqlparams['contactid'] = $USER->id;
+ $contactsqlparams = array_merge($sqlparams, [$USER->id], [$USER->id], $sqlparams);
$rs = $DB->get_recordset_sql("SELECT *
FROM {message_contacts}
- WHERE userid $sqluserids
- AND contactid = :contactid", $sqlparams);
+ WHERE (userid $sqluserids AND contactid = ?)
+ OR (userid = ? AND contactid $sqluserids)", $contactsqlparams);
foreach ($rs as $record) {
- if ($record->blocked) {
- // $record->userid is blocking current user
- $blocklist[$record->userid] = true;
- } else {
- // $record->userid have current user as contact
- $contactlist[$record->userid] = true;
+ $useridtouse = $record->userid;
+ if ($record->userid == $USER->id) {
+ $useridtouse = $record->contactid;
}
+ $contactlist[$useridtouse] = true;
+ }
+ $rs->close();
+ $blocksqlparams = array_merge($sqlparams, [$USER->id]);
+ $rs = $DB->get_recordset_sql("SELECT *
+ FROM {message_users_blocked}
+ WHERE userid $sqluserids
+ AND blockeduserid = ?", $blocksqlparams);
+ foreach ($rs as $record) {
+ $blocklist[$record->userid] = true;
}
$rs->close();
/**
* Create contacts parameters description.
*
+ * @deprecated since Moodle 3.6
* @return external_function_parameters
* @since Moodle 2.5
*/
/**
* Create contacts.
*
+ * @deprecated since Moodle 3.6
* @param array $userids array of user IDs.
* @param int $userid The id of the user we are creating the contacts for
* @return external_description
/**
* Create contacts return description.
*
+ * @deprecated since Moodle 3.6
* @return external_description
* @since Moodle 2.5
*/
return new external_warnings();
}
+ /**
+ * Marking the method as deprecated.
+ *
+ * @return bool
+ */
+ public static function create_contacts_is_deprecated() {
+ return true;
+ }
+
/**
* Delete contacts parameters description.
*
$params = self::validate_parameters(self::delete_contacts_parameters(), $params);
foreach ($params['userids'] as $id) {
- message_remove_contact($id, $userid);
+ \core_message\api::remove_contact($userid, $id);
}
return null;
return null;
}
+ /**
+ * Block user parameters description.
+ *
+ * @return external_function_parameters
+ */
+ public static function block_user_parameters() {
+ return new external_function_parameters(
+ [
+ 'userid' => new external_value(PARAM_INT, 'The id of the user who is blocking'),
+ 'blockeduserid' => new external_value(PARAM_INT, 'The id of the user being blocked'),
+ ]
+ );
+ }
+
+ /**
+ * Blocks a user.
+ *
+ * @param int $userid The id of the user who is blocking
+ * @param int $blockeduserid The id of the user being blocked
+ * @return external_description
+ */
+ public static function block_user(int $userid, int $blockeduserid) {
+ global $CFG, $USER;
+
+ // Check if messaging is enabled.
+ if (empty($CFG->messaging)) {
+ throw new moodle_exception('disabled', 'message');
+ }
+
+ // Validate context.
+ $context = context_system::instance();
+ self::validate_context($context);
+
+ $capability = 'moodle/site:manageallmessaging';
+ if (($USER->id != $userid) && !has_capability($capability, $context)) {
+ throw new required_capability_exception($context, $capability, 'nopermissions', '');
+ }
+
+ $params = ['userid' => $userid, 'blockeduserid' => $blockeduserid];
+ $params = self::validate_parameters(self::block_user_parameters(), $params);
+
+ if (!\core_message\api::is_blocked($params['userid'], $params['blockeduserid'])) {
+ \core_message\api::block_user($params['userid'], $params['blockeduserid']);
+ }
+
+ return [];
+ }
+
+ /**
+ * Block user return description.
+ *
+ * @return external_description
+ */
+ public static function block_user_returns() {
+ return new external_warnings();
+ }
+
+ /**
+ * Unblock user parameters description.
+ *
+ * @return external_function_parameters
+ */
+ public static function unblock_user_parameters() {
+ return new external_function_parameters(
+ [
+ 'userid' => new external_value(PARAM_INT, 'The id of the user who is unblocking'),
+ 'unblockeduserid' => new external_value(PARAM_INT, 'The id of the user being unblocked'),
+ ]
+ );
+ }
+
+ /**
+ * Unblock user.
+ *
+ * @param int $userid The id of the user who is unblocking
+ * @param int $unblockeduserid The id of the user being unblocked
+ */
+ public static function unblock_user(int $userid, int $unblockeduserid) {
+ global $CFG, $USER;
+
+ // Check if messaging is enabled.
+ if (empty($CFG->messaging)) {
+ throw new moodle_exception('disabled', 'message');
+ }
+
+ // Validate context.
+ $context = context_system::instance();
+ self::validate_context($context);
+
+ $capability = 'moodle/site:manageallmessaging';
+ if (($USER->id != $userid) && !has_capability($capability, $context)) {
+ throw new required_capability_exception($context, $capability, 'nopermissions', '');
+ }
+
+ $params = ['userid' => $userid, 'unblockeduserid' => $unblockeduserid];
+ $params = self::validate_parameters(self::unblock_user_parameters(), $params);
+
+ \core_message\api::unblock_user($params['userid'], $params['unblockeduserid']);
+
+ return [];
+ }
+
+ /**
+ * Unblock user return description.
+ *
+ * @return external_description
+ */
+ public static function unblock_user_returns() {
+ return new external_warnings();
+ }
+
/**
* Block contacts parameters description.
*
+ * @deprecated since Moodle 3.6
* @return external_function_parameters
* @since Moodle 2.5
*/
/**
* Block contacts.
*
+ * @deprecated since Moodle 3.6
* @param array $userids array of user IDs.
* @param int $userid The id of the user we are blocking the contacts for
* @return external_description
/**
* Block contacts return description.
*
+ * @deprecated since Moodle 3.6
* @return external_description
* @since Moodle 2.5
*/
return new external_warnings();
}
+ /**
+ * Marking the method as deprecated.
+ *
+ * @return bool
+ */
+ public static function block_contacts_is_deprecated() {
+ return true;
+ }
+
/**
* Unblock contacts parameters description.
*
+ * @deprecated since Moodle 3.6
* @return external_function_parameters
* @since Moodle 2.5
*/
/**
* Unblock contacts.
*
+ * @deprecated since Moodle 3.6
* @param array $userids array of user IDs.
* @param int $userid The id of the user we are unblocking the contacts for
* @return null
/**
* Unblock contacts return description.
*
+ * @deprecated since Moodle 3.6
* @return external_description
* @since Moodle 2.5
*/
return null;
}
+ /**
+ * Marking the method as deprecated.
+ *
+ * @return bool
+ */
+ public static function unblock_contacts_is_deprecated() {
+ return true;
+ }
+
+ /**
+ * Returns contact requests parameters description.
+ *
+ * @return external_function_parameters
+ */
+ public static function get_contact_requests_parameters() {
+ return new external_function_parameters(
+ [
+ 'userid' => new external_value(PARAM_INT, 'The id of the user we want the requests for')
+ ]
+ );
+ }
+
+ /**
+ * Handles returning the contact requests for a user.
+ *
+ * This also includes the user data necessary to display information
+ * about the user.
+ *
+ * It will not include blocked users.
+ *
+ * @param int $userid The id of the user we want to get the contact requests for
+ */
+ public static function get_contact_requests(int $userid) {
+ global $CFG, $USER;
+
+ // Check if messaging is enabled.
+ if (empty($CFG->messaging)) {
+ throw new moodle_exception('disabled', 'message');
+ }
+
+ // Validate context.
+ $context = context_system::instance();
+ self::validate_context($context);
+
+ $capability = 'moodle/site:manageallmessaging';
+ if (($USER->id != $userid) && !has_capability($capability, $context)) {
+ throw new required_capability_exception($context, $capability, 'nopermissions', '');
+ }
+
+ $params = ['userid' => $userid];
+ $params = self::validate_parameters(self::get_contact_requests_parameters(), $params);
+
+ return \core_message\api::get_contact_requests($params['userid']);
+ }
+
+ /**
+ * Returns the contact requests return description.
+ *
+ * @return external_description
+ */
+ public static function get_contact_requests_returns() {
+ return new external_multiple_structure(
+ new external_single_structure(
+ [
+ 'id' => new external_value(core_user::get_property_type('id'), 'ID of the user'),
+ 'contactrequestid' => new external_value(PARAM_INT, 'The ID of the contact request'),
+ 'picture' => new external_value(core_user::get_property_type('picture'), 'The picture'),
+ 'firstname' => new external_value(core_user::get_property_type('firstname'),
+ 'The first name(s) of the user'),
+ 'lastname' => new external_value(core_user::get_property_type('lastname'),
+ 'The family name of the user'),
+ 'firstnamephonetic' => new external_value(core_user::get_property_type('firstnamephonetic'),
+ 'The phonetic first name of the user'),
+ 'lastnamephonetic' => new external_value(core_user::get_property_type('lastnamephonetic'),
+ 'The phonetic last name of the user'),
+ 'middlename' => new external_value(core_user::get_property_type('middlename'),
+ 'The middle name of the user'),
+ 'alternatename' => new external_value(core_user::get_property_type('alternatename'),
+ 'The alternate name of the user'),
+ 'email' => new external_value(core_user::get_property_type('email'), 'An email address')
+ ]
+ )
+ );
+ }
+
+ /**
+ * Creates a contact request parameters description.
+ *
+ * @return external_function_parameters
+ */
+ public static function create_contact_request_parameters() {
+ return new external_function_parameters(
+ [
+ 'userid' => new external_value(PARAM_INT, 'The id of the user making the request'),
+ 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user being requested')
+ ]
+ );
+ }
+
+ /**
+ * Creates a contact request.
+ *
+ * @param int $userid The id of the user who is creating the contact request
+ * @param int $requesteduserid The id of the user being requested
+ */
+ public static function create_contact_request(int $userid, int $requesteduserid) {
+ global $CFG, $USER;
+
+ // Check if messaging is enabled.
+ if (empty($CFG->messaging)) {
+ throw new moodle_exception('disabled', 'message');
+ }
+
+ // Validate context.
+ $context = context_system::instance();
+ self::validate_context($context);
+
+ $capability = 'moodle/site:manageallmessaging';
+ if (($USER->id != $userid) && !has_capability($capability, $context)) {
+ throw new required_capability_exception($context, $capability, 'nopermissions', '');
+ }
+
+ $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
+ $params = self::validate_parameters(self::create_contact_request_parameters(), $params);
+
+ if (!\core_message\api::can_create_contact($params['userid'], $params['requesteduserid'])) {
+ $warning[] = [
+ 'item' => 'user',
+ 'itemid' => $params['requesteduserid'],
+ 'warningcode' => 'cannotcreatecontactrequest',
+ 'message' => 'You are unable to create a contact request for this user'
+ ];
+ return $warning;
+ }
+
+ if (!\core_message\api::does_contact_request_exist($params['userid'], $params['requesteduserid'])) {
+ \core_message\api::create_contact_request($params['userid'], $params['requesteduserid']);
+ }
+
+ return [];
+ }
+
+ /**
+ * Creates a contact request return description.
+ *
+ * @return external_description
+ */
+ public static function create_contact_request_returns() {
+ return new external_warnings();
+ }
+
+ /**
+ * Confirm a contact request parameters description.
+ *
+ * @return external_function_parameters
+ */
+ public static function confirm_contact_request_parameters() {
+ return new external_function_parameters(
+ [
+ 'userid' => new external_value(PARAM_INT, 'The id of the user making the request'),
+ 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user being requested')
+ ]
+ );
+ }
+
+ /**
+ * Confirm a contact request.
+ *
+ * @param int $userid The id of the user who is creating the contact request
+ * @param int $requesteduserid The id of the user being requested
+ */
+ public static function confirm_contact_request(int $userid, int $requesteduserid) {
+ global $CFG, $USER;
+
+ // Check if messaging is enabled.
+ if (empty($CFG->messaging)) {
+ throw new moodle_exception('disabled', 'message');
+ }
+
+ // Validate context.
+ $context = context_system::instance();
+ self::validate_context($context);
+
+ $capability = 'moodle/site:manageallmessaging';
+ if (($USER->id != $requesteduserid) && !has_capability($capability, $context)) {
+ throw new required_capability_exception($context, $capability, 'nopermissions', '');
+ }
+
+ $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
+ $params = self::validate_parameters(self::confirm_contact_request_parameters(), $params);
+
+ \core_message\api::confirm_contact_request($params['userid'], $params['requesteduserid']);
+
+ return [];
+ }
+
+ /**
+ * Confirm a contact request return description.
+ *
+ * @return external_description
+ */
+ public static function confirm_contact_request_returns() {
+ return new external_warnings();
+ }
+
+ /**
+ * Declines a contact request parameters description.
+ *
+ * @return external_function_parameters
+ */
+ public static function decline_contact_request_parameters() {
+ return new external_function_parameters(
+ [
+ 'userid' => new external_value(PARAM_INT, 'The id of the user making the request'),
+ 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user being requested')
+ ]
+ );
+ }
+
+ /**
+ * Declines a contact request.
+ *
+ * @param int $userid The id of the user who is creating the contact request
+ * @param int $requesteduserid The id of the user being requested
+ */
+ public static function decline_contact_request(int $userid, int $requesteduserid) {
+ global $CFG, $USER;
+
+ // Check if messaging is enabled.
+ if (empty($CFG->messaging)) {
+ throw new moodle_exception('disabled', 'message');
+ }
+
+ // Validate context.
+ $context = context_system::instance();
+ self::validate_context($context);
+
+ $capability = 'moodle/site:manageallmessaging';
+ if (($USER->id != $requesteduserid) && !has_capability($capability, $context)) {
+ throw new required_capability_exception($context, $capability, 'nopermissions', '');
+ }
+
+ $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
+ $params = self::validate_parameters(self::decline_contact_request_parameters(), $params);
+
+ \core_message\api::decline_contact_request($params['userid'], $params['requesteduserid']);
+
+ return [];
+ }
+
+ /**
+ * Declines a contact request return description.
+ *
+ * @return external_description
+ */
+ public static function decline_contact_request_returns() {
+ return new external_warnings();
+ }
+
/**
* Return the structure of a message area contact.
*
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
- * @param int $userid the user ID of the user we want to add the contact for, defaults to current user if not specified.
- * @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, $userid = 0) {
- global $USER, $DB;
-
- if (!$DB->record_exists('user', array('id' => $contactid))) { // invalid userid
- return false;
- }
-
- if (empty($userid)) {
- $userid = $USER->id;
- }
-
- // Check if a record already exists as we may be changing blocking status.
- if (($contact = $DB->get_record('message_contacts', array('userid' => $userid, 'contactid' => $contactid))) !== false) {
- // Check if blocking status has been changed.
- if ($contact->blocked != $blocked) {
- $contact->blocked = $blocked;
- $DB->update_record('message_contacts', $contact);
-
- if ($blocked == 1) {
- // Trigger event for blocking a contact.
- $event = \core\event\message_contact_blocked::create(array(
- 'objectid' => $contact->id,
- 'userid' => $contact->userid,
- 'relateduserid' => $contact->contactid,
- 'context' => context_user::instance($contact->userid)
- ));
- $event->add_record_snapshot('message_contacts', $contact);
- $event->trigger();
- } else {
- // Trigger event for unblocking a contact.
- $event = \core\event\message_contact_unblocked::create(array(
- 'objectid' => $contact->id,
- 'userid' => $contact->userid,
- 'relateduserid' => $contact->contactid,
- 'context' => context_user::instance($contact->userid)
- ));
- $event->add_record_snapshot('message_contacts', $contact);
- $event->trigger();
- }
-
- return true;
- } else {
- // No change to blocking status.
- return true;
- }
-
- } else {
- // New contact record.
- $contact = new stdClass();
- $contact->userid = $userid;
- $contact->contactid = $contactid;
- $contact->blocked = $blocked;
- $contact->id = $DB->insert_record('message_contacts', $contact);
-
- $eventparams = array(
- 'objectid' => $contact->id,
- 'userid' => $contact->userid,
- 'relateduserid' => $contact->contactid,
- 'context' => context_user::instance($contact->userid)
- );
-
- if ($blocked) {
- $event = \core\event\message_contact_blocked::create($eventparams);
- } else {
- $event = \core\event\message_contact_added::create($eventparams);
- }
- // Trigger event.
- $event->trigger();
-
- return true;
- }
-}
-
-/**
- * remove a contact
- *
- * @param int $contactid the user ID of the contact to remove
- * @param int $userid the user ID of the user we want to remove the contacts for, defaults to current user if not specified.
- * @return bool returns the result of delete_records()
- */
-function message_remove_contact($contactid, $userid = 0) {
- global $USER, $DB;
-
- if (empty($userid)) {
- $userid = $USER->id;
- }
-
- if ($contact = $DB->get_record('message_contacts', array('userid' => $userid, 'contactid' => $contactid))) {
- $DB->delete_records('message_contacts', array('id' => $contact->id));
-
- // Trigger event for removing a contact.
- $event = \core\event\message_contact_removed::create(array(
- 'objectid' => $contact->id,
- 'userid' => $contact->userid,
- 'relateduserid' => $contact->contactid,
- 'context' => context_user::instance($contact->userid)
- ));
- $event->add_record_snapshot('message_contacts', $contact);
- $event->trigger();
-
- return true;
- }
-
- return false;
-}
-
-/**
- * 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
- * @param int $userid the user ID of the user we want to unblock the contact for, defaults to current user
- * if not specified.
- * @return bool returns the result of delete_records()
- */
-function message_unblock_contact($contactid, $userid = 0) {
- return message_add_contact($contactid, 0, $userid);
-}
-
-/**
- * Block a user.
- *
- * @param int $contactid the user ID of the user to block
- * @param int $userid the user ID of the user we want to unblock the contact for, defaults to current user
- * if not specified.
- * @return bool
- */
-function message_block_contact($contactid, $userid = 0) {
- return message_add_contact($contactid, 1, $userid);
-}
-
-/**
- * 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));
-}
-
/**
* Search through course users.
*
$params = array(
'userid' => $USER->id,
+ 'userid2' => $USER->id,
'query' => "%$searchtext%"
);
if (in_array(SITEID, $courseids)) {
// Search on site level.
- return $DB->get_records_sql("SELECT $ufields, mc.id as contactlistid, mc.blocked
+ return $DB->get_records_sql("SELECT $ufields, mc.id as contactlistid, mub.id as userblockedid
FROM {user} u
LEFT JOIN {message_contacts} mc
ON mc.contactid = u.id AND mc.userid = :userid
+ LEFT JOIN {message_users_blocked} mub
+ ON mub.userid = :userid2 AND mub.blockeduserid = u.id
WHERE u.deleted = '0' AND u.confirmed = '1'
AND (".$DB->sql_like($fullname, ':query', false).")
$except
// Everyone who has a role assignment in this course or higher.
// TODO: add enabled enrolment join here (skodak)
- $users = $DB->get_records_sql("SELECT DISTINCT $ufields, mc.id as contactlistid, mc.blocked
+ $users = $DB->get_records_sql("SELECT DISTINCT $ufields, mc.id as contactlistid, mub.id as userblockedid
FROM {user} u
JOIN {role_assignments} ra ON ra.userid = u.id
LEFT JOIN {message_contacts} mc
ON mc.contactid = u.id AND mc.userid = :userid
+ LEFT JOIN {message_users_blocked} mub
+ ON mub.userid = :userid2 AND mub.blockeduserid = u.id
WHERE u.deleted = '0' AND u.confirmed = '1'
AND (".$DB->sql_like($fullname, ':query', false).")
AND ra.contextid $contextwhere
--- /dev/null
+<?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/>.
+
+/**
+ * A page displaying the user's contact requests.
+ *
+ * This is a temporary (well, should be) page until the new UI is introduced for 3.6.
+ *
+ * @package core_message
+ * @copyright 2018 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once('../config.php');
+require_once($CFG->dirroot . '/message/externallib.php');
+
+require_login(null, false);
+
+if (isguestuser()) {
+ redirect($CFG->wwwroot);
+}
+
+if (empty($CFG->messaging)) {
+ print_error('disabled', 'message');
+}
+
+$id = optional_param('id', '', PARAM_INT); // The id of the request.
+$action = optional_param('action', '', PARAM_ALPHA);
+
+// Confirm the request is able to be approved/disapproved.
+if ($id) {
+ $request = $DB->get_record('message_contact_requests', ['id' => $id, 'requesteduserid' => $USER->id], '*', MUST_EXIST);
+}
+
+// Use external functions as these are what we will be using in the new UI.
+if ($id && $action && confirm_sesskey()) {
+ if ($action == 'approve') {
+ core_message_external::confirm_contact_request($request->userid, $USER->id);
+ } else if ($action == 'decline') {
+ core_message_external::decline_contact_request($request->userid, $USER->id);
+ }
+
+ redirect(new moodle_url('/message/pendingcontactrequests.php'));
+}
+
+$table = new html_table();
+
+$headers = [];
+$headers[] = '';
+$headers[] = '';
+
+$table->head = $headers;
+
+// Use external functions as these are what we will be using in the new UI.
+if ($contactrequests = core_message_external::get_contact_requests($USER->id)) {
+ foreach ($contactrequests as $contactrequest) {
+ $approvelink = new moodle_url('/message/pendingcontactrequests.php', ['id' => $contactrequest->contactrequestid,
+ 'action' => 'approve', 'sesskey' => sesskey()]);
+ $declinelink = new moodle_url('/message/pendingcontactrequests.php', ['id' => $contactrequest->contactrequestid,
+ 'action' => 'decline', 'sesskey' => sesskey()]);
+
+ $cells = array();
+ $cells[] = fullname($contactrequest);
+ $cells[] = html_writer::link($approvelink, get_string('approve')) . " | " .
+ html_writer::link($declinelink, get_string('cancel'));
+ $table->data[] = new html_table_row($cells);
+ }
+}
+
+$url = new moodle_url('/message/pendingcontactrequests.php');
+$PAGE->set_url($url);
+
+$PAGE->set_context(context_user::instance($USER->id));
+$PAGE->set_pagelayout('standard');
+$PAGE->set_title('Pending contact requests');
+$PAGE->set_heading('Pending contact requests');
+
+echo $OUTPUT->header();
+echo html_writer::table($table);
+echo $OUTPUT->footer();
* Test count_blocked_users.
*/
public function test_count_blocked_users() {
+ global $USER;
+
// Set this user as the admin.
$this->setAdminUser();
- // Create users to add to the admin's contact list.
+ // Create user to add to the admin's block list.
$user1 = $this->getDataGenerator()->create_user();
- $user2 = $this->getDataGenerator()->create_user();
$this->assertEquals(0, \core_message\api::count_blocked_users());
- // Add 1 blocked and 1 normal contact to admin's contact list.
- message_add_contact($user1->id);
- message_add_contact($user2->id, 1);
+ // Add 1 blocked user to admin's blocked user list.
+ \core_message\api::block_user($USER->id, $user1->id);
- $this->assertEquals(0, \core_message\api::count_blocked_users($user2));
+ $this->assertEquals(0, \core_message\api::count_blocked_users($user1));
$this->assertEquals(1, \core_message\api::count_blocked_users());
}
$user2 = self::getDataGenerator()->create_user($user2);
// Block the second user.
- message_block_contact($user2->id, $user1->id);
+ \core_message\api::block_user($user1->id, $user2->id);
$user3 = new stdClass();
$user3->firstname = 'User';
$this->getDataGenerator()->enrol_user($user1->id, $course5->id, $role->id);
// Add some users as contacts.
- message_add_contact($user2->id, 0, $user1->id);
- message_add_contact($user3->id, 0, $user1->id);
- message_add_contact($user4->id, 0, $user1->id);
+ \core_message\api::add_contact($user1->id, $user2->id);
+ \core_message\api::add_contact($user1->id, $user3->id);
+ \core_message\api::add_contact($user1->id, $user4->id);
// Remove the viewparticipants capability from one of the courses.
$course5context = context_course::instance($course5->id);
// Create some users.
$user1 = self::getDataGenerator()->create_user();
$user2 = self::getDataGenerator()->create_user();
+ $user3 = self::getDataGenerator()->create_user();
// The person doing the search.
$this->setUser($user1);
// Send some messages back and forth.
$time = 1;
- $this->send_fake_message($user1, $user2, 'Yo!', 0, $time);
- $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 1);
- $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2);
- $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 3);
+ $this->send_fake_message($user3, $user1, 'Don\'t block me.', 0, $time);
+ $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
+ $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
+ $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
+ $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
+
+ // Block user 3.
+ \core_message\api::block_user($user1->id, $user3->id);
// Perform a search.
$messages = \core_message\api::search_messages($user1->id, 'o');
// Confirm the data is correct.
- $this->assertEquals(2, count($messages));
+ $this->assertEquals(3, count($messages));
$message1 = $messages[0];
$message2 = $messages[1];
+ $message3 = $messages[2];
$this->assertEquals($user2->id, $message1->userid);
$this->assertEquals($user2->id, $message1->useridfrom);
$this->assertTrue($message2->isread);
$this->assertFalse($message2->isblocked);
$this->assertNull($message2->unreadcount);
+
+ $this->assertEquals($user3->id, $message3->userid);
+ $this->assertEquals($user3->id, $message3->useridfrom);
+ $this->assertEquals(fullname($user3), $message3->fullname);
+ $this->assertTrue($message3->ismessaging);
+ $this->assertEquals('Don\'t block me.', $message3->lastmessage);
+ $this->assertNotEmpty($message3->messageid);
+ $this->assertNull($message3->isonline);
+ $this->assertFalse($message3->isread);
+ $this->assertTrue($message3->isblocked);
+ $this->assertNull($message3->unreadcount);
}
/**
$user5 = self::getDataGenerator()->create_user($user5);
// Add some users as contacts.
- message_add_contact($user2->id, 0, $user1->id);
- message_add_contact($user3->id, 0, $user1->id);
- message_add_contact($user4->id, 0, $user1->id);
+ \core_message\api::add_contact($user1->id, $user2->id);
+ \core_message\api::add_contact($user1->id, $user3->id);
+ \core_message\api::add_contact($user1->id, $user4->id);
// Retrieve the contacts.
$contacts = \core_message\api::get_contacts($user1->id);
// Confirm the data is correct.
$this->assertEquals(3, count($contacts));
+ usort($contacts, ['static', 'sort_contacts']);
$contact1 = $contacts[0];
$contact2 = $contacts[1];
$this->setUser($user1);
// Block the second user.
- message_block_contact($user2->id);
+ \core_message\api::block_user($user1->id, $user2->id);
// Check that the second user can no longer send the first user a message.
$this->assertFalse(\core_message\api::can_post_message($user1, $user2));
$this->assertTrue(\core_message\api::is_user_non_contact_blocked($user2));
// Add the first user as a contact for the second user.
- message_add_contact($user1->id, 0, $user2->id);
+ \core_message\api::add_contact($user2->id, $user1->id);
// Check that the return result is now false.
$this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
+
+ // Set the first user's preference to not receive messages from non-contacts.
+ set_user_preference('message_blocknoncontacts', 1, $user1->id);
+ $this->setUser($user2);
+ // Confirm it is still false. We want to ensure a contact request works both ways
+ // as it is now an agreement between users.
+ $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user1));
}
/**
// User shouldn't be blocked.
$this->assertFalse(\core_message\api::is_user_blocked($user1->id, $user2->id));
+ $this->assertDebuggingCalled();
// Block the user.
- message_block_contact($user2->id);
+ \core_message\api::block_user($user1->id, $user2->id);
// User should be blocked.
$this->assertTrue(\core_message\api::is_user_blocked($user1->id, $user2->id));
+ $this->assertDebuggingCalled();
// Unblock the user.
- message_unblock_contact($user2->id);
+ \core_message\api::unblock_user($user1->id, $user2->id);
$this->assertFalse(\core_message\api::is_user_blocked($user1->id, $user2->id));
+ $this->assertDebuggingCalled();
}
/**
$this->setUser($user1);
// Block the admin user.
- message_block_contact(2);
+ \core_message\api::block_user($user1->id, 2);
// Now change to the admin user.
$this->setAdminUser();
// As the admin you should still be able to send messages to the user.
$this->assertFalse(\core_message\api::is_user_blocked($user1->id));
+ $this->assertDebuggingCalled();
}
/*
$user2 = $this->getDataGenerator()->create_user();
// Add users to the admin's contact list.
- message_add_contact($user1->id);
- message_add_contact($user2->id, 1);
+ \core_message\api::block_user($USER->id, $user2->id);
$this->assertCount(1, \core_message\api::get_blocked_users($USER->id));
// Block other user.
- message_block_contact($user1->id);
+ \core_message\api::block_user($USER->id, $user1->id);
$this->assertCount(2, \core_message\api::get_blocked_users($USER->id));
// Test deleting users.
$user4 = self::getDataGenerator()->create_user();
// Add the users to each of their contacts.
- message_add_contact($user1->id, 0, $user2->id);
- message_add_contact($user2->id, 0, $user1->id);
- message_add_contact($user3->id, 0, $user2->id);
+ \core_message\api::add_contact($user1->id, $user2->id);
+ \core_message\api::add_contact($user2->id, $user3->id);
$this->send_fake_message($user1, $user2);
$this->send_fake_message($user1, $user2);
// Get the contacts and the unread message count.
$messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
-
// Confirm the size is correct.
$this->assertCount(2, $messages);
ksort($messages);
$messageinfo1 = array_shift($messages);
$messageinfo2 = array_shift($messages);
+
$this->assertEquals($user1->id, $messageinfo1->id);
$this->assertEquals(4, $messageinfo1->messagecount);
$this->assertEquals($user3->id, $messageinfo2->id);
$user2 = self::getDataGenerator()->create_user();
// Add the users to each of their contacts.
- message_add_contact($user1->id, 0, $user2->id);
+ \core_message\api::add_contact($user2->id, $user1->id);
// Check we get the correct message count.
$messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
$user4 = self::getDataGenerator()->create_user();
// Add a user to the contact list of the users we are testing this function with.
- message_add_contact($user4->id, 0, $user1->id);
- message_add_contact($user4->id, 0, $user2->id);
+ \core_message\api::add_contact($user1->id, $user4->id);
+ \core_message\api::add_contact($user2->id, $user4->id);
$this->send_fake_message($user1, $user2);
$this->send_fake_message($user1, $user2);
$this->assertEquals($conversationid,
\core_message\api::get_conversation_between_users([$user1->id, $user2->id]));
}
+
+ /**
+ * Test can create a contact request.
+ */
+ public function test_can_create_contact_request() {
+ global $CFG;
+
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ // Disable messaging.
+ $CFG->messaging = 0;
+ $this->assertFalse(\core_message\api::can_create_contact($user1->id, $user2->id));
+
+ // Re-enable messaging.
+ $CFG->messaging = 1;
+
+ // Allow users to message anyone site-wide.
+ $CFG->messagingallusers = 1;
+ $this->assertTrue(\core_message\api::can_create_contact($user1->id, $user2->id));
+
+ // Disallow users from messaging anyone site-wide.
+ $CFG->messagingallusers = 0;
+ $this->assertFalse(\core_message\api::can_create_contact($user1->id, $user2->id));
+
+ // Put the users in the same course so a contact request should be possible.
+ $course = self::getDataGenerator()->create_course();
+ $this->getDataGenerator()->enrol_user($user1->id, $course->id);
+ $this->getDataGenerator()->enrol_user($user2->id, $course->id);
+ $this->assertTrue(\core_message\api::can_create_contact($user1->id, $user2->id));
+ }
+
+ /**
+ * Test creating a contact request.
+ */
+ public function test_create_contact_request() {
+ global $DB;
+
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ \core_message\api::create_contact_request($user1->id, $user2->id);
+
+ $request = $DB->get_records('message_contact_requests');
+
+ $this->assertCount(1, $request);
+
+ $request = reset($request);
+
+ $this->assertEquals($user1->id, $request->userid);
+ $this->assertEquals($user2->id, $request->requesteduserid);
+ }
+
+ /**
+ * Test confirming a contact request.
+ */
+ public function test_confirm_contact_request() {
+ global $DB;
+
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ \core_message\api::create_contact_request($user1->id, $user2->id);
+
+ \core_message\api::confirm_contact_request($user1->id, $user2->id);
+
+ $this->assertEquals(0, $DB->count_records('message_contact_requests'));
+
+ $contact = $DB->get_records('message_contacts');
+
+ $this->assertCount(1, $contact);
+
+ $contact = reset($contact);
+
+ $this->assertEquals($user1->id, $contact->userid);
+ $this->assertEquals($user2->id, $contact->contactid);
+ }
+
+ /**
+ * Test declining a contact request.
+ */
+ public function test_decline_contact_request() {
+ global $DB;
+
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ \core_message\api::create_contact_request($user1->id, $user2->id);
+
+ \core_message\api::decline_contact_request($user1->id, $user2->id);
+
+ $this->assertEquals(0, $DB->count_records('message_contact_requests'));
+ $this->assertEquals(0, $DB->count_records('message_contacts'));
+ }
+
+ /**
+ * Test retrieving contact requests.
+ */
+ public function test_get_contact_requests() {
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+ $user3 = self::getDataGenerator()->create_user();
+
+ // Block one user, their request should not show up.
+ \core_message\api::block_user($user1->id, $user3->id);
+
+ \core_message\api::create_contact_request($user2->id, $user1->id);
+ \core_message\api::create_contact_request($user3->id, $user1->id);
+
+ $requests = \core_message\api::get_contact_requests($user1->id);
+
+ $this->assertCount(1, $requests);
+
+ $request = reset($requests);
+
+ $this->assertEquals($user2->id, $request->id);
+ $this->assertEquals($user2->picture, $request->picture);
+ $this->assertEquals($user2->firstname, $request->firstname);
+ $this->assertEquals($user2->lastname, $request->lastname);
+ $this->assertEquals($user2->firstnamephonetic, $request->firstnamephonetic);
+ $this->assertEquals($user2->lastnamephonetic, $request->lastnamephonetic);
+ $this->assertEquals($user2->middlename, $request->middlename);
+ $this->assertEquals($user2->alternatename, $request->alternatename);
+ $this->assertEquals($user2->email, $request->email);
+ }
+
+ /**
+ * Test adding contacts.
+ */
+ public function test_add_contact() {
+ global $DB;
+
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ \core_message\api::add_contact($user1->id, $user2->id);
+
+ $contact = $DB->get_records('message_contacts');
+
+ $this->assertCount(1, $contact);
+
+ $contact = reset($contact);
+
+ $this->assertEquals($user1->id, $contact->userid);
+ $this->assertEquals($user2->id, $contact->contactid);
+ }
+
+ /**
+ * Test removing contacts.
+ */
+ public function test_remove_contact() {
+ global $DB;
+
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ \core_message\api::add_contact($user1->id, $user2->id);
+ \core_message\api::remove_contact($user1->id, $user2->id);
+
+ $this->assertEquals(0, $DB->count_records('message_contacts'));
+ }
+
+ /**
+ * Test blocking users.
+ */
+ public function test_block_user() {
+ global $DB;
+
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ \core_message\api::block_user($user1->id, $user2->id);
+
+ $blockedusers = $DB->get_records('message_users_blocked');
+
+ $this->assertCount(1, $blockedusers);
+
+ $blockeduser = reset($blockedusers);
+
+ $this->assertEquals($user1->id, $blockeduser->userid);
+ $this->assertEquals($user2->id, $blockeduser->blockeduserid);
+ }
+
+ /**
+ * Test unblocking users.
+ */
+ public function test_unblock_user() {
+ global $DB;
+
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ \core_message\api::block_user($user1->id, $user2->id);
+ \core_message\api::unblock_user($user1->id, $user2->id);
+
+ $this->assertEquals(0, $DB->count_records('message_users_blocked'));
+ }
+
+ /**
+ * Test is contact check.
+ */
+ public function test_is_contact() {
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+ $user3 = self::getDataGenerator()->create_user();
+
+ \core_message\api::add_contact($user1->id, $user2->id);
+
+ $this->assertTrue(\core_message\api::is_contact($user1->id, $user2->id));
+ $this->assertTrue(\core_message\api::is_contact($user2->id, $user1->id));
+ $this->assertFalse(\core_message\api::is_contact($user2->id, $user3->id));
+ }
+
+ /**
+ * Test get contact.
+ */
+ public function test_get_contact() {
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ \core_message\api::add_contact($user1->id, $user2->id);
+
+ $contact = \core_message\api::get_contact($user1->id, $user2->id);
+
+ $this->assertEquals($user1->id, $contact->userid);
+ $this->assertEquals($user2->id, $contact->contactid);
+ }
+
+ /**
+ * Test is blocked checked.
+ */
+ public function test_is_blocked() {
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ $this->assertFalse(\core_message\api::is_blocked($user1->id, $user2->id));
+ $this->assertFalse(\core_message\api::is_blocked($user2->id, $user1->id));
+
+ \core_message\api::block_user($user1->id, $user2->id);
+
+ $this->assertTrue(\core_message\api::is_blocked($user1->id, $user2->id));
+ $this->assertFalse(\core_message\api::is_blocked($user2->id, $user1->id));
+ }
+
+ /**
+ * Test the contact request exist check.
+ */
+ public function test_does_contact_request_exist() {
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ $this->assertFalse(\core_message\api::does_contact_request_exist($user1->id, $user2->id));
+ $this->assertFalse(\core_message\api::does_contact_request_exist($user2->id, $user1->id));
+
+ \core_message\api::create_contact_request($user1->id, $user2->id);
+
+ $this->assertTrue(\core_message\api::does_contact_request_exist($user1->id, $user2->id));
+ $this->assertTrue(\core_message\api::does_contact_request_exist($user2->id, $user1->id));
+ }
+
+ /**
+ * Comparison function for sorting contacts.
+ *
+ * @param stdClass $a
+ * @param stdClass $b
+ * @return bool
+ */
+ protected static function sort_contacts($a, $b) {
+ return $a->userid > $b->userid;
+ }
}
Background:
Given the following "users" exist:
- | username | firstname | lastname | email |
+ | username | firstname | lastname | email |
| user1 | User | 1 | user1@example.com |
| user2 | User | 2 | user2@example.com |
| user3 | User | 3 | user3@example.com |
+ And I log in as "admin"
+ And I set the following administration settings values:
+ | messagingallusers | 1 |
+ And I log out
And I log in as "user1"
And I view the "User 2" contact in the message area
And I click on "Add contact" "link"
And I view the "User 3" contact in the message area
And I click on "Add contact" "link"
And I log out
+ # Approve the contact request for user2
+ And I log in as "user2"
+ And I open the notification popover
+ And I click on "View full notification" "link" in the "#nav-notification-popover-container" "css_element"
+ And I click on "Go to" "link" in the "[data-region=footer]" "css_element"
+ And I click on "Approve" "link" in the "User 1" "table_row"
+ And I log out
+ # Approve the contact request for user3
+ And I log in as "user3"
+ And I open the notification popover
+ And I click on "View full notification" "link" in the "#nav-notification-popover-container" "css_element"
+ And I click on "Go to" "link" in the "[data-region=footer]" "css_element"
+ And I click on "Approve" "link" in the "User 1" "table_row"
+ And I log out
Scenario: Add contact shows in contacts tab
When I log in as "user1"
* Test the message contact added event.
*/
public function test_message_contact_added() {
+ global $USER;
+
// Set this user as the admin.
$this->setAdminUser();
// Trigger and capture the event when adding a contact.
$sink = $this->redirectEvents();
- message_add_contact($user->id);
+ \core_message\api::add_contact($USER->id, $user->id);
$events = $sink->get_events();
$event = reset($events);
* Test the message contact removed event.
*/
public function test_message_contact_removed() {
+ global $USER;
+
// Set this user as the admin.
$this->setAdminUser();
$user = $this->getDataGenerator()->create_user();
// Add the user to the admin's contact list.
- message_add_contact($user->id);
+ \core_message\api::add_contact($USER->id, $user->id);
// Trigger and capture the event when adding a contact.
$sink = $this->redirectEvents();
- message_remove_contact($user->id);
+ \core_message\api::remove_contact($USER->id, $user->id);
$events = $sink->get_events();
$event = reset($events);
}
/**
- * Test the message contact blocked event.
+ * Test the message user blocked event.
*/
- public function test_message_contact_blocked() {
+ public function test_message_user_blocked() {
+ global $USER;
+
// Set this user as the admin.
$this->setAdminUser();
// Create a user to add to the admin's contact list.
$user = $this->getDataGenerator()->create_user();
- $user2 = $this->getDataGenerator()->create_user();
// Add the user to the admin's contact list.
- message_add_contact($user->id);
+ \core_message\api::add_contact($USER->id, $user->id);
// Trigger and capture the event when blocking a contact.
$sink = $this->redirectEvents();
- message_block_contact($user->id);
+ \core_message\api::block_user($USER->id, $user->id);
$events = $sink->get_events();
$event = reset($events);
// Check that the event data is valid.
- $this->assertInstanceOf('\core\event\message_contact_blocked', $event);
+ $this->assertInstanceOf('\core\event\message_user_blocked', $event);
$this->assertEquals(context_user::instance(2), $event->get_context());
- $expected = array(SITEID, 'message', 'block contact', 'index.php?user1=' . $user->id . '&user2=2', $user->id);
- $this->assertEventLegacyLogData($expected, $event);
- $url = new moodle_url('/message/index.php', array('user1' => $event->userid, 'user2' => $event->relateduserid));
- $this->assertEquals($url, $event->get_url());
-
- // Make sure that the contact blocked event is not triggered again.
- $sink->clear();
- message_block_contact($user->id);
- $events = $sink->get_events();
- $event = reset($events);
- $this->assertEmpty($event);
- // Make sure that we still have 1 blocked user.
- $this->assertEquals(1, \core_message\api::count_blocked_users());
-
- // Now blocking a user that is not a contact.
- $sink->clear();
- message_block_contact($user2->id);
- $events = $sink->get_events();
- $event = reset($events);
-
- // Check that the event data is valid.
- $this->assertInstanceOf('\core\event\message_contact_blocked', $event);
- $this->assertEquals(context_user::instance(2), $event->get_context());
- $expected = array(SITEID, 'message', 'block contact', 'index.php?user1=' . $user2->id . '&user2=2', $user2->id);
- $this->assertEventLegacyLogData($expected, $event);
- $url = new moodle_url('/message/index.php', array('user1' => $event->userid, 'user2' => $event->relateduserid));
- $this->assertEquals($url, $event->get_url());
}
/**
- * Test the message contact unblocked event.
+ * Test the message user unblocked event.
*/
- public function test_message_contact_unblocked() {
+ public function test_message_user_unblocked() {
+ global $USER;
+
// Set this user as the admin.
$this->setAdminUser();
$user = $this->getDataGenerator()->create_user();
// Add the user to the admin's contact list.
- message_add_contact($user->id);
+ \core_message\api::add_contact($USER->id, $user->id);
// Block the user.
- message_block_contact($user->id);
+ \core_message\api::block_user($USER->id, $user->id);
// Make sure that we have 1 blocked user.
$this->assertEquals(1, \core_message\api::count_blocked_users());
// Trigger and capture the event when unblocking a contact.
$sink = $this->redirectEvents();
- message_unblock_contact($user->id);
+ \core_message\api::unblock_user($USER->id, $user->id);
$events = $sink->get_events();
$event = reset($events);
// Check that the event data is valid.
- $this->assertInstanceOf('\core\event\message_contact_unblocked', $event);
+ $this->assertInstanceOf('\core\event\message_user_unblocked', $event);
$this->assertEquals(context_user::instance(2), $event->get_context());
- $expected = array(SITEID, 'message', 'unblock contact', 'index.php?user1=' . $user->id . '&user2=2', $user->id);
- $this->assertEventLegacyLogData($expected, $event);
- $url = new moodle_url('/message/index.php', array('user1' => $event->userid, 'user2' => $event->relateduserid));
- $this->assertEquals($url, $event->get_url());
// Make sure that we have no blocked users.
$this->assertEmpty(\core_message\api::count_blocked_users());
-
- // Make sure that the contact unblocked event is not triggered again.
- $sink->clear();
- message_unblock_contact($user->id);
- $events = $sink->get_events();
- $event = reset($events);
- $this->assertEmpty($event);
-
- // Make sure that we still have no blocked users.
- $this->assertEmpty(\core_message\api::count_blocked_users());
}
/**
}
/**
- * Test send_instant_messages
+ * Test send_instant_messages.
*/
public function test_send_instant_messages() {
+ global $DB, $USER;
- global $DB, $USER, $CFG;
+ $this->resetAfterTest();
- $this->resetAfterTest(true);
// Transactions used in tests, tell phpunit use alternative reset method.
$this->preventResetByRollback();
- // Turn off all message processors (so nothing is really sent)
- require_once($CFG->dirroot . '/message/lib.php');
- $messageprocessors = get_message_processors();
- foreach($messageprocessors as $messageprocessor) {
- $messageprocessor->enabled = 0;
- $DB->update_record('message_processors', $messageprocessor);
- }
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
- // Set the required capabilities by the external function
- $contextid = context_system::instance()->id;
- $roleid = $this->assignUserCapability('moodle/site:sendmessage', $contextid);
+ $this->setUser($user1);
+
+ // Create test message data.
+ $message1 = array();
+ $message1['touserid'] = $user2->id;
+ $message1['text'] = 'the message.';
+ $message1['clientmsgid'] = 4;
+ $messages = array($message1);
+
+ $sentmessages = core_message_external::send_instant_messages($messages);
+ $sentmessages = external_api::clean_returnvalue(core_message_external::send_instant_messages_returns(), $sentmessages);
+
+ $sentmessage = reset($sentmessages);
+
+ $sql = "SELECT m.*, mcm.userid as useridto
+ FROM {messages} m
+ INNER JOIN {message_conversations} mc
+ ON m.conversationid = mc.id
+ INNER JOIN {message_conversation_members} mcm
+ ON mcm.conversationid = mc.id
+ WHERE mcm.userid != ?
+ AND m.id = ?";
+ $themessage = $DB->get_record_sql($sql, [$USER->id, $sentmessage['msgid']]);
+
+ // Confirm that the message was inserted correctly.
+ $this->assertEquals($themessage->useridfrom, $user1->id);
+ $this->assertEquals($themessage->useridto, $message1['touserid']);
+ $this->assertEquals($themessage->smallmessage, $message1['text']);
+ $this->assertEquals($sentmessage['clientmsgid'], $message1['clientmsgid']);
+ }
+
+ /**
+ * Test send_instant_messages to a user who has blocked you.
+ */
+ public function test_send_instant_messages_blocked_user() {
+ global $DB;
+
+ $this->resetAfterTest();
+
+ // Transactions used in tests, tell phpunit use alternative reset method.
+ $this->preventResetByRollback();
$user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user1);
+
+ \core_message\api::block_user($user2->id, $user1->id);
// Create test message data.
$message1 = array();
- $message1['touserid'] = $user1->id;
+ $message1['touserid'] = $user2->id;
$message1['text'] = 'the message.';
$message1['clientmsgid'] = 4;
$messages = array($message1);
$sentmessages = core_message_external::send_instant_messages($messages);
+ $sentmessages = external_api::clean_returnvalue(core_message_external::send_instant_messages_returns(), $sentmessages);
- // We need to execute the return values cleaning process to simulate the web service server.
+ $sentmessage = reset($sentmessages);
+
+ $this->assertEquals(get_string('userisblockingyou', 'message'), $sentmessage['errormessage']);
+
+ $this->assertEquals(0, $DB->count_records('messages'));
+ }
+
+ /**
+ * Test send_instant_messages when sending a message to a non-contact who has blocked non-contacts.
+ */
+ public function test_send_instant_messages_block_non_contacts() {
+ global $DB;
+
+ $this->resetAfterTest(true);
+
+ // Transactions used in tests, tell phpunit use alternative reset method.
+ $this->preventResetByRollback();
+
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user1);
+
+ // Set the user preference so user 2 does not accept messages from non-contacts.
+ set_user_preference('message_blocknoncontacts', 1, $user2);
+
+ // Create test message data.
+ $message1 = array();
+ $message1['touserid'] = $user2->id;
+ $message1['text'] = 'the message.';
+ $message1['clientmsgid'] = 4;
+ $messages = array($message1);
+
+ $sentmessages = core_message_external::send_instant_messages($messages);
+ $sentmessages = external_api::clean_returnvalue(core_message_external::send_instant_messages_returns(), $sentmessages);
+
+ $sentmessage = reset($sentmessages);
+
+ $this->assertEquals(get_string('userisblockingyounoncontact', 'message', fullname($user2)), $sentmessage['errormessage']);
+
+ $this->assertEquals(0, $DB->count_records('messages'));
+ }
+
+ /**
+ * Test send_instant_messages when sending a message to a contact who has blocked non-contacts.
+ */
+ public function test_send_instant_messages_block_non_contacts_but_am_contact() {
+ global $DB, $USER;
+
+ $this->resetAfterTest(true);
+
+ // Transactions used in tests, tell phpunit use alternative reset method.
+ $this->preventResetByRollback();
+
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user1);
+
+ // Set the user preference so user 2 does not accept messages from non-contacts.
+ set_user_preference('message_blocknoncontacts', 1, $user2);
+
+ \core_message\api::add_contact($user1->id, $user2->id);
+
+ // Create test message data.
+ $message1 = array();
+ $message1['touserid'] = $user2->id;
+ $message1['text'] = 'the message.';
+ $message1['clientmsgid'] = 4;
+ $messages = array($message1);
+
+ $sentmessages = core_message_external::send_instant_messages($messages);
$sentmessages = external_api::clean_returnvalue(core_message_external::send_instant_messages_returns(), $sentmessages);
+ $sentmessage = reset($sentmessages);
+
$sql = "SELECT m.*, mcm.userid as useridto
FROM {messages} m
INNER JOIN {message_conversations} mc
ON mcm.conversationid = mc.id
WHERE mcm.userid != ?
AND m.id = ?";
- $themessage = $DB->get_record_sql($sql, [$USER->id, $sentmessages[0]['msgid']]);
+ $themessage = $DB->get_record_sql($sql, [$USER->id, $sentmessage['msgid']]);
// Confirm that the message was inserted correctly.
- $this->assertEquals($themessage->useridfrom, $USER->id);
+ $this->assertEquals($themessage->useridfrom, $user1->id);
$this->assertEquals($themessage->useridto, $message1['touserid']);
$this->assertEquals($themessage->smallmessage, $message1['text']);
- $this->assertEquals($sentmessages[0]['clientmsgid'], $message1['clientmsgid']);
+ $this->assertEquals($sentmessage['clientmsgid'], $message1['clientmsgid']);
+ }
+
+ /**
+ * Test send_instant_messages with no capabilities
+ */
+ public function test_send_instant_messages_no_capability() {
+ global $DB;
+
+ $this->resetAfterTest(true);
+
+ // Transactions used in tests, tell phpunit use alternative reset method.
+ $this->preventResetByRollback();
+
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user1);
+
+ // Unset the required capabilities by the external function.
+ $contextid = context_system::instance()->id;
+ $userrole = $DB->get_record('role', array('shortname' => 'user'));
+ $this->unassignUserCapability('moodle/site:sendmessage', $contextid, $userrole->id);
+
+ // Create test message data.
+ $message1 = array();
+ $message1['touserid'] = $user2->id;
+ $message1['text'] = 'the message.';
+ $message1['clientmsgid'] = 4;
+ $messages = array($message1);
+
+ $this->expectException('required_capability_exception');
+ core_message_external::send_instant_messages($messages);
+ }
+
+ /**
+ * Test send_instant_messages when messaging is disabled.
+ */
+ public function test_send_instant_messages_messaging_disabled() {
+ global $CFG;
+
+ $this->resetAfterTest(true);
+
+ // Transactions used in tests, tell phpunit use alternative reset method.
+ $this->preventResetByRollback();
+
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user1);
+
+ // Disable messaging.
+ $CFG->messaging = 0;
+
+ // Create test message data.
+ $message1 = array();
+ $message1['touserid'] = $user2->id;
+ $message1['text'] = 'the message.';
+ $message1['clientmsgid'] = 4;
+ $messages = array($message1);
+
+ $this->expectException('moodle_exception');
+ core_message_external::send_instant_messages($messages);
}
/**
// Adding a contact.
$return = core_message_external::create_contacts(array($user2->id));
+ $this->assertDebuggingCalled();
$return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return);
$this->assertEquals(array(), $return);
// Adding a contact who is already a contact.
$return = core_message_external::create_contacts(array($user2->id));
+ $this->assertDebuggingCalled();
$return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return);
$this->assertEquals(array(), $return);
// Adding multiple contacts.
$return = core_message_external::create_contacts(array($user3->id, $user4->id));
+ $this->assertDebuggingCalledCount(2);
$return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return);
$this->assertEquals(array(), $return);
// Adding a non-existing user.
$return = core_message_external::create_contacts(array(99999));
+ $this->assertDebuggingCalled();
$return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return);
$this->assertCount(1, $return);
$return = array_pop($return);
// Adding contacts with valid and invalid parameters.
$return = core_message_external::create_contacts(array($user5->id, 99999));
+ $this->assertDebuggingCalledCount(2);
$return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return);
$this->assertCount(1, $return);
$return = array_pop($return);
$user5 = self::getDataGenerator()->create_user();
$user6 = self::getDataGenerator()->create_user();
$this->setUser($user1);
- $this->assertEquals(array(), core_message_external::create_contacts(
- array($user3->id, $user4->id, $user5->id, $user6->id)));
+
+ \core_message\api::add_contact($user1->id, $user3->id);
+ \core_message\api::add_contact($user1->id, $user4->id);
+ \core_message\api::add_contact($user1->id, $user5->id);
+ \core_message\api::add_contact($user1->id, $user6->id);
// Removing a non-contact.
$return = core_message_external::delete_contacts(array($user2->id));
$user4 = self::getDataGenerator()->create_user();
$user5 = self::getDataGenerator()->create_user();
$this->setUser($user1);
- $this->assertEquals(array(), core_message_external::create_contacts(array($user3->id, $user4->id, $user5->id)));
+
+ \core_message\api::add_contact($user1->id, $user3->id);
+ \core_message\api::add_contact($user1->id, $user4->id);
+ \core_message\api::add_contact($user1->id, $user5->id);
// Blocking a contact.
$return = core_message_external::block_contacts(array($user2->id));
+ $this->assertDebuggingCalled();
$return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return);
$this->assertEquals(array(), $return);
// Blocking a contact who is already a contact.
$return = core_message_external::block_contacts(array($user2->id));
+ $this->assertDebuggingCalled();
$return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return);
$this->assertEquals(array(), $return);
// Blocking multiple contacts.
$return = core_message_external::block_contacts(array($user3->id, $user4->id));
+ $this->assertDebuggingCalledCount(2);
$return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return);
$this->assertEquals(array(), $return);
// Blocking a non-existing user.
$return = core_message_external::block_contacts(array(99999));
+ $this->assertDebuggingCalled();
$return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return);
$this->assertCount(1, $return);
$return = array_pop($return);
// Blocking contacts with valid and invalid parameters.
$return = core_message_external::block_contacts(array($user5->id, 99999));
+ $this->assertDebuggingCalledCount(2);
$return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return);
$this->assertCount(1, $return);
$return = array_pop($return);
$user5 = self::getDataGenerator()->create_user();
$user6 = self::getDataGenerator()->create_user();
$this->setUser($user1);
- $this->assertEquals(array(), core_message_external::create_contacts(
- array($user3->id, $user4->id, $user5->id, $user6->id)));
+
+ \core_message\api::add_contact($user1->id, $user3->id);
+ \core_message\api::add_contact($user1->id, $user4->id);
+ \core_message\api::add_contact($user1->id, $user5->id);
+ \core_message\api::add_contact($user1->id, $user6->id);
// Removing a non-contact.
$return = core_message_external::unblock_contacts(array($user2->id));
+ $this->assertDebuggingCalled();
$this->assertNull($return);
// Removing one contact.
$return = core_message_external::unblock_contacts(array($user3->id));
+ $this->assertDebuggingCalled();
$this->assertNull($return);
// Removing multiple contacts.
$return = core_message_external::unblock_contacts(array($user4->id, $user5->id));
+ $this->assertDebuggingCalledCount(2);
$this->assertNull($return);
// Removing contact from unexisting user.
$return = core_message_external::unblock_contacts(array(99999));
+ $this->assertDebuggingCalled();
$this->assertNull($return);
// Removing mixed valid and invalid data.
$return = core_message_external::unblock_contacts(array($user6->id, 99999));
+ $this->assertDebuggingCalledCount(2);
$this->assertNull($return);
// Try to unblock a contact of another user contact list, should throw an exception.
// All assertions must be added before this point.
$this->expectException('required_capability_exception');
core_message_external::unblock_contacts(array($user2->id), $user3->id);
+ $this->assertDebuggingCalled();
+ }
+
+ /**
+ * Test getting contact requests.
+ */
+ public function test_get_contact_requests() {
+ $this->resetAfterTest();
+
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+ $user3 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user1);
+
+ // Block one user, their request should not show up.
+ \core_message\api::block_user($user1->id, $user3->id);
+
+ \core_message\api::create_contact_request($user2->id, $user1->id);
+ \core_message\api::create_contact_request($user3->id, $user1->id);
+
+ $requests = core_message_external::get_contact_requests($user1->id);
+ $requests = external_api::clean_returnvalue(core_message_external::get_contact_requests_returns(), $requests);
+
+ $this->assertCount(1, $requests);
+
+ $request = reset($requests);
+
+ $this->assertEquals($user2->id, $request['id']);
+ $this->assertEquals($user2->picture, $request['picture']);
+ $this->assertEquals($user2->firstname, $request['firstname']);
+ $this->assertEquals($user2->lastname, $request['lastname']);
+ $this->assertEquals($user2->firstnamephonetic, $request['firstnamephonetic']);
+ $this->assertEquals($user2->lastnamephonetic, $request['lastnamephonetic']);
+ $this->assertEquals($user2->middlename, $request['middlename']);
+ $this->assertEquals($user2->alternatename, $request['alternatename']);
+ $this->assertEquals($user2->email, $request['email']);
+ }
+
+ /**
+ * Test getting contact requests with messaging disabled.
+ */
+ public function test_get_contact_requests_messaging_disabled() {
+ global $CFG;
+
+ $this->resetAfterTest();
+
+ // Create some skeleton data just so we can call the WS.
+ $user1 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user1);
+
+ // Disable messaging.
+ $CFG->messaging = 0;
+
+ // Ensure an exception is thrown.
+ $this->expectException('moodle_exception');
+ core_message_external::get_contact_requests($user1->id);
+ }
+
+ /**
+ * Test getting contact requests with no permission.
+ */
+ public function test_get_contact_requests_no_permission() {
+ $this->resetAfterTest();
+
+ // Create some skeleton data just so we can call the WS.
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+ $user3 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user3);
+
+ // Ensure an exception is thrown.
+ $this->expectException('required_capability_exception');
+ core_message_external::create_contact_request($user1->id, $user2->id);
+ }
+
+ /**
+ * Test creating a contact request.
+ */
+ public function test_create_contact_request() {
+ global $CFG, $DB;
+
+ $this->resetAfterTest();
+
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user1);
+
+ // Allow users to message anyone site-wide.
+ $CFG->messagingallusers = 1;
+
+ $return = core_message_external::create_contact_request($user1->id, $user2->id);
+ $return = external_api::clean_returnvalue(core_message_external::create_contact_request_returns(), $return);
+ $this->assertEquals(array(), $return);
+
+ $request = $DB->get_records('message_contact_requests');
+
+ $this->assertCount(1, $request);
+
+ $request = reset($request);
+
+ $this->assertEquals($user1->id, $request->userid);
+ $this->assertEquals($user2->id, $request->requesteduserid);
+ }
+
+ /**
+ * Test creating a contact request when not allowed.
+ */
+ public function test_create_contact_request_not_allowed() {
+ global $CFG;
+
+ $this->resetAfterTest();
+
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user1);
+
+ $CFG->messagingallusers = 0;
+
+ $return = core_message_external::create_contact_request($user1->id, $user2->id);
+ $return = external_api::clean_returnvalue(core_message_external::create_contact_request_returns(), $return);
+
+ $warning = reset($return);
+
+ $this->assertEquals('user', $warning['item']);
+ $this->assertEquals($user2->id, $warning['itemid']);
+ $this->assertEquals('cannotcreatecontactrequest', $warning['warningcode']);
+ $this->assertEquals('You are unable to create a contact request for this user', $warning['message']);
+ }
+
+ /**
+ * Test creating a contact request with messaging disabled.
+ */
+ public function test_create_contact_request_messaging_disabled() {
+ global $CFG;
+
+ $this->resetAfterTest();
+
+ // Create some skeleton data just so we can call the WS.
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user1);
+
+ // Disable messaging.
+ $CFG->messaging = 0;
+
+ // Ensure an exception is thrown.
+ $this->expectException('moodle_exception');
+ core_message_external::create_contact_request($user1->id, $user2->id);
+ }
+
+ /**
+ * Test creating a contact request with no permission.
+ */
+ public function test_create_contact_request_no_permission() {
+ $this->resetAfterTest();
+
+ // Create some skeleton data just so we can call the WS.
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+ $user3 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user3);
+
+ // Ensure an exception is thrown.
+ $this->expectException('required_capability_exception');
+ core_message_external::create_contact_request($user1->id, $user2->id);
+ }
+
+ /**
+ * Test confirming a contact request.
+ */
+ public function test_confirm_contact_request() {
+ global $DB;
+
+ $this->resetAfterTest();
+
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user1);
+
+ \core_message\api::create_contact_request($user1->id, $user2->id);
+
+ $this->setUser($user2);
+
+ $return = core_message_external::confirm_contact_request($user1->id, $user2->id);
+ $return = external_api::clean_returnvalue(core_message_external::confirm_contact_request_returns(), $return);
+ $this->assertEquals(array(), $return);
+
+ $this->assertEquals(0, $DB->count_records('message_contact_requests'));
+
+ $contact = $DB->get_records('message_contacts');
+
+ $this->assertCount(1, $contact);
+
+ $contact = reset($contact);
+
+ $this->assertEquals($user1->id, $contact->userid);
+ $this->assertEquals($user2->id, $contact->contactid);
+ }
+
+ /**
+ * Test confirming a contact request with messaging disabled.
+ */
+ public function test_confirm_contact_request_messaging_disabled() {
+ global $CFG;
+
+ $this->resetAfterTest();
+
+ // Create some skeleton data just so we can call the WS.
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user1);
+
+ // Disable messaging.
+ $CFG->messaging = 0;
+
+ // Ensure an exception is thrown.
+ $this->expectException('moodle_exception');
+ core_message_external::confirm_contact_request($user1->id, $user2->id);
+ }
+
+ /**
+ * Test confirming a contact request with no permission.
+ */
+ public function test_confirm_contact_request_no_permission() {
+ $this->resetAfterTest();
+
+ // Create some skeleton data just so we can call the WS.
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+ $user3 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user3);
+
+ // Ensure an exception is thrown.
+ $this->expectException('required_capability_exception');
+ core_message_external::confirm_contact_request($user1->id, $user2->id);
+ }
+
+ /**
+ * Test declining a contact request.
+ */
+ public function test_decline_contact_request() {
+ global $DB;
+
+ $this->resetAfterTest();
+
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user1);
+
+ \core_message\api::create_contact_request($user1->id, $user2->id);
+
+ $this->setUser($user2);
+
+ $return = core_message_external::decline_contact_request($user1->id, $user2->id);
+ $return = external_api::clean_returnvalue(core_message_external::decline_contact_request_returns(), $return);
+ $this->assertEquals(array(), $return);
+
+ $this->assertEquals(0, $DB->count_records('message_contact_requests'));
+ $this->assertEquals(0, $DB->count_records('message_contacts'));
+ }
+
+ /**
+ * Test declining a contact request with messaging disabled.
+ */
+ public function test_decline_contact_request_messaging_disabled() {
+ global $CFG;
+
+ $this->resetAfterTest();
+
+ // Create some skeleton data just so we can call the WS.
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user1);
+
+ // Disable messaging.
+ $CFG->messaging = 0;
+
+ // Ensure an exception is thrown.
+ $this->expectException('moodle_exception');
+ core_message_external::decline_contact_request($user1->id, $user2->id);
+ }
+
+ /**
+ * Test declining a contact request with no permission.
+ */
+ public function test_decline_contact_request_no_permission() {
+ $this->resetAfterTest();
+
+ // Create some skeleton data just so we can call the WS.
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+ $user3 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user3);
+
+ // Ensure an exception is thrown.
+ $this->expectException('required_capability_exception');
+ core_message_external::decline_contact_request($user1->id, $user2->id);
+ }
+
+ /**
+ * Test blocking a user.
+ */
+ public function test_block_user() {
+ global $DB;
+
+ $this->resetAfterTest(true);
+
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user1);
+
+ // Blocking a user.
+ $return = core_message_external::block_user($user1->id, $user2->id);
+ $return = external_api::clean_returnvalue(core_message_external::block_user_returns(), $return);
+ $this->assertEquals(array(), $return);
+
+ // Get list of blocked users.
+ $record = $DB->get_record('message_users_blocked', []);
+
+ $this->assertEquals($user1->id, $record->userid);
+ $this->assertEquals($user2->id, $record->blockeduserid);
+
+ // Blocking a user who is already blocked.
+ $return = core_message_external::block_user($user1->id, $user2->id);
+ $return = external_api::clean_returnvalue(core_message_external::block_user_returns(), $return);
+ $this->assertEquals(array(), $return);
+
+ $this->assertEquals(1, $DB->count_records('message_users_blocked'));
+ }
+
+ /**
+ * Test blocking a user with messaging disabled.
+ */
+ public function test_block_user_messaging_disabled() {
+ global $CFG;
+
+ $this->resetAfterTest();
+
+ // Create some skeleton data just so we can call the WS.
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user1);
+
+ // Disable messaging.
+ $CFG->messaging = 0;
+
+ // Ensure an exception is thrown.
+ $this->expectException('moodle_exception');
+ core_message_external::block_user($user1->id, $user2->id);
+ }
+
+ /**
+ * Test blocking a user with no permission.
+ */
+ public function test_block_user_no_permission() {
+ $this->resetAfterTest();
+
+ // Create some skeleton data just so we can call the WS.
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+ $user3 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user3);
+
+ // Ensure an exception is thrown.
+ $this->expectException('required_capability_exception');
+ core_message_external::block_user($user1->id, $user2->id);
+ }
+
+ /**
+ * Test unblocking a user.
+ */
+ public function test_unblock_user() {
+ global $DB;
+
+ $this->resetAfterTest(true);
+
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user1);
+
+ // Block the user.
+ \core_message\api::block_user($user1->id, $user2->id);
+
+ // Unblocking a user.
+ $return = core_message_external::unblock_user($user1->id, $user2->id);
+ $return = external_api::clean_returnvalue(core_message_external::unblock_user_returns(), $return);
+ $this->assertEquals(array(), $return);
+
+ $this->assertEquals(0, $DB->count_records('message_users_blocked'));
+
+ // Unblocking a user who is already unblocked.
+ $return = core_message_external::unblock_user($user1->id, $user2->id);
+ $return = external_api::clean_returnvalue(core_message_external::unblock_user_returns(), $return);
+ $this->assertEquals(array(), $return);
+
+ $this->assertEquals(0, $DB->count_records('message_users_blocked'));
+ }
+
+ /**
+ * Test unblocking a user with messaging disabled.
+ */
+ public function test_unblock_user_messaging_disabled() {
+ global $CFG;
+
+ $this->resetAfterTest();
+
+ // Create some skeleton data just so we can call the WS.
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user1);
+
+ // Disable messaging.
+ $CFG->messaging = 0;
+
+ // Ensure an exception is thrown.
+ $this->expectException('moodle_exception');
+ core_message_external::unblock_user($user1->id, $user2->id);
+ }
+
+ /**
+ * Test unblocking a user with no permission.
+ */
+ public function test_unblock_user_no_permission() {
+ $this->resetAfterTest();
+
+ // Create some skeleton data just so we can call the WS.
+ $user1 = self::getDataGenerator()->create_user();
+ $user2 = self::getDataGenerator()->create_user();
+ $user3 = self::getDataGenerator()->create_user();
+
+ $this->setUser($user3);
+
+ // Ensure an exception is thrown.
+ $this->expectException('required_capability_exception');
+ core_message_external::unblock_user($user1->id, $user2->id);
}
/**
// Login as user1.
$this->setUser($user1);
- $this->assertEquals(array(), core_message_external::create_contacts(
- array($user_offline1->id, $user_offline2->id, $user_offline3->id, $user_online->id)));
+ \core_message\api::add_contact($user1->id, $user_offline1->id);
+ \core_message\api::add_contact($user1->id, $user_offline2->id);
+ \core_message\api::add_contact($user1->id, $user_offline3->id);
+ \core_message\api::add_contact($user1->id, $user_online->id);
// User_stranger sends a couple of messages to user1.
$this->send_message($user_stranger, $user1, 'Hello there!');
$this->assertCount(1, $contacts['online']);
$this->assertCount(3, $contacts['strangers']);
core_message_external::block_contacts(array($user_blocked->id));
+ $this->assertDebuggingCalled();
$contacts = core_message_external::get_contacts();
$contacts = external_api::clean_returnvalue(core_message_external::get_contacts_returns(), $contacts);
$this->assertCount(3, $contacts['offline']);
// Login as user1.
$this->setUser($user1);
- $this->assertEquals(array(), core_message_external::create_contacts(
- array($useroffline1->id, $useroffline2->id)));
+
+ \core_message\api::add_contact($user1->id, $useroffline1->id);
+ \core_message\api::add_contact($user1->id, $useroffline2->id);
// The userstranger sends a couple of messages to user1.
$this->send_message($userstranger, $user1, 'Hello there!');
// Block the $userblocked and retrieve again the list.
core_message_external::block_contacts(array($userblocked->id));
+ $this->assertDebuggingCalled();
$blockedusers = core_message_external::get_blocked_users($user1->id);
$blockedusers = external_api::clean_returnvalue(core_message_external::get_blocked_users_returns(), $blockedusers);
$this->assertCount(1, $blockedusers['users']);
$blockedusers = core_message_external::get_blocked_users($user1->id);
$blockedusers = external_api::clean_returnvalue(core_message_external::get_blocked_users_returns(), $blockedusers);
$this->assertCount(0, $blockedusers['users']);
-
}
/**
// Login as user1.
$this->setUser($user1);
- $this->assertEquals(array(), core_message_external::create_contacts(
- array($user2->id, $user3->id)));
+ \core_message\api::add_contact($user1->id, $user2->id);
+ \core_message\api::add_contact($user1->id, $user3->id);
// The user2 sends a couple of messages to user1.
$this->send_message($user2, $user1, 'Hello there!');
// Login as user1.
$this->setUser($user1);
- $this->assertEquals(array(), core_message_external::create_contacts(
- array($user2->id, $user3->id)));
+ \core_message\api::add_contact($user1->id, $user2->id);
+ \core_message\api::add_contact($user1->id, $user3->id);
// The user2 sends a couple of notifications to user1.
$this->send_message($user2, $user1, 'Hello there!', 1);
// Login as user1.
$this->setUser($user1);
- $this->assertEquals(array(), core_message_external::create_contacts(array($user2->id, $user3->id)));
+ \core_message\api::add_contact($user1->id, $user2->id);
+ \core_message\api::add_contact($user1->id, $user3->id);
// User user1 does not interchange messages with user3.
$m1to2 = message_post_message($user1, $user2, 'some random text 1', FORMAT_MOODLE);
$user2 = self::getDataGenerator()->create_user($user2);
// Block the second user.
- message_block_contact($user2->id, $user1->id);
+ \core_message\api::block_user($user1->id, $user2->id);
$user3 = new stdClass();
$user3->firstname = 'User';
$this->getDataGenerator()->enrol_user($user1->id, $course3->id, 'student');
// Add some users as contacts.
- message_add_contact($user2->id, 0, $user1->id);
- message_add_contact($user3->id, 0, $user1->id);
- message_add_contact($user4->id, 0, $user1->id);
+ \core_message\api::add_contact($user1->id, $user2->id);
+ \core_message\api::add_contact($user1->id, $user3->id);
+ \core_message\api::add_contact($user1->id, $user4->id);
// Perform a search.
$result = core_message_external::data_for_messagearea_search_users($user1->id, 'search');
$course3 = $this->getDataGenerator()->create_course($course3);
// Add some users as contacts.
- message_add_contact($user2->id, 0, $user1->id);
- message_add_contact($user3->id, 0, $user1->id);
- message_add_contact($user4->id, 0, $user1->id);
+ \core_message\api::add_contact($user1->id, $user2->id);
+ \core_message\api::add_contact($user1->id, $user3->id);
+ \core_message\api::add_contact($user1->id, $user4->id);
// Perform a search.
$result = core_message_external::data_for_messagearea_search_users($user1->id, 'search');
$user5 = self::getDataGenerator()->create_user($user5);
// Add some users as contacts.
- message_add_contact($user2->id, 0, $user1->id);
- message_add_contact($user3->id, 0, $user1->id);
- message_add_contact($user4->id, 0, $user1->id);
+ \core_message\api::add_contact($user1->id, $user2->id);
+ \core_message\api::add_contact($user1->id, $user3->id);
+ \core_message\api::add_contact($user1->id, $user4->id);
// Retrieve the contacts.
$result = core_message_external::data_for_messagearea_contacts($user1->id);
// Confirm the data is correct.
$contacts = $result['contacts'];
+ usort($contacts, ['static', 'sort_contacts']);
$this->assertCount(3, $contacts);
$contact1 = $contacts[0];
$user5 = self::getDataGenerator()->create_user($user5);
// Add some users as contacts.
- message_add_contact($user2->id, 0, $user1->id);
- message_add_contact($user3->id, 0, $user1->id);
- message_add_contact($user4->id, 0, $user1->id);
+ \core_message\api::add_contact($user1->id, $user2->id);
+ \core_message\api::add_contact($user1->id, $user3->id);
+ \core_message\api::add_contact($user1->id, $user4->id);
// Retrieve the contacts.
$result = core_message_external::data_for_messagearea_contacts($user1->id);
// Confirm the data is correct.
$contacts = $result['contacts'];
+ usort($contacts, ['static', 'sort_contacts']);
$this->assertCount(3, $contacts);
$contact1 = $contacts[0];
$this->expectException('moodle_exception');
$prefs = core_message_external::get_user_message_preferences($otheruser->id);
}
+
+ /**
+ * Comparison function for sorting contacts.
+ *
+ * @param array $a
+ * @param array $b
+ * @return bool
+ */
+ protected static function sort_contacts($a, $b) {
+ return $a['userid'] > $b['userid'];
+ }
}
* Test message_get_blocked_users.
*/
public function test_message_get_blocked_users() {
+ global $USER;
+
// Set this user as the admin.
$this->setAdminUser();
$user1 = $this->getDataGenerator()->create_user();
$user2 = $this->getDataGenerator()->create_user();
- // Add users to the admin's contact list.
- message_add_contact($user1->id);
- message_add_contact($user2->id, 1);
+ \core_message\api::block_user($USER->id, $user2->id);
$this->assertCount(1, message_get_blocked_users());
$this->assertDebuggingCalled();
// Block other user.
- message_block_contact($user1->id);
+ \core_message\api::block_user($USER->id, $user1->id);
$this->assertCount(2, message_get_blocked_users());
$this->assertDebuggingCalled();
$user3 = $this->getDataGenerator()->create_user(); // Stranger.
// Add users to the admin's contact list.
- message_add_contact($user1->id);
- message_add_contact($user2->id);
+ \core_message\api::add_contact($USER->id, $user1->id);
+ \core_message\api::add_contact($USER->id, $user2->id);
// Send some messages.
$this->send_fake_message($user1, $USER);
$this->assertCount(3, $strangers);
// Block 1 user.
- message_block_contact($user2->id);
+ \core_message\api::block_user($USER->id, $user2->id);
list($onlinecontacts, $offlinecontacts, $strangers) = message_get_contacts();
$this->assertDebuggingCalled();
$this->assertCount(0, $onlinecontacts);
* Test message_add_contact.
*/
public function test_message_add_contact() {
+ global $DB, $USER;
+
// Set this user as the admin.
$this->setAdminUser();
// Create a user to add to the admin's contact list.
$user1 = $this->getDataGenerator()->create_user();
$user2 = $this->getDataGenerator()->create_user();
- $user3 = $this->getDataGenerator()->create_user();
message_add_contact($user1->id);
- message_add_contact($user2->id, 0);
- // Add duplicate contact and make sure only 1 record exists.
+ $this->assertDebuggingCalled();
+ $this->assertEquals(1, $DB->count_records('message_contact_requests'));
+
message_add_contact($user2->id, 1);
+ $this->assertDebuggingCalled();
+ $this->assertEquals(1, $DB->count_records('message_users_blocked'));
- $this->assertNotEmpty(message_get_contact($user1->id));
- $this->assertNotEmpty(message_get_contact($user2->id));
- $this->assertEquals(false, message_get_contact($user3->id));
- $this->assertEquals(1, \core_message\api::count_blocked_users());
+ message_add_contact($user2->id, 0);
+ $this->assertDebuggingCalled();
+ $this->assertEquals(0, $DB->count_records('message_users_blocked'));
}
/**
* Test message_remove_contact.
*/
public function test_message_remove_contact() {
+ global $USER;
+
// Set this user as the admin.
$this->setAdminUser();
$user = $this->getDataGenerator()->create_user();
// Add the user to the admin's contact list.
- message_add_contact($user->id);
- $this->assertNotEmpty(message_get_contact($user->id));
+ \core_message\api::add_contact($USER->id, $user->id);
// Remove user from admin's contact list.
message_remove_contact($user->id);
+ $this->assertDebuggingCalled();
$this->assertEquals(false, message_get_contact($user->id));
+ $this->assertDebuggingCalled();
}
/**
* Test message_block_contact.
*/
public function test_message_block_contact() {
+ global $USER;
+
// Set this user as the admin.
$this->setAdminUser();
$user2 = $this->getDataGenerator()->create_user();
// Add users to the admin's contact list.
- message_add_contact($user1->id);
- message_add_contact($user2->id);
+ \core_message\api::add_contact($USER->id, $user1->id);
+ \core_message\api::add_contact($USER->id, $user2->id);
$this->assertEquals(0, \core_message\api::count_blocked_users());
// Block 1 user.
message_block_contact($user2->id);
+ $this->assertDebuggingCalled();
$this->assertEquals(1, \core_message\api::count_blocked_users());
}
* Test message_unblock_contact.
*/
public function test_message_unblock_contact() {
+ global $USER;
+
// Set this user as the admin.
$this->setAdminUser();
// Create a user to add to the admin's contact list.
$user1 = $this->getDataGenerator()->create_user();
- $user2 = $this->getDataGenerator()->create_user();
-
- // Add users to the admin's contact list.
- message_add_contact($user1->id);
- message_add_contact($user2->id, 1); // Add blocked contact.
+ // Add users to the admin's blocked list.
+ \core_message\api::block_user($USER->id, $user1->id);
$this->assertEquals(1, \core_message\api::count_blocked_users());
// Unblock user.
- message_unblock_contact($user2->id);
+ message_unblock_contact($user1->id);
+ $this->assertDebuggingCalled();
$this->assertEquals(0, \core_message\api::count_blocked_users());
}
* Test message_search_users.
*/
public function test_message_search_users() {
+ global $USER;
+
// Set this user as the admin.
$this->setAdminUser();
$user2 = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'user2'));
// Add users to the admin's contact list.
- message_add_contact($user1->id);
- message_add_contact($user2->id); // Add blocked contact.
+ \core_message\api::add_contact($USER->id, $user1->id);
+ \core_message\api::add_contact($USER->id, $user2->id);
$this->assertCount(1, message_search_users(0, 'Test1'));
$this->assertCount(2, message_search_users(0, 'Test'));
$collection = new collection('core_message');
$newcollection = provider::get_metadata($collection);
$itemcollection = $newcollection->get_collection();
- $this->assertCount(6, $itemcollection);
+ $this->assertCount(8, $itemcollection);
$messagestable = array_shift($itemcollection);
$this->assertEquals('messages', $messagestable->get_name());
$messagecontacts = array_shift($itemcollection);
$this->assertEquals('message_contacts', $messagecontacts->get_name());
+ $messagecontactrequests = array_shift($itemcollection);
+ $this->assertEquals('message_contact_requests', $messagecontactrequests->get_name());
+
+ $messageusersblocked = array_shift($itemcollection);
+ $this->assertEquals('message_users_blocked', $messageusersblocked->get_name());
+
$notificationstable = array_shift($itemcollection);
$this->assertEquals('notifications', $notificationstable->get_name());
$privacyfields = $messagecontacts->get_privacy_fields();
$this->assertArrayHasKey('userid', $privacyfields);
$this->assertArrayHasKey('contactid', $privacyfields);
- $this->assertArrayHasKey('blocked', $privacyfields);
+ $this->assertArrayHasKey('timecreated', $privacyfields);
$this->assertEquals('privacy:metadata:message_contacts', $messagecontacts->get_summary());
+ $privacyfields = $messagecontactrequests->get_privacy_fields();
+ $this->assertArrayHasKey('userid', $privacyfields);
+ $this->assertArrayHasKey('requesteduserid', $privacyfields);
+ $this->assertArrayHasKey('timecreated', $privacyfields);
+ $this->assertEquals('privacy:metadata:message_contact_requests', $messagecontactrequests->get_summary());
+
+ $privacyfields = $messageusersblocked->get_privacy_fields();
+ $this->assertArrayHasKey('userid', $privacyfields);
+ $this->assertArrayHasKey('blockeduserid', $privacyfields);
+ $this->assertArrayHasKey('timecreated', $privacyfields);
+ $this->assertEquals('privacy:metadata:message_users_blocked', $messageusersblocked->get_summary());
+
$privacyfields = $notificationstable->get_privacy_fields();
$this->assertArrayHasKey('useridfrom', $privacyfields);
$this->assertArrayHasKey('useridto', $privacyfields);
$user3 = $this->getDataGenerator()->create_user();
$user4 = $this->getDataGenerator()->create_user();
- // This user will not be added as a contact.
- $this->getDataGenerator()->create_user();
-
- message_add_contact($user2->id, 0, $user1->id);
- message_add_contact($user3->id, 0, $user1->id);
- message_add_contact($user4->id, 1, $user1->id);
+ \core_message\api::add_contact($user1->id, $user2->id);
+ \core_message\api::add_contact($user1->id, $user3->id);
+ \core_message\api::add_contact($user1->id, $user4->id);
$this->export_context_data_for_user($user1->id, \context_system::instance(), 'core_message');
$contact1 = array_shift($contacts);
$this->assertEquals($user2->id, $contact1->contact);
- $this->assertEquals(get_string('no'), $contact1->blocked);
$contact2 = array_shift($contacts);
$this->assertEquals($user3->id, $contact2->contact);
- $this->assertEquals(get_string('no'), $contact2->blocked);
$contact3 = array_shift($contacts);
$this->assertEquals($user4->id, $contact3->contact);
- $this->assertEquals(get_string('yes'), $contact3->blocked);
+ }
+
+ /**
+ * Test for provider::export_user_data().
+ */
+ public function test_export_for_context_with_contact_requests() {
+ $this->resetAfterTest();
+
+ // Create users to test with.
+ $user1 = $this->getDataGenerator()->create_user();
+ $user2 = $this->getDataGenerator()->create_user();
+ $user3 = $this->getDataGenerator()->create_user();
+ $user4 = $this->getDataGenerator()->create_user();
+
+ \core_message\api::create_contact_request($user1->id, $user2->id);
+ \core_message\api::create_contact_request($user3->id, $user1->id);
+ \core_message\api::create_contact_request($user1->id, $user4->id);
+
+ $this->export_context_data_for_user($user1->id, \context_system::instance(), 'core_message');
+
+ $writer = writer::with_context(\context_system::instance());
+
+ $contactrequests = (array) $writer->get_data([get_string('contactrequests', 'core_message')]);
+
+ $this->assertCount(3, $contactrequests);
+
+ $contactrequest1 = array_shift($contactrequests);
+ $this->assertEquals($user2->id, $contactrequest1->contactrequest);
+ $this->assertEquals(get_string('yes'), $contactrequest1->maderequest);
+
+ $contactrequest2 = array_shift($contactrequests);
+ $this->assertEquals($user3->id, $contactrequest2->contactrequest);
+ $this->assertEquals(get_string('no'), $contactrequest2->maderequest);
+
+ $contactrequest3 = array_shift($contactrequests);
+ $this->assertEquals($user4->id, $contactrequest3->contactrequest);
+ $this->assertEquals(get_string('yes'), $contactrequest3->maderequest);
+ }
+
+ /**
+ * Test for provider::export_user_data().
+ */
+ public function test_export_for_context_with_blocked_users() {
+ $this->resetAfterTest();
+
+ // Create users to test with.
+ $user1 = $this->getDataGenerator()->create_user();
+ $user2 = $this->getDataGenerator()->create_user();
+ $user3 = $this->getDataGenerator()->create_user();
+ $user4 = $this->getDataGenerator()->create_user();
+
+ \core_message\api::block_user($user1->id, $user2->id);
+ \core_message\api::block_user($user1->id, $user3->id);
+ \core_message\api::block_user($user1->id, $user4->id);
+
+ $this->export_context_data_for_user($user1->id, \context_system::instance(), 'core_message');
+
+ $writer = writer::with_context(\context_system::instance());
+
+ $blockedusers = (array) $writer->get_data([get_string('blockedusers', 'core_message')]);
+
+ $this->assertCount(3, $blockedusers);
+
+ $blockeduser1 = array_shift($blockedusers);
+ $this->assertEquals($user2->id, $blockeduser1->blockeduser);
+
+ $blockeduser2 = array_shift($blockedusers);
+ $this->assertEquals($user3->id, $blockeduser2->blockeduser);
+
+ $blockeduser3 = array_shift($blockedusers);
+ $this->assertEquals($user4->id, $blockeduser3->blockeduser);
}
/**
// Create users to test with.
$user1 = $this->getDataGenerator()->create_user();
$user2 = $this->getDataGenerator()->create_user();
+ $user3 = $this->getDataGenerator()->create_user();
+ $user4 = $this->getDataGenerator()->create_user();
$now = time();
$timeread = $now - DAYSECS;
$systemcontext = \context_system::instance();
// Create contacts.
- message_add_contact($user1->id, 0, $user2->id);
- message_add_contact($user2->id, 0, $user1->id);
+ \core_message\api::add_contact($user1->id, $user2->id);
+
+ // Create contact requests.
+ \core_message\api::create_contact_request($user1->id, $user3->id);
+
+ // Block a user.
+ \core_message\api::block_user($user1->id, $user3->id);
// Create messages.
$m1 = $this->create_message($user1->id, $user2->id, $now + (9 * DAYSECS), true);
// Delete one of the messages.
\core_message\api::delete_message($user1->id, $m2);
- // There should be 2 contacts.
- $this->assertEquals(2, $DB->count_records('message_contacts'));
+ // There should be 1 contact.
+ $this->assertEquals(1, $DB->count_records('message_contacts'));
+
+ // There should be 1 contact request.
+ $this->assertEquals(1, $DB->count_records('message_contact_requests'));
+
+ // There should be 1 blocked user.
+ $this->assertEquals(1, $DB->count_records('message_users_blocked'));
// There should be two messages.
$this->assertEquals(2, $DB->count_records('messages'));
// There should be two conversation members.
$this->assertEquals(2, $DB->count_records('message_conversation_members'));
- // There should be two notifications.
- $this->assertEquals(2, $DB->count_records('notifications'));
+ // There should be two notifications + one for the contact request.
+ $this->assertEquals(3, $DB->count_records('notifications'));
provider::delete_data_for_all_users_in_context($systemcontext);
// Confirm all has been deleted.
$this->assertEquals(0, $DB->count_records('message_contacts'));
+ $this->assertEquals(0, $DB->count_records('message_contact_requests'));
+ $this->assertEquals(0, $DB->count_records('message_users_blocked'));
$this->assertEquals(0, $DB->count_records('messages'));
$this->assertEquals(0, $DB->count_records('message_user_actions'));
$this->assertEquals(0, $DB->count_records('message_conversation_members'));
$user1 = $this->getDataGenerator()->create_user();
$user2 = $this->getDataGenerator()->create_user();
$user3 = $this->getDataGenerator()->create_user();
+ $user4 = $this->getDataGenerator()->create_user();
+ $user5 = $this->getDataGenerator()->create_user();
+ $user6 = $this->getDataGenerator()->create_user();
$now = time();
$timeread = $now - DAYSECS;
// Create contacts.
- message_add_contact($user1->id, 0, $user2->id);
- message_add_contact($user2->id, 0, $user1->id);
- message_add_contact($user2->id, 0, $user3->id);
+ \core_message\api::add_contact($user1->id, $user2->id);
+ \core_message\api::add_contact($user2->id, $user3->id);
+
+ // Create contact requests.
+ \core_message\api::create_contact_request($user1->id, $user3->id);
+ \core_message\api::create_contact_request($user2->id, $user4->id);
+
+ // Block users.
+ \core_message\api::block_user($user1->id, $user5->id);
+ \core_message\api::block_user($user2->id, $user6->id);
// Create messages.
$m1 = $this->create_message($user1->id, $user2->id, $now + (9 * DAYSECS), $timeread);
// Delete one of the messages.
\core_message\api::delete_message($user1->id, $m2);
- // There should be 3 contacts.
- $this->assertEquals(3, $DB->count_records('message_contacts'));
+ // There should be 2 contacts.
+ $this->assertEquals(2, $DB->count_records('message_contacts'));
+
+ // There should be 1 contact request.
+ $this->assertEquals(2, $DB->count_records('message_contact_requests'));
+
+ // There should be 1 blocked user.
+ $this->assertEquals(2, $DB->count_records('message_users_blocked'));
// There should be two messages.
$this->assertEquals(2, $DB->count_records('messages'));
// There should be two conversation members.
$this->assertEquals(2, $DB->count_records('message_conversation_members'));
- // There should be three notifications.
- $this->assertEquals(3, $DB->count_records('notifications'));
+ // There should be three notifications + two for the contact requests.
+ $this->assertEquals(5, $DB->count_records('notifications'));
$systemcontext = \context_system::instance();
$contextlist = new \core_privacy\local\request\approved_contextlist($user1, 'core_message',
// Confirm the user 2 data still exists.
$contacts = $DB->get_records('message_contacts');
+ $contactrequests = $DB->get_records('message_contact_requests');
+ $blockedusers = $DB->get_records('message_users_blocked');
$messages = $DB->get_records('messages');
$muas = $DB->get_records('message_user_actions');
$mcms = $DB->get_records('message_conversation_members');
$this->assertCount(1, $contacts);
$contact = reset($contacts);
- $this->assertEquals($user3->id, $contact->userid);
- $this->assertEquals($user2->id, $contact->contactid);
+ $this->assertEquals($user2->id, $contact->userid);
+ $this->assertEquals($user3->id, $contact->contactid);
+
+ $this->assertCount(1, $contactrequests);
+ $contactrequest = reset($contactrequests);
+ $this->assertEquals($user2->id, $contactrequest->userid);
+ $this->assertEquals($user4->id, $contactrequest->requesteduserid);
+
+ $this->assertCount(1, $blockedusers);
+ $blockeduser = reset($blockedusers);
+ $this->assertEquals($user2->id, $blockeduser->userid);
+ $this->assertEquals($user6->id, $blockeduser->blockeduserid);
$this->assertCount(1, $messages);
$message = reset($messages);
$mcm = reset($mcms);
$this->assertEquals($user2->id, $mcm->userid);
- $this->assertCount(1, $notifications);
- $notification = reset($notifications);
+ $this->assertCount(2, $notifications);
+ ksort($notifications);
+
+ $notification = array_shift($notifications);
+ $this->assertEquals($user2->id, $notification->useridfrom);
+ $this->assertEquals($user4->id, $notification->useridto);
+
+ $notification = array_shift($notifications);
$this->assertEquals($user2->id, $notification->useridfrom);
$this->assertEquals($user3->id, $notification->useridto);
}
* message_can_post_message()
* message_is_user_non_contact_blocked()
* message_is_user_blocked()
+* The following functions have been deprecated and should not be used any more:
+ - message_add_contact()
+ - message_remove_contact()
+ - message_unblock_contact()
+ - message_block_contact()
+ - message_get_contact()
+ Please see their declaration in lib/deprecatedlib.php to view their alternatives (if applicable).
+* The following methods have been deprecated and should not be used any more:
+ - \core_message\api::is_user_blocked()
+* The following web services have been deprecated. Please do not call these any more.
+ - core_message_external::block_contacts, please use core_message_external::block_user instead.
+ - core_message_external::unblock_contacts, please use core_message_external::unblock_user instead.
+ - core_message_external::create_contacts, please use core_message_external::create_contact_request instead.
=== 3.5 ===
// Submissions are included if all are true:
// - The assignment is visible in the gradebook.
// - No previous notification has been sent.
+ // - The grader was a real user, not an automated process.
// - If marking workflow is not enabled, the grade was updated in the past 24 hours, or
// if marking workflow is enabled, the workflow state is at 'released'.
$sql = "SELECT g.id as gradeid, a.course, a.name, a.blindmarking, a.revealidentities,
LEFT JOIN {assign_user_mapping} um ON g.id = um.userid AND um.assignment = a.id
WHERE ((a.markingworkflow = 0 AND g.timemodified >= :yesterday AND g.timemodified <= :today) OR
(a.markingworkflow = 1 AND uf.workflowstate = :wfreleased)) AND
- uf.mailed = 0 AND gri.hidden = 0
+ g.grader > 0 AND uf.mailed = 0 AND gri.hidden = 0
ORDER BY a.course, cm.id";
$params = array(
$grade->timemodified = $grade->timecreated;
}
$grade->grade = -1;
- $grade->grader = $USER->id;
+ // Do not set the grader id here as it would be the admin users which is incorrect.
+ $grade->grader = -1;
if ($attemptnumber >= 0) {
$grade->attemptnumber = $attemptnumber;
}
$gradefordisplay = $this->display_grade($gradebookgrade->grade, false);
}
$gradeddate = $gradebookgrade->dategraded;
- if (isset($grade->grader)) {
+ if (isset($grade->grader) && $grade->grader > 0) {
$grader = $DB->get_record('user', array('id' => $grade->grader));
+ } else if (isset($gradebookgrade->usermodified) && $gradebookgrade->usermodified > 0) {
+ $grader = $DB->get_record('user', array('id' => $gradebookgrade->usermodified));
}
}
// First lookup the grader info.
if (isset($gradercache[$grade->grader])) {
$grade->grader = $gradercache[$grade->grader];
- } else {
+ } else if ($grade->grader > 0) {
// Not in cache - need to load the grader record.
$grade->grader = $DB->get_record('user', array('id'=>$grade->grader));
- $gradercache[$grade->grader->id] = $grade->grader;
+ if ($grade->grader) {
+ $gradercache[$grade->grader->id] = $grade->grader;
+ }
}
// Now get the gradefordisplay.
$assign->get_user_grade($student->id, true);
// Set the grade to something errant.
+ // We don't set the grader here, so we expect it to be -1 as a result.
$DB->set_field(
'assign_grades',
'grade',
// Check that the gradebook was updated with the assign grade. So we can guarentee test results later on.
$expectedgrade = $grade == -1 ? null : $grade; // Assign sends null to the gradebook for -1 grades.
$gradegrade = grade_grade::fetch(array('userid' => $student->id, 'itemid' => $assign->get_grade_item()->id));
+ $this->assertEquals(-1, $gradegrade->usermodified);
$this->assertEquals($expectedgrade, $gradegrade->rawgrade);
// Call fix_null_grades().
$gradegrade = grade_grade::fetch(array('userid' => $student->id, 'itemid' => $assign->get_grade_item()->id));
+ $this->assertEquals(-1, $gradegrade->usermodified);
+ $this->assertEquals($gradebookvalue, $gradegrade->finalgrade);
+
// Check that the grade was updated in the gradebook by fix_null_grades.
$this->assertEquals($gradebookvalue, $gradegrade->finalgrade);
}
}
$allnames = get_all_user_name_fields(true, 'u');
- $sql = "SELECT $postdata, d.name, d.timemodified, d.usermodified, d.groupid, d.timestart, d.timeend, d.pinned, $allnames,
- u.email, u.picture, u.imagealt $umfields
+ $sql = "SELECT $postdata, d.name, d.timemodified, d.usermodified, d.groupid, d.timestart, d.timeend, d.pinned, p.created,
+ $allnames, u.email, u.picture, u.imagealt $umfields
FROM {forum_discussions} d
JOIN {forum_posts} p ON p.discussion = d.id
JOIN {user} u ON p.userid = u.id
$output .= html_writer::div($postsubject, 'subject', ['role' => 'heading', 'aria-level' => '2']);
if ($authorhidden) {
- $bytext = userdate($post->modified);
+ $bytext = userdate($post->created);
} else {
$by = new stdClass();
- $by->date = userdate($post->modified);
+ $by->date = userdate($post->created);
$by->name = html_writer::link($postuser->profilelink, $postuser->fullname);
$bytext = get_string('bynameondate', 'forum', $by);
}
}
echo '<td class="lastpost">';
- $usedate = (empty($post->timemodified)) ? $post->modified : $post->timemodified; // Just in case
+ $usedate = (empty($post->created)) ? $post->timemodified : $post->created;
$parenturl = '';
$usermodified = new stdClass();
$usermodified->id = $post->usermodified;
--- /dev/null
+<svg width="32" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" height="32"><path d="M8 2.4l8 5.1-8 5.1-8-5.1 8-5.1zm16 0l8 5.1-8 5.1-8-5.1 8-5.1zM0 17.7l8-5.1 8 5.1-8 5.1-8-5.1zm24-5.1l8 5.1-8 5.1-8-5.1 8-5.1zM8 24.5l8-5.1 8 5.1-8 5.1-8-5.1z" fill="#0062FF"/></svg>
\ No newline at end of file
defined('MOODLE_INTERNAL') || die();
-$version = 2018092700.01; // YYYYMMDD = weekly release date of this DEV branch.
+$version = 2018092800.05; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.