ensureIntlNumberFormatter(); } /** * Bootstrap any application services. */ public function boot(): void { $this->registerFilamentLivewireResolver(); Paginator::defaultView('partials.pagination'); View::composer('layouts.app', function ($view): void { $categories = Category::with([ 'children' => function ($query) { $query->withCount('products') ->orderBy('sort'); }, ]) ->withCount('products') ->whereNull('parent_id') ->orderBy('sort') ->get(); $view->with([ 'sidebarCategories' => $categories, 'siteTitle' => SiteSetting::value('site_title', 'AI 工具导航'), 'siteDescription' => SiteSetting::value('site_description', '精选 AI 工具与产品导航'), 'siteLogo' => SiteSetting::value('site_logo'), 'siteFooter' => SiteSetting::value('site_footer'), 'gaId' => SiteSetting::value('ga_id'), 'icpNumber' => SiteSetting::value('icp_number'), 'socialLinks' => $this->parseSocialLinks(SiteSetting::value('social_links', '')), ]); }); } private function ensureIntlNumberFormatter(): void { if (class_exists('NumberFormatter')) { return; } $polyfill = app_path('Support/NumberFormatter.php'); if (is_file($polyfill)) { require_once $polyfill; } } private function registerFilamentLivewireResolver(): void { Livewire::resolveMissingComponent(function (string $name): ?string { if (! Str::startsWith($name, ['filament.', 'app.'])) { return null; } $class = collect(explode('.', $name)) ->map(fn (string $segment) => Str::studly($segment)) ->join('\\'); return is_subclass_of($class, \Livewire\Component::class) ? $class : null; }); } private function parseSocialLinks(?string $raw): array { if (!$raw) { return []; } $lines = preg_split('/\r\n|\r|\n/', $raw); $links = []; foreach ($lines as $line) { $line = trim($line); if ($line === '') { continue; } [$name, $url] = array_pad(explode('|', $line, 2), 2, ''); if ($name && $url) { $links[] = ['name' => trim($name), 'url' => trim($url)]; } } return $links; } }