Example #1
0
 /**
  *  テンプレートメールのヘッダ情報を取得する
  *
  *  @access private
  *  @param  string  $mail   メールテンプレート
  *  @return array   ヘッダ, 本文
  */
 function _parse($mail)
 {
     list($header_line, $body) = preg_split('/\\r?\\n\\r?\\n/', $mail, 2);
     $header_line .= "\n";
     $header_lines = explode("\n", $header_line);
     $header = array();
     foreach ($header_lines as $h) {
         if (strstr($h, ':') == false) {
             continue;
         }
         list($key, $value) = preg_split('/\\s*:\\s*/', $h, 2);
         $i = strtolower($key);
         $header[$i] = array();
         $header[$i][] = $key;
         $header[$i][] = preg_replace_callback('/([^\\x00-\\x7f]+)/', function ($matches) {
             return Ethna_Util::encode_MIME($matches[1]);
         }, $value);
     }
     return array($header, $body);
 }
Example #2
0
 /**
  *  メールを送信する
  *
  *  $attach の指定方法:
  *  - 既存のファイルを添付するとき
  *  <code>
  *  array('filename' => '/tmp/hoge.xls', 'content-type' => 'application/vnd.ms-excel')
  *  </code>
  *  - 文字列に名前を付けて添付するとき
  *  <code>
  *  array('name' => 'foo.txt', 'content' => 'this is foo.')
  *  </code>
  *  'content-type' 省略時は 'application/octet-stream' となる。
  *  複数添付するときは上の配列を添字0から始まるふつうの配列に入れる。
  *
  *  @param  string  $to         メール送信先アドレス (nullのときは送信せずに内容を return する)
  *  @param  string  $template   メールテンプレート名 or タイプ
  *  @param  array   $macro      テンプレートマクロ or $templateがMAILSENDER_TYPE_DIRECTのときはメール送信内容)
  *  @param  array   $attach     添付ファイル
  */
 function send($to, $template, $macro, $attach = null)
 {
     // メール内容を作成
     if ($template === MAILSENDER_TYPE_DIRECT) {
         $mail = $macro;
     } else {
         $renderer = $this->getTemplateEngine();
         // 基本情報設定
         $env_datetime = _et('%Y/%m/%d %H:%M:%S');
         $renderer->setProp("env_datetime", strftime($env_datetime));
         $renderer->setProp("env_useragent", $_SERVER["HTTP_USER_AGENT"]);
         $renderer->setProp("env_remoteaddr", $_SERVER["REMOTE_ADDR"]);
         // デフォルトマクロ設定
         $macro = $this->_setDefaultMacro($macro);
         // ユーザ定義情報設定
         if (is_array($macro)) {
             foreach ($macro as $key => $value) {
                 $renderer->setProp($key, $value);
             }
         }
         if (isset($this->def[$template])) {
             $template = $this->def[$template];
         }
         $mail = $renderer->perform(sprintf('%s/%s', $this->mail_dir, $template), true);
         if (Ethna::isError($mail)) {
             return $mail;
         }
     }
     if ($to === null) {
         return $mail;
     }
     // メール内容をヘッダと本文に分離
     $mail = str_replace("\r\n", "\n", $mail);
     list($header, $body) = $this->_parse($mail);
     // 添付ファイル (multipart)
     if ($attach !== null) {
         $attach = isset($attach[0]) ? $attach : array($attach);
         $boundary = Ethna_Util::getRandom();
         $body = "This is a multi-part message in MIME format.\n\n" . "--{$boundary}\n" . "Content-Type: text/plain; charset=iso-2022-jp\n" . "Content-Transfer-Encoding: 7bit\n\n" . "{$body}\n";
         foreach ($attach as $part) {
             if (isset($part['content']) === false && isset($part['filename']) && is_readable($part['filename'])) {
                 $part['content'] = file_get_contents($part['filename']);
                 $part['filename'] = basename($part['filename']);
             }
             if (isset($part['content']) === false) {
                 continue;
             }
             if (isset($part['content-type']) === false) {
                 $part['content-type'] = 'application/octet-stream';
             }
             if (isset($part['name']) === false) {
                 $part['name'] = $part['filename'];
             }
             if (isset($part['filename']) === false) {
                 $part['filename'] = $part['name'];
             }
             $part['name'] = preg_replace_callback('/([^\\x00-\\x7f]+)/', function (array $matches) {
                 return Ethna_Util::encode_MIME($matches[1]);
             }, $part['name']);
             // XXX: rfc2231
             $part['filename'] = preg_replace_callback('/([^\\x00-\\x7f]+)/', function (array $matches) {
                 return Ethna_Util::encode_MIME($matches[1]);
             }, $part['filename']);
             $body .= "--{$boundary}\n" . "Content-Type: " . $part['content-type'] . ";\n" . "\tname=\"" . $part['name'] . "\"\n" . "Content-Transfer-Encoding: base64\n" . "Content-Disposition: attachment;\n" . "\tfilename=\"" . $part['filename'] . "\"\n\n";
             $body .= chunk_split(base64_encode($part['content']));
         }
         $body .= "--{$boundary}--";
     }
     // ヘッダ
     if (isset($header['mime-version']) === false) {
         $header['mime-version'] = array('Mime-Version', '1.0');
     }
     if (isset($header['subject']) === false) {
         $header['subject'] = array('Subject', 'no subject in original');
     }
     if (isset($header['content-type']) === false) {
         $header['content-type'] = array('Content-Type', $attach === null ? 'text/plain; charset=iso-2022-jp' : "multipart/mixed; \n\tboundary=\"{$boundary}\"");
     }
     $header_line = "";
     foreach ($header as $key => $value) {
         if ($key == 'subject') {
             // should be added by mail()
             continue;
         }
         if ($header_line != "") {
             $header_line .= "\n";
         }
         $header_line .= $value[0] . ": " . $value[1];
     }
     // 改行コードを CRLF に
     if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
         $body = str_replace("\n", "\r\n", $body);
     }
     $wa_config = 'mail_func_workaround';
     if ($this->config->get($wa_config) == false && isset($this->options[$wa_config]) == false) {
         $header_line = str_replace("\n", "\r\n", $header_line);
     }
     // 送信
     foreach (to_array($to) as $rcpt) {
         if (is_string($this->option)) {
             mail($rcpt, $header['subject'][1], $body, $header_line, $this->option);
         } else {
             mail($rcpt, $header['subject'][1], $body, $header_line);
         }
     }
 }