Passed
Push — master ( b37a49...348454 )
by Joas
15:41 queued 15s
created
lib/public/Mail/Headers/AutoSubmitted.php 1 patch
Indentation   +32 added lines, -32 removed lines patch added patch discarded remove patch
@@ -37,39 +37,39 @@
 block discarded – undo
37 37
  */
38 38
 final class AutoSubmitted {
39 39
 
40
-	/**
41
-	 * Name of the Header as used in the final message later
42
-	 *
43
-	 * @var string
44
-	 * @since 26.0.0
45
-	 */
46
-	public const HEADER = 'Auto-Submitted';
40
+    /**
41
+     * Name of the Header as used in the final message later
42
+     *
43
+     * @var string
44
+     * @since 26.0.0
45
+     */
46
+    public const HEADER = 'Auto-Submitted';
47 47
 
48
-	/**
49
-	 * Indicates that a message was NOT automatically generated, but was
50
-	 * created by a human (or following human interaction). It is the equivalent
51
-	 * to the absence of an Auto-Submitted header altogether.
52
-	 *
53
-	 * @var string
54
-	 * @since 26.0.0
55
-	 */
56
-	public const VALUE_NO = 'no';
48
+    /**
49
+     * Indicates that a message was NOT automatically generated, but was
50
+     * created by a human (or following human interaction). It is the equivalent
51
+     * to the absence of an Auto-Submitted header altogether.
52
+     *
53
+     * @var string
54
+     * @since 26.0.0
55
+     */
56
+    public const VALUE_NO = 'no';
57 57
 
58
-	/**
59
-	 * Indicates that a message was generated by an automatic process, and is
60
-	 * not a direct response to another message
61
-	 *
62
-	 * @var string
63
-	 * @since 26.0.0
64
-	 */
65
-	public const VALUE_AUTO_GENERATED = 'auto-generated';
58
+    /**
59
+     * Indicates that a message was generated by an automatic process, and is
60
+     * not a direct response to another message
61
+     *
62
+     * @var string
63
+     * @since 26.0.0
64
+     */
65
+    public const VALUE_AUTO_GENERATED = 'auto-generated';
66 66
 
67
-	/**
68
-	 * Indicates that a message was automatically generated as a direct response
69
-	 * to another message.
70
-	 *
71
-	 * @var string
72
-	 * @since 26.0.0
73
-	 */
74
-	public const VALUE_AUTO_REPLIED = 'auto-replied';
67
+    /**
68
+     * Indicates that a message was automatically generated as a direct response
69
+     * to another message.
70
+     *
71
+     * @var string
72
+     * @since 26.0.0
73
+     */
74
+    public const VALUE_AUTO_REPLIED = 'auto-replied';
75 75
 }
Please login to merge, or discard this patch.
lib/public/Mail/IMessage.php 1 patch
Indentation   +63 added lines, -63 removed lines patch added patch discarded remove patch
@@ -33,74 +33,74 @@
 block discarded – undo
33 33
  */
34 34
 interface IMessage {
35 35
 
36
-	/**
37
-	 * @param IAttachment $attachment
38
-	 * @return IMessage
39
-	 * @since 13.0.0
40
-	 */
41
-	public function attach(IAttachment $attachment): IMessage;
36
+    /**
37
+     * @param IAttachment $attachment
38
+     * @return IMessage
39
+     * @since 13.0.0
40
+     */
41
+    public function attach(IAttachment $attachment): IMessage;
42 42
 
43
-	/**
44
-	 * Set the from address of this message.
45
-	 *
46
-	 * If no "From" address is used \OC\Mail\Mailer will use mail_from_address and mail_domain from config.php
47
-	 *
48
-	 * @param array $addresses Example: array('[email protected]', '[email protected]' => 'A name')
49
-	 * @return IMessage
50
-	 * @since 13.0.0
51
-	 */
52
-	public function setFrom(array $addresses): IMessage;
43
+    /**
44
+     * Set the from address of this message.
45
+     *
46
+     * If no "From" address is used \OC\Mail\Mailer will use mail_from_address and mail_domain from config.php
47
+     *
48
+     * @param array $addresses Example: array('[email protected]', '[email protected]' => 'A name')
49
+     * @return IMessage
50
+     * @since 13.0.0
51
+     */
52
+    public function setFrom(array $addresses): IMessage;
53 53
 
54
-	/**
55
-	 * Set the Reply-To address of this message
56
-	 *
57
-	 * @param array $addresses
58
-	 * @return IMessage
59
-	 * @since 13.0.0
60
-	 */
61
-	public function setReplyTo(array $addresses): IMessage;
54
+    /**
55
+     * Set the Reply-To address of this message
56
+     *
57
+     * @param array $addresses
58
+     * @return IMessage
59
+     * @since 13.0.0
60
+     */
61
+    public function setReplyTo(array $addresses): IMessage;
62 62
 
63
-	/**
64
-	 * Set the to addresses of this message.
65
-	 *
66
-	 * @param array $recipients Example: array('[email protected]', '[email protected]' => 'A name')
67
-	 * @return IMessage
68
-	 * @since 13.0.0
69
-	 */
70
-	public function setTo(array $recipients): IMessage;
63
+    /**
64
+     * Set the to addresses of this message.
65
+     *
66
+     * @param array $recipients Example: array('[email protected]', '[email protected]' => 'A name')
67
+     * @return IMessage
68
+     * @since 13.0.0
69
+     */
70
+    public function setTo(array $recipients): IMessage;
71 71
 
72
-	/**
73
-	 * Set the CC recipients of this message.
74
-	 *
75
-	 * @param array $recipients Example: array('[email protected]', '[email protected]' => 'A name')
76
-	 * @return IMessage
77
-	 * @since 13.0.0
78
-	 */
79
-	public function setCc(array $recipients): IMessage;
72
+    /**
73
+     * Set the CC recipients of this message.
74
+     *
75
+     * @param array $recipients Example: array('[email protected]', '[email protected]' => 'A name')
76
+     * @return IMessage
77
+     * @since 13.0.0
78
+     */
79
+    public function setCc(array $recipients): IMessage;
80 80
 
81
-	/**
82
-	 * Set the BCC recipients of this message.
83
-	 *
84
-	 * @param array $recipients Example: array('[email protected]', '[email protected]' => 'A name')
85
-	 * @return IMessage
86
-	 * @since 13.0.0
87
-	 */
88
-	public function setBcc(array $recipients): IMessage;
81
+    /**
82
+     * Set the BCC recipients of this message.
83
+     *
84
+     * @param array $recipients Example: array('[email protected]', '[email protected]' => 'A name')
85
+     * @return IMessage
86
+     * @since 13.0.0
87
+     */
88
+    public function setBcc(array $recipients): IMessage;
89 89
 
90
-	/**
91
-	 * @param IEMailTemplate $emailTemplate
92
-	 * @return IMessage
93
-	 * @since 13.0.0
94
-	 */
95
-	public function useTemplate(IEMailTemplate $emailTemplate): IMessage;
90
+    /**
91
+     * @param IEMailTemplate $emailTemplate
92
+     * @return IMessage
93
+     * @since 13.0.0
94
+     */
95
+    public function useTemplate(IEMailTemplate $emailTemplate): IMessage;
96 96
 
97
-	/**
98
-	 * Add the Auto-Submitted header to the email, preventing most automated
99
-	 * responses to automated messages.
100
-	 *
101
-	 * @param Headers\AutoSubmitted::VALUE_* $value (one of AutoSubmitted::VALUE_NO, AutoSubmitted::VALUE_AUTO_GENERATED, AutoSubmitted::VALUE_AUTO_REPLIED)
102
-	 * @return IMessage
103
-	 * @since 26.0.0
104
-	 */
105
-	public function setAutoSubmitted(string $value): IMessage;
97
+    /**
98
+     * Add the Auto-Submitted header to the email, preventing most automated
99
+     * responses to automated messages.
100
+     *
101
+     * @param Headers\AutoSubmitted::VALUE_* $value (one of AutoSubmitted::VALUE_NO, AutoSubmitted::VALUE_AUTO_GENERATED, AutoSubmitted::VALUE_AUTO_REPLIED)
102
+     * @return IMessage
103
+     * @since 26.0.0
104
+     */
105
+    public function setAutoSubmitted(string $value): IMessage;
106 106
 }
Please login to merge, or discard this patch.
lib/private/Mail/Message.php 1 patch
Indentation   +296 added lines, -296 removed lines patch added patch discarded remove patch
@@ -43,300 +43,300 @@
 block discarded – undo
43 43
  * @package OC\Mail
44 44
  */
