Completed
Push — master ( da1383...4ecd21 )
by Daniel
21:08
created
lib/private/Mail/Mailer.php 1 patch
Indentation   +292 added lines, -292 removed lines patch added patch discarded remove patch
@@ -51,296 +51,296 @@
 block discarded – undo
51 51
  * @package OC\Mail
52 52
  */
53 53
 class Mailer implements IMailer {
54
-	// Do not move this block or change it's content without contacting the release crew
55
-	public const DEFAULT_DIMENSIONS = '252x120';
56
-	// Do not move this block or change it's content without contacting the release crew
57
-
58
-	public const MAX_LOGO_SIZE = 105;
59
-
60
-	private ?MailerInterface $instance = null;
61
-
62
-	public function __construct(
63
-		private IConfig $config,
64
-		private LoggerInterface $logger,
65
-		private Defaults $defaults,
66
-		private IURLGenerator $urlGenerator,
67
-		private IL10N $l10n,
68
-		private IEventDispatcher $dispatcher,
69
-		private IFactory $l10nFactory,
70
-		private IEmailValidator $emailValidator,
71
-	) {
72
-	}
73
-
74
-	/**
75
-	 * Creates a new message object that can be passed to send()
76
-	 */
77
-	public function createMessage(): Message {
78
-		$plainTextOnly = $this->config->getSystemValueBool('mail_send_plaintext_only', false);
79
-		return new Message(new Email(), $plainTextOnly);
80
-	}
81
-
82
-	/**
83
-	 * @param string|null $data
84
-	 * @param string|null $filename
85
-	 * @param string|null $contentType
86
-	 * @since 13.0.0
87
-	 */
88
-	public function createAttachment($data = null, $filename = null, $contentType = null): IAttachment {
89
-		return new Attachment($data, $filename, $contentType);
90
-	}
91
-
92
-	/**
93
-	 * @param string|null $contentType
94
-	 * @since 13.0.0
95
-	 */
96
-	public function createAttachmentFromPath(string $path, $contentType = null): IAttachment {
97
-		return new Attachment(null, null, $contentType, $path);
98
-	}
99
-
100
-	/**
101
-	 * Creates a new email template object
102
-	 *
103
-	 * @since 12.0.0
104
-	 */
105
-	public function createEMailTemplate(string $emailId, array $data = []): IEMailTemplate {
106
-		$logoDimensions = $this->config->getAppValue('theming', 'logoDimensions', self::DEFAULT_DIMENSIONS);
107
-		if (str_contains($logoDimensions, 'x')) {
108
-			[$width, $height] = explode('x', $logoDimensions);
109
-			$width = (int)$width;
110
-			$height = (int)$height;
111
-
112
-			if ($width > self::MAX_LOGO_SIZE || $height > self::MAX_LOGO_SIZE) {
113
-				if ($width === $height) {
114
-					$logoWidth = self::MAX_LOGO_SIZE;
115
-					$logoHeight = self::MAX_LOGO_SIZE;
116
-				} elseif ($width > $height) {
117
-					$logoWidth = self::MAX_LOGO_SIZE;
118
-					$logoHeight = (int)(($height / $width) * self::MAX_LOGO_SIZE);
119
-				} else {
120
-					$logoWidth = (int)(($width / $height) * self::MAX_LOGO_SIZE);
121
-					$logoHeight = self::MAX_LOGO_SIZE;
122
-				}
123
-			} else {
124
-				$logoWidth = $width;
125
-				$logoHeight = $height;
126
-			}
127
-		} else {
128
-			$logoWidth = $logoHeight = null;
129
-		}
130
-
131
-		$class = $this->config->getSystemValueString('mail_template_class', '');
132
-
133
-		if ($class !== '' && class_exists($class) && is_a($class, EMailTemplate::class, true)) {
134
-			return new $class(
135
-				$this->defaults,
136
-				$this->urlGenerator,
137
-				$this->l10nFactory,
138
-				$logoWidth,
139
-				$logoHeight,
140
-				$emailId,
141
-				$data
142
-			);
143
-		}
144
-
145
-		return new EMailTemplate(
146
-			$this->defaults,
147
-			$this->urlGenerator,
148
-			$this->l10nFactory,
149
-			$logoWidth,
150
-			$logoHeight,
151
-			$emailId,
152
-			$data
153
-		);
154
-	}
155
-
156
-	/**
157
-	 * Send the specified message. Also sets the from address to the value defined in config.php
158
-	 * if no-one has been passed.
159
-	 *
160
-	 * If sending failed, the recipients that failed will be returned (to, cc and bcc).
161
-	 * Will output additional debug info if 'mail_smtpdebug' => 'true' is set in config.php
162
-	 *
163
-	 * @param IMessage $message Message to send
164
-	 * @return string[] $failedRecipients
165
-	 */
166
-	public function send(IMessage $message): array {
167
-		$debugMode = $this->config->getSystemValueBool('mail_smtpdebug', false);
168
-
169
-		if (!($message instanceof Message)) {
170
-			throw new \InvalidArgumentException('Object not of type ' . Message::class);
171
-		}
172
-
173
-		if (empty($message->getFrom())) {
174
-			$message->setFrom([\OCP\Util::getDefaultEmailAddress('no-reply') => $this->defaults->getName()]);
175
-		}
176
-
177
-		$mailer = $this->getInstance();
178
-
179
-		$this->dispatcher->dispatchTyped(new BeforeMessageSent($message));
180
-
181
-		try {
182
-			$message->setRecipients();
183
-		} catch (\InvalidArgumentException|RfcComplianceException $e) {
184
-			$logMessage = sprintf(
185
-				'Could not send mail to "%s" with subject "%s" as validation for address failed',
186
-				print_r(array_merge($message->getTo(), $message->getCc(), $message->getBcc()), true),
187
-				$message->getSubject()
188
-			);
189
-			$this->logger->debug($logMessage, ['app' => 'core', 'exception' => $e]);
190
-			$recipients = array_merge($message->getTo(), $message->getCc(), $message->getBcc());
191
-			$failedRecipients = [];
192
-
193
-			array_walk($recipients, function ($value, $key) use (&$failedRecipients) {
194
-				if (is_numeric($key)) {
195
-					$failedRecipients[] = $value;
196
-				} else {
197
-					$failedRecipients[] = $key;
198
-				}
199
-			});
200
-
201
-			return $failedRecipients;
202
-		}
203
-
204
-		try {
205
-			$mailer->send($message->getSymfonyEmail());
206
-		} catch (TransportExceptionInterface $e) {
207
-			$logMessage = sprintf('Sending mail to "%s" with subject "%s" failed', print_r($message->getTo(), true), $message->getSubject());
208
-			$this->logger->error($logMessage, ['app' => 'core', 'exception' => $e]);
209
-			if ($debugMode) {
210
-				$this->logger->debug($e->getDebug(), ['app' => 'core']);
211
-			}
212
-			$recipients = array_merge($message->getTo(), $message->getCc(), $message->getBcc());
213
-			$failedRecipients = [];
214
-
215
-			array_walk($recipients, function ($value, $key) use (&$failedRecipients) {
216
-				if (is_numeric($key)) {
217
-					$failedRecipients[] = $value;
218
-				} else {
219
-					$failedRecipients[] = $key;
220
-				}
221
-			});
222
-
223
-			return $failedRecipients;
224
-		}
225
-
226
-		// Debugging logging
227
-		$logMessage = sprintf('Sent mail to "%s" with subject "%s"', print_r($message->getTo(), true), $message->getSubject());
228
-		$this->logger->debug($logMessage, ['app' => 'core']);
229
-
230
-		return [];
231
-	}
232
-
233
-	/**
234
-	 * @param string $email Email address to be validated
235
-	 * @return bool True if the mail address is valid, false otherwise
236
-	 * @deprecated 26.0.0 use IEmailValidator.isValid instead
237
-	 */
238
-	public function validateMailAddress(string $email): bool {
239
-		return $this->emailValidator->isValid($email);
240
-	}
241
-
242
-	protected function getInstance(): MailerInterface {
243
-		if (!is_null($this->instance)) {
244
-			return $this->instance;
245
-		}
246
-
247
-		switch ($this->config->getSystemValueString('mail_smtpmode', 'smtp')) {
248
-			case 'null':
249
-				$transport = new NullTransport();
250
-				break;
251
-			case 'sendmail':
252
-				$transport = $this->getSendMailInstance();
253
-				break;
254
-			case 'smtp':
255
-			default:
256
-				$transport = $this->getSmtpInstance();
257
-				break;
258
-		}
259
-
260
-		$this->instance = new SymfonyMailer($transport);
261
-
262
-		return $this->instance;
263
-	}
264
-
265
-	/**
266
-	 * Returns the SMTP transport
267
-	 *
268
-	 * Only supports ssl/tls
269
-	 * starttls is not enforcable with Symfony Mailer but might be available
270
-	 * via the automatic config (Symfony Mailer internal)
271
-	 *
272
-	 * @return EsmtpTransport
273
-	 */
274
-	protected function getSmtpInstance(): EsmtpTransport {
275
-		// either null or true - if nothing is passed, let the symfony mailer figure out the configuration by itself
276
-		$mailSmtpsecure = ($this->config->getSystemValue('mail_smtpsecure', null) === 'ssl') ? true : null;
277
-		$transport = new EsmtpTransport(
278
-			$this->config->getSystemValueString('mail_smtphost', '127.0.0.1'),
279
-			$this->config->getSystemValueInt('mail_smtpport', 25),
280
-			$mailSmtpsecure,
281
-			null,
282
-			$this->logger
283
-		);
284
-		/** @var SocketStream $stream */
285
-		$stream = $transport->getStream();
286
-		/** @psalm-suppress InternalMethod */
287
-		$stream->setTimeout($this->config->getSystemValueInt('mail_smtptimeout', 10));
288
-
289
-		if ($this->config->getSystemValueBool('mail_smtpauth', false)) {
290
-			$transport->setUsername($this->config->getSystemValueString('mail_smtpname', ''));
291
-			$transport->setPassword($this->config->getSystemValueString('mail_smtppassword', ''));
292
-		}
293
-
294
-		$streamingOptions = $this->config->getSystemValue('mail_smtpstreamoptions', []);
295
-		if (is_array($streamingOptions) && !empty($streamingOptions)) {
296
-			/** @psalm-suppress InternalMethod */
297
-			$currentStreamingOptions = $stream->getStreamOptions();
298
-
299
-			$currentStreamingOptions = array_merge_recursive($currentStreamingOptions, $streamingOptions);
300
-
301
-			/** @psalm-suppress InternalMethod */
302
-			$stream->setStreamOptions($currentStreamingOptions);
303
-		}
304
-
305
-		$overwriteCliUrl = parse_url(
306
-			$this->config->getSystemValueString('overwrite.cli.url', ''),
307
-			PHP_URL_HOST
308
-		);
309
-
310
-		if (!empty($overwriteCliUrl)) {
311
-			$transport->setLocalDomain($overwriteCliUrl);
312
-		}
313
-
314
-		return $transport;
315
-	}
316
-
317
-	/**
318
-	 * Returns the sendmail transport
319
-	 *
320
-	 * @return SendmailTransport
321
-	 */
322
-	protected function getSendMailInstance(): SendmailTransport {
323
-		switch ($this->config->getSystemValueString('mail_smtpmode', 'smtp')) {
324
-			case 'qmail':
325
-				$binaryPath = '/var/qmail/bin/sendmail';
326
-				break;
327
-			default:
328
-				$sendmail = \OCP\Server::get(IBinaryFinder::class)->findBinaryPath('sendmail');
329
-				if ($sendmail === false) {
330
-					// fallback (though not sure what good it'll do)
331
-					$sendmail = '/usr/sbin/sendmail';
332
-					$this->logger->debug('sendmail binary search failed, using fallback ' . $sendmail, ['app' => 'core']);
333
-				}
334
-				$binaryPath = $sendmail;
335
-				break;
336
-		}
337
-
338
-		$binaryParam = match ($this->config->getSystemValueString('mail_sendmailmode', 'smtp')) {
339
-			'pipe' => ' -t -i',
340
-			default => ' -bs',
341
-		};
342
-
343
-		$this->logger->debug('Using sendmail binary: ' . $binaryPath, ['app' => 'core']);
344
-		return new SendmailTransport($binaryPath . $binaryParam, null, $this->logger);
345
-	}
54
+    // Do not move this block or change it's content without contacting the release crew
55
+    public const DEFAULT_DIMENSIONS = '252x120';
56
+    // Do not move this block or change it's content without contacting the release crew
57
+
58
+    public const MAX_LOGO_SIZE = 105;
59
+
60
+    private ?MailerInterface $instance = null;
61
+
62
+    public function __construct(
63
+        private IConfig $config,
64
+        private LoggerInterface $logger,
65
+        private Defaults $defaults,
66
+        private IURLGenerator $urlGenerator,
67
+        private IL10N $l10n,
68
+        private IEventDispatcher $dispatcher,
69
+        private IFactory $l10nFactory,
70
+        private IEmailValidator $emailValidator,
71
+    ) {
72
+    }
73
+
74
+    /**
75
+     * Creates a new message object that can be passed to send()
76
+     */
77
+    public function createMessage(): Message {
78
+        $plainTextOnly = $this->config->getSystemValueBool('mail_send_plaintext_only', false);
79
+        return new Message(new Email(), $plainTextOnly);
80
+    }
81
+
82
+    /**
83
+     * @param string|null $data
84
+     * @param string|null $filename
85
+     * @param string|null $contentType
86
+     * @since 13.0.0
87
+     */
88
+    public function createAttachment($data = null, $filename = null, $contentType = null): IAttachment {
89
+        return new Attachment($data, $filename, $contentType);
90
+    }
91
+
92
+    /**
93
+     * @param string|null $contentType
94
+     * @since 13.0.0
95
+     */
96
+    public function createAttachmentFromPath(string $path, $contentType = null): IAttachment {
97
+        return new Attachment(null, null, $contentType, $path);
98
+    }
99
+
100
+    /**
101
+     * Creates a new email template object
102
+     *
103
+     * @since 12.0.0
104
+     */
105
+    public function createEMailTemplate(string $emailId, array $data = []): IEMailTemplate {
106
+        $logoDimensions = $this->config->getAppValue('theming', 'logoDimensions', self::DEFAULT_DIMENSIONS);
107
+        if (str_contains($logoDimensions, 'x')) {
108
+            [$width, $height] = explode('x', $logoDimensions);
109
+            $width = (int)$width;
110
+            $height = (int)$height;
111
+
112
+            if ($width > self::MAX_LOGO_SIZE || $height > self::MAX_LOGO_SIZE) {
113
+                if ($width === $height) {
114
+                    $logoWidth = self::MAX_LOGO_SIZE;
115
+                    $logoHeight = self::MAX_LOGO_SIZE;
116
+                } elseif ($width > $height) {
117
+                    $logoWidth = self::MAX_LOGO_SIZE;
118
+                    $logoHeight = (int)(($height / $width) * self::MAX_LOGO_SIZE);
119
+                } else {
120
+                    $logoWidth = (int)(($width / $height) * self::MAX_LOGO_SIZE);
121
+                    $logoHeight = self::MAX_LOGO_SIZE;
122
+                }
123
+            } else {
124
+                $logoWidth = $width;
125
+                $logoHeight = $height;
126
+            }
127
+        } else {
128
+            $logoWidth = $logoHeight = null;
129
+        }
130
+
131
+        $class = $this->config->getSystemValueString('mail_template_class', '');
132
+
133
+        if ($class !== '' && class_exists($class) && is_a($class, EMailTemplate::class, true)) {
134
+            return new $class(
135
+                $this->defaults,
136
+                $this->urlGenerator,
137
+                $this->l10nFactory,
138
+                $logoWidth,
139
+                $logoHeight,
140
+                $emailId,
141
+                $data
142
+            );
143
+        }
144
+
145
+        return new EMailTemplate(
146
+            $this->defaults,
147
+            $this->urlGenerator,
148
+            $this->l10nFactory,
149
+            $logoWidth,
150
+            $logoHeight,
151
+            $emailId,
152
+            $data
153
+        );
154
+    }
155
+
156
+    /**
157
+     * Send the specified message. Also sets the from address to the value defined in config.php
158
+     * if no-one has been passed.
159
+     *
160
+     * If sending failed, the recipients that failed will be returned (to, cc and bcc).
161
+     * Will output additional debug info if 'mail_smtpdebug' => 'true' is set in config.php
162
+     *
163
+     * @param IMessage $message Message to send
164
+     * @return string[] $failedRecipients
165
+     */
166
+    public function send(IMessage $message): array {
167
+        $debugMode = $this->config->getSystemValueBool('mail_smtpdebug', false);
168
+
169
+        if (!($message instanceof Message)) {
170
+            throw new \InvalidArgumentException('Object not of type ' . Message::class);
171
+        }
172
+
173
+        if (empty($message->getFrom())) {
174
+            $message->setFrom([\OCP\Util::getDefaultEmailAddress('no-reply') => $this->defaults->getName()]);
175
+        }
176
+
177
+        $mailer = $this->getInstance();
178
+
179
+        $this->dispatcher->dispatchTyped(new BeforeMessageSent($message));
180
+
181
+        try {
182
+            $message->setRecipients();
183
+        } catch (\InvalidArgumentException|RfcComplianceException $e) {
184
+            $logMessage = sprintf(
185
+                'Could not send mail to "%s" with subject "%s" as validation for address failed',
186
+                print_r(array_merge($message->getTo(), $message->getCc(), $message->getBcc()), true),
187
+                $message->getSubject()
188
+            );
189
+            $this->logger->debug($logMessage, ['app' => 'core', 'exception' => $e]);
190
+            $recipients = array_merge($message->getTo(), $message->getCc(), $message->getBcc());
191
+            $failedRecipients = [];
192
+
193
+            array_walk($recipients, function ($value, $key) use (&$failedRecipients) {
194
+                if (is_numeric($key)) {
195
+                    $failedRecipients[] = $value;
196
+                } else {
197
+                    $failedRecipients[] = $key;
198
+                }
199
+            });
200
+
201
+            return $failedRecipients;
202
+        }
203
+
204
+        try {
205
+            $mailer->send($message->getSymfonyEmail());
206
+        } catch (TransportExceptionInterface $e) {
207
+            $logMessage = sprintf('Sending mail to "%s" with subject "%s" failed', print_r($message->getTo(), true), $message->getSubject());
208
+            $this->logger->error($logMessage, ['app' => 'core', 'exception' => $e]);
209
+            if ($debugMode) {
210
+                $this->logger->debug($e->getDebug(), ['app' => 'core']);
211
+            }
212
+            $recipients = array_merge($message->getTo(), $message->getCc(), $message->getBcc());
213
+            $failedRecipients = [];
214
+
215
+            array_walk($recipients, function ($value, $key) use (&$failedRecipients) {
216
+                if (is_numeric($key)) {
217
+                    $failedRecipients[] = $value;
218
+                } else {
219
+                    $failedRecipients[] = $key;
220
+                }
221
+            });
222
+
223
+            return $failedRecipients;
224
+        }
225
+
226
+        // Debugging logging
227
+        $logMessage = sprintf('Sent mail to "%s" with subject "%s"', print_r($message->getTo(), true), $message->getSubject());
228
+        $this->logger->debug($logMessage, ['app' => 'core']);
229
+
230
+        return [];
231
+    }
232
+
233
+    /**
234
+     * @param string $email Email address to be validated
235
+     * @return bool True if the mail address is valid, false otherwise
236
+     * @deprecated 26.0.0 use IEmailValidator.isValid instead
237
+     */
238
+    public function validateMailAddress(string $email): bool {
239
+        return $this->emailValidator->isValid($email);
240
+    }
241
+
242
+    protected function getInstance(): MailerInterface {
243
+        if (!is_null($this->instance)) {
244
+            return $this->instance;
245
+        }
246
+
247
+        switch ($this->config->getSystemValueString('mail_smtpmode', 'smtp')) {
248
+            case 'null':
249
+                $transport = new NullTransport();
250
+                break;
251
+            case 'sendmail':
252
+                $transport = $this->getSendMailInstance();
253
+                break;
254
+            case 'smtp':
255
+            default:
256
+                $transport = $this->getSmtpInstance();
257
+                break;
258
+        }
259
+
260
+        $this->instance = new SymfonyMailer($transport);
261
+
262
+        return $this->instance;
263
+    }
264
+
265
+    /**
266
+     * Returns the SMTP transport
267
+     *
268
+     * Only supports ssl/tls
269
+     * starttls is not enforcable with Symfony Mailer but might be available
270
+     * via the automatic config (Symfony Mailer internal)
271
+     *
272
+     * @return EsmtpTransport
273
+     */
274
+    protected function getSmtpInstance(): EsmtpTransport {
275
+        // either null or true - if nothing is passed, let the symfony mailer figure out the configuration by itself
276
+        $mailSmtpsecure = ($this->config->getSystemValue('mail_smtpsecure', null) === 'ssl') ? true : null;
277
+        $transport = new EsmtpTransport(
278
+            $this->config->getSystemValueString('mail_smtphost', '127.0.0.1'),
279
+            $this->config->getSystemValueInt('mail_smtpport', 25),
280
+            $mailSmtpsecure,
281
+            null,
282
+            $this->logger
283
+        );
284
+        /** @var SocketStream $stream */
285
+        $stream = $transport->getStream();
286
+        /** @psalm-suppress InternalMethod */
287
+        $stream->setTimeout($this->config->getSystemValueInt('mail_smtptimeout', 10));
288
+
289
+        if ($this->config->getSystemValueBool('mail_smtpauth', false)) {
290
+            $transport->setUsername($this->config->getSystemValueString('mail_smtpname', ''));
291
+            $transport->setPassword($this->config->getSystemValueString('mail_smtppassword', ''));
292
+        }
293
+
294
+        $streamingOptions = $this->config->getSystemValue('mail_smtpstreamoptions', []);
295
+        if (is_array($streamingOptions) && !empty($streamingOptions)) {
296
+            /** @psalm-suppress InternalMethod */
297
+            $currentStreamingOptions = $stream->getStreamOptions();
298
+
299
+            $currentStreamingOptions = array_merge_recursive($currentStreamingOptions, $streamingOptions);
300
+
301
+            /** @psalm-suppress InternalMethod */
302
+            $stream->setStreamOptions($currentStreamingOptions);
303
+        }
304
+
305
+        $overwriteCliUrl = parse_url(
306
+            $this->config->getSystemValueString('overwrite.cli.url', ''),
307
+            PHP_URL_HOST
308
+        );
309
+
310
+        if (!empty($overwriteCliUrl)) {
311
+            $transport->setLocalDomain($overwriteCliUrl);
312
+        }
313
+
314
+        return $transport;
315
+    }
316
+
317
+    /**
318
+     * Returns the sendmail transport
319
+     *
320
+     * @return SendmailTransport
321
+     */
322
+    protected function getSendMailInstance(): SendmailTransport {
323
+        switch ($this->config->getSystemValueString('mail_smtpmode', 'smtp')) {
324
+            case 'qmail':
325
+                $binaryPath = '/var/qmail/bin/sendmail';
326
+                break;
327
+            default:
328
+                $sendmail = \OCP\Server::get(IBinaryFinder::class)->findBinaryPath('sendmail');
329
+                if ($sendmail === false) {
330
+                    // fallback (though not sure what good it'll do)
331
+                    $sendmail = '/usr/sbin/sendmail';
332
+                    $this->logger->debug('sendmail binary search failed, using fallback ' . $sendmail, ['app' => 'core']);
333
+                }
334
+                $binaryPath = $sendmail;
335
+                break;
336
+        }
337
+
338
+        $binaryParam = match ($this->config->getSystemValueString('mail_sendmailmode', 'smtp')) {
339
+            'pipe' => ' -t -i',
340
+            default => ' -bs',
341
+        };
342
+
343
+        $this->logger->debug('Using sendmail binary: ' . $binaryPath, ['app' => 'core']);
344
+        return new SendmailTransport($binaryPath . $binaryParam, null, $this->logger);
345
+    }
346 346
 }
Please login to merge, or discard this patch.