. namespace theme_boost; /** * Creates a navbar for boost that allows easy control of the navbar items. * * @package theme_boost * @copyright 2021 Adrian Greeve * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class boostnavbar implements \renderable { /** @var array The individual items of the navbar. */ protected $items = []; /** * Takes a navbar object and picks the necessary parts for display. * * @param \navbar $navbar The navigation bar. */ public function __construct(\navbar $navbar) { foreach ($navbar->get_items() as $item) { $this->items[] = $item; } $this->prepare_nodes_for_boost(); } /** * Prepares the navigation nodes for use with boost. */ protected function prepare_nodes_for_boost(): void { // Don't display the navbar if we are in the site navigation. if (!is_null($this->get_item('root'))) { $this->clear_items(); return; } $this->remove('myhome'); // Dashboard. $this->remove('home'); // Set the designated one path for courses. $mycoursesnode = $this->get_item('mycourses'); if (!is_null($mycoursesnode)) { // TODO: Once MDL-70801 lands point this to the new page. $url = new \moodle_url('/course/'); $mycoursesnode->action = $url; $mycoursesnode->text = get_string('courses'); } $this->remove_no_link_items(); // Don't display the navbar if there is only one item. Apparently this is bad UX design. if ($this->item_count() <= 1) { $this->clear_items(); return; } // Make sure that the last item is not a link. Not sure if this is always a good idea. $this->remove_last_item_action(); } /** * Get all the boostnavbaritem elements. * * @return boostnavbaritem[] Boost navbar items. */ public function get_items(): array { return $this->items; } /** * Removes all navigation items out of this boost navbar */ protected function clear_items(): void { $this->items = []; } /** * Retrieve a single navbar item. * * @param string|int $key The identifier of the navbar item to return. * @return \breadcrumb_navigation_node|null The navbar item. */ protected function get_item($key): ?\breadcrumb_navigation_node { foreach ($this->items as $item) { if ($key === $item->key) { return $item; } } return null; } /** * Counts all of the navbar items. * * @return int How many navbar items there are. */ protected function item_count(): int { return count($this->items); } /** * Remove a boostnavbaritem from the boost navbar. * * @param string|int $itemkey An identifier for the boostnavbaritem */ protected function remove($itemkey): void { $itemfound = false; foreach ($this->items as $key => $item) { if ($item->key === $itemkey) { unset($this->items[$key]); $itemfound = true; break; } } if (!$itemfound) { return; } $itemcount = $this->item_count(); if ($itemcount <= 0) { return; } $this->items = array_values($this->items); // Set the last item to last item if it is not. $lastitem = $this->items[$itemcount - 1]; if (!$lastitem->is_last()) { $lastitem->set_last(true); } } /** * Removes the action from the last item of the boostnavbaritem. */ protected function remove_last_item_action(): void { $item = end($this->items); $item->action = null; reset($this->items); } /** * Returns the second last navbar item. This is for use in the mobile view where we are showing just the second * last item in the breadcrumb navbar. * * @return breakcrumb_navigation_node|null The second last navigation node. */ public function get_penultimate_item(): ?\breadcrumb_navigation_node { $number = $this->item_count() - 2; return ($number >= 0) ? $this->items[$number] : null; } /** * Remove items that are categories or have no actions associated with them. */ protected function remove_no_link_items(): void { foreach ($this->items as $key => $value) { if (!$value->has_action() || $value->type == \navigation_node::TYPE_SECTION) { unset($this->items[$key]); } } $this->items = array_values($this->items); } }