public function generateReferences($page)
{
$currentUrl = Request::path();
if (!strlen($currentUrl)) {
$currentUrl = '/';
}
$currentUrl = Str::lower(Url::to($currentUrl));
$activeMenuItem = $page->activeMenuItem ?: false;
$iterator = function ($items) use($currentUrl, &$iterator, $activeMenuItem) {
$result = [];
foreach ($items as $item) {
$parentReference = new MenuItemReference();
$parentReference->title = $item->title;
$parentReference->code = $item->code;
$parentReference->viewBag = $item->viewBag;
/*
* If the item type is URL, assign the reference the item's URL and compare the current URL with the item URL
* to determine whether the item is active.
*/
if ($item->type == 'url') {
$parentReference->url = $item->url;
$parentReference->isActive = $currentUrl == Str::lower($item->url) || $activeMenuItem === $item->code;
} else {
/*
* If the item type is not URL, use the API to request the item type's provider to
* return the item URL, subitems and determine whether the item is active.
*/
$apiResult = Event::fire('pages.menuitem.resolveItem', [$item->type, $item, $currentUrl, $this->theme]);
if (is_array($apiResult)) {
foreach ($apiResult as $itemInfo) {
if (!is_array($itemInfo)) {
continue;
}
if (!$item->replace && isset($itemInfo['url'])) {
$parentReference->url = $itemInfo['url'];
$parentReference->isActive = $itemInfo['isActive'] || $activeMenuItem === $item->code;
}
if (isset($itemInfo['items'])) {
$itemIterator = function ($items) use(&$itemIterator, $parentReference) {
$result = [];
foreach ($items as $item) {
$reference = new MenuItemReference();
$reference->title = isset($item['title']) ? $item['title'] : '--no title--';
$reference->url = isset($item['url']) ? $item['url'] : '#';
$reference->isActive = isset($item['isActive']) ? $item['isActive'] : false;
$reference->viewBag = isset($item['viewBag']) ? $item['viewBag'] : [];
if (!strlen($parentReference->url)) {
$parentReference->url = $reference->url;
$parentReference->isActive = $reference->isActive;
}
if (isset($item['items'])) {
$reference->items = $itemIterator($item['items']);
}
$result[] = $reference;
}
return $result;
};
$parentReference->items = $itemIterator($itemInfo['items']);
}
}
}
}
if ($item->items) {
$parentReference->items = $iterator($item->items);
}
if (!$item->replace) {
$result[] = $parentReference;
} else {
foreach ($parentReference->items as $subItem) {
$result[] = $subItem;
}
}
}
return $result;
};
$items = $iterator($this->items);
/*
* Populate the isChildActive property
*/
$hasActiveChild = function ($items) use(&$hasActiveChild) {
foreach ($items as $item) {
if ($item->isActive) {
return true;
}
$result = $hasActiveChild($item->items);
if ($result) {
return $result;
}
}
};
$iterator = function ($items) use(&$iterator, &$hasActiveChild) {
foreach ($items as $item) {
$item->isChildActive = $hasActiveChild($item->items);
$iterator($item->items);
}
};
$iterator($items);
return $items;
}