mirror of
https://github.com/moodle/moodle.git
synced 2025-03-14 12:40:01 +01:00
Merge branch 'MDL-78553-master' of https://github.com/davewoloszyn/moodle
This commit is contained in:
commit
aeeb1653c0
@ -7,6 +7,6 @@ define("core_communication/providerchooser",["exports"],(function(_exports){Obje
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @since 4.2
|
||||
*/
|
||||
const Selectors_fields={selector:'[data-communicationchooser-field="selector"]',updateButton:'[data-communicationchooser-field="updateButton"]'};_exports.init=()=>{document.querySelector(Selectors_fields.selector).addEventListener("change",(e=>{const form=e.target.closest("form"),updateButton=form.querySelector(Selectors_fields.updateButton),fieldset=updateButton.closest("fieldset"),url=new URL(form.action);url.hash=fieldset.id,form.action=url.toString(),updateButton.click()}))}}));
|
||||
const Selectors_fields={selector:'[data-communicationchooser-field="selector"]',updateButton:'[data-communicationchooser-field="updateButton"]'};_exports.init=()=>{document.querySelector(Selectors_fields.selector).addEventListener("change",(e=>{const form=e.target.closest("form"),updateButton=form.querySelector(Selectors_fields.updateButton),url=new URL(form.action);form.action=url.toString(),updateButton.click()}))}}));
|
||||
|
||||
//# sourceMappingURL=providerchooser.min.js.map
|
@ -1 +1 @@
|
||||
{"version":3,"file":"providerchooser.min.js","sources":["../src/providerchooser.js"],"sourcesContent":["\n// This file is part of Moodle - http://moodle.org/ //\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Communication provider selection handler.\n *\n * @module core_communication/communicationchooser\n * @copyright 2023 Safat Shahin <safat.shahin@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 4.2\n */\n\nconst Selectors = {\n fields: {\n selector: '[data-communicationchooser-field=\"selector\"]',\n updateButton: '[data-communicationchooser-field=\"updateButton\"]',\n },\n};\n\n/**\n * Initialise the format chooser.\n */\nexport const init = () => {\n document.querySelector(Selectors.fields.selector).addEventListener('change', e => {\n const form = e.target.closest('form');\n const updateButton = form.querySelector(Selectors.fields.updateButton);\n const fieldset = updateButton.closest('fieldset');\n\n const url = new URL(form.action);\n url.hash = fieldset.id;\n\n form.action = url.toString();\n updateButton.click();\n });\n};\n"],"names":["Selectors","selector","updateButton","document","querySelector","addEventListener","e","form","target","closest","fieldset","url","URL","action","hash","id","toString","click"],"mappings":";;;;;;;;;MAwBMA,iBACM,CACJC,SAAU,+CACVC,aAAc,kEAOF,KAChBC,SAASC,cAAcJ,iBAAiBC,UAAUI,iBAAiB,UAAUC,UACnEC,KAAOD,EAAEE,OAAOC,QAAQ,QACxBP,aAAeK,KAAKH,cAAcJ,iBAAiBE,cACnDQ,SAAWR,aAAaO,QAAQ,YAEhCE,IAAM,IAAIC,IAAIL,KAAKM,QACzBF,IAAIG,KAAOJ,SAASK,GAEpBR,KAAKM,OAASF,IAAIK,WAClBd,aAAae"}
|
||||
{"version":3,"file":"providerchooser.min.js","sources":["../src/providerchooser.js"],"sourcesContent":["\n// This file is part of Moodle - http://moodle.org/ //\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Communication provider selection handler.\n *\n * @module core_communication/communicationchooser\n * @copyright 2023 Safat Shahin <safat.shahin@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 4.2\n */\n\nconst Selectors = {\n fields: {\n selector: '[data-communicationchooser-field=\"selector\"]',\n updateButton: '[data-communicationchooser-field=\"updateButton\"]',\n },\n};\n\n/**\n * Initialise the format chooser.\n */\nexport const init = () => {\n document.querySelector(Selectors.fields.selector).addEventListener('change', e => {\n const form = e.target.closest('form');\n const updateButton = form.querySelector(Selectors.fields.updateButton);\n const url = new URL(form.action);\n\n form.action = url.toString();\n updateButton.click();\n });\n};\n"],"names":["Selectors","selector","updateButton","document","querySelector","addEventListener","e","form","target","closest","url","URL","action","toString","click"],"mappings":";;;;;;;;;MAwBMA,iBACM,CACJC,SAAU,+CACVC,aAAc,kEAOF,KAChBC,SAASC,cAAcJ,iBAAiBC,UAAUI,iBAAiB,UAAUC,UACnEC,KAAOD,EAAEE,OAAOC,QAAQ,QACxBP,aAAeK,KAAKH,cAAcJ,iBAAiBE,cACnDQ,IAAM,IAAIC,IAAIJ,KAAKK,QAEzBL,KAAKK,OAASF,IAAIG,WAClBX,aAAaY"}
|
@ -36,10 +36,7 @@ export const init = () => {
|
||||
document.querySelector(Selectors.fields.selector).addEventListener('change', e => {
|
||||
const form = e.target.closest('form');
|
||||
const updateButton = form.querySelector(Selectors.fields.updateButton);
|
||||
const fieldset = updateButton.closest('fieldset');
|
||||
|
||||
const url = new URL(form.action);
|
||||
url.hash = fieldset.id;
|
||||
|
||||
form.action = url.toString();
|
||||
updateButton.click();
|
||||
|
@ -148,8 +148,6 @@ class api {
|
||||
|
||||
$PAGE->requires->js_call_amd('core_communication/providerchooser', 'init');
|
||||
|
||||
$mform->addElement('header', 'communication', get_string('communication', 'communication'));
|
||||
|
||||
// List the communication providers.
|
||||
$mform->addElement(
|
||||
'select',
|
||||
|
87
communication/classes/form/configure_form.php
Normal file
87
communication/classes/form/configure_form.php
Normal file
@ -0,0 +1,87 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Configure communication for a given instance - the form definition.
|
||||
*
|
||||
* @package core_communication
|
||||
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace core_communication\form;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->libdir.'/formslib.php');
|
||||
|
||||
/**
|
||||
* Defines the configure communication form.
|
||||
*/
|
||||
class configure_form extends \moodleform {
|
||||
|
||||
/**
|
||||
* @var \core_communication\api $communication The communication api object.
|
||||
*/
|
||||
protected $communication;
|
||||
|
||||
/**
|
||||
* Defines the form fields.
|
||||
*/
|
||||
public function definition() {
|
||||
$mform = $this->_form;
|
||||
$instanceid = $this->_customdata['instanceid'];
|
||||
$instancetype = $this->_customdata['instancetype'];
|
||||
$component = $this->_customdata['component'];
|
||||
$instance = $this->_customdata['instance'];
|
||||
|
||||
// Add communication plugins to the form.
|
||||
$this->communication = \core_communication\api::load_by_instance(
|
||||
$component,
|
||||
$instancetype,
|
||||
$instanceid
|
||||
);
|
||||
$this->communication->form_definition($mform);
|
||||
$this->communication->set_data($instance);
|
||||
|
||||
// Form buttons.
|
||||
$buttonarray = [];
|
||||
$buttonarray[] = $mform->createElement('submit', 'saveandreturn', get_string('savechanges'));
|
||||
$buttonarray[] = $mform->createElement('cancel');
|
||||
$mform->addGroup($buttonarray, 'buttonar', '', [' '], false);
|
||||
$mform->closeHeaderBefore('buttonar');
|
||||
|
||||
// Hidden elements.
|
||||
$mform->addElement('hidden', 'instanceid', $instanceid);
|
||||
$mform->setType('instanceid', PARAM_INT);
|
||||
$mform->addElement('hidden', 'instancetype', $instancetype);
|
||||
$mform->setType('instancetype', PARAM_TEXT);
|
||||
$mform->addElement('hidden', 'component', $component);
|
||||
$mform->setType('component', PARAM_TEXT);
|
||||
|
||||
// Finally set the current form data.
|
||||
$this->set_data($instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill in the communication page data depending on provider selected.
|
||||
*/
|
||||
public function definition_after_data() {
|
||||
$mform = $this->_form;
|
||||
// Add communication plugins to the form with respect to the provider.
|
||||
$this->communication->form_definition_for_provider($mform);
|
||||
}
|
||||
}
|
86
communication/configure.php
Normal file
86
communication/configure.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Configure communication for a given instance.
|
||||
*
|
||||
* @package core_communication
|
||||
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once('../config.php');
|
||||
require_once('lib.php');
|
||||
|
||||
require_login();
|
||||
|
||||
$instanceid = required_param('instanceid', PARAM_INT);
|
||||
$instancetype = required_param('instancetype', PARAM_TEXT);
|
||||
$component = required_param('component', PARAM_COMPONENT);
|
||||
|
||||
$instanceinfo = [
|
||||
'instanceid' => $instanceid,
|
||||
'instancetype' => $instancetype,
|
||||
'component' => $component,
|
||||
];
|
||||
|
||||
// Requires communication to be enabled.
|
||||
if (!core_communication\api::is_available()) {
|
||||
throw new \moodle_exception('communicationdisabled', 'communication');
|
||||
}
|
||||
|
||||
// Attempt to load the communication instance with the provided params.
|
||||
$communication = \core_communication\api::load_by_instance($component, $instancetype, $instanceid);
|
||||
|
||||
// No communication, no way this form can be used.
|
||||
if (!$communication) {
|
||||
throw new \moodle_exception('nocommunicationinstance', 'communication');
|
||||
}
|
||||
|
||||
// Set variables according to the component callback and use them on the page.
|
||||
list($instance, $context, $heading, $returnurl) = component_callback(
|
||||
$component,
|
||||
'get_communication_instance_data',
|
||||
[$instanceid]
|
||||
);
|
||||
|
||||
// Set up the page.
|
||||
$PAGE->set_context($context);
|
||||
$PAGE->set_url('/communication/configure.php', $instanceinfo);
|
||||
$PAGE->set_title(get_string('communication', 'communication'));
|
||||
$PAGE->set_heading($heading);
|
||||
$PAGE->add_body_class('limitedwidth');
|
||||
|
||||
// Append the instance data before passing to form object.
|
||||
$instanceinfo['instance'] = $instance;
|
||||
// Get our form definitions.
|
||||
$form = new \core_communication\form\configure_form(null, $instanceinfo);
|
||||
|
||||
if ($form->is_cancelled()) {
|
||||
|
||||
redirect($returnurl);
|
||||
|
||||
} else if ($data = $form->get_data()) {
|
||||
|
||||
component_callback($component, 'update_communication_instance_data', [$data]);
|
||||
redirect($returnurl);
|
||||
}
|
||||
|
||||
// Display the page contents.
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->heading(get_string('communication', 'communication'), 2);
|
||||
$form->display();
|
||||
echo $OUTPUT->footer();
|
@ -19,35 +19,30 @@ Feature: Communication matrix form field
|
||||
Given a Matrix mock server is configured
|
||||
And I log in as "teacher1"
|
||||
And I am on "Test course" course homepage
|
||||
When I navigate to "Settings" in current page administration
|
||||
And I click on "Communication" "link"
|
||||
When I navigate to "Communication" in current page administration
|
||||
And I set the field "id_selectedcommunication" to "Matrix"
|
||||
And I wait to be redirected
|
||||
And I should see "Room name"
|
||||
And I set the field "id_communicationroomname" to "Sampleroomname"
|
||||
And I press "Save and display"
|
||||
And I navigate to "Settings" in current page administration
|
||||
And I expand all fieldsets
|
||||
And I press "Save changes"
|
||||
And I navigate to "Communication" in current page administration
|
||||
Then the field "id_communicationroomname" matches value "Sampleroomname"
|
||||
|
||||
Scenario: I can add room topic for matrix room
|
||||
Given a Matrix mock server is configured
|
||||
And I log in as "teacher1"
|
||||
And I am on "Test course" course homepage
|
||||
When I navigate to "Settings" in current page administration
|
||||
And I click on "Communication" "link"
|
||||
When I navigate to "Communication" in current page administration
|
||||
And I set the field "id_selectedcommunication" to "Matrix"
|
||||
And I wait to be redirected
|
||||
And I should see "Room name"
|
||||
And I should see "Room topic"
|
||||
And I set the field "id_communicationroomname" to "Sampleroomname"
|
||||
And I set the field "id_matrixroomtopic" to "Sampleroomtopic"
|
||||
And I press "Save and display"
|
||||
And I navigate to "Settings" in current page administration
|
||||
And I click on "Communication" "link"
|
||||
And I press "Save changes"
|
||||
And I navigate to "Communication" in current page administration
|
||||
Then the field "id_communicationroomname" matches value "Sampleroomname"
|
||||
And I press "Cancel"
|
||||
And I run all adhoc tasks
|
||||
And I navigate to "Settings" in current page administration
|
||||
And I click on "Communication" "link"
|
||||
And I navigate to "Communication" in current page administration
|
||||
And the field "id_matrixroomtopic" matches value "Sampleroomtopic"
|
||||
|
@ -37,10 +37,11 @@ Feature: Communication matrix
|
||||
And ".footer-link-communication" "css_element" should be visible
|
||||
|
||||
Scenario: I cannot see the matrix room link when communication provider is disabled
|
||||
Given I am on the "Test course" "Course editing" page logged in as "teacher1"
|
||||
Given I am on the "Test course" "Course" page logged in as "teacher1"
|
||||
When I navigate to "Communication" in current page administration
|
||||
And I set the following fields to these values:
|
||||
| selectedcommunication | none |
|
||||
And I press "Save and display"
|
||||
And I press "Save changes"
|
||||
And I run all adhoc tasks
|
||||
And I reload the page
|
||||
Then ".btn-footer-communication" "css_element" should not be visible
|
||||
|
@ -196,7 +196,7 @@ class api_test extends \advanced_testcase {
|
||||
*/
|
||||
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();
|
||||
$course = $this->get_course('Sampleroom', 'none');
|
||||
|
||||
// Test the tasks added.
|
||||
$adhoctask = \core\task\manager::get_adhoc_tasks('\\core_communication\\task\\create_and_configure_room_task');
|
||||
|
@ -37,4 +37,13 @@ class behat_communication extends \behat_base {
|
||||
public function enable_communication_experimental_feature(): void {
|
||||
$this->setup_communication_configs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable communication experimental feature.
|
||||
*
|
||||
* @Given /^I disable communication experimental feature$/
|
||||
*/
|
||||
public function disable_communication_experimental_feature(): void {
|
||||
$this->disable_communication_configs();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,41 @@
|
||||
@communication
|
||||
Feature: Access the communication configuration page
|
||||
As an editing teacher
|
||||
See dynamic form fields based on selected provider
|
||||
|
||||
Background: Set up teachers and course for the communication confifiguration page
|
||||
Given I enable communication experimental feature
|
||||
And the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
| teacher2 | Teacher | 2 | teacher2@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category | selectedcommunication |
|
||||
| Test course | Test course | 0 | none |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | Test course | editingteacher |
|
||||
| teacher2 | Test course | teacher |
|
||||
|
||||
Scenario: A teacher with the correct capability can access the communication configuration page
|
||||
Given I am on the "Test course" "Course" page logged in as "teacher1"
|
||||
When I navigate to "Communication" in current page administration
|
||||
Then I should see "Communication"
|
||||
|
||||
Scenario: A teacher without the correct capability cannot access the communication configuration page
|
||||
Given I am on the "Test course" "Course" page logged in as "teacher2"
|
||||
Then "Communication" "link" should not exist in current page administration
|
||||
|
||||
Scenario: I cannot see the communication link when communication provider is disabled
|
||||
Given I disable communication experimental feature
|
||||
And I am on the "Test course" "Course" page logged in as "teacher1"
|
||||
Then "Communication" "link" should not exist in current page administration
|
||||
|
||||
@javascript
|
||||
Scenario: The communication form fields toggle dynamically when valid provider is set
|
||||
Given I am on the "Test course" "Course" page logged in as "teacher1"
|
||||
When I navigate to "Communication" in current page administration
|
||||
And I set the following fields to these values:
|
||||
| selectedcommunication | communication_matrix |
|
||||
Then I should see "Room name"
|
||||
And I should see "Room topic"
|
@ -35,6 +35,15 @@ trait communication_test_helper_trait {
|
||||
set_config('enablecommunicationsubsystem', 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable configs for communication subsystem.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function disable_communication_configs(): void {
|
||||
set_config('enablecommunicationsubsystem', 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create course if it does not exist
|
||||
*
|
||||
|
@ -401,28 +401,6 @@ class course_edit_form extends moodleform {
|
||||
$handler->set_parent_context($categorycontext); // For course handler only.
|
||||
$handler->instance_form_definition($mform, empty($course->id) ? 0 : $course->id);
|
||||
|
||||
// Add communication plugins to the form.
|
||||
if (core_communication\api::is_available()) {
|
||||
|
||||
$instanceconfig = core_communication\processor::PROVIDER_NONE;
|
||||
// For new courses.
|
||||
if (empty($course->id)) {
|
||||
$instanceid = 0;
|
||||
if (!empty($courseconfig->coursecommunicationprovider)) {
|
||||
$instanceconfig = $courseconfig->coursecommunicationprovider;
|
||||
}
|
||||
} else {
|
||||
// For existing courses.
|
||||
$instanceid = $course->id;
|
||||
}
|
||||
|
||||
$communication = \core_communication\api::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$instanceid);
|
||||
$communication->form_definition($mform, $instanceconfig);
|
||||
$communication->set_data($course);
|
||||
}
|
||||
|
||||
// When two elements we need a group.
|
||||
$buttonarray = array();
|
||||
@ -494,15 +472,6 @@ class course_edit_form extends moodleform {
|
||||
$handler = core_course\customfield\course_handler::create();
|
||||
$handler->instance_form_definition_after_data($mform, empty($courseid) ? 0 : $courseid);
|
||||
|
||||
// Add communication plugins to the form.
|
||||
if (core_communication\api::is_available()) {
|
||||
$communication = \core_communication\api::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
empty($course->id) ? 0 : $course->id
|
||||
);
|
||||
$communication->form_definition_for_provider($mform);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2322,17 +2322,24 @@ function create_course($data, $editoroptions = NULL) {
|
||||
if (isset($data->tags)) {
|
||||
core_tag_tag::set_item_tags('core', 'course', $course->id, context_course::instance($course->id), $data->tags);
|
||||
}
|
||||
// Set up communication.
|
||||
if (core_communication\api::is_available()) {
|
||||
// Check for default provider config setting.
|
||||
$defaultprovider = get_config('moodlecourse', 'coursecommunicationprovider');
|
||||
$provider = (isset($data->selectedcommunication)) ? $data->selectedcommunication : $defaultprovider;
|
||||
|
||||
// Communication api implementation in course.
|
||||
if (isset($data->selectedcommunication) && core_communication\api::is_available()) {
|
||||
// Prepare the communication api date.
|
||||
$courseimage = course_get_courseimage($course);
|
||||
$communicationroomname = !empty($data->communicationroomname) ? $data->communicationroomname : $data->fullname;
|
||||
$selectedcommunication = $data->selectedcommunication;
|
||||
|
||||
// Communication api call.
|
||||
$communication = \core_communication\api::load_by_instance('core_course', 'coursecommunication', $course->id);
|
||||
$communication->create_and_configure_room($selectedcommunication, $communicationroomname, $courseimage, $data);
|
||||
if (!empty($provider)) {
|
||||
// Prepare the communication api data.
|
||||
$courseimage = course_get_courseimage($course);
|
||||
$communicationroomname = !empty($data->communicationroomname) ? $data->communicationroomname : $data->fullname;
|
||||
// Communication api call.
|
||||
$communication = \core_communication\api::load_by_instance(
|
||||
'core_course',
|
||||
'coursecommunication',
|
||||
$course->id
|
||||
);
|
||||
$communication->create_and_configure_room($provider, $communicationroomname, $courseimage, $data);
|
||||
}
|
||||
}
|
||||
|
||||
// Save custom fields if there are any of them in the form.
|
||||
@ -2463,6 +2470,11 @@ function update_course($data, $editoroptions = NULL) {
|
||||
$provider = 'none';
|
||||
}
|
||||
|
||||
// Attempt to get the communication provider if it wasn't provided in the data.
|
||||
if (empty($provider) && core_communication\api::is_available()) {
|
||||
$provider = \core_communication\api::load_by_instance('core_course', 'coursecommunication', $data->id)->get_provider();
|
||||
}
|
||||
|
||||
// Communication api call.
|
||||
if (!empty($provider) && core_communication\api::is_available()) {
|
||||
// Prepare the communication api data.
|
||||
@ -4004,6 +4016,7 @@ function course_get_user_navigation_options($context, $course = null) {
|
||||
'participants' => false,
|
||||
'search' => false,
|
||||
'tags' => false,
|
||||
'communication' => false,
|
||||
];
|
||||
|
||||
$options->blogs = !empty($CFG->enableblogs) &&
|
||||
@ -4075,6 +4088,10 @@ function course_get_user_navigation_options($context, $course = null) {
|
||||
$options->grades = $grades;
|
||||
}
|
||||
|
||||
if (\core_communication\api::is_available()) {
|
||||
$options->communication = has_capability('moodle/course:configurecoursecommunication', $context);
|
||||
}
|
||||
|
||||
if (\core_competency\api::is_enabled()) {
|
||||
$capabilities = array('moodle/competency:coursecompetencyview', 'moodle/competency:coursecompetencymanage');
|
||||
$options->competencies = has_any_capability($capabilities, $context);
|
||||
@ -5146,3 +5163,32 @@ function course_get_courseimage(\stdClass $course): ?stored_file {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get course specific data for configuring a communication instance.
|
||||
*
|
||||
* @param integer $courseid The course id.
|
||||
* @return array Returns course data, context and heading.
|
||||
*/
|
||||
function course_get_communication_instance_data(int $courseid): array {
|
||||
// Do some checks and prepare instance specific data.
|
||||
$course = get_course($courseid);
|
||||
require_login($course);
|
||||
$context = context_course::instance($course->id);
|
||||
require_capability('moodle/course:configurecoursecommunication', $context);
|
||||
|
||||
$heading = $course->fullname;
|
||||
$returnurl = new moodle_url('/course/view.php', ['id' => $courseid]);
|
||||
|
||||
return [$course, $context, $heading, $returnurl];
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a course using communication configuration data.
|
||||
*
|
||||
* @param stdClass $data The data to update the course with.
|
||||
*/
|
||||
function course_update_communication_instance_data(stdClass $data): void {
|
||||
$data->id = $data->instanceid; // For correct use in update_course.
|
||||
update_course($data);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
@core @core_course
|
||||
@core @core_course @communication
|
||||
Feature: Course communication
|
||||
In order to create a new communication room in for course
|
||||
As an admin
|
||||
@ -7,22 +7,23 @@ Feature: Course communication
|
||||
|
||||
Background:
|
||||
Given the following "courses" exist:
|
||||
| fullname | shortname |
|
||||
| Test course | C |
|
||||
| fullname | shortname |
|
||||
| Course 1 | C1 |
|
||||
And I enable communication experimental feature
|
||||
And I log in as "admin"
|
||||
|
||||
Scenario: I should have matrix plugin by default for new courses
|
||||
Given I go to the courses management page
|
||||
And I should see the "Categories" management page
|
||||
And I click on category "Category 1" in the management interface
|
||||
And I should see the "Course categories and courses" management page
|
||||
And I follow "Create new course"
|
||||
When I click on "Communication" "link"
|
||||
And I set the following fields to these values:
|
||||
| Course full name | Course 2 |
|
||||
| Course short name | C2 |
|
||||
And I press "Save and display"
|
||||
When I navigate to "Communication" in current page administration
|
||||
Then the field "Communication service" matches value "Matrix"
|
||||
|
||||
Scenario: I should have communication disabled by default for existing courses
|
||||
Given I am on "Test course" course homepage
|
||||
When I navigate to "Settings" in current page administration
|
||||
And I click on "Communication" "link"
|
||||
Given I am on "Course 1" course homepage
|
||||
When I navigate to "Communication" in current page administration
|
||||
Then the field "Communication service" matches value "None"
|
||||
|
@ -7303,4 +7303,67 @@ class courselib_test extends advanced_testcase {
|
||||
$image->get_id(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the course_get_communication_instance_data() function.
|
||||
*
|
||||
* @covers ::course_get_communication_instance_data
|
||||
*/
|
||||
public function test_course_get_communication_instance_data(): void {
|
||||
$this->resetAfterTest();
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
|
||||
// Set admin user as a valid enrolment will be checked in the callback function.
|
||||
$this->setAdminUser();
|
||||
|
||||
// Use the callback function and return the data.
|
||||
list($instance, $context, $heading, $returnurl) = component_callback(
|
||||
'core_course',
|
||||
'get_communication_instance_data',
|
||||
[$course->id]
|
||||
);
|
||||
|
||||
// Check the url is as expected.
|
||||
$expectedreturnurl = new moodle_url('/course/view.php', ['id' => $course->id]);
|
||||
$this->assertEquals($expectedreturnurl, $returnurl);
|
||||
|
||||
// Check the context is as expected.
|
||||
$expectedcontext = context_course::instance($course->id);
|
||||
$this->assertEquals($expectedcontext, $context);
|
||||
|
||||
// Check the instance id is as expected.
|
||||
$this->assertEquals($course->id, $instance->id);
|
||||
|
||||
// Check the heading is as expected.
|
||||
$this->assertEquals($course->fullname, $heading);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the course_update_communication_instance_data() function.
|
||||
*
|
||||
* @covers ::course_update_communication_instance_data
|
||||
*/
|
||||
public function test_course_update_communication_instance_data(): void {
|
||||
$this->resetAfterTest();
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
|
||||
// Set some data to update with.
|
||||
$data = new stdClass();
|
||||
$data->instanceid = $course->id;
|
||||
$data->fullname = 'newname';
|
||||
|
||||
// These should not be the same yet.
|
||||
$this->assertNotEquals($course->fullname, $data->fullname);
|
||||
|
||||
// Use the callback function to update the course with the data.
|
||||
component_callback(
|
||||
'core_course',
|
||||
'update_communication_instance_data',
|
||||
[$data]
|
||||
);
|
||||
|
||||
// Get the course and check it was updated.
|
||||
$course = get_course($course->id);
|
||||
$this->assertEquals($course->fullname, $data->fullname);
|
||||
}
|
||||
}
|
||||
|
@ -2636,7 +2636,7 @@ class externallib_test extends externallib_advanced_testcase {
|
||||
foreach ($course['options'] as $option) {
|
||||
$navoptions->{$option['name']} = $option['available'];
|
||||
}
|
||||
$this->assertCount(8, $course['options']);
|
||||
$this->assertCount(9, $course['options']);
|
||||
if ($course['id'] == SITEID) {
|
||||
$this->assertTrue($navoptions->blogs);
|
||||
$this->assertFalse($navoptions->notes);
|
||||
@ -2646,6 +2646,7 @@ class externallib_test extends externallib_advanced_testcase {
|
||||
$this->assertFalse($navoptions->grades);
|
||||
$this->assertFalse($navoptions->search);
|
||||
$this->assertTrue($navoptions->competencies);
|
||||
$this->assertFalse($navoptions->communication);
|
||||
} else {
|
||||
$this->assertTrue($navoptions->blogs);
|
||||
$this->assertFalse($navoptions->notes);
|
||||
@ -2655,6 +2656,7 @@ class externallib_test extends externallib_advanced_testcase {
|
||||
$this->assertTrue($navoptions->grades);
|
||||
$this->assertFalse($navoptions->search);
|
||||
$this->assertTrue($navoptions->competencies);
|
||||
$this->assertFalse($navoptions->communication);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,12 +23,14 @@
|
||||
*/
|
||||
|
||||
$string['communication'] = 'Communication';
|
||||
$string['communicationdisabled'] = 'Communication is disabled.';
|
||||
$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['communicationroompending'] = 'Your {$a} room will be ready soon.';
|
||||
$string['communicationroomready'] = 'Your {$a} room is ready!';
|
||||
$string['managecommunicationproviders'] = 'Manage communication providers';
|
||||
$string['nocommunicationinstance'] = 'No communication instance found.';
|
||||
$string['nocommunicationprovider'] = 'No communication provider found.';
|
||||
$string['nocommunicationselected'] = 'None';
|
||||
$string['privacy:metadata:communication_user'] = 'The communication user table stores the user id and communication id for communication provider mapping.';
|
||||
|
@ -166,6 +166,7 @@ $string['context'] = 'Context';
|
||||
$string['contextrolenotallowed'] = 'Role {$a} not allowed in this context.';
|
||||
$string['course:activityvisibility'] = 'Hide/show activities';
|
||||
$string['course:bulkmessaging'] = 'Send a message to many people';
|
||||
$string['course:configurecoursecommunication'] = 'Configure course communication settings';
|
||||
$string['course:create'] = 'Create courses';
|
||||
$string['course:creategroupconversations'] = 'Create group conversations';
|
||||
$string['course:delete'] = 'Delete courses';
|
||||
|
@ -89,6 +89,7 @@ class secondary extends view {
|
||||
'grades' => 2,
|
||||
'badgesview' => 7,
|
||||
'competencies' => 8,
|
||||
'communication' => 14,
|
||||
],
|
||||
self::TYPE_CUSTOM => [
|
||||
'contentbank' => 5,
|
||||
|
@ -2714,4 +2714,14 @@ $capabilities = array(
|
||||
'manager' => CAP_ALLOW,
|
||||
]
|
||||
],
|
||||
|
||||
// Allow users to configure course communication rooms.
|
||||
'moodle/course:configurecoursecommunication' => [
|
||||
'captype' => 'write',
|
||||
'contextlevel' => CONTEXT_COURSE,
|
||||
'archetypes' => [
|
||||
'editingteacher' => CAP_ALLOW,
|
||||
'manager' => CAP_ALLOW,
|
||||
]
|
||||
],
|
||||
);
|
||||
|
@ -2976,6 +2976,14 @@ class global_navigation extends navigation_node {
|
||||
}
|
||||
}
|
||||
|
||||
// Add link for configuring communication.
|
||||
if ($navoptions->communication) {
|
||||
$url = new moodle_url('/communication/configure.php', ['instanceid' => $course->id,
|
||||
'instancetype' => 'coursecommunication', 'component' => 'core_course']);
|
||||
$coursenode->add(get_string('communication', 'communication'), $url,
|
||||
navigation_node::TYPE_SETTING, null, 'communication');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$version = 2023080300.00; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
$version = 2023080300.01; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
// RR = release increments - 00 in DEV branches.
|
||||
// .XX = incremental changes.
|
||||
$release = '4.3dev (Build: 20230728)'; // Human-friendly version name
|
||||
|
Loading…
x
Reference in New Issue
Block a user