Decouple Site from pages

This commit is contained in:
Giuseppe Criscione 2024-10-05 12:41:35 +02:00
parent e58503d955
commit b6d6d7601d
21 changed files with 86 additions and 63 deletions

View File

@ -1,7 +1,9 @@
canonicalRoute: null
author: ''
defaultTemplate: page
description: ''
maintenance:
enabled: false
page: null

View File

@ -2,8 +2,8 @@
use Formwork\Fields\Exceptions\ValidationException;
use Formwork\Fields\Field;
use Formwork\Pages\Site;
use Formwork\Parsers\Markdown;
use Formwork\Site;
use Formwork\Utils\Constraint;
use Formwork\Utils\Str;

View File

@ -4,7 +4,7 @@ use Formwork\Fields\Exceptions\ValidationException;
use Formwork\Fields\Field;
use Formwork\Pages\Page;
use Formwork\Pages\PageCollection;
use Formwork\Pages\Site;
use Formwork\Site;
return function (Site $site) {
return [

View File

@ -1,7 +1,7 @@
<?php
use Formwork\Fields\Field;
use Formwork\Pages\Site;
use Formwork\Site;
return function (Site $site) {
return [

View File

@ -16,5 +16,5 @@ parameters:
- '#^Call to an undefined method Formwork\\Data\\CollectionDataProxy\:\:#'
- '#^Call to an undefined method Formwork\\Fields\\Field\:\:#'
- '#^Call to an undefined method Formwork\\Pages\\Page\:\:#'
- '#^Call to an undefined method Formwork\\Pages\\Site\:\:#'
- '#^Call to an undefined method Formwork\\Site\:\:#'
- '#^Call to an undefined method Formwork\\Panel\\Users\\User\:\:#'

View File

@ -13,7 +13,6 @@ use Formwork\Http\Request;
use Formwork\Http\Response;
use Formwork\Images\ImageFactory;
use Formwork\Languages\Languages;
use Formwork\Pages\Site;
use Formwork\Pages\Templates\TemplateFactory;
use Formwork\Panel\Panel;
use Formwork\Panel\Users\UserFactory;

View File

@ -10,9 +10,9 @@ use Formwork\Http\RedirectResponse;
use Formwork\Http\Response;
use Formwork\Http\ResponseStatus;
use Formwork\Pages\Page;
use Formwork\Pages\Site;
use Formwork\Router\RouteParams;
use Formwork\Router\Router;
use Formwork\Site;
use Formwork\Statistics\Statistics;
use Formwork\Utils\FileSystem;
use Formwork\View\ViewFactory;
@ -64,8 +64,8 @@ class PageController extends AbstractController
)) {
// Clear cache if the site was not modified since the page has been published or unpublished
$this->filesCache->clear();
if ($this->site->path() !== null) {
FileSystem::touch($this->site->path());
if ($this->site->contentPath() !== null) {
FileSystem::touch($this->site->contentPath());
}
}

View File

@ -4,8 +4,8 @@ namespace Formwork\Files;
use Formwork\Config\Config;
use Formwork\Files\Exceptions\FileUriGenerationException;
use Formwork\Pages\Site;
use Formwork\Router\Router;
use Formwork\Site;
use Formwork\Utils\FileSystem;
use Formwork\Utils\Str;
use RuntimeException;

View File

@ -16,6 +16,7 @@ use Formwork\Pages\Traits\PageStatus;
use Formwork\Pages\Traits\PageTraversal;
use Formwork\Pages\Traits\PageUid;
use Formwork\Pages\Traits\PageUri;
use Formwork\Site;
use Formwork\Utils\Arr;
use Formwork\Utils\FileSystem;
use Formwork\Utils\Path;
@ -493,6 +494,16 @@ class Page extends Model implements Stringable
$this->__construct($data);
}
public function contentPath(): ?string
{
return $this->path;
}
public function contentRelativePath(): ?string
{
return $this->relativePath;
}
/**
* Load files related to page
*/
@ -602,11 +613,11 @@ class Page extends Model implements Stringable
{
$this->path = FileSystem::normalizePath($path . '/');
if ($this->site()->path() === null) {
if ($this->site()->contentPath() === null) {
throw new UnexpectedValueException('Unexpected missing site path');
}
$this->relativePath = Str::prepend(Path::makeRelative($this->path, $this->site()->path(), DS), DS);
$this->relativePath = Str::prepend(Path::makeRelative($this->path, $this->site()->contentPath(), DS), DS);
$routePath = preg_replace('~[/\\\](\d+-)~', '/', $this->relativePath)
?? throw new RuntimeException(sprintf('Replacement failed with error: %s', preg_last_error_msg()));

View File

@ -4,6 +4,7 @@ namespace Formwork\Pages;
use Formwork\Data\AbstractCollection;
use Formwork\Data\Contracts\Paginable;
use Formwork\Site;
use Formwork\Utils\Str;
use RuntimeException;

View File

@ -5,7 +5,7 @@ namespace Formwork\Pages\Templates;
use Closure;
use Formwork\App;
use Formwork\Assets;
use Formwork\Pages\Site;
use Formwork\Site;
use Formwork\Utils\Constraint;
use Formwork\Utils\FileSystem;
use Formwork\View\Exceptions\RenderingException;

View File

@ -4,7 +4,7 @@ namespace Formwork\Pages\Traits;
use Formwork\Pages\Page;
use Formwork\Pages\PageCollection;
use Formwork\Pages\Site;
use Formwork\Site;
use Formwork\Utils\FileSystem;
use RuntimeException;
@ -43,7 +43,7 @@ trait PageTraversal
/**
* Get page or site path
*/
abstract public function path(): ?string;
abstract public function contentPath(): ?string;
/**
* Get page or site route
@ -66,13 +66,13 @@ trait PageTraversal
return $this->parent;
}
if ($this->path() === null) {
if ($this->contentPath() === null) {
return null;
}
$parentPath = FileSystem::joinPaths(dirname($this->path()), '/');
$parentPath = FileSystem::joinPaths(dirname($this->contentPath()), '/');
if ($parentPath === $this->site()->path()) {
if ($parentPath === $this->site()->contentPath()) {
return $this->parent = $this->site();
}
@ -104,11 +104,11 @@ trait PageTraversal
return $this->children;
}
if ($this->path() === null) {
if ($this->contentPath() === null) {
return $this->children = new PageCollection();
}
return $this->children = $this->site()->retrievePages($this->path());
return $this->children = $this->site()->retrievePages($this->contentPath());
}
/**
@ -136,11 +136,11 @@ trait PageTraversal
return $this->descendants;
}
if ($this->path() === null) {
if ($this->contentPath() === null) {
return $this->descendants = new PageCollection();
}
return $this->descendants = $this->site()->retrievePages($this->path(), recursive: true);
return $this->descendants = $this->site()->retrievePages($this->contentPath(), recursive: true);
}
/**
@ -213,7 +213,7 @@ trait PageTraversal
return $this->inclusiveSiblings;
}
if ($this->path() === null || $this->parent() === null) {
if ($this->contentPath() === null || $this->parent() === null) {
return $this->inclusiveSiblings = new PageCollection([$this->route() => $this]);
}

View File

@ -14,7 +14,7 @@ trait PageUid
/**
* Get page or site relative path
*/
abstract public function relativePath(): ?string;
abstract public function contentRelativePath(): ?string;
/**
* Get the page unique identifier
@ -25,7 +25,7 @@ trait PageUid
return $this->uid;
}
$id = $this->relativePath() ?: spl_object_hash($this);
$id = $this->contentRelativePath() ?: spl_object_hash($this);
return $this->uid = Str::chunk(substr(hash('sha256', (string) $id), 0, 32), 8, '-');
}

View File

@ -3,7 +3,7 @@
namespace Formwork\Pages\Traits;
use Formwork\App;
use Formwork\Pages\Site;
use Formwork\Site;
use Formwork\Utils\Path;
use Formwork\Utils\Uri;

View File

@ -8,7 +8,6 @@ use Formwork\Controllers\AbstractController as BaseAbstractController;
use Formwork\Http\RedirectResponse;
use Formwork\Http\Request;
use Formwork\Http\ResponseStatus;
use Formwork\Pages\Site;
use Formwork\Panel\Modals\Modal;
use Formwork\Panel\Modals\ModalCollection;
use Formwork\Panel\Modals\ModalFactory;
@ -18,6 +17,7 @@ use Formwork\Parsers\Json;
use Formwork\Router\Router;
use Formwork\Security\CsrfToken;
use Formwork\Services\Container;
use Formwork\Site;
use Formwork\Translations\Translations;
use Formwork\Utils\Date;
use Formwork\Utils\Uri;

View File

@ -50,10 +50,10 @@ class OptionsController extends AbstractController
// Touch content folder to invalidate cache
if ($differ) {
if ($this->site()->path() === null) {
if ($this->site()->contentPath() === null) {
throw new UnexpectedValueException('Unexpected missing site path');
}
FileSystem::touch($this->site()->path());
FileSystem::touch($this->site()->contentPath());
}
$this->panel()->notify($this->translate('panel.options.updated'), 'success');
@ -93,10 +93,10 @@ class OptionsController extends AbstractController
// Touch content folder to invalidate cache
if ($differ) {
if ($this->site()->path() === null) {
if ($this->site()->contentPath() === null) {
throw new UnexpectedValueException('Unexpected missing site path');
}
FileSystem::touch($this->site()->path());
FileSystem::touch($this->site()->contentPath());
}
$this->panel()->notify($this->translate('panel.options.updated'), 'success');

View File

@ -15,12 +15,12 @@ use Formwork\Http\RequestMethod;
use Formwork\Http\Response;
use Formwork\Images\Image;
use Formwork\Pages\Page;
use Formwork\Pages\Site;
use Formwork\Panel\ContentHistory\ContentHistory;
use Formwork\Panel\ContentHistory\ContentHistoryEvent;
use Formwork\Parsers\Yaml;
use Formwork\Router\RouteParams;
use Formwork\Schemes\Schemes;
use Formwork\Site;
use Formwork\Utils\Arr;
use Formwork\Utils\Constraint;
use Formwork\Utils\Date;
@ -655,12 +655,12 @@ class PagesController extends AbstractController
throw new UnexpectedValueException('Unexpected missing page path');
}
if ($this->site()->path() === null) {
if ($this->site()->contentPath() === null) {
throw new UnexpectedValueException('Unexpected missing site path');
}
FileSystem::write($page->path() . $filename, $fileContent);
FileSystem::touch($this->site()->path());
FileSystem::touch($this->site()->contentPath());
$contentHistory = new ContentHistory($page->path());

View File

@ -4,11 +4,10 @@ namespace Formwork\Services\Loaders;
use Formwork\Config\Config;
use Formwork\Languages\Languages;
use Formwork\Pages\Site;
use Formwork\Parsers\Yaml;
use Formwork\Schemes\Schemes;
use Formwork\Services\Container;
use Formwork\Services\ResolutionAwareServiceLoaderInterface;
use Formwork\Site;
class SiteServiceLoader implements ResolutionAwareServiceLoaderInterface
{
@ -19,12 +18,13 @@ class SiteServiceLoader implements ResolutionAwareServiceLoaderInterface
public function load(Container $container): Site
{
$this->schemes->loadFromPath($this->config->get('system.schemes.paths.site'));
$config = Yaml::parseFile(ROOT_PATH . '/site/config/site.yaml');
$config = $this->config->get('site');
return $container->build(Site::class, ['data' => [
'path' => $this->config->get('system.pages.path'),
'languages' => $this->languages,
] + $config]);
...$config,
'contentPath' => $this->config->get('system.pages.path'),
'languages' => $this->languages,
]]);
}
/**

View File

@ -1,19 +1,20 @@
<?php
namespace Formwork\Pages;
namespace Formwork;
use Formwork\App;
use Formwork\Config\Config;
use Formwork\Languages\Languages;
use Formwork\Metadata\MetadataCollection;
use Formwork\Model\Model;
use Formwork\Pages\ContentFile;
use Formwork\Pages\Exceptions\PageNotFoundException;
use Formwork\Pages\Page;
use Formwork\Pages\PageCollection;
use Formwork\Pages\Templates\TemplateCollection;
use Formwork\Pages\Templates\TemplateFactory;
use Formwork\Pages\Traits\PageTraversal;
use Formwork\Pages\Traits\PageUid;
use Formwork\Pages\Traits\PageUri;
use Formwork\Parsers\Yaml;
use Formwork\Schemes\Schemes;
use Formwork\Utils\Arr;
use Formwork\Utils\FileSystem;
@ -32,10 +33,7 @@ class Site extends Model implements Stringable
*/
protected ?string $path = null;
/**
* Site relative path
*/
protected ?string $relativePath = null;
protected ?string $contentPath = null;
/**
* Site content file
@ -122,7 +120,7 @@ class Site extends Model implements Stringable
*/
public function defaults(): array
{
$defaults = Yaml::parseFile(SYSTEM_PATH . '/config/site.yaml');
$defaults = $this->config->getDefaults('site');
return [...$defaults, ...Arr::reject($this->fields()->pluck('default'), fn ($value) => $value === null)];
}
@ -150,14 +148,6 @@ class Site extends Model implements Stringable
return $this->path;
}
/**
* Get site relative path
*/
public function relativePath(): ?string
{
return $this->relativePath;
}
/**
* Get site filename
*/
@ -166,6 +156,16 @@ class Site extends Model implements Stringable
return $this->contentFile;
}
public function contentPath(): ?string
{
return $this->contentPath;
}
public function contentRelativePath(): ?string
{
return '/';
}
/**
* Get site route
*/
@ -254,10 +254,10 @@ class Site extends Model implements Stringable
*/
public function modifiedSince(int $time): bool
{
if ($this->path === null) {
if ($this->contentPath === null) {
return false;
}
return FileSystem::directoryModifiedSince($this->path, $time);
return FileSystem::directoryModifiedSince($this->contentPath, $time);
}
/**
@ -322,7 +322,7 @@ class Site extends Model implements Stringable
}
$components = explode('/', trim($route, '/'));
$path = $this->path;
$path = $this->contentPath;
if ($path === null) {
return null;
@ -432,6 +432,14 @@ class Site extends Model implements Stringable
$this->fields->setValues($this->data);
}
/**
* @param array<string, mixed> $metadata
*/
protected function setMetadata(array $metadata): void
{
$this->data['metadata'] = $metadata;
}
protected function loadTemplates(): void
{
$path = $this->config->get('system.templates.path');
@ -460,9 +468,12 @@ class Site extends Model implements Stringable
protected function setPath(string $path): void
{
$this->path = FileSystem::normalizePath($path . '/');
$this->path = $this->data['path'] = FileSystem::normalizePath($path . '/');
}
$this->relativePath = DS;
protected function setContentPath(string $path): void
{
$this->contentPath = FileSystem::normalizePath($path . '/');
$this->route = '/';

View File

@ -4,9 +4,9 @@ use Formwork\Http\JsonResponse;
use Formwork\Http\RedirectResponse;
use Formwork\Http\Request;
use Formwork\Http\ResponseStatus;
use Formwork\Pages\Site;
use Formwork\Panel\Panel;
use Formwork\Security\CsrfToken;
use Formwork\Site;
use Formwork\Translations\Translations;
use Formwork\Utils\FileSystem;

View File

@ -1,2 +1 @@
title: Formwork
description: ''