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;
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.