108 lines
3.3 KiB
PHP
108 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace Modules\Stylist\Theme;
|
|
|
|
use Modules\Stylist\Services\TenantThemeResolver;
|
|
use Modules\Stylist\Services\ThemeSettings;
|
|
use Modules\Stylist\Theme\Exceptions\ThemeNotFoundException;
|
|
|
|
final class Stylist
|
|
{
|
|
public function __construct(private readonly Loader $loader, private readonly TenantThemeResolver $resolver, private readonly ThemeSettings $settings) {}
|
|
|
|
public function current(?string $context = null): Theme
|
|
{
|
|
$requested = $this->resolver->resolve($context);
|
|
try {
|
|
$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')
|
|
: (string) config('stylist.default_backend_theme', config('stylist.default_theme', 'sonardesk-admin'));
|
|
if ($requested !== $fallback) {
|
|
return $this->loader->find($fallback);
|
|
}
|
|
throw ThemeNotFoundException::forKey($requested);
|
|
}
|
|
}
|
|
|
|
public function frontend(): Theme
|
|
{
|
|
return $this->current('frontend');
|
|
}
|
|
|
|
public function backend(): Theme
|
|
{
|
|
return $this->current('backend');
|
|
}
|
|
|
|
public function variables(): array
|
|
{
|
|
$theme = $this->current();
|
|
$variant = $this->settings->variant($theme);
|
|
$variantVars = (array) data_get($theme->variants(), $variant.'.variables', []);
|
|
$appearanceVars = (array) data_get($theme->appearances(), $this->appearance().'.variables', []);
|
|
$accentVars = (array) data_get($theme->accents(), $this->accent().'.variables', []);
|
|
$settingVars = collect($this->settings->get($theme))
|
|
->filter(fn ($value, $key) => is_string($key) && str_starts_with($key, '--'))
|
|
->mapWithKeys(fn ($value, $key) => [ltrim($key, '-') => $value])
|
|
->all();
|
|
|
|
return array_replace(
|
|
(array) config('stylist.fallback_variables', []),
|
|
$this->inheritedVariables($theme),
|
|
$variantVars,
|
|
$appearanceVars,
|
|
$accentVars,
|
|
$settingVars,
|
|
$this->resolver->variables(),
|
|
);
|
|
}
|
|
|
|
public function settings(): array
|
|
{
|
|
return $this->settings->get($this->current());
|
|
}
|
|
|
|
public function variant(): string
|
|
{
|
|
return $this->settings->variant($this->current());
|
|
}
|
|
|
|
public function appearance(): string
|
|
{
|
|
return $this->settings->appearance($this->current());
|
|
}
|
|
|
|
public function accent(): string
|
|
{
|
|
return $this->settings->accent($this->current());
|
|
}
|
|
|
|
public function all()
|
|
{
|
|
return $this->loader->all();
|
|
}
|
|
|
|
private function inheritedVariables(Theme $theme, array $seen = []): array
|
|
{
|
|
if (in_array($theme->key(), $seen, true)) {
|
|
return [];
|
|
}
|
|
$seen[] = $theme->key();
|
|
$parent = [];
|
|
if ($theme->parent()) {
|
|
try {
|
|
$parent = $this->inheritedVariables($this->loader->find($theme->parent()), $seen);
|
|
} catch (ThemeNotFoundException) {
|
|
}
|
|
}
|
|
|
|
return array_replace($parent, $theme->variables());
|
|
}
|
|
}
|