From b4ecd9d805a772818b976550b0f3f4ef5f6de754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikel=20Mart=C3=ADn?= Date: Fri, 17 May 2024 09:41:45 +0200 Subject: [PATCH 1/3] MDL-81648 course: Add a method to retrieve delegate section parent - New 'get_parent_section()' function added to sectiondelegate abstract class --- course/format/classes/sectiondelegate.php | 9 +++++++++ course/format/tests/sectiondelegate_test.php | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/course/format/classes/sectiondelegate.php b/course/format/classes/sectiondelegate.php index 2dcfcb17ee1..14af95ff4db 100644 --- a/course/format/classes/sectiondelegate.php +++ b/course/format/classes/sectiondelegate.php @@ -124,4 +124,13 @@ abstract class sectiondelegate { ): ?action_menu { return $controlmenu->get_default_action_menu($output); } + + /** + * Get the parent section of the current delegated section if any. + * + * @return section_info|null + */ + public function get_parent_section(): ?section_info { + return null; + } } diff --git a/course/format/tests/sectiondelegate_test.php b/course/format/tests/sectiondelegate_test.php index e3932342c0e..39d793ba78f 100644 --- a/course/format/tests/sectiondelegate_test.php +++ b/course/format/tests/sectiondelegate_test.php @@ -141,4 +141,21 @@ class sectiondelegate_test extends \advanced_testcase { $result = $delegated->get_section_action_menu($format, $controlmenu, $renderer); $this->assertNull($result); } + + /** + * Test get_parent_section(). + * + * @covers ::get_parent_section + */ + public function test_get_parent_section(): void { + $this->resetAfterTest(); + + $course = $this->getDataGenerator()->create_course(['format' => 'topics', 'numsections' => 1]); + $sectioninfo = formatactions::section($course)->create_delegated('test_component', 1); + + /** @var testsectiondelegate */ + $delegated = $sectioninfo->get_component_instance(); + + $this->assertNull($delegated->get_parent_section()); + } } From 932b094134a5af32f5282e91ad7fc82ec0c0acd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikel=20Mart=C3=ADn?= Date: Fri, 17 May 2024 09:56:36 +0200 Subject: [PATCH 2/3] MDL-81648 course: Add new sectiondelegatemodule class - Created sectiondelegatemodule abstract class for those delegated sections managed by a module - This class will override get_parent_section from the base class, retrieving the parent section from the module --- .../format/classes/sectiondelegatemodule.php | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 course/format/classes/sectiondelegatemodule.php diff --git a/course/format/classes/sectiondelegatemodule.php b/course/format/classes/sectiondelegatemodule.php new file mode 100644 index 00000000000..124ad1b34f8 --- /dev/null +++ b/course/format/classes/sectiondelegatemodule.php @@ -0,0 +1,90 @@ +. + +namespace core_courseformat; + +use cm_info; +use section_info; +use stdClass; + +/** + * Class sectiondelegatemodule + * + * @package core_courseformat + * @copyright 2024 Mikel Martín + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +abstract class sectiondelegatemodule extends sectiondelegate { + /** @var section_info $sectioninfo The section_info object of the delegated section module */ + + /** @var cm_info|null $cm The cm_info object of the delegated section module */ + private $cm = null; + + /** @var stdClass|null $course The course object of the delegated section module */ + private $course = null; + + /** + * Constructor. + * @param section_info $sectioninfo + */ + public function __construct( + protected section_info $sectioninfo + ) { + parent::__construct($sectioninfo); + + [$this->course, $this->cm] = get_course_and_cm_from_instance( + $this->sectioninfo->itemid, + $this->get_module_name(), + $this->sectioninfo->course, + ); + } + + /** + * Get the parent section of the current delegated section. + * + * @return section_info|null + */ + public function get_parent_section(): ?section_info { + return $this->cm->get_section_info(); + } + + /** + * Get the course object. + * + * @return cm_info + */ + public function get_cm(): cm_info { + return $this->cm; + } + + /** + * Get the course object. + * + * @return stdClass + */ + public function get_course(): stdClass { + return $this->course; + } + + /** + * Get the module name from the section component frankenstyle name. + * + * @return string + */ + private function get_module_name(): string { + return \core_component::normalize_component($this->sectioninfo->component)[1]; + } +} From e3c36e48cc37644f8df8e1999d677624d3022b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikel=20Mart=C3=ADn?= Date: Fri, 17 May 2024 10:09:39 +0200 Subject: [PATCH 3/3] MDL-81648 navigation: Add delegated section logic to section nodes --- lib/navigationlib.php | 12 +++++++++++- theme/boost/classes/boostnavbar.php | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/navigationlib.php b/lib/navigationlib.php index bb86b2d9810..60ddb51602e 100644 --- a/lib/navigationlib.php +++ b/lib/navigationlib.php @@ -2295,10 +2295,20 @@ class global_navigation extends navigation_node { continue; } + $parentnode = $coursenode; + + // Set the parent node to the parent section if this is a delegated section. + if ($section->is_delegated()) { + $parentsection = $section->get_component_instance()->get_parent_section(); + if ($parentsection) { + $parentnode = $coursenode->find($parentsection->id, self::TYPE_SECTION) ?: $coursenode; + } + } + $sectionname = get_section_name($course, $section); $url = course_get_url($course, $section->section, array('navigation' => true)); - $sectionnode = $coursenode->add($sectionname, $url, navigation_node::TYPE_SECTION, + $sectionnode = $parentnode->add($sectionname, $url, navigation_node::TYPE_SECTION, null, $section->id, new pix_icon('i/section', '')); $sectionnode->nodetype = navigation_node::NODETYPE_BRANCH; $sectionnode->hidden = (!$section->visible || !$section->available); diff --git a/theme/boost/classes/boostnavbar.php b/theme/boost/classes/boostnavbar.php index ad767af3dd4..e5b84953bc1 100644 --- a/theme/boost/classes/boostnavbar.php +++ b/theme/boost/classes/boostnavbar.php @@ -68,6 +68,7 @@ class boostnavbar implements \renderable { } } if ($this->page->context->contextlevel == CONTEXT_COURSE) { + $removesections = course_get_format($this->page->course)->can_sections_be_removed_from_navigation(); // Remove any duplicate navbar nodes. $this->remove_duplicate_items(); // Remove 'My courses' and 'Courses' if we are in the course context.