public function getNavigation($activeDocument, $navigationRootDocument = null, $htmlMenuIdPrefix = null, $pageCallback = null, $cache = true)
{
$cacheEnabled = (bool) $cache;
$this->_htmlMenuIdPrefix = $htmlMenuIdPrefix;
if (!$navigationRootDocument) {
$navigationRootDocument = Document::getById(1);
}
$cacheKeys = ["root_id__" . $navigationRootDocument->getId(), $htmlMenuIdPrefix];
if (Site::isSiteRequest()) {
$site = Site::getCurrentSite();
$cacheKeys[] = "site__" . $site->getId();
}
if (is_string($cache)) {
$cacheKeys[] = "custom__" . $cache;
}
if ($pageCallback instanceof \Closure) {
$cacheKeys[] = "pageCallback_" . closureHash($pageCallback);
}
$cacheKey = "nav_" . md5(serialize($cacheKeys));
$navigation = CacheManager::load($cacheKey);
if (!$navigation || !$cacheEnabled) {
$navigation = new \Zend_Navigation();
if ($navigationRootDocument->hasChilds()) {
$rootPage = $this->buildNextLevel($navigationRootDocument, true, $pageCallback);
$navigation->addPages($rootPage);
}
// we need to force caching here, otherwise the active classes and other settings will be set and later
// also written into cache (pass-by-reference) ... when serializing the data directly here, we don't have this problem
if ($cacheEnabled) {
CacheManager::save($navigation, $cacheKey, ["output", "navigation"], null, 999, true);
}
}
// set active path
$front = \Zend_Controller_Front::getInstance();
$request = $front->getRequest();
// try to find a page matching exactly the request uri
$activePages = $navigation->findAllBy("uri", $request->getRequestUri());
if (empty($activePages)) {
// try to find a page matching the path info
$activePages = $navigation->findAllBy("uri", $request->getPathInfo());
}
if (empty($activePages)) {
// use the provided pimcore document
$activePages = $navigation->findAllBy("realFullPath", $activeDocument->getRealFullPath());
}
if (empty($activePages)) {
// find by link target
$activePages = $navigation->findAllBy("uri", $activeDocument->getFullPath());
}
// cleanup active pages from links
// pages have priority, if we don't find any active page, we use all we found
$tmpPages = [];
foreach ($activePages as $page) {
if ($page instanceof Uri && $page->getDocumentType() != "link") {
$tmpPages[] = $page;
}
}
if (count($tmpPages)) {
$activePages = $tmpPages;
}
if (!empty($activePages)) {
// we found an active document, so we can build the active trail by getting respectively the parent
foreach ($activePages as $activePage) {
$this->addActiveCssClasses($activePage, true);
}
} else {
// we don't have an active document, so we try to build the trail on our own
$allPages = $navigation->findAllBy("uri", "/.*/", true);
foreach ($allPages as $page) {
$activeTrail = false;
if ($page->getUri() && strpos($activeDocument->getRealFullPath(), $page->getUri() . "/") === 0) {
$activeTrail = true;
}
if ($page instanceof Uri) {
if ($page->getDocumentType() == "link") {
if ($page->getUri() && strpos($activeDocument->getFullPath(), $page->getUri() . "/") === 0) {
$activeTrail = true;
}
}
}
if ($activeTrail) {
$page->setActive(true);
$page->setClass($page->getClass() . " active active-trail");
}
}
}
return $navigation;
}