Passed
Push — master ( 7ce657...eef289 )
by Jeroen
28:05 queued 06:52
created

EmailService::buildMessageBody()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 23
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 2.0014

Importance

Changes 0
Metric Value
cc 2
eloc 13
nc 2
nop 1
dl 0
loc 23
ccs 13
cts 14
cp 0.9286
crap 2.0014
rs 9.0856
c 0
b 0
f 0
1
<?php
2
3
namespace Elgg;
4
5
use RuntimeException;
6
use Zend\Mail\Message as MailMessage;
7
use Zend\Mail\Transport\TransportInterface;
8
use Zend\Mime\Mime;
9
use Zend\Mime\Message as MimeMessage;
10
use Zend\Mime\Part;
11
12
/**
13
 * WARNING: API IN FLUX. DO NOT USE DIRECTLY.
14
 *
15
 * Use the elgg_* versions instead.
16
 *
17
 * @access private
18
 * @since  3.0
19
 */
20
class EmailService {
21
22
	/**
23
	 * @var Config
24
	 */
25
	private $config;
26
27
	/**
28
	 * @var PluginHooksService
29
	 */
30
	private $hooks;
31
32
	/**
33
	 * @var TransportInterface
34
	 */
35
	private $mailer;
36
37
	/**
38
	 * @var Logger
39
	 */
40
	private $logger;
41
42
	/**
43
	 * Constructor
44
	 *
45
	 * @param Config             $config Config
46
	 * @param PluginHooksService $hooks  Hook registration service
47
	 * @param TransportInterface $mailer Mailer
48
	 * @param Logger             $logger Logger
49
	 */
50 4
	public function __construct(Config $config, PluginHooksService $hooks, TransportInterface $mailer, Logger $logger) {
51 4
		$this->config = $config;
52 4
		$this->hooks = $hooks;
53 4
		$this->mailer = $mailer;
54 4
		$this->logger = $logger;
55 4
	}
56
57
	/**
58
	 * Sends an email
59
	 *
60
	 * @param Email $email Email
61
	 *
62
	 * @return bool
63
	 * @throws RuntimeException
64
	 */
65 3
	public function send(Email $email) {
66 3
		$email = $this->hooks->trigger('prepare', 'system:email', null, $email);
67 3
		if (!$email instanceof Email) {
68
			$msg = "'prepare','system:email' hook handlers should return an instance of " . Email::class;
69
			throw new RuntimeException($msg);
70
		}
71
72
		$hook_params = [
73 3
			'email' => $email,
74
		];
75
76 3
		$is_valid = $email->getFrom() && $email->getTo();
77 3
		if (!$this->hooks->trigger('validate', 'system:email', $hook_params, $is_valid)) {
78
			return false;
79
		}
80
81 3
		return $this->transport($email);
82
	}
83
84
	/**
85
	 * Transports an email
86
	 *
87
	 * @param Email $email Email
88
	 *
89
	 * @return bool
90
	 * @throws RuntimeException
91
	 */
92 3
	public function transport(Email $email) {
93
94
		$hook_params = [
95 3
			'email' => $email,
96
		];
97
98 3
		if ($this->hooks->trigger('transport', 'system:email', $hook_params, false)) {
99 1
			return true;
100
		}
101
102
		// create the e-mail message
103 2
		$message = new MailMessage();
104 2
		$message->setEncoding('UTF-8');
105 2
		$message->addFrom($email->getFrom());
106 2
		$message->addTo($email->getTo());
107
		
108
		// set headers
109
		$headers = [
110 2
			"Content-Type" => "text/plain; charset=UTF-8; format=flowed",
111
			"MIME-Version" => "1.0",
112
			"Content-Transfer-Encoding" => "8bit",
113
		];
114 2
		$headers = array_merge($headers, $email->getHeaders());
115
116 2
		foreach ($headers as $name => $value) {
117
			// See #11018
118
			// Create a headerline as a concatenated string "name: value"
119
			// This is done to force correct class detection for each header type,
120
			// which influences the output of the header in the message
121 2
			$message->getHeaders()->addHeaderLine("{$name}: {$value}");
122
		}
123
		
124
		// set Subject
125 2
		$subject = elgg_strip_tags($email->getSubject());
126 2
		$subject = html_entity_decode($subject, ENT_QUOTES, 'UTF-8');
127
		// Sanitise subject by stripping line endings
128 2
		$subject = preg_replace("/(\r\n|\r|\n)/", " ", $subject);
129 2
		$subject = trim($subject);
130
		
131 2
		$message->setSubject($subject);
132
		
133
		// add the body to the message
134 2
		$body = $this->buildMessageBody($email);
135 2
		$message->setBody($body);
136
137
		// allow others to modify the $message content
138
		// eg. add html body, add attachments
139 2
		$message = $this->hooks->trigger('zend:message', 'system:email', $hook_params, $message);
140
141
		try {
142 2
			$this->mailer->send($message);
143
		} catch (RuntimeException $e) {
144
			$this->logger->error($e->getMessage());
145
146
			return false;
147
		}
148
149 2
		return true;
150
	}
151
	
152
	/**
153
	 * Build the body part of the e-mail message
154
	 *
155
	 * @param Email $email Email
156
	 *
157
	 * @return \Zend\Mime\Message
158
	 */
159 2
	protected function buildMessageBody(Email $email) {
160
		// create body
161 2
		$body = new MimeMessage();
162
		
163
		// add plain text part
164 2
		$plain_text = elgg_strip_tags($email->getBody());
165 2
		$plain_text = html_entity_decode($plain_text, ENT_QUOTES, 'UTF-8');
166 2
		$plain_text = wordwrap($plain_text);
167
		
168 2
		$plain_text_part = new Part($plain_text);
169 2
		$plain_text_part->setId('plaintext');
170 2
		$plain_text_part->setType(Mime::TYPE_TEXT);
171 2
		$plain_text_part->setCharset('UTF-8');
172
		
173 2
		$body->addPart($plain_text_part);
174
		
175
		// process attachements
176 2
		$attachements = $email->getAttachments();
177 2
		foreach ($attachements as $attachement) {
178
			$body->addPart($attachement);
179
		}
180
		
181 2
		return $body;
182
	}
183
184
}
185