Completed
Push — master ( 1fb7be...e8e72a )
by Lukas
15:57
created

MailNotifications   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 192
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 192
rs 10
wmc 14
lcom 1
cbo 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 16 1
B sendInternalShareMail() 0 60 7
B sendLinkShareMail() 0 29 3
A createMailBody() 0 19 2
A getItemSharedWithUser() 0 3 1
1
<?php
2
/**
3
 * @author Björn Schießle <[email protected]>
4
 * @author Joas Schilling <[email protected]>
5
 * @author Lukas Reschke <[email protected]>
6
 * @author Morris Jobke <[email protected]>
7
 * @author Robin McCorkell <[email protected]>
8
 * @author scolebrook <[email protected]>
9
 * @author Thomas Müller <[email protected]>
10
 * @author Tom Needham <[email protected]>
11
 *
12
 * @copyright Copyright (c) 2016, ownCloud, Inc.
13
 * @license AGPL-3.0
14
 *
15
 * This code is free software: you can redistribute it and/or modify
16
 * it under the terms of the GNU Affero General Public License, version 3,
17
 * as published by the Free Software Foundation.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
 * GNU Affero General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU Affero General Public License, version 3,
25
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
26
 *
27
 */
28
29
namespace OC\Share;
30
31
use DateTime;
32
use OCP\IL10N;
33
use OCP\IURLGenerator;
34
use OCP\IUser;
35
use OCP\Mail\IMailer;
36
use OCP\ILogger;
37
use OCP\Defaults;
38
use OCP\Util;
39
40
/**
41
 * Class MailNotifications
42
 *
43
 * @package OC\Share
44
 */
