diff --git a/src/Content/ContentStorage.php b/src/Content/ContentStorage.php deleted file mode 100644 index 4ac5355479..0000000000 --- a/src/Content/ContentStorage.php +++ /dev/null @@ -1,287 +0,0 @@ - - * @author Nico Hoffmann - * @link https://getkirby.com - * @copyright Bastian Allgeier - * @license https://getkirby.com/license - */ -class ContentStorage -{ - protected ContentStorageHandler $handler; - - public function __construct( - protected ModelWithContent $model, - string $handler = PlainTextContentStorageHandler::class - ) { - $this->handler = new $handler($model); - } - - /** - * Magic caller for handler methods - */ - public function __call(string $name, array $args): mixed - { - return $this->handler->$name(...$args); - } - - /** - * Returns generator for all existing versions-languages combinations - * - * @return Generator - * @todo 4.0.0 consider more descpritive name - */ - public function all(): Generator - { - foreach ($this->model->kirby()->languages()->codes() as $lang) { - foreach ($this->dynamicVersions() as $versionId) { - if ($this->exists($versionId, $lang) === true) { - yield $versionId => $lang; - } - } - } - } - - /** - * Returns the absolute path to the content file - * @internal eventually should only exists in PlainTextContentStorage, - * when not relying anymore on language helper - * - * @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( - VersionId $versionId, - string $lang, - ): string { - $lang = $this->language($lang); - return $this->handler->contentFile($versionId, $lang); - } - - /** - * Adapts all versions when converting languages - * @internal - */ - public function convertLanguage(string $from, string $to): void - { - $from = $this->language($from, true); - $to = $this->language($to, true); - - foreach ($this->dynamicVersions() as $versionId) { - $this->handler->move($versionId, $from, $versionId, $to); - } - } - - /** - * Creates a new version - * - * @param string|null $lang Code `'default'` in a single-lang installation - * @param array $fields Content fields - */ - public function create( - VersionId $versionId, - string|null $lang, - array $fields - ): void { - $lang = $this->language($lang); - $this->handler->create($versionId, $lang, $fields); - } - - /** - * 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( - VersionId $versionId, - string|null $lang = null, - ): void { - $lang = $this->language($lang); - $this->handler->delete($versionId, $lang); - } - - /** - * Deletes all versions when deleting a language - * @internal - */ - public function deleteLanguage(string|null $lang): void - { - $lang = $this->language($lang, true); - - foreach ($this->dynamicVersions() as $version) { - $this->handler->delete($version, $lang); - } - } - - /** - * Returns all versions availalbe for the model that can be updated - * @internal - */ - public function dynamicVersions(): array - { - $versions = [VersionId::changes()]; - - if ( - $this->model instanceof Page === false || - $this->model->isDraft() === false - ) { - $versions[] = VersionId::published(); - } - - return $versions; - } - - /** - * Checks if a version exists - * - * @param string $lang Code `'default'` in a single-lang installation - */ - public function exists( - VersionId $versionId, - string $lang - ): bool { - return $this->handler->exists($versionId, $this->language($lang)); - } - - /** - * Returns the modification timestamp of a version - * if it exists - * - * @param string $lang Code `'default'` in a single-lang installation - */ - public function modified( - VersionId $versionId, - string|null $lang = null - ): int|null { - $lang = $this->language($lang); - return $this->handler->modified($versionId, $lang); - } - - /** - * Returns the stored content fields - * - * @param string $lang Code `'default'` in a single-lang installation - * @return array - * - * @throws \Kirby\Exception\NotFoundException If the version does not exist - */ - public function read( - VersionId $versionId, - string|null $lang = null - ): array { - $lang = $this->language($lang); - $this->ensureExistingVersion($versionId, $lang); - return $this->handler->read($versionId, $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( - VersionId $versionId, - string|null $lang = null - ): void { - $lang = $this->language($lang); - $this->ensureExistingVersion($versionId, $lang); - $this->handler->touch($versionId, $lang); - } - - /** - * Touches all versions of a language - * @internal - */ - public function touchLanguage(string|null $lang): void - { - $lang = $this->language($lang, true); - - foreach ($this->dynamicVersions() as $version) { - if ($this->exists($version, $lang) === true) { - $this->handler->touch($version, $lang); - } - } - } - - /** - * Updates the content fields of an existing version - * - * @param string $lang Code `'default'` in a single-lang installation - * @param array $fields Content fields - * - * @throws \Kirby\Exception\NotFoundException If the version does not exist - */ - public function update( - VersionId $versionId, - string|null $lang = null, - array $fields = [] - ): void { - $lang = $this->language($lang); - $this->ensureExistingVersion($versionId, $lang); - $this->handler->update($versionId, $lang, $fields); - } - - /** - * @throws \Kirby\Exception\NotFoundException If the version does not exist - */ - protected function ensureExistingVersion( - VersionId $versionId, - string $lang - ): void { - if ($this->exists($versionId, $lang) !== true) { - - $message = match($this->model->kirby()->multilang()) { - true => 'Version "' . $versionId . ' (' . $lang . ')" does not already exist', - false => 'Version "' . $versionId . '" does not already exist', - }; - - throw new NotFoundException($message); - } - } - - /** - * Converts a "user-facing" language code to a "raw" language code to be - * used for storage - * - * @param bool $force If set to `true`, the language code is not validated - */ - 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); - } -} diff --git a/tests/Content/ContentStorageTest.php b/tests/Content/ContentStorageTest.php deleted file mode 100644 index c6a1b9e2af..0000000000 --- a/tests/Content/ContentStorageTest.php +++ /dev/null @@ -1,207 +0,0 @@ -model = new Page([ - 'kirby' => new App(), - 'root' => static::TMP, - 'slug' => 'a-page', - 'template' => 'article' - ]); - $this->storage = new ContentStorage($this->model); - } - - public function tearDown(): void - { - App::destroy(); - Dir::remove(static::TMP); - } - - /** - * @covers ::create - */ - public function testCreateChangesMultiLang() - { - $fields = [ - 'title' => 'Foo', - 'text' => 'Bar' - ]; - - $this->assertFalse($this->storage->exists(VersionId::changes(), 'en')); - $this->storage->create(VersionId::changes(), 'en', $fields); - $this->assertTrue($this->storage->exists(VersionId::changes(), 'en')); - } - - /** - * @covers ::create - */ - public function testCreateChangesSingleLang() - { - $fields = [ - 'title' => 'Foo', - 'text' => 'Bar' - ]; - - $this->assertFalse($this->storage->exists(VersionId::changes(), 'default')); - $this->storage->create(VersionId::changes(), 'default', $fields); - $this->assertTrue($this->storage->exists(VersionId::changes(), 'default')); - } - - /** - * @covers ::read - * @covers ::ensureExistingVersion - */ - public function testReadDoesNotExist() - { - $this->expectException(NotFoundException::class); - $this->expectExceptionMessage('Version "published" does not already exist'); - - $this->storage->read(VersionId::published()); - } - - /** - * @covers ::touch - * @covers ::ensureExistingVersion - */ - public function testTouchDoesNotExist() - { - $this->expectException(NotFoundException::class); - $this->expectExceptionMessage('Version "published" does not already exist'); - - $this->storage->touch(VersionId::published()); - } - - /** - * @covers ::update - * @covers ::ensureExistingVersion - */ - public function testUpdateDoesNotExist() - { - $this->expectException(NotFoundException::class); - $this->expectExceptionMessage('Version "published" does not already exist'); - - $fields = [ - 'title' => 'Foo', - 'text' => 'Bar' - ]; - - $this->storage->update(VersionId::published(), 'default', $fields); - } - - /** - * @covers ::language - */ - public function testLanguageMultiLang() - { - $app = new App([ - 'languages' => [ - [ - 'code' => 'en', - 'default' => true - ], - [ - 'code' => 'de' - ] - ] - ]); - - $language = $this->language($this->storage, 'en'); - $this->assertSame('en', $language->code()); - - $language = $this->language($this->storage, 'de'); - $this->assertSame('de', $language->code()); - - $language = $this->language($this->storage, 'default'); - $this->assertSame('en', $language->code()); - - $language = $this->language($this->storage); - $this->assertSame('en', $language->code()); - } - - /** - * @covers ::language - */ - public function testLanguageMultiLangInvalid() - { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Invalid language: fr'); - - $app = new App([ - 'languages' => [ - [ - 'code' => 'en', - 'default' => true - ], - [ - 'code' => 'de' - ] - ] - ]); - - $this->language($this->storage, 'fr', false); - } - - /** - * @covers ::language - */ - public function testLanguageSingleLang() - { - $language = $this->language($this->storage, 'en'); - $this->assertSame('en', $language->code()); - - $language = $this->language($this->storage, 'de'); - $this->assertSame('en', $language->code()); - } - - /** - * @covers ::language - */ - public function testLanguageSingleLangInvalid() - { - $language = $this->language($this->storage, 'fr', false); - $this->assertSame('en', $language->code()); - } - - public static function languageProvider(): array - { - return [ - [null, false, ['en', 'default']], - [null, true, ['default', 'default']], - ['en', false, ['en', 'default']], - ['en', true, ['en', 'en']], - ['de', false, ['de', 'default']], - ['de', true, ['de', 'de']], - ['fr', true, ['fr', 'fr']], - ]; - } - - protected function language(ContentStorage $obj, ...$args) - { - $method = new ReflectionMethod(ContentStorage::class, 'language'); - $method->setAccessible(true); - return $method->invoke($obj, ...$args); - } -}