<?php class MenutrailbypathMenuHelper { protected $language; /** @var \MenutrailbypathUrlHelper */ protected $urlHelper; /** * MenutrailbypathMenuHelper constructor. * * @param $language */ public function __construct($language, MenutrailbypathUrlHelper $urlHelper) { $this->language = $language; $this->urlHelper = $urlHelper; } /** * Find link items matching the given link_paths in (almost) all menus * * @param $link_paths * @return array */ public function getMenuLinksByPaths(array $link_paths) { if (empty($link_paths)) { return array(); } $query = db_select('menu_links', 'ml') ->fields('ml') ->condition('link_path', $link_paths, 'IN') ->condition('hidden', 0) // Only consider normal, visible menu links. ->orderBy('depth') ->orderBy('weight') ->orderBy('mlid'); if (module_exists('i18n_menu')) { $query->condition('language', array(LANGUAGE_NONE, $this->language->language), 'IN'); } $results = $query->execute(); return ($results instanceof DatabaseStatementInterface) ? $this->translateMenuLinkTitles($results->fetchAll()) : array(); } /** * Get menu_links for a given menu_name * * @param $menu_name * @return array */ public function getMenuLinks($menu_name) { $cid = 'menu_trail_by_path:menu_links:' . $menu_name . ':' . $this->language->language; $cache = cache_get($cid, 'cache_menu'); if (!empty($cache->data)) { $menu_links = $cache->data; } if (!isset($menu_links)) { $query = db_select('menu_links', 'ml') ->fields('ml') ->condition('menu_name', $menu_name, '=') // Do not touch admin menu. ->condition('hidden', 0) // Only consider normal, visible menu links. ->orderBy('depth') ->orderBy('weight') ->orderBy('mlid'); if (module_exists('i18n_menu')) { $query->condition('language', array(LANGUAGE_NONE, $this->language->language), 'IN'); } $results = $query->execute(); $menu_links = ($results instanceof DatabaseStatementInterface) ? $this->translateMenuLinkTitles($results->fetchAll()) : array(); foreach ($menu_links as &$menu_link) { $menu_link->menu_path_by_trail_url = $this->urlHelper->getUrl($menu_link->link_path); } cache_set($cid, $menu_links, 'cache_menu'); } return $menu_links; } /** * translateMenuLinkTitles * * @param array $menu_links * @return array */ protected function translateMenuLinkTitles(array $menu_links) { foreach ($menu_links as $k => $menu_link) { if (module_exists('i18n_menu')) { $menu_link->link_title = _i18n_menu_link_title((array) $menu_link, $this->language->language); } } return $menu_links; } /** * Sort menu_links by the menu preference order, see menu_set_active_menu_names() * Stable sorting based on https://github.com/vanderlee/PHP-stable-sort-functions * * @param array $menu_links */ public function sortMenuLinksByMenuPreference(array &$menu_links) { $menu_preference = array_flip(menu_get_active_menu_names()); $menu_preference_max = count($menu_preference); $index = 0; foreach ($menu_links as &$item) { if (!isset($menu_preference[$item->menu_name])) { $menu_preference[$item->menu_name] = $menu_preference_max; } $item = array($index++, $item); } $usort_result = usort($menu_links, array(new MenutrailbypathUsortMenulinks($menu_preference), 'compare')); foreach ($menu_links as &$item) { $item = $item[1]; } return $usort_result; } /** * Make sure all custom menus are present in the active menus variable so that * their items may appear in the active trail. * @see https://www.drupal.org/node/2830385 * @see menu_update_7003() * * @return array */ public function getActiveMenuNames() { $active_menus = menu_get_active_menu_names(); foreach (menu_get_names() as $menu_name) { if (!in_array($menu_name, $active_menus) && (strpos($menu_name, 'menu-') === 0)) { $active_menus[] = $menu_name; } } return $active_menus; } }