Skip to content

Commit

Permalink
Adopt changes in /lib/classes/navigation/output/primary.php for Moodl…
Browse files Browse the repository at this point in the history
…e 4.3, resolves moodle-an-hochschulen#436
  • Loading branch information
prasanna-lmsace authored and abias committed Nov 18, 2024
1 parent 458086f commit 79c5ab6
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Changes

### Unreleased

* 2024-11-18 - Upstream change: Adopt changes from MDL-77732 ('Custom menu items do not receive active behaviour'), resolves #436 #620 #384 #715.
* 2024-11-13 - Upstream change: Adopt changes from MDL-78999 ('Site logo does not appear in mobile view'), resolves #753.
* 2024-11-11 - Release: Add ssystems GmbH to the list of maintainers in README.md.

Expand Down
90 changes: 87 additions & 3 deletions classes/output/navigation/primary.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ public function export_for_template(?renderer_base $output = null): array {
$locationbottom = smartmenu::get_menus_forlocation(smartmenu::LOCATION_BOTTOM, $smartmenus);

// Merge the smart menu nodes which contain the main menu location with the primary and custom menu nodes.
$menudata = array_merge($this->get_primary_nav(), $this->get_custom_menu($output), $mainmenu);
$mainsmartmenumergedcustom = array_merge($this->get_custom_menu($output), $mainmenu);
$menudata = (object) $this->merge_primary_and_custom($this->get_primary_nav(), $mainsmartmenumergedcustom);
$moremenu = new \core\navigation\output\more_menu((object) $menudata, 'navbar-nav', false);

// Menubar.
Expand All @@ -119,9 +120,10 @@ public function export_for_template(?renderer_base $output = null): array {

// Bottom bar.
// Include the menu navigation menus to the mobile menu when the bottom bar doesn't have any menus.
$mergecustombottommenus = array_merge($this->get_custom_menu($output), $locationbottom);
$mobileprimarynav = (!empty($locationbottom))
? array_merge($this->get_primary_nav(), $this->get_custom_menu($output), $locationbottom)
: $mobileprimarynav = $menudata;
? $this->merge_primary_and_custom($this->get_primary_nav(), $mergecustombottommenus, true)
: $this->merge_primary_and_custom($this->get_primary_nav(), $mainsmartmenumergedcustom, true);

if (!empty($mobileprimarynav)) {
$bottombar = new \core\navigation\output\more_menu((object) $mobileprimarynav, 'navbar-nav-bottom-bar', false);
Expand Down Expand Up @@ -306,4 +308,86 @@ public function build_usermenus(&$usermenu, $menus) {
array_push($usermenu['items'], $logout);
}
}

/**
* Recursive checks if any of the children is active. If that's the case this node (the parent) is active as
* well. If the node has no children, check if the node itself is active. Use pass by reference for the node
* object because we actively change/set the "isactive" flag inside the method and this needs to be kept at the
* callers side.
* Set $expandedmenu to true, if the mobile menu is done, in this case the active flag gets the node that is
* actually active, while the parent hierarchy of the active node gets the flag isopen.
*
* Modifications compared to the original function:
* * Updated the children node type to object
*
* @param object $node
* @param bool $expandedmenu
* @return bool
*/
protected function flag_active_nodes(object $node, bool $expandedmenu = false): bool {
global $FULLME;
$active = false;
foreach (array_keys($node->children ?? []) as $c) {

// Update the type of child nodes (smart menu).
// To prevent issues with already configured menus,
// The type of children is not updated during the smart menu build process.
$child = (object) $node->children[$c];

if ($this->flag_active_nodes($child, $expandedmenu)) {
$active = true;
}
}
// One of the children is active, so this node (the parent) is active as well.
if ($active) {
if ($expandedmenu) {
$node->isopen = true;
} else {
$node->isactive = true;
}
return true;
}

// By default, the menu item node to check is not active.
$node->isactive = false;

// Check if the node url matches the called url. The node url may omit the trailing index.php, therefore check
// this as well.
if (empty($node->url)) {
// Current menu node has no url set, so it can't be active.
return false;
}
$nodeurl = parse_url($node->url);
$current = parse_url($FULLME ?? '');

$pathmatches = false;

// Exact match of the path of node and current url.
$nodepath = $nodeurl['path'] ?? '/';
$currentpath = $current['path'] ?? '/';
if ($nodepath === $currentpath) {
$pathmatches = true;
}
// The current url may be trailed by a index.php, otherwise it's the same as the node path.
if (!$pathmatches && $nodepath . 'index.php' === $currentpath) {
$pathmatches = true;
}
// No path did match, so the node can't be active.
if (!$pathmatches) {
return false;
}
// We are here because the path matches, so now look at the query string.
$nodequery = $nodeurl['query'] ?? '';
$currentquery = $current['query'] ?? '';
// If the node has no query string defined, then the patch match is sufficient.
if (empty($nodeurl['query'])) {
$node->isactive = true;
return true;
}
// If the node contains a query string then also the current url must match this query.
if ($nodequery === $currentquery) {
$node->isactive = true;
}
return $node->isactive;
}
}

0 comments on commit 79c5ab6

Please sign in to comment.