diff --git a/extensions/Others/NavbarManager/Admin/Resources/NavbarLinkResource.php b/extensions/Others/NavbarManager/Admin/Resources/NavbarLinkResource.php index 013bf9dbd..68cee1721 100644 --- a/extensions/Others/NavbarManager/Admin/Resources/NavbarLinkResource.php +++ b/extensions/Others/NavbarManager/Admin/Resources/NavbarLinkResource.php @@ -20,11 +20,11 @@ class NavbarLinkResource extends Resource { protected static ?string $model = NavbarLink::class; - protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-bars-3'; + protected static ?string $navigationIcon = 'heroicon-o-bars-3'; protected static ?string $navigationLabel = 'Navbar Manager'; - protected static string|\UnitEnum|null $navigationGroup = 'Content'; + protected static ?string $navigationGroup = 'Content'; public static function getAvailableRoutes(): array { diff --git a/extensions/Others/NavbarManager/NavbarManager.php b/extensions/Others/NavbarManager/NavbarManager.php index dd9b8d819..76ea478f5 100644 --- a/extensions/Others/NavbarManager/NavbarManager.php +++ b/extensions/Others/NavbarManager/NavbarManager.php @@ -50,26 +50,79 @@ class NavbarManager extends Extension public function boot() { - // Register view service provider + // Don't run any navigation modifications in admin or console + if ($this->isAdminContext()) { + // Only register Filament resource in admin + $this->registerFilamentResource(); + return; + } + + // Register view service provider (frontend only) app()->register(\Paymenter\Extensions\Others\NavbarManager\Providers\ViewServiceProvider::class); // Register custom routes for navbar links require __DIR__ . '/routes/web.php'; - // Register event listeners for navigation - dodaće naše linkove uz postojeće + // Register event listeners for navigation - only for frontend Event::listen('navigation', function () { - return $this->getNavigationLinks('primary'); + if (!$this->isAdminContext()) { + return $this->getNavigationLinks('primary'); + } + return []; }); Event::listen('navigation.account-dropdown', function () { - return $this->getNavigationLinks('account'); + if (!$this->isAdminContext()) { + return $this->getNavigationLinks('account'); + } + return []; }); Event::listen('navigation.dashboard', function () { - return $this->getNavigationLinks('dashboard'); + if (!$this->isAdminContext()) { + return $this->getNavigationLinks('dashboard'); + } + return []; }); + } - // Register the Filament resource + /** + * Check if we're in admin context + */ + private function isAdminContext(): bool + { + if (app()->runningInConsole()) { + return false; // Allow in console for migrations, etc. + } + + try { + $currentPath = request()->path(); + + // Check for admin routes + if (str_starts_with($currentPath, 'admin') || + str_contains($currentPath, '/admin/') || + request()->is('admin') || + request()->is('admin/*')) { + return true; + } + + // Check for Filament routes + if (str_starts_with($currentPath, 'filament') || + request()->is('filament/*')) { + return true; + } + + return false; + } catch (\Exception $e) { + return false; + } + } + + /** + * Register Filament resource + */ + private function registerFilamentResource(): void + { try { \Filament\Facades\Filament::serving(function () { \Filament\Facades\Filament::getCurrentPanel() @@ -78,7 +131,9 @@ class NavbarManager extends Extension ]); }); } catch (\Exception $e) { - // Resource not yet available + \Log::error('NavbarManager: Failed to register Filament resource', [ + 'error' => $e->getMessage() + ]); } } @@ -248,6 +303,61 @@ class NavbarManager extends Extension } } + private function isValidIcon($icon) + { + // Basic validation for RemixIcon format + if (!preg_match('/^ri-[\w-]+$/', $icon)) { + return false; + } + + // List of common valid RemixIcon names to avoid errors (without -line/-fill suffix) + $commonIcons = [ + 'ri-home', 'ri-user', 'ri-settings', 'ri-dashboard', + 'ri-menu', 'ri-link', 'ri-external-link', 'ri-folder', + 'ri-file', 'ri-edit', 'ri-delete-bin', 'ri-add', + 'ri-navigation', 'ri-admin', 'ri-function', 'ri-archive-stack', + 'ri-receipt', 'ri-customer-service', 'ri-settings-3', 'ri-megaphone', + 'ri-shopping-bag', 'ri-check', 'ri-close', 'ri-arrow-down-s' + ]; + + // Remove -line or -fill suffix if present to get base icon name + $baseIcon = preg_replace('/-(?:line|fill)$/', '', $icon); + + // If it's in our common list, it's definitely valid + if (in_array($baseIcon, $commonIcons)) { + return true; + } + + // For other icons, just check the format (basic validation) + // In a production environment, you might want to check if the SVG file actually exists + return true; + } +} + + $children = []; + foreach ($link->children->where('is_active', true) as $child) { + if ($this->shouldShowLink($child)) { + $childFormatted = $this->formatLink($child); + if ($childFormatted) { + $children[] = $childFormatted; + } + } + } + if (!empty($children)) { + $formatted['children'] = $children; + } + } + + return $formatted; + } catch (\Exception $e) { + \Log::error('NavbarManager: Error formatting link', [ + 'link_id' => $link->id ?? 'unknown', + 'error' => $e->getMessage() + ]); + return null; + } + } + private function isValidIcon($icon) { // Basic validation for RemixIcon format diff --git a/extensions/Others/NavbarManager/Providers/ViewServiceProvider.php b/extensions/Others/NavbarManager/Providers/ViewServiceProvider.php index 24b7e0c95..209651f27 100644 --- a/extensions/Others/NavbarManager/Providers/ViewServiceProvider.php +++ b/extensions/Others/NavbarManager/Providers/ViewServiceProvider.php @@ -10,17 +10,44 @@ class ViewServiceProvider extends ServiceProvider { public function boot() { - // Register view namespace - $this->loadViewsFrom(__DIR__ . '/../resources/views', 'navbar-manager'); - // Load migrations from the extension so they run when the extension is enabled + // Always load migrations regardless of context $this->loadMigrationsFrom(__DIR__ . '/../Database/migrations'); - // Register Blade components - Blade::componentNamespace('Paymenter\\Extensions\\Others\\NavbarManager\\View\\Components', 'navbar-manager'); - - // Register global Blade directive for easy navbar usage - Blade::directive('navbarManagerLinks', function ($expression) { - return ""; - }); + // Only register views and components if not in admin context + if (!$this->isAdminContext()) { + // Register view namespace + $this->loadViewsFrom(__DIR__ . '/../resources/views', 'navbar-manager'); + + // Register Blade components + Blade::componentNamespace('Paymenter\\Extensions\\Others\\NavbarManager\\View\\Components', 'navbar-manager'); + + // Register global Blade directive for easy navbar usage + Blade::directive('navbarManagerLinks', function ($expression) { + return ""; + }); + } + } + + /** + * Check if we're in admin context + */ + private function isAdminContext(): bool + { + if (app()->runningInConsole()) { + return false; + } + + try { + $currentPath = request()->path(); + + return str_starts_with($currentPath, 'admin') || + str_contains($currentPath, '/admin/') || + str_starts_with($currentPath, 'filament') || + request()->is('admin') || + request()->is('admin/*') || + request()->is('filament/*'); + } catch (\Exception $e) { + return false; + } } } diff --git a/extensions/Others/NavbarManager/routes/web.php b/extensions/Others/NavbarManager/routes/web.php index 143a81b72..2c1ce0e90 100644 --- a/extensions/Others/NavbarManager/routes/web.php +++ b/extensions/Others/NavbarManager/routes/web.php @@ -3,7 +3,8 @@ use Illuminate\Support\Facades\Route; use Paymenter\Extensions\Others\NavbarManager\Models\NavbarLink; -Route::group(['prefix' => 'navbar'], function () { +// Only register frontend routes, not in admin +Route::group(['prefix' => 'navbar', 'middleware' => ['web']], function () { Route::get('/redirect/{linkId}', function($linkId) { try { $link = NavbarLink::findOrFail($linkId); @@ -19,6 +20,10 @@ Route::group(['prefix' => 'navbar'], function () { abort(404); } catch (\Exception $e) { + \Log::error('NavbarManager: Redirect failed', [ + 'link_id' => $linkId, + 'error' => $e->getMessage() + ]); abort(404); } })->name('navbar.redirect');