113 lines
2.7 KiB
PHP
113 lines
2.7 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Support;
|
||
|
|
|
||
|
|
use Illuminate\Support\Facades\File;
|
||
|
|
use Illuminate\Support\Str;
|
||
|
|
|
||
|
|
class ThemeManager
|
||
|
|
{
|
||
|
|
protected string $themesPath;
|
||
|
|
|
||
|
|
public function __construct()
|
||
|
|
{
|
||
|
|
$this->themesPath = base_path('themes');
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get all available themes.
|
||
|
|
*/
|
||
|
|
public function getThemes(): array
|
||
|
|
{
|
||
|
|
if (! File::exists($this->themesPath)) {
|
||
|
|
return [];
|
||
|
|
}
|
||
|
|
|
||
|
|
$directories = File::directories($this->themesPath);
|
||
|
|
$themes = [];
|
||
|
|
|
||
|
|
foreach ($directories as $directory) {
|
||
|
|
$slug = basename($directory);
|
||
|
|
$metadata = $this->getMetadata($slug);
|
||
|
|
if ($metadata) {
|
||
|
|
$themes[$slug] = $metadata;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return $themes;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get metadata for a specific theme.
|
||
|
|
*/
|
||
|
|
public function getMetadata(string $slug): ?array
|
||
|
|
{
|
||
|
|
$path = "{$this->themesPath}/{$slug}/theme.md";
|
||
|
|
|
||
|
|
if (! File::exists($path)) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
$content = File::get($path);
|
||
|
|
return $this->parseMetadata($content, $slug);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Parse theme.md content into metadata array.
|
||
|
|
*/
|
||
|
|
protected function parseMetadata(string $content, string $slug): array
|
||
|
|
{
|
||
|
|
$metadata = [
|
||
|
|
'slug' => $slug,
|
||
|
|
'title' => Str::title($slug),
|
||
|
|
'author' => 'Unknown',
|
||
|
|
'description' => '',
|
||
|
|
'parent' => null,
|
||
|
|
];
|
||
|
|
|
||
|
|
$lines = explode("\n", $content);
|
||
|
|
foreach ($lines as $line) {
|
||
|
|
if (strpos($line, ':') !== false) {
|
||
|
|
$parts = explode(':', $line, 2);
|
||
|
|
$key = strtolower(trim($parts[0]));
|
||
|
|
$value = trim($parts[1]);
|
||
|
|
|
||
|
|
if (array_key_exists($key, $metadata)) {
|
||
|
|
$metadata[$key] = $value;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return $metadata;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the active theme slug.
|
||
|
|
*/
|
||
|
|
public function getActiveTheme(): string
|
||
|
|
{
|
||
|
|
return \App\Models\Setting::get('active_theme', config('cms.active_theme', 'icehouse'));
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the asset path for a theme, searching Child -> Parent.
|
||
|
|
*/
|
||
|
|
public function getAssetPath(string $path, string $activeTheme): ?string
|
||
|
|
{
|
||
|
|
$metadata = $this->getMetadata($activeTheme);
|
||
|
|
$paths = [$activeTheme];
|
||
|
|
|
||
|
|
if ($metadata && !empty($metadata['parent'])) {
|
||
|
|
$paths[] = $metadata['parent'];
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach ($paths as $themeSlug) {
|
||
|
|
if (File::exists("{$this->themesPath}/{$themeSlug}/{$path}")) {
|
||
|
|
return "themes/{$themeSlug}/{$path}";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
}
|