Rename plugins to libs and update all file references

This commit is contained in:
johnnyq
2026-07-10 13:24:20 -04:00
parent 7ba1571400
commit 8da3a107fb
3410 changed files with 140 additions and 140 deletions

View File

@@ -0,0 +1,245 @@
<?php
namespace DirectoryTree\ImapEngine\Testing;
use DirectoryTree\ImapEngine\ComparesFolders;
use DirectoryTree\ImapEngine\Exceptions\Exception;
use DirectoryTree\ImapEngine\FolderInterface;
use DirectoryTree\ImapEngine\MailboxInterface;
use DirectoryTree\ImapEngine\MessageQueryInterface;
use DirectoryTree\ImapEngine\Support\Str;
class FakeFolder implements FolderInterface
{
use ComparesFolders;
/**
* Constructor.
*/
public function __construct(
protected string $path = '',
protected array $flags = [],
/** @var FakeMessage[] */
protected array $messages = [],
protected string $delimiter = '/',
protected ?MailboxInterface $mailbox = null,
) {}
/**
* {@inheritDoc}
*/
public function mailbox(): MailboxInterface
{
return $this->mailbox ?? throw new Exception('Folder has no mailbox.');
}
/**
* {@inheritDoc}
*/
public function path(): string
{
return $this->path;
}
/**
* {@inheritDoc}
*/
public function flags(): array
{
return $this->flags;
}
/**
* {@inheritDoc}
*/
public function delimiter(): string
{
return $this->delimiter;
}
/**
* {@inheritDoc}
*/
public function name(): string
{
return Str::fromImapUtf7(
last(explode($this->delimiter, $this->path))
);
}
/**
* {@inheritDoc}
*/
public function is(FolderInterface $folder): bool
{
return $this->isSameFolder($this, $folder);
}
/**
* {@inheritDoc}
*/
public function messages(): MessageQueryInterface
{
// Ensure the folder is selected.
$this->select(true);
return new FakeMessageQuery($this);
}
/**
* {@inheritDoc}
*/
public function idle(callable $callback, ?callable $query = null, callable|int $timeout = 300): void
{
foreach ($this->messages as $message) {
$callback($message);
}
}
/**
* {@inheritDoc}
*/
public function poll(callable $callback, ?callable $query = null, callable|int $frequency = 60): void
{
foreach ($this->messages as $message) {
$callback($message);
}
}
/**
* {@inheritDoc}
*/
public function move(string $newPath): void
{
// Do nothing.
}
/**
* {@inheritDoc}
*/
public function select(bool $force = false): void
{
$this->mailbox?->select($this, $force);
}
/**
* {@inheritDoc}
*/
public function status(): array
{
return [];
}
/**
* {@inheritDoc}
*/
public function examine(): array
{
return [];
}
/**
* {@inheritDoc}
*/
public function expunge(): array
{
return [];
}
/**
* {@inheritDoc}
*/
public function quota(): array
{
return [
$this->path => [
'STORAGE' => [
'usage' => 0,
'limit' => 0,
],
'MESSAGE' => [
'usage' => 0,
'limit' => 0,
],
],
];
}
/**
* {@inheritDoc}
*/
public function delete(): void
{
// Do nothing.
}
/**
* Set the folder's path.
*/
public function setPath(string $path): FakeFolder
{
$this->path = $path;
return $this;
}
/**
* Set the folder's flags.
*/
public function setFlags(array $flags): FakeFolder
{
$this->flags = $flags;
return $this;
}
/**
* Set the folder's mailbox.
*/
public function setMailbox(MailboxInterface $mailbox): FakeFolder
{
$this->mailbox = $mailbox;
return $this;
}
/**
* Set the folder's messages.
*
* @param FakeMessage[] $messages
*/
public function setMessages(array $messages): FakeFolder
{
$this->messages = $messages;
return $this;
}
/**
* Get the folder's messages.
*
* @return FakeMessage[]
*/
public function getMessages(): array
{
return $this->messages;
}
/**
* Add a message to the folder.
*/
public function addMessage(FakeMessage $message): void
{
$this->messages[] = $message;
}
/**
* Set the folder's delimiter.
*/
public function setDelimiter(string $delimiter = '/'): FakeFolder
{
$this->delimiter = $delimiter;
return $this;
}
}

View File

