85 lines
2.4 KiB
PHP
85 lines
2.4 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Navigation;
|
|
|
|
use App\Models\NavItem;
|
|
use App\Models\RoleNavItem;
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
|
class NavbarService
|
|
{
|
|
public function getMenuForRoles(array $roles): array
|
|
{
|
|
$roles = array_values(array_filter(array_map(fn ($r) => strtolower(trim((string) $r)), $roles)));
|
|
$cacheKey = 'navbar_' . md5(json_encode($roles));
|
|
|
|
return Cache::remember($cacheKey, 300, function () use ($roles) {
|
|
$allowedIds = RoleNavItem::getNavItemIdsForRoles($roles);
|
|
if (empty($allowedIds)) {
|
|
return [];
|
|
}
|
|
|
|
$rows = NavItem::query()
|
|
->where('is_enabled', 1)
|
|
->orderBy('menu_parent_id', 'asc')
|
|
->orderBy('label', 'asc')
|
|
->orderBy('id', 'asc')
|
|
->get()
|
|
->toArray();
|
|
|
|
$byId = [];
|
|
foreach ($rows as $row) {
|
|
if (in_array((int) $row['id'], $allowedIds, true)) {
|
|
$row['children'] = [];
|
|
$byId[$row['id']] = $row;
|
|
}
|
|
}
|
|
|
|
$tree = [];
|
|
foreach ($byId as $id => &$node) {
|
|
$pid = $node['menu_parent_id'] ?? null;
|
|
if ($pid && isset($byId[$pid])) {
|
|
$byId[$pid]['children'][] = &$node;
|
|
} else {
|
|
$tree[] = &$node;
|
|
}
|
|
}
|
|
unset($node);
|
|
|
|
$this->sortTreeAlpha($tree);
|
|
|
|
return $tree;
|
|
});
|
|
}
|
|
|
|
public function clearCache(): void
|
|
{
|
|
Cache::flush();
|
|
}
|
|
|
|
private function labelKey(string $s): string
|
|
{
|
|
$s = trim(preg_replace('/\s+/', ' ', $s));
|
|
$s = preg_replace('/^[^[:alnum:]]+/u', '', $s);
|
|
$s = preg_replace('/^(?i)(the|an|a)\s+/', '', $s);
|
|
|
|
return mb_strtolower($s, 'UTF-8');
|
|
}
|
|
|
|
private function sortTreeAlpha(array &$nodes): void
|
|
{
|
|
usort($nodes, function ($a, $b) {
|
|
$result = strnatcasecmp($this->labelKey($a['label'] ?? ''), $this->labelKey($b['label'] ?? ''));
|
|
|
|
return $result !== 0 ? $result : ((int) ($a['id'] ?? 0) <=> (int) ($b['id'] ?? 0));
|
|
});
|
|
|
|
foreach ($nodes as &$node) {
|
|
if (!empty($node['children'])) {
|
|
$this->sortTreeAlpha($node['children']);
|
|
}
|
|
}
|
|
unset($node);
|
|
}
|
|
}
|