統計
| ブランチ: | リビジョン:

pictcode / lib / Cake / Controller / Component / EmailComponent.php @ 635eef61

履歴 | 表示 | アノテート | ダウンロード (10.505 KB)

1
<?php
2
/**
3
 * Email Component
4
 *
5
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
6
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
7
 *
8
 * Licensed under The MIT License
9
 * For full copyright and license information, please see the LICENSE.txt
10
 * Redistributions of files must retain the above copyright notice.
11
 *
12
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
13
 * @link          http://cakephp.org CakePHP(tm) Project
14
 * @package       Cake.Controller.Component
15
 * @since         CakePHP(tm) v 1.2.0.3467
16
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
 */
18

    
19
App::uses('Component', 'Controller');
20
App::uses('Multibyte', 'I18n');
21
App::uses('CakeEmail', 'Network/Email');
22

    
23
/**
24
 * EmailComponent
25
 *
26
 * This component is used for handling Internet Message Format based
27
 * based on the standard outlined in http://www.rfc-editor.org/rfc/rfc2822.txt
28
 *
29
 * @package       Cake.Controller.Component
30
 * @link          http://book.cakephp.org/2.0/en/core-libraries/components/email.html
31
 * @link          http://book.cakephp.org/2.0/en/core-utility-libraries/email.html
32
 * @deprecated    3.0.0 Will be removed in 3.0. Use Network/CakeEmail instead
33
 */
