84 lines
2.7 KiB
PHP
84 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace Modules\Content\Services;
|
|
|
|
use Illuminate\Support\Facades\Route;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Illuminate\Support\Facades\View;
|
|
use Modules\Content\Models\ContentDocument;
|
|
use Modules\Content\Models\PageContent;
|
|
use Throwable;
|
|
|
|
final class PageRenderer
|
|
{
|
|
public function hasComposition(string $pageKey): bool
|
|
{
|
|
try {
|
|
return Schema::hasTable('page_content')
|
|
&& PageContent::query()->where('page_key', $pageKey)->where('is_enabled', true)->exists();
|
|
} catch (Throwable) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public function renderRegion(string $pageKey, string $region): string
|
|
{
|
|
if (! $this->hasComposition($pageKey)) {
|
|
return '';
|
|
}
|
|
|
|
$preview = Route::currentRouteNamed('content.pages.preview');
|
|
$placements = PageContent::query()
|
|
->with('document.type')
|
|
->where('page_key', $pageKey)
|
|
->where('region', $region)
|
|
->where('is_enabled', true)
|
|
->where(fn ($query) => $query->whereNull('starts_at')->orWhere('starts_at', '<=', now()))
|
|
->where(fn ($query) => $query->whereNull('ends_at')->orWhere('ends_at', '>', now()))
|
|
->orderBy('sort_order')
|
|
->get();
|
|
|
|
return $placements->map(function (PageContent $placement) use ($preview): string {
|
|
$document = $placement->document;
|
|
if (! $document || ! $document->type || ! $this->isRenderable($document, $preview)) {
|
|
return '';
|
|
}
|
|
|
|
$view = 'stylist-theme-saasland::documents.'.$document->type->renderer;
|
|
if (! View::exists($view)) {
|
|
$view = 'content::documents.unsupported';
|
|
}
|
|
|
|
$rendered = View::make($view, [
|
|
'document' => $document,
|
|
'data' => $document->data ?? [],
|
|
'placement' => $placement,
|
|
'isCompositionPreview' => $preview,
|
|
])->render();
|
|
|
|
if ($preview && $document->status !== 'published') {
|
|
return '<div style="position:relative"><div style="position:absolute;z-index:1000;top:8px;right:8px;padding:5px 9px;border-radius:999px;background:#f59e0b;color:#111827;font:600 12px/1 sans-serif">Draft preview</div>'.$rendered.'</div>';
|
|
}
|
|
|
|
return $rendered;
|
|
})->implode("\n");
|
|
}
|
|
|
|
private function isRenderable(ContentDocument $document, bool $preview): bool
|
|
{
|
|
if ($preview) {
|
|
return true;
|
|
}
|
|
|
|
if ($document->status !== 'published') {
|
|
return false;
|
|
}
|
|
|
|
if ($document->published_at?->isFuture()) {
|
|
return false;
|
|
}
|
|
|
|
return ! $document->expires_at?->isPast();
|
|
}
|
|
}
|