Elgg  Version 3.0
EmailService.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg;
4 
8 use Zend\Mail\Message as MailMessage;
10 use Zend\Mime\Mime;
11 use Zend\Mime\Message as MimeMessage;
12 use Zend\Mime\Part;
14 
23 class EmailService {
24 
25  use Loggable;
26 
30  private $config;
31 
35  private $hooks;
36 
40  private $mailer;
41 
50  public function __construct(Config $config, PluginHooksService $hooks, TransportInterface $mailer, LoggerInterface $logger) {
51  $this->config = $config;
52  $this->hooks = $hooks;
53  $this->mailer = $mailer;
54  $this->logger = $logger;
55  }
56 
65  public function send(Email $email) {
66  $email = $this->hooks->trigger('prepare', 'system:email', null, $email);
67  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  'email' => $email,
74  ];
75 
76  $is_valid = $email->getFrom() && $email->getTo();
77  if (!$this->hooks->trigger('validate', 'system:email', $hook_params, $is_valid)) {
78  return false;
79  }
80 
81  return $this->transport($email);
82  }
83 
92  public function transport(Email $email) {
93 
94  $hook_params = [
95  'email' => $email,
96  ];
97 
98  if ($this->hooks->trigger('transport', 'system:email', $hook_params, false)) {
99  return true;
100  }
101 
102  // create the e-mail message
103  $message = new MailMessage();
104  $message->setEncoding('UTF-8');
105  $message->setSender($email->getFrom());
106  $message->addFrom($email->getFrom());
107  $message->addTo($email->getTo());
108 
109  // set headers
110  $headers = [
111  "MIME-Version" => "1.0",
112  "Content-Transfer-Encoding" => "8bit",
113  ];
114  $headers = array_merge($headers, $email->getHeaders());
115 
116  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  $message->getHeaders()->addHeaderLine("{$name}: {$value}");
122  }
123 
124  // add the body to the message
125  try {
126  $body = $this->buildMessageBody($email);
127  } catch (InvalidArgumentException $e) {
128  $this->logger->error($e->getMessage());
129 
130  return false;
131  }
132 
133 
134  $message->setBody($body);
135 
136  // set Subject
137  $subject = elgg_strip_tags($email->getSubject());
138  $subject = html_entity_decode($subject, ENT_QUOTES, 'UTF-8');
139  // Sanitise subject by stripping line endings
140  $subject = preg_replace("/(\r\n|\r|\n)/", " ", $subject);
141  $subject = trim($subject);
142 
143  $message->setSubject($subject);
144 
145  // allow others to modify the $message content
146  // eg. add html body, add attachments
147  $message = $this->hooks->trigger('zend:message', 'system:email', $hook_params, $message);
148 
149  // fix content type header
150  // @see https://github.com/Elgg/Elgg/issues/12555
151  $ct = $message->getHeaders()->get('Content-Type');
152  if ($ct instanceof ContentType) {
153  $ct->addParameter('format', 'flowed');
154  }
155 
156  try {
157  $this->mailer->send($message);
158  } catch (RuntimeException $e) {
159  $this->logger->error($e->getMessage());
160 
161  return false;
162  }
163 
164  return true;
165  }
166 
175  protected function buildMessageBody(Email $email) {
176  // create body
177  $body = new MimeMessage();
178 
179  // add plain text part
180  $plain_text = elgg_strip_tags($email->getBody());
181  $plain_text = html_entity_decode($plain_text, ENT_QUOTES, 'UTF-8');
182  $plain_text = wordwrap($plain_text);
183 
184  $plain_text_part = new Part($plain_text);
185  $plain_text_part->setId('plaintext');
186  $plain_text_part->setType(Mime::TYPE_TEXT);
187  $plain_text_part->setCharset('UTF-8');
188 
189  $body->addPart($plain_text_part);
190 
191  // process attachments
192  $attachments = $email->getAttachments();
193  foreach ($attachments as $attachement) {
194  $body->addPart($attachement);
195  }
196 
197  return $body;
198  }
199 
200 }
getTo()
Returns recipient address.
Definition: Email.php:123
if(!$user||!$user->canDelete()) $name
Definition: delete.php:22
elgg_strip_tags($string, $allowable_tags=null)
Strip tags and offer plugins the chance.
Definition: output.php:383
trait Loggable
Enables adding a logger.
Definition: Loggable.php:12
$email
Definition: register.php:18
transport(Email $email)
Transports an email.
$config
Advanced site settings, debugging section.
Definition: debugging.php:6
Configuration exception.
send(Email $email)
Sends an email.
Email message.
Definition: Email.php:15
getSubject()
Returns the subject.
Definition: Email.php:142
$body
Definition: useradd.php:60
getBody()
Returns email body.
Definition: Email.php:161
$value
Definition: debugging.php:7
$attachments
Outputs attachments.
Definition: attachments.php:9
buildMessageBody(Email $email)
Build the body part of the e-mail message.
getHeaders()
Returns headers.
Definition: Email.php:211
WARNING: API IN FLUX.
class
Definition: placeholder.php:21
getFrom()
Returns sender address.
Definition: Email.php:104
$subject
Definition: useradd.php:59
__construct(Config $config, PluginHooksService $hooks, TransportInterface $mailer, LoggerInterface $logger)
Constructor.
getAttachments()
Get all attachments.
Definition: Email.php:249