added theme support

This commit is contained in:
Mark Gregory
2026-10-20 10:23:23 +01:00
parent 1d70a9c8cf
commit f0e31aad6b
5 changed files with 55 additions and 25 deletions
@@ -59,6 +59,9 @@ final class ThemeManagementController extends Controller
public function uninstall(string $theme, Loader $loader, ThemePackageManager $packages)
{
$item = $loader->find($theme);
abort_if(in_array($item->key(), ['sonardesk', 'sonardesk-admin'], true), 403, 'Bundled themes cannot be removed.');
$settings = app(SettingsRepository::class);
abort_if($settings->get($item->type().'_theme', null, 'site') === $item->key(), 409, 'Deactivate this theme before uninstalling.');
$packages->uninstall($item);
return back()->with('status', $item->name().' uninstalled.');
@@ -5,6 +5,7 @@ namespace Modules\Stylist\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\View;
use Modules\Stylist\Theme\Loader;
use Modules\Stylist\Theme\Stylist;
use Throwable;
@@ -12,20 +13,38 @@ final class ApplyActiveTheme
{
public function handle(Request $request, Closure $next)
{
$context = $request->is('admin', 'admin/*', 'stylist', 'stylist/*') ? 'backend' : 'frontend';
$context = $request->is('admin', 'admin/*', 'stylist', 'stylist/*')
|| $request->routeIs('admin.*', 'stylist.*') ? 'backend' : 'frontend';
try {
$loader = app(Loader::class);
$theme = app(Stylist::class)->current($context);
if ($theme->type() === $context) {
if ($theme->type() !== $context) {
$theme = $loader->find($context === 'backend' ? 'sonardesk-admin' : 'sonardesk');
}
$paths = [];
$seen = [];
while ($theme && ! isset($seen[$theme->key()])) {
$seen[$theme->key()] = true;
$path = $theme->path().'/views';
if (is_dir($path)) {
// Prepend so ordinary view('admin.index') and @extends('layouts.app')
// resolve theme files first, then original application files.
View::getFinder()->prependLocation($path);
$paths[] = $path;
}
$theme = $theme->parent() ? $loader->find($theme->parent()) : null;
}
$baseline = $loader->find($context === 'backend' ? 'sonardesk-admin' : 'sonardesk');
$paths[] = $baseline->path().'/views';
// Finder uses first match. Prepend in reverse order to preserve precedence.
foreach (array_reverse(array_unique($paths)) as $path) {
View::getFinder()->prependLocation($path);
}
} catch (Throwable $exception) {
report($exception); // Original application views remain available.
report($exception);
// Original Laravel views remain available for recovery.
}
return $next($request);
}
}