generated from Nodarx/template
refactor: split service into ServiceBase and LiveService
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
@@ -33,6 +33,8 @@ use KTXM\ProviderImap\Client\Protocol\IdentifierMode;
|
||||
use KTXM\ProviderImap\Client\ImapException;
|
||||
use KTXM\ProviderImap\Client\Protocol\Command\Argument\ListReturnOptions;
|
||||
use KTXM\ProviderImap\Client\Mailbox;
|
||||
use KTXM\ProviderImap\Providers\CollectionResource;
|
||||
use KTXM\ProviderImap\Providers\EntityResource;
|
||||
use KTXM\ProviderImap\Client\Message;
|
||||
use KTXM\ProviderImap\Client\MessageAddress;
|
||||
use KTXM\ProviderImap\Client\MessagePart;
|
||||
@@ -49,7 +51,7 @@ use KTXF\Resource\Range\RangeAnchorType;
|
||||
use KTXF\Resource\Range\RangeTally;
|
||||
use KTXF\Resource\Sort\ISort;
|
||||
use KTXF\Resource\BinaryResource;
|
||||
use KTXM\ProviderImap\Providers\Service;
|
||||
use KTXM\ProviderImap\Providers\ServiceBase;
|
||||
use KTXM\ProviderImap\Smtp\Client as SmtpClient;
|
||||
use RuntimeException;
|
||||
|
||||
@@ -69,7 +71,7 @@ class LiveMailService
|
||||
private ?Mailbox $selected = null;
|
||||
|
||||
public function __construct(
|
||||
private readonly Service $service,
|
||||
private readonly ServiceBase $service,
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -140,11 +142,48 @@ class LiveMailService
|
||||
}
|
||||
|
||||
/**
|
||||
* list of collections in remote storage
|
||||
*
|
||||
* @since Release 1.0.0
|
||||
*/
|
||||
public function collectionList(?string $location = null, IFilter|null $filter = null, ISort|null $sort = null, string $depth = '*'): Generator
|
||||
* List the collections of the account, keyed by mailbox name.
|
||||
*
|
||||
* @return array<string, CollectionResource>
|
||||
*/
|
||||
public function collectionList(?string $location = null, ?IFilter $filter = null, ?ISort $sort = null): array
|
||||
{
|
||||
$list = [];
|
||||
foreach ($this->mailboxList($location, $filter, $sort) as $name => $mailbox) {
|
||||
$list[(string) $name] = $this->collectionResource($mailbox);
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a single collection by its mailbox name; null when it does not exist.
|
||||
*/
|
||||
public function collectionFetch(string $identifier): ?CollectionResource
|
||||
{
|
||||
$mailbox = $this->mailboxFetch($identifier);
|
||||
|
||||
return $mailbox === null ? null : $this->collectionResource($mailbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hierarchy delimiter of the account, from `LIST "" ""` (no mailboxes are listed); "/" when unknown.
|
||||
*/
|
||||
public function collectionDelimiter(): string
|
||||
{
|
||||
foreach ($this->imapClient()->perform(new ListCommand('', '')) as $mailbox) {
|
||||
return $mailbox->delimiter() ?: '/';
|
||||
}
|
||||
|
||||
return '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* List the IMAP mailboxes of the account (with status), keyed by name.
|
||||
*
|
||||
* @return Generator<string, Mailbox>
|
||||
*/
|
||||
public function mailboxList(?string $location = null, IFilter|null $filter = null, ISort|null $sort = null, string $depth = '*'): Generator
|
||||
{
|
||||
// Prepare location filter
|
||||
if (!empty($location)) {
|
||||
@@ -196,11 +235,11 @@ class LiveMailService
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a single mailbox by its full name.
|
||||
* Fetch a single IMAP mailbox (with status) by its full name.
|
||||
*
|
||||
* Returns null when no mailbox matching $identifier is found.
|
||||
*/
|
||||
public function collectionFetch(string $identifier): ?Mailbox
|
||||
public function mailboxFetch(string $identifier): ?Mailbox
|
||||
{
|
||||
// LIST-STATUS (RFC 5819) returns the status with the LIST response in one round trip
|
||||
$listStatus = $this->imapClient()->hasCapability('LIST-STATUS');
|
||||
@@ -225,38 +264,38 @@ class LiveMailService
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new IMAP mailbox and return it.
|
||||
* Create a new IMAP mailbox and return it as a collection resource.
|
||||
*
|
||||
* If the server-side LIST cannot confirm the new mailbox (e.g., immediate
|
||||
* consistency), a lightweight stub resource is returned instead.
|
||||
*/
|
||||
public function collectionCreate(string $name): Mailbox
|
||||
public function collectionCreate(string $name, ?string $delimiter = null): CollectionResource
|
||||
{
|
||||
$this->imapClient()->perform(new CreateCommand($name));
|
||||
|
||||
// Attempt to refetch the new mailbox from the server
|
||||
$mailbox = $this->collectionFetch($name);
|
||||
$mailbox = $this->mailboxFetch($name);
|
||||
if ($mailbox === null) {
|
||||
throw new ImapException('Failed to create mailbox: ' . $name);
|
||||
}
|
||||
|
||||
return $mailbox;
|
||||
return $this->collectionResource($mailbox, $delimiter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename a mailbox and return the updated resource.
|
||||
*/
|
||||
public function collectionRename(string $oldName, string $newName): Mailbox
|
||||
public function collectionRename(string $oldName, string $newName, ?string $delimiter = null): CollectionResource
|
||||
{
|
||||
$this->imapClient()->perform(new RenameCommand($oldName, $newName));
|
||||
|
||||
$mailbox = $this->collectionFetch($newName);
|
||||
$mailbox = $this->mailboxFetch($newName);
|
||||
|
||||
if ($mailbox === null) {
|
||||
throw new ImapException('Failed to rename mailbox: ' . $oldName . ' to ' . $newName);
|
||||
}
|
||||
|
||||
return $mailbox;
|
||||
return $this->collectionResource($mailbox, $delimiter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -354,11 +393,36 @@ class LiveMailService
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a list of messages in a mailbox matching the given filter, sorted and paginated as requested.
|
||||
* List the entities of a mailbox matching the given filter, sorted and paginated as requested.
|
||||
*
|
||||
* @return Message[] list of messages matching the filter, sorted and paginated as requested
|
||||
* @return Generator<int, EntityResource> keyed by UID
|
||||
*/
|
||||
public function entityList(string $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null): Generator
|
||||
{
|
||||
foreach ($this->messageList($collection, $filter, $sort, $range) as $message) {
|
||||
$entity = $this->entityResource($message, $collection);
|
||||
yield (int) $entity->identifier() => $entity;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch entities by UID (full TEXT).
|
||||
*
|
||||
* @return Generator<int, EntityResource> keyed by UID
|
||||
*/
|
||||
public function entityFetch(string $collection, int ...$uids): Generator
|
||||
{
|
||||
foreach ($this->messageFetch($collection, null, ...$uids) as $uid => $message) {
|
||||
yield $uid => $this->entityResource($message, $collection);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List IMAP messages of a mailbox matching the given filter, sorted and paginated as requested.
|
||||
*
|
||||
* @return Generator<Message>
|
||||
*/
|
||||
public function messageList(string $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null): Generator
|
||||
{
|
||||
// text parts normally precede attachments, so capping TEXT avoids transferring attachment bytes
|
||||
$options = FetchOptions::message()->withBodyText(self::LIST_BODY_TEXT_LIMIT);
|
||||
@@ -387,16 +451,16 @@ class LiveMailService
|
||||
return [];
|
||||
}
|
||||
|
||||
yield from $this->entityFetch($collection, $options, ...$uids);
|
||||
yield from $this->messageFetch($collection, $options, ...$uids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch one or more messages by UID and return EntityResource objects.
|
||||
* Fetch one or more messages by UID as IMAP messages.
|
||||
*
|
||||
* @param int ...$uids
|
||||
* @return Message[] keyed by UID
|
||||
* @return Generator<int, Message> keyed by UID
|
||||
*/
|
||||
public function entityFetch(string $collection, ?FetchOptions $options = null, int ...$uids): Generator
|
||||
public function messageFetch(string $collection, ?FetchOptions $options = null, int ...$uids): Generator
|
||||
{
|
||||
if (empty($uids)) {
|
||||
return [];
|
||||
@@ -1181,6 +1245,18 @@ class LiveMailService
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
private function collectionResource(Mailbox $mailbox, ?string $delimiter = null): CollectionResource
|
||||
{
|
||||
return (new CollectionResource($this->service->provider(), $this->service->identifier()))
|
||||
->fromImap($mailbox, ['delimiter' => $delimiter]);
|
||||
}
|
||||
|
||||
private function entityResource(Message $message, string $collection): EntityResource
|
||||
{
|
||||
return (new EntityResource($this->service->provider(), $this->service->identifier()))
|
||||
->fromImap($message, $collection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a mailbox, reusing the current selection when possible.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user