generated from Nodarx/template
106 lines
3.2 KiB
PHP
106 lines
3.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace KTXM\ProviderImap\Client\Command;
|
|
|
|
use KTXM\ProviderImap\Client\FetchTarget;
|
|
use KTXM\ProviderImap\Client\IdentifierMode;
|
|
use KTXM\ProviderImap\Client\ImapException;
|
|
use KTXM\ProviderImap\Client\Protocol\RequestFrame;
|
|
use KTXM\ProviderImap\Client\Protocol\Response\TaggedResponse;
|
|
use KTXM\ProviderImap\Client\Protocol\Response\UntaggedResponse;
|
|
use KTXM\ProviderImap\Client\Protocol\ResponseStream;
|
|
use KTXM\ProviderImap\Client\SequenceSet;
|
|
use KTXM\ProviderImap\Client\SessionContext;
|
|
use KTXM\ProviderImap\Client\SessionState;
|
|
|
|
/**
|
|
* @implements CommandInterface<list<int>>
|
|
*/
|
|
final class ExpungeCommand implements CommandInterface
|
|
{
|
|
private readonly ?SequenceSet $sequenceSet;
|
|
|
|
public function __construct(FetchTarget|string|SequenceSet|null $target = null)
|
|
{
|
|
if ($target === null) {
|
|
$this->sequenceSet = null;
|
|
|
|
return;
|
|
}
|
|
|
|
$resolvedTarget = match (true) {
|
|
$target instanceof FetchTarget => $target,
|
|
$target instanceof SequenceSet => FetchTarget::sequence($target),
|
|
is_string($target) => FetchTarget::sequence($target),
|
|
default => null,
|
|
};
|
|
|
|
if ($resolvedTarget === null || $resolvedTarget->identifierMode() !== IdentifierMode::Uid) {
|
|
throw new ImapException('Targeted EXPUNGE requires a UID target.');
|
|
}
|
|
|
|
$this->sequenceSet = $resolvedTarget->sequenceSet();
|
|
}
|
|
|
|
public function name(): string
|
|
{
|
|
return 'EXPUNGE';
|
|
}
|
|
|
|
public function allowedStates(): array
|
|
{
|
|
return [SessionState::Selected];
|
|
}
|
|
|
|
public function encode(string $tag, SessionContext $context): RequestFrame
|
|
{
|
|
unset($tag);
|
|
|
|
if ($this->sequenceSet === null) {
|
|
unset($context);
|
|
|
|
return new RequestFrame('EXPUNGE');
|
|
}
|
|
|
|
if (!$context->hasCapability('UIDPLUS')) {
|
|
throw new ImapException('UID EXPUNGE requires the IMAP UIDPLUS capability.');
|
|
}
|
|
|
|
return new RequestFrame(sprintf(
|
|
'UID EXPUNGE %s',
|
|
$this->sequenceSet->toCommand(),
|
|
));
|
|
}
|
|
|
|
public function handle(ResponseStream $responses, SessionContext $context): array
|
|
{
|
|
if ($context->selectedMailbox() === null) {
|
|
throw new ImapException('EXPUNGE requires a selected mailbox.');
|
|
}
|
|
|
|
$expunged = [];
|
|
|
|
foreach ($responses as $response) {
|
|
if ($response instanceof UntaggedResponse && preg_match('/^\*\s+(\d+)\s+EXPUNGE$/i', $response->raw(), $matches) === 1) {
|
|
$expunged[] = (int) $matches[1];
|
|
continue;
|
|
}
|
|
|
|
if ($response instanceof TaggedResponse) {
|
|
if (!$response->isOk()) {
|
|
throw new ImapException($this->sequenceSet === null
|
|
? 'EXPUNGE failed: ' . $response->text()
|
|
: 'UID EXPUNGE failed: ' . $response->text());
|
|
}
|
|
|
|
return $expunged;
|
|
}
|
|
}
|
|
|
|
throw new ImapException($this->sequenceSet === null
|
|
? 'EXPUNGE did not receive a tagged completion response.'
|
|
: 'UID EXPUNGE did not receive a tagged completion response.');
|
|
}
|
|
} |