OSDN Git Service

79033664d06b7cb88a88aa508a5383a0f926aea0
[ethna/ethna.git] / class / Ethna_MailSender.php
1 <?php
2 // vim: foldmethod=marker
3 /**
4  *  Ethna_MailSender.php
5  *
6  *  @author     Masaki Fujimoto <fujimoto@php.net>
7  *  @license    http://www.opensource.org/licenses/bsd-license.php The BSD License
8  *  @package    Ethna
9  *  @version    $Id$
10  */
11
12 /** ¥á¡¼¥ë¥Æ¥ó¥×¥ì¡¼¥È¥¿¥¤¥×: Ä¾ÀÜÁ÷¿® */
13 define('MAILSENDER_TYPE_DIRECT', 0);
14
15
16 // {{{ Ethna_MailSender
17 /**
18  *  ¥á¡¼¥ëÁ÷¿®¥¯¥é¥¹
19  *
20  *  @author     Masaki Fujimoto <fujimoto@php.net>
21  *  @access     public
22  *  @package    Ethna
23  */
24 class Ethna_MailSender
25 {
26     /**#@+
27      *  @access private
28      */
29
30     /** @var    array   ¥á¡¼¥ë¥Æ¥ó¥×¥ì¡¼¥ÈÄêµÁ */
31     var $def = array(
32     );
33
34     /** @var    string  ¥á¡¼¥ë¥Æ¥ó¥×¥ì¡¼¥È¥Ç¥£¥ì¥¯¥È¥ê */
35     var $mail_dir = 'mail';
36
37     /** @var    int     Á÷¿®¥á¡¼¥ë¥¿¥¤¥× */
38     var $type;
39
40     /** @var    string  Á÷¿®¥ª¥×¥·¥ç¥ó */
41     var $option = '';
42
43     /** @var    object  Ethna_Backend   backend¥ª¥Ö¥¸¥§¥¯¥È */
44     var $backend;
45
46     /** @var    object  Ethna_Config    ÀßÄꥪ¥Ö¥¸¥§¥¯¥È */
47     var $config;
48
49     /**#@-*/
50
51     /**
52      *  Ethna_MailSender¥¯¥é¥¹¤Î¥³¥ó¥¹¥È¥é¥¯¥¿
53      *
54      *  @access public
55      *  @param  object  Ethna_Backend   &$backend       backend¥ª¥Ö¥¸¥§¥¯¥È
56      */
57     function Ethna_MailSender(&$backend)
58     {
59         $this->backend =& $backend;
60         $this->config =& $this->backend->getConfig();
61     }
62
63     /**
64      *  ¥á¡¼¥ë¥ª¥×¥·¥ç¥ó¤òÀßÄꤹ¤ë
65      *
66      *  @access public
67      *  @param  string  $option ¥á¡¼¥ëÁ÷¿®¥ª¥×¥·¥ç¥ó
68      */
69     function setOption($option)
70     {
71         $this->option = $option;
72     }
73
74     /**
75      *  ¥á¡¼¥ë¤òÁ÷¿®¤¹¤ë
76      *
77      *  $attach ¤Î»ØÄêÊýË¡:
78      *  - ´û¸¤Î¥Õ¥¡¥¤¥ë¤òźÉÕ¤¹¤ë¤È¤­
79      *  <code>
80      *  array('filename' => '/tmp/hoge.xls', 'content-type' => 'application/vnd.ms-excel')
81      *  </code>
82      *  - Ê¸»úÎó¤Ë̾Á°¤òÉÕ¤±¤ÆźÉÕ¤¹¤ë¤È¤­
83      *  <code>
84      *  array('name' => 'foo.txt', 'content' => 'this is foo.')
85      *  </code>
86      *  'content-type' ¾Êά»þ¤Ï 'application/octet-stream' ¤È¤Ê¤ë¡£
87      *  Ê£¿ôźÉÕ¤¹¤ë¤È¤­¤Ï¾å¤ÎÇÛÎó¤òź»ú0¤«¤é»Ï¤Þ¤ë¤Õ¤Ä¤¦¤ÎÇÛÎó¤ËÆþ¤ì¤ë¡£
88      *
89      *  @access public
90      *  @param  string  $to         ¥á¡¼¥ëÁ÷¿®À襢¥É¥ì¥¹ (null¤Î¤È¤­¤ÏÁ÷¿®¤»¤º¤ËÆâÍƤò return ¤¹¤ë)
91      *  @param  string  $template   ¥á¡¼¥ë¥Æ¥ó¥×¥ì¡¼¥È̾ or ¥¿¥¤¥×
92      *  @param  array   $macro      ¥Æ¥ó¥×¥ì¡¼¥È¥Þ¥¯¥í or $template¤¬MAILSENDER_TYPE_DIRECT¤Î¤È¤­¤Ï¥á¡¼¥ëÁ÷¿®ÆâÍÆ)
93      *  @param  array   $attach     ÅºÉÕ¥Õ¥¡¥¤¥ë
94      *  @return bool|string  mail() ´Ø¿ô¤ÎÌá¤êÃÍ or ¥á¡¼¥ëÆâÍÆ
95      */
96     function send($to, $template, $macro, $attach = null)
97     {
98         // ¥á¡¼¥ëÆâÍƤòºîÀ®
99         if ($template === MAILSENDER_TYPE_DIRECT) {
100             $mail = $macro;
101         } else {
102             $renderer =& $this->getTemplateEngine();
103
104             // ´ðËܾðÊóÀßÄê
105             $renderer->setProp("env_datetime", strftime('%Yǯ%m·î%dÆü %H»þ%Mʬ%SÉÃ'));
106             $renderer->setProp("env_useragent", $_SERVER["HTTP_USER_AGENT"]);
107             $renderer->setProp("env_remoteaddr", $_SERVER["REMOTE_ADDR"]);
108
109             // ¥Ç¥Õ¥©¥ë¥È¥Þ¥¯¥íÀßÄê
110             $macro = $this->_setDefaultMacro($macro);
111
112             // ¥æ¡¼¥¶ÄêµÁ¾ðÊóÀßÄê
113             if (is_array($macro)) {
114                 foreach ($macro as $key => $value) {
115                     $renderer->setProp($key, $value);
116                 }
117             }
118             if (isset($this->def[$template])) {
119                 $template = $this->def[$template];
120             }
121             $mail = $renderer->perform(sprintf('%s/%s', $this->mail_dir, $template), true);
122         }
123         if ($to === null) {
124             return $mail;
125         }
126
127         // ¥á¡¼¥ëÆâÍƤò¥Ø¥Ã¥À¤ÈËÜʸ¤ËʬΥ
128         $mail = str_replace("\r\n", "\n", $mail);
129         list($header, $body) = $this->_parse($mail);
130
131         // ÅºÉÕ¥Õ¥¡¥¤¥ë (multipart)
132         if ($attach !== null) {
133             $attach = isset($attach[0]) ? $attach : array($attach);
134             $boundary = Ethna_Util::getRandom(); 
135             $body = "This is a multi-part message in MIME format.\n\n" .
136                 "--$boundary\n" .
137                 "Content-Type: text/plain; charset=iso-2022-jp\n" .
138                 "Content-Transfer-Encoding: 7bit\n\n" .
139                 "$body\n";
140             foreach ($attach as $part) {
141                 if (isset($part['content']) === false
142                     && isset($part['filename']) && is_readable($part['filename'])) {
143                     $part['content'] = file_get_contents($part['filename']);
144                     $part['filename'] = basename($part['filename']);
145                 }
146                 if (isset($part['content']) === false) {
147                     continue;
148                 }
149                 if (isset($part['content-type']) === false) {
150                     $part['content-type'] = 'application/octet-stream';
151                 }
152                 if (isset($part['name']) === false) {
153                     $part['name'] = $part['filename'];
154                 }
155                 if (isset($part['filename']) === false) {
156                     $part['filename'] = $part['name'];
157                 }
158                 $part['name'] = preg_replace('/([^\x00-\x7f]+)/e',
159                     "Ethna_Util::encode_MIME('$1')", $part['name']); // XXX: rfc2231
160                 $part['filename'] = preg_replace('/([^\x00-\x7f]+)/e',
161                     "Ethna_Util::encode_MIME('$1')", $part['filename']);
162
163                 $body .=
164                     "--$boundary\n" .
165                     "Content-Type: " . $part['content-type'] . ";\n" .
166                         "\tname=\"" . $part['name'] . "\"\n" .
167                     "Content-Transfer-Encoding: base64\n" . 
168                     "Content-Disposition: attachment;\n" .
169                         "\tfilename=\"" . $part['filename'] . "\"\n\n";
170                 $body .= chunk_split(base64_encode($part['content']));
171             }
172             $body .= "--$boundary--";
173         }
174
175         // ¥Ø¥Ã¥À
176         if (isset($header['mime-version']) === false) {
177             $header['mime-version'] = array('Mime-Version', '1.0');
178         }
179         if (isset($header['subject']) === false) {
180             $header['subject'] = array('Subject', 'no subject in original');
181         }
182         if (isset($header['content-type']) === false) {
183             $header['content-type'] = array(
184                 'Content-Type',
185                 $attach === null ? 'text/plain; charset=iso-2022-jp'
186                                  : "multipart/mixed; \n\tboundary=\"$boundary\"",
187             );
188         }
189
190         $header_line = "";
191         foreach ($header as $key => $value) {
192             if ($key == 'subject') {
193                 // should be added by mail()
194                 continue;
195             }
196             if ($header_line != "") {
197                 $header_line .= "\n";
198             }
199             $header_line .= $value[0] . ": " . $value[1];
200         }
201
202         // Á÷¿®
203         foreach (to_array($to) as $rcpt) {
204             if (is_string($this->option)) {
205                 mail($rcpt, $header['subject'][1], $body, $header_line, $this->option);
206             } else {
207                 mail($rcpt, $header['subject'][1], $body, $header_line);
208             }
209         }
210     }
211
212     /**
213      *  ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¸ÇÍ­¤Î¥Þ¥¯¥í¤òÀßÄꤹ¤ë
214      *
215      *  @access protected
216      *  @param  array   $macro  ¥æ¡¼¥¶ÄêµÁ¥Þ¥¯¥í
217      *  @return array   ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¸ÇÍ­½èÍýºÑ¤ß¥Þ¥¯¥í
218      */
219     function _setDefaultMacro($macro)
220     {
221         return $macro;
222     }
223
224     /**
225      *  ¥Æ¥ó¥×¥ì¡¼¥È¥á¡¼¥ë¤Î¥Ø¥Ã¥À¾ðÊó¤ò¼èÆÀ¤¹¤ë
226      *
227      *  @access private
228      *  @param  string  $mail   ¥á¡¼¥ë¥Æ¥ó¥×¥ì¡¼¥È
229      *  @return array   ¥Ø¥Ã¥À, ËÜʸ
230      */
231     function _parse($mail)
232     {
233         list($header_line, $body) = preg_split('/\r?\n\r?\n/', $mail, 2);
234         $header_line .= "\n";
235
236         $header_lines = explode("\n", $header_line);
237         $header = array();
238         foreach ($header_lines as $h) {
239             if (strstr($h, ':') == false) {
240                 continue;
241             }
242             list($key, $value) = preg_split('/\s*:\s*/', $h, 2);
243             $i = strtolower($key);
244             $header[$i] = array();
245             $header[$i][] = $key;
246             $header[$i][] = preg_replace('/([^\x00-\x7f]+)/e', "Ethna_Util::encode_MIME('$1')", $value);
247         }
248
249         $body = mb_convert_encoding($body, "ISO-2022-JP");
250
251         return array($header, $body);
252     }
253
254     /**
255      *  ¥á¡¼¥ë¥Õ¥©¡¼¥Þ¥Ã¥ÈÍÑ¥ì¥ó¥À¥é¥ª¥Ö¥¸¥§¥¯¥È¼èÆÀ¤¹¤ë
256      *
257      *  @access public
258      *  @return object  Ethna_Renderer  ¥ì¥ó¥À¥é¥ª¥Ö¥¸¥§¥¯¥È
259      */
260     function &getRenderer()
261     {
262         $_ret_object =& $this->getTemplateEngine();
263         return $_ret_object;
264     }
265
266     /**
267      *  ¥á¡¼¥ë¥Õ¥©¡¼¥Þ¥Ã¥ÈÍÑ¥ì¥ó¥À¥é¥ª¥Ö¥¸¥§¥¯¥È¼èÆÀ¤¹¤ë
268      *
269      *  @access public
270      *  @return object  Ethna_Renderer  ¥ì¥ó¥À¥é¥ª¥Ö¥¸¥§¥¯¥È
271      */
272     function &getTemplateEngine()
273     {
274         $c =& $this->backend->getController();
275         $renderer =& $c->getRenderer();
276         return $renderer;
277     }
278 }
279 // }}}
280 ?>