Files
server/shared/lib/Mail/Object/MessagePropertiesBaseAbstract.php
T
2026-06-25 23:47:52 -04:00

304 lines
7.2 KiB
PHP

<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: Sebastian Krupinski <krupinski01@gmail.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace KTXF\Mail\Object;
use DateTimeImmutable;
use Exception;
use KTXF\Resource\Provider\Node\NodePropertiesBaseAbstract;
/**
* Abstract Message Properties Base Class
*
* Provides common implementation for message properties (read-only)
*
* @since 2025.05.01
*/
abstract class MessagePropertiesBaseAbstract extends NodePropertiesBaseAbstract implements MessagePropertiesBaseInterface {
protected string $type = 'mail:message';
protected function extractBodyContent(?MessagePartInterface $part, string $type): ?string {
if ($part === null) {
return null;
}
if ($part->getType() === $type) {
$content = $part->getContent();
return is_string($content) && $content !== '' ? $content : null;
}
foreach ($part->getParts() as $subPart) {
$content = $this->extractBodyContent($subPart, $type);
if ($content !== null) {
return $content;
}
}
return null;
}
protected function materializeAddress(mixed $value): ?AddressInterface {
if ($value instanceof AddressInterface) {
return $value;
}
if (is_string($value) && $value !== '') {
return Address::fromString($value);
}
if (!is_array($value) || $value === []) {
return null;
}
if (array_is_list($value)) {
return $this->materializeAddress($value[0] ?? null);
}
return Address::fromArray([
AddressInterface::PROPERTY_ADDRESS => $value[AddressInterface::PROPERTY_ADDRESS],
AddressInterface::PROPERTY_LABEL => $value[AddressInterface::PROPERTY_LABEL] ?? null,
]);
}
/**
* @return array<int,AddressInterface>
*/
protected function materializeAddresses(array $values): array {
$addresses = [];
foreach ($values as $value) {
$address = $this->materializeAddress($value);
if ($address !== null) {
$addresses[] = $address;
}
}
return $addresses;
}
protected function materializeDate(mixed $value): ?DateTimeImmutable {
if ($value instanceof DateTimeImmutable) {
return $value;
}
if (!is_string($value) || $value === '') {
return null;
}
try {
return new DateTimeImmutable($value);
} catch (Exception) {
return null;
}
}
protected function materializePart(mixed $value): ?MessagePartInterface {
if ($value instanceof MessagePartInterface) {
return $value;
}
if (!is_array($value) || $value === []) {
return null;
}
return MessagePart::fromArray($value);
}
/**
* @return array<int,MessagePartInterface>
*/
protected function materializeParts(array $values): array {
$parts = [];
foreach ($values as $value) {
$part = $this->materializePart($value);
if ($part !== null) {
$parts[] = $part;
}
}
return $parts;
}
/**
* @inheritDoc
*/
public function jsonSerialize(): array {
return $this->data;
}
/**
* @inheritDoc
*/
public function getSize(): ?int {
return $this->data[static::PROPERTY_SIZE] ?? null;
}
/**
* @inheritDoc
*/
public function getHeaders(): array {
return $this->data[static::PROPERTY_HEADERS] ?? [];
}
/**
* @inheritDoc
*/
public function getHeader(string $name): string|array|null {
return $this->data[static::PROPERTY_HEADERS][$name] ?? null;
}
/**
* @inheritDoc
*/
public function getUrid(): ?string {
return $this->data[static::PROPERTY_URID] ?? null;
}
/**
* @inheritDoc
*/
public function getInReplyTo(): ?string {
return $this->data[static::PROPERTY_IN_REPLY_TO] ?? null;
}
/**
* @inheritDoc
*/
public function getReferences(): array {
return $this->data[static::PROPERTY_REFERENCES] ?? [];
}
/**
* @inheritDoc
*/
public function getReceived(): ?DateTimeImmutable {
return $this->materializeDate($this->data[static::PROPERTY_RECEIVED] ?? null);
}
/**
* @inheritDoc
*/
public function getSent(): ?DateTimeImmutable {
return $this->materializeDate($this->data[static::PROPERTY_SENT] ?? null);
}
/**
* @inheritDoc
*/
public function getSender(): ?AddressInterface {
return $this->materializeAddress($this->data[static::PROPERTY_SENDER] ?? null);
}
/**
* @inheritDoc
*/
public function getFrom(): ?AddressInterface {
return $this->materializeAddress($this->data[static::PROPERTY_FROM] ?? null);
}
/**
* @inheritDoc
*/
public function getReplyTo(): array {
return $this->materializeAddresses($this->data[static::PROPERTY_REPLY_TO] ?? []);
}
/**
* @inheritDoc
*/
public function getTo(): array {
return $this->materializeAddresses($this->data[static::PROPERTY_TO] ?? []);
}
/**
* @inheritDoc
*/
public function getCc(): array {
return $this->materializeAddresses($this->data[static::PROPERTY_CC] ?? []);
}
/**
* @inheritDoc
*/
public function getBcc(): array {
return $this->materializeAddresses($this->data[static::PROPERTY_BCC] ?? []);
}
/**
* @inheritDoc
*/
public function getSubject(): string {
return $this->data[static::PROPERTY_SUBJECT] ?? '';
}
/**
* @inheritDoc
*/
public function getBody(): ?MessagePartInterface {
return $this->materializePart($this->data[static::PROPERTY_BODY] ?? null);
}
/**
* @inheritDoc
*/
public function hasBody(): bool {
$body = $this->getBody();
return $this->extractBodyContent($body, 'text/plain') !== null
|| $this->extractBodyContent($body, 'text/html') !== null;
}
/**
* @inheritDoc
*/
public function getBodyTextPlain(): ?string {
return $this->extractBodyContent($this->getBody(), 'text/plain');
}
/**
* @inheritDoc
*/
public function getBodyTextHtml(): ?string {
return $this->extractBodyContent($this->getBody(), 'text/html');
}
/**
* @inheritDoc
*/
public function getAttachments(): array {
return $this->materializeParts($this->data[static::PROPERTY_ATTACHMENTS] ?? []);
}
/**
* @inheritDoc
*/
public function getFlags(): array {
return $this->data[static::PROPERTY_FLAGS] ?? [
'seen' => false,
'starred' => false,
'important' => false,
'answered' => false,
'forwarded' => false,
'draft' => false,
'deleted' => false,
'flagged' => false,
];
}
/**
* @inheritDoc
*/
public function getFlag(string $name): bool {
return $this->data[static::PROPERTY_FLAGS][$name] ?? false;
}
}