Merge branch 'MDL-78553-master' of https://github.com/davewoloszyn/moodle

This commit is contained in:
Huong Nguyen 2023-08-03 09:44:24 +07:00
commit aeeb1653c0
No known key found for this signature in database
GPG Key ID: 40D88AB693A3E72A
23 changed files with 400 additions and 74 deletions

View File

@ -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

View File

@ -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"}

View File

@ -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();

View File

@ -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',

View 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);
}
}

View 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();

View File

@ -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"

View File

@ -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

View File

@ -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');

View File

@ -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();
}
}

View File

@ -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"

View File

@ -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
*

View File

@ -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);
}
}
/**

View File

@ -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);
}

View File

@ -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"

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

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

View File

@ -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';

View File

@ -89,6 +89,7 @@ class secondary extends view {
'grades' => 2,
'badgesview' => 7,
'competencies' => 8,
'communication' => 14,
],
self::TYPE_CUSTOM => [
'contentbank' => 5,

View File

@ -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,
]
],
);

View File

@ -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;
}
/**

View File

@ -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