@@ -0,0 +1,77 @@
<?php
namespace DirectoryTree\ImapEngine\Testing;
use DirectoryTree\ImapEngine\Collections\FolderCollection;
use DirectoryTree\ImapEngine\FolderInterface;
use DirectoryTree\ImapEngine\FolderRepositoryInterface;
use DirectoryTree\ImapEngine\MailboxInterface;
use DirectoryTree\ImapEngine\Support\Str;
use Illuminate\Support\ItemNotFoundException;
class FakeFolderRepository implements FolderRepositoryInterface
{
/**
* Constructor.
*/
public function __construct(
protected MailboxInterface $mailbox,
/** @var FolderInterface[] */
protected array $folders = []
) {}
/**
* {@inheritDoc}
*/
public function find(string $path): ?FolderInterface
{
try {
return $this->findOrFail($path);
} catch (ItemNotFoundException) {
return null;
}
}
/**
* {@inheritDoc}
*/
public function findOrFail(string $path): FolderInterface
{
return $this->get()->firstOrFail(
fn (FolderInterface $folder) => strtolower($folder->path()) === strtolower($path)
);
}
/**
* {@inheritDoc}
*/
public function create(string $path): FolderInterface
{
return $this->folders[] = new FakeFolder($path, mailbox: $this->mailbox);
}
/**
* {@inheritDoc}
*/
public function firstOrCreate(string $path): FolderInterface
{
return $this->find($path) ?? $this->create($path);
}
/**
* {@inheritDoc}
*/
public function get(?string $match = '*', ?string $reference = ''): FolderCollection
{
$folders = FolderCollection::make($this->folders);
// If we're not matching all, filter the folders by the match pattern.
if (! in_array($match, ['*', null])) {
return $folders->filter(
fn (FolderInterface $folder) => Str::is($match, $folder->path())
);
}
return $folders;
}
}

View File

@@ -0,0 +1,123 @@
<?php
namespace DirectoryTree\ImapEngine\Testing;
use DirectoryTree\ImapEngine\Connection\ConnectionInterface;
use DirectoryTree\ImapEngine\Exceptions\Exception;
use DirectoryTree\ImapEngine\FolderInterface;
use DirectoryTree\ImapEngine\FolderRepositoryInterface;
use DirectoryTree\ImapEngine\MailboxInterface;
class FakeMailbox implements MailboxInterface
{
/**
* The currently selected folder.
*/
protected ?FolderInterface $selected = null;
/**
* Constructor.
*/
public function __construct(
protected array $config = [],
/** @var FakeFolder[] */
protected array $folders = [],
protected array $capabilities = [],
) {
foreach ($folders as $folder) {
$folder->setMailbox($this);
}
}
/**
* {@inheritDoc}
*/
public function config(?string $key = null, mixed $default = null): mixed
{
if (is_null($key)) {
return $this->config;
}
return data_get($this->config, $key, $default);
}
/**
* {@inheritDoc}
*/
public function connection(): ConnectionInterface
{
throw new Exception('Unsupported.');
}
/**
* {@inheritDoc}
*/
public function connected(): bool
{
return true;
}
/**
* {@inheritDoc}
*/
public function reconnect(): void
{
// Do nothing.
}
/**
* {@inheritDoc}
*/
public function connect(?ConnectionInterface $connection = null): void
{
// Do nothing.
}
/**
* {@inheritDoc}
*/
public function disconnect(): void
{
// Do nothing.
}
/**
* {@inheritDoc}
*/
public function inbox(): FolderInterface
{
return $this->folders()->findOrFail('inbox');
}
/**
* {@inheritDoc}
*/
public function folders(): FolderRepositoryInterface
{
return new FakeFolderRepository($this, $this->folders);
}
/**
* {@inheritDoc}
*/
public function capabilities(): array
{
return $this->capabilities;
}
/**
* {@inheritDoc}
*/
public function select(FolderInterface $folder, bool $force = false): void
{
$this->selected = $folder;
}
/**
* {@inheritDoc}
*/
public function selected(FolderInterface $folder): bool
{
return $this->selected?->is($folder) ?? false;
}
}

View File

@@ -0,0 +1,116 @@
<?php
namespace DirectoryTree\ImapEngine\Testing;
use BackedEnum;
use DirectoryTree\ImapEngine\BodyStructureCollection;
use DirectoryTree\ImapEngine\HasFlags;
use DirectoryTree\ImapEngine\HasMessageAccessors;
use DirectoryTree\ImapEngine\HasParsedMessage;
use DirectoryTree\ImapEngine\MessageInterface;
use DirectoryTree\ImapEngine\Support\Str;
class FakeMessage implements MessageInterface
{
use HasFlags, HasMessageAccessors, HasParsedMessage;
/**
* Constructor.
*/
public function __construct(
protected int $uid,
protected array $flags = [],
protected string $contents = '',
protected ?int $size = null,
protected ?BodyStructureCollection $bodyStructure = null,
) {}
/**
* {@inheritDoc}
*/
public function uid(): int
{
return $this->uid;
}
/**
* {@inheritDoc}
*/
public function size(): int
{
return $this->size ?? strlen($this->contents);
}
/**
* {@inheritDoc}
*/
public function is(MessageInterface $message): bool
{
return $message instanceof self
&& $this->uid === $message->uid
&& $this->flags === $message->flags
&& $this->contents === $message->contents;
}
/**
* {@inheritDoc}
*/
public function flag(BackedEnum|string $flag, string $operation, bool $expunge = false): void
{
$flag = Str::enum($flag);
if ($operation === '+') {
$this->flags = array_unique([...$this->flags, $flag]);
} else {
$this->flags = array_filter($this->flags, fn (string $value) => $value !== $flag);
}
}
/**
* {@inheritDoc}
*/
public function flags(): array
{
return $this->flags;
}
/**
* {@inheritDoc}
*/
public function bodyStructure(): ?BodyStructureCollection
{
return $this->bodyStructure;
}
/**
* {@inheritDoc}
*/
public function hasBodyStructure(): bool
{
return (bool) $this->bodyStructure;
}
/**
* {@inheritDoc}
*/
public function bodyPart(string $partNumber, bool $peek = true): ?string
{
return null;
}
/**
* {@inheritDoc}
*/
public function isEmpty(): bool
{
return empty($this->contents);
}
/**
* {@inheritDoc}
*/
public function __toString(): string
{
return $this->contents;
}
}

