feat: initial version

Signed-off-by: Sebastian Krupinski <root@LAPTOP-7DVOR6NC>
This commit was merged in pull request #1.
This commit is contained in:
Sebastian Krupinski
2026-02-20 16:41:19 -05:00
committed by Sebastian Krupinski
parent a313767846
commit e51c65bf19
139 changed files with 11256 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Gricob\IMAP\Mime\Part;
use Stringable;
class Body implements Stringable
{
public function __construct(
protected string $value
) {
}
public function __toString(): string
{
return $this->value;
}
}

View File

@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace Gricob\IMAP\Mime\Part;
final readonly class Disposition
{
public function __construct(
public string $type,
public ?string $filename,
) {
}
}

View File

@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace Gricob\IMAP\Mime\Part;
use Gricob\IMAP\Client;
class LazyBody extends Body
{
public function __construct(
private Client $client,
private int $id,
private string $section,
) {
}
public function __toString(): string
{
if (!isset($this->value)) {
$this->value = $this->client->fetchSectionBody($this->id, $this->section);
}
return $this->value;
}
}

View File

@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace Gricob\IMAP\Mime\Part;
final readonly class MultiPart extends Part
{
/**
* @param array<string,string> $attributes
* @param list<Part> $parts
*/
public function __construct(
string $subtype,
array $attributes,
public array $parts,
) {
parent::__construct('multipart', $subtype, $attributes);
}
public function findPartByMimeType(string $mimeType): ?SinglePart
{
foreach ($this->parts as $part) {
if ($matchedPart = $part->findPartByMimeType(strtolower($mimeType))) {
return $matchedPart;
}
}
return null;
}
}

View File

@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace Gricob\IMAP\Mime\Part;
abstract readonly class Part
{
public string $type;
public string $subtype;
/**
* @var array<string, string>
*/
public array $attributes;
/**
* @param array<string,string> $attributes
*/
public function __construct(
string $type,
string $subtype,
array $attributes,
) {
$this->subtype = strtolower($subtype);
$this->type = strtolower($type);
$this->attributes = $attributes;
}
abstract public function findPartByMimeType(string $mimeType): ?SinglePart;
public function mimeType(): string
{
return $this->type.'/'.$this->subtype;
}
}

View File

@@ -0,0 +1,62 @@
<?php
declare(strict_types=1);
namespace Gricob\IMAP\Mime\Part;
final readonly class SinglePart extends Part
{
private string $encoding;
public function __construct(
string $type,
string $subtype,
array $attributes,
private Body $body,
private string $charset,
string $encoding,
private ?Disposition $disposition,
) {
$this->encoding = strtolower($encoding);
parent::__construct($type, $subtype, $attributes);
}
public function body(): string
{
return (string) $this->body;
}
public function decodedBody(): string
{
return match ($this->encoding) {
'quoted-printable' => quoted_printable_decode($this->body()),
'base64' => base64_decode($this->body()),
default => $this->body(),
};
}
public function charset(): string
{
return $this->charset;
}
public function encoding(): string
{
return $this->encoding;
}
public function disposition(): ?Disposition
{
return $this->disposition;
}
public function findPartByMimeType(string $mimeType): ?SinglePart
{
if ($this->mimeType() === strtolower($mimeType)) {
return $this;
}
return null;
}
}