generated from Nodarx/template
refactor: use custom imap client
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
112
lib/Client/Command/StoreCommand.php
Normal file
112
lib/Client/Command/StoreCommand.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace KTXM\ProviderImap\Client\Command;
|
||||
|
||||
use KTXM\ProviderImap\Client\Command\Result\CommandStatusResult;
|
||||
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\ResponseStream;
|
||||
use KTXM\ProviderImap\Client\SequenceSet;
|
||||
use KTXM\ProviderImap\Client\SessionContext;
|
||||
use KTXM\ProviderImap\Client\SessionState;
|
||||
|
||||
/**
|
||||
* @implements CommandInterface<CommandStatusResult>
|
||||
*/
|
||||
final class StoreCommand implements CommandInterface
|
||||
{
|
||||
private readonly SequenceSet $sequenceSet;
|
||||
private readonly IdentifierMode $identifierMode;
|
||||
|
||||
/**
|
||||
* @param list<string> $flags
|
||||
*/
|
||||
public function __construct(
|
||||
FetchTarget|string|SequenceSet|null $target = null,
|
||||
private readonly array $flags = [],
|
||||
private readonly string $action = '',
|
||||
private readonly bool $silent = true,
|
||||
) {
|
||||
$resolvedTarget = match (true) {
|
||||
$target instanceof FetchTarget => $target,
|
||||
$target instanceof SequenceSet => FetchTarget::sequence($target),
|
||||
is_string($target) => FetchTarget::sequence($target),
|
||||
default => FetchTarget::all(),
|
||||
};
|
||||
|
||||
$normalizedAction = trim($this->action);
|
||||
if (!in_array($normalizedAction, ['', '+', '-'], true)) {
|
||||
throw new ImapException('STORE action must be one of "", "+", or "-".');
|
||||
}
|
||||
|
||||
$normalizedFlags = array_values(array_filter(array_map(
|
||||
static fn (string $flag): string => trim($flag),
|
||||
$this->flags,
|
||||
), static fn (string $flag): bool => $flag !== ''));
|
||||
|
||||
if ($normalizedFlags === []) {
|
||||
throw new ImapException('STORE requires at least one flag.');
|
||||
}
|
||||
|
||||
$this->flags = $normalizedFlags;
|
||||
$this->action = $normalizedAction;
|
||||
$this->sequenceSet = $resolvedTarget->sequenceSet();
|
||||
$this->identifierMode = $resolvedTarget->identifierMode();
|
||||
}
|
||||
|
||||
public function name(): string
|
||||
{
|
||||
return 'STORE';
|
||||
}
|
||||
|
||||
public function allowedStates(): array
|
||||
{
|
||||
return [SessionState::Selected];
|
||||
}
|
||||
|
||||
public function encode(string $tag, SessionContext $context): RequestFrame
|
||||
{
|
||||
unset($tag, $context);
|
||||
|
||||
return new RequestFrame(sprintf(
|
||||
'%sSTORE %s %s (%s)',
|
||||
$this->identifierMode === IdentifierMode::Uid ? 'UID ' : '',
|
||||
$this->sequenceSet->toCommand(),
|
||||
$this->itemName(),
|
||||
implode(' ', $this->flags),
|
||||
));
|
||||
}
|
||||
|
||||
public function handle(ResponseStream $responses, SessionContext $context): CommandStatusResult
|
||||
{
|
||||
if ($context->selectedMailbox() === null) {
|
||||
throw new ImapException('STORE requires a selected mailbox.');
|
||||
}
|
||||
|
||||
foreach ($responses as $response) {
|
||||
if ($response instanceof TaggedResponse) {
|
||||
if (!$response->isOk()) {
|
||||
throw new ImapException('STORE failed: ' . $response->text());
|
||||
}
|
||||
|
||||
return new CommandStatusResult($response->status(), $response->text());
|
||||
}
|
||||
}
|
||||
|
||||
throw new ImapException('STORE did not receive a tagged completion response.');
|
||||
}
|
||||
|
||||
private function itemName(): string
|
||||
{
|
||||
return sprintf(
|
||||
'%sFLAGS%s',
|
||||
$this->action,
|
||||
$this->silent ? '.SILENT' : '',
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user