45 45
 class Message implements IMessage {
46
-	/** @var Swift_Message */
47
-	private $swiftMessage;
48
-	/** @var bool */
49
-	private $plainTextOnly;
50
-
51
-	public function __construct(Swift_Message $swiftMessage, bool $plainTextOnly) {
52
-		$this->swiftMessage = $swiftMessage;
53
-		$this->plainTextOnly = $plainTextOnly;
54
-	}
55
-
56
-	/**
57
-	 * @param IAttachment $attachment
58
-	 * @return $this
59
-	 * @since 13.0.0
60
-	 */
61
-	public function attach(IAttachment $attachment): IMessage {
62
-		/** @var Attachment $attachment */
63
-		$this->swiftMessage->attach($attachment->getSwiftAttachment());
64
-		return $this;
65
-	}
66
-
67
-	/**
68
-	 * SwiftMailer does currently not work with IDN domains, this function therefore converts the domains
69
-	 * FIXME: Remove this once SwiftMailer supports IDN
70
-	 *
71
-	 * @param array $addresses Array of mail addresses, key will get converted
72
-	 * @return array Converted addresses if `idn_to_ascii` exists
73
-	 */
74
-	protected function convertAddresses(array $addresses): array {
75
-		if (!function_exists('idn_to_ascii') || !defined('INTL_IDNA_VARIANT_UTS46')) {
76
-			return $addresses;
77
-		}
78
-
79
-		$convertedAddresses = [];
80
-
81
-		foreach ($addresses as $email => $readableName) {
82
-			$parsableEmail = is_numeric($email) ? $readableName : $email;
83
-			if (strpos($parsableEmail, '@') === false) {
84
-				$convertedAddresses[$parsableEmail] = $readableName;
85
-				continue;
86
-			}
87
-
88
-			[$name, $domain] = explode('@', $parsableEmail, 2);
89
-			$domain = idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46);
90
-			if (is_numeric($email)) {
91
-				$convertedAddresses[] = $name . '@' . $domain;
92
-			} else {
93
-				$convertedAddresses[$name . '@' . $domain] = $readableName;
94
-			}
95
-		}
96
-
97
-		return $convertedAddresses;
98
-	}
99
-
100
-	/**
101
-	 * Set the from address of this message.
102
-	 *
103
-	 * If no "From" address is used \OC\Mail\Mailer will use mail_from_address and mail_domain from config.php
104
-	 *
105
-	 * @param array $addresses Example: array('[email protected]', '[email protected]' => 'A name')
106
-	 * @return $this
107
-	 */
108
-	public function setFrom(array $addresses): IMessage {
109
-		$addresses = $this->convertAddresses($addresses);
110
-
111
-		$this->swiftMessage->setFrom($addresses);
112
-		return $this;
113
-	}
114
-
115
-	/**
116
-	 * Get the from address of this message.
117
-	 *
118
-	 * @return array
119
-	 */
120
-	public function getFrom(): array {
121
-		return $this->swiftMessage->getFrom() ?? [];
122
-	}
123
-
124
-	/**
125
-	 * Set the Reply-To address of this message
126
-	 *
127
-	 * @param array $addresses
128
-	 * @return $this
129
-	 */
130
-	public function setReplyTo(array $addresses): IMessage {
131
-		$addresses = $this->convertAddresses($addresses);
132
-
133
-		$this->swiftMessage->setReplyTo($addresses);
134
-		return $this;
135
-	}
136
-
137
-	/**
138
-	 * Returns the Reply-To address of this message
139
-	 *
140
-	 * @return string
141
-	 */
142
-	public function getReplyTo(): string {
143
-		return $this->swiftMessage->getReplyTo();
144
-	}
145
-
146
-	/**
147
-	 * Set the to addresses of this message.
148
-	 *
149
-	 * @param array $recipients Example: array('[email protected]', '[email protected]' => 'A name')
150
-	 * @return $this
151
-	 */
152
-	public function setTo(array $recipients): IMessage {
153
-		$recipients = $this->convertAddresses($recipients);
154
-
155
-		$this->swiftMessage->setTo($recipients);
156
-		return $this;
157
-	}
158
-
159
-	/**
160
-	 * Get the to address of this message.
161
-	 *
162
-	 * @return array
163
-	 */
164
-	public function getTo(): array {
165
-		return $this->swiftMessage->getTo() ?? [];
166
-	}
167
-
168
-	/**
169
-	 * Set the CC recipients of this message.
170
-	 *
171
-	 * @param array $recipients Example: array('[email protected]', '[email protected]' => 'A name')
172
-	 * @return $this
173
-	 */
174
-	public function setCc(array $recipients): IMessage {
175
-		$recipients = $this->convertAddresses($recipients);
176
-
177
-		$this->swiftMessage->setCc($recipients);
178
-		return $this;
179
-	}
180
-
181
-	/**
182
-	 * Get the cc address of this message.
183
-	 *
184
-	 * @return array
185
-	 */
186
-	public function getCc(): array {
187
-		return $this->swiftMessage->getCc() ?? [];
188
-	}
189
-
190
-	/**
191
-	 * Set the BCC recipients of this message.
192
-	 *
193
-	 * @param array $recipients Example: array('[email protected]', '[email protected]' => 'A name')
194
-	 * @return $this
195
-	 */
196
-	public function setBcc(array $recipients): IMessage {
197
-		$recipients = $this->convertAddresses($recipients);
198
-
199
-		$this->swiftMessage->setBcc($recipients);
200
-		return $this;
201
-	}
202
-
203
-	/**
204
-	 * Get the Bcc address of this message.
205
-	 *
206
-	 * @return array
207
-	 */
208
-	public function getBcc(): array {
209
-		return $this->swiftMessage->getBcc() ?? [];
210
-	}
211
-
212
-	/**
213
-	 * Set the subject of this message.
214
-	 *
215
-	 * @param string $subject
216
-	 * @return IMessage
217
-	 */
218
-	public function setSubject(string $subject): IMessage {
219
-		$this->swiftMessage->setSubject($subject);
220
-		return $this;
221
-	}
222
-
223
-	/**
224
-	 * Get the from subject of this message.
225
-	 *
226
-	 * @return string
227
-	 */
228
-	public function getSubject(): string {
229
-		return $this->swiftMessage->getSubject();
230
-	}
231
-
232
-	/**
233
-	 * Set the plain-text body of this message.
234
-	 *
235
-	 * @param string $body
236
-	 * @return $this
237
-	 */
238
-	public function setPlainBody(string $body): IMessage {
239
-		$this->swiftMessage->setBody($body);
240
-		return $this;
241
-	}
242
-
243
-	/**
244
-	 * Get the plain body of this message.
245
-	 *
246
-	 * @return string
247
-	 */
248
-	public function getPlainBody(): string {
249
-		return $this->swiftMessage->getBody();
250
-	}
251
-
252
-	/**
253
-	 * Set the HTML body of this message. Consider also sending a plain-text body instead of only an HTML one.
254
-	 *
255
-	 * @param string $body
256
-	 * @return $this
257
-	 */
258
-	public function setHtmlBody($body) {
259
-		if (!$this->plainTextOnly) {
260
-			$this->swiftMessage->addPart($body, 'text/html');
261
-		}
262
-		return $this;
263
-	}
264
-
265
-	/**
266
-	 * Get's the underlying SwiftMessage
267
-	 * @param Swift_Message $swiftMessage
268
-	 */
269
-	public function setSwiftMessage(Swift_Message $swiftMessage): void {
270
-		$this->swiftMessage = $swiftMessage;
271
-	}
272
-
273
-	/**
274
-	 * Get's the underlying SwiftMessage
275
-	 * @return Swift_Message
276
-	 */
277
-	public function getSwiftMessage(): Swift_Message {
278
-		return $this->swiftMessage;
279
-	}
280
-
281
-	/**
282
-	 * @param string $body
283
-	 * @param string $contentType
284
-	 * @return $this
285
-	 */
286
-	public function setBody($body, $contentType) {
287
-		if (!$this->plainTextOnly || $contentType !== 'text/html') {
288
-			$this->swiftMessage->setBody($body, $contentType);
289
-		}
290
-		return $this;
291
-	}
292
-
293
-	/**
294
-	 * @param IEMailTemplate $emailTemplate
295
-	 * @return $this
296
-	 */
297
-	public function useTemplate(IEMailTemplate $emailTemplate): IMessage {
298
-		$this->setSubject($emailTemplate->renderSubject());
299
-		$this->setPlainBody($emailTemplate->renderText());
300
-		if (!$this->plainTextOnly) {
301
-			$this->setHtmlBody($emailTemplate->renderHtml());
302
-		}
303
-		return $this;
304
-	}
305
-
306
-	/**
307
-	 * Add the Auto-Submitted header to the email, preventing most automated
308
-	 * responses to automated messages.
309
-	 *
310
-	 * @param AutoSubmitted::VALUE_* $value (one of AutoSubmitted::VALUE_NO, AutoSubmitted::VALUE_AUTO_GENERATED, AutoSubmitted::VALUE_AUTO_REPLIED)
311
-	 * @return $this
312
-	 */
313
-	public function setAutoSubmitted(string $value): IMessage {
314
-		$headers = $this->swiftMessage->getHeaders();
315
-
316
-		if ($headers->has(AutoSubmitted::HEADER)) {
317
-			// if the header already exsists, remove it.
318
-			// the value can be modified with some implementations
319
-			// of the interface \Swift_Mime_Header, however the
320
-			// interface doesn't, and this makes the static-code
321
-			// analysis unhappy.
322
-			$headers->remove(AutoSubmitted::HEADER);
323
-		}
324
-
325
-		$headers->addTextHeader(AutoSubmitted::HEADER, $value);
326
-
327
-		return $this;
328
-	}
329
-
330
-	/**
331
-	 * Get the current value of the Auto-Submitted header. Defaults to "no"
332
-	 * which is equivalent to the header not existing at all
333
-	 *
334
-	 * @return string
335
-	 */
336
-	public function getAutoSubmitted(): string {
337
-		$headers = $this->swiftMessage->getHeaders();
338
-
339
-		return $headers->has(AutoSubmitted::HEADER) ?
340
-			$headers->get(AutoSubmitted::HEADER)->toString() : AutoSubmitted::VALUE_NO;
341
-	}
46
+    /** @var Swift_Message */
47
+    private $swiftMessage;
48
+    /** @var bool */
49
+    private $plainTextOnly;
50
+
51
+    public function __construct(Swift_Message $swiftMessage, bool $plainTextOnly) {
52
+        $this->swiftMessage = $swiftMessage;
53
+        $this->plainTextOnly = $plainTextOnly;
54
+    }
55
+
56
+    /**
57
+     * @param IAttachment $attachment
58
+     * @return $this
59
+     * @since 13.0.0
60
+     */
61
+    public function attach(IAttachment $attachment): IMessage {
62
+        /** @var Attachment $attachment */
63
+        $this->swiftMessage->attach($attachment->getSwiftAttachment());
64
+        return $this;
65
+    }
66
+
67
+    /**
68
+     * SwiftMailer does currently not work with IDN domains, this function therefore converts the domains
69
+     * FIXME: Remove this once SwiftMailer supports IDN
70
+     *
71
+     * @param array $addresses Array of mail addresses, key will get converted
72
+     * @return array Converted addresses if `idn_to_ascii` exists
73
+     */
74
+    protected function convertAddresses(array $addresses): array {
75
+        if (!function_exists('idn_to_ascii') || !defined('INTL_IDNA_VARIANT_UTS46')) {
76
+            return $addresses;
77
+        }
78
+
79
+        $convertedAddresses = [];
80
+
81
+        foreach ($addresses as $email => $readableName) {
82
+            $parsableEmail = is_numeric($email) ? $readableName : $email;
83
+            if (strpos($parsableEmail, '@') === false) {
84
+                $convertedAddresses[$parsableEmail] = $readableName;
85
+                continue;
86
+            }
87
+
88
+            [$name, $domain] = explode('@', $parsableEmail, 2);
89
+            $domain = idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46);
90
+            if (is_numeric($email)) {
91
+                $convertedAddresses[] = $name . '@' . $domain;
92
+            } else {
93
+                $convertedAddresses[$name . '@' . $domain] = $readableName;
94
+            }
95
+        }
96
+
97
+        return $convertedAddresses;
98
+    }
99
+
100
+    /**
101
+     * Set the from address of this message.
102
+     *
103
+     * If no "From" address is used \OC\Mail\Mailer will use mail_from_address and mail_domain from config.php
104
+     *
105
+     * @param array $addresses Example: array('[email protected]', '[email protected]' => 'A name')
106
+     * @return $this
107
+     */
108
+    public function setFrom(array $addresses): IMessage {
109
+        $addresses = $this->convertAddresses($addresses);
110
+
111
+        $this->swiftMessage->setFrom($addresses);
112
+        return $this;
113
+    }
114
+
115
+    /**
116
+     * Get the from address of this message.
117
+     *
118
+     * @return array
119
+     */
120
+    public function getFrom(): array {
121
+        return $this->swiftMessage->getFrom() ?? [];
122
+    }
123
+
124
+    /**
125
+     * Set the Reply-To address of this message
126
+     *
127
+     * @param array $addresses
128
+     * @return $this
129
+     */
130
+    public function setReplyTo(array $addresses): IMessage {
131
+        $addresses = $this->convertAddresses($addresses);
132
+
133
+        $this->swiftMessage->setReplyTo($addresses);
134
+        return $this;
135
+    }
136
+
137
+    /**
138
+     * Returns the Reply-To address of this message
139
+     *
140
+     * @return string
141
+     */
142
+    public function getReplyTo(): string {
143
+        return $this->swiftMessage->getReplyTo();
144
+    }
145
+
146
+    /**
147
+     * Set the to addresses of this message.
148
+     *
149
+     * @param array $recipients Example: array('[email protected]', '[email protected]' => 'A name')
150
+     * @return $this
151
+     */
152
+    public function setTo(array $recipients): IMessage {
153
+        $recipients = $this->convertAddresses($recipients);
154
+
155
+        $this->swiftMessage->setTo($recipients);
156
+        return $this;
157
+    }
158
+
159
+    /**
160
+     * Get the to address of this message.
161
+     *
162
+     * @return array
163
+     */
164
+    public function getTo(): array {
165
+        return $this->swiftMessage->getTo() ?? [];
166
+    }
167
+
168
+    /**
169
+     * Set the CC recipients of this message.
170
+     *
171
+     * @param array $recipients Example: array('[email protected]', '[email protected]' => 'A name')
172
+     * @return $this
173
+     */
174
+    public function setCc(array $recipients): IMessage {
175
+        $recipients = $this->convertAddresses($recipients);
176
+
177
+        $this->swiftMessage->setCc($recipients);
178
+        return $this;
179
+    }
180
+
181
+    /**
182
+     * Get the cc address of this message.
183
+     *
184
+     * @return array
185
+     */
186
+    public function getCc(): array {
187
+        return $this->swiftMessage->getCc() ?? [];
188
+    }
189
+
190
+    /**
191
+     * Set the BCC recipients of this message.
192
+     *
193
+     * @param array $recipients Example: array('[email protected]', '[email protected]' => 'A name')
194
+     * @return $this
195
+     */
196
+    public function setBcc(array $recipients): IMessage {
197
+        $recipients = $this->convertAddresses($recipients);
198
+
199
+        $this->swiftMessage->setBcc($recipients);
200
+        return $this;
201
+    }
202
+
203
+    /**
204
+     * Get the Bcc address of this message.
205
+     *
206
+     * @return array
207
+     */
208
+    public function getBcc(): array {
209
+        return $this->swiftMessage->getBcc() ?? [];
210
+    }
211
+
212
+    /**
213
+     * Set the subject of this message.
214
+     *
215
+     * @param string $subject
216
+     * @return IMessage
217
+     */
218
+    public function setSubject(string $subject): IMessage {
219
+        $this->swiftMessage->setSubject($subject);
220
+        return $this;
221
+    }
222
+
223
+    /**
224
+     * Get the from subject of this message.
225
+     *
226
+     * @return string
227
+     */
228
+    public function getSubject(): string {
229
+        return $this->swiftMessage->getSubject();
230
+    }
231
+
232
+    /**
233
+     * Set the plain-text body of this message.
234
+     *
235
+     * @param string $body
236
+     * @return $this
237
+     */
238
+    public function setPlainBody(string $body): IMessage {
239
+        $this->swiftMessage->setBody($body);
240
+        return $this;
241
+    }
242
+
243
+    /**
244
+     * Get the plain body of this message.
245
+     *
246
+     * @return string
247
+     */
248
+    public function getPlainBody(): string {
249
+        return $this->swiftMessage->getBody();
250
+    }
251
+
252
+    /**
253
+     * Set the HTML body of this message. Consider also sending a plain-text body instead of only an HTML one.
254
+     *
255
+     * @param string $body
256
+     * @return $this
257
+     */
258
+    public function setHtmlBody($body) {
259
+        if (!$this->plainTextOnly) {
260
+            $this->swiftMessage->addPart($body, 'text/html');
261
+        }
262
+        return $this;
263
+    }
264
+
265
+    /**
266
+     * Get's the underlying SwiftMessage
267
+     * @param Swift_Message $swiftMessage
268
+     */
269
+    public function setSwiftMessage(Swift_Message $swiftMessage): void {
270
+        $this->swiftMessage = $swiftMessage;
271
+    }
272
+
273
+    /**
274
+     * Get's the underlying SwiftMessage
275
+     * @return Swift_Message
276
+     */
277
+    public function getSwiftMessage(): Swift_Message {
278
+        return $this->swiftMessage;
279
+    }
280
+
281
+    /**
282
+     * @param string $body
283
+     * @param string $contentType
284
+     * @return $this
285
+     */
286
+    public function setBody($body, $contentType) {
287
+        if (!$this->plainTextOnly || $contentType !== 'text/html') {
288
+            $this->swiftMessage->setBody($body, $contentType);
289
+        }
290
+        return $this;
291
+    }
292
+
293
+    /**
294
+     * @param IEMailTemplate $emailTemplate
295
+     * @return $this
296
+     */
297
+    public function useTemplate(IEMailTemplate $emailTemplate): IMessage {
298
+        $this->setSubject($emailTemplate->renderSubject());
299
+        $this->setPlainBody($emailTemplate->renderText());
300
+        if (!$this->plainTextOnly) {
301
+            $this->setHtmlBody($emailTemplate->renderHtml());
302
+        }
303
+        return $this;
304
+    }
305
+
306
+    /**
307
+     * Add the Auto-Submitted header to the email, preventing most automated
308
+     * responses to automated messages.
309
+     *
310
+     * @param AutoSubmitted::VALUE_* $value (one of AutoSubmitted::VALUE_NO, AutoSubmitted::VALUE_AUTO_GENERATED, AutoSubmitted::VALUE_AUTO_REPLIED)
311
+     * @return $this
312
+     */
313
+    public function setAutoSubmitted(string $value): IMessage {
314
+        $headers = $this->swiftMessage->getHeaders();
315
+
316
+        if ($headers->has(AutoSubmitted::HEADER)) {
317
+            // if the header already exsists, remove it.
318
+            // the value can be modified with some implementations
319
+            // of the interface \Swift_Mime_Header, however the
320
+            // interface doesn't, and this makes the static-code
321
+            // analysis unhappy.
322
+            $headers->remove(AutoSubmitted::HEADER);
323
+        }
324
+
325
+        $headers->addTextHeader(AutoSubmitted::HEADER, $value);
326
+
327
+        return $this;
328
+    }
329
+
330
+    /**
331
+     * Get the current value of the Auto-Submitted header. Defaults to "no"
332
+     * which is equivalent to the header not existing at all
333
+     *
334
+     * @return string
335
+     */
336
+    public function getAutoSubmitted(): string {
337
+        $headers = $this->swiftMessage->getHeaders();
338
+
339
+        return $headers->has(AutoSubmitted::HEADER) ?
340
+            $headers->get(AutoSubmitted::HEADER)->toString() : AutoSubmitted::VALUE_NO;
341
+    }
342 342
 }
