aboutsummaryrefslogtreecommitdiffstats
path: root/lib/public/Mail
diff options
context:
space:
mode:
Diffstat (limited to 'lib/public/Mail')
-rw-r--r--lib/public/Mail/Events/BeforeMessageSent.php39
-rw-r--r--lib/public/Mail/Headers/AutoSubmitted.php57
-rw-r--r--lib/public/Mail/IAttachment.php37
-rw-r--r--lib/public/Mail/IEMailTemplate.php154
-rw-r--r--lib/public/Mail/IMailer.php85
-rw-r--r--lib/public/Mail/IMessage.php129
-rw-r--r--lib/public/Mail/Provider/Address.php85
-rw-r--r--lib/public/Mail/Provider/Attachment.php139
-rw-r--r--lib/public/Mail/Provider/Exception/Exception.php18
-rw-r--r--lib/public/Mail/Provider/Exception/SendException.php18
-rw-r--r--lib/public/Mail/Provider/IAddress.php61
-rw-r--r--lib/public/Mail/Provider/IAttachment.php101
-rw-r--r--lib/public/Mail/Provider/IManager.php106
-rw-r--r--lib/public/Mail/Provider/IMessage.php232
-rw-r--r--lib/public/Mail/Provider/IMessageSend.php33
-rw-r--r--lib/public/Mail/Provider/IProvider.php94
-rw-r--r--lib/public/Mail/Provider/IService.php119
-rw-r--r--lib/public/Mail/Provider/Message.php338
18 files changed, 1845 insertions, 0 deletions
diff --git a/lib/public/Mail/Events/BeforeMessageSent.php b/lib/public/Mail/Events/BeforeMessageSent.php
new file mode 100644
index 00000000000..f528bd11409
--- /dev/null
+++ b/lib/public/Mail/Events/BeforeMessageSent.php
@@ -0,0 +1,39 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Events;
+
+use OCP\EventDispatcher\Event;
+use OCP\Mail\IMessage;
+
+/**
+ * Emitted before a system mail is sent. It can be used to alter the message.
+ *
+ * @since 19.0.0
+ */
+class BeforeMessageSent extends Event {
+ /** @var IMessage */
+ private $message;
+
+ /**
+ * @param IMessage $message
+ * @since 19.0.0
+ */
+ public function __construct(IMessage $message) {
+ parent::__construct();
+ $this->message = $message;
+ }
+
+ /**
+ * @return IMessage
+ * @since 19.0.0
+ */
+ public function getMessage(): IMessage {
+ return $this->message;
+ }
+}
diff --git a/lib/public/Mail/Headers/AutoSubmitted.php b/lib/public/Mail/Headers/AutoSubmitted.php
new file mode 100644
index 00000000000..1191628d401
--- /dev/null
+++ b/lib/public/Mail/Headers/AutoSubmitted.php
@@ -0,0 +1,57 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Headers;
+
+/**
+ * Keyword values for the Auto-Submitted email header, as per RFC 3834.
+ *
+ * The value "auto-notified" as per RFC 5436 is deliberately omitted as it is
+ * meant of notification of the sieve system.
+ *
+ * @link https://www.iana.org/assignments/auto-submitted-keywords/auto-submitted-keywords.xhtml
+ *
+ * @since 26.0.0
+ */
+final class AutoSubmitted {
+ /**
+ * Name of the Header as used in the final message later
+ *
+ * @var string
+ * @since 26.0.0
+ */
+ public const HEADER = 'Auto-Submitted';
+
+ /**
+ * Indicates that a message was NOT automatically generated, but was
+ * created by a human (or following human interaction). It is the equivalent
+ * to the absence of an Auto-Submitted header altogether.
+ *
+ * @var string
+ * @since 26.0.0
+ */
+ public const VALUE_NO = 'no';
+
+ /**
+ * Indicates that a message was generated by an automatic process, and is
+ * not a direct response to another message
+ *
+ * @var string
+ * @since 26.0.0
+ */
+ public const VALUE_AUTO_GENERATED = 'auto-generated';
+
+ /**
+ * Indicates that a message was automatically generated as a direct response
+ * to another message.
+ *
+ * @var string
+ * @since 26.0.0
+ */
+ public const VALUE_AUTO_REPLIED = 'auto-replied';
+}
diff --git a/lib/public/Mail/IAttachment.php b/lib/public/Mail/IAttachment.php
new file mode 100644
index 00000000000..f58a5771cc2
--- /dev/null
+++ b/lib/public/Mail/IAttachment.php
@@ -0,0 +1,37 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail;
+
+/**
+ * Interface IAttachment
+ *
+ * @since 13.0.0
+ */
+interface IAttachment {
+ /**
+ * @param string $filename
+ * @return IAttachment
+ * @since 13.0.0
+ */
+ public function setFilename(string $filename): IAttachment;
+
+ /**
+ * @param string $contentType
+ * @return IAttachment
+ * @since 13.0.0
+ */
+ public function setContentType(string $contentType): IAttachment;
+
+ /**
+ * @param string $body
+ * @return IAttachment
+ * @since 13.0.0
+ */
+ public function setBody(string $body): IAttachment;
+}
diff --git a/lib/public/Mail/IEMailTemplate.php b/lib/public/Mail/IEMailTemplate.php
new file mode 100644
index 00000000000..66379abd8ae
--- /dev/null
+++ b/lib/public/Mail/IEMailTemplate.php
@@ -0,0 +1,154 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail;
+
+/**
+ * Interface IEMailTemplate
+ *
+ * Interface to a class that allows to build HTML emails
+ *
+ * Example:
+ *
+ * <?php
+ *
+ * $emailTemplate = new EMailTemplate($this->defaults, $this->urlGenerator, $this->l10n);
+ *
+ * $emailTemplate->addHeader();
+ * $emailTemplate->addHeading('Welcome aboard');
+ * $emailTemplate->addBodyText('Welcome to your Nextcloud account, you can add, protect, and share your data.');
+ *
+ * $emailTemplate->addBodyButtonGroup(
+ * 'Set your password', 'https://example.org/resetPassword/q1234567890qwertz',
+ * 'Install Client', 'https://nextcloud.com/install/#install-clients'
+ * );
+ *
+ * $emailTemplate->addFooter('Optional footer text');
+ *
+ * $htmlContent = $emailTemplate->renderHtml();
+ * $plainContent = $emailTemplate->renderText();
+ *
+ * @since 12.0.0
+ */
+interface IEMailTemplate {
+ /**
+ * Sets the subject of the email
+ *
+ * @param string $subject
+ *
+ * @since 13.0.0
+ */
+ public function setSubject(string $subject);
+
+ /**
+ * Adds a header to the email
+ *
+ * @since 12.0.0
+ */
+ public function addHeader();
+
+ /**
+ * Adds a heading to the email
+ *
+ * @param string $title
+ * @param string|bool $plainTitle Title that is used in the plain text email
+ * if empty the $title is used, if false none will be used
+ *
+ * @since 12.0.0
+ */
+ public function addHeading(string $title, $plainTitle = '');
+
+ /**
+ * Adds a paragraph to the body of the email
+ *
+ * @param string $text; Note: When $plainText falls back to this, HTML is automatically escaped in the HTML email
+ * @param string|bool $plainText Text that is used in the plain text email
+ * if empty the $text is used, if false none will be used
+ *
+ * @since 12.0.0
+ */
+ public function addBodyText(string $text, $plainText = '');
+
+ /**
+ * Adds a list item to the body of the email
+ *
+ * @param string $text; Note: When $plainText falls back to this, HTML is automatically escaped in the HTML email
+ * @param string $metaInfo; Note: When $plainMetaInfo falls back to this, HTML is automatically escaped in the HTML email
+ * @param string $icon Absolute path, must be 16*16 pixels
+ * @param string|bool $plainText Text that is used in the plain text email
+ * if empty the $text is used, if false none will be used
+ * @param string|bool $plainMetaInfo Meta info that is used in the plain text email
+ * if empty the $metaInfo is used, if false none will be used
+ * @param integer plainIndent If > 0, Indent plainText by this amount.
+ * @since 12.0.0
+ */
+ public function addBodyListItem(string $text, string $metaInfo = '', string $icon = '', $plainText = '', $plainMetaInfo = '', $plainIndent = 0);
+
+ /**
+ * Adds a button group of two buttons to the body of the email
+ *
+ * @param string $textLeft Text of left button; Note: When $plainTextLeft falls back to this, HTML is automatically escaped in the HTML email
+ * @param string $urlLeft URL of left button
+ * @param string $textRight Text of right button; Note: When $plainTextRight falls back to this, HTML is automatically escaped in the HTML email
+ * @param string $urlRight URL of right button
+ * @param string $plainTextLeft Text of left button that is used in the plain text version - if empty the $textLeft is used
+ * @param string $plainTextRight Text of right button that is used in the plain text version - if empty the $textRight is used
+ *
+ * @since 12.0.0
+ */
+ public function addBodyButtonGroup(string $textLeft, string $urlLeft, string $textRight, string $urlRight, string $plainTextLeft = '', string $plainTextRight = '');
+
+ /**
+ * Adds a button to the body of the email
+ *
+ * @param string $text Text of button; Note: When $plainText falls back to this, HTML is automatically escaped in the HTML email
+ * @param string $url URL of button
+ * @param string|false $plainText Text of button in plain text version
+ * if empty the $text is used, if false none will be used
+ *
+ * @since 12.0.0
+ */
+ public function addBodyButton(string $text, string $url, $plainText = '');
+
+ /**
+ * Adds a logo and a text to the footer. <br> in the text will be replaced by new lines in the plain text email
+ *
+ * @param string $text If the text is empty the default "Name - Slogan<br>This is an automatically sent email" will be used
+ * @param string $lang Optional language to set the default footer in
+ *
+ * @since 12.0.0
+ */
+ public function addFooter(string $text = '', ?string $lang = null);
+
+ /**
+ * Returns the rendered email subject as string
+ *
+ * @return string
+ *
+ * @since 13.0.0
+ */
+ public function renderSubject(): string;
+
+ /**
+ * Returns the rendered HTML email as string
+ *
+ * @return string
+ *
+ * @since 12.0.0
+ */
+ public function renderHtml(): string;
+
+ /**
+ * Returns the rendered plain text email as string
+ *
+ * @return string
+ *
+ * @since 12.0.0
+ */
+ public function renderText(): string;
+}
diff --git a/lib/public/Mail/IMailer.php b/lib/public/Mail/IMailer.php
new file mode 100644
index 00000000000..277f7863184
--- /dev/null
+++ b/lib/public/Mail/IMailer.php
@@ -0,0 +1,85 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+namespace OCP\Mail;
+
+/**
+ * Class IMailer provides some basic functions to create a mail message that can be used in combination with
+ * \OC\Mail\Message.
+ *
+ * Example usage:
+ *
+ * $mailer = \OCP\Server::get(\OCP\Mail\IMailer::class);
+ * $message = $mailer->createMessage();
+ * $message->setSubject('Your Subject');
+ * $message->setFrom(['cloud@domain.org' => 'Nextcloud Notifier']);
+ * $message->setTo(['recipient@domain.org' => 'Recipient']);
+ * $message->setPlainBody('The message text');
+ * $message->setHtmlBody('The <strong>message</strong> text');
+ * $mailer->send($message);
+ *
+ * This message can then be passed to send() of \OC\Mail\Mailer
+ *
+ * @since 8.1.0
+ */
+interface IMailer {
+ /**
+ * Creates a new message object that can be passed to send()
+ *
+ * @return IMessage
+ * @since 8.1.0
+ */
+ public function createMessage(): IMessage;
+
+ /**
+ * @param string|null $data
+ * @param string|null $filename
+ * @param string|null $contentType
+ * @return IAttachment
+ * @since 13.0.0
+ */
+ public function createAttachment($data = null, $filename = null, $contentType = null): IAttachment;
+
+ /**
+ * @param string $path
+ * @param string|null $contentType
+ * @return IAttachment
+ * @since 13.0.0
+ */
+ public function createAttachmentFromPath(string $path, $contentType = null): IAttachment;
+
+ /**
+ * Creates a new email template object
+ *
+ * @param string $emailId
+ * @param array $data
+ * @return IEMailTemplate
+ * @since 12.0.0 Parameters added in 12.0.3
+ */
+ public function createEMailTemplate(string $emailId, array $data = []): IEMailTemplate;
+
+ /**
+ * Send the specified message. Also sets the from address to the value defined in config.php
+ * if no-one has been passed.
+ *
+ * @param IMessage $message Message to send
+ * @return string[] Array with failed recipients. Be aware that this depends on the used mail backend and
+ * therefore should be considered
+ * @throws \Exception In case it was not possible to send the message. (for example if an invalid mail address
+ * has been supplied.)
+ * @since 8.1.0
+ */
+ public function send(IMessage $message): array;
+
+ /**
+ * @param string $email Email address to be validated
+ * @return bool True if the mail address is valid, false otherwise
+ * @since 8.1.0
+ */
+ public function validateMailAddress(string $email): bool;
+}
diff --git a/lib/public/Mail/IMessage.php b/lib/public/Mail/IMessage.php
new file mode 100644
index 00000000000..c3d1d047478
--- /dev/null
+++ b/lib/public/Mail/IMessage.php
@@ -0,0 +1,129 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail;
+
+/**
+ * Interface IMessage
+ *
+ * @since 13.0.0
+ */
+interface IMessage {
+ /**
+ * Set the subject of this message
+ *
+ * @param string $subject
+ *
+ * @return self
+ * @since 28.0.0
+ */
+ public function setSubject(string $subject): IMessage;
+
+ /**
+ * Set the plain-text body of this message
+ *
+ * @param string $body
+ *
+ * @return self
+ * @since 28.0.0
+ */
+ public function setPlainBody(string $body): IMessage;
+
+ /**
+ * Set the HTML body of this message. Consider also sending a plain-text body instead of only an HTML one.
+ *
+ * @param string $body
+ *
+ * @return self
+ * @since 28.0.0
+ */
+ public function setHtmlBody(string $body): IMessage;
+
+ /**
+ * @param IAttachment $attachment
+ * @return IMessage
+ * @since 13.0.0
+ */
+ public function attach(IAttachment $attachment): IMessage;
+
+ /**
+ * Can be used to "attach content inline" as message parts with specific MIME type and encoding.
+ *
+ * @param string $body body of the MIME part
+ * @param string $name the file name
+ * @param string|null $contentType MIME Content-Type (e.g. text/plain or text/calendar)
+ *
+ * @return IMessage
+ * @since 27.0.0
+ */
+ public function attachInline(string $body, string $name, ?string $contentType = null): IMessage;
+
+ /**
+ * Set the from address of this message.
+ *
+ * If no "From" address is used \OC\Mail\Mailer will use mail_from_address and mail_domain from config.php
+ *
+ * @param array $addresses Example: array('sender@domain.org', 'other@domain.org' => 'A name')
+ * @return IMessage
+ * @since 13.0.0
+ */
+ public function setFrom(array $addresses): IMessage;
+
+ /**
+ * Set the Reply-To address of this message
+ *
+ * @param array $addresses
+ * @return IMessage
+ * @since 13.0.0
+ */
+ public function setReplyTo(array $addresses): IMessage;
+
+ /**
+ * Set the to addresses of this message.
+ *
+ * @param array $recipients Example: array('recipient@domain.org', 'other@domain.org' => 'A name')
+ * @return IMessage
+ * @since 13.0.0
+ */
+ public function setTo(array $recipients): IMessage;
+
+ /**
+ * Set the CC recipients of this message.
+ *
+ * @param array $recipients Example: array('recipient@domain.org', 'other@domain.org' => 'A name')
+ * @return IMessage
+ * @since 13.0.0
+ */
+ public function setCc(array $recipients): IMessage;
+
+ /**
+ * Set the BCC recipients of this message.
+ *
+ * @param array $recipients Example: array('recipient@domain.org', 'other@domain.org' => 'A name')
+ * @return IMessage
+ * @since 13.0.0
+ */
+ public function setBcc(array $recipients): IMessage;
+
+ /**
+ * @param IEMailTemplate $emailTemplate
+ * @return IMessage
+ * @since 13.0.0
+ */
+ public function useTemplate(IEMailTemplate $emailTemplate): IMessage;
+
+ /**
+ * Add the Auto-Submitted header to the email, preventing most automated
+ * responses to automated messages.
+ *
+ * @param Headers\AutoSubmitted::VALUE_* $value (one of AutoSubmitted::VALUE_NO, AutoSubmitted::VALUE_AUTO_GENERATED, AutoSubmitted::VALUE_AUTO_REPLIED)
+ * @return IMessage
+ * @since 26.0.0
+ */
+ public function setAutoSubmitted(string $value): IMessage;
+}
diff --git a/lib/public/Mail/Provider/Address.php b/lib/public/Mail/Provider/Address.php
new file mode 100644
index 00000000000..751fb99d930
--- /dev/null
+++ b/lib/public/Mail/Provider/Address.php
@@ -0,0 +1,85 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider;
+
+/**
+ * Mail Address Object
+ *
+ * This object is used to define the address and label of a email address
+ *
+ * @since 30.0.0
+ *
+ */
+class Address implements \OCP\Mail\Provider\IAddress {
+
+ /**
+ * initialize the mail address object
+ *
+ * @since 30.0.0
+ *
+ * @param string|null $address mail address (e.g test@example.com)
+ * @param string|null $label mail address label/name
+ */
+ public function __construct(
+ protected ?string $address = null,
+ protected ?string $label = null,
+ ) {
+ }
+
+ /**
+ * sets the mail address
+ *
+ * @since 30.0.0
+ *
+ * @param string $value mail address (e.g. test@example.com)
+ *
+ * @return self return this object for command chaining
+ */
+ public function setAddress(string $value): self {
+ $this->address = $value;
+ return $this;
+ }
+
+ /**
+ * gets the mail address
+ *
+ * @since 30.0.0
+ *
+ * @return string|null returns the mail address or null if one is not set
+ */
+ public function getAddress(): ?string {
+ return $this->address;
+ }
+
+ /**
+ * sets the mail address label/name
+ *
+ * @since 30.0.0
+ *
+ * @param string $value mail address label/name
+ *
+ * @return self return this object for command chaining
+ */
+ public function setLabel(string $value): self {
+ $this->label = $value;
+ return $this;
+ }
+
+ /**
+ * gets the mail address label/name
+ *
+ * @since 30.0.0
+ *
+ * @return string|null returns the mail address label/name or null if one is not set
+ */
+ public function getLabel(): ?string {
+ return $this->label;
+ }
+
+}
diff --git a/lib/public/Mail/Provider/Attachment.php b/lib/public/Mail/Provider/Attachment.php
new file mode 100644
index 00000000000..af7340a3ccf
--- /dev/null
+++ b/lib/public/Mail/Provider/Attachment.php
@@ -0,0 +1,139 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider;
+
+/**
+ * Mail Attachment Object
+ *
+ * This object is used to define the parameters of a mail attachment
+ *
+ * @since 30.0.0
+ *
+ */
+class Attachment implements \OCP\Mail\Provider\IAttachment {
+
+ /**
+ * initialize the mail attachment object
+ *
+ * @since 30.0.0
+ *
+ * @param string|null $contents binary contents of file
+ * @param string|null $name file name (e.g example.txt)
+ * @param string|null $type mime type (e.g. text/plain)
+ * @param bool $embedded embedded status of the attachment, default is false
+ */
+ public function __construct(
+ protected ?string $contents,
+ protected ?string $name,
+ protected ?string $type,
+ protected bool $embedded = false,
+ ) {
+ }
+
+ /**
+ * sets the attachment file name
+ *
+ * @since 30.0.0
+ *
+ * @param string $value file name (e.g example.txt)
+ *
+ * @return self return this object for command chaining
+ */
+ public function setName(string $value): self {
+ $this->name = $value;
+ return $this;
+ }
+
+ /**
+ * gets the attachment file name
+ *
+ * @since 30.0.0
+ *
+ * @return string | null returns the attachment file name or null if not set
+ */
+ public function getName(): ?string {
+ return $this->name;
+ }
+
+ /**
+ * sets the attachment mime type
+ *
+ * @since 30.0.0
+ *
+ * @param string $value mime type (e.g. text/plain)
+ *
+ * @return self return this object for command chaining
+ */
+ public function setType(string $value): self {
+ $this->type = $value;
+ return $this;
+ }
+
+ /**
+ * gets the attachment mime type
+ *
+ * @since 30.0.0
+ *
+ * @return string | null returns the attachment mime type or null if not set
+ */
+ public function getType(): ?string {
+ return $this->type;
+ }
+
+ /**
+ * sets the attachment contents (actual data)
+ *
+ * @since 30.0.0
+ *
+ * @param string $value binary contents of file
+ *
+ * @return self return this object for command chaining
+ */
+ public function setContents(string $value): self {
+ $this->contents = $value;
+ return $this;
+ }
+
+ /**
+ * gets the attachment contents (actual data)
+ *
+ * @since 30.0.0
+ *
+ * @return string | null returns the attachment contents or null if not set
+ */
+ public function getContents(): ?string {
+ return $this->contents;
+ }
+
+ /**
+ * sets the embedded status of the attachment
+ *
+ * @since 30.0.0
+ *
+ * @param bool $value true - embedded / false - not embedded
+ *
+ * @return self return this object for command chaining
+ */
+ public function setEmbedded(bool $value): self {
+ $this->embedded = $value;
+ return $this;
+ }
+
+ /**
+ * gets the embedded status of the attachment
+ *
+ * @since 30.0.0
+ *
+ * @return bool embedded status of the attachment
+ */
+ public function getEmbedded(): bool {
+ return $this->embedded;
+ }
+
+}
diff --git a/lib/public/Mail/Provider/Exception/Exception.php b/lib/public/Mail/Provider/Exception/Exception.php
new file mode 100644
index 00000000000..7514c72a869
--- /dev/null
+++ b/lib/public/Mail/Provider/Exception/Exception.php
@@ -0,0 +1,18 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider\Exception;
+
+/**
+ * Mail Provider Base Exception
+ *
+ * @since 30.0.0
+ */
+class Exception extends \Exception {
+
+}
diff --git a/lib/public/Mail/Provider/Exception/SendException.php b/lib/public/Mail/Provider/Exception/SendException.php
new file mode 100644
index 00000000000..fba0903cbb3
--- /dev/null
+++ b/lib/public/Mail/Provider/Exception/SendException.php
@@ -0,0 +1,18 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider\Exception;
+
+/**
+ * Mail Provider Send Exception
+ *
+ * @since 30.0.0
+ */
+class SendException extends Exception {
+
+}
diff --git a/lib/public/Mail/Provider/IAddress.php b/lib/public/Mail/Provider/IAddress.php
new file mode 100644
index 00000000000..47bb9148968
--- /dev/null
+++ b/lib/public/Mail/Provider/IAddress.php
@@ -0,0 +1,61 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider;
+
+/**
+ * Mail Address Interface
+ *
+ * This interface is a base requirement of methods and functionality used to construct a mail address object
+ *
+ * @since 30.0.0
+ *
+ */
+interface IAddress {
+
+ /**
+ * sets the mail address
+ *
+ * @since 30.0.0
+ *
+ * @param string $value mail address (test@example.com)
+ *
+ * @return self return this object for command chaining
+ */
+ public function setAddress(string $value): self;
+
+ /**
+ * gets the mail address
+ *
+ * @since 30.0.0
+ *
+ * @return string returns the mail address
+ */
+ public function getAddress(): ?string;
+
+ /**
+ * sets the mail address label/name
+ *
+ * @since 30.0.0
+ *
+ * @param string $value mail address label/name
+ *
+ * @return self return this object for command chaining
+ */
+ public function setLabel(string $value): self;
+
+ /**
+ * gets the mail address label/name
+ *
+ * @since 30.0.0
+ *
+ * @return string returns the mail address label/name
+ */
+ public function getLabel(): ?string;
+
+}
diff --git a/lib/public/Mail/Provider/IAttachment.php b/lib/public/Mail/Provider/IAttachment.php
new file mode 100644
index 00000000000..ff266994919
--- /dev/null
+++ b/lib/public/Mail/Provider/IAttachment.php
@@ -0,0 +1,101 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider;
+
+/**
+ * Mail Attachment Interface
+ *
+ * This interface is used for defining individual attachments that are attached to a message
+ *
+ * @since 30.0.0
+ *
+ */
+interface IAttachment {
+
+ /**
+ * sets the attachment file name
+ *
+ * @since 30.0.0
+ *
+ * @param string $value file name (e.g example.txt)
+ *
+ * @return self return this object for command chaining
+ */
+ public function setName(string $value): self;
+
+ /**
+ * gets the attachment file name
+ *
+ * @since 30.0.0
+ *
+ * @return string | null returns the attachment file name or null if one is not set
+ */
+ public function getName(): ?string;
+
+ /**
+ * sets the attachment mime type
+ *
+ * @since 30.0.0
+ *
+ * @param string $value mime type (e.g. text/plain)
+ *
+ * @return self return this object for command chaining
+ */
+ public function setType(string $value): self;
+
+ /**
+ * gets the attachment mime type
+ *
+ * @since 30.0.0
+ *
+ * @return string | null returns the attachment mime type or null if not set
+ */
+ public function getType(): ?string;
+
+ /**
+ * sets the attachment contents (actual data)
+ *
+ * @since 30.0.0
+ *
+ * @param string $value binary contents of file
+ *
+ * @return self return this object for command chaining
+ */
+ public function setContents(string $value): self;
+
+ /**
+ * gets the attachment contents (actual data)
+ *
+ * @since 30.0.0
+ *
+ * @return string | null returns the attachment contents or null if not set
+ */
+ public function getContents(): ?string;
+
+ /**
+ * sets the embedded status of the attachment
+ *
+ * @since 30.0.0
+ *
+ * @param bool $value true - embedded / false - not embedded
+ *
+ * @return self return this object for command chaining
+ */
+ public function setEmbedded(bool $value): self;
+
+ /**
+ * gets the embedded status of the attachment
+ *
+ * @since 30.0.0
+ *
+ * @return bool embedded status of the attachment
+ */
+ public function getEmbedded(): bool;
+
+}
diff --git a/lib/public/Mail/Provider/IManager.php b/lib/public/Mail/Provider/IManager.php
new file mode 100644
index 00000000000..b55fed3f26f
--- /dev/null
+++ b/lib/public/Mail/Provider/IManager.php
@@ -0,0 +1,106 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider;
+
+/**
+ * Mail Provider Manager Interface
+ *
+ * This interface is a base requirement of methods and functionality used to construct a mail provider manager object
+ *
+ * @since 30.0.0
+ *
+ */
+interface IManager {
+
+ /**
+ * determine if any mail providers are registered
+ *
+ * @since 30.0.0
+ *
+ * @return bool
+ */
+ public function has(): bool;
+
+ /**
+ * retrieve a count of how many mail providers are registered
+ *
+ * @since 30.0.0
+ *
+ * @return int
+ */
+ public function count(): int;
+
+ /**
+ * retrieve which mail providers are registered
+ *
+ * @since 30.0.0
+ *
+ * @return array<string,String> collection of provider id and label ['jmap' => 'JMap Connector']
+ */
+ public function types(): array;
+
+ /**
+ * retrieve all registered mail providers
+ *
+ * @since 30.0.0
+ *
+ * @return array<string,IProvider> collection of provider id and object ['jmap' => IProviderObject]
+ */
+ public function providers(): array;
+
+ /**
+ * retrieve a provider with a specific id
+ *
+ * @since 30.0.0
+ *
+ * @param string $providerId provider id
+ *
+ * @return IProvider|null
+ */
+ public function findProviderById(string $providerId): ?IProvider;
+
+ /**
+ * retrieve all services for all registered mail providers
+ *
+ * @since 30.0.0
+ *
+ * @param string $userId user id
+ *
+ * @return array<string,array<string,IService>> collection of provider id, service id and object ['jmap' => ['Service1' => IServiceObject]]
+ */
+ public function services(string $userId): array;
+
+ /**
+ * retrieve a service with a specific id
+ *
+ * @since 30.0.0
+ *
+ * @param string $userId user id
+ * @param string $serviceId service id
+ * @param string $providerId provider id
+ *
+ * @return IService|null returns service object or null if none found
+ */
+ public function findServiceById(string $userId, string $serviceId, ?string $providerId = null): ?IService;
+
+ /**
+ * retrieve a service for a specific mail address
+ * returns first service with specific primary address
+ *
+ * @since 30.0.0
+ *
+ * @param string $userId user id
+ * @param string $address mail address (e.g. test@example.com)
+ * @param string $providerId provider id
+ *
+ * @return IService|null returns service object or null if none found
+ */
+ public function findServiceByAddress(string $userId, string $address, ?string $providerId = null): ?IService;
+
+}
diff --git a/lib/public/Mail/Provider/IMessage.php b/lib/public/Mail/Provider/IMessage.php
new file mode 100644
index 00000000000..599d9b0566d
--- /dev/null
+++ b/lib/public/Mail/Provider/IMessage.php
@@ -0,0 +1,232 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider;
+
+/**
+ * Mail Message Interface
+ *
+ * This interface is a base requirement of methods and functionality used to construct a mail message object
+ *
+ * @since 30.0.0
+ *
+ */
+interface IMessage {
+
+ /**
+ * arbitrary unique text string identifying this message
+ *
+ * @since 30.0.0
+ *
+ * @return string id of this message
+ */
+ public function id(): string;
+
+ /**
+ * sets the sender of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress $value sender's mail address object
+ *
+ * @return self return this object for command chaining
+ */
+ public function setFrom(IAddress $value): self;
+
+ /**
+ * gets the sender of this message
+ *
+ * @since 30.0.0
+ *
+ * @return IAddress|null sender's mail address object
+ */
+ public function getFrom(): ?IAddress;
+
+ /**
+ * sets the sender's reply to address of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress $value senders's reply to mail address object
+ *
+ * @return self return this object for command chaining
+ */
+ public function setReplyTo(IAddress $value): self;
+
+ /**
+ * gets the sender's reply to address of this message
+ *
+ * @since 30.0.0
+ *
+ * @return IAddress|null sender's reply to mail address object
+ */
+ public function getReplyTo(): ?IAddress;
+
+ /**
+ * sets the recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress ...$value collection of or one or more mail address objects
+ *
+ * @return self return this object for command chaining
+ */
+ public function setTo(IAddress ...$value): self;
+
+ /**
+ * gets the recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @return array<int,IAddress> collection of all recipient mail address objects
+ */
+ public function getTo(): array;
+
+ /**
+ * sets the copy to recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress ...$value collection of or one or more mail address objects
+ *
+ * @return self return this object for command chaining
+ */
+ public function setCc(IAddress ...$value): self;
+
+ /**
+ * gets the copy to recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @return array<int,IAddress> collection of all copied recipient mail address objects
+ */
+ public function getCc(): array;
+
+ /**
+ * sets the blind copy to recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress ...$value collection of or one or more mail address objects
+ *
+ * @return self return this object for command chaining
+ */
+ public function setBcc(IAddress ...$value): self;
+
+ /**
+ * gets the blind copy to recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @return array<int,IAddress> collection of all blind copied recipient mail address objects
+ */
+ public function getBcc(): array;
+
+ /**
+ * sets the subject of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string $value subject of mail message
+ *
+ * @return self return this object for command chaining
+ */
+ public function setSubject(string $value): self;
+
+ /**
+ * gets the subject of this message
+ *
+ * @since 30.0.0
+ *
+ * @return string|null subject of message or null if one is not set
+ */
+ public function getSubject(): ?string;
+
+ /**
+ * sets the plain text or html body of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string $value text or html body of message
+ * @param bool $html html flag - true for html
+ *
+ * @return self return this object for command chaining
+ */
+ public function setBody(string $value, bool $html): self;
+
+ /**
+ * gets either the html or plain text body of this message
+ *
+ * html body will be returned over plain text if html body exists
+ *
+ * @since 30.0.0
+ *
+ * @return string|null html/plain body of this message or null if one is not set
+ */
+ public function getBody(): ?string;
+
+ /**
+ * sets the html body of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string $value html body of message
+ *
+ * @return self return this object for command chaining
+ */
+ public function setBodyHtml(string $value): self;
+
+ /**
+ * gets the html body of this message
+ *
+ * @since 30.0.0
+ *
+ * @return string|null html body of this message or null if one is not set
+ */
+ public function getBodyHtml(): ?string;
+
+ /**
+ * sets the plain text body of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string $value plain text body of message
+ *
+ * @return self return this object for command chaining
+ */
+ public function setBodyPlain(string $value): self;
+
+ /**
+ * gets the plain text body of this message
+ *
+ * @since 30.0.0
+ *
+ * @return string|null plain text body of this message or null if one is not set
+ */
+ public function getBodyPlain(): ?string;
+
+ /**
+ * sets the attachments of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAttachment ...$value collection of or one or more mail attachment objects
+ *
+ * @return self return this object for command chaining
+ */
+ public function setAttachments(IAttachment ...$value): self;
+
+ /**
+ * gets the attachments of this message
+ *
+ * @since 30.0.0
+ *
+ * @return array<int,IAttachment> collection of all mail attachment objects
+ */
+ public function getAttachments(): array;
+}
diff --git a/lib/public/Mail/Provider/IMessageSend.php b/lib/public/Mail/Provider/IMessageSend.php
new file mode 100644
index 00000000000..fe1b2884452
--- /dev/null
+++ b/lib/public/Mail/Provider/IMessageSend.php
@@ -0,0 +1,33 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider;
+
+/**
+ * Mail Message Send Interface
+ *
+ * This interface is the required set of methods and functionality used to extend IService with message sending functionality
+ *
+ * @since 30.0.0
+ *
+ */
+interface IMessageSend {
+
+ /**
+ * send an outbound message
+ *
+ * @since 30.0.0
+ *
+ * @param IMessage $message mail message object with all required parameters to send a message
+ * @param array $options array of options reserved for future use
+ *
+ * @throws \OCP\Mail\Provider\Exception\SendException on failure, check message for reason
+ */
+ public function sendMessage(IMessage $message, array $options = []): void;
+
+}
diff --git a/lib/public/Mail/Provider/IProvider.php b/lib/public/Mail/Provider/IProvider.php
new file mode 100644
index 00000000000..d89022d7cbf
--- /dev/null
+++ b/lib/public/Mail/Provider/IProvider.php
@@ -0,0 +1,94 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider;
+
+/**
+ * Mail Provider Interface
+ *
+ * This interface is a base requirement of methods and functionality used to construct a mail provider object
+ *
+ * @since 30.0.0
+ *
+ */
+interface IProvider {
+
+ /**
+ * arbitrary unique text string identifying this provider
+ *
+ * @since 30.0.0
+ *
+ * @return string id of this provider (e.g. UUID or 'IMAP/SMTP' or anything else)
+ */
+ public function id(): string;
+
+ /**
+ * localized human friendly name of this provider
+ *
+ * @since 30.0.0
+ *
+ * @return string label/name of this provider (e.g. Plain Old IMAP/SMTP)
+ */
+ public function label(): string;
+
+ /**
+ * determine if any services are configured for a specific user
+ *
+ * @since 30.0.0
+ *
+ * @param string $userId user id
+ *
+ * @return bool true if any services are configure for the user
+ */
+ public function hasServices(string $userId): bool;
+
+ /**
+ * retrieve collection of services for a specific user
+ *
+ * @param string $userId user id
+ *
+ * @since 30.0.0
+ *
+ * @return array<string,IService> collection of service id and object ['1' => IServiceObject]
+ */
+ public function listServices(string $userId): array;
+
+ /**
+ * retrieve a service with a specific id
+ *
+ * @since 30.0.0
+ *
+ * @param string $userId user id
+ * @param string $serviceId service id
+ *
+ * @return IService|null returns service object or null if none found
+ */
+ public function findServiceById(string $userId, string $serviceId): ?IService;
+
+ /**
+ * retrieve a service for a specific mail address
+ *
+ * @since 30.0.0
+ *
+ * @param string $userId user id
+ * @param string $address mail address (e.g. test@example.com)
+ *
+ * @return IService|null returns service object or null if none found
+ */
+ public function findServiceByAddress(string $userId, string $address): ?IService;
+
+ /**
+ * construct a new empty service object
+ *
+ * @since 30.0.0
+ *
+ * @return IService blank service object
+ */
+ public function initiateService(): IService;
+
+}
diff --git a/lib/public/Mail/Provider/IService.php b/lib/public/Mail/Provider/IService.php
new file mode 100644
index 00000000000..e0bb5161aa6
--- /dev/null
+++ b/lib/public/Mail/Provider/IService.php
@@ -0,0 +1,119 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider;
+
+/**
+ * Mail Service Interface
+ *
+ * This interface is a base requirement of methods and functionality used to construct a mail service object
+ *
+ * @since 30.0.0
+ *
+ */
+interface IService {
+
+ /**
+ * arbitrary unique text string identifying this service
+ *
+ * @since 30.0.0
+ *
+ * @return string id of this service (e.g. 1 or service1 or anything else)
+ */
+ public function id(): string;
+
+ /**
+ * checks if a service is able of performing an specific action
+ *
+ * @since 30.0.0
+ *
+ * @param string $value required ability e.g. 'MessageSend'
+ *
+ * @return bool true/false if ability is supplied and found in collection
+ */
+ public function capable(string $value): bool;
+
+ /**
+ * retrieves a collection of what actions a service can perfrom
+ *
+ * @since 30.0.0
+ *
+ * @return array collection of abilities otherwise empty collection
+ */
+ public function capabilities(): array;
+
+ /**
+ * gets the localized human frendly name of this service
+ *
+ * @since 30.0.0
+ *
+ * @return string label/name of service (e.g. ACME Company Mail Service)
+ */
+ public function getLabel(): string;
+
+ /**
+ * sets the localized human frendly name of this service
+ *
+ * @since 30.0.0
+ *
+ * @param string $value label/name of service (e.g. ACME Company Mail Service)
+ *
+ * @return self return this object for command chaining
+ */
+ public function setLabel(string $value): self;
+
+ /**
+ * gets the primary mailing address for this service
+ *
+ * @since 30.0.0
+ *
+ * @return IAddress mail address object
+ */
+ public function getPrimaryAddress(): IAddress;
+
+ /**
+ * sets the primary mailing address for this service
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress $value mail address object
+ *
+ * @return self return this object for command chaining
+ */
+ public function setPrimaryAddress(IAddress $value): self;
+
+ /**
+ * gets the secondary mailing addresses (aliases) collection for this service
+ *
+ * @since 30.0.0
+ *
+ * @return array<int, IAddress> collection of mail address objects
+ */
+ public function getSecondaryAddresses(): array;
+
+ /**
+ * sets the secondary mailing addresses (aliases) for this service
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress ...$value collection of one or more mail address objects
+ *
+ * @return self return this object for command chaining
+ */
+ public function setSecondaryAddresses(IAddress ...$value): self;
+
+ /**
+ * construct a new empty message object
+ *
+ * @since 30.0.0
+ *
+ * @return IMessage blank message object
+ */
+ public function initiateMessage(): IMessage;
+
+}
diff --git a/lib/public/Mail/Provider/Message.php b/lib/public/Mail/Provider/Message.php
new file mode 100644
index 00000000000..f7a21c05ed3
--- /dev/null
+++ b/lib/public/Mail/Provider/Message.php
@@ -0,0 +1,338 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider;
+
+/**
+ * Mail Message Object
+ *
+ * This object is used to define a mail message that can be used to transfer data to a provider
+ *
+ * @since 30.0.0
+ *
+ */
+class Message implements \OCP\Mail\Provider\IMessage {
+
+ /**
+ * initialize the mail message object
+ *
+ * @since 30.0.0
+ *
+ * @param array $data message data array
+ */
+ public function __construct(
+ protected array $data = [],
+ ) {
+ }
+
+ /**
+ * arbitrary unique text string identifying this message
+ *
+ * @since 30.0.0
+ *
+ * @return string id of this message
+ */
+ public function id(): string {
+ // return id of message
+ return (isset($this->data['id'])) ? $this->data['id'] : '';
+ }
+
+ /**
+ * sets the sender of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress $value sender's mail address object
+ *
+ * @return self return this object for command chaining
+ */
+ public function setFrom(IAddress $value): self {
+ // create or update field in data store with value
+ $this->data['from'] = $value;
+ // return this object for command chaining
+ return $this;
+ }
+
+ /**
+ * gets the sender of this message
+ *
+ * @since 30.0.0
+ *
+ * @return IAddress|null sender's mail address object
+ */
+ public function getFrom(): ?IAddress {
+ // evaluate if data store field exists and return value(s) or null otherwise
+ return (isset($this->data['from'])) ? $this->data['from'] : null;
+ }
+
+ /**
+ * sets the sender's reply to address of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress $value senders's reply to mail address object
+ *
+ * @return self return this object for command chaining
+ */
+ public function setReplyTo(IAddress $value): self {
+ // create or update field in data store with value
+ $this->data['replyTo'] = $value;
+ // return this object for command chaining
+ return $this;
+ }
+
+ /**
+ * gets the sender's reply to address of this message
+ *
+ * @since 30.0.0
+ *
+ * @return IAddress|null sender's reply to mail address object
+ */
+ public function getReplyTo(): ?IAddress {
+ // evaluate if data store field exists and return value(s) or null otherwise
+ return (isset($this->data['replyTo'])) ? $this->data['replyTo'] : null;
+ }
+
+ /**
+ * sets the recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress ...$value collection of or one or more mail address objects
+ *
+ * @return self return this object for command chaining
+ */
+ public function setTo(IAddress ...$value): self {
+ // create or update field in data store with value
+ $this->data['to'] = $value;
+ // return this object for command chaining
+ return $this;
+ }
+
+ /**
+ * gets the recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @return array<int,IAddress> collection of all recipient mail address objects
+ */
+ public function getTo(): array {
+ // evaluate if data store field exists and return value(s) or empty collection
+ return (isset($this->data['to'])) ? $this->data['to'] : [];
+ }
+
+ /**
+ * sets the copy to recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress ...$value collection of or one or more mail address objects
+ *
+ * @return self return this object for command chaining
+ */
+ public function setCc(IAddress ...$value): self {
+ // create or update field in data store with value
+ $this->data['cc'] = $value;
+ // return this object for command chaining
+ return $this;
+ }
+
+ /**
+ * gets the copy to recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @return array<int,IAddress> collection of all copied recipient mail address objects
+ */
+ public function getCc(): array {
+ // evaluate if data store field exists and return value(s) or empty collection
+ return (isset($this->data['cc'])) ? $this->data['cc'] : [];
+ }
+
+ /**
+ * sets the blind copy to recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress ...$value collection of or one or more mail address objects
+ *
+ * @return self return this object for command chaining
+ */
+ public function setBcc(IAddress ...$value): self {
+ // create or update field in data store with value
+ $this->data['bcc'] = $value;
+ // return this object for command chaining
+ return $this;
+ }
+
+ /**
+ * gets the blind copy to recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @return array<int,IAddress> collection of all blind copied recipient mail address objects
+ */
+ public function getBcc(): array {
+ // evaluate if data store field exists and return value(s) or empty collection
+ return (isset($this->data['bcc'])) ? $this->data['bcc'] : [];
+ }
+
+ /**
+ * sets the subject of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string $value subject of mail message
+ *
+ * @return self return this object for command chaining
+ */
+ public function setSubject(string $value): self {
+ // create or update field in data store with value
+ $this->data['subject'] = $value;
+ // return this object for command chaining
+ return $this;
+ }
+
+ /**
+ * gets the subject of this message
+ *
+ * @since 30.0.0
+ *
+ * @return string|null subject of message or null if one is not set
+ */
+ public function getSubject(): ?string {
+ // evaluate if data store field exists and return value(s) or null otherwise
+ return (isset($this->data['subject'])) ? $this->data['subject'] : null;
+ }
+
+ /**
+ * sets the plain text or html body of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string $value text or html body of message
+ * @param bool $html html flag - true for html
+ *
+ * @return self return this object for command chaining
+ */
+ public function setBody(string $value, bool $html = false): self {
+ // evaluate html flag and create or update appropriate field in data store with value
+ if ($html) {
+ $this->data['bodyHtml'] = $value;
+ } else {
+ $this->data['bodyPlain'] = $value;
+ }
+ // return this object for command chaining
+ return $this;
+ }
+
+ /**
+ * gets either the html or plain text body of this message
+ *
+ * html body will be returned over plain text if html body exists
+ *
+ * @since 30.0.0
+ *
+ * @return string|null html/plain body of this message or null if one is not set
+ */
+ public function getBody(): ?string {
+ // evaluate if data store field(s) exists and return value
+ if (isset($this->data['bodyHtml'])) {
+ return $this->data['bodyHtml'];
+ } elseif (isset($this->data['bodyPlain'])) {
+ return $this->data['bodyPlain'];
+ }
+ // return null if data fields did not exist in data store
+ return null;
+ }
+
+ /**
+ * sets the html body of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string $value html body of message
+ *
+ * @return self return this object for command chaining
+ */
+ public function setBodyHtml(string $value): self {
+ // create or update field in data store with value
+ $this->data['bodyHtml'] = $value;
+ // return this object for command chaining
+ return $this;
+ }
+
+ /**
+ * gets the html body of this message
+ *
+ * @since 30.0.0
+ *
+ * @return string|null html body of this message or null if one is not set
+ */
+ public function getBodyHtml(): ?string {
+ // evaluate if data store field exists and return value(s) or null otherwise
+ return (isset($this->data['bodyHtml'])) ? $this->data['bodyHtml'] : null;
+ }
+
+ /**
+ * sets the plain text body of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string $value plain text body of message
+ *
+ * @return self return this object for command chaining
+ */
+ public function setBodyPlain(string $value): self {
+ // create or update field in data store with value
+ $this->data['bodyPlain'] = $value;
+ // return this object for command chaining
+ return $this;
+ }
+
+ /**
+ * gets the plain text body of this message
+ *
+ * @since 30.0.0
+ *
+ * @return string|null plain text body of this message or null if one is not set
+ */
+ public function getBodyPlain(): ?string {
+ // evaluate if data store field exists and return value(s) or null otherwise
+ return (isset($this->data['bodyPlain'])) ? $this->data['bodyPlain'] : null;
+ }
+
+ /**
+ * sets the attachments of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAttachment ...$value collection of or one or more mail attachment objects
+ *
+ * @return self return this object for command chaining
+ */
+ public function setAttachments(IAttachment ...$value): self {
+ // create or update field in data store with value
+ $this->data['attachments'] = $value;
+ // return this object for command chaining
+ return $this;
+ }
+
+ /**
+ * gets the attachments of this message
+ *
+ * @since 30.0.0
+ *
+ * @return array<int,IAttachment> collection of all mail attachment objects
+ */
+ public function getAttachments(): array {
+ // evaluate if data store field exists and return value(s) or null otherwise
+ return (isset($this->data['attachments'])) ? $this->data['attachments'] : [];
+ }
+
+}