feat: speed improvements

Signed-off-by: Sebastian Krupinski <root@LAPTOP-7DVOR6NC>
This commit is contained in:
Sebastian Krupinski
2026-02-20 23:34:30 -05:00
parent e51c65bf19
commit 7446edced3
37 changed files with 648 additions and 1086 deletions

View File

@@ -11,12 +11,10 @@ namespace KTXM\ProviderImapMail\Providers;
use DateTimeImmutable;
use DateTimeInterface;
use Gricob\IMAP\Mime\Part\Part as MimePart;
use Gricob\IMAP\Protocol\Response\Line\Data\Fetch\BodyStructure;
use Gricob\IMAP\Protocol\Response\Line\Data\Fetch\BodyStructure\MultiPart;
use Gricob\IMAP\Protocol\Response\Line\Data\Fetch\BodyStructure\Part;
use Gricob\IMAP\Protocol\Response\Line\Data\Fetch\BodyStructure\SinglePart;
use Gricob\IMAP\Protocol\Response\Line\Data\Fetch\Envelope;
use Gricob\IMAP\Protocol\Response\Line\Data\FetchData;
use KTXF\Mail\Object\MessagePropertiesMutableAbstract;
/**
@@ -27,25 +25,16 @@ class MessageProperties extends MessagePropertiesMutableAbstract {
/**
* Convert IMAP data to mail message properties object
*
* @param array $flags IMAP flags (e.g. ['\Seen', '\Flagged', ...])
* @param ?Envelope $envelope parsed envelope from gricob
* @param ?BodyStructure $bodyStructure parsed body structure from gricob
* @param int $size RFC822.SIZE byte count
* @param FetchData $fetchData result from IMAP FETCH command
*/
public function fromImap(
array $flags,
?Envelope $envelope,
?BodyStructure $bodyStructure,
int $size = 0,
?MimePart $bodyPart = null,
): static {
public function fromImap(FetchData $fetchData): static {
// ── Size ──────────────────────────────────────────────────────
$this->data['size'] = $size;
$this->data['size'] = $fetchData->rfc822Size ?? 0;
// ── Flags ─────────────────────────────────────────────────────
$this->data['flags'] = [];
foreach ($flags as $flag) {
foreach ($fetchData->flags ?? [] as $flag) {
$flag = ltrim($flag, '\\');
$normalized = match (strtolower($flag)) {
'seen' => 'read',
@@ -59,7 +48,8 @@ class MessageProperties extends MessagePropertiesMutableAbstract {
}
// ── Envelope ──────────────────────────────────────────────────
if ($envelope !== null) {
if ($fetchData->envelope !== null) {
$envelope = $fetchData->envelope;
if ($envelope->messageId !== null) {
$this->data['urid'] = trim($envelope->messageId, '<>');
@@ -114,19 +104,28 @@ class MessageProperties extends MessagePropertiesMutableAbstract {
}
// ── Body Structure ────────────────────────────────────────────
if ($bodyStructure !== null) {
$rootPart = (new MessagePart())->fromImap($bodyStructure->part, '1');
if ($fetchData->bodyStructure !== null) {
$bodyStructure = $fetchData->bodyStructure;
// Root multipart containers have no fetchable section ID; their
// children are numbered "1", "2", … to match IMAP section IDs.
$isRootMultipart = $bodyStructure->part instanceof MultiPart;
$rootPartId = $isRootMultipart ? '' : '1';
$rootPart = (new MessagePart())->fromImap($bodyStructure->part, $rootPartId);
// ── Body Content: inject decoded content onto part nodes ──────
if ($bodyPart !== null) {
$rootPart->injectBodyContent($bodyPart);
if (!empty($fetchData->bodySections)) {
$sectionMap = [];
foreach ($fetchData->bodySections as $bs) {
$sectionMap[$bs->section] = $bs->text;
}
$rootPart->injectSections($sectionMap);
}
$this->data['body'] = $rootPart->toStore();
// Collect attachments: non-body parts with name or attachment disposition
$attachments = [];
self::collectAttachments($bodyStructure->part, '1', $attachments);
self::collectAttachments($bodyStructure->part, $rootPartId, $attachments);
if (!empty($attachments)) {
$this->data['attachments'] = $attachments;
}
@@ -198,7 +197,8 @@ class MessageProperties extends MessagePropertiesMutableAbstract {
}
} elseif ($part instanceof MultiPart) {
foreach ($part->parts as $index => $subPart) {
self::collectAttachments($subPart, $partId . '.' . ($index + 1), $attachments);
$subPartId = ($partId === '') ? (string)($index + 1) : $partId . '.' . ($index + 1);
self::collectAttachments($subPart, $subPartId, $attachments);
}
}
}