View File

@@ -0,0 +1,226 @@
<?php
namespace DirectoryTree\ImapEngine\Testing;
use BackedEnum;
use DirectoryTree\ImapEngine\Collections\MessageCollection;
use DirectoryTree\ImapEngine\Connection\ImapQueryBuilder;
use DirectoryTree\ImapEngine\Enums\ImapFetchIdentifier;
use DirectoryTree\ImapEngine\MessageInterface;
use DirectoryTree\ImapEngine\MessageQueryInterface;
use DirectoryTree\ImapEngine\Pagination\LengthAwarePaginator;
use DirectoryTree\ImapEngine\QueriesMessages;
class FakeMessageQuery implements MessageQueryInterface
{
use QueriesMessages;
/**
* Constructor.
*/
public function __construct(
protected FakeFolder $folder,
protected ImapQueryBuilder $query = new ImapQueryBuilder
) {}
/**
* {@inheritDoc}
*/
public function get(): MessageCollection
{
return new MessageCollection(
$this->folder->getMessages()
);
}
/**
* {@inheritDoc}
*/
public function count(): int
{
return count(
$this->folder->getMessages()
);
}
/**
* {@inheritDoc}
*/
public function first(): ?MessageInterface
{
return $this->get()->first();
}
/**
* {@inheritDoc}
*/
public function firstOrFail(): MessageInterface
{
return $this->get()->firstOrFail();
}
/**
* {@inheritDoc}
*/
public function append(string $message, mixed $flags = null): int
{
$uid = 1;
if ($lastMessage = $this->get()->last()) {
$uid = $lastMessage->uid() + 1;
}
$this->folder->addMessage(
new FakeMessage($uid, $flags === null ? [] : $flags, $message)
);
return $uid;
}
/**
* {@inheritDoc}
*/
public function each(callable $callback, int $chunkSize = 10, int $startChunk = 1): void
{
$this->chunk(function (MessageCollection $messages) use ($callback) {
foreach ($messages as $key => $message) {
if ($callback($message, $key) === false) {
return false;
}
}
}, $chunkSize, $startChunk);
}
/**
* {@inheritDoc}
*/
public function chunk(callable $callback, int $chunkSize = 10, int $startChunk = 1): void
{
$page = $startChunk;
foreach ($this->get()->chunk($chunkSize) as $chunk) {
if ($page < $startChunk) {
$page++;
continue;
}
// If the callback returns false, break out.
if ($callback($chunk, $page) === false) {
break;
}
$page++;
}
}
/**
* {@inheritDoc}
*/
public function paginate(int $perPage = 5, $page = null, string $pageName = 'page'): LengthAwarePaginator
{
return $this->get()->paginate($perPage, $page, $pageName);
}
/**
* {@inheritDoc}
*/
public function findOrFail(int $id, ImapFetchIdentifier $identifier = ImapFetchIdentifier::Uid): MessageInterface
{
return $this->get()->findOrFail($id);
}
/**
* {@inheritDoc}
*/
public function find(int $id, ImapFetchIdentifier $identifier = ImapFetchIdentifier::Uid): ?MessageInterface
{
return $this->get()->find($id);
}
/**
* {@inheritDoc}
*/
public function destroy(array|int $uids, bool $expunge = false): void
{
$messages = $this->get()->keyBy(
fn (MessageInterface $message) => $message->uid()
);
foreach ((array) $uids as $uid) {
$messages->pull($uid);
}
$this->folder->setMessages(
$messages->values()->all()
);
}
/**
* {@inheritDoc}
*/
public function flag(BackedEnum|string $flag, string $operation, bool $expunge = false): int
{
return count($this->folder->getMessages());
}
/**
* {@inheritDoc}
*/
public function markRead(): int
{
return count($this->folder->getMessages());
}
/**
* {@inheritDoc}
*/
public function markUnread(): int
{
return count($this->folder->getMessages());
}
/**
* {@inheritDoc}
*/
public function markFlagged(): int
{
return count($this->folder->getMessages());
}
/**
* {@inheritDoc}
*/
public function unmarkFlagged(): int
{
return count($this->folder->getMessages());
}
/**
* {@inheritDoc}
*/
public function delete(bool $expunge = false): int
{
$count = count($this->folder->getMessages());
$this->folder->setMessages([]);
return $count;
}
/**
* {@inheritDoc}
*/
public function move(string $folder, bool $expunge = false): int
{
return count($this->folder->getMessages());
}
/**
* {@inheritDoc}
*/
public function copy(string $folder): int
{
return count($this->folder->getMessages());
}
}