New Branch Structure
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Stylist\Diagnostics;
|
||||
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Modules\Stylist\Theme\Loader;
|
||||
use Modules\Stylist\Theme\Theme;
|
||||
|
||||
final class ThemeInspector
|
||||
{
|
||||
public function __construct(
|
||||
private readonly Filesystem $files,
|
||||
private readonly Loader $loader,
|
||||
) {}
|
||||
|
||||
/** @return array<int, array<string, mixed>> */
|
||||
public function themes(): array
|
||||
{
|
||||
return $this->loader->all()->map(function (Theme $theme): array {
|
||||
return [
|
||||
'key' => $theme->key(),
|
||||
'name' => $theme->name(),
|
||||
'parent' => $theme->parent(),
|
||||
'path' => $theme->path(),
|
||||
'views' => count($this->viewFiles($theme)),
|
||||
'entry_view' => $theme->entryView(),
|
||||
];
|
||||
})->values()->all();
|
||||
}
|
||||
|
||||
/** @return array<string, array<int, array{theme:string,path:string}>> */
|
||||
public function duplicateViews(): array
|
||||
{
|
||||
$ownership = [];
|
||||
|
||||
foreach ($this->loader->all() as $theme) {
|
||||
foreach ($this->viewFiles($theme) as $relative => $absolute) {
|
||||
$ownership[$relative][] = [
|
||||
'theme' => $theme->key(),
|
||||
'path' => $absolute,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return array_filter($ownership, fn (array $owners): bool => count($owners) > 1);
|
||||
}
|
||||
|
||||
/** @return array<int, array{severity:string,theme:string,message:string}> */
|
||||
public function issues(): array
|
||||
{
|
||||
$issues = [];
|
||||
$themes = $this->loader->all();
|
||||
|
||||
foreach ($themes as $theme) {
|
||||
$parent = $theme->parent();
|
||||
|
||||
if ($parent !== null && ! $themes->has($parent)) {
|
||||
$issues[] = [
|
||||
'severity' => 'error',
|
||||
'theme' => $theme->key(),
|
||||
'message' => "Parent theme [{$parent}] is not installed.",
|
||||
];
|
||||
}
|
||||
|
||||
if ($this->hasInheritanceCycle($theme, $themes->all())) {
|
||||
$issues[] = [
|
||||
'severity' => 'error',
|
||||
'theme' => $theme->key(),
|
||||
'message' => 'Theme inheritance contains a cycle.',
|
||||
];
|
||||
}
|
||||
|
||||
$entry = $theme->path().'/views/'.str_replace('.', '/', $theme->entryView()).'.blade.php';
|
||||
if (! $this->files->exists($entry) && $parent === null) {
|
||||
$issues[] = [
|
||||
'severity' => 'warning',
|
||||
'theme' => $theme->key(),
|
||||
'message' => "Entry view [{$theme->entryView()}] does not exist in this theme.",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->duplicateViews() as $view => $owners) {
|
||||
$issues[] = [
|
||||
'severity' => 'error',
|
||||
'theme' => implode(', ', array_column($owners, 'theme')),
|
||||
'message' => "View [{$view}] has multiple owners.",
|
||||
];
|
||||
}
|
||||
|
||||
$default = (string) config('stylist.default_theme');
|
||||
if ($default !== '' && ! $themes->has($default)) {
|
||||
$issues[] = [
|
||||
'severity' => 'warning',
|
||||
'theme' => $default,
|
||||
'message' => 'Configured default theme is not installed.',
|
||||
];
|
||||
}
|
||||
|
||||
return $issues;
|
||||
}
|
||||
|
||||
/** @return array<string, string> */
|
||||
private function viewFiles(Theme $theme): array
|
||||
{
|
||||
$root = $theme->path().'/views';
|
||||
if (! $this->files->isDirectory($root)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$views = [];
|
||||
foreach ($this->files->allFiles($root) as $file) {
|
||||
if (! str_ends_with($file->getFilename(), '.blade.php')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$absolute = str_replace('\\', '/', $file->getPathname());
|
||||
$relative = ltrim(str_replace(str_replace('\\', '/', $root), '', $absolute), '/');
|
||||
$views[$relative] = $absolute;
|
||||
}
|
||||
|
||||
ksort($views);
|
||||
return $views;
|
||||
}
|
||||
|
||||
/** @param array<string, Theme> $themes */
|
||||
private function hasInheritanceCycle(Theme $theme, array $themes): bool
|
||||
{
|
||||
$seen = [];
|
||||
$key = $theme->key();
|
||||
|
||||
while (isset($themes[$key])) {
|
||||
if (isset($seen[$key])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$seen[$key] = true;
|
||||
$key = $themes[$key]->parent() ?? '';
|
||||
if ($key === '') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user