mirror of
https://github.com/moodle/moodle.git
synced 2025-04-13 04:22:07 +02:00
MDL-77576 core_communication: Add core communication api
This commit will implement the base api for core communication. This will include the room creation, room membership, room access url and all associated api and related interfaces. Originally implemented as MDL-76702, MDL-76703 and MDL-76705. Co-Authored-By: David Woloszyn <david.woloszyn@moodle.com> Co-Authored-By: Safat Shahin <safat.shahin@moodle.com>
This commit is contained in:
parent
e703bdeb0a
commit
ca1e5d0beb
402
communication/classes/api.php
Normal file
402
communication/classes/api.php
Normal file
@ -0,0 +1,402 @@
|
||||
<?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_communication;
|
||||
|
||||
use core_communication\task\add_members_to_room_task;
|
||||
use core_communication\task\create_and_configure_room_task;
|
||||
use core_communication\task\delete_room_task;
|
||||
use core_communication\task\remove_members_from_room;
|
||||
use core_communication\task\update_room_task;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Class api is the public endpoint of the communication api. This class is the point of contact for api usage.
|
||||
*
|
||||
* Communication api allows to add ad-hoc tasks to the queue to perform actions on the communication providers. This api will
|
||||
* not allow any immediate actions to be performed on the communication providers. It will only add the tasks to the queue. The
|
||||
* exception has been made for deletion of members in case of deleting the user. This is because the user will not be available.
|
||||
* The member management api part allows run actions immediately if required.
|
||||
*
|
||||
* Communication api does allow to have form elements related to communication api in the required forms. This is done by using
|
||||
* the form_definition method. This method will add the form elements to the form.
|
||||
*
|
||||
* @package core_communication
|
||||
* @copyright 2023 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class api {
|
||||
|
||||
/**
|
||||
* @var null|processor $communication The communication settings object
|
||||
*/
|
||||
private ?processor $communication;
|
||||
|
||||
/**
|
||||
* Communication handler constructor to manage and handle all communication related actions.
|
||||
*
|
||||
* This class is the entrypoint for all kinda usages.
|
||||
* It will be used by the other api to manage the communication providers.
|
||||
*
|
||||
* @param string $component The component of the item for the instance
|
||||
* @param string $instancetype The type of the item for the instance
|
||||
* @param int $instanceid The id of the instance
|
||||
*
|
||||
*/
|
||||
private function __construct(
|
||||
private string $component,
|
||||
private string $instancetype,
|
||||
private int $instanceid
|
||||
) {
|
||||
$this->communication = processor::load_by_instance(
|
||||
$this->component,
|
||||
$this->instancetype,
|
||||
$this->instanceid,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the communication processor object.
|
||||
*
|
||||
* @param string $component The component of the item for the instance
|
||||
* @param string $instancetype The type of the item for the instance
|
||||
* @param int $instanceid The id of the instance
|
||||
* @return api
|
||||
*/
|
||||
public static function load_by_instance(
|
||||
string $component,
|
||||
string $instancetype,
|
||||
int $instanceid
|
||||
): self {
|
||||
return new self($component, $instancetype, $instanceid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the communication api is enabled.
|
||||
*/
|
||||
public static function is_available(): bool {
|
||||
return (bool) get_config('core', 'enablecommunicationsubsystem');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the communication room url.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_communication_room_url(): ?string {
|
||||
return $this->communication?->get_room_url();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of plugins for form selection.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_communication_plugin_list_for_form(): array {
|
||||
// Add the option to have communication disabled.
|
||||
$selection[processor::PROVIDER_NONE] = get_string('nocommunicationselected', 'communication');
|
||||
$communicationplugins = \core\plugininfo\communication::get_enabled_plugins();
|
||||
foreach ($communicationplugins as $pluginname => $notusing) {
|
||||
$selection['communication_' . $pluginname] = get_string('pluginname', 'communication_'. $pluginname);
|
||||
}
|
||||
return $selection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the form elements for the communication api.
|
||||
* This method will be called from the form definition method of the instance.
|
||||
*
|
||||
* @param \MoodleQuickForm $mform The form element
|
||||
*/
|
||||
public function form_definition(\MoodleQuickForm $mform): void {
|
||||
$mform->addElement('header', 'communication', get_string('communication', 'communication'));
|
||||
|
||||
// List the communication providers.
|
||||
$communicationproviders = self::get_communication_plugin_list_for_form();
|
||||
$mform->addElement(
|
||||
'select',
|
||||
'selectedcommunication',
|
||||
get_string('seleccommunicationprovider', 'communication'),
|
||||
$communicationproviders);
|
||||
$mform->addHelpButton('selectedcommunication', 'seleccommunicationprovider', 'communication');
|
||||
$mform->setDefault('selectedcommunication', processor::PROVIDER_NONE);
|
||||
|
||||
// Room name for the communication provider.
|
||||
$mform->addElement('text',
|
||||
'communicationroomname',
|
||||
get_string('communicationroomname', 'communication'),
|
||||
'maxlength="100" size="20"');
|
||||
$mform->addHelpButton('communicationroomname', 'communicationroomname', 'communication');
|
||||
$mform->setType('communicationroomname', PARAM_TEXT);
|
||||
$mform->hideIf(
|
||||
'communicationroomname',
|
||||
'selectedcommunication',
|
||||
'eq',
|
||||
processor::PROVIDER_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the avatar file record for the avatar for filesystem.
|
||||
*
|
||||
* @param string $filename The filename of the avatar
|
||||
* @return stdClass
|
||||
*/
|
||||
public function get_avatar_filerecord(string $filename): stdClass {
|
||||
return (object) [
|
||||
'contextid' => \context_system::instance()->id,
|
||||
'component' => 'core_communication',
|
||||
'filearea' => 'avatar',
|
||||
'filename' => $filename,
|
||||
'filepath' => '/',
|
||||
'itemid' => $this->communication->get_id(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Get the avatar file.
|
||||
*
|
||||
* If null is set, then delete the old area file and set the avatarfilename to null.
|
||||
* This will make sure the plugin api deletes the avatar from the room.
|
||||
*
|
||||
* @param string|null $datauri The datauri of the avatar
|
||||
* @return bool
|
||||
*/
|
||||
public function set_avatar_from_datauri_or_filepath(?string $datauri): bool {
|
||||
global $DB;
|
||||
|
||||
$currentfilename = $DB->get_field('communication', 'avatarfilename', ['id' => $this->communication->get_id()]);
|
||||
if (empty($datauri) && empty($currentfilename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$currentfilerecord = $this->communication->get_avatar();
|
||||
if (!empty($datauri) && !empty($currentfilerecord)) {
|
||||
$currentfilehash = $currentfilerecord->get_contenthash();
|
||||
$updatedfilehash = \file_storage::hash_from_string(file_get_contents($datauri));
|
||||
|
||||
// No update required.
|
||||
if ($currentfilehash === $updatedfilehash) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$context = \context_system::instance();
|
||||
$filename = null;
|
||||
|
||||
$fs = get_file_storage();
|
||||
$fs->delete_area_files(
|
||||
$context->id,
|
||||
'core_communication',
|
||||
'avatar',
|
||||
$this->communication->get_id()
|
||||
);
|
||||
|
||||
if (!empty($datauri)) {
|
||||
$filename = "avatar.svg";
|
||||
$fs->create_file_from_string($this->get_avatar_filerecord($filename), file_get_contents($datauri));
|
||||
}
|
||||
|
||||
$DB->set_field('communication', 'avatarfilename', $filename, ['id' => $this->communication->get_id()]);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the form data if the data is already available.
|
||||
*
|
||||
* @param \stdClass $instance The instance object
|
||||
*/
|
||||
public function set_data(\stdClass $instance): void {
|
||||
if (!empty($instance->id) && $this->communication) {
|
||||
$instance->selectedcommunication = $this->communication->get_provider();
|
||||
$instance->communicationroomname = $this->communication->get_room_name();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the communication provider.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_provider(): string {
|
||||
if (!$this->communication) {
|
||||
return '';
|
||||
}
|
||||
return $this->communication->get_provider();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a communication ad-hoc task for create operation.
|
||||
* This method will add a task to the queue to create the room.
|
||||
*
|
||||
* @param string $selectedcommunication The selected communication provider
|
||||
* @param string $communicationroomname The communication room name
|
||||
* @param string|null $avatarurl The avatar url
|
||||
*/
|
||||
public function create_and_configure_room(
|
||||
string $selectedcommunication,
|
||||
string $communicationroomname,
|
||||
?string $avatarurl = null,
|
||||
): void {
|
||||
|
||||
if ($selectedcommunication !== processor::PROVIDER_NONE && $selectedcommunication !== '') {
|
||||
// Create communication record.
|
||||
$this->communication = processor::create_instance(
|
||||
$selectedcommunication,
|
||||
$this->instanceid,
|
||||
$this->component,
|
||||
$this->instancetype,
|
||||
$communicationroomname,
|
||||
);
|
||||
|
||||
// Set the avatar.
|
||||
if (!empty($avatarurl)) {
|
||||
$this->set_avatar_from_datauri_or_filepath($avatarurl);
|
||||
}
|
||||
|
||||
// Add ad-hoc task to create the provider room.
|
||||
create_and_configure_room_task::queue(
|
||||
$this->communication,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a communication ad-hoc task for update operation.
|
||||
* This method will add a task to the queue to update the room.
|
||||
*
|
||||
* @param string $selectedprovider The selected communication provider
|
||||
* @param string $communicationroomname The communication room name
|
||||
* @param string|null $avatarurl The avatar url
|
||||
*/
|
||||
public function update_room(
|
||||
string $selectedprovider,
|
||||
string $communicationroomname,
|
||||
?string $avatarurl = null,
|
||||
): void {
|
||||
|
||||
// Existing object found, let's update the communication record and associated actions.
|
||||
if ($this->communication !== null) {
|
||||
// Get the previous data to compare for update.
|
||||
$previousroomname = $this->communication->get_room_name();
|
||||
$previousprovider = $this->communication->get_provider();
|
||||
|
||||
// Update communication record.
|
||||
$this->communication->update_instance($selectedprovider, $communicationroomname);
|
||||
|
||||
// Update the avatar.
|
||||
$imageupdaterequired = $this->set_avatar_from_datauri_or_filepath($avatarurl);
|
||||
|
||||
// If the provider is none, we don't need to do anything from room point of view.
|
||||
if ($this->communication->get_provider() === processor::PROVIDER_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add ad-hoc task to update the provider room if the room name changed.
|
||||
if (
|
||||
$previousprovider === $selectedprovider &&
|
||||
($previousroomname !== $communicationroomname || $imageupdaterequired)
|
||||
) {
|
||||
update_room_task::queue(
|
||||
$this->communication,
|
||||
);
|
||||
} else if (
|
||||
$previousprovider !== $selectedprovider
|
||||
) {
|
||||
// Add ad-hoc task to create the provider room.
|
||||
create_and_configure_room_task::queue(
|
||||
$this->communication,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// The instance didn't have any communication record, so create one.
|
||||
$this->create_and_configure_room($selectedprovider, $communicationroomname, $avatarurl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a communication ad-hoc task for delete operation.
|
||||
* This method will add a task to the queue to delete the room.
|
||||
*/
|
||||
public function delete_room(): void {
|
||||
if ($this->communication !== null) {
|
||||
// Add the ad-hoc task to remove the room data from the communication table and associated provider actions.
|
||||
delete_room_task::queue(
|
||||
$this->communication,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a communication ad-hoc task for add members operation and add the user mapping.
|
||||
*
|
||||
* This method will add a task to the queue to add the room users.
|
||||
*
|
||||
* @param array $userids The user ids to add to the room
|
||||
* @param bool $queue Whether to queue the task or not
|
||||
*/
|
||||
public function add_members_to_room(array $userids, bool $queue = true): void {
|
||||
// No communication object? something not done right.
|
||||
if (!$this->communication) {
|
||||
return;
|
||||
}
|
||||
|
||||
// No userids? don't bother doing anything.
|
||||
if (empty($userids)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->communication->create_instance_user_mapping($userids);
|
||||
|
||||
if ($queue) {
|
||||
add_members_to_room_task::queue(
|
||||
$this->communication
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a communication ad-hoc task for remove members operation or action immediately.
|
||||
*
|
||||
* This method will add a task to the queue to remove the room users.
|
||||
*
|
||||
* @param array $userids The user ids to remove from the room
|
||||
* @param bool $queue Whether to queue the task or not
|
||||
*/
|
||||
public function remove_members_from_room(array $userids, bool $queue = true): void {
|
||||
// No communication object? something not done right.
|
||||
if (!$this->communication) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->communication->get_provider() === processor::PROVIDER_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// No user ids? don't bother doing anything.
|
||||
if (empty($userids)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->communication->add_delete_user_flag($userids);
|
||||
|
||||
if ($queue) {
|
||||
remove_members_from_room::queue(
|
||||
$this->communication
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
38
communication/classes/communication_provider.php
Normal file
38
communication/classes/communication_provider.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?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_communication;
|
||||
|
||||
/**
|
||||
* A base communication provider.
|
||||
*
|
||||
* This interface should be used to declare support for the instantiation method for communication providers.
|
||||
*
|
||||
* Every communication provider must, as a minimum, implement this provider.
|
||||
*
|
||||
* @package core_communication
|
||||
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
interface communication_provider {
|
||||
|
||||
/**
|
||||
* A base communication provider.
|
||||
*
|
||||
* @param processor $communication The communication object
|
||||
*/
|
||||
public static function load_for_instance(processor $communication): self;
|
||||
}
|
563
communication/classes/processor.php
Normal file
563
communication/classes/processor.php
Normal file
@ -0,0 +1,563 @@
|
||||
<?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_communication;
|
||||
|
||||
use stdClass;
|
||||
use stored_file;
|
||||
|
||||
/**
|
||||
* Class processor to manage the base operations of the providers.
|
||||
*
|
||||
* This class is responsible for creating, updating, deleting and loading the communication instance, associated actions.
|
||||
*
|
||||
* @package core_communication
|
||||
* @copyright 2023 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class processor {
|
||||
|
||||
/** @var string The magic 'none' provider */
|
||||
public const PROVIDER_NONE = 'none';
|
||||
|
||||
/** @var int The provider active flag */
|
||||
public const PROVIDER_ACTIVE = 1;
|
||||
|
||||
/** @var int The provider inactive flag */
|
||||
public const PROVIDER_INACTIVE = 0;
|
||||
|
||||
/** @var null|communication_provider|user_provider|room_chat_provider|room_user_provider The provider class */
|
||||
private communication_provider|user_provider|room_chat_provider|room_user_provider|null $provider = null;
|
||||
|
||||
/**
|
||||
* Communication processor constructor.
|
||||
*
|
||||
* @param stdClass $instancedata The instance data object
|
||||
*/
|
||||
protected function __construct(
|
||||
private stdClass $instancedata,
|
||||
) {
|
||||
$providercomponent = $this->instancedata->provider;
|
||||
if (!\core\plugininfo\communication::is_plugin_enabled($providercomponent)) {
|
||||
throw new \moodle_exception('communicationproviderdisabled', 'core_communication', '', $providercomponent);
|
||||
}
|
||||
$providerclass = $this->get_classname_for_provider($providercomponent);
|
||||
if (!class_exists($providerclass)) {
|
||||
throw new \moodle_exception('communicationproviderclassnotfound', 'core_communication', '', $providerclass);
|
||||
}
|
||||
|
||||
if (!is_a($providerclass, communication_provider::class, true)) {
|
||||
// At the moment we only have one communication provider interface.
|
||||
// In the future, we may have others, at which point we will support the newest first and
|
||||
// emit a debugging notice for older ones.
|
||||
throw new \moodle_exception('communicationproviderclassinvalid', 'core_communication', '', $providerclass);
|
||||
}
|
||||
|
||||
$this->provider = $providerclass::load_for_instance($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create communication instance.
|
||||
*
|
||||
* @param string $provider The communication provider
|
||||
* @param int $instanceid The instance id
|
||||
* @param string $component The component name
|
||||
* @param string $instancetype The instance type
|
||||
* @param string $roomname The room name
|
||||
* @return processor|null
|
||||
*/
|
||||
public static function create_instance(
|
||||
string $provider,
|
||||
int $instanceid,
|
||||
string $component,
|
||||
string $instancetype,
|
||||
string $roomname,
|
||||
): ?self {
|
||||
global $DB;
|
||||
|
||||
if ($provider === self::PROVIDER_NONE) {
|
||||
return null;
|
||||
}
|
||||
$record = (object) [
|
||||
'provider' => $provider,
|
||||
'instanceid' => $instanceid,
|
||||
'component' => $component,
|
||||
'instancetype' => $instancetype,
|
||||
'roomname' => $roomname,
|
||||
'avatarfilename' => null,
|
||||
'active' => self::PROVIDER_ACTIVE,
|
||||
];
|
||||
$record->id = $DB->insert_record('communication', $record);
|
||||
|
||||
return new self($record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update communication instance.
|
||||
*
|
||||
* @param string $provider The communication provider
|
||||
* @param string $roomname The room name
|
||||
*/
|
||||
public function update_instance(
|
||||
string $provider,
|
||||
string $roomname,
|
||||
): void {
|
||||
|
||||
global $DB;
|
||||
if ($provider === self::PROVIDER_NONE) {
|
||||
$this->instancedata->active = self::PROVIDER_INACTIVE;
|
||||
} else {
|
||||
$this->instancedata->provider = $provider;
|
||||
$this->instancedata->active = self::PROVIDER_ACTIVE;
|
||||
}
|
||||
$this->instancedata->roomname = $roomname;
|
||||
|
||||
$DB->update_record('communication', $this->instancedata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete communication data.
|
||||
*/
|
||||
public function delete_instance(): void {
|
||||
global $DB;
|
||||
$DB->delete_records('communication', ['id' => $this->instancedata->id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get non synced instance user ids for the instance.
|
||||
*
|
||||
* @param bool $synced The synced status
|
||||
* @param bool $deleted The deleted status
|
||||
* @return array
|
||||
*/
|
||||
public function get_instance_userids(bool $synced = false, bool $deleted = false): array {
|
||||
global $DB;
|
||||
return $DB->get_fieldset_select(
|
||||
'communication_user',
|
||||
'userid',
|
||||
'commid = ? AND synced = ? AND deleted = ?',
|
||||
[$this->instancedata->id, (int) $synced, (int) $deleted]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get existing instance user ids.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_all_userids_for_instance(): array {
|
||||
global $DB;
|
||||
return $DB->get_fieldset_select(
|
||||
'communication_user',
|
||||
'userid',
|
||||
'commid = ?',
|
||||
[$this->instancedata->id]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create communication user record for mapping and sync.
|
||||
*
|
||||
* @param array $userids The user ids
|
||||
*/
|
||||
public function create_instance_user_mapping(array $userids): void {
|
||||
global $DB;
|
||||
|
||||
// Check if user ids exits in existing user ids.
|
||||
$useridstoadd = array_diff($userids, $this->get_all_userids_for_instance());
|
||||
|
||||
foreach ($useridstoadd as $userid) {
|
||||
$record = (object) [
|
||||
'commid' => $this->instancedata->id,
|
||||
'userid' => $userid,
|
||||
];
|
||||
$DB->insert_record('communication_user', $record);
|
||||
}
|
||||
$this->mark_users_as_not_deleted($userids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark users as not deleted for the instance.
|
||||
*
|
||||
* @param array $userids The user ids
|
||||
*/
|
||||
public function mark_users_as_not_deleted(array $userids): void {
|
||||
global $DB;
|
||||
|
||||
if (empty($userids)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$DB->set_field_select(
|
||||
'communication_user',
|
||||
'deleted',
|
||||
0,
|
||||
'commid = ? AND userid IN (' . implode(',', $userids) . ')',
|
||||
[$this->instancedata->id]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark users as synced for the instance.
|
||||
*
|
||||
* @param array $userids The user ids
|
||||
*/
|
||||
public function mark_users_as_synced(array $userids): void {
|
||||
global $DB;
|
||||
|
||||
if (empty($userids)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$DB->set_field_select(
|
||||
'communication_user',
|
||||
'synced',
|
||||
1,
|
||||
'commid = ? AND userid IN (' . implode(',', $userids) . ')',
|
||||
[$this->instancedata->id]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset users sync flag for the instance.
|
||||
*
|
||||
* @param array $userids The user ids
|
||||
*/
|
||||
public function reset_users_sync_flag(array $userids): void {
|
||||
global $DB;
|
||||
|
||||
if (empty($userids)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$DB->set_field_select(
|
||||
'communication_user',
|
||||
'synced',
|
||||
0,
|
||||
'commid = ? AND userid IN (' . implode(',', $userids) . ')',
|
||||
[$this->instancedata->id]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete users flag for the instance users.
|
||||
*
|
||||
* @param array $userids The user ids
|
||||
*/
|
||||
public function add_delete_user_flag(array $userids): void {
|
||||
global $DB;
|
||||
|
||||
if (empty($userids)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$DB->set_field_select(
|
||||
'communication_user',
|
||||
'deleted',
|
||||
1,
|
||||
'commid = ? AND userid IN (' . implode(',', $userids) . ')',
|
||||
[$this->instancedata->id]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete communication user record for userid.
|
||||
*
|
||||
* @param array $userids The user ids
|
||||
*/
|
||||
public function delete_instance_user_mapping(array $userids): void {
|
||||
global $DB;
|
||||
|
||||
if (empty($userids)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$DB->delete_records_select(
|
||||
'communication_user',
|
||||
'commid = ? AND userid IN (' . implode(',', $userids) . ')',
|
||||
[$this->instancedata->id]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete communication user record for userid who are not synced.
|
||||
*
|
||||
* @param array $userids The user ids
|
||||
*/
|
||||
public function delete_instance_non_synced_user_mapping(array $userids): void {
|
||||
global $DB;
|
||||
|
||||
if (empty($userids)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$DB->delete_records_select(
|
||||
'communication_user',
|
||||
'commid = ? AND userid IN (' . implode(',', $userids) . ') AND synced = ?' ,
|
||||
[$this->instancedata->id, 0]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete communication user record for instance.
|
||||
*/
|
||||
public function delete_user_mappings_for_instance(): void {
|
||||
global $DB;
|
||||
$DB->delete_records('communication_user', [
|
||||
'commid' => $this->instancedata->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load communication instance by id.
|
||||
*
|
||||
* @param int $id The communication instance id
|
||||
* @return processor|null
|
||||
*/
|
||||
public static function load_by_id(int $id): ?self {
|
||||
global $DB;
|
||||
|
||||
if ($record = $DB->get_record('communication', ['id' => $id])) {
|
||||
return new self($record);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load communication instance by instance id.
|
||||
*
|
||||
* @param string $component The component name
|
||||
* @param string $instancetype The instance type
|
||||
* @param int $instanceid The instance id
|
||||
* @return processor|null
|
||||
*/
|
||||
public static function load_by_instance(
|
||||
string $component,
|
||||
string $instancetype,
|
||||
int $instanceid
|
||||
): ?self {
|
||||
|
||||
global $DB;
|
||||
|
||||
$record = $DB->get_record('communication', [
|
||||
'instanceid' => $instanceid,
|
||||
'component' => $component,
|
||||
'instancetype' => $instancetype,
|
||||
]);
|
||||
|
||||
if ($record) {
|
||||
return new self($record);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if communication instance is active.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_instance_active(): bool {
|
||||
return $this->instancedata->active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get communication provider class name.
|
||||
*
|
||||
* @param string $component The component name.
|
||||
* @return string
|
||||
*/
|
||||
private function get_classname_for_provider(string $component): string {
|
||||
return "{$component}\\communication_feature";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get communication instance id after creating the instance in communication table.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_id(): int {
|
||||
return $this->instancedata->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get communication instance id.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_component(): string {
|
||||
return $this->instancedata->component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get communication provider.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_provider(): ?string {
|
||||
// var_dump($this->instancedata);die;
|
||||
if ((int)$this->instancedata->active === self::PROVIDER_ACTIVE) {
|
||||
return $this->instancedata->provider;
|
||||
}
|
||||
return self::PROVIDER_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get room name.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_room_name(): ?string {
|
||||
return $this->instancedata->roomname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get communication instance id.
|
||||
*
|
||||
* @return room_chat_provider
|
||||
*/
|
||||
public function get_room_provider(): room_chat_provider {
|
||||
$this->require_api_enabled();
|
||||
$this->require_room_features();
|
||||
return $this->provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get communication instance id.
|
||||
*
|
||||
* @return user_provider
|
||||
*/
|
||||
public function get_user_provider(): user_provider {
|
||||
$this->require_api_enabled();
|
||||
$this->require_user_features();
|
||||
return $this->provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get communication instance id.
|
||||
*
|
||||
* @return room_user_provider
|
||||
*/
|
||||
public function get_room_user_provider(): room_user_provider {
|
||||
$this->require_api_enabled();
|
||||
$this->require_room_features();
|
||||
$this->require_room_user_features();
|
||||
return $this->provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get communication instance id.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function supports_user_features(): bool {
|
||||
return ($this->provider instanceof user_provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get communication instance id.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function supports_room_user_features(): bool {
|
||||
if (!$this->supports_user_features()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->supports_room_features()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ($this->provider instanceof room_user_provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get communication instance id.
|
||||
*/
|
||||
public function require_user_features(): void {
|
||||
if (!$this->supports_user_features()) {
|
||||
throw new \coding_exception('User features are not supported by the provider');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get communication instance id.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function supports_room_features(): bool {
|
||||
return ($this->provider instanceof room_chat_provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if communication api is enabled.
|
||||
*/
|
||||
public function require_api_enabled(): void {
|
||||
if (!api::is_available()) {
|
||||
throw new \coding_exception('Communication API is not enabled, please enable it from experimental features');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get communication instance id.
|
||||
*/
|
||||
public function require_room_features(): void {
|
||||
if (!$this->supports_room_features()) {
|
||||
throw new \coding_exception('room features are not supported by the provider');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get communication instance id.
|
||||
*/
|
||||
public function require_room_user_features(): void {
|
||||
if (!$this->supports_room_user_features()) {
|
||||
throw new \coding_exception('room features are not supported by the provider');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get communication instance id.
|
||||
*
|
||||
* @return bool|\stored_file
|
||||
*/
|
||||
public function get_avatar(): ?stored_file {
|
||||
$fs = get_file_storage();
|
||||
$file = $fs->get_file(
|
||||
(\context_system::instance())->id,
|
||||
'core_communication',
|
||||
'avatar',
|
||||
$this->instancedata->id,
|
||||
'/',
|
||||
$this->instancedata->avatarfilename,
|
||||
);
|
||||
|
||||
return $file ? $file : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a room url.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_room_url(): ?string {
|
||||
if ($this->provider && $this->is_instance_active()) {
|
||||
return $this->get_room_provider()->get_chat_room_url();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
51
communication/classes/room_chat_provider.php
Normal file
51
communication/classes/room_chat_provider.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?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_communication;
|
||||
|
||||
/**
|
||||
* Class communication_room_base to manage the room operations of communication providers.
|
||||
*
|
||||
* Every plugin that supports room operation must implement/extend this class in the plugin.
|
||||
*
|
||||
* @package core_communication
|
||||
* @copyright 2023 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
interface room_chat_provider {
|
||||
|
||||
/**
|
||||
* Create a provider room when a instance is created.
|
||||
*/
|
||||
public function create_chat_room(): bool;
|
||||
|
||||
/**
|
||||
* Update a provider room when a instance is updated.
|
||||
*/
|
||||
public function update_chat_room(): bool;
|
||||
|
||||
/**
|
||||
* Delete a provider room when a instance is deleted.
|
||||
*/
|
||||
public function delete_chat_room(): bool;
|
||||
|
||||
/**
|
||||
* Generate a room url if there is a room.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_chat_room_url(): ?string;
|
||||
}
|
40
communication/classes/room_user_provider.php
Normal file
40
communication/classes/room_user_provider.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?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_communication;
|
||||
|
||||
/**
|
||||
* Class communication_user_base to manage communication provider users.
|
||||
*
|
||||
* @package core_communication
|
||||
* @copyright 2023 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
interface room_user_provider {
|
||||
/**
|
||||
* Add members to communication room.
|
||||
*
|
||||
* @param array $userids The user ids to be added
|
||||
*/
|
||||
public function add_members_to_room(array $userids): void;
|
||||
|
||||
/**
|
||||
* Remove members from room.
|
||||
*
|
||||
* @param array $userids The user ids to be removed
|
||||
*/
|
||||
public function remove_members_from_room(array $userids): void;
|
||||
}
|
64
communication/classes/task/add_members_to_room_task.php
Normal file
64
communication/classes/task/add_members_to_room_task.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?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_communication\task;
|
||||
|
||||
use core\task\adhoc_task;
|
||||
use core_communication\processor;
|
||||
|
||||
/**
|
||||
* Class add_members_to_room_task to add the task to add members to the room and execute the task to action the addition.
|
||||
*
|
||||
* @package core_communication
|
||||
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class add_members_to_room_task extends adhoc_task {
|
||||
|
||||
public function execute() {
|
||||
// Initialize the custom data operation to be used for the action.
|
||||
$data = $this->get_custom_data();
|
||||
|
||||
// Call the communication api to action the operation.
|
||||
$communication = processor::load_by_id($data->id);
|
||||
|
||||
if ($communication === null) {
|
||||
mtrace("Skipping room creation because the instance does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
$communication->get_room_user_provider()->add_members_to_room($communication->get_instance_userids());
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue the task for the next run.
|
||||
*
|
||||
* @param processor $communication The communication processor to perform the action on
|
||||
*/
|
||||
public static function queue(
|
||||
processor $communication
|
||||
): void {
|
||||
|
||||
// Add ad-hoc task to update the provider room.
|
||||
$task = new self();
|
||||
$task->set_custom_data([
|
||||
'id' => $communication->get_id()
|
||||
]);
|
||||
|
||||
// Queue the task for the next run.
|
||||
\core\task\manager::queue_adhoc_task($task);
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
<?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_communication\task;
|
||||
|
||||
use core\task\adhoc_task;
|
||||
use core_communication\processor;
|
||||
|
||||
/**
|
||||
* Class create_and_configure_room_task to add a task to create a room and execute the task to action the creation.
|
||||
*
|
||||
* this task will be queued by the communication api and will use the communication handler api to action the creation.
|
||||
*
|
||||
* @package core_communication
|
||||
* @copyright 2023 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class create_and_configure_room_task extends adhoc_task {
|
||||
|
||||
public function execute() {
|
||||
$data = $this->get_custom_data();
|
||||
|
||||
// Call the communication api to action the operation.
|
||||
$communication = processor::load_by_id($data->id);
|
||||
|
||||
if ($communication === null) {
|
||||
mtrace("Skipping room creation because the instance does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$communication->is_instance_active()) {
|
||||
mtrace("Skipping room creation because the instance is not active");
|
||||
return;
|
||||
}
|
||||
|
||||
// If the room is created successfully, add members to the room.
|
||||
if ($communication->get_room_provider()->create_chat_room()) {
|
||||
add_members_to_room_task::queue(
|
||||
$communication
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue the task for the next run.
|
||||
*
|
||||
* @param processor $communication The communication processor to perform the action on
|
||||
*/
|
||||
public static function queue(
|
||||
processor $communication,
|
||||
): void {
|
||||
|
||||
// Add ad-hoc task to update the provider room.
|
||||
$task = new self();
|
||||
$task->set_custom_data([
|
||||
'id' => $communication->get_id()
|
||||
]);
|
||||
|
||||
// Queue the task for the next run.
|
||||
\core\task\manager::queue_adhoc_task($task);
|
||||
}
|
||||
}
|
72
communication/classes/task/delete_room_task.php
Normal file
72
communication/classes/task/delete_room_task.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?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_communication\task;
|
||||
|
||||
use core\task\adhoc_task;
|
||||
use core_communication\processor;
|
||||
|
||||
/**
|
||||
* Class delete_room_task to add a task to delete a room and execute the task to action the deletion.
|
||||
*
|
||||
* this task will be queued by the communication api and will use the communication handler api to action the deletion.
|
||||
*
|
||||
* @package core_communication
|
||||
* @copyright 2023 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class delete_room_task extends adhoc_task {
|
||||
|
||||
public function execute() {
|
||||
$data = $this->get_custom_data();
|
||||
|
||||
$communication = processor::load_by_id($data->id);
|
||||
|
||||
if ($communication === null) {
|
||||
mtrace("Skipping room creation because the instance does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
// First remove the members from the room.
|
||||
$communication->get_room_user_provider()->remove_members_from_room($communication->get_instance_userids(true, true));
|
||||
// Now remove any mapping for users who are not in the room.
|
||||
$communication->delete_instance_non_synced_user_mapping($communication->get_instance_userids(false, true));
|
||||
|
||||
// Now delete the room.
|
||||
if ($communication->get_room_provider()->delete_chat_room()) {
|
||||
$communication->delete_instance();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue the task for the next run.
|
||||
*
|
||||
* @param processor $communication The communication processor to perform the action on
|
||||
*/
|
||||
public static function queue(
|
||||
processor $communication,
|
||||
): void {
|
||||
|
||||
// Add ad-hoc task to update the provider room.
|
||||
$task = new self();
|
||||
$task->set_custom_data([
|
||||
'id' => $communication->get_id()
|
||||
]);
|
||||
|
||||
// Queue the task for the next run.
|
||||
\core\task\manager::queue_adhoc_task($task);
|
||||
}
|
||||
}
|
67
communication/classes/task/remove_members_from_room.php
Normal file
67
communication/classes/task/remove_members_from_room.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?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_communication\task;
|
||||
|
||||
use core\task\adhoc_task;
|
||||
use core_communication\processor;
|
||||
|
||||
/**
|
||||
* Class remove_members_from_room to add the task to remove members to the room and execute the task to action the removal.
|
||||
*
|
||||
* @package core_communication
|
||||
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class remove_members_from_room extends adhoc_task {
|
||||
|
||||
public function execute() {
|
||||
// Initialize the custom data operation to be used for the action.
|
||||
$data = $this->get_custom_data();
|
||||
|
||||
// Call the communication api to action the operation.
|
||||
$communication = processor::load_by_id($data->id);
|
||||
|
||||
if ($communication === null) {
|
||||
mtrace("Skipping room creation because the instance does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
$communication->get_room_user_provider()->remove_members_from_room($communication->get_instance_userids(true, true));
|
||||
|
||||
// Now remove any mapping for users who are not in the room.
|
||||
$communication->delete_instance_non_synced_user_mapping($communication->get_instance_userids(false, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue the task for the next run.
|
||||
*
|
||||
* @param processor $communication The communication processor to perform the action on
|
||||
*/
|
||||
public static function queue(
|
||||
processor $communication
|
||||
): void {
|
||||
|
||||
// Add ad-hoc task to update the provider room.
|
||||
$task = new self();
|
||||
$task->set_custom_data([
|
||||
'id' => $communication->get_id()
|
||||
]);
|
||||
|
||||
// Queue the task for the next run.
|
||||
\core\task\manager::queue_adhoc_task($task);
|
||||
}
|
||||
}
|
65
communication/classes/task/update_room_task.php
Normal file
65
communication/classes/task/update_room_task.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?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_communication\task;
|
||||
|
||||
use core\task\adhoc_task;
|
||||
use core_communication\processor;
|
||||
|
||||
/**
|
||||
* Class update_room_task to add a task to update a room and execute the task to action the update.
|
||||
*
|
||||
* this task will be queued by the communication api and will use the communication handler api to action the updates.
|
||||
*
|
||||
* @package core_communication
|
||||
* @copyright 2023 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class update_room_task extends adhoc_task {
|
||||
|
||||
public function execute() {
|
||||
$data = $this->get_custom_data();
|
||||
|
||||
// Call the communication api to action the operation.
|
||||
$communication = processor::load_by_id($data->id);
|
||||
|
||||
if ($communication === null) {
|
||||
mtrace("Skipping room creation because the instance does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
$communication->get_room_provider()->update_chat_room();
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue the task for the next run.
|
||||
*
|
||||
* @param processor $communication The communication processor to perform the action on
|
||||
*/
|
||||
public static function queue(
|
||||
processor $communication,
|
||||
): void {
|
||||
|
||||
// Add ad-hoc task to update the provider room.
|
||||
$task = new self();
|
||||
$task->set_custom_data([
|
||||
'id' => $communication->get_id()
|
||||
]);
|
||||
|
||||
// Queue the task for the next run.
|
||||
\core\task\manager::queue_adhoc_task($task);
|
||||
}
|
||||
}
|
34
communication/classes/user_provider.php
Normal file
34
communication/classes/user_provider.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?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_communication;
|
||||
|
||||
/**
|
||||
* Class communication_user_base to manage communication provider users.
|
||||
*
|
||||
* @package core_communication
|
||||
* @copyright 2023 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
interface user_provider {
|
||||
|
||||
/**
|
||||
* Create members.
|
||||
*
|
||||
* @param array $userid The users ids to be created
|
||||
*/
|
||||
public function create_members(array $userid): void;
|
||||
}
|
61
communication/lib.php
Normal file
61
communication/lib.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Callback and library methods for core communication.
|
||||
*
|
||||
* @package core_communication
|
||||
* @copyright 2023 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Serve the files from the core_communication file areas.
|
||||
*
|
||||
* @param stdClass $course the course object
|
||||
* @param stdClass $cm the course module object
|
||||
* @param context $context the context
|
||||
* @param string $filearea the name of the file area
|
||||
* @param array $args extra arguments (itemid, path)
|
||||
* @param bool $forcedownload whether force download
|
||||
* @param array $options additional options affecting the file serving
|
||||
*/
|
||||
function core_communication_pluginfile(
|
||||
$course,
|
||||
$cm,
|
||||
$context,
|
||||
$filearea,
|
||||
$args,
|
||||
$forcedownload,
|
||||
array $options = []
|
||||
): void {
|
||||
|
||||
if ($filearea !== 'avatar') {
|
||||
return;
|
||||
}
|
||||
|
||||
$itemid = array_shift($args);
|
||||
$filename = array_pop($args);
|
||||
|
||||
// Retrieve the file from the Files API.
|
||||
$fs = get_file_storage();
|
||||
$file = $fs->get_file($context->id, 'core_communication', $filearea, $itemid, '/', $filename);
|
||||
if (!$file) {
|
||||
return;
|
||||
}
|
||||
|
||||
send_file($file, $filename);
|
||||
}
|
315
communication/tests/api_test.php
Normal file
315
communication/tests/api_test.php
Normal file
@ -0,0 +1,315 @@
|
||||
<?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_communication;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once(__DIR__ . '/communication_test_helper_trait.php');
|
||||
|
||||
/**
|
||||
* Class api_test to test the communication public api and its associated methods.
|
||||
*
|
||||
* @package core_communication
|
||||
* @category test
|
||||
* @copyright 2023 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \core_communication\api
|
||||
*/
|
||||
class api_test extends \advanced_testcase {
|
||||
|
||||
use communication_test_helper_trait;
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
$this->resetAfterTest();
|
||||
$this->setup_communication_configs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the communication plugin list for the form element returns the correct number of plugins.
|
||||
*
|
||||
* @covers ::get_communication_plugin_list_for_form
|
||||
*/
|
||||
public function test_get_communication_plugin_list_for_form(): void {
|
||||
$communicationplugins = \core_communication\api::get_communication_plugin_list_for_form();
|
||||
// Get the communication plugins.
|
||||
$plugins = \core_component::get_plugin_list('communication');
|
||||
// Check the number of plugins matches plus 1 as we have none in the selection.
|
||||
$this->assertCount(count($plugins) + 1, $communicationplugins);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set data to the instance.
|
||||
*
|
||||
* @covers ::set_data
|
||||
*/
|
||||
public function test_set_data(): void {
|
||||
$course = $this->get_course();
|
||||
|
||||
$communication = \core_communication\api::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
// Sample data.
|
||||
$roomname = 'Sampleroom';
|
||||
$provider = 'communication_matrix';
|
||||
|
||||
// Set the data.
|
||||
$communication->set_data($course);
|
||||
|
||||
// Test the set data.
|
||||
$this->assertEquals($roomname, $course->communicationroomname);
|
||||
$this->assertEquals($provider, $course->selectedcommunication);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_current_communication_provider method.
|
||||
*
|
||||
* @covers ::get_provider
|
||||
*/
|
||||
public function test_get_provider(): void {
|
||||
$course = $this->get_course();
|
||||
|
||||
$communication = \core_communication\api::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertEquals('communication_matrix', $communication->get_provider());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_avatar_filerecord method.
|
||||
*
|
||||
* @covers ::get_avatar_filerecord
|
||||
*/
|
||||
public function test_get_avatar_filerecord(): void {
|
||||
$course = $this->get_course();
|
||||
|
||||
$communication = \core_communication\api::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
$filerecord = $communication->get_avatar_filerecord('avatar.svg');
|
||||
|
||||
$this->assertEquals('avatar.svg', $filerecord->filename);
|
||||
$this->assertEquals('core_communication', $filerecord->component);
|
||||
$this->assertEquals('avatar', $filerecord->filearea);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set_avatar_from_datauri method.
|
||||
*
|
||||
* @covers ::set_avatar_from_datauri_or_filepath
|
||||
* @covers ::get_avatar_filerecord
|
||||
*/
|
||||
public function test_set_avatar_from_datauri_or_filepath(): void {
|
||||
global $CFG;
|
||||
$course = $this->get_course('Sampleroom', 'none');
|
||||
|
||||
// Sample data.
|
||||
$communicationroomname = 'Sampleroom';
|
||||
$selectedcommunication = 'communication_matrix';
|
||||
$avatarurl = $CFG->dirroot . '/communication/tests/fixtures/moodle_logo.jpg';
|
||||
|
||||
$communication = \core_communication\api::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
$communication->create_and_configure_room($selectedcommunication, $communicationroomname, $avatarurl);
|
||||
|
||||
$communicationprocessor = processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertNotNull($communicationprocessor->get_avatar());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the create_and_configure_room method to add/create tasks.
|
||||
*
|
||||
* @covers ::create_and_configure_room
|
||||
*/
|
||||
public function test_create_and_configure_room(): void {
|
||||
// Get the course by disabling communication so that we can create it manually calling the api.
|
||||
$course = $this->get_course('Sampleroom', 'none');
|
||||
|
||||
// Sample data.
|
||||
$communicationroomname = 'Sampleroom';
|
||||
$selectedcommunication = 'communication_matrix';
|
||||
|
||||
$communication = \core_communication\api::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
$communication->create_and_configure_room($selectedcommunication, $communicationroomname);
|
||||
|
||||
// Test the tasks added.
|
||||
$adhoctask = \core\task\manager::get_adhoc_tasks('\\core_communication\\task\\create_and_configure_room_task');
|
||||
$this->assertCount(1, $adhoctask);
|
||||
|
||||
$adhoctask = reset($adhoctask);
|
||||
$this->assertInstanceOf('\\core_communication\\task\\create_and_configure_room_task', $adhoctask);
|
||||
|
||||
// Test the communication record exists.
|
||||
$communicationprocessor = processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertEquals($communicationroomname, $communicationprocessor->get_room_name());
|
||||
$this->assertEquals($selectedcommunication, $communicationprocessor->get_provider());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the create_and_configure_room method to add/create tasks when no communication provider selected.
|
||||
*
|
||||
* @covers ::create_and_configure_room
|
||||
*/
|
||||
public function test_create_and_configure_room_without_communication_provider_selected(): void {
|
||||
// Get the course by disabling communication so that we can create it manually calling the api.
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
|
||||
// Test the tasks added.
|
||||
$adhoctask = \core\task\manager::get_adhoc_tasks('\\core_communication\\task\\create_and_configure_room_task');
|
||||
$this->assertCount(0, $adhoctask);
|
||||
|
||||
// Test the communication record exists.
|
||||
$communicationprocessor = processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertNull($communicationprocessor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test update operation.
|
||||
*
|
||||
* @covers ::update_room
|
||||
*/
|
||||
public function test_update_room(): void {
|
||||
$course = $this->get_course();
|
||||
|
||||
// Sample data.
|
||||
$communicationroomname = 'Sampleroomupdated';
|
||||
$selectedcommunication = 'communication_matrix';
|
||||
|
||||
$communication = \core_communication\api::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
$communication->update_room($selectedcommunication, $communicationroomname);
|
||||
|
||||
// Test the tasks added.
|
||||
$adhoctask = \core\task\manager::get_adhoc_tasks('\\core_communication\\task\\update_room_task');
|
||||
// Should be 2 as one for create, another for update.
|
||||
$this->assertCount(1, $adhoctask);
|
||||
|
||||
$adhoctask = reset($adhoctask);
|
||||
$this->assertInstanceOf('\\core_communication\\task\\update_room_task', $adhoctask);
|
||||
|
||||
// Test the communication record exists.
|
||||
$communicationprocessor = processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertEquals($communicationroomname, $communicationprocessor->get_room_name());
|
||||
$this->assertEquals($selectedcommunication, $communicationprocessor->get_provider());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete operation.
|
||||
*
|
||||
* @covers ::delete_room
|
||||
*/
|
||||
public function test_delete_room(): void {
|
||||
$course = $this->get_course();
|
||||
|
||||
// Sample data.
|
||||
$communicationroomname = 'Sampleroom';
|
||||
$selectedcommunication = 'communication_matrix';
|
||||
|
||||
// Test the communication record exists.
|
||||
$communicationprocessor = processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertEquals($communicationroomname, $communicationprocessor->get_room_name());
|
||||
$this->assertEquals($selectedcommunication, $communicationprocessor->get_provider());
|
||||
|
||||
$communication = \core_communication\api::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
$communication->delete_room();
|
||||
|
||||
// Test the tasks added.
|
||||
$adhoctask = \core\task\manager::get_adhoc_tasks('\\core_communication\\task\\delete_room_task');
|
||||
// Should be 2 as one for create, another for update.
|
||||
$this->assertCount(1, $adhoctask);
|
||||
|
||||
$adhoctask = reset($adhoctask);
|
||||
$this->assertInstanceOf('\\core_communication\\task\\delete_room_task', $adhoctask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the update_room_membership for adding adn removing members.
|
||||
*
|
||||
* @covers ::add_members_to_room
|
||||
* @covers ::remove_members_from_room
|
||||
*/
|
||||
public function test_update_room_membership(): void {
|
||||
$course = $this->get_course();
|
||||
$userid = $this->get_user()->id;
|
||||
|
||||
// First test the adding members to a room.
|
||||
$communication = \core_communication\api::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
$communication->add_members_to_room([$userid]);
|
||||
|
||||
// Test the tasks added.
|
||||
$adhoctask = \core\task\manager::get_adhoc_tasks('\\core_communication\\task\\add_members_to_room_task');
|
||||
$this->assertCount(1, $adhoctask);
|
||||
|
||||
// Now test the removing members from a room.
|
||||
$communication->remove_members_from_room([$userid]);
|
||||
|
||||
// Test the tasks added.
|
||||
$adhoctask = \core\task\manager::get_adhoc_tasks('\\core_communication\\task\\remove_members_from_room');
|
||||
$this->assertCount(1, $adhoctask);
|
||||
}
|
||||
}
|
587
communication/tests/communication_processor_test.php
Normal file
587
communication/tests/communication_processor_test.php
Normal file
@ -0,0 +1,587 @@
|
||||
<?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_communication;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once(__DIR__ . '/communication_test_helper_trait.php');
|
||||
|
||||
/**
|
||||
* Class communication_processor_test to test the communication internal api and its associated methods.
|
||||
*
|
||||
* @package core_communication
|
||||
* @category test
|
||||
* @copyright 2023 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \core_communication\communication_processor
|
||||
*/
|
||||
class communication_processor_test extends \advanced_testcase {
|
||||
|
||||
use communication_test_helper_trait;
|
||||
|
||||
/**
|
||||
* Test create instance.
|
||||
*
|
||||
* @covers ::create_instance
|
||||
*/
|
||||
public function test_create_instance(): void {
|
||||
global $DB;
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Sameple test data.
|
||||
$instanceid = 10;
|
||||
$component = 'core_course';
|
||||
$instancetype = 'coursecommunication';
|
||||
$selectedcommunication = 'communication_matrix';
|
||||
$communicationroomname = 'communicationroom';
|
||||
|
||||
$communicationprocessor = communication_processor::create_instance(
|
||||
$selectedcommunication,
|
||||
$instanceid,
|
||||
$component,
|
||||
$instancetype,
|
||||
$communicationroomname,
|
||||
);
|
||||
|
||||
// Now test the record against the database.
|
||||
$communicationrecord = $DB->get_record('communication',
|
||||
['instanceid' => $instanceid, 'component' => $component, 'instancetype' => $instancetype]);
|
||||
|
||||
// Test against the set data.
|
||||
$this->assertNotEmpty($communicationrecord);
|
||||
$this->assertEquals($instanceid, $communicationrecord->instanceid);
|
||||
$this->assertEquals($component, $communicationrecord->component);
|
||||
$this->assertEquals($selectedcommunication, $communicationrecord->provider);
|
||||
$this->assertEquals($communicationroomname, $communicationrecord->roomname);
|
||||
$this->assertEquals($instancetype, $communicationrecord->instancetype);
|
||||
|
||||
// Test against the object.
|
||||
$this->assertEquals($communicationprocessor->get_id(), $communicationrecord->id);
|
||||
$this->assertEquals($communicationprocessor->get_provider(), $communicationrecord->provider);
|
||||
$this->assertEquals($communicationprocessor->get_room_name(), $communicationrecord->roomname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test update instance.
|
||||
*
|
||||
* @covers ::update_instance
|
||||
*/
|
||||
public function test_update_instance(): void {
|
||||
global $DB;
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Sameple test data.
|
||||
$instanceid = 10;
|
||||
$component = 'core_course';
|
||||
$instancetype = 'coursecommunication';
|
||||
$selectedcommunication = 'communication_matrix';
|
||||
$communicationroomname = 'communicationroom';
|
||||
|
||||
$communicationprocessor = communication_processor::create_instance(
|
||||
$selectedcommunication,
|
||||
$instanceid,
|
||||
$component,
|
||||
$instancetype,
|
||||
$communicationroomname,
|
||||
);
|
||||
|
||||
$selectedcommunication = 'none';
|
||||
$communicationroomname = 'communicationroomedited';
|
||||
|
||||
$communicationprocessor->update_instance($selectedcommunication, $communicationroomname);
|
||||
|
||||
// Now test the record against the database.
|
||||
$communicationrecord = $DB->get_record('communication', [
|
||||
'instanceid' => $instanceid,
|
||||
'component' => $component,
|
||||
'instancetype' => $instancetype
|
||||
]);
|
||||
|
||||
// Test against the set data.
|
||||
$this->assertNotEmpty($communicationrecord);
|
||||
$this->assertEquals($instanceid, $communicationrecord->instanceid);
|
||||
$this->assertEquals($component, $communicationrecord->component);
|
||||
$this->assertEquals($selectedcommunication, $communicationrecord->provider);
|
||||
$this->assertEquals($communicationroomname, $communicationrecord->roomname);
|
||||
$this->assertEquals($instancetype, $communicationrecord->instancetype);
|
||||
|
||||
// Test against the object.
|
||||
$this->assertEquals($communicationprocessor->get_id(), $communicationrecord->id);
|
||||
$this->assertEquals($communicationprocessor->get_provider(), $communicationrecord->provider);
|
||||
$this->assertEquals($communicationprocessor->get_room_name(), $communicationrecord->roomname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete instance.
|
||||
*
|
||||
* @covers ::delete_instance
|
||||
*/
|
||||
public function test_delete_instance(): void {
|
||||
global $DB;
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Sameple test data.
|
||||
$instanceid = 10;
|
||||
$component = 'core_course';
|
||||
$instancetype = 'coursecommunication';
|
||||
$selectedcommunication = 'communication_matrix';
|
||||
$communicationroomname = 'communicationroom';
|
||||
|
||||
$communicationprocessor = communication_processor::create_instance(
|
||||
$selectedcommunication,
|
||||
$instanceid,
|
||||
$component,
|
||||
$instancetype,
|
||||
$communicationroomname,
|
||||
);
|
||||
|
||||
$communicationprocessor->delete_instance();
|
||||
|
||||
// Now test the record against the database.
|
||||
$communicationrecord = $DB->get_record('communication', [
|
||||
'instanceid' => $instanceid,
|
||||
'component' => $component,
|
||||
'instancetype' => $instancetype
|
||||
]);
|
||||
|
||||
// Test against the set data.
|
||||
$this->assertEmpty($communicationrecord);
|
||||
|
||||
// Test against the object.
|
||||
$communicationprocessor = communication_processor::load_by_instance(
|
||||
$component,
|
||||
$instancetype,
|
||||
$instanceid);
|
||||
$this->assertNull($communicationprocessor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test create instance user mapping.
|
||||
*
|
||||
* @covers ::create_instance_user_mapping
|
||||
* @covers ::get_all_userids_for_instance
|
||||
*/
|
||||
public function test_create_instance_user_mapping(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
global $DB;
|
||||
$course = $this->get_course('Sampleroom', 'none');
|
||||
$userid = $this->get_user()->id;
|
||||
|
||||
// Sample data.
|
||||
$communicationroomname = 'Sampleroom';
|
||||
$selectedcommunication = 'communication_matrix';
|
||||
$component = 'core_course';
|
||||
$instancetype = 'coursecommunication';
|
||||
|
||||
// First test the adding members to a room.
|
||||
$communication = \core_communication\api::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
$communication->create_and_configure_room($selectedcommunication, $communicationroomname);
|
||||
$communication->add_members_to_room([$userid]);
|
||||
|
||||
// Test against the object.
|
||||
$communicationprocessor = communication_processor::load_by_instance(
|
||||
$component,
|
||||
$instancetype,
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertEquals([$userid], $communicationprocessor->get_all_userids_for_instance());
|
||||
|
||||
// Test against the database.
|
||||
$communicationuserrecord = $DB->get_record('communication_user', [
|
||||
'commid' => $communicationprocessor->get_id(),
|
||||
'userid' => $userid
|
||||
]);
|
||||
|
||||
$this->assertEquals($communicationuserrecord->userid, $userid);
|
||||
$this->assertEquals($communicationuserrecord->commid, $communicationprocessor->get_id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test update instance user mapping.
|
||||
*
|
||||
* @covers ::get_all_userids_for_instance
|
||||
*/
|
||||
public function test_update_instance_user_mapping(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
global $DB;
|
||||
$course = $this->get_course();
|
||||
$userid = $this->get_user()->id;
|
||||
|
||||
// Sample data.
|
||||
$communicationroomname = 'Sampleroom';
|
||||
$selectedcommunication = 'communication_matrix';
|
||||
$component = 'core_course';
|
||||
$instancetype = 'coursecommunication';
|
||||
|
||||
$communication = \core_communication\api::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
$communication->update_room($selectedcommunication, $communicationroomname);
|
||||
$communication->add_members_to_room([$userid]);
|
||||
|
||||
// Test against the object.
|
||||
$communicationprocessor = communication_processor::load_by_instance(
|
||||
$component,
|
||||
$instancetype,
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertnotEmpty($communicationprocessor->get_instance_userids_by_synced());
|
||||
|
||||
// Test against the database.
|
||||
$communicationuserrecord = $DB->get_record('communication_user', [
|
||||
'commid' => $communicationprocessor->get_id(),
|
||||
'userid' => $userid
|
||||
]);
|
||||
|
||||
$this->assertEquals($communicationuserrecord->userid, $userid);
|
||||
$this->assertEquals($communicationuserrecord->commid, $communicationprocessor->get_id());
|
||||
|
||||
// Now add again.
|
||||
$communicationprocessor->delete_instance_user_mapping([$userid]);
|
||||
|
||||
// Test against the database.
|
||||
$communicationuserrecord = $DB->get_record('communication_user', [
|
||||
'commid' => $communicationprocessor->get_id(),
|
||||
'userid' => $userid
|
||||
]);
|
||||
|
||||
$this->assertEmpty($communicationuserrecord);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete instance user mapping.
|
||||
*
|
||||
* @covers ::delete_instance_user_mapping
|
||||
* @covers ::get_all_userids_for_instance
|
||||
*/
|
||||
public function test_delete_instance_user_mapping(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
global $DB;
|
||||
$course = $this->get_course('Sampleroom', 'none');
|
||||
$userid = $this->get_user()->id;
|
||||
|
||||
// Sample data.
|
||||
$communicationroomname = 'Sampleroom';
|
||||
$selectedcommunication = 'communication_matrix';
|
||||
$component = 'core_course';
|
||||
$instancetype = 'coursecommunication';
|
||||
|
||||
// First test the adding members to a room.
|
||||
$communication = \core_communication\api::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
$communication->create_and_configure_room($selectedcommunication, $communicationroomname);
|
||||
$communication->add_members_to_room([$userid]);
|
||||
|
||||
// Test against the object.
|
||||
$communicationprocessor = communication_processor::load_by_instance(
|
||||
$component,
|
||||
$instancetype,
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertEquals([$userid], $communicationprocessor->get_all_userids_for_instance());
|
||||
|
||||
// Delete the user mapping.
|
||||
$communicationprocessor->delete_instance_user_mapping([$userid]);
|
||||
|
||||
$this->assertEmpty($communicationprocessor->get_all_userids_for_instance());
|
||||
|
||||
// Test against the database.
|
||||
$communicationuserrecord = $DB->get_record('communication_user', [
|
||||
'commid' => $communicationprocessor->get_id(),
|
||||
'userid' => $userid
|
||||
]);
|
||||
|
||||
$this->assertEmpty($communicationuserrecord);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete user mappings for instance.
|
||||
*
|
||||
* @covers ::delete_user_mappings_for_instance
|
||||
* @covers ::get_all_userids_for_instance
|
||||
*/
|
||||
public function test_delete_user_mappings_for_instance(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
global $DB;
|
||||
$course = $this->get_course('Sampleroom', 'none');
|
||||
$userid = $this->get_user()->id;
|
||||
|
||||
// Sample data.
|
||||
$communicationroomname = 'Sampleroom';
|
||||
$selectedcommunication = 'communication_matrix';
|
||||
$component = 'core_course';
|
||||
$instancetype = 'coursecommunication';
|
||||
|
||||
// First test the adding members to a room.
|
||||
$communication = \core_communication\api::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
$communication->create_and_configure_room($selectedcommunication, $communicationroomname);
|
||||
$communication->add_members_to_room([$userid]);
|
||||
|
||||
// Test against the object.
|
||||
$communicationprocessor = communication_processor::load_by_instance(
|
||||
$component,
|
||||
$instancetype,
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertEquals([$userid], $communicationprocessor->get_all_userids_for_instance());
|
||||
|
||||
// Delete the user mapping.
|
||||
$communicationprocessor->delete_user_mappings_for_instance();
|
||||
|
||||
$this->assertEmpty($communicationprocessor->get_all_userids_for_instance());
|
||||
|
||||
// Test against the database.
|
||||
$communicationuserrecord = $DB->get_record('communication_user', [
|
||||
'commid' => $communicationprocessor->get_id(),
|
||||
'userid' => $userid
|
||||
]);
|
||||
|
||||
$this->assertEmpty($communicationuserrecord);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test load by id.
|
||||
*
|
||||
* @covers ::load_by_instance
|
||||
*/
|
||||
public function test_load_by_instance(): void {
|
||||
$this->resetAfterTest();
|
||||
$course = $this->get_course();
|
||||
|
||||
// Test the communication record exists.
|
||||
$communicationprocessor = communication_processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertNotNull($communicationprocessor);
|
||||
$this->assertInstanceOf(communication_provider::class, $communicationprocessor->get_room_provider());
|
||||
$this->assertInstanceOf(room_chat_provider::class, $communicationprocessor->get_room_provider());
|
||||
$this->assertInstanceOf(room_user_provider::class, $communicationprocessor->get_room_provider());
|
||||
$this->assertInstanceOf(user_provider::class, $communicationprocessor->get_room_provider());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test load by id.
|
||||
*
|
||||
* @covers ::load_by_id
|
||||
*/
|
||||
public function test_load_by_id(): void {
|
||||
$this->resetAfterTest();
|
||||
$course = $this->get_course();
|
||||
|
||||
// Test the communication record exists.
|
||||
$communicationprocessor = communication_processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$communicationprocessorbyid = communication_processor::load_by_id($communicationprocessor->get_id());
|
||||
|
||||
$this->assertNotNull($communicationprocessorbyid);
|
||||
$this->assertInstanceOf(communication_provider::class, $communicationprocessorbyid->get_room_provider());
|
||||
$this->assertInstanceOf(room_chat_provider::class, $communicationprocessorbyid->get_room_provider());
|
||||
$this->assertInstanceOf(room_user_provider::class, $communicationprocessorbyid->get_room_provider());
|
||||
$this->assertInstanceOf(user_provider::class, $communicationprocessorbyid->get_room_provider());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get component.
|
||||
*
|
||||
* @covers ::get_component
|
||||
*/
|
||||
public function test_get_component(): void {
|
||||
$this->resetAfterTest();
|
||||
$course = $this->get_course();
|
||||
|
||||
// Test the communication record exists.
|
||||
$communicationprocessor = communication_processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertEquals('core_course', $communicationprocessor->get_component());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get provider.
|
||||
*
|
||||
* @covers ::get_provider
|
||||
*/
|
||||
public function test_get_provider(): void {
|
||||
$this->resetAfterTest();
|
||||
$course = $this->get_course();
|
||||
|
||||
// Test the communication record exists.
|
||||
$communicationprocessor = communication_processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertEquals('communication_matrix', $communicationprocessor->get_provider());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get room name.
|
||||
*
|
||||
* @covers ::get_room_name
|
||||
*/
|
||||
public function test_get_room_name(): void {
|
||||
$this->resetAfterTest();
|
||||
$course = $this->get_course();
|
||||
|
||||
// Test the communication record exists.
|
||||
$communicationprocessor = communication_processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertEquals('Sampleroom', $communicationprocessor->get_room_name());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get room provider.
|
||||
*
|
||||
* @covers ::get_room_provider
|
||||
* @covers ::require_room_features
|
||||
* @covers ::supports_room_features
|
||||
*/
|
||||
public function test_get_room_provider(): void {
|
||||
$this->resetAfterTest();
|
||||
$course = $this->get_course();
|
||||
|
||||
// Test the communication record exists.
|
||||
$communicationprocessor = communication_processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertInstanceOf(room_chat_provider::class, $communicationprocessor->get_room_provider());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get user provider.
|
||||
*
|
||||
* @covers ::get_user_provider
|
||||
* @covers ::require_user_features
|
||||
* @covers ::supports_user_features
|
||||
*/
|
||||
public function test_get_user_provider(): void {
|
||||
$this->resetAfterTest();
|
||||
$course = $this->get_course();
|
||||
|
||||
// Test the communication record exists.
|
||||
$communicationprocessor = communication_processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertInstanceOf(user_provider::class, $communicationprocessor->get_room_provider());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get room user provider.
|
||||
*
|
||||
* @covers ::get_room_user_provider
|
||||
* @covers ::require_room_features
|
||||
* @covers ::require_room_user_features
|
||||
* @covers ::supports_room_user_features
|
||||
* @covers ::supports_room_features
|
||||
*/
|
||||
public function test_get_room_user_provider(): void {
|
||||
$this->resetAfterTest();
|
||||
$course = $this->get_course();
|
||||
|
||||
// Test the communication record exists.
|
||||
$communicationprocessor = communication_processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertInstanceOf(room_user_provider::class, $communicationprocessor->get_room_user_provider());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get avatar.
|
||||
*
|
||||
* @covers ::get_avatar
|
||||
*/
|
||||
public function test_get_avatar(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
global $CFG;
|
||||
$course = $this->get_course('Sampleroom', 'none');
|
||||
|
||||
// Sample data.
|
||||
$communicationroomname = 'Sampleroom';
|
||||
$selectedcommunication = 'communication_matrix';
|
||||
$avatarurl = $CFG->dirroot . '/communication/tests/fixtures/moodle_logo.jpg';
|
||||
|
||||
$communication = \core_communication\api::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
$communication->create_and_configure_room($selectedcommunication, $communicationroomname, $avatarurl);
|
||||
|
||||
$communicationprocessor = communication_processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$avatar = $communicationprocessor->get_avatar();
|
||||
|
||||
$this->assertNotNull($avatar);
|
||||
$this->assertEquals($avatar->get_component(), 'core_communication');
|
||||
$this->assertEquals($avatar->get_filearea(), 'avatar');
|
||||
$this->assertEquals($avatar->get_itemid(), $communicationprocessor->get_id());
|
||||
$this->assertEquals($avatar->get_filepath(), '/');
|
||||
$this->assertEquals($avatar->get_filearea(), 'avatar');
|
||||
}
|
||||
}
|
82
communication/tests/communication_test_helper_trait.php
Normal file
82
communication/tests/communication_test_helper_trait.php
Normal file
@ -0,0 +1,82 @@
|
||||
<?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_communication;
|
||||
|
||||
/**
|
||||
* Trait communication_test_helper_trait to generate initial setup for communication providers.
|
||||
*
|
||||
* @package core_communication
|
||||
* @category test
|
||||
* @copyright 2023 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
trait communication_test_helper_trait {
|
||||
|
||||
/**
|
||||
* Setup necessary configs for communication subsystem.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setup_communication_configs(): void {
|
||||
set_config('enablecommunicationsubsystem', 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create course if it does not exist
|
||||
*
|
||||
* @param string $roomname The room name for the communication api
|
||||
* @param string $provider The selected provider
|
||||
* @return \stdClass
|
||||
*/
|
||||
protected function get_course(
|
||||
string $roomname = 'Sampleroom',
|
||||
string $provider = 'communication_matrix'
|
||||
): \stdClass {
|
||||
|
||||
$this->setup_communication_configs();
|
||||
$records = [
|
||||
'selectedcommunication' => $provider,
|
||||
'communicationroomname' => $roomname,
|
||||
];
|
||||
|
||||
return $this->getDataGenerator()->create_course($records);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create user if it does not exist.
|
||||
*
|
||||
* @param string $firstname The user's firstname for the communication api
|
||||
* @param string $lastname The user's lastname for the communication api
|
||||
* @param string $username The user's username for the communication api
|
||||
* @return \stdClass
|
||||
*/
|
||||
protected function get_user(
|
||||
string $firstname = 'Samplefn',
|
||||
string $lastname = 'Sampleln',
|
||||
string $username = 'sampleun'
|
||||
): \stdClass {
|
||||
|
||||
$this->setup_communication_configs();
|
||||
$records = [
|
||||
'firstname' => $firstname,
|
||||
'lastname' => $lastname,
|
||||
'username' => $username
|
||||
];
|
||||
|
||||
return $this->getDataGenerator()->create_user($records);
|
||||
}
|
||||
}
|
BIN
communication/tests/fixtures/moodle_logo.jpg
vendored
Normal file
BIN
communication/tests/fixtures/moodle_logo.jpg
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 75 KiB |
398
communication/tests/processor_test.php
Normal file
398
communication/tests/processor_test.php
Normal file
@ -0,0 +1,398 @@
|
||||
<?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_communication;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once(__DIR__ . '/communication_test_helper_trait.php');
|
||||
|
||||
/**
|
||||
* Class processor_test to test the communication internal api and its associated methods.
|
||||
*
|
||||
* @package core_communication
|
||||
* @category test
|
||||
* @copyright 2023 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \core_communication\processor
|
||||
*/
|
||||
class processor_test extends \advanced_testcase {
|
||||
|
||||
use communication_test_helper_trait;
|
||||
|
||||
/**
|
||||
* Test create instance.
|
||||
*
|
||||
* @covers ::create_instance
|
||||
* @covers ::get_id
|
||||
* @covers ::get_instance
|
||||
* @covers ::get_room_name
|
||||
*/
|
||||
public function test_create_instance(): void {
|
||||
global $DB;
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Sameple test data.
|
||||
$instanceid = 10;
|
||||
$component = 'core_course';
|
||||
$instancetype = 'coursecommunication';
|
||||
$selectedcommunication = 'communication_matrix';
|
||||
$communicationroomname = 'communicationroom';
|
||||
|
||||
$communicationprocessor = processor::create_instance(
|
||||
$selectedcommunication,
|
||||
$instanceid,
|
||||
$component,
|
||||
$instancetype,
|
||||
$communicationroomname,
|
||||
);
|
||||
|
||||
// Now test the record against the database.
|
||||
$communicationrecord = $DB->get_record('communication',
|
||||
['instanceid' => $instanceid, 'component' => $component, 'instancetype' => $instancetype]);
|
||||
|
||||
// Test against the set data.
|
||||
$this->assertNotEmpty($communicationrecord);
|
||||
$this->assertEquals($instanceid, $communicationrecord->instanceid);
|
||||
$this->assertEquals($component, $communicationrecord->component);
|
||||
$this->assertEquals($selectedcommunication, $communicationrecord->provider);
|
||||
$this->assertEquals($communicationroomname, $communicationrecord->roomname);
|
||||
$this->assertEquals($instancetype, $communicationrecord->instancetype);
|
||||
|
||||
// Test against the object.
|
||||
$this->assertEquals($communicationprocessor->get_id(), $communicationrecord->id);
|
||||
$this->assertEquals($communicationprocessor->get_provider(), $communicationrecord->provider);
|
||||
$this->assertEquals($communicationprocessor->get_room_name(), $communicationrecord->roomname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test update instance.
|
||||
*
|
||||
* @covers ::update_instance
|
||||
* @covers ::is_instance_active
|
||||
* @covers ::get_id
|
||||
* @covers ::get_room_name
|
||||
*/
|
||||
public function test_update_instance(): void {
|
||||
global $DB;
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Sameple test data.
|
||||
$instanceid = 10;
|
||||
$component = 'core_course';
|
||||
$instancetype = 'coursecommunication';
|
||||
$selectedcommunication = 'communication_matrix';
|
||||
$communicationroomname = 'communicationroom';
|
||||
|
||||
$communicationprocessor = processor::create_instance(
|
||||
$selectedcommunication,
|
||||
$instanceid,
|
||||
$component,
|
||||
$instancetype,
|
||||
$communicationroomname,
|
||||
);
|
||||
|
||||
$selectedcommunication = 'none';
|
||||
$communicationroomname = 'communicationroomedited';
|
||||
|
||||
$communicationprocessor->update_instance($selectedcommunication, $communicationroomname);
|
||||
|
||||
// Now test the record against the database.
|
||||
$communicationrecord = $DB->get_record('communication', [
|
||||
'instanceid' => $instanceid,
|
||||
'component' => $component,
|
||||
'instancetype' => $instancetype
|
||||
]);
|
||||
|
||||
// Test against the set data.
|
||||
$this->assertNotEmpty($communicationrecord);
|
||||
$this->assertEquals($instanceid, $communicationrecord->instanceid);
|
||||
$this->assertEquals($component, $communicationrecord->component);
|
||||
$this->assertEquals(processor::PROVIDER_INACTIVE, $communicationrecord->active);
|
||||
$this->assertEquals($communicationroomname, $communicationrecord->roomname);
|
||||
$this->assertEquals($instancetype, $communicationrecord->instancetype);
|
||||
|
||||
// Test against the object.
|
||||
$this->assertEquals($communicationprocessor->get_id(), $communicationrecord->id);
|
||||
$this->assertEquals($communicationprocessor->is_instance_active(), $communicationrecord->active);
|
||||
$this->assertEquals($communicationprocessor->get_room_name(), $communicationrecord->roomname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete instance.
|
||||
*
|
||||
* @covers ::delete_instance
|
||||
* @covers ::create_instance
|
||||
* @covers ::load_by_instance
|
||||
*/
|
||||
public function test_delete_instance(): void {
|
||||
global $DB;
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Sameple test data.
|
||||
$instanceid = 10;
|
||||
$component = 'core_course';
|
||||
$instancetype = 'coursecommunication';
|
||||
$selectedcommunication = 'communication_matrix';
|
||||
$communicationroomname = 'communicationroom';
|
||||
|
||||
$communicationprocessor = processor::create_instance(
|
||||
$selectedcommunication,
|
||||
$instanceid,
|
||||
$component,
|
||||
$instancetype,
|
||||
$communicationroomname,
|
||||
);
|
||||
|
||||
$communicationprocessor->delete_instance();
|
||||
|
||||
// Now test the record against the database.
|
||||
$communicationrecord = $DB->get_record('communication', [
|
||||
'instanceid' => $instanceid,
|
||||
'component' => $component,
|
||||
'instancetype' => $instancetype
|
||||
]);
|
||||
|
||||
// Test against the set data.
|
||||
$this->assertEmpty($communicationrecord);
|
||||
|
||||
// Test against the object.
|
||||
$communicationprocessor = processor::load_by_instance(
|
||||
$component,
|
||||
$instancetype,
|
||||
$instanceid);
|
||||
$this->assertNull($communicationprocessor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test load by id.
|
||||
*
|
||||
* @covers ::load_by_instance
|
||||
* @covers ::get_room_provider
|
||||
*/
|
||||
public function test_load_by_instance(): void {
|
||||
$this->resetAfterTest();
|
||||
$course = $this->get_course();
|
||||
|
||||
// Test the communication record exists.
|
||||
$communicationprocessor = processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertNotNull($communicationprocessor);
|
||||
$this->assertInstanceOf(communication_provider::class, $communicationprocessor->get_room_provider());
|
||||
$this->assertInstanceOf(room_chat_provider::class, $communicationprocessor->get_room_provider());
|
||||
$this->assertInstanceOf(room_user_provider::class, $communicationprocessor->get_room_provider());
|
||||
$this->assertInstanceOf(user_provider::class, $communicationprocessor->get_room_provider());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test load by id.
|
||||
*
|
||||
* @covers ::load_by_id
|
||||
* @covers ::get_room_provider
|
||||
* @covers ::load_by_instance
|
||||
*/
|
||||
public function test_load_by_id(): void {
|
||||
$this->resetAfterTest();
|
||||
$course = $this->get_course();
|
||||
|
||||
// Test the communication record exists.
|
||||
$communicationprocessor = processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$communicationprocessorbyid = processor::load_by_id($communicationprocessor->get_id());
|
||||
|
||||
$this->assertNotNull($communicationprocessorbyid);
|
||||
$this->assertInstanceOf(communication_provider::class, $communicationprocessorbyid->get_room_provider());
|
||||
$this->assertInstanceOf(room_chat_provider::class, $communicationprocessorbyid->get_room_provider());
|
||||
$this->assertInstanceOf(room_user_provider::class, $communicationprocessorbyid->get_room_provider());
|
||||
$this->assertInstanceOf(user_provider::class, $communicationprocessorbyid->get_room_provider());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get component.
|
||||
*
|
||||
* @covers ::get_component
|
||||
* @covers ::load_by_instance
|
||||
*/
|
||||
public function test_get_component(): void {
|
||||
$this->resetAfterTest();
|
||||
$course = $this->get_course();
|
||||
|
||||
// Test the communication record exists.
|
||||
$communicationprocessor = processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertEquals('core_course', $communicationprocessor->get_component());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get provider.
|
||||
*
|
||||
* @covers ::get_provider
|
||||
* @covers ::load_by_instance
|
||||
*/
|
||||
public function test_get_provider(): void {
|
||||
$this->resetAfterTest();
|
||||
$course = $this->get_course();
|
||||
|
||||
// Test the communication record exists.
|
||||
$communicationprocessor = processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertEquals('communication_matrix', $communicationprocessor->get_provider());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get room name.
|
||||
*
|
||||
* @covers ::get_room_name
|
||||
* @covers ::load_by_instance
|
||||
*/
|
||||
public function test_get_room_name(): void {
|
||||
$this->resetAfterTest();
|
||||
$course = $this->get_course();
|
||||
|
||||
// Test the communication record exists.
|
||||
$communicationprocessor = processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertEquals('Sampleroom', $communicationprocessor->get_room_name());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get room provider.
|
||||
*
|
||||
* @covers ::get_room_provider
|
||||
* @covers ::require_room_features
|
||||
* @covers ::supports_room_features
|
||||
* @covers ::load_by_instance
|
||||
*/
|
||||
public function test_get_room_provider(): void {
|
||||
$this->resetAfterTest();
|
||||
$course = $this->get_course();
|
||||
|
||||
// Test the communication record exists.
|
||||
$communicationprocessor = processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertInstanceOf(room_chat_provider::class, $communicationprocessor->get_room_provider());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get user provider.
|
||||
*
|
||||
* @covers ::get_user_provider
|
||||
* @covers ::require_user_features
|
||||
* @covers ::supports_user_features
|
||||
* @covers ::load_by_instance
|
||||
*/
|
||||
public function test_get_user_provider(): void {
|
||||
$this->resetAfterTest();
|
||||
$course = $this->get_course();
|
||||
|
||||
// Test the communication record exists.
|
||||
$communicationprocessor = processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertInstanceOf(user_provider::class, $communicationprocessor->get_room_provider());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get room user provider.
|
||||
*
|
||||
* @covers ::get_room_user_provider
|
||||
* @covers ::require_room_features
|
||||
* @covers ::require_room_user_features
|
||||
* @covers ::supports_room_user_features
|
||||
* @covers ::supports_room_features
|
||||
* @covers ::load_by_instance
|
||||
*/
|
||||
public function test_get_room_user_provider(): void {
|
||||
$this->resetAfterTest();
|
||||
$course = $this->get_course();
|
||||
|
||||
// Test the communication record exists.
|
||||
$communicationprocessor = processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$this->assertInstanceOf(room_user_provider::class, $communicationprocessor->get_room_user_provider());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get avatar.
|
||||
*
|
||||
* @covers ::get_avatar
|
||||
* @covers ::load_by_instance
|
||||
*/
|
||||
public function test_get_avatar(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
global $CFG;
|
||||
$course = $this->get_course('Sampleroom', 'none');
|
||||
|
||||
// Sample data.
|
||||
$communicationroomname = 'Sampleroom';
|
||||
$selectedcommunication = 'communication_matrix';
|
||||
$avatarurl = $CFG->dirroot . '/communication/tests/fixtures/moodle_logo.jpg';
|
||||
|
||||
$communication = \core_communication\api::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
$communication->create_and_configure_room($selectedcommunication, $communicationroomname, $avatarurl);
|
||||
|
||||
$communicationprocessor = processor::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
|
||||
$avatar = $communicationprocessor->get_avatar();
|
||||
|
||||
$this->assertNotNull($avatar);
|
||||
$this->assertEquals($avatar->get_component(), 'core_communication');
|
||||
$this->assertEquals($avatar->get_filearea(), 'avatar');
|
||||
$this->assertEquals($avatar->get_itemid(), $communicationprocessor->get_id());
|
||||
$this->assertEquals($avatar->get_filepath(), '/');
|
||||
$this->assertEquals($avatar->get_filearea(), 'avatar');
|
||||
}
|
||||
}
|
@ -24,6 +24,11 @@
|
||||
|
||||
$string['communication'] = 'Communication';
|
||||
$string['communicationprovidernotfound'] = 'The \'{$a}\' communication provider doesn\'t exist or is not recognised.';
|
||||
$string['communicationroomname'] = 'Room name';
|
||||
$string['communicationroomname_help'] = 'The name that participants see when they visit the room. If you leave this blank, a default room name will be automatically set.';
|
||||
$string['managecommunicationproviders'] = 'Manage communication providers';
|
||||
$string['nocommunicationprovider'] = 'No communication provider found.';
|
||||
$string['nocommunicationselected'] = 'None';
|
||||
$string['privacy:metadata'] = 'The Moodle communication subsystem does not store any personal data.';
|
||||
$string['seleccommunicationprovider'] = 'Communication service';
|
||||
$string['seleccommunicationprovider_help'] = 'The tool available for chat and related communication methods.';
|
||||
|
@ -218,6 +218,35 @@
|
||||
<INDEX NAME="useridcourse" UNIQUE="true" FIELDS="userid, course"/>
|
||||
</INDEXES>
|
||||
</TABLE>
|
||||
<TABLE NAME="communication" COMMENT="Communication records">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
|
||||
<FIELD NAME="instanceid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="ID of the instance where the communication is a part of"/>
|
||||
<FIELD NAME="component" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false" COMMENT="Component of the instance where the communication room is a part of"/>
|
||||
<FIELD NAME="instancetype" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false" COMMENT="The type of the instance for the given component"/>
|
||||
<FIELD NAME="provider" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false" COMMENT="Name of the selected communication provider"/>
|
||||
<FIELD NAME="roomname" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" COMMENT="Name of the communication room"/>
|
||||
<FIELD NAME="avatarfilename" TYPE="char" LENGTH="100" NOTNULL="false" SEQUENCE="false" COMMENT="Name of the avatar file name for the communication instance"/>
|
||||
<FIELD NAME="active" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="The communication instance is active or not"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
||||
</KEYS>
|
||||
</TABLE>
|
||||
<TABLE NAME="communication_user" COMMENT="Communication user records mapping">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
|
||||
<FIELD NAME="commid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="ID of the communication instance"/>
|
||||
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="ID of the moodle user to map with communication instance"/>
|
||||
<FIELD NAME="synced" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="The user is synced or not"/>
|
||||
<FIELD NAME="deleted" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="The user need to be deleted or not"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
||||
<KEY NAME="commid" TYPE="foreign" FIELDS="commid" REFTABLE="communication" REFFIELDS="id"/>
|
||||
<KEY NAME="userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id"/>
|
||||
</KEYS>
|
||||
</TABLE>
|
||||
<TABLE NAME="enrol" COMMENT="Instances of enrolment plugins used in courses, fields marked as custom have a plugin defined meaning, core does not touch them. Create a new linked table if you need even more custom fields.">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
|
||||
|
@ -3256,6 +3256,52 @@ privatefiles,moodle|/user/files.php';
|
||||
upgrade_main_savepoint(true, 2023042000.00);
|
||||
}
|
||||
|
||||
if ($oldversion < 2023050400.01) {
|
||||
// Define communication table.
|
||||
$table = new xmldb_table('communication');
|
||||
|
||||
// Adding fields to table communication.
|
||||
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE);
|
||||
$table->add_field('instanceid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id');
|
||||
$table->add_field('component', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null, 'instanceid');
|
||||
$table->add_field('instancetype', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null, 'component');
|
||||
$table->add_field('provider', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null, 'instancerype');
|
||||
$table->add_field('roomname', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'provider');
|
||||
$table->add_field('avatarfilename', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'roomname');
|
||||
$table->add_field('active', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, 1, 'avatarfilename');
|
||||
|
||||
// Add key.
|
||||
$table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
|
||||
|
||||
// Conditionally launch create table for communication.
|
||||
if (!$dbman->table_exists($table)) {
|
||||
$dbman->create_table($table);
|
||||
}
|
||||
|
||||
// Define communication user table.
|
||||
$table = new xmldb_table('communication_user');
|
||||
|
||||
// Adding fields to table communication.
|
||||
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE);
|
||||
$table->add_field('commid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id');
|
||||
$table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'commid');
|
||||
$table->add_field('synced', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, 0, 'userid');
|
||||
$table->add_field('deleted', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, 0, 'synced');
|
||||
|
||||
// Add keys.
|
||||
$table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
|
||||
$table->add_key('commid', XMLDB_KEY_FOREIGN, ['commid'], 'communication', ['id']);
|
||||
$table->add_key('userid', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']);
|
||||
|
||||
// Conditionally launch create table for communication.
|
||||
if (!$dbman->table_exists($table)) {
|
||||
$dbman->create_table($table);
|
||||
}
|
||||
|
||||
// Main savepoint reached.
|
||||
upgrade_main_savepoint(true, 2023050400.01);
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$version = 2023050400.00; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
$version = 2023050400.01; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
// RR = release increments - 00 in DEV branches.
|
||||
// .XX = incremental changes.
|
||||
$release = '4.3dev (Build: 20230504)'; // Human-friendly version name
|
||||
|
Loading…
x
Reference in New Issue
Block a user