Skip to content

Commit

Permalink
Version class improvements and more unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
bastianallgeier committed May 17, 2024
1 parent 9e4c051 commit e36af98
Show file tree
Hide file tree
Showing 2 changed files with 454 additions and 50 deletions.
126 changes: 89 additions & 37 deletions src/Content/Version.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace Kirby\Content;

use Kirby\Cms\Language;
use Kirby\Cms\ModelWithContent;
use Kirby\Exception\InvalidArgumentException;
use Kirby\Exception\NotFoundException;

/**
Expand Down Expand Up @@ -33,39 +35,50 @@ public function content(string $language = 'default'): Content
{
return new Content(
parent: $this->model,
data: $this->model->storage()->read($this->id, $language),
data: $this->model->storage()->read($this->id, $this->language($language)),
);
}

/**
* Creates a new version for the given language
*
* @param array<string, string> $fields Content fields
*/
public function create(array $fields, string $language = 'default'): void
{
$this->model->storage()->create($this->id, $language, $fields);
$this->model->storage()->create($this->id, $this->language($language), $fields);
}

/**
* Deletes a version by language or for any language
*
* @param string|null $language If null, all available languages will be deleted
*/
public function delete(string|null $language = null): void
{
// delete all languages
if ($language === null) {
foreach ($this->model->kirby()->languages() as $language) {
$this->model->storage()->delete($this->id, $language->code());
}
// delete a single language
if ($this->model->kirby()->multilang() === false) {
$this->deleteLanguage('default');
}

// delete the default language in single-language mode
if ($this->model->kirby()->multilang() === false) {
$this->model->storage()->delete($this->id, 'default');
// delete a specific language
if ($language !== null) {
$this->deleteLanguage($language);
return;
}

// delete a single language
$this->model->storage()->delete($this->id, $language);
// delete all languages
foreach ($this->model->kirby()->languages() as $language) {
$this->deleteLanguage($language);
}
}

/**
* Deletes a version by a specific language
*/
public function deleteLanguage(string $language = 'default'): void
{
$this->model->storage()->delete($this->id, $this->language($language));
}

/**
Expand All @@ -76,18 +89,25 @@ public function delete(string|null $language = null): void
*/
public function ensure(
string $language = 'default'
): void {
): bool {
if ($this->exists($language) !== true) {
throw new NotFoundException('Version "' . $this->id . ' (' . $language . ')" does not already exist');
$message = match($this->model->kirby()->multilang()) {
true => 'Version "' . $this->id . ' (' . $language . ')" does not already exist',
false => 'Version "' . $this->id . '" does not already exist',
};

throw new NotFoundException($message);
}

return true;
}

/**
* Checks if a version exists for the given language
*/
public function exists(string $language = 'default'): bool
{
return $this->model->storage()->exists($this->id, $language);
return $this->model->storage()->exists($this->id, $this->language($language));
}

/**
Expand All @@ -98,6 +118,27 @@ public function id(): VersionId
return $this->id;
}

/**
* Converts a "user-facing" language code to a `Language` object
* to be used in storage methods
*/
protected function language(
string|null $languageCode = null,
): Language {
// single language
if ($this->model->kirby()->multilang() === false) {
return Language::single();
}

// look up the actual language object if possible
if ($language = $this->model->kirby()->language($languageCode)) {
return $language;
}

// validate the language code
throw new InvalidArgumentException('Invalid language: ' . $languageCode);
}

/**
* Returns the parent model
*/
Expand All @@ -109,14 +150,12 @@ public function model(): ModelWithContent
/**
* Returns the modification timestamp of a version
* if it exists
*
* @param string $lang Code `'default'` in a single-lang installation
*/
public function modified(
string $language = 'default'
): int|null {
$this->ensure($language);
return $this->model->storage()->modified($this->id, $language);
return $this->model->storage()->modified($this->id, $this->language($language));
}

/**
Expand All @@ -125,61 +164,74 @@ public function modified(
public function move(string $fromLanguage, VersionId $toVersionId, string $toLanguage): void
{
$this->ensure($fromLanguage);
$this->model->storage()->move($this->id, $fromLanguage, $toVersionId, $toLanguage);
$this->model->storage()->move(
fromVersionId: $this->id,
fromLanguage: $this->language($fromLanguage),
toVersionId: $toVersionId,
toLanguage: $this->language($toLanguage)
);
}

/**
* Returns the stored content fields
*
* @param string $lang Code `'default'` in a single-lang installation
* @return array<string, string>
*/
public function read(string $language = 'default'): array
{
$this->ensure($language);
return $this->model->storage()->read($this->id, $language);
return $this->model->storage()->read($this->id, $this->language($language));
}

/**
* Updates the modification timestamp of an existing version
*
* @param string $lang Code `'default'` in a single-lang installation
* @param string|null $language If null, all available languages will be touched
*
* @throws \Kirby\Exception\NotFoundException If the version does not exist
*/
public function touch(string|null $language = null): void
{
// touch all languages
if ($language === null) {
foreach ($this->model->kirby()->languages() as $language) {
$this->touch($language->code());
}
// touch a single language
if ($this->model->kirby()->multilang() === false) {
$this->touchLanguage('default');
return;
}

// make sure the version exists
$this->ensure($language);

// touch the default language in single-language mode
if ($this->model->kirby()->multilang() === false) {
$this->model->storage()->touch($this->id, 'default');
// touch a specific language
if ($language !== null) {
$this->touchLanguage($language);
return;
}

// touch a single language
$this->model->storage()->touch($this->id, $language);
// touch all languages
foreach ($this->model->kirby()->languages() as $language) {
$this->touchLanguage($language);
}
}

/**
* Updates the modification timestamp of a specific language
*
* @throws \Kirby\Exception\NotFoundException If the version does not exist
*/
public function touchLanguage(string $language = 'default'): void
{
// make sure the version exists
$this->ensure($language);
$this->model->storage()->touch($this->id, $this->language($language));
}

/**
* Updates the content fields of an existing version
*
* @param array<string, string> $fields Content fields
* @param string $lang Code `'default'` in a single-lang installation
*
* @throws \Kirby\Exception\NotFoundException If the version does not exist
*/
public function update(array $fields, string $language = 'default'): void
{
$this->ensure($language);
$this->model->storage()->update($this->id, $language, $fields);
$this->model->storage()->update($this->id, $this->language($language), $fields);
}
}
Loading

0 comments on commit e36af98

Please sign in to comment.