Files
Virtnet.bond/extensions/Others/NavbarManager/Helpers/DefaultRouteManager.php
2025-12-03 14:23:33 +01:00

383 lines
13 KiB
PHP

<?php
namespace Paymenter\Extensions\Others\NavbarManager\Helpers;
use App\Classes\Navigation;
use Paymenter\Extensions\Others\NavbarManager\Models\NavbarLink;
class DefaultRouteManager
{
/**
* Get all default navigation routes from the core Navigation class
*/
public static function getDefaultRoutes()
{
// Get routes for different navigation sections
$routes = [
'primary' => self::extractDefaultRoutes('getLinks'),
'dashboard' => self::extractDefaultRoutes('getDashboardLinks'),
'account' => self::extractDefaultRoutes('getAccountDropdownLinks'),
];
return $routes;
}
/**
* Extract default routes from a Navigation method (safe - no events)
*/
private static function extractDefaultRoutes($method)
{
try {
// Instead of calling Navigation methods that trigger events,
// we'll recreate the core logic without events
switch ($method) {
case 'getLinks':
return self::getCoreLinksWithoutEvents();
case 'getDashboardLinks':
return self::getCoreDashboardLinksWithoutEvents();
case 'getAccountDropdownLinks':
return self::getCoreAccountLinksWithoutEvents();
default:
return [];
}
} catch (\Exception $e) {
\Log::error('DefaultRouteManager: Error extracting routes from ' . $method, [
'error' => $e->getMessage()
]);
return [];
}
}
/**
* Get core primary navigation links without triggering events
*/
private static function getCoreLinksWithoutEvents()
{
$categories = \App\Models\Category::whereNull('parent_id')->where(function ($query) {
$query->whereHas('children')->orWhereHas('products', function ($query) {
$query->where('hidden', false);
});
})->get();
$routes = [
[
'name' => __('navigation.home'),
'route' => 'home',
'icon' => 'ri-home-2',
'priority' => 10,
],
[
'name' => __('navigation.shop'),
'route' => 'shop',
'icon' => 'ri-shopping-bag',
'priority' => 20,
'children' => $categories->map(function ($category, $index) {
return [
'name' => $category->name,
'route' => 'category.show',
'params' => ['category' => $category->slug],
'priority' => $index * 10,
];
})->toArray(),
'condition' => count($categories) > 0,
],
];
$extractedRoutes = [];
foreach ($routes as $index => $route) {
if (isset($route['route'])) {
$extractedRoutes[] = [
'key' => $route['route'] . '_' . $index,
'name' => $route['name'] ?? ucfirst($route['route']),
'route' => $route['route'],
'icon' => $route['icon'] ?? null,
'priority' => $route['priority'] ?? $index * 10,
'params' => $route['params'] ?? null,
'condition' => isset($route['condition']) ? (is_bool($route['condition']) ? ($route['condition'] ? 'always_visible' : 'always_hidden') : 'custom') : 'always_visible',
'children' => isset($route['children']) ? self::extractChildRoutes($route['children'], $route['route']) : [],
];
}
}
return $extractedRoutes;
}
/**
* Get core dashboard links without triggering events
*/
private static function getCoreDashboardLinksWithoutEvents()
{
$routes = [
[
'name' => __('navigation.dashboard'),
'route' => 'dashboard',
'icon' => 'ri-function',
'priority' => 10,
],
[
'name' => __('navigation.services'),
'route' => 'services',
'icon' => 'ri-archive-stack',
'priority' => 20,
],
[
'name' => __('navigation.invoices'),
'route' => 'invoices',
'icon' => 'ri-receipt',
'priority' => 30,
],
];
$extractedRoutes = [];
foreach ($routes as $index => $route) {
if (isset($route['route'])) {
$extractedRoutes[] = [
'key' => $route['route'] . '_' . $index,
'name' => $route['name'] ?? ucfirst($route['route']),
'route' => $route['route'],
'icon' => $route['icon'] ?? null,
'priority' => $route['priority'] ?? $index * 10,
'params' => $route['params'] ?? null,
'condition' => 'always_visible',
'children' => [],
];
}
}
return $extractedRoutes;
}
/**
* Get core account links without triggering events
*/
private static function getCoreAccountLinksWithoutEvents()
{
$routes = [
[
'name' => __('navigation.profile'),
'route' => 'profile',
'icon' => 'ri-user',
'priority' => 10,
],
[
'name' => __('navigation.logout'),
'route' => 'auth.logout',
'icon' => 'ri-logout',
'priority' => 90,
],
];
$extractedRoutes = [];
foreach ($routes as $index => $route) {
if (isset($route['route'])) {
$extractedRoutes[] = [
'key' => $route['route'] . '_' . $index,
'name' => $route['name'] ?? ucfirst($route['route']),
'route' => $route['route'],
'icon' => $route['icon'] ?? null,
'priority' => $route['priority'] ?? $index * 10,
'params' => $route['params'] ?? null,
'condition' => 'always_visible',
'children' => [],
];
}
}
return $extractedRoutes;
}
/**
* Extract child routes from parent route
*/
private static function extractChildRoutes($children, $parentRoute)
{
$extractedChildren = [];
foreach ($children as $index => $child) {
if (isset($child['route'])) {
$extractedChildren[] = [
'key' => $parentRoute . '_child_' . $child['route'] . '_' . $index,
'name' => $child['name'] ?? ucfirst($child['route']),
'route' => $child['route'],
'icon' => $child['icon'] ?? null,
'priority' => $child['priority'] ?? $index * 10,
'params' => $child['params'] ?? null,
];
}
}
return $extractedChildren;
}
/**
* Sync default routes to database for editing
*/
public static function syncDefaultRoutes($type = 'primary')
{
$defaultRoutes = self::getDefaultRoutes()[$type] ?? [];
$synced = 0;
foreach ($defaultRoutes as $route) {
$existing = NavbarLink::where('default_route_key', $route['key'])
->where('type', $type)
->first();
if (!$existing) {
NavbarLink::create([
'name' => $route['name'],
'type' => $type,
'link_type' => 'route',
'route_name' => $route['route'],
'route_params' => $route['params'],
'icon' => $route['icon'],
'condition' => $route['condition'],
'sort_order' => $route['priority'],
'is_active' => true,
'is_default_override' => true,
'default_route_key' => $route['key'],
'default_priority' => $route['priority'],
]);
$synced++;
}
// Sync children
foreach ($route['children'] as $child) {
$existingChild = NavbarLink::where('default_route_key', $child['key'])
->where('type', $type)
->first();
if (!$existingChild && $existing) {
NavbarLink::create([
'name' => $child['name'],
'type' => $type,
'link_type' => 'route',
'route_name' => $child['route'],
'route_params' => $child['params'],
'icon' => $child['icon'],
'sort_order' => $child['priority'],
'is_active' => true,
'parent_id' => $existing->id,
'is_default_override' => true,
'default_route_key' => $child['key'],
'default_priority' => $child['priority'],
]);
$synced++;
}
}
}
return $synced;
}
/**
* Get merged navigation (default + custom)
*/
public static function getMergedNavigation($type = 'primary')
{
// Get default routes that are NOT overridden
$defaultRoutes = self::getDefaultRoutes()[$type] ?? [];
$overriddenKeys = NavbarLink::defaultOverrides()
->where('type', $type)
->pluck('default_route_key')
->toArray();
$mergedRoutes = [];
// Add non-overridden default routes
foreach ($defaultRoutes as $route) {
if (!in_array($route['key'], $overriddenKeys)) {
$mergedRoutes[] = [
'name' => $route['name'],
'route' => $route['route'],
'icon' => $route['icon'],
'priority' => $route['priority'],
'params' => $route['params'],
'spa' => true,
'source' => 'default',
];
}
}
// Add custom and overridden routes from database
$customRoutes = NavbarLink::active()
->topLevel()
->where('type', $type)
->orderBy('sort_order')
->get();
foreach ($customRoutes as $link) {
$formatted = self::formatNavbarLink($link);
if ($formatted) {
$formatted['source'] = $link->is_default_override ? 'override' : 'custom';
$mergedRoutes[] = $formatted;
}
}
// Sort by priority
usort($mergedRoutes, function ($a, $b) {
return ($a['priority'] ?? 0) <=> ($b['priority'] ?? 0);
});
return $mergedRoutes;
}
/**
* Format NavbarLink model to navigation array format
*/
private static function formatNavbarLink($link)
{
$formatted = [
'name' => $link->name,
'priority' => $link->sort_order,
];
// Add icon if valid
if ($link->icon) {
$baseIcon = preg_replace('/-(?:line|fill)$/', '', $link->icon);
$formatted['icon'] = $baseIcon;
}
// Handle different link types
switch ($link->link_type) {
case 'route':
if ($link->route_name) {
$formatted['route'] = $link->route_name;
$formatted['spa'] = true;
if ($link->route_params) {
$params = is_string($link->route_params)
? json_decode($link->route_params, true)
: $link->route_params;
if ($params && is_array($params)) {
$formatted['params'] = $params;
}
}
} else {
return null;
}
break;
case 'path':
case 'url':
$formatted['route'] = 'navbar.redirect';
$formatted['params'] = ['linkId' => $link->id];
$formatted['spa'] = false;
break;
}
// Handle children
if ($link->children && $link->children->count() > 0) {
$children = [];
foreach ($link->children->where('is_active', true) as $child) {
$childFormatted = self::formatNavbarLink($child);
if ($childFormatted) {
$children[] = $childFormatted;
}
}
if (!empty($children)) {
$formatted['children'] = $children;
}
}
return $formatted;
}
}