Files

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();
}
}