Merge branch 'MDL-72586-master' of git://github.com/dpalou/moodle

This commit is contained in:
Andrew Nicols 2021-10-15 10:23:15 +08:00
commit 8d5d300047
6 changed files with 273 additions and 31 deletions

View File

@ -1492,6 +1492,12 @@ $functions = array(
'ajax' => true,
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),
'core_message_get_unread_notification_count' => [
'classname' => '\core_message\external\get_unread_notification_count',
'description' => 'Get number of unread notifications.',
'type' => 'read',
'services' => [MOODLE_OFFICIAL_MOBILE_SERVICE],
],
'core_notes_create_notes' => array(
'classname' => 'core_notes_external',
'methodname' => 'create_notes',

View File

@ -0,0 +1,99 @@
<?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/>.
namespace core_message\external;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->libdir . '/externallib.php');
require_once($CFG->dirroot . '/message/lib.php');
use external_api;
use external_function_parameters;
use external_value;
use context_system;
use core_user;
use moodle_exception;
/**
* External service to get number of unread notifications
*
* @package core_message
* @category external
* @copyright 2021 Dani Palou <dani@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 4.0
*/
class get_unread_notification_count extends external_api {
/**
* Returns description of method parameters
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'useridto' => new external_value(PARAM_INT, 'user id who received the notification, 0 for any user', VALUE_REQUIRED),
]);
}
/**
* Get number of unread notifications.
*
* @param int $useridto the user id who received the notification, 0 for any user
* @return int number of unread notifications
* @throws \moodle_exception
*/
public static function execute(int $useridto): int {
global $USER;
$params = self::validate_parameters(
self::execute_parameters(),
['useridto' => $useridto],
);
$context = context_system::instance();
self::validate_context($context);
$useridto = $params['useridto'];
if (!empty($useridto)) {
if (core_user::is_real_user($useridto)) {
$userto = core_user::get_user($useridto, '*', MUST_EXIST);
} else {
throw new moodle_exception('invaliduser');
}
}
// Check if the current user is the sender/receiver or just a privileged user.
if ($useridto != $USER->id and !has_capability('moodle/site:readallmessages', $context)) {
throw new moodle_exception('accessdenied', 'admin');
}
$messages = message_get_messages($useridto, 0, 1, MESSAGE_GET_UNREAD);
return count($messages);
}
/**
* Describe the return structure of the external service.
*
* @return external_value
*/
public static function execute_returns(): external_value {
return new external_value(PARAM_INT, 'The count of unread notifications.');
}
}

View File

@ -58,4 +58,70 @@ class helper {
$record->timecreated = $time;
return $DB->insert_record('messages', $record);
}
/**
* Send a fake unread notification.
*
* message_send() does not support transaction, this function will simulate a message
* sent from a user to another. We should stop using it once message_send() will support
* transactions. This is not clean at all, this is just used to add rows to the table.
*
* @param stdClass $userfrom user object of the one sending the message.
* @param stdClass $userto user object of the one receiving the message.
* @param string $message message to send.
* @param int $timecreated time the message was created.
* @return int the id of the message
*/
public static function send_fake_unread_notification(\stdClass $userfrom, \stdClass $userto, string $message = 'Hello world!',
int $timecreated = 0): int {
global $DB;
$record = new \stdClass();
$record->useridfrom = $userfrom->id;
$record->useridto = $userto->id;
$record->notification = 1;
$record->subject = 'No subject';
$record->fullmessage = $message;
$record->smallmessage = $message;
$record->timecreated = $timecreated ? $timecreated : time();
$record->customdata = json_encode(['datakey' => 'data']);
return $DB->insert_record('notifications', $record);
}
/**
* Send a fake read notification.
*
* message_send() does not support transaction, this function will simulate a message
* sent from a user to another. We should stop using it once message_send() will support
* transactions. This is not clean at all, this is just used to add rows to the table.
*
* @param stdClass $userfrom user object of the one sending the message.
* @param stdClass $userto user object of the one receiving the message.
* @param string $message message to send.
* @param int $timecreated time the message was created.
* @param int $timeread the the message was read
* @return int the id of the message
*/
public static function send_fake_read_notification(\stdClass $userfrom, \stdClass $userto, string $message = 'Hello world!',
int $timecreated = 0, int $timeread = 0): int {
global $DB;
$record = new \stdClass();
$record->useridfrom = $userfrom->id;
$record->useridto = $userto->id;
$record->notification = 1;
$record->subject = 'No subject';
$record->fullmessage = $message;
$record->smallmessage = $message;
$record->timecreated = $timecreated ? $timecreated : time();
$record->timeread = $timeread ? $timeread : time();
$record->id = $DB->insert_record('notifications', $record);
// Mark it as read.
\core_message\api::mark_notification_as_read($record);
return $record->id;
}
}

