1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* YAWIK |
4
|
|
|
* |
5
|
|
|
* @filesource |
6
|
|
|
* @copyright (c) 2013 - 2016 Cross Solution (http://cross-solution.de) |
7
|
|
|
* @license MIT |
8
|
|
|
*/ |
9
|
|
|
|
10
|
|
|
/** */ |
11
|
|
|
namespace Core\Mail; |
12
|
|
|
|
13
|
|
|
use Core\Factory\ContainerAwareInterface; |
14
|
|
|
use Interop\Container\ContainerInterface; |
15
|
|
|
use Zend\I18n\Translator\TranslatorAwareInterface; |
16
|
|
|
use Zend\Mail\Address; |
17
|
|
|
use Zend\Mail\AddressList; |
18
|
|
|
use Zend\Mail\Message as MailMessage; |
19
|
|
|
use Zend\Mail\Transport\TransportInterface; |
20
|
|
|
use Zend\ServiceManager\AbstractPluginManager; |
21
|
|
|
use Zend\ServiceManager\ConfigInterface; |
22
|
|
|
use Zend\ServiceManager\ServiceLocatorInterface; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* Mail Plugin Manager |
26
|
|
|
* |
27
|
|
|
* @author Mathias Gelhausen <[email protected]> |
28
|
|
|
* @author Mathias Weitz <[email protected]> |
29
|
|
|
* @author Carsten Bleek <[email protected]> |
30
|
|
|
* @author Anthonius Munthi <[email protected]> |
31
|
|
|
*/ |
32
|
|
|
class MailService extends AbstractPluginManager |
33
|
|
|
{ |
34
|
|
|
/** |
35
|
|
|
* Define transport type to use |
36
|
|
|
*/ |
37
|
|
|
const TRANSPORT_SMTP = 'smtp'; |
38
|
|
|
const TRANSPORT_FILE = 'file'; |
39
|
|
|
const TRANSPORT_SENDMAIL = 'sendmail'; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* The mail Transport |
43
|
|
|
* |
44
|
|
|
* @var TransportInterface |
45
|
|
|
*/ |
46
|
|
|
protected $transport; |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* Default from address to use if no from address is set in the mail. |
50
|
|
|
* |
51
|
|
|
* @var string |
52
|
|
|
*/ |
53
|
|
|
protected $from; |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* Value for the X-Mailer header. |
57
|
|
|
* |
58
|
|
|
* @var string |
59
|
|
|
*/ |
60
|
|
|
protected $mailer; |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* If set, all mails are send to the addresses in this list |
64
|
|
|
* |
65
|
|
|
* This is useful when developing. |
66
|
|
|
* |
67
|
|
|
* @var AddressList|null |
68
|
|
|
*/ |
69
|
|
|
protected $overrideRecipient; |
70
|
|
|
|
71
|
|
|
protected $language; |
72
|
|
|
|
73
|
|
|
protected $shareByDefault = false; |
74
|
|
|
|
75
|
|
|
protected $invokableClasses = array( |
76
|
|
|
'simple' => '\Zend\Mail\Message', |
77
|
|
|
'stringtemplate' => '\Core\Mail\StringTemplateMessage', |
78
|
|
|
); |
79
|
|
|
|
80
|
|
|
protected $factories = array( |
81
|
|
|
'htmltemplate' => [HTMLTemplateMessage::class,'factory'], |
82
|
|
|
); |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* Creates an instance. |
86
|
|
|
* |
87
|
|
|
* Adds two default initializers: |
88
|
|
|
* - Inject the translator to mails implementing TranslatorAwareInterface |
89
|
|
|
* - Call init() method on Mails if such method exists. |
90
|
|
|
* |
91
|
|
|
* @param ContainerInterface $container |
92
|
|
|
* @param mixed $configuration |
93
|
|
|
*/ |
94
|
|
|
public function __construct($container, $configuration = []) |
95
|
|
|
{ |
96
|
|
|
parent::__construct($container,$configuration); |
97
|
|
|
|
98
|
|
|
$this->addInitializer( |
99
|
|
|
function ($context,$instance){ |
100
|
|
|
if ($instance instanceof TranslatorAwareInterface) { |
101
|
|
|
$translator = $context->get('translator'); |
102
|
|
|
$instance->setTranslator($translator); |
103
|
|
|
if (null === $instance->getTranslatorTextDomain()) { |
104
|
|
|
$instance->setTranslatorTextDomain(); |
105
|
|
|
} |
106
|
|
|
$instance->setTranslatorEnabled(true); |
107
|
|
|
} |
108
|
|
|
if($instance instanceof ContainerAwareInterface){ |
109
|
|
|
$instance->setContainer($context); |
110
|
|
|
} |
111
|
|
|
} |
112
|
|
|
); |
113
|
|
|
|
114
|
|
|
//@TODO: [ZF3] verify that removing this lines is save |
115
|
|
|
//$this->addInitializer( |
116
|
|
|
// function ($context,$instance) { |
|
|
|
|
117
|
|
|
// if (method_exists($instance, 'setServiceLocator')) { |
|
|
|
|
118
|
|
|
// //$instance->setServiceLocator($this); |
119
|
|
|
// } |
120
|
|
|
// } |
121
|
|
|
//); |
122
|
|
|
|
123
|
|
|
$this->addInitializer( |
124
|
|
|
function ($context,$instance){ |
125
|
|
|
if (method_exists($instance, 'init')) { |
126
|
|
|
$instance->init(); |
127
|
|
|
} |
128
|
|
|
} |
129
|
|
|
); |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
/** |
133
|
|
|
* Checks that a plugin is a child of an email message. |
134
|
|
|
* |
135
|
|
|
* @throws \InvalidArgumentException |
136
|
|
|
*/ |
137
|
|
|
public function validate($plugin) |
138
|
|
|
{ |
139
|
|
|
if (!$plugin instanceof MailMessage) { |
140
|
|
|
throw new \InvalidArgumentException( |
141
|
|
|
sprintf( |
142
|
|
|
'Expected instance of \Zend\Mail\Message but received %s', |
143
|
|
|
get_class($plugin) |
144
|
|
|
) |
145
|
|
|
); |
146
|
|
|
} |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
/** |
150
|
|
|
* Gets the default from address |
151
|
|
|
* |
152
|
|
|
* @return null|String|Address|AddressList|array |
153
|
|
|
*/ |
154
|
|
|
public function getFrom() |
155
|
|
|
{ |
156
|
|
|
return $this->from; |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
/** |
160
|
|
|
* Sets the default from address. |
161
|
|
|
* |
162
|
|
|
* @param string|AddressList|Address $email |
163
|
|
|
* @param String|null $name |
164
|
|
|
* |
165
|
|
|
* @return self |
166
|
|
|
*/ |
167
|
|
|
public function setFrom($email, $name = null) |
168
|
|
|
{ |
169
|
|
|
if(is_array($email)){ |
170
|
|
|
$this->from = [$email['email'] => $email['name']]; |
|
|
|
|
171
|
|
|
}else{ |
172
|
|
|
$this->from = is_object($email) || null === $name |
173
|
|
|
? $email |
174
|
|
|
: array($email => $name); |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
return $this; |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
/** |
181
|
|
|
* Sets override recipients. |
182
|
|
|
* |
183
|
|
|
* @param AddressList $recipients |
184
|
|
|
* |
185
|
|
|
* @return self |
186
|
|
|
*/ |
187
|
|
|
public function setOverrideRecipient(AddressList $recipients) |
188
|
|
|
{ |
189
|
|
|
$this->overrideRecipient = $recipients; |
190
|
|
|
|
191
|
|
|
return $this; |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
/** |
195
|
|
|
* Sends a mail. |
196
|
|
|
* |
197
|
|
|
* Sets default values where needed. |
198
|
|
|
* |
199
|
|
|
* @param string|MailMessage $mail |
200
|
|
|
* @param array $options |
201
|
|
|
*/ |
202
|
|
|
public function send($mail, array $options = array()) |
203
|
|
|
{ |
204
|
|
|
if (!$mail instanceof MailMessage) { |
205
|
|
|
$mail = $this->get($mail, $options); |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
$headers = $mail->getHeaders(); |
209
|
|
|
$transport = $this->getTransport(); |
210
|
|
|
|
211
|
|
|
if (!$mail->isValid() && $this->from) { |
212
|
|
|
$mail->setFrom($this->from); |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
if ($this->overrideRecipient instanceof AddressList) { |
216
|
|
|
$originalRecipient = $headers->get('to')->toString(); |
217
|
|
|
if ($headers->has('cc')) { |
218
|
|
|
$originalRecipient .= '; ' . $headers->get('cc')->toString(); |
219
|
|
|
$headers->removeHeader('cc'); |
220
|
|
|
} |
221
|
|
|
if ($headers->has('bcc')) { |
222
|
|
|
$originalRecipient .= '; ' . $headers->get('bcc')->toString(); |
223
|
|
|
$headers->removeHeader('bcc'); |
224
|
|
|
} |
225
|
|
|
$headers->addHeaderLine('X-Original-Recipients', $originalRecipient); |
226
|
|
|
$mail->setTo($this->overrideRecipient); |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
if (!$headers->has('X-Mailer')) { |
230
|
|
|
$mailerHeader = new \Zend\Mail\Header\GenericHeader('X-Mailer', $this->getMailer()); |
231
|
|
|
$headers->addHeader($mailerHeader); |
232
|
|
|
$mailerHeader->setEncoding('ASCII'); // get rid of other encodings for this header! |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
/* Allow HTMLTemplateMails to alter subject in the view script. |
236
|
|
|
* As the Zend Transport class build subject before the getBodyText call, |
237
|
|
|
* we have to call it here. |
238
|
|
|
*/ |
239
|
|
|
if ($mail instanceOf \Core\Mail\HTMLTemplateMessage) { |
240
|
|
|
$mail->getBodyText(); |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
$transport->send($mail); |
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
/** |
247
|
|
|
* Gets the transport. |
248
|
|
|
* |
249
|
|
|
* @return TransportInterface $transport |
250
|
|
|
*/ |
251
|
|
|
public function getTransport() |
252
|
|
|
{ |
253
|
|
|
return $this->transport; |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
/** |
257
|
|
|
* Sets the transport |
258
|
|
|
* |
259
|
|
|
* @param TransportInterface $transport |
260
|
|
|
* |
261
|
|
|
* @return self |
262
|
|
|
*/ |
263
|
|
|
public function setTransport(TransportInterface $transport) |
264
|
|
|
{ |
265
|
|
|
$this->transport = $transport; |
266
|
|
|
|
267
|
|
|
return $this; |
268
|
|
|
} |
269
|
|
|
|
270
|
|
|
/** |
271
|
|
|
* Gest the value of the X-Mailer header. |
272
|
|
|
* |
273
|
|
|
* @return string |
274
|
|
|
*/ |
275
|
|
|
public function getMailer() |
276
|
|
|
{ |
277
|
|
|
return $this->mailer; |
278
|
|
|
} |
279
|
|
|
|
280
|
|
|
/** |
281
|
|
|
* Sets the value for the X-Mailer header |
282
|
|
|
* |
283
|
|
|
* @param string $mailer |
284
|
|
|
* |
285
|
|
|
* @return $this |
286
|
|
|
*/ |
287
|
|
|
public function setMailer($mailer) |
288
|
|
|
{ |
289
|
|
|
$this->mailer = $mailer; |
290
|
|
|
|
291
|
|
|
return $this; |
292
|
|
|
} |
293
|
|
|
} |
294
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.