* SPDX-License-Identifier: AGPL-3.0-or-later */ namespace KTXM\ProviderImap\Providers; use KTXM\ProviderImap\Client\Message; use KTXF\Mail\Entity\EntityMutableAbstract; use KTXF\Mail\Object\MessagePropertiesMutableInterface; /** * Mail Entity Resource Implementation */ class EntityResource extends EntityMutableAbstract { /** Version of the meta store / content store formats; bump on any change to either */ public const CACHE_SCHEMA_VERSION = 1; public function __construct( string $provider = 'imap', string|int|null $service = null, ) { parent::__construct($provider, $service); } /** * Convert IMAP data to a mail entity object. */ public function fromImap(Message $message, string $mailbox): static { $this->data['collection'] = $mailbox; $this->data['identifier'] = $message->uid() ?: $message->sequence(); if ($message->internalDate() !== null) { $this->data['created'] = $message->internalDate(); } $this->getProperties()->fromImap($message); return $this; } /** * Populate an entity returned by a create or replacement operation. */ public function fromMutation( string $mailbox, string|int $identifier, MessagePropertiesMutableInterface $properties, ): static { $this->data['collection'] = $mailbox; $this->data['identifier'] = $identifier; if ($properties instanceof MessageProperties) { $this->setProperties($properties); } else { $this->getProperties()->jsonDeserialize($properties->jsonSerialize()); } return $this; } // ── Cache (meta store / content store) ─────────────────────────────────── /** * Serialise to a meta store document. * * The store adds the key fields it owns (sid, tid, uidValidity). */ public function toCacheMeta(): array { return [ 'mailbox' => (string) $this->data['collection'], 'uid' => (int) $this->data['identifier'], 'created' => $this->data['created'] ?? null, 'schemaVersion' => self::CACHE_SCHEMA_VERSION, ...$this->getProperties()->toCacheMeta(), ]; } /** * Restore identity and mutable fields (flags) from a meta store document. */ public function fromCacheMeta(array $document): static { $this->data['collection'] = (string) $document['mailbox']; $this->data['identifier'] = (int) $document['uid']; $this->getProperties()->fromCacheMeta($document); return $this; } /** * Serialise the immutable message content for the content store (message.json). */ public function toCacheContent(): array { return [ 'schemaVersion' => self::CACHE_SCHEMA_VERSION, 'created' => $this->data['created'] ?? null, 'properties' => $this->getProperties()->toCacheContent(), ]; } /** * Restore the immutable message content from the content store (message.json). * * @throws \UnexpectedValueException when the content was written with a different schema version */ public function fromCacheContent(array $content): static { if (($content['schemaVersion'] ?? null) !== self::CACHE_SCHEMA_VERSION) { throw new \UnexpectedValueException('Cached message content has an unsupported schema version'); } if (isset($content['created'])) { $this->data['created'] = $content['created']; } $this->getProperties()->fromCacheContent($content['properties'] ?? []); return $this; } /** * @inheritDoc */ public function getProperties(): MessageProperties { if (!isset($this->properties)) { $this->properties = new MessageProperties([]); } return $this->properties; } }