Update to Kirby 4.7.0
This commit is contained in:
parent
02a9ab387c
commit
ba25a9a198
509 changed files with 26604 additions and 14872 deletions
253
kirby/src/Content/PlainTextContentStorageHandler.php
Normal file
253
kirby/src/Content/PlainTextContentStorageHandler.php
Normal file
|
@ -0,0 +1,253 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Content;
|
||||
|
||||
use Kirby\Cms\ModelWithContent;
|
||||
use Kirby\Data\Data;
|
||||
use Kirby\Exception\Exception;
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
use Kirby\Exception\LogicException;
|
||||
use Kirby\Filesystem\Dir;
|
||||
use Kirby\Filesystem\F;
|
||||
|
||||
/**
|
||||
* Content storage handler using plain text files
|
||||
* stored in the content folder
|
||||
* @internal
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @package Kirby Content
|
||||
* @author Lukas Bestle <lukas@getkirby.com>
|
||||
* @link https://getkirby.com
|
||||
* @copyright Bastian Allgeier
|
||||
* @license https://getkirby.com/license
|
||||
*/
|
||||
class PlainTextContentStorageHandler implements ContentStorageHandler
|
||||
{
|
||||
public function __construct(protected ModelWithContent $model)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new version
|
||||
*
|
||||
* @param string $lang Code `'default'` in a single-lang installation
|
||||
* @param array<string, string> $fields Content fields
|
||||
*/
|
||||
public function create(string $versionType, string $lang, array $fields): void
|
||||
{
|
||||
$success = Data::write($this->contentFile($versionType, $lang), $fields);
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
if ($success !== true) {
|
||||
throw new Exception('Could not write new content file');
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an existing version in an idempotent way if it was already deleted
|
||||
*
|
||||
* @param string $lang Code `'default'` in a single-lang installation
|
||||
*/
|
||||
public function delete(string $version, string $lang): void
|
||||
{
|
||||
$contentFile = $this->contentFile($version, $lang);
|
||||
$success = F::unlink($contentFile);
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
if ($success !== true) {
|
||||
throw new Exception('Could not delete content file');
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
// clean up empty directories
|
||||
$contentDir = dirname($contentFile);
|
||||
if (
|
||||
Dir::exists($contentDir) === true &&
|
||||
Dir::isEmpty($contentDir) === true
|
||||
) {
|
||||
$success = rmdir($contentDir);
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
if ($success !== true) {
|
||||
throw new Exception('Could not delete empty content directory');
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a version exists
|
||||
*
|
||||
* @param string|null $lang Code `'default'` in a single-lang installation;
|
||||
* checks for "any language" if not provided
|
||||
*/
|
||||
public function exists(string $version, string|null $lang): bool
|
||||
{
|
||||
if ($lang === null) {
|
||||
foreach ($this->contentFiles($version) as $file) {
|
||||
if (is_file($file) === true) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return is_file($this->contentFile($version, $lang)) === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the modification timestamp of a version
|
||||
* if it exists
|
||||
*
|
||||
* @param string $lang Code `'default'` in a single-lang installation
|
||||
*/
|
||||
public function modified(string $version, string $lang): int|null
|
||||
{
|
||||
$modified = F::modified($this->contentFile($version, $lang));
|
||||
|
||||
if (is_int($modified) === true) {
|
||||
return $modified;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stored content fields
|
||||
*
|
||||
* @param string $lang Code `'default'` in a single-lang installation
|
||||
* @return array<string, string>
|
||||
*
|
||||
* @throws \Kirby\Exception\NotFoundException If the version does not exist
|
||||
*/
|
||||
public function read(string $version, string $lang): array
|
||||
{
|
||||
return Data::read($this->contentFile($version, $lang));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the modification timestamp of an existing version
|
||||
*
|
||||
* @param string $lang Code `'default'` in a single-lang installation
|
||||
*
|
||||
* @throws \Kirby\Exception\NotFoundException If the version does not exist
|
||||
*/
|
||||
public function touch(string $version, string $lang): void
|
||||
{
|
||||
$success = touch($this->contentFile($version, $lang));
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
if ($success !== true) {
|
||||
throw new Exception('Could not touch existing content file');
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the content fields of an existing version
|
||||
*
|
||||
* @param string $lang Code `'default'` in a single-lang installation
|
||||
* @param array<string, string> $fields Content fields
|
||||
*
|
||||
* @throws \Kirby\Exception\NotFoundException If the version does not exist
|
||||
*/
|
||||
public function update(string $version, string $lang, array $fields): void
|
||||
{
|
||||
$success = Data::write($this->contentFile($version, $lang), $fields);
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
if ($success !== true) {
|
||||
throw new Exception('Could not write existing content file');
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute path to the content file
|
||||
* @internal To be made `protected` when the CMS core no longer relies on it
|
||||
*
|
||||
* @param string $lang Code `'default'` in a single-lang installation
|
||||
*
|
||||
* @throws \Kirby\Exception\LogicException If the model type doesn't have a known content filename
|
||||
*/
|
||||
public function contentFile(string $version, string $lang): string
|
||||
{
|
||||
if (in_array($version, ['published', 'changes']) !== true) {
|
||||
throw new InvalidArgumentException('Invalid version identifier "' . $version . '"');
|
||||
}
|
||||
|
||||
$extension = $this->model->kirby()->contentExtension();
|
||||
$directory = $this->model->root();
|
||||
|
||||
$directory = match ($this->model::CLASS_ALIAS) {
|
||||
'file' => dirname($this->model->root()),
|
||||
default => $this->model->root()
|
||||
};
|
||||
|
||||
$filename = match ($this->model::CLASS_ALIAS) {
|
||||
'file' => $this->model->filename(),
|
||||
'page' => $this->model->intendedTemplate()->name(),
|
||||
'site',
|
||||
'user' => $this->model::CLASS_ALIAS,
|
||||
// @codeCoverageIgnoreStart
|
||||
default => throw new LogicException('Cannot determine content filename for model type "' . $this->model::CLASS_ALIAS . '"')
|
||||
// @codeCoverageIgnoreEnd
|
||||
};
|
||||
|
||||
if ($this->model::CLASS_ALIAS === 'page' && $this->model->isDraft() === true) {
|
||||
// changes versions don't need anything extra
|
||||
// (drafts already have the `_drafts` prefix in their root),
|
||||
// but a published version is not possible
|
||||
if ($version === 'published') {
|
||||
throw new LogicException('Drafts cannot have a published content file');
|
||||
}
|
||||
} elseif ($version === 'changes') {
|
||||
// other model type or published page that has a changes subfolder
|
||||
$directory .= '/_changes';
|
||||
}
|
||||
|
||||
if ($lang !== 'default') {
|
||||
return $directory . '/' . $filename . '.' . $lang . '.' . $extension;
|
||||
}
|
||||
|
||||
return $directory . '/' . $filename . '.' . $extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array with content files of all languages
|
||||
* @internal To be made `protected` when the CMS core no longer relies on it
|
||||
*/
|
||||
public function contentFiles(string $version): array
|
||||
{
|
||||
if ($this->model->kirby()->multilang() === true) {
|
||||
return $this->model->kirby()->languages()->values(
|
||||
fn ($lang) => $this->contentFile($version, $lang)
|
||||
);
|
||||
}
|
||||
|
||||
return [
|
||||
$this->contentFile($version, 'default')
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves content from one version-language combination to another
|
||||
*
|
||||
* @param string $fromLang Code `'default'` in a single-lang installation
|
||||
* @param string $toLang Code `'default'` in a single-lang installation
|
||||
*/
|
||||
public function move(
|
||||
string $fromVersion,
|
||||
string $fromLang,
|
||||
string $toVersion,
|
||||
string $toLang
|
||||
): void {
|
||||
F::move(
|
||||
$this->contentFile($fromVersion, $fromLang),
|
||||
$this->contentFile($toVersion, $toLang)
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue