Extract System emails from enotify
[friendica.git/.git] / src / Util / EMailer / MailBuilder.php
1 <?php
2
3 namespace Friendica\Util\EMailer;
4
5 use Exception;
6 use Friendica\App\BaseURL;
7 use Friendica\Core\Config\IConfig;
8 use Friendica\Core\L10n;
9 use Friendica\Core\Renderer;
10 use Friendica\Model\User;
11 use Friendica\Network\HTTPException\InternalServerErrorException;
12 use Friendica\Object\Email;
13 use Friendica\Object\EMail\IEmail;
14
15 /**
16  * A base class for building new emails
17  */
18 abstract class MailBuilder
19 {
20         /** @var L10n */
21         protected $l10n;
22         /** @var IConfig */
23         protected $config;
24         /** @var BaseURL */
25         protected $baseUrl;
26
27         /** @var string */
28         protected $headers;
29
30         /** @var string */
31         protected $senderName = null;
32         /** @var string */
33         protected $senderAddress = null;
34         /** @var string */
35         protected $senderNoReply = null;
36
37         /** @var string */
38         protected $recipientAddress = null;
39         /** @var int */
40         protected $recipientUid = null;
41
42         public function __construct(L10n $l10n, BaseURL $baseUrl, IConfig $config)
43         {
44                 $this->l10n    = $l10n;
45                 $this->baseUrl = $baseUrl;
46                 $this->config  = $config;
47
48                 $hostname = $baseUrl->getHostname();
49                 if (strpos($hostname, ':')) {
50                         $hostname = substr($hostname, 0, strpos($hostname, ':'));
51                 }
52
53                 $this->headers = "";
54                 $this->headers .= "Precedence: list\n";
55                 $this->headers .= "X-Friendica-Host: " . $hostname . "\n";
56                 $this->headers .= "X-Friendica-Platform: " . FRIENDICA_PLATFORM . "\n";
57                 $this->headers .= "X-Friendica-Version: " . FRIENDICA_VERSION . "\n";
58                 $this->headers .= "List-ID: <notification." . $hostname . ">\n";
59                 $this->headers .= "List-Archive: <" . $baseUrl->get() . "/notifications/system>\n";
60         }
61
62         /**
63          * Gets the subject of the concrete builder, which inherits this base class
64          *
65          * @return string
66          */
67         abstract protected function getSubject();
68
69         /**
70          * Gets the HTML version of the body of the concrete builder, which inherits this base class
71          *
72          * @return string
73          */
74         abstract protected function getHtmlMessage();
75
76         /**
77          * Gets the Plaintext version of the body of the concrete builder, which inherits this base class
78          *
79          * @return string
80          */
81         abstract protected function getPlaintextMessage();
82
83         /**
84          * Adds the User ID to the email in case the mail sending needs additional properties of this user
85          *
86          * @param int $uid The User ID
87          *
88          * @return static
89          */
90         public function forUser(int $uid)
91         {
92                 $this->recipientUid = $uid;
93
94                 return $this;
95         }
96
97         /**
98          * Adds the sender to the email (if not called/set, the sender will get loaded with the help of the user id)
99          *
100          * @param string      $name    The name of the sender
101          * @param string      $address The (email) address of the sender
102          * @param string|null $noReply Optional "no-reply" (email) address (if not set, it's the same as the address)
103          *
104          * @return static
105          */
106         public function withSender(string $name, string $address, string $noReply = null)
107         {
108                 $this->senderName    = $name;
109                 $this->senderAddress = $address;
110                 $this->senderNoReply = $noReply ?? $this->senderNoReply;
111
112                 return $this;
113         }
114
115         /**
116          * Adds a recipient to the email
117          *
118          * @param string $address The (email) address of the recipient
119          *
120          * @return static
121          */
122         public function withRecipient(string $address)
123         {
124                 $this->recipientAddress = $address;
125
126                 return $this;
127         }
128
129         /**
130          * Build a email based on the given attributes
131          *
132          * @param bool $raw True, if the email shouldn't get extended by the default email-template
133          *
134          * @return IEmail A new generated email
135          *
136          * @throws InternalServerErrorException
137          * @throws Exception
138          */
139         public function build(bool $raw = false)
140         {
141                 if (empty($this->recipientAddress)) {
142                         throw new InternalServerErrorException('Recipient address is missing.');
143                 }
144
145                 if ((empty($this->senderName) || empty($this->senderAddress)) &&
146                     !empty($this->recipientUid)) {
147                         $user = User::getById($this->recipientUid, ['username', 'email']);
148
149                         if (!empty($user)) {
150                                 $this->senderName    = $user['username'];
151                                 $this->senderAddress = $user['email'];
152                         }
153                 }
154
155                 if (empty($this->senderAddress) || empty($this->senderName)) {
156                         throw new InternalServerErrorException('Sender address or name is missing.');
157                 }
158
159                 $this->senderNoReply = $this->senderNoReply ?? $this->senderAddress;
160
161                 $msgHtml = $this->getHtmlMessage() ?? '';
162
163                 if (!$raw) {
164                         // load the template for private message notifications
165                         $tpl     = Renderer::getMarkupTemplate('email/notify/html.tpl');
166                         $msgHtml = Renderer::replaceMacros($tpl, [
167                                 '$banner'      => $this->l10n->t('Friendica Notification'),
168                                 '$product'     => FRIENDICA_PLATFORM,
169                                 '$htmlversion' => $msgHtml,
170                                 '$sitename'    => $this->config->get('config', 'sitename'),
171                                 '$siteurl'     => $this->baseUrl->get(true),
172                         ]);
173                 }
174
175                 return new Email(
176                         $this->senderName,
177                         $this->senderAddress,
178                         $this->senderNoReply,
179                         $this->recipientAddress,
180                         $this->getSubject() ?? '',
181                         $msgHtml,
182                         $this->getPlaintextMessage() ?? '',
183                         $this->headers,
184                         $this->recipientUid ?? null);
185         }
186 }