Please login to merge, or discard this patch.
apps/dav/lib/CalDAV/Reminder/NotificationProvider/EmailProvider.php 1 patch
Indentation   +410 added lines, -410 removed lines patch added patch discarded remove patch
@@ -52,414 +52,414 @@
 block discarded – undo
52 52
  * @package OCA\DAV\CalDAV\Reminder\NotificationProvider
53 53
  */
54 54
 class EmailProvider extends AbstractProvider {
55
-	/** @var string */
56
-	public const NOTIFICATION_TYPE = 'EMAIL';
57
-
58
-	private IMailer $mailer;
59
-
60
-	public function __construct(IConfig $config,
61
-								IMailer $mailer,
62
-								LoggerInterface $logger,
63
-								L10NFactory $l10nFactory,
64
-								IURLGenerator $urlGenerator) {
65
-		parent::__construct($logger, $l10nFactory, $urlGenerator, $config);
66
-		$this->mailer = $mailer;
67
-	}
68
-
69
-	/**
70
-	 * Send out notification via email
71
-	 *
72
-	 * @param VEvent $vevent
73
-	 * @param string $calendarDisplayName
74
-	 * @param string[] $principalEmailAddresses
75
-	 * @param array $users
76
-	 * @throws \Exception
77
-	 */
78
-	public function send(VEvent $vevent,
79
-						 string $calendarDisplayName,
80
-						 array $principalEmailAddresses,
81
-						 array $users = []):void {
82
-		$fallbackLanguage = $this->getFallbackLanguage();
83
-
84
-		$organizerEmailAddress = null;
85
-		if (isset($vevent->ORGANIZER)) {
86
-			$organizerEmailAddress = $this->getEMailAddressOfAttendee($vevent->ORGANIZER);
87
-		}
88
-
89
-		$emailAddressesOfSharees = $this->getEMailAddressesOfAllUsersWithWriteAccessToCalendar($users);
90
-		$emailAddressesOfAttendees = [];
91
-		if (count($principalEmailAddresses) === 0
92
-			|| ($organizerEmailAddress && in_array($organizerEmailAddress, $principalEmailAddresses, true))
93
-		) {
94
-			$emailAddressesOfAttendees = $this->getAllEMailAddressesFromEvent($vevent);
95
-		}
96
-
97
-		// Quote from php.net:
98
-		// If the input arrays have the same string keys, then the later value for that key will overwrite the previous one.
99
-		// => if there are duplicate email addresses, it will always take the system value
100
-		$emailAddresses = array_merge(
101
-			$emailAddressesOfAttendees,
102
-			$emailAddressesOfSharees
103
-		);
104
-
105
-		$sortedByLanguage = $this->sortEMailAddressesByLanguage($emailAddresses, $fallbackLanguage);
106
-		$organizer = $this->getOrganizerEMailAndNameFromEvent($vevent);
107
-
108
-		foreach ($sortedByLanguage as $lang => $emailAddresses) {
109
-			if (!$this->hasL10NForLang($lang)) {
110
-				$lang = $fallbackLanguage;
111
-			}
112
-			$l10n = $this->getL10NForLang($lang);
113
-			$fromEMail = \OCP\Util::getDefaultEmailAddress('reminders-noreply');
114
-
115
-			$template = $this->mailer->createEMailTemplate('dav.calendarReminder');
116
-			$template->addHeader();
117
-			$this->addSubjectAndHeading($template, $l10n, $vevent);
118
-			$this->addBulletList($template, $l10n, $calendarDisplayName, $vevent);
119
-			$template->addFooter();
120
-
121
-			foreach ($emailAddresses as $emailAddress) {
122
-				if (!$this->mailer->validateMailAddress($emailAddress)) {
123
-					$this->logger->error('Email address {address} for reminder notification is incorrect', ['app' => 'dav', 'address' => $emailAddress]);
124
-					continue;
125
-				}
126
-
127
-				$message = $this->mailer->createMessage();
128
-				$message->setFrom([$fromEMail]);
129
-				if ($organizer) {
130
-					$message->setReplyTo($organizer);
131
-				}
132
-				$message->setTo([$emailAddress]);
133
-				$message->useTemplate($template);
134
-				$message->setAutoSubmitted(AutoSubmitted::VALUE_AUTO_GENERATED);
135
-
136
-				try {
137
-					$failed = $this->mailer->send($message);
138
-					if ($failed) {
139
-						$this->logger->error('Unable to deliver message to {failed}', ['app' => 'dav', 'failed' => implode(', ', $failed)]);
140
-					}
141
-				} catch (\Exception $ex) {
142
-					$this->logger->error($ex->getMessage(), ['app' => 'dav', 'exception' => $ex]);
143
-				}
144
-			}
145
-		}
146
-	}
147
-
148
-	/**
149
-	 * @param IEMailTemplate $template
150
-	 * @param IL10N $l10n
151
-	 * @param VEvent $vevent
152
-	 */
153
-	private function addSubjectAndHeading(IEMailTemplate $template, IL10N $l10n, VEvent $vevent):void {
154
-		$template->setSubject('Notification: ' . $this->getTitleFromVEvent($vevent, $l10n));
155
-		$template->addHeading($this->getTitleFromVEvent($vevent, $l10n));
156
-	}
157
-
158
-	/**
159
-	 * @param IEMailTemplate $template
160
-	 * @param IL10N $l10n
161
-	 * @param string $calendarDisplayName
162
-	 * @param array $eventData
163
-	 */
164
-	private function addBulletList(IEMailTemplate $template,
165
-								   IL10N $l10n,
166
-								   string $calendarDisplayName,
167
-								   VEvent $vevent):void {
168
-		$template->addBodyListItem($calendarDisplayName, $l10n->t('Calendar:'),
169
-			$this->getAbsoluteImagePath('actions/info.png'));
170
-
171
-		$template->addBodyListItem($this->generateDateString($l10n, $vevent), $l10n->t('Date:'),
172
-			$this->getAbsoluteImagePath('places/calendar.png'));
173
-
174
-		if (isset($vevent->LOCATION)) {
175
-			$template->addBodyListItem((string) $vevent->LOCATION, $l10n->t('Where:'),
176
-				$this->getAbsoluteImagePath('actions/address.png'));
177
-		}
178
-		if (isset($vevent->DESCRIPTION)) {
179
-			$template->addBodyListItem((string) $vevent->DESCRIPTION, $l10n->t('Description:'),
180
-				$this->getAbsoluteImagePath('actions/more.png'));
181
-		}
182
-	}
183
-
184
-	private function getAbsoluteImagePath(string $path):string {
185
-		return $this->urlGenerator->getAbsoluteURL(
186
-			$this->urlGenerator->imagePath('core', $path)
187
-		);
188
-	}
189
-
190
-	/**
191
-	 * @param VEvent $vevent
192
-	 * @return array|null
193
-	 */
194
-	private function getOrganizerEMailAndNameFromEvent(VEvent $vevent):?array {
195
-		if (!$vevent->ORGANIZER) {
196
-			return null;
197
-		}
198
-
199
-		$organizer = $vevent->ORGANIZER;
200
-		if (strcasecmp($organizer->getValue(), 'mailto:') !== 0) {
201
-			return null;
202
-		}
203
-
204
-		$organizerEMail = substr($organizer->getValue(), 7);
205
-
206
-		if (!$this->mailer->validateMailAddress($organizerEMail)) {
207
-			return null;
208
-		}
209
-
210
-		$name = $organizer->offsetGet('CN');
211
-		if ($name instanceof Parameter) {
212
-			return [$organizerEMail => $name];
213
-		}
214
-
215
-		return [$organizerEMail];
216
-	}
217
-
218
-	/**
219
-	 * @param array<string, array{LANG?: string}> $emails
220
-	 * @return array<string, string[]>
221
-	 */
222
-	private function sortEMailAddressesByLanguage(array $emails,
223
-												  string $defaultLanguage):array {
224
-		$sortedByLanguage = [];
225
-
226
-		foreach ($emails as $emailAddress => $parameters) {
227
-			if (isset($parameters['LANG'])) {
228
-				$lang = $parameters['LANG'];
229
-			} else {
230
-				$lang = $defaultLanguage;
231
-			}
232
-
233
-			if (!isset($sortedByLanguage[$lang])) {
234
-				$sortedByLanguage[$lang] = [];
235
-			}
236
-
237
-			$sortedByLanguage[$lang][] = $emailAddress;
238
-		}
239
-
240
-		return $sortedByLanguage;
241
-	}
242
-
243
-	/**
244
-	 * @param VEvent $vevent
245
-	 * @return array<string, array{LANG?: string}>
246
-	 */
247
-	private function getAllEMailAddressesFromEvent(VEvent $vevent):array {
248
-		$emailAddresses = [];
249
-
250
-		if (isset($vevent->ATTENDEE)) {
251
-			foreach ($vevent->ATTENDEE as $attendee) {
252
-				if (!($attendee instanceof VObject\Property)) {
253
-					continue;
254
-				}
255
-
256
-				$cuType = $this->getCUTypeOfAttendee($attendee);
257
-				if (\in_array($cuType, ['RESOURCE', 'ROOM', 'UNKNOWN'])) {
258
-					// Don't send emails to things
259
-					continue;
260
-				}
261
-
262
-				$partstat = $this->getPartstatOfAttendee($attendee);
263
-				if ($partstat === 'DECLINED') {
264
-					// Don't send out emails to people who declined
265
-					continue;
266
-				}
267
-				if ($partstat === 'DELEGATED') {
268
-					$delegates = $attendee->offsetGet('DELEGATED-TO');
269
-					if (!($delegates instanceof VObject\Parameter)) {
270
-						continue;
271
-					}
272
-
273
-					$emailAddressesOfDelegates = $delegates->getParts();
274
-					foreach ($emailAddressesOfDelegates as $addressesOfDelegate) {
275
-						if (strcasecmp($addressesOfDelegate, 'mailto:') === 0) {
276
-							$delegateEmail = substr($addressesOfDelegate, 7);
277
-							if ($this->mailer->validateMailAddress($delegateEmail)) {
278
-								$emailAddresses[$delegateEmail] = [];
279
-							}
280
-						}
281
-					}
282
-
283
-					continue;
284
-				}
285
-
286
-				$emailAddressOfAttendee = $this->getEMailAddressOfAttendee($attendee);
287
-				if ($emailAddressOfAttendee !== null) {
288
-					$properties = [];
289
-
290
-					$langProp = $attendee->offsetGet('LANG');
291
-					if ($langProp instanceof VObject\Parameter && $langProp->getValue() !== null) {
292
-						$properties['LANG'] = $langProp->getValue();
293
-					}
294
-
295
-					$emailAddresses[$emailAddressOfAttendee] = $properties;
296
-				}
297
-			}
298
-		}
299
-
300
-		if (isset($vevent->ORGANIZER) && $this->hasAttendeeMailURI($vevent->ORGANIZER)) {
301
-			$organizerEmailAddress = $this->getEMailAddressOfAttendee($vevent->ORGANIZER);
302
-			if ($organizerEmailAddress !== null) {
303
-				$emailAddresses[$organizerEmailAddress] = [];
304
-			}
305
-		}
306
-
307
-		return $emailAddresses;
308
-	}
309
-
310
-	private function getCUTypeOfAttendee(VObject\Property $attendee):string {
311
-		$cuType = $attendee->offsetGet('CUTYPE');
312
-		if ($cuType instanceof VObject\Parameter) {
313
-			return strtoupper($cuType->getValue());
314
-		}
315
-
316
-		return 'INDIVIDUAL';
317
-	}
318
-
319
-	private function getPartstatOfAttendee(VObject\Property $attendee):string {
320
-		$partstat = $attendee->offsetGet('PARTSTAT');
321
-		if ($partstat instanceof VObject\Parameter) {
322
-			return strtoupper($partstat->getValue());
323
-		}
324
-
325
-		return 'NEEDS-ACTION';
326
-	}
327
-
328
-	private function hasAttendeeMailURI(VObject\Property $attendee): bool {
329
-		return stripos($attendee->getValue(), 'mailto:') === 0;
330
-	}
331
-
332
-	private function getEMailAddressOfAttendee(VObject\Property $attendee): ?string {
333
-		if (!$this->hasAttendeeMailURI($attendee)) {
334
-			return null;
335
-		}
336
-		$attendeeEMail = substr($attendee->getValue(), 7);
337
-		if (!$this->mailer->validateMailAddress($attendeeEMail)) {
338
-			return null;
339
-		}
340
-
341
-		return $attendeeEMail;
342
-	}
343
-
344
-	/**
345
-	 * @param IUser[] $users
346
-	 * @return array<string, array{LANG?: string}>
347
-	 */
348
-	private function getEMailAddressesOfAllUsersWithWriteAccessToCalendar(array $users):array {
349
-		$emailAddresses = [];
350
-
351
-		foreach ($users as $user) {
352
-			$emailAddress = $user->getEMailAddress();
353
-			if ($emailAddress) {
354
-				$lang = $this->l10nFactory->getUserLanguage($user);
355
-				if ($lang) {
356
-					$emailAddresses[$emailAddress] = [
357
-						'LANG' => $lang,
358
-					];
359
-				} else {
360
-					$emailAddresses[$emailAddress] = [];
361
-				}
362
-			}
363
-		}
364
-
365
-		return $emailAddresses;
366
-	}
367
-
368
-	/**
369
-	 * @throws \Exception
370
-	 */
371
-	private function generateDateString(IL10N $l10n, VEvent $vevent): string {
372
-		$isAllDay = $vevent->DTSTART instanceof Property\ICalendar\Date;
373
-
374
-		/** @var Property\ICalendar\Date | Property\ICalendar\DateTime $dtstart */
375
-		/** @var Property\ICalendar\Date | Property\ICalendar\DateTime $dtend */
376
-		/** @var \DateTimeImmutable $dtstartDt */
377
-		$dtstartDt = $vevent->DTSTART->getDateTime();
378
-		/** @var \DateTimeImmutable $dtendDt */
379
-		$dtendDt = $this->getDTEndFromEvent($vevent)->getDateTime();
380
-
381
-		$diff = $dtstartDt->diff($dtendDt);
382
-
383
-		$dtstartDt = new \DateTime($dtstartDt->format(\DateTimeInterface::ATOM));
384
-		$dtendDt = new \DateTime($dtendDt->format(\DateTimeInterface::ATOM));
385
-
386
-		if ($isAllDay) {
387
-			// One day event
388
-			if ($diff->days === 1) {
389
-				return $this->getDateString($l10n, $dtstartDt);
390
-			}
391
-
392
-			return implode(' - ', [
393
-				$this->getDateString($l10n, $dtstartDt),
394
-				$this->getDateString($l10n, $dtendDt),
395
-			]);
396
-		}
397
-
398
-		$startTimezone = $endTimezone = null;
399
-		if (!$vevent->DTSTART->isFloating()) {
400
-			$startTimezone = $vevent->DTSTART->getDateTime()->getTimezone()->getName();
401
-			$endTimezone = $this->getDTEndFromEvent($vevent)->getDateTime()->getTimezone()->getName();
402
-		}
403
-
404
-		$localeStart = implode(', ', [
405
-			$this->getWeekDayName($l10n, $dtstartDt),
406
-			$this->getDateTimeString($l10n, $dtstartDt)
407
-		]);
408
-
409
-		// always show full date with timezone if timezones are different
410
-		if ($startTimezone !== $endTimezone) {
411
-			$localeEnd = implode(', ', [
412
-				$this->getWeekDayName($l10n, $dtendDt),
413
-				$this->getDateTimeString($l10n, $dtendDt)
414
-			]);
415
-
416
-			return $localeStart
417
-				. ' (' . $startTimezone . ') '
418
-				. ' - '
419
-				. $localeEnd
420
-				. ' (' . $endTimezone . ')';
421
-		}
422
-
423
-		// Show only the time if the day is the same
424
-		$localeEnd = $this->isDayEqual($dtstartDt, $dtendDt)
425
-			? $this->getTimeString($l10n, $dtendDt)
426
-			: implode(', ', [
427
-				$this->getWeekDayName($l10n, $dtendDt),
428
-				$this->getDateTimeString($l10n, $dtendDt)
429
-			]);
430
-
431
-		return $localeStart
432
-			. ' - '
433
-			. $localeEnd
434
-			. ' (' . $startTimezone . ')';
435
-	}
436
-
437
-	private function isDayEqual(DateTime $dtStart,
438
-								DateTime $dtEnd):bool {
439
-		return $dtStart->format('Y-m-d') === $dtEnd->format('Y-m-d');
440
-	}
441
-
442
-	private function getWeekDayName(IL10N $l10n, DateTime $dt):string {
443
-		return (string)$l10n->l('weekdayName', $dt, ['width' => 'abbreviated']);
444
-	}
445
-
446
-	private function getDateString(IL10N $l10n, DateTime $dt):string {
447
-		return (string)$l10n->l('date', $dt, ['width' => 'medium']);
448
-	}
449
-
450
-	private function getDateTimeString(IL10N $l10n, DateTime $dt):string {
451
-		return (string)$l10n->l('datetime', $dt, ['width' => 'medium|short']);
452
-	}
453
-
454
-	private function getTimeString(IL10N $l10n, DateTime $dt):string {
455
-		return (string)$l10n->l('time', $dt, ['width' => 'short']);
456
-	}
457
-
458
-	private function getTitleFromVEvent(VEvent $vevent, IL10N $l10n):string {
459
-		if (isset($vevent->SUMMARY)) {
460
-			return (string)$vevent->SUMMARY;
461
-		}
462
-
463
-		return $l10n->t('Untitled event');
464
-	}
55
+    /** @var string */
56
+    public const NOTIFICATION_TYPE = 'EMAIL';
57
+
58
+    private IMailer $mailer;
59
+
60
+    public function __construct(IConfig $config,
61
+                                IMailer $mailer,
62
+                                LoggerInterface $logger,
63
+                                L10NFactory $l10nFactory,
64
+                                IURLGenerator $urlGenerator) {
65
+        parent::__construct($logger, $l10nFactory, $urlGenerator, $config);
66
+        $this->mailer = $mailer;
67
+    }
68
+
69
+    /**
70
+     * Send out notification via email
71
+     *
72
+     * @param VEvent $vevent
73
+     * @param string $calendarDisplayName
74
+     * @param string[] $principalEmailAddresses
75
+     * @param array $users
76
+     * @throws \Exception
77
+     */
78
+    public function send(VEvent $vevent,
79
+                            string $calendarDisplayName,
80
+                            array $principalEmailAddresses,
81
+                            array $users = []):void {
82
+        $fallbackLanguage = $this->getFallbackLanguage();
83
+
84
+        $organizerEmailAddress = null;
85
+        if (isset($vevent->ORGANIZER)) {
86
+            $organizerEmailAddress = $this->getEMailAddressOfAttendee($vevent->ORGANIZER);
87
+        }
88
+
89
+        $emailAddressesOfSharees = $this->getEMailAddressesOfAllUsersWithWriteAccessToCalendar($users);
90
+        $emailAddressesOfAttendees = [];
91
+        if (count($principalEmailAddresses) === 0
92
+            || ($organizerEmailAddress && in_array($organizerEmailAddress, $principalEmailAddresses, true))
93
+        ) {
94
+            $emailAddressesOfAttendees = $this->getAllEMailAddressesFromEvent($vevent);
95
+        }
96
+
97
+        // Quote from php.net:
98
+        // If the input arrays have the same string keys, then the later value for that key will overwrite the previous one.
99
+        // => if there are duplicate email addresses, it will always take the system value
100
+        $emailAddresses = array_merge(
101
+            $emailAddressesOfAttendees,
102
+            $emailAddressesOfSharees
103
+        );
104
+
105
+        $sortedByLanguage = $this->sortEMailAddressesByLanguage($emailAddresses, $fallbackLanguage);
106
+        $organizer = $this->getOrganizerEMailAndNameFromEvent($vevent);
107
+
108
+        foreach ($sortedByLanguage as $lang => $emailAddresses) {
109
+            if (!$this->hasL10NForLang($lang)) {
110
+                $lang = $fallbackLanguage;
111
+            }
112
+            $l10n = $this->getL10NForLang($lang);
113
+            $fromEMail = \OCP\Util::getDefaultEmailAddress('reminders-noreply');
114
+
115
+            $template = $this->mailer->createEMailTemplate('dav.calendarReminder');
116
+            $template->addHeader();
117
+            $this->addSubjectAndHeading($template, $l10n, $vevent);
118
+            $this->addBulletList($template, $l10n, $calendarDisplayName, $vevent);
119
+            $template->addFooter();
120
+
121
+            foreach ($emailAddresses as $emailAddress) {
122
+                if (!$this->mailer->validateMailAddress($emailAddress)) {
123
+                    $this->logger->error('Email address {address} for reminder notification is incorrect', ['app' => 'dav', 'address' => $emailAddress]);
124
+                    continue;
125
+                }
126
+
127
+                $message = $this->mailer->createMessage();
128
+                $message->setFrom([$fromEMail]);
129
+                if ($organizer) {
130
+                    $message->setReplyTo($organizer);
131
+                }
132
+                $message->setTo([$emailAddress]);
133
+                $message->useTemplate($template);
134
+                $message->setAutoSubmitted(AutoSubmitted::VALUE_AUTO_GENERATED);
135
+
136
+                try {
137
+                    $failed = $this->mailer->send($message);
138
+                    if ($failed) {
139
+                        $this->logger->error('Unable to deliver message to {failed}', ['app' => 'dav', 'failed' => implode(', ', $failed)]);
140
+                    }
141
+                } catch (\Exception $ex) {
142
+                    $this->logger->error($ex->getMessage(), ['app' => 'dav', 'exception' => $ex]);
143
+                }
144
+            }
145
+        }
146
+    }
147
+
148
+    /**
149
+     * @param IEMailTemplate $template
150
+     * @param IL10N $l10n
151
+     * @param VEvent $vevent
152
+     */
153
+    private function addSubjectAndHeading(IEMailTemplate $template, IL10N $l10n, VEvent $vevent):void {
154
+        $template->setSubject('Notification: ' . $this->getTitleFromVEvent($vevent, $l10n));
155
+        $template->addHeading($this->getTitleFromVEvent($vevent, $l10n));
156
+    }
157
+
158
+    /**
159
+     * @param IEMailTemplate $template
160
+     * @param IL10N $l10n
161
+     * @param string $calendarDisplayName
162
+     * @param array $eventData
163
+     */
164
+    private function addBulletList(IEMailTemplate $template,
165
+                                    IL10N $l10n,
166
+                                    string $calendarDisplayName,
167
+                                    VEvent $vevent):void {
168
+        $template->addBodyListItem($calendarDisplayName, $l10n->t('Calendar:'),
169
+            $this->getAbsoluteImagePath('actions/info.png'));
170
+
171
+        $template->addBodyListItem($this->generateDateString($l10n, $vevent), $l10n->t('Date:'),
172
+            $this->getAbsoluteImagePath('places/calendar.png'));
173
+
174
+        if (isset($vevent->LOCATION)) {
175
+            $template->addBodyListItem((string) $vevent->LOCATION, $l10n->t('Where:'),
176
+                $this->getAbsoluteImagePath('actions/address.png'));
177
+        }
178
+        if (isset($vevent->DESCRIPTION)) {
179
+            $template->addBodyListItem((string) $vevent->DESCRIPTION, $l10n->t('Description:'),
180
+                $this->getAbsoluteImagePath('actions/more.png'));
181
+        }
182
+    }
183
+
184
+    private function getAbsoluteImagePath(string $path):string {
185
+        return $this->urlGenerator->getAbsoluteURL(
186
+            $this->urlGenerator->imagePath('core', $path)
187
+        );
188
+    }
189
+
190
+    /**
191
+     * @param VEvent $vevent
192
+     * @return array|null
193
+     */
194
+    private function getOrganizerEMailAndNameFromEvent(VEvent $vevent):?array {
195
+        if (!$vevent->ORGANIZER) {
196
+            return null;
197
+        }
198
+
199
+        $organizer = $vevent->ORGANIZER;
200
+        if (strcasecmp($organizer->getValue(), 'mailto:') !== 0) {
201
+            return null;
202
+        }
203
+
204
+        $organizerEMail = substr($organizer->getValue(), 7);
205
+
206
+        if (!$this->mailer->validateMailAddress($organizerEMail)) {
207
+            return null;
208
+        }
209
+
210
+        $name = $organizer->offsetGet('CN');
211
+        if ($name instanceof Parameter) {
212
+            return [$organizerEMail => $name];
213
+        }
214
+
215
+        return [$organizerEMail];
216
+    }
217
+
218
+    /**
219
+     * @param array<string, array{LANG?: string}> $emails
220
+     * @return array<string, string[]>
221
+     */
222
+    private function sortEMailAddressesByLanguage(array $emails,
223
+                                                    string $defaultLanguage):array {
224
+        $sortedByLanguage = [];
225
+
226
+        foreach ($emails as $emailAddress => $parameters) {
227
+            if (isset($parameters['LANG'])) {
228
+                $lang = $parameters['LANG'];
229
+            } else {
230
+                $lang = $defaultLanguage;
231
+            }
232
+
233
+            if (!isset($sortedByLanguage[$lang])) {
234
+                $sortedByLanguage[$lang] = [];
235
+            }
236
+
237
+            $sortedByLanguage[$lang][] = $emailAddress;
238
+        }
239
+
240
+        return $sortedByLanguage;
241
+    }
242
+
243
+    /**
244
+     * @param VEvent $vevent
245
+     * @return array<string, array{LANG?: string}>
246
+     */
247
+    private function getAllEMailAddressesFromEvent(VEvent $vevent):array {
248
+        $emailAddresses = [];
249
+
250
+        if (isset($vevent->ATTENDEE)) {
251
+            foreach ($vevent->ATTENDEE as $attendee) {
252
+                if (!($attendee instanceof VObject\Property)) {
253
+                    continue;
254
+                }
255
+
256
+                $cuType = $this->getCUTypeOfAttendee($attendee);
257
+                if (\in_array($cuType, ['RESOURCE', 'ROOM', 'UNKNOWN'])) {
258
+                    // Don't send emails to things
259
+                    continue;
260
+                }
261
+
262
+                $partstat = $this->getPartstatOfAttendee($attendee);
263
+                if ($partstat === 'DECLINED') {
264
+                    // Don't send out emails to people who declined
265
+                    continue;
266
+                }
267
+                if ($partstat === 'DELEGATED') {
268
+                    $delegates = $attendee->offsetGet('DELEGATED-TO');
269
+                    if (!($delegates instanceof VObject\Parameter)) {
270
+                        continue;
271
+                    }
272
+
273
+                    $emailAddressesOfDelegates = $delegates->getParts();
274
+                    foreach ($emailAddressesOfDelegates as $addressesOfDelegate) {
275
+                        if (strcasecmp($addressesOfDelegate, 'mailto:') === 0) {
276
+                            $delegateEmail = substr($addressesOfDelegate, 7);
277
+                            if ($this->mailer->validateMailAddress($delegateEmail)) {
278
+                                $emailAddresses[$delegateEmail] = [];
279
+                            }
280
+                        }
281
+                    }
282
+
283
+                    continue;
284
+                }
285
+
286
+                $emailAddressOfAttendee = $this->getEMailAddressOfAttendee($attendee);
287
+                if ($emailAddressOfAttendee !== null) {
288
+                    $properties = [];
289
+
290
+                    $langProp = $attendee->offsetGet('LANG');
291
+                    if ($langProp instanceof VObject\Parameter && $langProp->getValue() !== null) {
292
+                        $properties['LANG'] = $langProp->getValue();
293
+                    }
294
+
295
+                    $emailAddresses[$emailAddressOfAttendee] = $properties;
296
+                }
297
+            }
298
+        }
299
+
300
+        if (isset($vevent->ORGANIZER) && $this->hasAttendeeMailURI($vevent->ORGANIZER)) {
301
+            $organizerEmailAddress = $this->getEMailAddressOfAttendee($vevent->ORGANIZER);
302
+            if ($organizerEmailAddress !== null) {
303
+                $emailAddresses[$organizerEmailAddress] = [];
304
+            }
305
+        }
306
+
307
+        return $emailAddresses;
308
+    }
309
+
310
+    private function getCUTypeOfAttendee(VObject\Property $attendee):string {
311
+        $cuType = $attendee->offsetGet('CUTYPE');
312
+        if ($cuType instanceof VObject\Parameter) {
313
+            return strtoupper($cuType->getValue());
314
+        }
315
+
316
+        return 'INDIVIDUAL';
317
+    }
318
+
319
+    private function getPartstatOfAttendee(VObject\Property $attendee):string {
320
+        $partstat = $attendee->offsetGet('PARTSTAT');
321
+        if ($partstat instanceof VObject\Parameter) {
322
+            return strtoupper($partstat->getValue());
323
+        }
324
+
325
+        return 'NEEDS-ACTION';
326
+    }
327
+
328
+    private function hasAttendeeMailURI(VObject\Property $attendee): bool {
329
+        return stripos($attendee->getValue(), 'mailto:') === 0;
330
+    }
331
+
332
+    private function getEMailAddressOfAttendee(VObject\Property $attendee): ?string {
333
+        if (!$this->hasAttendeeMailURI($attendee)) {
334
+            return null;
335
+        }
336
+        $attendeeEMail = substr($attendee->getValue(), 7);
337
+        if (!$this->mailer->validateMailAddress($attendeeEMail)) {
338
+            return null;
339
+        }
340
+
341
+        return $attendeeEMail;
342
+    }
343
+
344
+    /**
345
+     * @param IUser[] $users
346
+     * @return array<string, array{LANG?: string}>
347
+     */
348
+    private function getEMailAddressesOfAllUsersWithWriteAccessToCalendar(array $users):array {
349
+        $emailAddresses = [];
350
+
351
+        foreach ($users as $user) {
352
+            $emailAddress = $user->getEMailAddress();
353
+            if ($emailAddress) {
354
+                $lang = $this->l10nFactory->getUserLanguage($user);
355
+                if ($lang) {
356
+                    $emailAddresses[$emailAddress] = [
357
+                        'LANG' => $lang,
358
+                    ];
359
+                } else {
360
+                    $emailAddresses[$emailAddress] = [];
361
+                }
362
+            }
363
+        }
364
+
365
+        return $emailAddresses;
366
+    }
367
+
368
+    /**
369
+     * @throws \Exception
370
+     */
371
+    private function generateDateString(IL10N $l10n, VEvent $vevent): string {
372
+        $isAllDay = $vevent->DTSTART instanceof Property\ICalendar\Date;
373
+
374
+        /** @var Property\ICalendar\Date | Property\ICalendar\DateTime $dtstart */
375
+        /** @var Property\ICalendar\Date | Property\ICalendar\DateTime $dtend */
376
+        /** @var \DateTimeImmutable $dtstartDt */
377
+        $dtstartDt = $vevent->DTSTART->getDateTime();
378
+        /** @var \DateTimeImmutable $dtendDt */
379
+        $dtendDt = $this->getDTEndFromEvent($vevent)->getDateTime();
380
+
381
+        $diff = $dtstartDt->diff($dtendDt);
382
+
383
+        $dtstartDt = new \DateTime($dtstartDt->format(\DateTimeInterface::ATOM));
384
+        $dtendDt = new \DateTime($dtendDt->format(\DateTimeInterface::ATOM));
385
+
386
+        if ($isAllDay) {
387
+            // One day event
388
+            if ($diff->days === 1) {
389
+                return $this->getDateString($l10n, $dtstartDt);
390
+            }
391
+
392
+            return implode(' - ', [
393
+                $this->getDateString($l10n, $dtstartDt),
394
+                $this->getDateString($l10n, $dtendDt),
395
+            ]);
396
+        }
397
+
398
+        $startTimezone = $endTimezone = null;
399
+        if (!$vevent->DTSTART->isFloating()) {
400
+            $startTimezone = $vevent->DTSTART->getDateTime()->getTimezone()->getName();
401
+            $endTimezone = $this->getDTEndFromEvent($vevent)->getDateTime()->getTimezone()->getName();
402
+        }
403
+
404
+        $localeStart = implode(', ', [
405
+            $this->getWeekDayName($l10n, $dtstartDt),
406
+            $this->getDateTimeString($l10n, $dtstartDt)
407
+        ]);
408
+
409
+        // always show full date with timezone if timezones are different
410
+        if ($startTimezone !== $endTimezone) {
411
+            $localeEnd = implode(', ', [
412
+                $this->getWeekDayName($l10n, $dtendDt),
413
+                $this->getDateTimeString($l10n, $dtendDt)
414
+            ]);
415
+
416
+            return $localeStart
417
+                . ' (' . $startTimezone . ') '
418
+                . ' - '
419
+                . $localeEnd
420
+                . ' (' . $endTimezone . ')';
421
+        }
422
+
423
+        // Show only the time if the day is the same
424
+        $localeEnd = $this->isDayEqual($dtstartDt, $dtendDt)
425
+            ? $this->getTimeString($l10n, $dtendDt)
426
+            : implode(', ', [
427
+                $this->getWeekDayName($l10n, $dtendDt),
428
+                $this->getDateTimeString($l10n, $dtendDt)
429
+            ]);
430
+
431
+        return $localeStart
432
+            . ' - '
433
+            . $localeEnd
434
+            . ' (' . $startTimezone . ')';
435
+    }
436
+
437
+    private function isDayEqual(DateTime $dtStart,
438
+                                DateTime $dtEnd):bool {
439
+        return $dtStart->format('Y-m-d') === $dtEnd->format('Y-m-d');
440
+    }
441
+
442
+    private function getWeekDayName(IL10N $l10n, DateTime $dt):string {
443
+        return (string)$l10n->l('weekdayName', $dt, ['width' => 'abbreviated']);
444
+    }
445
+
446
+    private function getDateString(IL10N $l10n, DateTime $dt):string {
447
+        return (string)$l10n->l('date', $dt, ['width' => 'medium']);
448
+    }
449
+
450
+    private function getDateTimeString(IL10N $l10n, DateTime $dt):string {
451
+        return (string)$l10n->l('datetime', $dt, ['width' => 'medium|short']);
452
+    }
453
+
454
+    private function getTimeString(IL10N $l10n, DateTime $dt):string {
455
+        return (string)$l10n->l('time', $dt, ['width' => 'short']);
456
+    }
457
+
458
+    private function getTitleFromVEvent(VEvent $vevent, IL10N $l10n):string {
459
+        if (isset($vevent->SUMMARY)) {
460
+            return (string)$vevent->SUMMARY;
461
+        }
462
+
463
+        return $l10n->t('Untitled event');
464
+    }
465 465
 }
