* SPDX-License-Identifier: AGPL-3.0-or-later */ namespace KTXM\ProviderImapMail\Providers; use Gricob\IMAP\Mailbox; use KTXF\Mail\Collection\CollectionPropertiesMutableAbstract; use KTXF\Mail\Collection\CollectionRoles; /** * IMAP Mail Collection Properties * * Backed by the same internal $data shape as the JMAP provider so that cache * documents are interchangeable with fromStore() / toStore(). */ class CollectionProperties extends CollectionPropertiesMutableAbstract { // ── IMAP hydration ─────────────────────────────────────────────────────── /** * Populate from a gricob Mailbox object. * * Total / unread counts are NOT available from a LIST response alone. * They must be set separately (after SELECT + SEARCH UNSEEN). */ public function fromImap(Mailbox $mailbox): static { $delimiter = $mailbox->hierarchyDelimiter; $this->data['label'] = ($delimiter !== '' && str_contains($mailbox->name, $delimiter)) ? substr($mailbox->name, strrpos($mailbox->name, $delimiter) + strlen($delimiter)) : $mailbox->name; $this->data['delimiter'] = $delimiter; $this->data['attributes'] = $mailbox->nameAttributes; $this->data['subscribed'] = in_array('\Subscribed', $mailbox->nameAttributes, true); $this->data['total'] = 0; $this->data['unread'] = 0; $this->data['rank'] = 0; // Map standard IMAP role attributes $this->data['role'] = $this->roleFromAttributes($mailbox->nameAttributes)->value; return $this; } // ── Store (MongoDB cache) ──────────────────────────────────────────────── public function toStore(): array { return $this->data; } public function fromStore(array $data): static { $this->data = $data; return $this; } // ── JSON helpers ───────────────────────────────────────────────────────── public function jsonSerialize(): array { return $this->data; } public function getDelimiter(): ?string { return $this->data['delimiter'] ?? null; } // ── Helpers ─────────────────────────────────────────────────────────────── private function roleFromAttributes(array $attributes): CollectionRoles { foreach ($attributes as $attr) { $lower = strtolower($attr); $role = match ($lower) { '\sent' => CollectionRoles::Sent, '\trash' => CollectionRoles::Trash, '\drafts' => CollectionRoles::Drafts, '\junk' => CollectionRoles::Junk, '\archive' => CollectionRoles::Archive, default => null, }; if ($role !== null) { return $role; } } return CollectionRoles::Custom; } }