breakign changes
This commit is contained in:
@@ -13,7 +13,10 @@ use Modules\Stylist\Console\ThemeDoctorCommand;
|
||||
use Modules\Stylist\Console\ValidateThemeCommand;
|
||||
use Modules\Stylist\Html\ThemeHtmlBuilder;
|
||||
use Modules\Stylist\Html\ThemeSeoBuilder;
|
||||
use Modules\Stylist\Support\FrontendNavigation;
|
||||
use Modules\Stylist\Support\ModuleInfo;
|
||||
use Modules\Stylist\Services\ThemeSettings;
|
||||
use Modules\Stylist\Theme\Loader;
|
||||
use Modules\Stylist\Theme\Stylist;
|
||||
|
||||
final class StylistServiceProvider extends ServiceProvider
|
||||
@@ -62,6 +65,24 @@ final class StylistServiceProvider extends ServiceProvider
|
||||
|
||||
$view->with('activeTheme', $this->app->make(Stylist::class)->current());
|
||||
});
|
||||
|
||||
|
||||
View::composer('stylist-theme-saasland::*', function ($view): void {
|
||||
$theme = $this->app->make(Loader::class)->find('saasland');
|
||||
$settings = $this->app->make(ThemeSettings::class)->get($theme);
|
||||
$navigation = $this->app->make(FrontendNavigation::class);
|
||||
|
||||
$view->with([
|
||||
'siteTitle' => filled($settings['site_title'] ?? null) ? $settings['site_title'] : config('app.name', 'Saasland'),
|
||||
'siteDescription' => filled($settings['site_description'] ?? null) ? $settings['site_description'] : 'Modern software for modern companies.',
|
||||
'logoUrl' => $settings['logo_url'] ?? null,
|
||||
'facebookUrl' => $settings['facebook_url'] ?? null,
|
||||
'xUrl' => $settings['x_url'] ?? null,
|
||||
'linkedinUrl' => $settings['linkedin_url'] ?? null,
|
||||
'primaryNavigation' => $navigation->primary(),
|
||||
'footerNavigation' => $navigation->footer(),
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
private function registerViews(): void
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Stylist\Support;
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Modules\Menus\Models\Menu;
|
||||
use Throwable;
|
||||
|
||||
final class FrontendNavigation
|
||||
{
|
||||
/** @return array<int, array<string, mixed>> */
|
||||
public function primary(): array
|
||||
{
|
||||
return $this->forLocations(['primary', 'header', 'main'], $this->fallbackPrimary());
|
||||
}
|
||||
|
||||
/** @return array<int, array<string, mixed>> */
|
||||
public function footer(): array
|
||||
{
|
||||
return $this->forLocations(['footer'], $this->fallbackFooter());
|
||||
}
|
||||
|
||||
/** @param array<int, string> $locations
|
||||
* @param array<int, array<string, mixed>> $fallback
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
private function forLocations(array $locations, array $fallback): array
|
||||
{
|
||||
try {
|
||||
if (! Schema::hasTable('menus')) {
|
||||
return $fallback;
|
||||
}
|
||||
|
||||
$menu = Menu::query()
|
||||
->where('enabled', true)
|
||||
->whereIn('location', $locations)
|
||||
->orderByRaw('CASE location '.collect($locations)->map(fn (string $location, int $index) => "WHEN ? THEN {$index}")->implode(' ').' ELSE 999 END', $locations)
|
||||
->first();
|
||||
|
||||
if (! $menu || ! is_array($menu->items) || $menu->items === []) {
|
||||
return $fallback;
|
||||
}
|
||||
|
||||
$items = $this->normaliseItems($menu->items);
|
||||
|
||||
return $items === [] ? $fallback : $items;
|
||||
} catch (Throwable) {
|
||||
return $fallback;
|
||||
}
|
||||
}
|
||||
|
||||
/** @param array<int, mixed> $items
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
private function normaliseItems(array $items): array
|
||||
{
|
||||
return collect($items)
|
||||
->filter(fn (mixed $item): bool => is_array($item) && ($item['enabled'] ?? true) !== false)
|
||||
->map(function (array $item): ?array {
|
||||
$label = trim((string) ($item['label'] ?? $item['title'] ?? $item['name'] ?? ''));
|
||||
if ($label === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$url = $this->resolveUrl($item);
|
||||
if ($url === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'label' => $label,
|
||||
'url' => $url,
|
||||
'target' => ($item['target'] ?? null) === '_blank' ? '_blank' : null,
|
||||
'children' => $this->normaliseItems((array) ($item['children'] ?? $item['items'] ?? [])),
|
||||
];
|
||||
})
|
||||
->filter()
|
||||
->values()
|
||||
->all();
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $item */
|
||||
private function resolveUrl(array $item): ?string
|
||||
{
|
||||
$routeName = trim((string) ($item['route'] ?? $item['route_name'] ?? ''));
|
||||
if ($routeName !== '' && Route::has($routeName)) {
|
||||
return route($routeName, (array) ($item['parameters'] ?? []));
|
||||
}
|
||||
|
||||
$pageSlug = trim((string) ($item['page_slug'] ?? $item['slug'] ?? ''));
|
||||
if ($pageSlug !== '' && Route::has('pages.public.show')) {
|
||||
return route('pages.public.show', $pageSlug);
|
||||
}
|
||||
|
||||
$url = trim((string) ($item['url'] ?? $item['href'] ?? ''));
|
||||
|
||||
return $url !== '' ? $url : null;
|
||||
}
|
||||
|
||||
/** @return array<int, array<string, mixed>> */
|
||||
private function fallbackPrimary(): array
|
||||
{
|
||||
$items = [['label' => 'Home', 'url' => url('/'), 'target' => null, 'children' => []]];
|
||||
|
||||
if (Route::has('blog.public.index')) {
|
||||
$items[] = ['label' => 'Blog', 'url' => route('blog.public.index'), 'target' => null, 'children' => []];
|
||||
}
|
||||
if (Route::has('news.public.index')) {
|
||||
$items[] = ['label' => 'News', 'url' => route('news.public.index'), 'target' => null, 'children' => []];
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/** @return array<int, array<string, mixed>> */
|
||||
private function fallbackFooter(): array
|
||||
{
|
||||
return $this->fallbackPrimary();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user