mirror of
https://github.com/moodle/moodle.git
synced 2025-04-21 00:12:56 +02:00
Merge branch 'MDL-81765-main-v02' of https://github.com/ferranrecio/moodle
This commit is contained in:
commit
096897d623
@ -16,7 +16,13 @@
|
||||
|
||||
namespace core_courseformat;
|
||||
|
||||
use action_menu;
|
||||
use cm_info;
|
||||
use core_courseformat\base as course_format;
|
||||
use core_courseformat\formatactions;
|
||||
use core_courseformat\output\local\content\section\controlmenu;
|
||||
use core_courseformat\stateupdates;
|
||||
use renderer_base;
|
||||
use section_info;
|
||||
use stdClass;
|
||||
|
||||
@ -110,4 +116,56 @@ abstract class sectiondelegatemodule extends sectiondelegate {
|
||||
private function get_module_name(): string {
|
||||
return \core_component::normalize_component($this->sectioninfo->component)[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync the section renaming with the activity name.
|
||||
*
|
||||
* @param section_info $section
|
||||
* @param string|null $newname
|
||||
* @return string|null
|
||||
*/
|
||||
public function preprocess_section_name(section_info $section, ?string $newname): ?string {
|
||||
$cm = get_coursemodule_from_instance($this->get_module_name(), $section->itemid);
|
||||
if (!$cm) {
|
||||
return $newname;
|
||||
}
|
||||
if (empty($newname) || $newname === $cm->name) {
|
||||
return $cm->name;
|
||||
}
|
||||
formatactions::cm($section->course)->rename($cm->id, $newname);
|
||||
return $newname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow delegate plugin to modify the available section menu.
|
||||
*
|
||||
* @param course_format $format The course format instance.
|
||||
* @param controlmenu $controlmenu The control menu instance.
|
||||
* @param renderer_base $output The renderer instance.
|
||||
* @return action_menu|null The new action menu with the list of edit control items or null if no action menu is available.
|
||||
*/
|
||||
public function get_section_action_menu(
|
||||
course_format $format,
|
||||
controlmenu $controlmenu,
|
||||
renderer_base $output,
|
||||
): ?action_menu {
|
||||
$controlmenuclass = $format->get_output_classname('content\\cm\\controlmenu');
|
||||
$controlmenu = new $controlmenuclass(
|
||||
$format,
|
||||
$this->sectioninfo,
|
||||
$this->cm,
|
||||
);
|
||||
return $controlmenu->get_action_menu($output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add extra state updates when put or create a section.
|
||||
*
|
||||
* @param section_info $section the affected section.
|
||||
* @param stateupdates $updates the state updates object to notify the UI.
|
||||
*/
|
||||
public function put_section_state_extra_updates(section_info $section, stateupdates $updates): void {
|
||||
$cm = get_coursemodule_from_instance($this->get_module_name(), $section->itemid);
|
||||
$updates->add_cm_put($cm->id);
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
"number": 1,
|
||||
"sectionurl": "#",
|
||||
"indexcollapsed": 0,
|
||||
"component": null,
|
||||
"current": 1,
|
||||
"visible": 1,
|
||||
"hasrestrictions": 0,
|
||||
@ -56,7 +57,7 @@
|
||||
}
|
||||
}}
|
||||
<div
|
||||
class="courseindex-section {{#current}}current{{/current}}"
|
||||
class="courseindex-section {{#current}}current{{/current}} {{#component}}delegated-section{{/component}}"
|
||||
id="course-index-section-{{id}}"
|
||||
data-for="section"
|
||||
data-id="{{id}}"
|
||||
|
@ -18,6 +18,7 @@ namespace core_courseformat;
|
||||
|
||||
use course_modinfo;
|
||||
use moodle_exception;
|
||||
use ReflectionMethod;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
@ -1419,4 +1420,122 @@ class stateactions_test extends \advanced_testcase {
|
||||
'section0'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that set_cm_indentation on activities with a delegated section.
|
||||
*
|
||||
* @covers ::set_cm_indentation
|
||||
*/
|
||||
public function test_set_cm_indentation_delegated_section(): void {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$manager = \core_plugin_manager::resolve_plugininfo_class('mod');
|
||||
$manager::enable_plugin('subsection', 1);
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$subsection = $this->getDataGenerator()->create_module('subsection', ['course' => $course]);
|
||||
$otheractvity = $this->getDataGenerator()->create_module('forum', ['course' => $course]);
|
||||
$this->setAdminUser();
|
||||
|
||||
// Initialise stateupdates.
|
||||
$courseformat = course_get_format($course->id);
|
||||
|
||||
// Execute given method.
|
||||
$updates = new stateupdates($courseformat);
|
||||
$actions = new stateactions();
|
||||
$actions->cm_moveright(
|
||||
$updates,
|
||||
$course,
|
||||
[$subsection->cmid, $otheractvity->cmid],
|
||||
);
|
||||
|
||||
// Format results in a way we can compare easily.
|
||||
$results = $this->summarize_updates($updates);
|
||||
|
||||
// The state actions does not use create or remove actions because they are designed
|
||||
// to refresh parts of the state.
|
||||
$this->assertEquals(0, $results['create']['count']);
|
||||
$this->assertEquals(0, $results['remove']['count']);
|
||||
|
||||
// Mod subsection should be ignored.
|
||||
$this->assertEquals(1, $results['put']['count']);
|
||||
|
||||
// Validate course, section and cm.
|
||||
$this->assertArrayHasKey($otheractvity->cmid, $results['put']['cm']);
|
||||
$this->assertArrayNotHasKey($subsection->cmid, $results['put']['cm']);
|
||||
|
||||
// Validate activity indentation.
|
||||
$mondinfo = get_fast_modinfo($course);
|
||||
$this->assertEquals(1, $mondinfo->get_cm($otheractvity->cmid)->indent);
|
||||
$this->assertEquals(1, $DB->get_field('course_modules', 'indent', ['id' => $otheractvity->cmid]));
|
||||
$this->assertEquals(0, $mondinfo->get_cm($subsection->cmid)->indent);
|
||||
$this->assertEquals(0, $DB->get_field('course_modules', 'indent', ['id' => $subsection->cmid]));
|
||||
|
||||
// Now move left.
|
||||
$updates = new stateupdates($courseformat);
|
||||
$actions->cm_moveleft(
|
||||
$updates,
|
||||
$course,
|
||||
[$subsection->cmid, $otheractvity->cmid],
|
||||
);
|
||||
|
||||
// Format results in a way we can compare easily.
|
||||
$results = $this->summarize_updates($updates);
|
||||
|
||||
// The state actions does not use create or remove actions because they are designed
|
||||
// to refresh parts of the state.
|
||||
$this->assertEquals(0, $results['create']['count']);
|
||||
$this->assertEquals(0, $results['remove']['count']);
|
||||
|
||||
// Mod subsection should be ignored.
|
||||
$this->assertEquals(1, $results['put']['count']);
|
||||
|
||||
// Validate course, section and cm.
|
||||
$this->assertArrayHasKey($otheractvity->cmid, $results['put']['cm']);
|
||||
$this->assertArrayNotHasKey($subsection->cmid, $results['put']['cm']);
|
||||
|
||||
// Validate activity indentation.
|
||||
$mondinfo = get_fast_modinfo($course);
|
||||
$this->assertEquals(0, $mondinfo->get_cm($otheractvity->cmid)->indent);
|
||||
$this->assertEquals(0, $DB->get_field('course_modules', 'indent', ['id' => $otheractvity->cmid]));
|
||||
$this->assertEquals(0, $mondinfo->get_cm($subsection->cmid)->indent);
|
||||
$this->assertEquals(0, $DB->get_field('course_modules', 'indent', ['id' => $subsection->cmid]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for filter_cms_with_section_delegate protected method.
|
||||
*
|
||||
* @covers ::filter_cms_with_section_delegate
|
||||
*/
|
||||
public function test_filter_cms_with_section_delegate(): void {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$manager = \core_plugin_manager::resolve_plugininfo_class('mod');
|
||||
$manager::enable_plugin('subsection', 1);
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$subsection = $this->getDataGenerator()->create_module('subsection', ['course' => $course]);
|
||||
$otheractvity = $this->getDataGenerator()->create_module('forum', ['course' => $course]);
|
||||
$this->setAdminUser();
|
||||
|
||||
$courseformat = course_get_format($course->id);
|
||||
|
||||
$modinfo = $courseformat->get_modinfo();
|
||||
$subsectioninfo = $modinfo->get_cm($subsection->cmid);
|
||||
$otheractvityinfo = $modinfo->get_cm($otheractvity->cmid);
|
||||
|
||||
$actions = new stateactions();
|
||||
|
||||
$method = new ReflectionMethod($actions, 'filter_cms_with_section_delegate');
|
||||
$result = $method->invoke($actions, [$subsectioninfo, $otheractvityinfo]);
|
||||
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertArrayHasKey($otheractvity->cmid, $result);
|
||||
$this->assertArrayNotHasKey($subsection->cmid, $result);
|
||||
$this->assertEquals($otheractvityinfo, $result[$otheractvityinfo->id]);
|
||||
}
|
||||
}
|
||||
|
@ -320,6 +320,7 @@
|
||||
"quiz",
|
||||
"resource",
|
||||
"scorm",
|
||||
"subsection",
|
||||
"survey",
|
||||
"url",
|
||||
"wiki",
|
||||
|
@ -1787,4 +1787,64 @@ class modinfolib_test extends advanced_testcase {
|
||||
$cacherevthree = $DB->get_field('course', 'cacherev', ['id' => $coursethree->id]);
|
||||
$this->assertGreaterThan($prevcacherevthree, $cacherevthree);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_sections_delegated_by_cm method
|
||||
*
|
||||
* @covers \course_modinfo::get_sections_delegated_by_cm
|
||||
*/
|
||||
public function test_get_sections_delegated_by_cm(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$manager = \core_plugin_manager::resolve_plugininfo_class('mod');
|
||||
$manager::enable_plugin('subsection', 1);
|
||||
|
||||
$course = $this->getDataGenerator()->create_course(['numsections' => 1]);
|
||||
|
||||
$modinfo = get_fast_modinfo($course);
|
||||
$delegatedsections = $modinfo->get_sections_delegated_by_cm();
|
||||
$this->assertEmpty($delegatedsections);
|
||||
|
||||
// Add a section delegated by a course module.
|
||||
$subsection = $this->getDataGenerator()->create_module('subsection', ['course' => $course]);
|
||||
$modinfo = get_fast_modinfo($course);
|
||||
$delegatedsections = $modinfo->get_sections_delegated_by_cm();
|
||||
$this->assertCount(1, $delegatedsections);
|
||||
$this->assertArrayHasKey($subsection->cmid, $delegatedsections);
|
||||
|
||||
// Add a section delegated by a block.
|
||||
formatactions::section($course)->create_delegated('block_site_main_menu', 1);
|
||||
$modinfo = get_fast_modinfo($course);
|
||||
$delegatedsections = $modinfo->get_sections_delegated_by_cm();
|
||||
// Sections delegated by a block shouldn't be returned.
|
||||
$this->assertCount(1, $delegatedsections);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_sections_delegated_by_cm method
|
||||
*
|
||||
* @covers \cm_info::get_delegated_section_info
|
||||
*/
|
||||
public function test_get_delegated_section_info(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$manager = \core_plugin_manager::resolve_plugininfo_class('mod');
|
||||
$manager::enable_plugin('subsection', 1);
|
||||
|
||||
$course = $this->getDataGenerator()->create_course(['numsections' => 1]);
|
||||
|
||||
// Add a section delegated by a course module.
|
||||
$subsection = $this->getDataGenerator()->create_module('subsection', ['course' => $course]);
|
||||
$otheractivity = $this->getDataGenerator()->create_module('page', ['course' => $course]);
|
||||
|
||||
$modinfo = get_fast_modinfo($course);
|
||||
$delegatedsections = $modinfo->get_sections_delegated_by_cm();
|
||||
|
||||
$delegated = $modinfo->get_cm($subsection->cmid)->get_delegated_section_info();
|
||||
$this->assertNotNull($delegated);
|
||||
$this->assertEquals($delegated, $delegatedsections[$subsection->cmid]);
|
||||
|
||||
$delegated = $modinfo->get_cm($otheractivity->cmid)->get_delegated_section_info();
|
||||
$this->assertNull($delegated);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* The task that provides all the steps to perform a complete backup is defined here.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @category backup
|
||||
* @copyright 2023 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
// More information about the backup process: {@link https://docs.moodle.org/dev/Backup_API}.
|
||||
// More information about the restore process: {@link https://docs.moodle.org/dev/Restore_API}.
|
||||
|
||||
require_once($CFG->dirroot.'//mod/subsection/backup/moodle2/backup_subsection_stepslib.php');
|
||||
|
||||
/**
|
||||
* Provides all the settings and steps to perform a complete backup of mod_subsection.
|
||||
*/
|
||||
class backup_subsection_activity_task extends backup_activity_task {
|
||||
|
||||
/**
|
||||
* Defines particular settings for the plugin.
|
||||
*/
|
||||
protected function define_my_settings() {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines particular steps for the backup process.
|
||||
*/
|
||||
protected function define_my_steps() {
|
||||
$this->add_step(new backup_subsection_activity_structure_step('subsection_structure', 'subsection.xml'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Codes the transformations to perform in the activity in order to get transportable (encoded) links.
|
||||
*
|
||||
* @param string $content
|
||||
* @return string
|
||||
*/
|
||||
public static function encode_content_links($content) {
|
||||
global $CFG;
|
||||
|
||||
$base = preg_quote($CFG->wwwroot, "/");
|
||||
|
||||
// Link to the list of subsections.
|
||||
$search = "/(".$base."\/mod\/subsection\/index.php\?id\=)([0-9]+)/";
|
||||
$content = preg_replace($search, '$@SUBSECTIONINDEX*$2@$', $content);
|
||||
|
||||
// Link to page view by moduleid.
|
||||
$search = "/(".$base."\/mod\/subsection\/view.php\?id\=)([0-9]+)/";
|
||||
$content = preg_replace($search, '$@SUBSECTIONVIEWBYID*$2@$', $content);
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
48
mod/subsection/backup/moodle2/backup_subsection_stepslib.php
Normal file
48
mod/subsection/backup/moodle2/backup_subsection_stepslib.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Backup steps for mod_subsection are defined here.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @category backup
|
||||
* @copyright 2023 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
// More information about the backup process: {@link https://docs.moodle.org/dev/Backup_API}.
|
||||
|
||||
/**
|
||||
* Define the complete structure for backup, with file and id annotations.
|
||||
*/
|
||||
class backup_subsection_activity_structure_step extends backup_activity_structure_step {
|
||||
|
||||
/**
|
||||
* Defines the structure of the resulting xml file.
|
||||
*
|
||||
* @return backup_nested_element The structure wrapped by the common 'activity' element.
|
||||
*/
|
||||
protected function define_structure() {
|
||||
// Define each element separated.
|
||||
$subsection = new backup_nested_element('subsection', ['id'], ['name', 'timemodified']);
|
||||
|
||||
// Define sources.
|
||||
$subsection->set_source_table('subsection', ['id' => backup::VAR_ACTIVITYID]);
|
||||
|
||||
// Return the root element (subsection), wrapped into standard activity structure.
|
||||
return $this->prepare_activity_structure($subsection);
|
||||
}
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* The task that provides a complete restore of mod_subsection is defined here.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @category backup
|
||||
* @copyright 2023 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
// More information about the backup process: {@link https://docs.moodle.org/dev/Backup_API}.
|
||||
// More information about the restore process: {@link https://docs.moodle.org/dev/Restore_API}.
|
||||
|
||||
require_once($CFG->dirroot.'//mod/subsection/backup/moodle2/restore_subsection_stepslib.php');
|
||||
|
||||
/**
|
||||
* Restore task for mod_subsection.
|
||||
*/
|
||||
class restore_subsection_activity_task extends restore_activity_task {
|
||||
|
||||
/**
|
||||
* Defines particular settings that this activity can have.
|
||||
*/
|
||||
protected function define_my_settings() {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines particular steps that this activity can have.
|
||||
*
|
||||
* @return base_step.
|
||||
*/
|
||||
protected function define_my_steps() {
|
||||
$this->add_step(new restore_subsection_activity_structure_step('subsection_structure', 'subsection.xml'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the contents in the activity that must be processed by the link decoder.
|
||||
*
|
||||
* @return array.
|
||||
*/
|
||||
public static function define_decode_contents() {
|
||||
$contents = [];
|
||||
|
||||
// Define the contents.
|
||||
|
||||
return $contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the decoding rules for links belonging to the activity to be executed by the link decoder.
|
||||
*
|
||||
* @return array.
|
||||
*/
|
||||
public static function define_decode_rules() {
|
||||
$rules = [];
|
||||
|
||||
// Define the rules.
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the restore log rules that will be applied by the
|
||||
* {@see restore_logs_processor} when restoring mod_subsection logs. It
|
||||
* must return one array of {@see restore_log_rule} objects.
|
||||
*
|
||||
* @return array.
|
||||
*/
|
||||
public static function define_restore_log_rules() {
|
||||
$rules = [];
|
||||
|
||||
// Define the rules.
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* All the steps to restore mod_subsection are defined here.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @category backup
|
||||
* @copyright 2023 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
use mod_subsection\manager;
|
||||
|
||||
// More information about the restore process: {@link https://docs.moodle.org/dev/Restore_API}.
|
||||
|
||||
/**
|
||||
* Defines the structure step to restore one mod_subsection activity.
|
||||
*/
|
||||
class restore_subsection_activity_structure_step extends restore_activity_structure_step {
|
||||
|
||||
/**
|
||||
* Defines the structure to be restored.
|
||||
*
|
||||
* @return restore_path_element[].
|
||||
*/
|
||||
protected function define_structure() {
|
||||
$paths = [];
|
||||
$paths[] = new restore_path_element('subsection', '/activity/subsection');
|
||||
|
||||
// Return the paths wrapped into standard activity structure.
|
||||
return $this->prepare_activity_structure($paths);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the subsection element.
|
||||
*
|
||||
* @param \stdClass $data the data to be processed.
|
||||
*/
|
||||
protected function process_subsection($data) {
|
||||
global $DB;
|
||||
|
||||
$data = (object)$data;
|
||||
$oldid = $data->id;
|
||||
$data->course = $this->get_courseid();
|
||||
|
||||
// Insert the subsection record.
|
||||
$newitemid = $DB->insert_record('subsection', $data);
|
||||
// Immediately after inserting "activity" record, call this.
|
||||
$this->apply_activity_instance($newitemid);
|
||||
$this->set_delegated_section_mapping(manager::PLUGINNAME, $oldid, $newitemid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines post-execution actions.
|
||||
*/
|
||||
protected function after_execute() {
|
||||
return;
|
||||
}
|
||||
}
|
38
mod/subsection/classes/courseformat/sectiondelegate.php
Normal file
38
mod/subsection/classes/courseformat/sectiondelegate.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 mod_subsection\courseformat;
|
||||
|
||||
use action_menu;
|
||||
use core_courseformat\base as course_format;
|
||||
use core_courseformat\output\local\content\section\controlmenu;
|
||||
use core_courseformat\sectiondelegatemodule;
|
||||
use mod_subsection\manager;
|
||||
use renderer_base;
|
||||
|
||||
/**
|
||||
* Subsection plugin section delegate class.
|
||||
*
|
||||
* This class implements all the integrations needed to delegate core section logic to
|
||||
* the plugin. For a basic subsection plugin, all methods are inherited from the
|
||||
* sectiondelegatemodule class.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @copyright 2023 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class sectiondelegate extends sectiondelegatemodule {
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
<?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 mod_subsection\event;
|
||||
|
||||
/**
|
||||
* The mod_subsection viewed event class.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @since Moodle 4.5
|
||||
* @copyright 2023 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class course_module_instance_list_viewed extends \core\event\course_module_instance_list_viewed {
|
||||
// No code required here as the parent class handles it all.
|
||||
}
|
41
mod/subsection/classes/event/course_module_viewed.php
Normal file
41
mod/subsection/classes/event/course_module_viewed.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?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 mod_subsection\event;
|
||||
|
||||
/**
|
||||
* The mod_subsection viewed event class.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @since Moodle 4.5
|
||||
* @copyright 2023 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class course_module_viewed extends \core\event\course_module_viewed {
|
||||
|
||||
/**
|
||||
* Init method.
|
||||
*/
|
||||
protected function init() {
|
||||
$this->data['crud'] = 'r';
|
||||
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
|
||||
$this->data['objecttable'] = 'subsection';
|
||||
}
|
||||
|
||||
public static function get_objectid_mapping() {
|
||||
return ['db' => 'subsection', 'restore' => 'subsection'];
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
<?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 mod_subsection\local\callbacks;
|
||||
|
||||
use core_courseformat\hook\after_cm_name_edited;
|
||||
use core_courseformat\formatactions;
|
||||
use mod_subsection\manager;
|
||||
|
||||
/**
|
||||
* Class after activity renaming hook handler.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @copyright 2024 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class after_cm_name_edited_handler {
|
||||
/**
|
||||
* Handle the activity name change.
|
||||
*
|
||||
* @param after_cm_name_edited $hook
|
||||
*/
|
||||
public static function callback(after_cm_name_edited $hook): void {
|
||||
$cm = $hook->get_cm();
|
||||
|
||||
if ($cm->modname !== manager::MODULE) {
|
||||
return;
|
||||
}
|
||||
|
||||
$section = get_fast_modinfo($cm->course)->get_section_info_by_component(manager::PLUGINNAME, $cm->instance);
|
||||
if ($section) {
|
||||
formatactions::section($cm->course)->update($section, ['name' => $hook->get_newname()]);
|
||||
}
|
||||
}
|
||||
}
|
183
mod/subsection/classes/manager.php
Normal file
183
mod/subsection/classes/manager.php
Normal file
@ -0,0 +1,183 @@
|
||||
<?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 mod_subsection;
|
||||
|
||||
use cm_info;
|
||||
use context_module;
|
||||
use completion_info;
|
||||
use mod_subsection\event\course_module_viewed;
|
||||
use moodle_page;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Class manager for subsection
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @copyright 2023 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class manager {
|
||||
|
||||
/** Module name. */
|
||||
const MODULE = 'subsection';
|
||||
|
||||
/** The plugin name. */
|
||||
const PLUGINNAME = 'mod_subsection';
|
||||
|
||||
/** @var string plugin path. */
|
||||
public $path;
|
||||
|
||||
/** @var stdClass course_module record. */
|
||||
private $instance;
|
||||
|
||||
/** @var context_module the current context. */
|
||||
private $context;
|
||||
|
||||
/** @var cm_info course_modules record. */
|
||||
private $cm;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param cm_info $cm course module info object
|
||||
* @param stdClass $instance activity instance object.
|
||||
*/
|
||||
public function __construct(cm_info $cm, stdClass $instance) {
|
||||
global $CFG;
|
||||
$this->cm = $cm;
|
||||
$this->instance = $instance;
|
||||
$this->context = context_module::instance($cm->id);
|
||||
$this->instance->cmidnumber = $cm->idnumber;
|
||||
$this->path = $CFG->dirroot . '/mod/' . self::MODULE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a manager instance from an instance record.
|
||||
*
|
||||
* @param stdClass $instance an activity record
|
||||
* @return manager
|
||||
*/
|
||||
public static function create_from_instance(stdClass $instance): self {
|
||||
$cm = get_coursemodule_from_instance(self::MODULE, $instance->id);
|
||||
// Ensure that $this->cm is a cm_info object.
|
||||
$cm = cm_info::create($cm);
|
||||
return new self($cm, $instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a manager instance from a course_modules record.
|
||||
*
|
||||
* @param stdClass|cm_info $cm an activity record
|
||||
* @return manager
|
||||
*/
|
||||
public static function create_from_coursemodule($cm): self {
|
||||
global $DB;
|
||||
// Ensure that $this->cm is a cm_info object.
|
||||
$cm = cm_info::create($cm);
|
||||
$instance = $DB->get_record(self::MODULE, ['id' => $cm->instance], '*', MUST_EXIST);
|
||||
return new self($cm, $instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a manager instance from a record id.
|
||||
*
|
||||
* @param int $courseid the course id
|
||||
* @param int $id an activity id
|
||||
* @return manager
|
||||
*/
|
||||
public static function create_from_id(int $courseid, int $id): self {
|
||||
$cm = get_coursemodule_from_instance('subsection', $id, $courseid);
|
||||
return self::create_from_coursemodule($cm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a manager instance from a subsection_record entry.
|
||||
*
|
||||
* @param stdClass $record the subsection_record record
|
||||
* @return manager
|
||||
*/
|
||||
public static function create_from_data_record($record): self {
|
||||
global $DB;
|
||||
$instance = $DB->get_record(self::MODULE, ['id' => $record->dataid], '*', MUST_EXIST);
|
||||
$cm = get_coursemodule_from_instance(self::MODULE, $instance->id);
|
||||
$cm = cm_info::create($cm);
|
||||
return new self($cm, $instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current context.
|
||||
*
|
||||
* @return context_module
|
||||
*/
|
||||
public function get_context(): context_module {
|
||||
return $this->context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current instance.
|
||||
*
|
||||
* @return stdClass the instance record
|
||||
*/
|
||||
public function get_instance(): stdClass {
|
||||
return $this->instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current cm_info.
|
||||
*
|
||||
* @return cm_info the course module
|
||||
*/
|
||||
public function get_coursemodule(): cm_info {
|
||||
return $this->cm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current module renderer.
|
||||
*
|
||||
* @param moodle_page|null $page the current page
|
||||
* @return \mod_subsection_renderer the module renderer
|
||||
*/
|
||||
public function get_renderer(?moodle_page $page = null): \mod_subsection_renderer {
|
||||
global $PAGE;
|
||||
$page = $page ?? $PAGE;
|
||||
return $page->get_renderer(self::PLUGINNAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger module viewed event and set the module viewed for completion.
|
||||
*
|
||||
* @param stdClass $course course object
|
||||
*/
|
||||
public function set_module_viewed(stdClass $course) {
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/completionlib.php');
|
||||
|
||||
// Trigger module viewed event.
|
||||
$event = course_module_viewed::create([
|
||||
'objectid' => $this->instance->id,
|
||||
'context' => $this->context,
|
||||
]);
|
||||
$event->add_record_snapshot('course', $course);
|
||||
$event->add_record_snapshot('course_modules', $this->cm);
|
||||
$event->add_record_snapshot(self::MODULE, $this->instance);
|
||||
$event->trigger();
|
||||
|
||||
// Completion.
|
||||
$completion = new completion_info($course);
|
||||
$completion->set_module_viewed($this->cm);
|
||||
}
|
||||
}
|
37
mod/subsection/classes/privacy/provider.php
Normal file
37
mod/subsection/classes/privacy/provider.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
namespace mod_subsection\privacy;
|
||||
|
||||
/**
|
||||
* Privacy API implementation for the Subsection plugin.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @category privacy
|
||||
* @copyright 2023 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class provider implements \core_privacy\local\metadata\null_provider {
|
||||
|
||||
/**
|
||||
* Returns stringid of a text explaining that this plugin stores no personal data.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_reason(): string {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
41
mod/subsection/db/access.php
Normal file
41
mod/subsection/db/access.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Plugin capabilities are defined here.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @category access
|
||||
* @copyright 2023 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$capabilities = [
|
||||
|
||||
'mod/subsection:addinstance' => [
|
||||
'riskbitmask' => RISK_XSS,
|
||||
|
||||
'captype' => 'write',
|
||||
'contextlevel' => CONTEXT_COURSE,
|
||||
'archetypes' => [
|
||||
'editingteacher' => CAP_ALLOW,
|
||||
'manager' => CAP_ALLOW,
|
||||
],
|
||||
'clonepermissionsfrom' => 'moodle/course:manageactivities',
|
||||
],
|
||||
];
|
33
mod/subsection/db/hooks.php
Normal file
33
mod/subsection/db/hooks.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Hook callbacks for Subsection
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @copyright 2024 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$callbacks = [
|
||||
[
|
||||
'hook' => core_courseformat\hook\after_cm_name_edited::class,
|
||||
'callback' => 'mod_subsection\local\callbacks\after_cm_name_edited_handler::callback',
|
||||
'priority' => 0,
|
||||
],
|
||||
];
|
36
mod/subsection/db/install.php
Normal file
36
mod/subsection/db/install.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Code to be executed after the plugin's database scheme has been installed is defined here.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @category upgrade
|
||||
* @copyright 2023 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Custom code to be run on installing the plugin.
|
||||
*/
|
||||
function xmldb_subsection_install() {
|
||||
global $DB;
|
||||
|
||||
// Disable the chat activity module on new installs by default.
|
||||
$DB->set_field('modules', 'visible', 0, ['name' => 'subsection']);
|
||||
|
||||
return true;
|
||||
}
|
23
mod/subsection/db/install.xml
Normal file
23
mod/subsection/db/install.xml
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<XMLDB PATH="mod/subsection/db" VERSION="20231116" COMMENT="XMLDB file for Moodle mod_subsection"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
|
||||
>
|
||||
<TABLES>
|
||||
<TABLE NAME="subsection" COMMENT="Stores the delegated subsection instances.">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
|
||||
<FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
|
||||
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
|
||||
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
||||
<KEY NAME="fk_course" TYPE="foreign" FIELDS="course" REFTABLE="course" REFFIELDS="id"/>
|
||||
</KEYS>
|
||||
<INDEXES>
|
||||
<INDEX NAME="course" UNIQUE="false" FIELDS="course"/>
|
||||
</INDEXES>
|
||||
</TABLE>
|
||||
</TABLES>
|
||||
</XMLDB>
|
31
mod/subsection/db/uninstall.php
Normal file
31
mod/subsection/db/uninstall.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Code that is executed before the tables and data are dropped during the plugin uninstallation.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @category upgrade
|
||||
* @copyright 2023 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Custom uninstallation procedure.
|
||||
*/
|
||||
function xmldb_subsection_uninstall() {
|
||||
return true;
|
||||
}
|
43
mod/subsection/db/upgrade.php
Normal file
43
mod/subsection/db/upgrade.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Plugin upgrade steps are defined here.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @category upgrade
|
||||
* @copyright 2023 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Execute mod_subsection upgrade from the given old version.
|
||||
*
|
||||
* @param int $oldversion
|
||||
* @return bool
|
||||
*/
|
||||
function xmldb_subsection_upgrade($oldversion) {
|
||||
global $DB;
|
||||
|
||||
$dbman = $DB->get_manager();
|
||||
|
||||
// For further information please read {@link https://docs.moodle.org/dev/Upgrade_API}.
|
||||
//
|
||||
// You will also have to create the db/install.xml file by using the XMLDB Editor.
|
||||
// Documentation for the XMLDB Editor can be found at {@link https://docs.moodle.org/dev/XMLDB_editor}.
|
||||
|
||||
return true;
|
||||
}
|
89
mod/subsection/index.php
Normal file
89
mod/subsection/index.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Display information about all the mod_subsection modules in the requested course.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @copyright 2023 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require(__DIR__.'/../../config.php');
|
||||
|
||||
require_once(__DIR__.'/lib.php');
|
||||
|
||||
$id = required_param('id', PARAM_INT);
|
||||
|
||||
$course = $DB->get_record('course', ['id' => $id], '*', MUST_EXIST);
|
||||
require_course_login($course);
|
||||
|
||||
$coursecontext = context_course::instance($course->id);
|
||||
$event = \mod_subsection\event\course_module_instance_list_viewed::create(['context' => $coursecontext]);
|
||||
$event->add_record_snapshot('course', $course);
|
||||
$event->trigger();
|
||||
|
||||
$PAGE->set_url('/mod/subsection/index.php', ['id' => $id]);
|
||||
$PAGE->set_title(format_string($course->fullname));
|
||||
$PAGE->set_heading(format_string($course->fullname));
|
||||
$PAGE->set_context($coursecontext);
|
||||
|
||||
echo $OUTPUT->header();
|
||||
|
||||
$modulenameplural = get_string('modulenameplural', 'mod_subsection');
|
||||
echo $OUTPUT->heading($modulenameplural);
|
||||
|
||||
$subsections = get_all_instances_in_course('subsection', $course);
|
||||
|
||||
if (empty($subsections)) {
|
||||
notice(get_string('thereareno', 'moodle', $modulenameplural), "$CFG->wwwroot/course/view.php?id=$course->id");
|
||||
}
|
||||
|
||||
$table = new html_table();
|
||||
$table->attributes['class'] = 'generaltable mod_index';
|
||||
|
||||
if ($course->format == 'weeks') {
|
||||
$table->head = [get_string('week'), get_string('name')];
|
||||
$table->align = ['center', 'left'];
|
||||
} else if ($course->format == 'topics') {
|
||||
$table->head = [get_string('topic'), get_string('name')];
|
||||
$table->align = ['center', 'left', 'left', 'left'];
|
||||
} else {
|
||||
$table->head = [get_string('name')];
|
||||
$table->align = ['left', 'left', 'left'];
|
||||
}
|
||||
|
||||
foreach ($subsections as $subsection) {
|
||||
if (!$subsection->visible) {
|
||||
$link = html_writer::link(
|
||||
new moodle_url('/mod/subsection/view.php', ['id' => $subsection->coursemodule]),
|
||||
format_string($subsection->name, true),
|
||||
['class' => 'dimmed']);
|
||||
} else {
|
||||
$link = html_writer::link(
|
||||
new moodle_url('/mod/subsection/view.php', ['id' => $subsection->coursemodule]),
|
||||
format_string($subsection->name, true));
|
||||
}
|
||||
|
||||
if ($course->format == 'weeks' || $course->format == 'topics') {
|
||||
$table->data[] = [$subsection->section, $link];
|
||||
} else {
|
||||
$table->data[] = [$link];
|
||||
}
|
||||
}
|
||||
|
||||
echo html_writer::table($table);
|
||||
echo $OUTPUT->footer();
|
34
mod/subsection/lang/en/subsection.php
Normal file
34
mod/subsection/lang/en/subsection.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Plugin strings are defined here.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @category string
|
||||
* @copyright 2023 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['modulename'] = 'Subsection';
|
||||
$string['modulename_help'] = 'Delegated subsections';
|
||||
$string['modulenameplural'] = 'Subsections';
|
||||
$string['pluginadministration'] = 'Subsection administration';
|
||||
$string['pluginname'] = 'Subsection';
|
||||
$string['privacy:metadata'] = 'Subsection does not store any personal data';
|
||||
$string['subsection:addinstance'] = 'Add subsection';
|
||||
$string['subsection:view'] = 'View subsection';
|
||||
$string['subsectionname'] = 'Name';
|
209
mod/subsection/lib.php
Normal file
209
mod/subsection/lib.php
Normal file
@ -0,0 +1,209 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Library of interface functions and constants.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @copyright 2023 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
use core_courseformat\formatactions;
|
||||
use mod_subsection\manager;
|
||||
|
||||
/**
|
||||
* Return if the plugin supports $feature.
|
||||
*
|
||||
* @param string $feature Constant representing the feature.
|
||||
* @return mixed True if module supports feature, false if not, null if doesn't know or string for the module purpose.
|
||||
*/
|
||||
function subsection_supports($feature) {
|
||||
return match ($feature) {
|
||||
FEATURE_MOD_ARCHETYPE => MOD_ARCHETYPE_RESOURCE,
|
||||
FEATURE_GROUPS => false,
|
||||
FEATURE_GROUPINGS => false,
|
||||
FEATURE_MOD_INTRO => false,
|
||||
FEATURE_COMPLETION_TRACKS_VIEWS => true,
|
||||
FEATURE_GRADE_HAS_GRADE => false,
|
||||
FEATURE_GRADE_OUTCOMES => false,
|
||||
FEATURE_BACKUP_MOODLE2 => true,
|
||||
FEATURE_SHOW_DESCRIPTION => false,
|
||||
FEATURE_MOD_PURPOSE => MOD_PURPOSE_CONTENT,
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a new instance of the mod_subsection into the database.
|
||||
*
|
||||
* Given an object containing all the necessary data, (defined by the form
|
||||
* in mod_form.php) this function will create a new instance and return the id
|
||||
* number of the instance.
|
||||
*
|
||||
* @param object $moduleinstance An object from the form.
|
||||
* @param mod_subsection_mod_form $mform The form.
|
||||
* @return int The id of the newly inserted record.
|
||||
*/
|
||||
function subsection_add_instance($moduleinstance, $mform = null) {
|
||||
global $DB;
|
||||
|
||||
$moduleinstance->timecreated = time();
|
||||
|
||||
$id = $DB->insert_record('subsection', $moduleinstance);
|
||||
|
||||
formatactions::section($moduleinstance->course)->create_delegated(
|
||||
manager::PLUGINNAME,
|
||||
$id,
|
||||
(object)[
|
||||
'name' => $moduleinstance->name,
|
||||
]);
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an instance of the mod_subsection in the database.
|
||||
*
|
||||
* Given an object containing all the necessary data (defined in mod_form.php),
|
||||
* this function will update an existing instance with new data.
|
||||
*
|
||||
* @param object $moduleinstance An object from the form in mod_form.php.
|
||||
* @param mod_subsection_mod_form $mform The form.
|
||||
* @return bool True if successful, false otherwise.
|
||||
*/
|
||||
function subsection_update_instance($moduleinstance, $mform = null) {
|
||||
global $DB;
|
||||
|
||||
$moduleinstance->timemodified = time();
|
||||
$moduleinstance->id = $moduleinstance->instance;
|
||||
|
||||
return $DB->update_record('subsection', $moduleinstance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an instance of the mod_subsection from the database.
|
||||
*
|
||||
* @param int $id Id of the module instance.
|
||||
* @return bool True if successful, false on failure.
|
||||
*/
|
||||
function subsection_delete_instance($id) {
|
||||
global $DB;
|
||||
|
||||
$exists = $DB->get_record('subsection', ['id' => $id]);
|
||||
if (!$exists) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cm = get_coursemodule_from_instance(manager::MODULE, $id);
|
||||
$delegatesection = get_fast_modinfo($cm->course)->get_section_info_by_component(manager::PLUGINNAME, $id);
|
||||
if ($delegatesection) {
|
||||
formatactions::section($cm->course)->delete($delegatesection);
|
||||
}
|
||||
|
||||
$DB->delete_records('subsection', ['id' => $id]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lists of all browsable file areas within the given module context.
|
||||
*
|
||||
* The file area 'intro' for the activity introduction field is added automatically
|
||||
* by {@see file_browser::get_file_info_context_module()}.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @category files
|
||||
*
|
||||
* @param stdClass $course
|
||||
* @param stdClass $cm
|
||||
* @param stdClass $context
|
||||
* @return string[].
|
||||
*/
|
||||
function subsection_get_file_areas($course, $cm, $context) {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* File browsing support for mod_subsection file areas.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @category files
|
||||
*
|
||||
* @param file_browser $browser
|
||||
* @param array $areas
|
||||
* @param stdClass $course
|
||||
* @param stdClass $cm
|
||||
* @param stdClass $context
|
||||
* @param string $filearea
|
||||
* @param int $itemid
|
||||
* @param string $filepath
|
||||
* @param string $filename
|
||||
* @return file_info|null file_info instance or null if not found.
|
||||
*/
|
||||
function subsection_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serves the files from the mod_subsection file areas.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @category files
|
||||
*
|
||||
* @param stdClass $course The course object.
|
||||
* @param stdClass $cm The course module object.
|
||||
* @param stdClass $context The mod_subsection's context.
|
||||
* @param string $filearea The name of the file area.
|
||||
* @param array $args Extra arguments (itemid, path).
|
||||
* @param bool $forcedownload Whether or not force download.
|
||||
* @param array $options Additional options affecting the file serving.
|
||||
*/
|
||||
function subsection_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, $options = []) {
|
||||
global $DB, $CFG;
|
||||
|
||||
if ($context->contextlevel != CONTEXT_MODULE) {
|
||||
send_file_not_found();
|
||||
}
|
||||
|
||||
require_login($course, true, $cm);
|
||||
send_file_not_found();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends the global navigation tree by adding mod_subsection nodes if there is a relevant content.
|
||||
*
|
||||
* This can be called by an AJAX request so do not rely on $PAGE as it might not be set up properly.
|
||||
*
|
||||
* @param navigation_node $subsectionnode An object representing the navigation tree node.
|
||||
* @param stdClass $course
|
||||
* @param stdClass $module
|
||||
* @param cm_info $cm
|
||||
*/
|
||||
function subsection_extend_navigation($subsectionnode, $course, $module, $cm) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends the settings navigation with the mod_subsection settings.
|
||||
*
|
||||
* This function is called when the context for the page is a mod_subsection module.
|
||||
* This is not called by AJAX so it is safe to rely on the $PAGE.
|
||||
*
|
||||
* @param settings_navigation $settingsnav {@see settings_navigation}
|
||||
* @param navigation_node $subsectionnode {@see navigation_node}
|
||||
*/
|
||||
function subsection_extend_settings_navigation($settingsnav, $subsectionnode = null) {
|
||||
}
|
67
mod/subsection/mod_form.php
Normal file
67
mod/subsection/mod_form.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* The main mod_subsection configuration form.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @copyright 2023 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->dirroot.'/course/moodleform_mod.php');
|
||||
|
||||
/**
|
||||
* Module instance settings form.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @copyright 2023 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class mod_subsection_mod_form extends moodleform_mod {
|
||||
|
||||
/**
|
||||
* Defines forms elements
|
||||
*/
|
||||
public function definition() {
|
||||
global $CFG;
|
||||
|
||||
$mform = $this->_form;
|
||||
|
||||
// Adding the "general" fieldset, where all the common settings are shown.
|
||||
$mform->addElement('header', 'general', get_string('general', 'form'));
|
||||
|
||||
// Adding the standard "name" field.
|
||||
$mform->addElement('text', 'name', get_string('subsectionname', 'mod_subsection'), ['size' => '64']);
|
||||
|
||||
if (!empty($CFG->formatstringstriptags)) {
|
||||
$mform->setType('name', PARAM_TEXT);
|
||||
} else {
|
||||
$mform->setType('name', PARAM_CLEANHTML);
|
||||
}
|
||||
|
||||
$mform->addRule('name', null, 'required', null, 'client');
|
||||
$mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'client');
|
||||
|
||||
// Add standard elements.
|
||||
$this->standard_coursemodule_elements();
|
||||
|
||||
// Add standard buttons.
|
||||
$this->add_action_buttons();
|
||||
}
|
||||
}
|
3
mod/subsection/pix/monologo.svg
Normal file
3
mod/subsection/pix/monologo.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.99951 7.83057C2.99951 6.44985 4.1188 5.33057 5.49951 5.33057H18.5012C19.8819 5.33057 21.0012 6.44985 21.0012 7.83057V16.8306C21.0012 18.2113 19.8819 19.3306 18.5012 19.3306H5.49951C4.1188 19.3306 2.99951 18.2113 2.99951 16.8306V7.83057ZM5.49951 6.33057C4.67108 6.33057 3.99951 7.00214 3.99951 7.83057V16.8306C3.99951 17.659 4.67108 18.3306 5.49951 18.3306H18.5012C19.3296 18.3306 20.0012 17.659 20.0012 16.8306V7.83057C20.0012 7.00214 19.3296 6.33057 18.5012 6.33057H5.49951ZM8.49756 9.83154C8.49756 9.5554 8.72142 9.33154 8.99756 9.33154L17.512 9.33154C17.7881 9.33154 18.012 9.5554 18.012 9.83154C18.012 10.1077 17.7881 10.3315 17.512 10.3315L8.99756 10.3315C8.72142 10.3315 8.49756 10.1077 8.49756 9.83154ZM8.49756 14.8323C8.49756 14.5561 8.72142 14.3323 8.99756 14.3323L17.512 14.3323C17.7881 14.3323 18.012 14.5561 18.012 14.8323C18.012 15.1084 17.7881 15.3323 17.512 15.3323L8.99756 15.3323C8.72142 15.3323 8.49756 15.1084 8.49756 14.8323ZM8.99756 11.8306C8.72142 11.8306 8.49756 12.0544 8.49756 12.3306C8.49756 12.6067 8.72142 12.8306 8.99756 12.8306L17.512 12.8306C17.7881 12.8306 18.012 12.6067 18.012 12.3306C18.012 12.0544 17.7881 11.8306 17.512 11.8306L8.99756 11.8306ZM6.50342 9.33154C6.22728 9.33154 6.00342 9.5554 6.00342 9.83154C6.00342 10.1077 6.22728 10.3315 6.50342 10.3315H7.00146C7.27761 10.3315 7.50146 10.1077 7.50146 9.83154C7.50146 9.5554 7.27761 9.33154 7.00146 9.33154H6.50342ZM6.00342 12.3306C6.00342 12.0544 6.22728 11.8306 6.50342 11.8306H7.00146C7.27761 11.8306 7.50146 12.0544 7.50146 12.3306C7.50146 12.6067 7.27761 12.8306 7.00146 12.8306H6.50342C6.22728 12.8306 6.00342 12.6067 6.00342 12.3306ZM6.50342 14.3323C6.22728 14.3323 6.00342 14.5561 6.00342 14.8323C6.00342 15.1084 6.22728 15.3323 6.50342 15.3323H7.00146C7.27761 15.3323 7.50146 15.1084 7.50146 14.8323C7.50146 14.5561 7.27761 14.3323 7.00146 14.3323H6.50342Z" fill="#212529"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
25
mod/subsection/renderer.php
Normal file
25
mod/subsection/renderer.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Subsection activity renderer.
|
||||
*
|
||||
* @copyright 2023 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @package mod_subsection
|
||||
*/
|
||||
class mod_subsection_renderer extends plugin_renderer_base {
|
||||
}
|
34
mod/subsection/settings.php
Normal file
34
mod/subsection/settings.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Plugin administration pages are defined here.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @category admin
|
||||
* @copyright 2023 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
if ($hassiteconfig) {
|
||||
$settings = new admin_settingpage('mod_subsection_settings', new lang_string('pluginname', 'mod_subsection'));
|
||||
|
||||
// phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedIf
|
||||
if ($ADMIN->fulltree) {
|
||||
}
|
||||
}
|
52
mod/subsection/tests/behat/subsection_actionmenu.feature
Normal file
52
mod/subsection/tests/behat/subsection_actionmenu.feature
Normal file
@ -0,0 +1,52 @@
|
||||
@mod @mod_subsection
|
||||
Feature: The module menu replaces the section menu when accessing the subsection page
|
||||
In order to use subsections
|
||||
As an teacher
|
||||
I need to see the module action menu in the section page.
|
||||
|
||||
Background:
|
||||
Given I enable "subsection" "mod" plugin
|
||||
And the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category | numsections |
|
||||
| Course 1 | C1 | 0 | 2 |
|
||||
And the following "activity" exists:
|
||||
| activity | subsection |
|
||||
| name | Subsection1 |
|
||||
| course | C1 |
|
||||
| idnumber | subsection1 |
|
||||
| section | 1 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
And I am on the "C1" "Course" page logged in as "teacher1"
|
||||
|
||||
@javascript
|
||||
Scenario: The action menu for subsection page meets the module menu
|
||||
Given I click on "Subsection1" "link" in the "region-main" "region"
|
||||
And I turn editing mode on
|
||||
# Open the action menu.
|
||||
When I click on "Edit" "icon" in the "[data-region='header-actions-container']" "css_element"
|
||||
Then I should not see "Move right"
|
||||
And I should not see "Assign roles"
|
||||
And I should not see "Permalink"
|
||||
And I should not see "Highlight"
|
||||
And I should see "Edit settings"
|
||||
And I should see "Move"
|
||||
And I should see "Hide"
|
||||
And I should see "Duplicate"
|
||||
And I should see "Delete"
|
||||
|
||||
@javascript
|
||||
Scenario: The action menu for subsection module has less options thant a regular activity
|
||||
Given I turn editing mode on
|
||||
When I open "Subsection1" actions menu
|
||||
Then I should not see "Move right"
|
||||
And I should not see "Assign roles"
|
||||
And I should see "Edit settings"
|
||||
And I should see "Move"
|
||||
And I should see "Hide"
|
||||
And I should see "Duplicate"
|
||||
And I should see "Delete"
|
61
mod/subsection/tests/behat/subsection_handling.feature
Normal file
61
mod/subsection/tests/behat/subsection_handling.feature
Normal file
@ -0,0 +1,61 @@
|
||||
@mod @mod_subsection
|
||||
Feature: Teachers create and destroy subsections
|
||||
In order to use subsections
|
||||
As an teacher
|
||||
I need to create and destroy subsections
|
||||
|
||||
Background:
|
||||
Given I enable "subsection" "mod" plugin
|
||||
And the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category | numsections |
|
||||
| Course 1 | C1 | 0 | 2 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
And I log in as "teacher1"
|
||||
|
||||
Scenario: Subsections are not listed as regular sections
|
||||
Given the following "activities" exist:
|
||||
| activity | name | course | idnumber | section |
|
||||
| subsection | Subsection1 | C1 | forum1 | 1 |
|
||||
| data | Subactivity1 | C1 | data1 | 3 |
|
||||
When I am on "Course 1" course homepage
|
||||
Then "Subsection1" "section" should not exist
|
||||
And I should not see "Subactivity1" in the "region-main" "region"
|
||||
And I click on "Subsection1" "link" in the "region-main" "region"
|
||||
And I should see "Subsection1" in the "page" "region"
|
||||
And I should see "Subactivity1" in the "region-main" "region"
|
||||
|
||||
Scenario: Activities can be created in a subsection
|
||||
Given the following "activities" exist:
|
||||
| activity | name | course | idnumber | section |
|
||||
| subsection | Subsection1 | C1 | forum1 | 1 |
|
||||
When I add an "assign" activity to course "Course 1" section "3" and I fill the form with:
|
||||
| Assignment name | Test assignment name |
|
||||
| ID number | Test assignment name |
|
||||
| Description | Test assignment description |
|
||||
And I am on "Course 1" course homepage
|
||||
And I click on "Subsection1" "link" in the "region-main" "region"
|
||||
Then I should see "Test assignment name" in the "region-main" "region"
|
||||
And I am on "Course 1" course homepage
|
||||
And I should not see "Test assignment name" in the "region-main" "region"
|
||||
|
||||
@javascript
|
||||
Scenario: Teacher can create activities in a subsection page with the activity chooser
|
||||
Given the following "activities" exist:
|
||||
| activity | name | course | idnumber | section |
|
||||
| subsection | Subsection1 | C1 | forum1 | 1 |
|
||||
When I am on "Course 1" course homepage with editing mode on
|
||||
And I click on "Subsection1" "link" in the "region-main" "region"
|
||||
And I add a "Assignment" to section "3" using the activity chooser
|
||||
And I set the following fields to these values:
|
||||
| Assignment name | Test assignment name |
|
||||
| ID number | Test assignment name |
|
||||
| Description | Test assignment description |
|
||||
And I press "Save and return to course"
|
||||
Then I should see "Test assignment name" in the "region-main" "region"
|
||||
And I am on "Course 1" course homepage
|
||||
And I should not see "Test assignment name" in the "region-main" "region"
|
44
mod/subsection/tests/behat/subsection_navigation.feature
Normal file
44
mod/subsection/tests/behat/subsection_navigation.feature
Normal file
@ -0,0 +1,44 @@
|
||||
@mod @mod_subsection
|
||||
Feature: Teachers navigate to subsections
|
||||
In order to use subsections
|
||||
As an teacher
|
||||
I need to navigate to subsections
|
||||
|
||||
Background:
|
||||
Given I enable "subsection" "mod" plugin
|
||||
And the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category | numsections | initsections |
|
||||
| Course 1 | C1 | 0 | 1 | 1 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
And the following "activities" exist:
|
||||
| activity | name | course | idnumber | section |
|
||||
| subsection | Subsection 1 | C1 | subsection1 | 1 |
|
||||
| page | Page in Subsection 1 | C1 | page1 | 2 |
|
||||
And I log in as "teacher1"
|
||||
|
||||
Scenario: Subsection section page shows parent section in the breadcrumb
|
||||
When I am on the "C1 > Subsection 1" "course > section" page
|
||||
Then "C1" "link" should exist in the ".breadcrumb" "css_element"
|
||||
And "Section 1" "link" should exist in the ".breadcrumb" "css_element"
|
||||
And "Subsection 1" "text" should exist in the ".breadcrumb" "css_element"
|
||||
|
||||
Scenario: Activity page shows subsection and its parent section in the breadcrumb
|
||||
When I am on the "page1" "Activity" page
|
||||
Then "C1" "link" should exist in the ".breadcrumb" "css_element"
|
||||
And "Section 1" "link" should exist in the ".breadcrumb" "css_element"
|
||||
And "Subsection 1" "link" should exist in the ".breadcrumb" "css_element"
|
||||
And "Page in Subsection 1" "text" should exist in the ".breadcrumb" "css_element"
|
||||
|
||||
Scenario: Sections and Subsections are displayed in the navigation block
|
||||
Given the following config values are set as admin:
|
||||
| unaddableblocks | | theme_boost|
|
||||
And I turn editing mode on
|
||||
When I am on the "page1" "Activity" page
|
||||
And I add the "Navigation" block if not present
|
||||
Then "Section 1" "link" should appear before "Subsection 1" "link" in the "Navigation" "block"
|
||||
And "Subsection 1" "link" should appear before "Page in Subsection 1" "link" in the "Navigation" "block"
|
54
mod/subsection/tests/behat/subsection_rename.feature
Normal file
54
mod/subsection/tests/behat/subsection_rename.feature
Normal file
@ -0,0 +1,54 @@
|
||||
@mod @mod_subsection
|
||||
Feature: Teachers can rename subsections
|
||||
In order to change subsections name
|
||||
As an teacher
|
||||
I need to sync subsection and activity names
|
||||
|
||||
Background:
|
||||
Given I enable "subsection" "mod" plugin
|
||||
And the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category | numsections |
|
||||
| Course 1 | C1 | 0 | 2 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
And the following "activities" exist:
|
||||
| activity | name | course | idnumber | section |
|
||||
| subsection | Subsection activity | C1 | forum1 | 1 |
|
||||
| data | Subactivity | C1 | data1 | 3 |
|
||||
And I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
|
||||
@javascript
|
||||
Scenario: Renaming the subsection activity changes the subsection name
|
||||
Given I should see "Subsection activity" in the "page-content" "region"
|
||||
When I set the field "Edit title" in the "Subsection activity" "activity" to "New name"
|
||||
And I should not see "Subsection activity" in the "region-main" "region"
|
||||
And I should see "New name" in the "page-content" "region"
|
||||
Then I click on "New name" "link" in the "page-content" "region"
|
||||
And I should see "New name" in the "page" "region"
|
||||
And I should see "Subactivity" in the "region-main" "region"
|
||||
|
||||
Scenario: Renaming the activity using the settings form rename the subsection name
|
||||
Given I should see "Subsection activity" in the "page-content" "region"
|
||||
When I click on "Edit settings" "link" in the "Subsection activity" "activity"
|
||||
And I set the following fields to these values:
|
||||
| Name | New name |
|
||||
And I press "Save and display"
|
||||
Then I should see "New name" in the "page" "region"
|
||||
And I should see "Subactivity" in the "region-main" "region"
|
||||
And I am on "Course 1" course homepage
|
||||
And I should see "New name" in the "page-content" "region"
|
||||
|
||||
@javascript
|
||||
Scenario: Renaming the subsection renames the subsection activity name
|
||||
Given I click on "Subsection activity" "link" in the "page-content" "region"
|
||||
And I should see "Subsection activity" in the "page" "region"
|
||||
And I should see "Subactivity" in the "region-main" "region"
|
||||
When I set the field "Edit section name" in the "page" "region" to "New name"
|
||||
Then I should see "New name" in the "page" "region"
|
||||
And I am on "Course 1" course homepage
|
||||
And I should see "New name" in the "page-content" "region"
|
75
mod/subsection/tests/courseformat/sectiondelegate_test.php
Normal file
75
mod/subsection/tests/courseformat/sectiondelegate_test.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?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 mod_subsection\courseformat;
|
||||
|
||||
/**
|
||||
* Subsection delegated section tests.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @copyright 2024 Sara Arjona <sara@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @covers \mod_subsection\courseformat\sectiondelegate
|
||||
* @coversDefaultClass \mod_subsection\courseformat\sectiondelegate
|
||||
*/
|
||||
final class sectiondelegate_test extends \advanced_testcase {
|
||||
|
||||
/**
|
||||
* Test has_delegate_class().
|
||||
*
|
||||
* @covers ::has_delegate_class
|
||||
*/
|
||||
public function test_has_delegate_class(): void {
|
||||
$this->assertTrue(sectiondelegate::has_delegate_class('mod_subsection'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_section_action_menu().
|
||||
*
|
||||
* @covers ::get_section_action_menu
|
||||
*/
|
||||
public function test_get_section_action_menu(): void {
|
||||
global $PAGE;
|
||||
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$manager = \core_plugin_manager::resolve_plugininfo_class('mod');
|
||||
$manager::enable_plugin('subsection', 1);
|
||||
|
||||
$course = $this->getDataGenerator()->create_course(['format' => 'topics', 'numsections' => 1]);
|
||||
$this->getDataGenerator()->create_module('subsection', ['course' => $course->id, 'section' => 1]);
|
||||
|
||||
$modinfo = get_fast_modinfo($course->id);
|
||||
$sectioninfos = $modinfo->get_section_info_all();
|
||||
// Get the section info for the delegated section.
|
||||
$sectioninfo = $sectioninfos[2];
|
||||
$delegated = sectiondelegate::instance($sectioninfo);
|
||||
$format = course_get_format($course);
|
||||
|
||||
$outputclass = $format->get_output_classname('content\\section\\controlmenu');
|
||||
$controlmenu = new $outputclass($format, $sectioninfo);
|
||||
$renderer = $PAGE->get_renderer('format_' . $course->format);
|
||||
|
||||
// The default section menu should be different for the delegated section menu.
|
||||
$result = $delegated->get_section_action_menu($format, $controlmenu, $renderer);
|
||||
foreach ($result->get_secondary_actions() as $secondaryaction) {
|
||||
// Highlight and Permalink are only present in section menu (not module), so they shouldn't be find in the result.
|
||||
$this->assertNotEquals(get_string('highlight'), $secondaryaction->text);
|
||||
$this->assertNotEquals(get_string('sectionlink', 'course'), $secondaryaction->text);
|
||||
}
|
||||
}
|
||||
}
|
112
mod/subsection/tests/courseformat/sectiondelegatemodule_test.php
Normal file
112
mod/subsection/tests/courseformat/sectiondelegatemodule_test.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?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 mod_subsection\courseformat;
|
||||
|
||||
use mod_subsection\courseformat\sectiondelegate as testsectiondelegatemodule;
|
||||
use section_info;
|
||||
use cm_info;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Section delegate module tests.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @copyright 2024 Mikel Martín <mikel@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @covers \core_courseformat\sectiondelegatemodule
|
||||
* @coversDefaultClass \core_courseformat\sectiondelegatemodule
|
||||
*/
|
||||
final class sectiondelegatemodule_test extends \advanced_testcase {
|
||||
|
||||
/**
|
||||
* Test get_parent_section.
|
||||
*
|
||||
* @covers ::get_parent_section
|
||||
*/
|
||||
public function test_get_parent_section(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$manager = \core_plugin_manager::resolve_plugininfo_class('mod');
|
||||
$manager::enable_plugin('subsection', 1);
|
||||
|
||||
$course = $this->getDataGenerator()->create_course(['format' => 'topics', 'numsections' => 2]);
|
||||
$module = $this->getDataGenerator()->create_module('subsection', (object)['course' => $course->id, 'section' => 2]);
|
||||
|
||||
// Get the section info for the delegated section.
|
||||
$sectioninfo = get_fast_modinfo($course)->get_section_info_by_component('mod_subsection', $module->id);
|
||||
|
||||
/** @var testsectiondelegatemodule */
|
||||
$delegated = sectiondelegate::instance($sectioninfo);
|
||||
|
||||
$parentsectioninfo = $delegated->get_parent_section();
|
||||
|
||||
$this->assertInstanceOf(section_info::class, $parentsectioninfo);
|
||||
$this->assertEquals(2, $parentsectioninfo->sectionnum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_cm.
|
||||
*
|
||||
* @covers ::get_cm
|
||||
*/
|
||||
public function test_get_cm(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$manager = \core_plugin_manager::resolve_plugininfo_class('mod');
|
||||
$manager::enable_plugin('subsection', 1);
|
||||
|
||||
$course = $this->getDataGenerator()->create_course(['format' => 'topics', 'numsections' => 1]);
|
||||
$module = $this->getDataGenerator()->create_module('subsection', (object)['course' => $course->id, 'section' => 1]);
|
||||
|
||||
// Get the section info for the delegated section.
|
||||
$sectioninfo = get_fast_modinfo($course)->get_section_info_by_component('mod_subsection', $module->id);
|
||||
|
||||
/** @var testsectiondelegatemodule */
|
||||
$delegated = sectiondelegate::instance($sectioninfo);
|
||||
|
||||
$delegatedsectioncm = $delegated->get_cm();
|
||||
|
||||
$this->assertInstanceOf(cm_info::class, $delegatedsectioncm);
|
||||
$this->assertEquals($module->id, $delegatedsectioncm->instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_course.
|
||||
*
|
||||
* @covers ::get_course
|
||||
*/
|
||||
public function test_get_course(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$manager = \core_plugin_manager::resolve_plugininfo_class('mod');
|
||||
$manager::enable_plugin('subsection', 1);
|
||||
|
||||
$course = $this->getDataGenerator()->create_course(['format' => 'topics', 'numsections' => 1]);
|
||||
$module = $this->getDataGenerator()->create_module('subsection', (object)['course' => $course->id, 'section' => 1]);
|
||||
|
||||
// Get the section info for the delegated section.
|
||||
$sectioninfo = get_fast_modinfo($course)->get_section_info_by_component('mod_subsection', $module->id);
|
||||
|
||||
/** @var testsectiondelegatemodule */
|
||||
$delegated = sectiondelegate::instance($sectioninfo);
|
||||
|
||||
$delegatedsectioncourse = $delegated->get_course();
|
||||
|
||||
$this->assertInstanceOf(stdClass::class, $delegatedsectioncourse);
|
||||
$this->assertEquals($course->id, $delegatedsectioncourse->id);
|
||||
}
|
||||
}
|
26
mod/subsection/tests/generator/lib.php
Normal file
26
mod/subsection/tests/generator/lib.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Data generator class for mod_subsection.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @category test
|
||||
* @copyright 2023 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class mod_subsection_generator extends testing_module_generator {
|
||||
}
|
31
mod/subsection/version.php
Normal file
31
mod/subsection/version.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Plugin version and other meta-data are defined here.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @copyright 2023 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->component = 'mod_subsection';
|
||||
$plugin->release = '0.1.0';
|
||||
$plugin->version = 2024070100;
|
||||
$plugin->requires = 2024070500;
|
||||
$plugin->maturity = MATURITY_ALPHA;
|
57
mod/subsection/view.php
Normal file
57
mod/subsection/view.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Prints an instance of mod_subsection.
|
||||
*
|
||||
* @package mod_subsection
|
||||
* @copyright 2023 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
use mod_subsection\manager;
|
||||
use core_courseformat\formatactions;
|
||||
|
||||
require(__DIR__.'/../../config.php');
|
||||
require_once(__DIR__.'/lib.php');
|
||||
|
||||
// Course module id.
|
||||
$id = required_param('id', PARAM_INT);
|
||||
$cm = get_coursemodule_from_id('subsection', $id, 0, false, MUST_EXIST);
|
||||
$manager = manager::create_from_coursemodule($cm);
|
||||
$course = $DB->get_record('course', ['id' => $cm->course], '*', MUST_EXIST);
|
||||
$moduleinstance = $manager->get_instance();
|
||||
|
||||
require_login($course, true, $cm);
|
||||
|
||||
$modulecontext = $manager->get_context();
|
||||
$manager->set_module_viewed($course);
|
||||
|
||||
$modinfo = get_fast_modinfo($course);
|
||||
|
||||
$delegatesection = $modinfo->get_section_info_by_component(manager::PLUGINNAME, $moduleinstance->id);
|
||||
if (!$delegatesection) {
|
||||
// Some restorations can produce a situation where the section is not found.
|
||||
// In that case, we create a new one.
|
||||
formatactions::section($course)->create_delegated(
|
||||
manager::PLUGINNAME,
|
||||
$id,
|
||||
(object) [
|
||||
'name' => $moduleinstance->name,
|
||||
]
|
||||
);
|
||||
}
|
||||
redirect(new moodle_url('/course/section.php', ['id' => $delegatesection->id]));
|
32
report/outline/tests/behat/subsection_reports.feature
Normal file
32
report/outline/tests/behat/subsection_reports.feature
Normal file
@ -0,0 +1,32 @@
|
||||
@mod @mod_subsection @report
|
||||
Feature: Subsections are shown in reports
|
||||
In order to use reports
|
||||
As an teacher
|
||||
I need to see sections and subsections structure in reports
|
||||
|
||||
Background:
|
||||
Given I enable "subsection" "mod" plugin
|
||||
And the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category | numsections | initsections |
|
||||
| Course 1 | C1 | 0 | 1 | 1 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
And the following "activities" exist:
|
||||
| activity | name | course | idnumber | section |
|
||||
| page | First page | C1 | page1 | 1 |
|
||||
| subsection | Subsection 1 | C1 | subsection1 | 1 |
|
||||
| page | Last page | C1 | last | 1 |
|
||||
| page | Page in Subsection 1 | C1 | subpage | 2 |
|
||||
And I log in as "teacher1"
|
||||
|
||||
@report_outline
|
||||
Scenario: Course Activity report show subsections' information
|
||||
Given I am on "Course 1" course homepage
|
||||
When I navigate to "Reports > Activity report" in current page administration
|
||||
Then I should see "First page" in the "generaltable" "table"
|
||||
And "Subsection" "table_row" should appear before "Last page" "table_row"
|
||||
And "Page in Subsection 1" "table_row" should appear before "Last page" "table_row"
|
@ -158,6 +158,11 @@ $courseindex-item-current: $primary !default;
|
||||
.current-badge {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* Skip current badges in delegated sections. */
|
||||
.delegated-section .current-badge {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.dropready .courseindex-item-content {
|
||||
|
@ -38450,10 +38450,14 @@ div.editor_atto_toolbar button .icon {
|
||||
}
|
||||
.courseindex .courseindex-section.current {
|
||||
border-left: solid 3px #0f6cbf;
|
||||
/* Skip current badges in delegated sections. */
|
||||
}
|
||||
.courseindex .courseindex-section.current .current-badge {
|
||||
display: inline-block;
|
||||
}
|
||||
.courseindex .courseindex-section.current .delegated-section .current-badge {
|
||||
display: none;
|
||||
}
|
||||
.courseindex .courseindex-section.dropready .courseindex-item-content {
|
||||
/* Extra dropzone space */
|
||||
padding-bottom: 1em;
|
||||
|
@ -38384,10 +38384,14 @@ div.editor_atto_toolbar button .icon {
|
||||
}
|
||||
.courseindex .courseindex-section.current {
|
||||
border-left: solid 3px #0f6cbf;
|
||||
/* Skip current badges in delegated sections. */
|
||||
}
|
||||
.courseindex .courseindex-section.current .current-badge {
|
||||
display: inline-block;
|
||||
}
|
||||
.courseindex .courseindex-section.current .delegated-section .current-badge {
|
||||
display: none;
|
||||
}
|
||||
.courseindex .courseindex-section.dropready .courseindex-item-content {
|
||||
/* Extra dropzone space */
|
||||
padding-bottom: 1em;
|
||||
|
Loading…
x
Reference in New Issue
Block a user