2 // vim: foldmethod=marker
6 * @author Masaki Fujimoto <fujimoto@php.net>
7 * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
12 /** ¥á¡¼¥ë¥Æ¥ó¥×¥ì¡¼¥È¥¿¥¤¥×: ľÀÜÁ÷¿® */
13 define('MAILSENDER_TYPE_DIRECT', 0);
16 // {{{ Ethna_MailSender
20 * @author Masaki Fujimoto <fujimoto@php.net>
24 class Ethna_MailSender
30 /** @var array ¥á¡¼¥ë¥Æ¥ó¥×¥ì¡¼¥ÈÄêµÁ */
34 /** @var string ¥á¡¼¥ë¥Æ¥ó¥×¥ì¡¼¥È¥Ç¥£¥ì¥¯¥È¥ê */
35 var $mail_dir = 'mail';
37 /** @var int Á÷¿®¥á¡¼¥ë¥¿¥¤¥× */
40 /** @var string Á÷¿®¥ª¥×¥·¥ç¥ó */
43 /** @var object Ethna_Backend backend¥ª¥Ö¥¸¥§¥¯¥È */
46 /** @var object Ethna_Config ÀßÄꥪ¥Ö¥¸¥§¥¯¥È */
52 * Ethna_MailSender¥¯¥é¥¹¤Î¥³¥ó¥¹¥È¥é¥¯¥¿
55 * @param object Ethna_Backend &$backend backend¥ª¥Ö¥¸¥§¥¯¥È
57 function Ethna_MailSender(&$backend)
59 $this->backend =& $backend;
60 $this->config =& $this->backend->getConfig();
64 * ¥á¡¼¥ë¥ª¥×¥·¥ç¥ó¤òÀßÄꤹ¤ë
67 * @param string $option ¥á¡¼¥ëÁ÷¿®¥ª¥×¥·¥ç¥ó
69 function setOption($option)
71 $this->option = $option;
78 * - ´û¸¤Î¥Õ¥¡¥¤¥ë¤òźÉÕ¤¹¤ë¤È¤
80 * array('filename' => '/tmp/hoge.xls', 'content-type' => 'application/vnd.ms-excel')
82 * - ʸ»úÎó¤Ë̾Á°¤òÉÕ¤±¤ÆźÉÕ¤¹¤ë¤È¤
84 * array('name' => 'foo.txt', 'content' => 'this is foo.')
86 * 'content-type' ¾Êά»þ¤Ï 'application/octet-stream' ¤È¤Ê¤ë¡£
87 * Ê£¿ôźÉÕ¤¹¤ë¤È¤¤Ï¾å¤ÎÇÛÎó¤òź»ú0¤«¤é»Ï¤Þ¤ë¤Õ¤Ä¤¦¤ÎÇÛÎó¤ËÆþ¤ì¤ë¡£
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 ¥á¡¼¥ëÆâÍÆ
96 function send($to, $template, $macro, $attach = null)
99 if ($template === MAILSENDER_TYPE_DIRECT) {
102 $renderer =& $this->getTemplateEngine();
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"]);
109 // ¥Ç¥Õ¥©¥ë¥È¥Þ¥¯¥íÀßÄê
110 $macro = $this->_setDefaultMacro($macro);
112 // ¥æ¡¼¥¶ÄêµÁ¾ðÊóÀßÄê
113 if (is_array($macro)) {
114 foreach ($macro as $key => $value) {
115 $renderer->setProp($key, $value);
118 if (isset($this->def[$template])) {
119 $template = $this->def[$template];
121 $mail = $renderer->perform(sprintf('%s/%s', $this->mail_dir, $template), true);
127 // ¥á¡¼¥ëÆâÍƤò¥Ø¥Ã¥À¤ÈËÜʸ¤ËʬΥ
128 $mail = str_replace("\r\n", "\n", $mail);
129 list($header, $body) = $this->_parse($mail);
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" .
137 "Content-Type: text/plain; charset=iso-2022-jp\n" .
138 "Content-Transfer-Encoding: 7bit\n\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']);
146 if (isset($part['content']) === false) {
149 if (isset($part['content-type']) === false) {
150 $part['content-type'] = 'application/octet-stream';
152 if (isset($part['name']) === false) {
153 $part['name'] = $part['filename'];
155 if (isset($part['filename']) === false) {
156 $part['filename'] = $part['name'];
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']);
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']));
172 $body .= "--$boundary--";
176 if (isset($header['mime-version']) === false) {
177 $header['mime-version'] = array('Mime-Version', '1.0');
179 if (isset($header['subject']) === false) {
180 $header['subject'] = array('Subject', 'no subject in original');
182 if (isset($header['content-type']) === false) {
183 $header['content-type'] = array(
185 $attach === null ? 'text/plain; charset=iso-2022-jp'
186 : "multipart/mixed; \n\tboundary=\"$boundary\"",
191 foreach ($header as $key => $value) {
192 if ($key == 'subject') {
193 // should be added by mail()
196 if ($header_line != "") {
197 $header_line .= "\n";
199 $header_line .= $value[0] . ": " . $value[1];
203 foreach (to_array($to) as $rcpt) {
204 if (is_string($this->option)) {
205 mail($rcpt, $header['subject'][1], $body, $header_line, $this->option);
207 mail($rcpt, $header['subject'][1], $body, $header_line);
213 * ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¸ÇͤΥޥ¯¥í¤òÀßÄꤹ¤ë
216 * @param array $macro ¥æ¡¼¥¶ÄêµÁ¥Þ¥¯¥í
217 * @return array ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¸ÇͽèÍýºÑ¤ß¥Þ¥¯¥í
219 function _setDefaultMacro($macro)
225 * ¥Æ¥ó¥×¥ì¡¼¥È¥á¡¼¥ë¤Î¥Ø¥Ã¥À¾ðÊó¤ò¼èÆÀ¤¹¤ë
228 * @param string $mail ¥á¡¼¥ë¥Æ¥ó¥×¥ì¡¼¥È
229 * @return array ¥Ø¥Ã¥À, ËÜʸ
231 function _parse($mail)
233 list($header_line, $body) = preg_split('/\r?\n\r?\n/', $mail, 2);
234 $header_line .= "\n";
236 $header_lines = explode("\n", $header_line);
238 foreach ($header_lines as $h) {
239 if (strstr($h, ':') == false) {
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);
249 $body = mb_convert_encoding($body, "ISO-2022-JP");
251 return array($header, $body);
255 * ¥á¡¼¥ë¥Õ¥©¡¼¥Þ¥Ã¥ÈÍÑ¥ì¥ó¥À¥é¥ª¥Ö¥¸¥§¥¯¥È¼èÆÀ¤¹¤ë
258 * @return object Ethna_Renderer ¥ì¥ó¥À¥é¥ª¥Ö¥¸¥§¥¯¥È
260 function &getRenderer()
262 $_ret_object =& $this->getTemplateEngine();
267 * ¥á¡¼¥ë¥Õ¥©¡¼¥Þ¥Ã¥ÈÍÑ¥ì¥ó¥À¥é¥ª¥Ö¥¸¥§¥¯¥È¼èÆÀ¤¹¤ë
270 * @return object Ethna_Renderer ¥ì¥ó¥À¥é¥ª¥Ö¥¸¥§¥¯¥È
272 function &getTemplateEngine()
274 $c =& $this->backend->getController();
275 $renderer =& $c->getRenderer();