From 9bbf0670e191761703e34017ebb50e8fd4b71e30 Mon Sep 17 00:00:00 2001 From: Bastian Allgeier Date: Wed, 22 May 2024 12:37:56 +0200 Subject: [PATCH] First draft for a new MemoryContentStorageHandler --- src/Content/MemoryContentStorageHandler.php | 130 ++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 src/Content/MemoryContentStorageHandler.php diff --git a/src/Content/MemoryContentStorageHandler.php b/src/Content/MemoryContentStorageHandler.php new file mode 100644 index 0000000000..5cab9333a3 --- /dev/null +++ b/src/Content/MemoryContentStorageHandler.php @@ -0,0 +1,130 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://getkirby.com/license + */ +class MemoryContentStorageHandler extends ContentStorageHandler +{ + /** + * Cache instance, used to store content in memory + */ + protected MemoryCache $cache; + + /** + * Sets up the cache instance + */ + public function __construct(protected ModelWithContent $model) + { + parent::__construct($model); + $this->cache = new MemoryCache(); + } + + /** + * Returns a unique id for a combination + * of the version id, the language code and the model id + */ + protected function cacheId(VersionId $versionId, Language $language): string + { + return $versionId->value() . '/' . $language->code() . '/' . $this->model->id(); + } + + /** + * Deletes an existing version in an idempotent way if it was already deleted + */ + public function delete(VersionId $versionId, Language $language): void + { + $this->cache->remove($this->cacheId($versionId, $language)); + } + + /** + * Checks if a version exists + */ + public function exists(VersionId $versionId, Language $language): bool + { + $data = $this->cache->get($this->cacheId($versionId, $language)); + + // validate the cached data + if ( + isset($data['fields']) === true && + is_array($data['fields']) === true && + isset($data['modified']) === true && + is_int($data['modified']) === true + ) { + return true; + } + + return false; + } + + /** + * Returns the modification timestamp of a version if it exists + */ + public function modified(VersionId $versionId, Language $language): int|null + { + if ($this->exists($versionId, $language) === false) { + return null; + } + + return $this->cache->get($this->cacheId($versionId, $language))['modified']; + } + + /** + * Returns the stored content fields + * + * @return array + * + * @throws \Kirby\Exception\NotFoundException If the version does not exist + */ + public function read(VersionId $versionId, Language $language): array + { + $this->ensure($versionId, $language); + return $this->cache->get($this->cacheId($versionId, $language))['fields']; + } + + /** + * Updates the modification timestamp of an existing version + * + * @throws \Kirby\Exception\NotFoundException If the version does not exist + */ + public function touch(VersionId $versionId, Language $language): void + { + $fields = $this->read($versionId, $language); + $this->write($versionId, $language, $fields); + } + + /** + * Updates the content fields of an existing version + * + * @param array $fields Content fields + * + * @throws \Kirby\Exception\NotFoundException If the version does not exist + */ + public function update(VersionId $versionId, Language $language, array $fields): void + { + $this->ensure($versionId, $language); + $this->write($versionId, $language, $fields); + } + + /** + * Writes the content fields of an existing version + * + * @param array $fields Content fields + */ + protected function write(VersionId $versionId, Language $language, array $fields): void + { + $this->cache->set($this->cacheId($versionId, $language), [ + 'fields' => $fields, + 'modified' => time() + ]); + } +}