45
class MailNotifications {
46
47
	/** @var IUser sender userId */
48
	private $user;
49
	/** @var string sender email address */
50
	private $replyTo;
51
	/** @var string */
52
	private $senderDisplayName;
53
	/** @var IL10N */
54
	private $l;
55
	/** @var IMailer */
56
	private $mailer;
57
	/** @var Defaults */
58
	private $defaults;
59
	/** @var ILogger */
60
	private $logger;
61
	/** @var IURLGenerator */
62
	private $urlGenerator;
63
64
	/**
65
	 * @param IUser $user
66
	 * @param IL10N $l10n
67
	 * @param IMailer $mailer
68
	 * @param ILogger $logger
69
	 * @param Defaults $defaults
70
	 * @param IURLGenerator $urlGenerator
71
	 */
72
	public function __construct(IUser $user,
73
								IL10N $l10n,
74
								IMailer $mailer,
75
								ILogger $logger,
76
								Defaults $defaults,
77
								IURLGenerator $urlGenerator) {
78
		$this->l = $l10n;
79
		$this->user = $user;
80
		$this->mailer = $mailer;
81
		$this->logger = $logger;
82
		$this->defaults = $defaults;
83
		$this->urlGenerator = $urlGenerator;
84
85
		$this->replyTo = $this->user->getEMailAddress();
86
		$this->senderDisplayName = $this->user->getDisplayName();
87
	}
88
89
	/**
90
	 * inform users if a file was shared with them
91
	 *
92
	 * @param IUser[] $recipientList list of recipients
93
	 * @param string $itemSource shared item source
94
	 * @param string $itemType shared item type
95
	 * @return array list of user to whom the mail send operation failed
96
	 */
97
	public function sendInternalShareMail($recipientList, $itemSource, $itemType) {
98
		$noMail = [];
99
100
		foreach ($recipientList as $recipient) {
101
			$recipientDisplayName = $recipient->getDisplayName();
102
			$to = $recipient->getEMailAddress();
103
104
			if ($to === '') {
105
				$noMail[] = $recipientDisplayName;
106
				continue;
107
			}
108
109
			$items = $this->getItemSharedWithUser($itemSource, $itemType, $recipient);
110
			$filename = trim($items[0]['file_target'], '/');
111
			$subject = (string) $this->l->t('%s shared »%s« with you', array($this->senderDisplayName, $filename));
112
			$expiration = null;
113
			if (isset($items[0]['expiration'])) {
114
				try {
115
					$date = new DateTime($items[0]['expiration']);
116
					$expiration = $date->getTimestamp();
117
				} catch (\Exception $e) {
118
					$this->logger->error("Couldn't read date: ".$e->getMessage(), ['app' => 'sharing']);
119
				}
120
			}
121
122
			$link = $this->urlGenerator->linkToRouteAbsolute(
123
				'files.viewcontroller.showFile',
124
				['fileId' => $items[0]['item_source']]
125
			);
126
127
			list($htmlBody, $textBody) = $this->createMailBody($filename, $link, $expiration, 'internal');
128
129
			// send it out now
130
			try {
131
				$message = $this->mailer->createMessage();
132
				$message->setSubject($subject);
133
				$message->setTo([$to => $recipientDisplayName]);
134
				$message->setHtmlBody($htmlBody);
0 ignored issues
show
Bug introduced by
It seems like $htmlBody defined by $this->createMailBody($f...expiration, 'internal') on line 127 can also be of type boolean; however, OC\Mail\Message::setHtmlBody() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
135
				$message->setPlainBody($textBody);
0 ignored issues
show
Bug introduced by
It seems like $textBody defined by $this->createMailBody($f...expiration, 'internal') on line 127 can also be of type boolean; however, OC\Mail\Message::setPlainBody() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
136
				$message->setFrom([
137
					Util::getDefaultEmailAddress('sharing-noreply') =>
138
						(string)$this->l->t('%s via %s', [
139
							$this->senderDisplayName,
140
							$this->defaults->getName()
141
						]),
142
					]);
143
				if(!is_null($this->replyTo)) {
144
					$message->setReplyTo([$this->replyTo]);
145
				}
146
147
				$this->mailer->send($message);
148
			} catch (\Exception $e) {
149
				$this->logger->error("Can't send mail to inform the user about an internal share: ".$e->getMessage(), ['app' => 'sharing']);
150
				$noMail[] = $recipientDisplayName;
151
			}
152
		}
153
154
		return $noMail;
155
156
	}
157
158
	/**
159
	 * inform recipient about public link share
160
	 *
161
	 * @param string $recipient recipient email address
162
	 * @param string $filename the shared file
163
	 * @param string $link the public link
164
	 * @param int $expiration expiration date (timestamp)
165
	 * @return string[] $result of failed recipients
166
	 */
167
	public function sendLinkShareMail($recipient, $filename, $link, $expiration) {
168
		$subject = (string)$this->l->t('%s shared »%s« with you', [$this->senderDisplayName, $filename]);
169
		list($htmlBody, $textBody) = $this->createMailBody($filename, $link, $expiration);
170
171
		$recipient = str_replace([', ', '; ', ',', ';', ' '], ',', $recipient);
172
		$recipients = explode(',', $recipient);
173
		try {
174
			$message = $this->mailer->createMessage();
175
			$message->setSubject($subject);
176
			$message->setTo($recipients);
177
			$message->setHtmlBody($htmlBody);
0 ignored issues
show
Bug introduced by
It seems like $htmlBody defined by $this->createMailBody($f...me, $link, $expiration) on line 169 can also be of type boolean; however, OC\Mail\Message::setHtmlBody() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
178
			$message->setPlainBody($textBody);
0 ignored issues
show
Bug introduced by
It seems like $textBody defined by $this->createMailBody($f...me, $link, $expiration) on line 169 can also be of type boolean; however, OC\Mail\Message::setPlainBody() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
179
			$message->setFrom([
180
				Util::getDefaultEmailAddress('sharing-noreply') =>
181
					(string)$this->l->t('%s via %s', [
182
						$this->senderDisplayName,
183
						$this->defaults->getName()
184
					]),
185
			]);
186
			if(!is_null($this->replyTo)) {
187
				$message->setReplyTo([$this->replyTo]);
188
			}
189
190
			return $this->mailer->send($message);
191
		} catch (\Exception $e) {
192
			$this->logger->error("Can't send mail with public link to $recipient: ".$e->getMessage(), ['app' => 'sharing']);
193
			return [$recipient];
194
		}
195
	}
196
197
	/**
198
	 * create mail body for plain text and html mail
199
	 *
200
	 * @param string $filename the shared file
201
	 * @param string $link link to the shared file
202
	 * @param int $expiration expiration date (timestamp)
203
	 * @param string $prefix prefix of mail template files
204
	 * @return array an array of the html mail body and the plain text mail body
205
	 */
206
	private function createMailBody($filename, $link, $expiration, $prefix = '') {
207
		$formattedDate = $expiration ? $this->l->l('date', $expiration) : null;
208
209
		$html = new \OC_Template('core', $prefix . 'mail', '');
210
		$html->assign ('link', $link);
211
		$html->assign ('user_displayname', $this->senderDisplayName);
212
		$html->assign ('filename', $filename);
213
		$html->assign('expiration',  $formattedDate);
214
		$htmlMail = $html->fetchPage();
215
216
		$plainText = new \OC_Template('core', $prefix . 'altmail', '');
217
		$plainText->assign ('link', $link);
218
		$plainText->assign ('user_displayname', $this->senderDisplayName);
219
		$plainText->assign ('filename', $filename);
220
		$plainText->assign('expiration', $formattedDate);
221
		$plainTextMail = $plainText->fetchPage();
222
223
		return [$htmlMail, $plainTextMail];
224
	}
225
226
	/**
227
	 * @param string $itemSource
228
	 * @param string $itemType
229
	 * @param IUser $recipient
230
	 * @return array
231
	 */
232
	protected function getItemSharedWithUser($itemSource, $itemType, $recipient) {
233
		return Share::getItemSharedWithUser($itemType, $itemSource, $recipient->getUID());
234
	}
235
236
}
237