View File

@ -24,7 +24,10 @@
defined('MOODLE_INTERNAL') || die();
use \core_message\tests\helper as testhelper;
trait message_popup_test_helper {
/**
* Send a fake unread popup notification.
*
@ -38,20 +41,11 @@ trait message_popup_test_helper {
* @param int $timecreated time the message was created.
* @return int the id of the message
*/
protected function send_fake_unread_popup_notification($userfrom, $userto, $message = 'Hello world!', $timecreated = 0) {
protected function send_fake_unread_popup_notification(\stdClass $userfrom, \stdClass $userto,
string $message = 'Hello world!', int $timecreated = 0): int {
global $DB;
$record = new stdClass();
$record->useridfrom = $userfrom->id;
$record->useridto = $userto->id;
$record->notification = 1;
$record->subject = 'No subject';
$record->fullmessage = $message;
$record->smallmessage = $message;
$record->timecreated = $timecreated ? $timecreated : time();
$record->customdata = json_encode(['datakey' => 'data']);
$id = $DB->insert_record('notifications', $record);
$id = testhelper::send_fake_unread_notification($userfrom, $userto, $message, $timecreated);
$popup = new stdClass();
$popup->notificationid = $id;
@ -75,29 +69,16 @@ trait message_popup_test_helper {
* @param int $timeread the the message was read
* @return int the id of the message
*/
protected function send_fake_read_popup_notification($userfrom, $userto, $message = 'Hello world!',
$timecreated = 0, $timeread = 0) {
protected function send_fake_read_popup_notification(\stdClass $userfrom, \stdClass $userto, string $message = 'Hello world!',
int $timecreated = 0, int $timeread = 0): int {
global $DB;
$record = new stdClass();
$record->useridfrom = $userfrom->id;
$record->useridto = $userto->id;
$record->notification = 1;
$record->subject = 'No subject';
$record->fullmessage = $message;
$record->smallmessage = $message;
$record->timecreated = $timecreated ? $timecreated : time();
$record->timeread = $timeread ? $timeread : time();
$record->id = $DB->insert_record('notifications', $record);
// Mark it as read.
\core_message\api::mark_notification_as_read($record);
$id = testhelper::send_fake_read_notification($userfrom, $userto, $message, $timecreated, $timeread);
$popup = new stdClass();
$popup->notificationid = $record->id;
$popup->notificationid = $id;
$DB->insert_record('message_popup_notifications', $popup);
return $record->id;
return $id;
}
}

View File

@ -0,0 +1,90 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_message\external;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
use external_api;
use externallib_advanced_testcase;
use \core_message\tests\helper as testhelper;
/**
* External function test for get_unread_notification_count.
*
* @package core_message
* @category test
* @copyright 2021 Dani Palou <dani@moodle.com>, based on Ryan Wyllie <ryan@moodle.com> code
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 4.0
*/
class get_unread_notification_count_test extends externallib_advanced_testcase {
/**
* get_unread_notification should throw an exception for an invalid user.
*/
public function test_get_unread_notification_count_invalid_user_exception(): void {
$this->resetAfterTest(true);
$this->expectException('moodle_exception');
$result = get_unread_notification_count::execute(-2132131);
}
/**
* get_unread_notification_count should throw exception if being requested for non-logged in user.
*/
public function test_get_unread_notification_count_access_denied_exception(): void {
$this->resetAfterTest(true);
$sender = $this->getDataGenerator()->create_user();
$user = $this->getDataGenerator()->create_user();
$this->setUser($user);
$this->expectException('moodle_exception');
$result = get_unread_notification_count::execute($sender->id);
}
/**
* Test get_unread_notification_count.
*/
public function test_get_unread_notification_count(): void {
$this->resetAfterTest(true);
$sender1 = $this->getDataGenerator()->create_user();
$sender2 = $this->getDataGenerator()->create_user();
$sender3 = $this->getDataGenerator()->create_user();
$recipient = $this->getDataGenerator()->create_user();
$this->setUser($recipient);
$notificationids = [
testhelper::send_fake_unread_notification($sender1, $recipient, 'Notification', 1),
testhelper::send_fake_unread_notification($sender1, $recipient, 'Notification', 2),
testhelper::send_fake_unread_notification($sender2, $recipient, 'Notification', 3),
testhelper::send_fake_unread_notification($sender2, $recipient, 'Notification', 4),
testhelper::send_fake_unread_notification($sender3, $recipient, 'Notification', 5),
testhelper::send_fake_unread_notification($sender3, $recipient, 'Notification', 6),
];
$count = get_unread_notification_count::execute($recipient->id);
$this->assertEquals($count, 6);
}
}

View File

@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die();
$version = 2021101300.01; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2021101500.00; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.
$release = '4.0dev+ (Build: 20211013)'; // Human-friendly version name