* SPDX-License-Identifier: AGPL-3.0-or-later */ namespace KTXF\Mail\Entity; use DateTimeImmutable; /** * Mail Message Implementation * * Concrete implementation of IMessageMutable for composing mail messages. * * @since 2025.05.01 */ class Message implements IMessageMutable { private ?string $id = null; private string $subject = ''; private ?IAddress $from = null; private ?IAddress $replyTo = null; /** @var array */ private array $to = []; /** @var array */ private array $cc = []; /** @var array */ private array $bcc = []; private ?DateTimeImmutable $date = null; private ?string $bodyText = null; private ?string $bodyHtml = null; /** @var array */ private array $attachments = []; /** @var array */ private array $headers = []; /** * Creates a message from array data * * @since 2025.05.01 * * @param array $data * * @return self */ public static function fromArray(array $data): self { $message = new self(); if (isset($data[self::JSON_PROPERTY_ID])) { $message->setId($data[self::JSON_PROPERTY_ID]); } if (isset($data[self::JSON_PROPERTY_SUBJECT])) { $message->setSubject($data[self::JSON_PROPERTY_SUBJECT]); } if (isset($data[self::JSON_PROPERTY_FROM])) { $message->setFrom(Address::fromArray($data[self::JSON_PROPERTY_FROM])); } if (isset($data[self::JSON_PROPERTY_REPLY_TO])) { $message->setReplyTo(Address::fromArray($data[self::JSON_PROPERTY_REPLY_TO])); } if (isset($data[self::JSON_PROPERTY_TO])) { $message->setTo(array_map(fn($a) => Address::fromArray($a), $data[self::JSON_PROPERTY_TO])); } if (isset($data[self::JSON_PROPERTY_CC])) { $message->setCc(array_map(fn($a) => Address::fromArray($a), $data[self::JSON_PROPERTY_CC])); } if (isset($data[self::JSON_PROPERTY_BCC])) { $message->setBcc(array_map(fn($a) => Address::fromArray($a), $data[self::JSON_PROPERTY_BCC])); } if (isset($data[self::JSON_PROPERTY_DATE])) { $message->setDate(new DateTimeImmutable($data[self::JSON_PROPERTY_DATE])); } if (isset($data[self::JSON_PROPERTY_BODY_TEXT])) { $message->setBodyText($data[self::JSON_PROPERTY_BODY_TEXT]); } if (isset($data[self::JSON_PROPERTY_BODY_HTML])) { $message->setBodyHtml($data[self::JSON_PROPERTY_BODY_HTML]); } if (isset($data[self::JSON_PROPERTY_ATTACHMENTS])) { $message->setAttachments(array_map(fn($a) => Attachment::fromArray($a), $data[self::JSON_PROPERTY_ATTACHMENTS])); } if (isset($data[self::JSON_PROPERTY_HEADERS])) { $message->setHeaders($data[self::JSON_PROPERTY_HEADERS]); } return $message; } /** * @inheritDoc */ public function getId(): ?string { return $this->id; } /** * @inheritDoc */ public function setId(?string $id): self { $this->id = $id; return $this; } /** * @inheritDoc */ public function getSubject(): string { return $this->subject; } /** * @inheritDoc */ public function setSubject(string $subject): self { $this->subject = $subject; return $this; } /** * @inheritDoc */ public function getFrom(): ?IAddress { return $this->from; } /** * @inheritDoc */ public function setFrom(?IAddress $from): self { $this->from = $from; return $this; } /** * @inheritDoc */ public function getReplyTo(): ?IAddress { return $this->replyTo; } /** * @inheritDoc */ public function setReplyTo(?IAddress $replyTo): self { $this->replyTo = $replyTo; return $this; } /** * @inheritDoc */ public function getTo(): array { return $this->to; } /** * @inheritDoc */ public function setTo(array $to): self { $this->to = $to; return $this; } /** * @inheritDoc */ public function addTo(IAddress $address): self { $this->to[] = $address; return $this; } /** * @inheritDoc */ public function getCc(): array { return $this->cc; } /** * @inheritDoc */ public function setCc(array $cc): self { $this->cc = $cc; return $this; } /** * @inheritDoc */ public function addCc(IAddress $address): self { $this->cc[] = $address; return $this; } /** * @inheritDoc */ public function getBcc(): array { return $this->bcc; } /** * @inheritDoc */ public function setBcc(array $bcc): self { $this->bcc = $bcc; return $this; } /** * @inheritDoc */ public function addBcc(IAddress $address): self { $this->bcc[] = $address; return $this; } /** * @inheritDoc */ public function getDate(): ?DateTimeImmutable { return $this->date; } /** * @inheritDoc */ public function setDate(?DateTimeImmutable $date): self { $this->date = $date; return $this; } /** * @inheritDoc */ public function getBodyText(): ?string { return $this->bodyText; } /** * @inheritDoc */ public function setBodyText(?string $text): self { $this->bodyText = $text; return $this; } /** * @inheritDoc */ public function getBodyHtml(): ?string { return $this->bodyHtml; } /** * @inheritDoc */ public function setBodyHtml(?string $html): self { $this->bodyHtml = $html; return $this; } /** * @inheritDoc */ public function getAttachments(): array { return $this->attachments; } /** * @inheritDoc */ public function setAttachments(array $attachments): self { $this->attachments = $attachments; return $this; } /** * @inheritDoc */ public function addAttachment(IAttachment $attachment): self { $this->attachments[] = $attachment; return $this; } /** * @inheritDoc */ public function getHeaders(): array { return $this->headers; } /** * @inheritDoc */ public function getHeader(string $name): ?string { return $this->headers[$name] ?? null; } /** * @inheritDoc */ public function setHeaders(array $headers): self { $this->headers = $headers; return $this; } /** * @inheritDoc */ public function setHeader(string $name, string $value): self { $this->headers[$name] = $value; return $this; } /** * @inheritDoc */ public function hasRecipients(): bool { return !empty($this->to) || !empty($this->cc) || !empty($this->bcc); } /** * @inheritDoc */ public function hasBody(): bool { return ($this->bodyText !== null && $this->bodyText !== '') || ($this->bodyHtml !== null && $this->bodyHtml !== ''); } /** * @inheritDoc */ public function jsonSerialize(): array { $data = [ self::JSON_PROPERTY_TYPE => self::JSON_TYPE, ]; if ($this->id !== null) { $data[self::JSON_PROPERTY_ID] = $this->id; } $data[self::JSON_PROPERTY_SUBJECT] = $this->subject; if ($this->from !== null) { $data[self::JSON_PROPERTY_FROM] = $this->from; } if ($this->replyTo !== null) { $data[self::JSON_PROPERTY_REPLY_TO] = $this->replyTo; } if (!empty($this->to)) { $data[self::JSON_PROPERTY_TO] = $this->to; } if (!empty($this->cc)) { $data[self::JSON_PROPERTY_CC] = $this->cc; } if (!empty($this->bcc)) { $data[self::JSON_PROPERTY_BCC] = $this->bcc; } if ($this->date !== null) { $data[self::JSON_PROPERTY_DATE] = $this->date->format('c'); } if ($this->bodyText !== null) { $data[self::JSON_PROPERTY_BODY_TEXT] = $this->bodyText; } if ($this->bodyHtml !== null) { $data[self::JSON_PROPERTY_BODY_HTML] = $this->bodyHtml; } if (!empty($this->attachments)) { $data[self::JSON_PROPERTY_ATTACHMENTS] = $this->attachments; } if (!empty($this->headers)) { $data[self::JSON_PROPERTY_HEADERS] = $this->headers; } return $data; } }