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

335 lines
8.9 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 DateTimeInterface;
/**
* Abstract Message Properties Mutable Class
*
* Provides common implementation for mutable message properties
*
* @since 2025.05.01
*/
abstract class MessagePropertiesMutableAbstract extends MessagePropertiesBaseAbstract implements MessagePropertiesMutableInterface {
protected string $type = 'mail.message';
/**
* @param array<int,AddressInterface> $values
*
* @return array<int,array<string,string|null>>
*/
protected function normalizeAddresses(array $values): array {
return array_map(
static fn(AddressInterface $value): array => $value->toArray(),
$values,
);
}
protected function normalizeDate(?DateTimeImmutable $value): ?string {
return $value?->format(DATE_ATOM);
}
/**
* @param array<int,MessagePartInterface> $values
*
* @return array<int,array<string,mixed>>
*/
protected function normalizeParts(array $values): array {
return array_map(
static fn(MessagePartInterface $value): array => $value->jsonSerialize(),
$values,
);
}
protected function buildBodyPartFromContent(?string $textPlain, ?string $textHtml): ?MessagePart {
$hasTextPlain = is_string($textPlain) && $textPlain !== '';
$hasTextHtml = is_string($textHtml) && $textHtml !== '';
if (!$hasTextPlain && !$hasTextHtml) {
return null;
}
if ($hasTextPlain && $hasTextHtml) {
return MessagePart::fromArray([
'partId' => 'body',
'type' => 'multipart/alternative',
'subParts' => [
[
'partId' => 'body.text',
'type' => 'text/plain',
'charset' => 'utf-8',
'content' => $textPlain,
'disposition' => 'inline',
],
[
'partId' => 'body.html',
'type' => 'text/html',
'charset' => 'utf-8',
'content' => $textHtml,
'disposition' => 'inline',
],
],
]);
}
return MessagePart::fromArray([
'partId' => 'body',
'type' => $hasTextHtml ? 'text/html' : 'text/plain',
'charset' => 'utf-8',
'content' => $hasTextHtml ? $textHtml : $textPlain,
'disposition' => 'inline',
]);
}
protected function updateBodyContent(string $type, ?string $value): static {
$currentPlain = $this->getBodyTextPlain();
$currentHtml = $this->getBodyTextHtml();
if ($type === 'text/plain') {
$currentPlain = $value;
} else {
$currentHtml = $value;
}
$this->data[static::PROPERTY_BODY] = $this->buildBodyPartFromContent($currentPlain, $currentHtml)?->jsonSerialize();
return $this;
}
/**
* @inheritDoc
*/
public function jsonDeserialize(array|string $data): static {
if (is_string($data)) {
$data = json_decode($data, true);
}
// Merge deserialized data into internal storage
foreach ($data as $key => $value) {
if (!in_array($key, ['collection', 'identifier', 'signature', 'created', 'modified'])) {
$this->data[$key] = $value;
}
}
return $this;
}
/**
* @inheritDoc
*/
public function setSize(?int $value): static {
$this->data[static::PROPERTY_SIZE] = $value;
return $this;
}
/**
* @inheritDoc
*/
public function setHeaders(array $value): static {
$this->data[static::PROPERTY_HEADERS] = $value;
return $this;
}
/**
* @inheritDoc
*/
public function setHeader(string $name, string|array $value): static {
$this->data[static::PROPERTY_HEADERS][$name] = $value;
return $this;
}
/**
* @inheritDoc
*/
public function setUrid(?string $value): static {
$this->data[static::PROPERTY_URID] = $value;
return $this;
}
/**
* @inheritDoc
*/
public function setInReplyTo(?string $value): static {
$this->data[static::PROPERTY_IN_REPLY_TO] = $value;
return $this;
}
/**
* @inheritDoc
*/
public function setReferences(string ...$value): static {
$this->data[static::PROPERTY_REFERENCES] = $value;
return $this;
}
/**
* @inheritDoc
*/
public function setReceived(?DateTimeInterface $value): static {
$this->data[static::PROPERTY_RECEIVED] = $this->normalizeDate($value);
return $this;
}
/**
* @inheritDoc
*/
public function setSent(?DateTimeInterface $value): static {
$this->data[static::PROPERTY_SENT] = $this->normalizeDate($value);
return $this;
}
/**
* @inheritDoc
*/
public function setSender(?AddressInterface $value): static {
$this->data[static::PROPERTY_SENDER] = $value?->toArray();
return $this;
}
/**
* @inheritDoc
*/
public function setFrom(AddressInterface $value): static {
$this->data[static::PROPERTY_FROM] = $value->toArray();
return $this;
}
/**
* @inheritDoc
*/
public function setReplyTo(AddressInterface ...$value): static {
$this->data[static::PROPERTY_REPLY_TO] = $this->normalizeAddresses($value);
return $this;
}
/**
* @inheritDoc
*/
public function setTo(AddressInterface ...$value): static {
$this->data[static::PROPERTY_TO] = $this->normalizeAddresses($value);
return $this;
}
/**
* @inheritDoc
*/
public function setCc(AddressInterface ...$value): static {
$this->data[static::PROPERTY_CC] = $this->normalizeAddresses($value);
return $this;
}
/**
* @inheritDoc
*/
public function setBcc(AddressInterface ...$value): static {
$this->data[static::PROPERTY_BCC] = $this->normalizeAddresses($value);
return $this;
}
/**
* @inheritDoc
*/
public function setSubject(string $value): static {
$this->data[static::PROPERTY_SUBJECT] = $value;
return $this;
}
/**
* @inheritDoc
*/
public function setBody(?MessagePartInterface $value): static {
$this->data[static::PROPERTY_BODY] = $value?->jsonSerialize();
return $this;
}
/**
* @inheritDoc
*/
public function setBodyTextPlain(?string $value): static {
return $this->updateBodyContent('text/plain', $value);
}
/**
* @inheritDoc
*/
public function setBodyTextHtml(?string $value): static {
return $this->updateBodyContent('text/html', $value);
}
/**
* @inheritDoc
*/
public function setAttachments(\KTXF\Mail\Object\MessagePartInterface ...$value): static {
$this->data[static::PROPERTY_ATTACHMENTS] = $this->normalizeParts($value);
return $this;
}
/**
* @inheritDoc
*/
public function addAttachment(\KTXF\Mail\Object\MessagePartInterface $value): static {
$this->data[static::PROPERTY_ATTACHMENTS][] = $value->jsonSerialize();
return $this;
}
/**
* Sets message flags
*
* @since 2025.05.01
*
* @param array $value
*
* @return static
*/
public function setFlags(array $value): static {
if (!isset($this->data[static::PROPERTY_FLAGS])) {
$this->data[static::PROPERTY_FLAGS] = [
'seen' => false,
'starred' => false,
'important' => false,
'answered' => false,
'forwarded' => false,
'draft' => false,
'deleted' => false,
'flagged' => false,
];
}
$this->data[static::PROPERTY_FLAGS] = array_merge($this->data[static::PROPERTY_FLAGS], $value);
return $this;
}
/**
* @inheritDoc
*/
public function setFlag(string $name, bool $value): static {
if (!isset($this->data[static::PROPERTY_FLAGS])) {
$this->data[static::PROPERTY_FLAGS] = [
'seen' => false,
'starred' => false,
'important' => false,
'answered' => false,
'forwarded' => false,
'draft' => false,
'deleted' => false,
'flagged' => false,
];
}
if (array_key_exists($name, $this->data[static::PROPERTY_FLAGS])) {
$this->data[static::PROPERTY_FLAGS][$name] = $value;
}
return $this;
}
}