added theme support
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
# SonarDesk Stylist integration — 1.0.0
|
||||
# SonarDesk — Stylist theme integration
|
||||
|
||||
- `resources/themes/sonardesk/views` contains the original frontend Blade templates.
|
||||
- `resources/themes/sonardesk-admin/views` contains the original backend Blade templates.
|
||||
- Both are fully editable independent view trees, with application view fallback.
|
||||
- Active theme is selected by existing Stylist SettingsRepository (`frontend_theme` / `backend_theme`).
|
||||
- The `ApplyActiveTheme` web middleware prepends the active theme view directory for each request.
|
||||
- Public pages and authenticated customer pages use frontend; `/admin` and `/stylist` use backend.
|
||||
- Controllers, routes, licensing, payments, APIs and mail templates remain unchanged.
|
||||
- Theme management now requires AdminOnly permissions.
|
||||
- Existing CSS/JS assets remain in place. Replacement themes may provide new layout asset links.
|
||||
- Run `php artisan optimize:clear` and `php artisan migrate` after deployment.
|
||||
- Check `/stylist` as an administrator, then verify public, account, admin, and checkout pages.
|
||||
- If database already contains old `frontend_theme`/`backend_theme` values, activate the new bundled themes from Stylist.
|
||||
- Theme ZIP installation security and the completeness of third-party theme templates require separate review before production use.
|
||||
Stylist is the primary resolver for ordinary frontend and backend Laravel views. The active theme, its parents, the bundled baseline and finally `resources/views` are searched in that order.
|
||||
|
||||
- Frontend: `resources/themes/sonardesk/views`.
|
||||
- Backend: `resources/themes/sonardesk-admin/views`.
|
||||
- The bundled themes preserve existing markup, CSS, JavaScript, routes and business logic.
|
||||
- `/admin` and `/stylist` use backend; other web pages (including authenticated customer pages) use frontend.
|
||||
- AdminOnly middleware protects Stylist operations.
|
||||
- Bundled and active themes cannot be uninstalled.
|
||||
- Keep `resources/views`: email templates, fallback and compatibility views are required.
|
||||
- New theme ZIPs must include all needed templates, layouts, assets and a valid theme.json. Missing views fall back to baseline.
|
||||
- The middleware does not change asset URLs. Replacement themes must supply their own asset references and use the existing Stylist asset serving facilities.
|
||||
|
||||
## Local validation
|
||||
|
||||
Run `php artisan optimize:clear`, `php artisan migrate`, `php artisan stylist:doctor` (if registered) and `php artisan view:cache` using your configured PHP binary. Test public pages, authentication, checkout, admin, Stylist, and transactional email before deployment.
|
||||
|
||||
This package has not been executed against your ServBay environment. Do not deploy to production without smoke testing.
|
||||
|
||||
@@ -43,10 +43,10 @@ final class TenantThemeResolver
|
||||
|
||||
$request = request();
|
||||
|
||||
return $request->routeIs('home', 'blog.public.*', 'news.public.*', 'pages.public.*')
|
||||
|| ! $request->user()
|
||||
? 'frontend'
|
||||
: 'backend';
|
||||
return $request->is('admin', 'admin/*', 'stylist', 'stylist/*')
|
||||
|| $request->routeIs('admin.*', 'stylist.*')
|
||||
? 'backend'
|
||||
: 'frontend';
|
||||
}
|
||||
|
||||
public function variables(): array
|
||||
|
||||
@@ -14,7 +14,11 @@ final class Stylist
|
||||
{
|
||||
$requested = $this->resolver->resolve($context);
|
||||
try {
|
||||
return $this->loader->find($requested);
|
||||
$theme = $this->loader->find($requested);
|
||||
if ($context !== null && $theme->type() !== $context) {
|
||||
throw ThemeNotFoundException::forKey($requested);
|
||||
}
|
||||
return $theme;
|
||||
} catch (ThemeNotFoundException) {
|
||||
$fallback = $context === 'frontend'
|
||||
? (string) config('stylist.default_frontend_theme', 'sonardesk')
|
||||
|
||||
Reference in New Issue
Block a user