Your IP : 216.73.216.79


Current Path : /var/www/html/reddsis/app/Http/Helpers/
Upload File :
Current File : /var/www/html/reddsis/app/Http/Helpers/MenuHelper.php

<?php

namespace App\Http\Helpers;

use App\Models\Backend\menu\backend\Menu;
use App\Models\Backend\menu\backend\RoleMapping;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Str;

class MenuHelper
{
    public static function getCacheName(): string
    {
        return 'backend_menu_' . Str::slug(static::getCurrentRoles() ?: 'guest');
    }

    public static function getCurrentRoles(): string
    {
        $user = auth('admin')->user() ?: auth()->user();

        if (! $user || ! method_exists($user, 'getRoleNames')) {
            return '';
        }

        return $user->getRoleNames()->sort()->implode(',');
    }

    public static function getMenu(): array
    {
        $menus = Cache::remember(static::getCacheName(), 60, fn () => static::getAssignedMenu());

        return static::setActiveMenu($menus);
    }

    public static function bustCache(): void
    {
        Cache::forget(static::getCacheName());
    }

    private static function getAssignedMenu(): array
    {
        $roles = explode(',', static::getCurrentRoles());

        $assignedMenus = RoleMapping::with('menu')
            ->whereIn('role_code', array_filter($roles))
            ->whereHas('menu', fn ($q) => $q->where('menu_status', 1))
            ->orderBy('sort')
            ->get();

        return $assignedMenus
            ->filter(fn (RoleMapping $mapping) => static::parentId($mapping) === 0)
            ->map(fn (RoleMapping $mapping) => static::formatItem($mapping, $assignedMenus))
            ->values()
            ->all();
    }

    private static function getChild(int $id, $assignedMenus): array
    {
        return $assignedMenus
            ->filter(fn (RoleMapping $mapping) => static::parentId($mapping) === $id)
            ->sortBy('sort')
            ->map(fn (RoleMapping $mapping) => static::formatItem($mapping, $assignedMenus))
            ->values()
            ->all();
    }

    private static function formatItem(RoleMapping $mapping, $assignedMenus): array
    {
        $menu = $mapping->menu;

        return [
            'id' => $menu?->menu_id,
            'label' => $menu?->menu_name,
            'icon' => $menu?->menu_class,
            'url' => static::resolveUrl($menu?->menu_link),
            'active_routes' => $menu?->menu_active_route ?: [],
            'items' => static::getChild((int) $mapping->menu_id, $assignedMenus),
            'active' => false,
        ];
    }

    private static function parentId(RoleMapping $mapping): int
    {
        if ((int) $mapping->parent_id > 0) {
            return (int) $mapping->parent_id;
        }

        return (int) ($mapping->menu?->menu_parent_id ?? 0);
    }

    public static function setActiveMenu(array $menus): array
    {
        return static::loopSetChildItems($menus);
    }

    public static function loopSetChildItems(array $menus): array
    {
        foreach ($menus as &$menu) {
            $menu['items'] = static::loopSetChildItems($menu['items'] ?? []);
            $menu['active'] = static::checkActive($menu) || collect($menu['items'])->contains('active', true);
        }

        return $menus;
    }

    public static function checkActive(array $child): bool
    {
        $routeName = request()->route()?->getName();
        $activeRoutes = $child['active_routes'] ?? [];

        return $routeName && in_array($routeName, $activeRoutes, true);
    }

    public static function getPageTitle(string|null $routeName = null): string
    {
        $routeName ??= request()->route()?->getName();

        if (! $routeName) {
            return 'Home';
        }

        $menu = Menu::where('menu_link', $routeName)->first();

        if ($menu) {
            return $menu->menu_name;
        }

        $base = preg_replace('/\.(create|edit|show|index)$/', '', $routeName);

        if ($base !== $routeName) {
            $menu = Menu::where('menu_link', $base)->first();

            if ($menu) {
                $action = Str::of($routeName)->afterLast('.')->title();

                return $menu->menu_name . ' - ' . $action;
            }
        }

        return Str::of($routeName)->replace('.', ' ')->title();
    }

    private static function resolveUrl(?string $link): string
    {
        if (! $link) {
            return '#';
        }

        if (Route::has($link)) {
            return route($link);
        }

        return url($link);
    }
}