34
class EmailComponent extends Component {
35

    
36
/**
37
 * Recipient of the email
38
 *
39
 * @var string
40
 */
41
        public $to = null;
42

    
43
/**
44
 * The mail which the email is sent from
45
 *
46
 * @var string
47
 */
48
        public $from = null;
49

    
50
/**
51
 * The email the recipient will reply to
52
 *
53
 * @var string
54
 */
55
        public $replyTo = null;
56

    
57
/**
58
 * The read receipt email
59
 *
60
 * @var string
61
 */
62
        public $readReceipt = null;
63

    
64
/**
65
 * The mail that will be used in case of any errors like
66
 * - Remote mailserver down
67
 * - Remote user has exceeded his quota
68
 * - Unknown user
69
 *
70
 * @var string
71
 */
72
        public $return = null;
73

    
74
/**
75
 * Carbon Copy
76
 *
77
 * List of email's that should receive a copy of the email.
78
 * The Recipient WILL be able to see this list
79
 *
80
 * @var array
81
 */
82
        public $cc = array();
83

    
84
/**
85
 * Blind Carbon Copy
86
 *
87
 * List of email's that should receive a copy of the email.
88
 * The Recipient WILL NOT be able to see this list
89
 *
90
 * @var array
91
 */
92
        public $bcc = array();
93

    
94
/**
95
 * The date to put in the Date: header. This should be a date
96
 * conforming with the RFC2822 standard. Leave null, to have
97
 * today's date generated.
98
 *
99
 * @var string
100
 */
101
        public $date = null;
102

    
103
/**
104
 * The subject of the email
105
 *
106
 * @var string
107
 */
108
        public $subject = null;
109

    
110
/**
111
 * Associative array of a user defined headers
112
 * Keys will be prefixed 'X-' as per RFC2822 Section 4.7.5
113
 *
114
 * @var array
115
 */
116
        public $headers = array();
117

    
118
/**
119
 * List of additional headers
120
 *
121
 * These will NOT be used if you are using safemode and mail()
122
 *
123
 * @var string
124
 */
125
        public $additionalParams = null;
126

    
127
/**
128
 * Layout for the View
129
 *
130
 * @var string
131
 */
132
        public $layout = 'default';
133

    
134
/**
135
 * Template for the view
136
 *
137
 * @var string
138
 */
139
        public $template = null;
140

    
141
/**
142
 * Line feed character(s) to be used when sending using mail() function
143
 * By default PHP_EOL is used.
144
 * RFC2822 requires it to be CRLF but some Unix
145
 * mail transfer agents replace LF by CRLF automatically
146
 * (which leads to doubling CR if CRLF is used).
147
 *
148
 * @var string
149
 */
150
        public $lineFeed = PHP_EOL;
151

    
152
/**
153
 * What format should the email be sent in
154
 *
155
 * Supported formats:
156
 * - text
157
 * - html
158
 * - both
159
 *
160
 * @var string
161
 */
162
        public $sendAs = 'text';
163

    
164
/**
165
 * What method should the email be sent by
166
 *
167
 * Supported methods:
168
 * - mail
169
 * - smtp
170
 * - debug
171
 *
172
 * @var string
173
 */
174
        public $delivery = 'mail';
175

    
176
/**
177
 * charset the email is sent in
178
 *
179
 * @var string
180
 */
181
        public $charset = 'utf-8';
182

    
183
/**
184
 * List of files that should be attached to the email.
185
 *
186
 * Can be both absolute and relative paths
187
 *
188
 * @var array
189
 */
190
        public $attachments = array();
191

    
192
/**
193
 * What mailer should EmailComponent identify itself as
194
 *
195
 * @var string
196
 */
197
        public $xMailer = 'CakePHP Email Component';
198

    
199
/**
200
 * The list of paths to search if an attachment isn't absolute
201
 *
202
 * @var array
203
 */
204
        public $filePaths = array();
205

    
206
/**
207
 * List of options to use for smtp mail method
208
 *
209
 * Options is:
210
 * - port
211
 * - host
212
 * - timeout
213
 * - username
214
 * - password
215
 * - client
216
 *
217
 * @var array
218
 */
219
        public $smtpOptions = array();
220

    
221
/**
222
 * Contains the rendered plain text message if one was sent.
223
 *
224
 * @var string
225
 */
226
        public $textMessage = null;
227

    
228
/**
229
 * Contains the rendered HTML message if one was sent.
230
 *
231
 * @var string
232
 */
233
        public $htmlMessage = null;
234

    
235
/**
236
 * Whether to generate a Message-ID header for the
237
 * e-mail. True to generate a Message-ID, False to let
238
 * it be handled by sendmail (or similar) or a string
239
 * to completely override the Message-ID.
240
 *
241
 * If you are sending Email from a shell, be sure to set this value. As you
242
 * could encounter delivery issues if you do not.
243
 *
244
 * @var mixed
245
 */
246
        public $messageId = true;
247

    
248
/**
249
 * Controller reference
250
 *
251
 * @var Controller
252
 */
253
        protected $_controller = null;
254

    
255
/**
256
 * Constructor
257
 *
258
 * @param ComponentCollection $collection A ComponentCollection this component can use to lazy load its components
259
 * @param array $settings Array of configuration settings.
260
 */
261
        public function __construct(ComponentCollection $collection, $settings = array()) {
262
                $this->_controller = $collection->getController();
263
                parent::__construct($collection, $settings);
264
        }
265

    
266
/**
267
 * Initialize component
268
 *
269
 * @param Controller $controller Instantiating controller
270
 * @return void
271
 */
272
        public function initialize(Controller $controller) {
273
                if (Configure::read('App.encoding') !== null) {
274
                        $this->charset = Configure::read('App.encoding');
275
                }
276
        }
277

    
278
/**
279
 * Send an email using the specified content, template and layout
280
 *
281
 * @param string|array $content Either an array of text lines, or a string with contents
282
 *  If you are rendering a template this variable will be sent to the templates as `$content`
283
 * @param string $template Template to use when sending email
284
 * @param string $layout Layout to use to enclose email body
285
 * @return bool Success
286
 */
287
        public function send($content = null, $template = null, $layout = null) {
288
                $lib = new CakeEmail();
289
                $lib->charset = $this->charset;
290
                $lib->headerCharset = $this->charset;
291

    
292
                $lib->from($this->_formatAddresses((array)$this->from));
293
                if (!empty($this->to)) {
294
                        $lib->to($this->_formatAddresses((array)$this->to));
295
                }
296
                if (!empty($this->cc)) {
297
                        $lib->cc($this->_formatAddresses((array)$this->cc));
298
                }
299
                if (!empty($this->bcc)) {
300
                        $lib->bcc($this->_formatAddresses((array)$this->bcc));
301
                }
302
                if (!empty($this->replyTo)) {
303
                        $lib->replyTo($this->_formatAddresses((array)$this->replyTo));
304
                }
305
                if (!empty($this->return)) {
306
                        $lib->returnPath($this->_formatAddresses((array)$this->return));
307
                }
308
                if (!empty($this->readReceipt)) {
309
                        $lib->readReceipt($this->_formatAddresses((array)$this->readReceipt));
310
                }
311

    
312
                $lib->subject($this->subject);
313
                $lib->messageID($this->messageId);
314
                $lib->helpers($this->_controller->helpers);
315

    
316
                $headers = array('X-Mailer' => $this->xMailer);
317
                foreach ($this->headers as $key => $value) {
318
                        $headers['X-' . $key] = $value;
319
                }
320
                if ($this->date) {
321
                        $headers['Date'] = $this->date;
322
                }
323
                $lib->setHeaders($headers);
324

    
325
                if ($template) {
326
                        $this->template = $template;
327
                }
328
                if ($layout) {
329
                        $this->layout = $layout;
330
                }
331
                $lib->template($this->template, $this->layout)->viewVars($this->_controller->viewVars)->emailFormat($this->sendAs);
332

    
333
                if (!empty($this->attachments)) {
334
                        $lib->attachments($this->_formatAttachFiles());
335
                }
336

    
337
                $lib->transport(ucfirst($this->delivery));
338
                if ($this->delivery === 'mail') {
339
                        $lib->config(array('eol' => $this->lineFeed, 'additionalParameters' => $this->additionalParams));
340
                } elseif ($this->delivery === 'smtp') {
341
                        $lib->config($this->smtpOptions);
342
                } else {
343
                        $lib->config(array());
344
                }
345

    
346
                $sent = $lib->send($content);
347

    
348
                $this->htmlMessage = $lib->message(CakeEmail::MESSAGE_HTML);
349
                if (empty($this->htmlMessage)) {
350
                        $this->htmlMessage = null;
351
                }
352
                $this->textMessage = $lib->message(CakeEmail::MESSAGE_TEXT);
353
                if (empty($this->textMessage)) {
354
                        $this->textMessage = null;
355
                }
356

    
357
                $this->_header = array();
358
                $this->_message = array();
359

    
360
                return $sent;
361
        }
362

    
363
/**
364
 * Reset all EmailComponent internal variables to be able to send out a new email.
365
 *
366
 * @return void
367
 */
368
        public function reset() {
369
                $this->template = null;
370
                $this->to = array();
371
                $this->from = null;
372
                $this->replyTo = null;
373
                $this->return = null;
374
                $this->cc = array();
375
                $this->bcc = array();
376
                $this->subject = null;
377
                $this->additionalParams = null;
378
                $this->date = null;
379
                $this->attachments = array();
380
                $this->htmlMessage = null;
381
                $this->textMessage = null;
382
                $this->messageId = true;
383
                $this->delivery = 'mail';
384
        }
385

    
386
/**
387
 * Format the attach array
388
 *
389
 * @return array
390
 */
391
        protected function _formatAttachFiles() {
392
                $files = array();
393
                foreach ($this->attachments as $filename => $attachment) {
394
                        $file = $this->_findFiles($attachment);
395
                        if (!empty($file)) {
396
                                if (is_int($filename)) {
397
                                        $filename = basename($file);
398
                                }
399
                                $files[$filename] = $file;
400
                        }
401
                }
402
                return $files;
403
        }
404

    
405
/**
406
 * Find the specified attachment in the list of file paths
407
 *
408
 * @param string $attachment Attachment file name to find
409
 * @return string|null Path to located file
410
 */
411
        protected function _findFiles($attachment) {
412
                if (file_exists($attachment)) {
413
                        return $attachment;
414
                }
415
                foreach ($this->filePaths as $path) {
416
                        if (file_exists($path . DS . $attachment)) {
417
                                $file = $path . DS . $attachment;
418
                                return $file;
419
                        }
420
                }
421
                return null;
422
        }
423

    
424
/**
425
 * Format addresses to be an array with email as key and alias as value
426
 *
427
 * @param array $addresses Address to format.
428
 * @return array
429
 */
430
        protected function _formatAddresses($addresses) {
431
                $formatted = array();
432
                foreach ($addresses as $address) {
433
                        if (preg_match('/((.*))?\s?<(.+)>/', $address, $matches) && !empty($matches[2])) {
434
                                $formatted[$this->_strip($matches[3])] = $matches[2];
435
                        } else {
436
                                $address = $this->_strip($address);
437
                                $formatted[$address] = $address;
438
                        }
439
                }
440
                return $formatted;
441
        }
442

    
443
/**
444
 * Remove certain elements (such as bcc:, to:, %0a) from given value.
445
 * Helps prevent header injection / manipulation on user content.
446
 *
447
 * @param string $value Value to strip
448
 * @param bool $message Set to true to indicate main message content
449
 * @return string Stripped value
450
 */
451
        protected function _strip($value, $message = false) {
452
                $search = '%0a|%0d|Content-(?:Type|Transfer-Encoding)\:';
453
                $search .= '|charset\=|mime-version\:|multipart/mixed|(?:[^a-z]to|b?cc)\:.*';
454

    
455
                if ($message !== true) {
456
                        $search .= '|\r|\n';
457
                }
458
                $search = '#(?:' . $search . ')#i';
459
                while (preg_match($search, $value)) {
460
                        $value = preg_replace($search, '', $value);
461
                }
462
                return $value;
463
        }
464

    
465
}