diff --git a/lang/en/moodle.php b/lang/en/moodle.php index 4aa150f52c7..549e25ba965 100644 --- a/lang/en/moodle.php +++ b/lang/en/moodle.php @@ -239,6 +239,7 @@ $string['categorycontents'] = 'Subcategories and courses'; $string['categorycurrentcontents'] = 'Contents of {$a}'; $string['categorydeleted'] = 'The category \'{$a}\' was deleted'; $string['categoryduplicate'] = 'A category named \'{$a}\' already exists!'; +$string['categoryheader'] = 'Category menu'; $string['categoryhidden'] = '(hidden)'; $string['categorymodifiedcancel'] = 'Category was modified! Please cancel and try again.'; $string['categoryname'] = 'Category name'; diff --git a/lib/classes/navigation/views/secondary.php b/lib/classes/navigation/views/secondary.php index e28655811f6..4cc2cf71f49 100644 --- a/lib/classes/navigation/views/secondary.php +++ b/lib/classes/navigation/views/secondary.php @@ -166,6 +166,10 @@ class secondary extends view { $this->load_module_navigation(); $defaultmoremenunodes = $this->get_default_module_more_menu_nodes(); break; + case CONTEXT_COURSECAT: + $this->headertitle = get_string('categoryheader'); + $this->load_category_navigation(); + break; case CONTEXT_SYSTEM: $this->headertitle = get_string('homeheader'); $this->load_admin_navigation(); @@ -244,6 +248,19 @@ class secondary extends view { } } + /** + * Load the course category navigation. + */ + protected function load_category_navigation(): void { + $settingsnav = $this->page->settingsnav; + $mainnode = $settingsnav->find('categorysettings', self::TYPE_CONTAINER); + if ($mainnode) { + $url = new \moodle_url('/course/index.php', ['categoryid' => $this->context->instanceid]); + $this->add($this->context->get_context_name(), $url, self::TYPE_CONTAINER, null, 'categorymain'); + $this->load_remaining_nodes($mainnode, []); + } + } + /** * Load the site admin navigation */ diff --git a/lib/classes/navigation/views/view.php b/lib/classes/navigation/views/view.php index e711f7f5131..428cce91fa3 100644 --- a/lib/classes/navigation/views/view.php +++ b/lib/classes/navigation/views/view.php @@ -58,14 +58,6 @@ abstract class view extends navigation_node { $this->page = $page; $this->context = $this->page->context; - - // Not all pages override the active url. Do it now. - if ($this->page->has_set_url()) { - self::override_active_url(new \moodle_url($this->page->url)); - } else { - self::override_active_url(new \moodle_url($FULLME)); - } - $this->children = new navigation_node_collection(); } @@ -89,9 +81,25 @@ abstract class view extends navigation_node { return $nodesordered; } + /** + * Scan the given node for the active node. It starts first with a strict search and then switches to a base search if + * required. + * + * @param navigation_node $node The node to scan. + * @return navigation_node|null The active node or null. + */ + protected function scan_for_active_node(navigation_node $node): ?navigation_node { + $result = $this->active_node_scan($node); + if (!is_null($result)) { + return $result; + } else { + return $this->active_node_scan($node, URL_MATCH_BASE); + } + } + /** * This function recursively scans nodes until it finds the active node or there - * are no more nodes. We are using a custom implementation here to be more strict with the comparison + * are no more nodes. We are using a custom implementation here to adjust the strictness * and also because we need the parent node and not the specific child node in the new views. * e.g. Structure for site admin, * SecondaryNav @@ -102,16 +110,18 @@ abstract class view extends navigation_node { * In the above example, if we are on the 'User Policies' page, the active node should be 'Users' * * @param navigation_node $node + * @param int $strictness How stict to be with the scan for the active node. * @return navigation_node|null */ - protected function scan_for_active_node(navigation_node $node): ?navigation_node { - if ($node->check_if_active()) { + protected function active_node_scan(navigation_node $node, int $strictness = URL_MATCH_EXACT): ?navigation_node { + + if ($node->check_if_active($strictness)) { return $node; // No need to continue, exit function. } if ($node->children->count() > 0) { foreach ($node->children as $child) { - if ($this->scan_for_active_node($child)) { + if ($this->active_node_scan($child, $strictness)) { // If node is one of the new views then set the active node to the child. if (!$node instanceof view) { $node->make_active(); @@ -122,10 +132,12 @@ abstract class view extends navigation_node { } return $node; // We have found the active node, set the parent status, no need to continue. + } else { + // Make sure to reset the active state. + $child->make_inactive(); } } } - return null; } } diff --git a/lib/navigationlib.php b/lib/navigationlib.php index e8a8abf75e6..fdd52a5052e 100644 --- a/lib/navigationlib.php +++ b/lib/navigationlib.php @@ -5326,7 +5326,7 @@ class settings_navigation extends navigation_node { if (can_edit_in_category($catcontext->instanceid)) { $url = new moodle_url('/course/management.php', array('categoryid' => $catcontext->instanceid)); $editstring = get_string('managecategorythis'); - $categorynode->add($editstring, $url, self::TYPE_SETTING, null, null, new pix_icon('i/edit', '')); + $categorynode->add($editstring, $url, self::TYPE_SETTING, null, 'managecategory', new pix_icon('i/edit', '')); } if (has_capability('moodle/category:manage', $catcontext)) { diff --git a/lib/tests/navigation/views/secondary_test.php b/lib/tests/navigation/views/secondary_test.php index fa511af14b5..a1a217cb91b 100644 --- a/lib/tests/navigation/views/secondary_test.php +++ b/lib/tests/navigation/views/secondary_test.php @@ -116,6 +116,7 @@ class secondary_test extends \advanced_testcase { } $PAGE->set_url($pageurl); + navigation_node::override_active_url($pageurl); $PAGE->set_course($pagecourse); $PAGE->set_context($contextrecord);