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