From ec6bdcf7fdfd53088c67dc5601d896a935d7f594 Mon Sep 17 00:00:00 2001 From: Sebastian Krupinski Date: Sat, 26 Sep 2026 21:46:34 -0400 Subject: [PATCH] refactor: role based mailbox resolution Signed-off-by: Sebastian Krupinski --- lib/Providers/Service.php | 108 ++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 57 deletions(-) diff --git a/lib/Providers/Service.php b/lib/Providers/Service.php index 4b97ba3..e9fa117 100644 --- a/lib/Providers/Service.php +++ b/lib/Providers/Service.php @@ -474,31 +474,15 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC $this->initialize(); $deleteMode = $this->auxiliary['deleteMode'] ?? 'soft'; - $deleteTarget = $this->auxiliary['deleteTarget'] ?? null; if ($deleteMode !== 'soft' && $deleteMode !== 'hard') { throw new \InvalidArgumentException("Invalid delete mode: $deleteMode"); } - // Move to target collection (e.g. Trash) instead of deleting - if ($deleteMode === 'soft' && $deleteTarget !== null) { - return $this->collectionMove(new CollectionIdentifier($target->provider(), $target->service(), $deleteTarget), $target); - } - - if ($deleteMode === 'soft' && $deleteTarget === null) { - $filter = $this->collectionListFilter(); - $filter->condition('role', CollectionRoles::Trash->value); - - $mailboxes = iterator_to_array($this->remoteService->collectionList(null, $filter, null)); - if (empty($mailboxes)) { - throw new \RuntimeException('No Trash collection configured or found for deletion'); - } - - $deleteTarget = key($mailboxes); - } + $deleteTarget = $deleteMode === 'soft' ? $this->resolveDeleteDestination() : null; // we need to determine if the folder being deleted is already in the trash - if (str_starts_with((string) $target->collection(), (string) $deleteTarget)) { + if ($deleteTarget !== null && str_starts_with((string) $target->collection(), $deleteTarget)) { // if so, we should hard delete instead of moving to avoid duplicates in the trash $deleteMode = 'hard'; } @@ -699,23 +683,6 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC ); } - /** - * Resolve the native name of the collection flagged with the Sent role. - */ - private function resolveSentCollection(): ?string - { - $filter = $this->collectionListFilter(); - $filter->condition('role', CollectionRoles::Sent->value); - - /** @var Mailbox[] $mailboxes */ - $mailboxes = iterator_to_array($this->remoteService->collectionList(null, $filter, null)); - if ($mailboxes === []) { - return null; - } - $mailbox = reset($mailboxes); - return $mailbox === false ? null : $mailbox->name(); - } - public function entityCreate(CollectionIdentifier $target, MessagePropertiesMutableInterface $properties, array $options = []): EntityResource { if ($target->provider() !== $this->provider() || (string)$target->service() !== (string)$this->identifier()) { @@ -799,7 +766,6 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC // determine delete mode and target collection (e.g. Trash) if applicable $deleteMode = $this->auxiliary['deleteMode'] ?? 'soft'; - $deleteTarget = $this->auxiliary['deleteTarget'] ?? null; if ($deleteMode !== 'soft' && $deleteMode !== 'hard') { throw new \InvalidArgumentException("Invalid delete mode: $deleteMode"); @@ -808,26 +774,10 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC // connect to remote store $this->initialize(); - // attempt to find a target collection for soft deletion if none was specified - if ($deleteMode === 'soft' && $deleteTarget === null) { - $filter = $this->collectionListFilter(); - $filter->condition('role', CollectionRoles::Trash->value); - - /** @var Mailbox[] $mailboxes */ - $mailboxes = iterator_to_array($this->remoteService->collectionList(null, $filter, null)); - if (empty($mailboxes)) { - throw new \RuntimeException('No Trash collection configured or found for deletion'); - } - - $targetMailbox = reset($mailboxes); - if ($targetMailbox === false) { - throw new \RuntimeException('No Trash collection configured or found for deletion'); - } - - $deleteTargetNative = $targetMailbox->name(); - $deleteTargetIdentifier = new CollectionIdentifier($this->provider(), (string) $this->identifier(), $deleteTargetNative); - } else { - $deleteTargetNative = $deleteTarget; + $deleteTargetNative = null; + $deleteTargetIdentifier = null; + if ($deleteMode === 'soft') { + $deleteTargetNative = $this->resolveDeleteDestination(); $deleteTargetIdentifier = new CollectionIdentifier($this->provider(), (string) $this->identifier(), $deleteTargetNative); } @@ -930,6 +880,51 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC return $list; } + /** + * Resolve the native name of the first collection flagged with the given role. + */ + private function resolveRoleCollection(CollectionRoles $role): ?string + { + $filter = $this->collectionListFilter(); + $filter->condition('role', $role->value); + + /** @var Mailbox[] $mailboxes */ + $mailboxes = iterator_to_array($this->remoteService->collectionList(null, $filter, null)); + if ($mailboxes === []) { + return null; + } + $mailbox = reset($mailboxes); + return $mailbox === false ? null : $mailbox->name(); + } + + /** + * Resolve the native name of the collection flagged with the Sent role. + */ + private function resolveSentCollection(): ?string + { + return $this->resolveRoleCollection(CollectionRoles::Sent); + } + + /** + * Resolve the native name of the collection soft-deleted messages and collections are moved to. + */ + private function resolveDeleteDestination(): string + { + $destination = trim((string) ($this->auxiliary['deleteDestination'] ?? '')); + + if ($destination === '') { + return $this->resolveRoleCollection(CollectionRoles::Trash) + ?? throw new \RuntimeException('No Trash collection configured or found for deletion'); + } + + $role = CollectionRoles::tryFrom(strtolower($destination)); + if ($role !== null && $role !== CollectionRoles::None) { + return $this->resolveRoleCollection($role) ?? $destination; + } + + return $destination; + } + private function groupEntitiesByCollection(EntityIdentifier ...$identifiers): array { $list = []; @@ -982,5 +977,4 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC return [(new MessageBuilder())->build($properties), $flags]; } - }