mirror of
https://github.com/itflow-org/itflow
synced 2026-07-24 17:30:43 +00:00
Rewrite email parser using ImapEngine, harden processing loop
Replace webklex/php-imap with directorytree/imapengine in the ticket email parser. ImapEngine is pure PHP over sockets. Parser improvements: - Wrap per-message processing in try/catch so one malformed email can't abort the run; failures are flagged and logged with UID - Query unseen + unflagged so previously-failed (flagged) messages are no longer re-processed on every cron run - Skip vacation/auto-responder emails (RFC 3834) to prevent mail loops with the ticket auto-reply - Cap messages per run (50) and attachment size (15MB); inline images over 2MB are stored as attachments instead of base64-embedded in ticket details - Atomic lock file creation - preg_quote() the ticket prefix in subject matching - Dedupe CC watchers and exclude the sender - Map webklex 'tls' encryption setting to STARTTLS for compatibility NDR/DSN parsing now walks MIME parts via the underlying zbateson parser instead of relying on attachment extraction.
This commit is contained in:
11
plugins/vendor/directorytree/imapengine/src/Collections/FolderCollection.php
vendored
Normal file
11
plugins/vendor/directorytree/imapengine/src/Collections/FolderCollection.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace DirectoryTree\ImapEngine\Collections;
|
||||
|
||||
use DirectoryTree\ImapEngine\FolderInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @template-extends Collection<array-key, FolderInterface>
|
||||
*/
|
||||
class FolderCollection extends Collection {}
|
||||
32
plugins/vendor/directorytree/imapengine/src/Collections/MessageCollection.php
vendored
Normal file
32
plugins/vendor/directorytree/imapengine/src/Collections/MessageCollection.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace DirectoryTree\ImapEngine\Collections;
|
||||
|
||||
use DirectoryTree\ImapEngine\Message;
|
||||
use DirectoryTree\ImapEngine\MessageInterface;
|
||||
|
||||
/**
|
||||
* @template-extends PaginatedCollection<array-key, MessageInterface|Message>
|
||||
*/
|
||||
class MessageCollection extends PaginatedCollection
|
||||
{
|
||||
/**
|
||||
* Find a message by its UID.
|
||||
*/
|
||||
public function find(int $uid): ?MessageInterface
|
||||
{
|
||||
return $this->first(
|
||||
fn (MessageInterface $message) => $message->uid() === $uid
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a message by its UID or throw an exception.
|
||||
*/
|
||||
public function findOrFail(int $uid): MessageInterface
|
||||
{
|
||||
return $this->firstOrFail(
|
||||
fn (MessageInterface $message) => $message->uid() === $uid
|
||||
);
|
||||
}
|
||||
}
|
||||
56
plugins/vendor/directorytree/imapengine/src/Collections/PaginatedCollection.php
vendored
Normal file
56
plugins/vendor/directorytree/imapengine/src/Collections/PaginatedCollection.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace DirectoryTree\ImapEngine\Collections;
|
||||
|
||||
use DirectoryTree\ImapEngine\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @template TKey of array-key
|
||||
* @template TValue
|
||||
*
|
||||
* @template-extends Collection<TKey, TValue>
|
||||
*/
|
||||
class PaginatedCollection extends Collection
|
||||
{
|
||||
/**
|
||||
* The total number of items.
|
||||
*/
|
||||
protected int $total = 0;
|
||||
|
||||
/**
|
||||
* Paginate the current collection.
|
||||
*
|
||||
* @return LengthAwarePaginator<TKey, TValue>
|
||||
*/
|
||||
public function paginate(int $perPage = 15, ?int $page = null, string $pageName = 'page', bool $prepaginated = false): LengthAwarePaginator
|
||||
{
|
||||
$total = $this->total ?: $this->count();
|
||||
|
||||
$results = ! $prepaginated && $total ? $this->forPage($page, $perPage) : $this;
|
||||
|
||||
return $this->paginator($results, $total, $perPage, $page, $pageName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new length-aware paginator instance.
|
||||
*
|
||||
* @return LengthAwarePaginator<TKey, TValue>
|
||||
*/
|
||||
protected function paginator(Collection $items, int $total, int $perPage, ?int $currentPage, string $pageName): LengthAwarePaginator
|
||||
{
|
||||
return new LengthAwarePaginator($items, $total, $perPage, $currentPage, $pageName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or set the total amount.
|
||||
*/
|
||||
public function total(?int $total = null): ?int
|
||||
{
|
||||
if (is_null($total)) {
|
||||
return $this->total;
|
||||
}
|
||||
|
||||
return $this->total = $total;
|
||||
}
|
||||
}
|
||||
48
plugins/vendor/directorytree/imapengine/src/Collections/ResponseCollection.php
vendored
Normal file
48
plugins/vendor/directorytree/imapengine/src/Collections/ResponseCollection.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace DirectoryTree\ImapEngine\Collections;
|
||||
|
||||
use DirectoryTree\ImapEngine\Connection\Responses\ContinuationResponse;
|
||||
use DirectoryTree\ImapEngine\Connection\Responses\TaggedResponse;
|
||||
use DirectoryTree\ImapEngine\Connection\Responses\UntaggedResponse;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @template TKey of array-key
|
||||
*
|
||||
* @template-covariant TValue
|
||||
*
|
||||
* @extends Collection<array-key, TValue>
|
||||
*/
|
||||
class ResponseCollection extends Collection
|
||||
{
|
||||
/**
|
||||
* Filter the collection to only tagged responses.
|
||||
*
|
||||
* @return self<array-key, TaggedResponse>
|
||||
*/
|
||||
public function tagged(): self
|
||||
{
|
||||
return $this->whereInstanceOf(TaggedResponse::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the collection to only untagged responses.
|
||||
*
|
||||
* @return self<array-key, UntaggedResponse>
|
||||
*/
|
||||
public function untagged(): self
|
||||
{
|
||||
return $this->whereInstanceOf(UntaggedResponse::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the collection to only continuation responses.
|
||||
*
|
||||
* @return self<array-key, ContinuationResponse>
|
||||
*/
|
||||
public function continuation(): self
|
||||
{
|
||||
return $this->whereInstanceOf(ContinuationResponse::class);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user