Please login to merge, or discard this patch.
apps/settings/lib/Mailer/NewUserMailHelper.php 1 patch
Indentation   +132 added lines, -132 removed lines patch added patch discarded remove patch
@@ -42,147 +42,147 @@
 block discarded – undo
42 42
 use OCP\Security\ISecureRandom;
43 43
 
44 44
 class NewUserMailHelper {
45
-	/** @var Defaults */
46
-	private $themingDefaults;
47
-	/** @var IURLGenerator */
48
-	private $urlGenerator;
49
-	/** @var IFactory */
50
-	private $l10nFactory;
51
-	/** @var IMailer */
52
-	private $mailer;
53
-	/** @var ISecureRandom */
54
-	private $secureRandom;
55
-	/** @var ITimeFactory */
56
-	private $timeFactory;
57
-	/** @var IConfig */
58
-	private $config;
59
-	/** @var ICrypto */
60
-	private $crypto;
61
-	/** @var string */
62
-	private $fromAddress;
45
+    /** @var Defaults */
46
+    private $themingDefaults;
47
+    /** @var IURLGenerator */
48
+    private $urlGenerator;
49
+    /** @var IFactory */
50
+    private $l10nFactory;
51
+    /** @var IMailer */
52
+    private $mailer;
53
+    /** @var ISecureRandom */
54
+    private $secureRandom;
55
+    /** @var ITimeFactory */
56
+    private $timeFactory;
57
+    /** @var IConfig */
58
+    private $config;
59
+    /** @var ICrypto */
60
+    private $crypto;
61
+    /** @var string */
62
+    private $fromAddress;
63 63
 
64
-	/**
65
-	 * @param Defaults $themingDefaults
66
-	 * @param IURLGenerator $urlGenerator
67
-	 * @param IFactory $l10nFactory
68
-	 * @param IMailer $mailer
69
-	 * @param ISecureRandom $secureRandom
70
-	 * @param ITimeFactory $timeFactory
71
-	 * @param IConfig $config
72
-	 * @param ICrypto $crypto
73
-	 * @param string $fromAddress
74
-	 */
75
-	public function __construct(Defaults $themingDefaults,
76
-								IURLGenerator $urlGenerator,
77
-								IFactory $l10nFactory,
78
-								IMailer $mailer,
79
-								ISecureRandom $secureRandom,
80
-								ITimeFactory $timeFactory,
81
-								IConfig $config,
82
-								ICrypto $crypto,
83
-								$fromAddress) {
84
-		$this->themingDefaults = $themingDefaults;
85
-		$this->urlGenerator = $urlGenerator;
86
-		$this->l10nFactory = $l10nFactory;
87
-		$this->mailer = $mailer;
88
-		$this->secureRandom = $secureRandom;
89
-		$this->timeFactory = $timeFactory;
90
-		$this->config = $config;
91
-		$this->crypto = $crypto;
92
-		$this->fromAddress = $fromAddress;
93
-	}
64
+    /**
65
+     * @param Defaults $themingDefaults
66
+     * @param IURLGenerator $urlGenerator
67
+     * @param IFactory $l10nFactory
68
+     * @param IMailer $mailer
69
+     * @param ISecureRandom $secureRandom
70
+     * @param ITimeFactory $timeFactory
71
+     * @param IConfig $config
72
+     * @param ICrypto $crypto
73
+     * @param string $fromAddress
74
+     */
75
+    public function __construct(Defaults $themingDefaults,
76
+                                IURLGenerator $urlGenerator,
77
+                                IFactory $l10nFactory,
78
+                                IMailer $mailer,
79
+                                ISecureRandom $secureRandom,
80
+                                ITimeFactory $timeFactory,
81
+                                IConfig $config,
82
+                                ICrypto $crypto,
83
+                                $fromAddress) {
84
+        $this->themingDefaults = $themingDefaults;
85
+        $this->urlGenerator = $urlGenerator;
86
+        $this->l10nFactory = $l10nFactory;
87
+        $this->mailer = $mailer;
88
+        $this->secureRandom = $secureRandom;
89
+        $this->timeFactory = $timeFactory;
90
+        $this->config = $config;
91
+        $this->crypto = $crypto;
92
+        $this->fromAddress = $fromAddress;
93
+    }
94 94
 
95
-	/**
96
-	 * @param IUser $user
97
-	 * @param bool $generatePasswordResetToken
98
-	 * @return IEMailTemplate
99
-	 */
100
-	public function generateTemplate(IUser $user, $generatePasswordResetToken = false) {
101
-		$userId = $user->getUID();
102
-		$lang = $this->l10nFactory->getUserLanguage($user);
103
-		$l10n = $this->l10nFactory->get('settings', $lang);
95
+    /**
96
+     * @param IUser $user
97
+     * @param bool $generatePasswordResetToken
98
+     * @return IEMailTemplate
99
+     */
100
+    public function generateTemplate(IUser $user, $generatePasswordResetToken = false) {
101
+        $userId = $user->getUID();
102
+        $lang = $this->l10nFactory->getUserLanguage($user);
103
+        $l10n = $this->l10nFactory->get('settings', $lang);
104 104
 
105
-		if ($generatePasswordResetToken) {
106
-			$token = $this->secureRandom->generate(
107
-				21,
108
-				ISecureRandom::CHAR_ALPHANUMERIC
109
-			);
110
-			$tokenValue = $this->timeFactory->getTime() . ':' . $token;
111
-			$mailAddress = (null !== $user->getEMailAddress()) ? $user->getEMailAddress() : '';
112
-			$encryptedValue = $this->crypto->encrypt($tokenValue, $mailAddress . $this->config->getSystemValue('secret'));
113
-			$this->config->setUserValue($user->getUID(), 'core', 'lostpassword', $encryptedValue);
114
-			$link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', ['userId' => $user->getUID(), 'token' => $token]);
115
-		} else {
116
-			$link = $this->urlGenerator->getAbsoluteURL('/');
117
-		}
118
-		$displayName = $user->getDisplayName();
105
+        if ($generatePasswordResetToken) {
106
+            $token = $this->secureRandom->generate(
107
+                21,
108
+                ISecureRandom::CHAR_ALPHANUMERIC
109
+            );
110
+            $tokenValue = $this->timeFactory->getTime() . ':' . $token;
111
+            $mailAddress = (null !== $user->getEMailAddress()) ? $user->getEMailAddress() : '';
112
+            $encryptedValue = $this->crypto->encrypt($tokenValue, $mailAddress . $this->config->getSystemValue('secret'));
113
+            $this->config->setUserValue($user->getUID(), 'core', 'lostpassword', $encryptedValue);
114
+            $link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', ['userId' => $user->getUID(), 'token' => $token]);
115
+        } else {
116
+            $link = $this->urlGenerator->getAbsoluteURL('/');
117
+        }
118
+        $displayName = $user->getDisplayName();
119 119
 
120
-		$emailTemplate = $this->mailer->createEMailTemplate('settings.Welcome', [
121
-			'link' => $link,
122
-			'displayname' => $displayName,
123
-			'userid' => $userId,
124
-			'instancename' => $this->themingDefaults->getName(),
125
-			'resetTokenGenerated' => $generatePasswordResetToken,
126
-		]);
120
+        $emailTemplate = $this->mailer->createEMailTemplate('settings.Welcome', [
121
+            'link' => $link,
122
+            'displayname' => $displayName,
123
+            'userid' => $userId,
124
+            'instancename' => $this->themingDefaults->getName(),
125
+            'resetTokenGenerated' => $generatePasswordResetToken,
126
+        ]);
127 127
 
128
-		$emailTemplate->setSubject($l10n->t('Your %s account was created', [$this->themingDefaults->getName()]));
129
-		$emailTemplate->addHeader();
130
-		if ($displayName === $userId) {
131
-			$emailTemplate->addHeading($l10n->t('Welcome aboard'));
132
-		} else {
133
-			$emailTemplate->addHeading($l10n->t('Welcome aboard %s', [$displayName]));
134
-		}
135
-		$emailTemplate->addBodyText($l10n->t('Welcome to your %s account, you can add, protect, and share your data.', [$this->themingDefaults->getName()]));
136
-		if ($user->getBackendClassName() !== 'LDAP') {
137
-			$emailTemplate->addBodyText($l10n->t('Your username is: %s', [$userId]));
138
-		}
139
-		if ($generatePasswordResetToken) {
140
-			$leftButtonText = $l10n->t('Set your password');
141
-		} else {
142
-			$leftButtonText = $l10n->t('Go to %s', [$this->themingDefaults->getName()]);
143
-		}
128
+        $emailTemplate->setSubject($l10n->t('Your %s account was created', [$this->themingDefaults->getName()]));
129
+        $emailTemplate->addHeader();
130
+        if ($displayName === $userId) {
131
+            $emailTemplate->addHeading($l10n->t('Welcome aboard'));
132
+        } else {
133
+            $emailTemplate->addHeading($l10n->t('Welcome aboard %s', [$displayName]));
134
+        }
135
+        $emailTemplate->addBodyText($l10n->t('Welcome to your %s account, you can add, protect, and share your data.', [$this->themingDefaults->getName()]));
136
+        if ($user->getBackendClassName() !== 'LDAP') {
137
+            $emailTemplate->addBodyText($l10n->t('Your username is: %s', [$userId]));
138
+        }
139
+        if ($generatePasswordResetToken) {
140
+            $leftButtonText = $l10n->t('Set your password');
141
+        } else {
142
+            $leftButtonText = $l10n->t('Go to %s', [$this->themingDefaults->getName()]);
143
+        }
144 144
 
145
-		$clientDownload = $this->config->getSystemValue('customclient_desktop', 'https://nextcloud.com/install/#install-clients');
146
-		if ($clientDownload === '') {
147
-			$emailTemplate->addBodyButton(
148
-				$leftButtonText,
149
-				$link
150
-			);
151
-		} else {
152
-			$emailTemplate->addBodyButtonGroup(
153
-				$leftButtonText,
154
-				$link,
155
-				$l10n->t('Install Client'),
156
-				$clientDownload
157
-			);
158
-		}
145
+        $clientDownload = $this->config->getSystemValue('customclient_desktop', 'https://nextcloud.com/install/#install-clients');
146
+        if ($clientDownload === '') {
147
+            $emailTemplate->addBodyButton(
148
+                $leftButtonText,
149
+                $link
150
+            );
151
+        } else {
152
+            $emailTemplate->addBodyButtonGroup(
153
+                $leftButtonText,
154
+                $link,
155
+                $l10n->t('Install Client'),
156
+                $clientDownload
157
+            );
158
+        }
159 159
 
160
-		$emailTemplate->addFooter('', $lang);
160
+        $emailTemplate->addFooter('', $lang);
161 161
 
162
-		return $emailTemplate;
163
-	}
162
+        return $emailTemplate;
163
+    }
164 164
 
165
-	/**
166
-	 * Sends a welcome mail to $user
167
-	 *
168
-	 * @param IUser $user
169
-	 * @param IEmailTemplate $emailTemplate
170
-	 * @throws \Exception If mail could not be sent
171
-	 */
172
-	public function sendMail(IUser $user,
173
-							 IEMailTemplate $emailTemplate): void {
165
+    /**
166
+     * Sends a welcome mail to $user
167
+     *
168
+     * @param IUser $user
169
+     * @param IEmailTemplate $emailTemplate
170
+     * @throws \Exception If mail could not be sent
171
+     */
172
+    public function sendMail(IUser $user,
173
+                                IEMailTemplate $emailTemplate): void {
174 174
 
175
-		// Be sure to never try to send to an empty e-mail
176
-		$email = $user->getEMailAddress();
177
-		if ($email === null) {
178
-			return;
179
-		}
175
+        // Be sure to never try to send to an empty e-mail
176
+        $email = $user->getEMailAddress();
177
+        if ($email === null) {
178
+            return;
179
+        }
180 180
 
181
-		$message = $this->mailer->createMessage();
182
-		$message->setTo([$email => $user->getDisplayName()]);
183
-		$message->setFrom([$this->fromAddress => $this->themingDefaults->getName()]);
184
-		$message->useTemplate($emailTemplate);
185
-		$message->setAutoSubmitted(AutoSubmitted::VALUE_AUTO_GENERATED);
186
-		$this->mailer->send($message);
187
-	}
181
+        $message = $this->mailer->createMessage();
182
+        $message->setTo([$email => $user->getDisplayName()]);
183
+        $message->setFrom([$this->fromAddress => $this->themingDefaults->getName()]);
184
+        $message->useTemplate($emailTemplate);
185
+        $message->setAutoSubmitted(AutoSubmitted::VALUE_AUTO_GENERATED);
186
+        $this->mailer->send($message);
187
+    }
188 188
 }
Please login to merge, or discard this patch.