00001 <?php
00002
00019
00020
00021
00022 define('MAIL_EOL', Core::isWindows() ? "\r\n" : "\n");
00023 define('MAIL_WRAP', 76);
00024
00025 class Mail extends DataObject {
00027 var $privateParams;
00028
00032 function Mail() {
00033 parent::DataObject();
00034 $this->privateParams = array();
00035 if (Config::getVar('email', 'allow_envelope_sender')) {
00036 $defaultEnvelopeSender = Config::getVar('email', 'default_envelope_sender');
00037 if (!empty($defaultEnvelopeSender)) $this->setEnvelopeSender($defaultEnvelopeSender);
00038 }
00039 }
00040
00045 function addPrivateParam($name, $value) {
00046 $this->privateParams[$name] = $value;
00047 }
00048
00053 function setPrivateParams($privateParams) {
00054 $this->privateParams = $privateParams;
00055 }
00056
00057 function addRecipient($email, $name = '') {
00058 if (($recipients = $this->getData('recipients')) == null) {
00059 $recipients = array();
00060 }
00061 array_push($recipients, array('name' => $name, 'email' => $email));
00062
00063 return $this->setData('recipients', $recipients);
00064 }
00065
00066 function setEnvelopeSender($envelopeSender) {
00067 $this->setData('envelopeSender', $envelopeSender);
00068 }
00069
00070 function getEnvelopeSender() {
00071 return $this->getData('envelopeSender');
00072 }
00073
00074 function getContentType() {
00075 return $this->getData('content_type');
00076 }
00077
00078 function setContentType($contentType) {
00079 return $this->setData('content_type', $contentType);
00080 }
00081
00082 function getRecipients() {
00083 return $this->getData('recipients');
00084 }
00085
00086 function setRecipients($recipients) {
00087 return $this->setData('recipients', $recipients);
00088 }
00089
00090 function addCc($email, $name = '') {
00091 if (($ccs = $this->getData('ccs')) == null) {
00092 $ccs = array();
00093 }
00094 array_push($ccs, array('name' => $name, 'email' => $email));
00095
00096 return $this->setData('ccs', $ccs);
00097 }
00098
00099 function getCcs() {
00100 return $this->getData('ccs');
00101 }
00102
00103 function setCcs($ccs) {
00104 return $this->setData('ccs', $ccs);
00105 }
00106
00107 function addBcc($email, $name = '') {
00108 if (($bccs = $this->getData('bccs')) == null) {
00109 $bccs = array();
00110 }
00111 array_push($bccs, array('name' => $name, 'email' => $email));
00112
00113 return $this->setData('bccs', $bccs);
00114 }
00115
00116 function getBccs() {
00117 return $this->getData('bccs');
00118 }
00119
00120 function setBccs($bccs) {
00121 return $this->setData('bccs', $bccs);
00122 }
00123
00127 function clearAllRecipients() {
00128 $this->setRecipients(array());
00129 $this->setCcs(array());
00130 $this->setBccs(array());
00131 }
00132
00133 function addHeader($name, $content) {
00134 $updated = false;
00135
00136 if (($headers = $this->getData('headers')) == null) {
00137 $headers = array();
00138 }
00139
00140 foreach ($headers as $key => $value) {
00141 if ($headers[$key]['name'] == $name) {
00142 $headers[$key]['content'] = $content;
00143 $updated = true;
00144 }
00145 }
00146
00147 if (!$updated) {
00148 array_push($headers, array('name' => $name,'content' => $content));
00149 }
00150
00151 return $this->setData('headers', $headers);
00152 }
00153
00154 function getHeaders() {
00155 return $this->getData('headers');
00156 }
00157
00158 function setHeaders(&$headers) {
00159 return $this->setData('headers', $headers);
00160 }
00161
00169 function addAttachment($filePath, $fileName = '', $contentType = '', $contentDisposition = 'attachment') {
00170 if ($attachments = &$this->getData('attachments') == null) {
00171 $attachments = array();
00172 }
00173
00174
00175
00176 if (empty($fileName)) {
00177 $fileName = basename($filePath);
00178 }
00179
00180 if (empty($contentType)) {
00181 $contentType = String::mime_content_type($filePath);
00182 if (empty($contentType)) $contentType = 'application/x-unknown-content-type';
00183 }
00184
00185
00186 if (is_readable($filePath) && is_file($filePath)) {
00187 $fp = fopen($filePath, 'rb');
00188 if ($fp) {
00189 $content = '';
00190 while (!feof($fp)) {
00191 $content .= fread($fp, 4096);
00192 }
00193 fclose($fp);
00194 }
00195 }
00196
00197 if (isset($content)) {
00198
00199 $content = chunk_split(base64_encode($content), MAIL_WRAP, MAIL_EOL);
00200 array_push($attachments, array('filename' => $fileName, 'content-type' => $contentType, 'disposition' => $contentDisposition, 'content' => $content));
00201
00202 return $this->setData('attachments', $attachments);
00203 } else {
00204 return false;
00205 }
00206 }
00207
00208 function &getAttachments() {
00209 $attachments = &$this->getData('attachments');
00210 return $attachments;
00211 }
00212
00213 function hasAttachments() {
00214 $attachments = &$this->getAttachments();
00215 return ($attachments != null && count($attachments) != 0);
00216 }
00217
00218 function setFrom($email, $name = '') {
00219 return $this->setData('from', array('name' => $name, 'email' => $email));
00220 }
00221
00222 function getFrom() {
00223 return $this->getData('from');
00224 }
00225
00226 function setSubject($subject) {
00227 return $this->setData('subject', $subject);
00228 }
00229
00230 function getSubject() {
00231 return $this->getData('subject');
00232 }
00233
00234 function setBody($body) {
00235 return $this->setData('body', $body);
00236 }
00237
00238 function getBody() {
00239 return $this->getData('body');
00240 }
00241
00246 function getFromString() {
00247 $from = $this->getFrom();
00248 if ($from == null) {
00249 return null;
00250 } else {
00251 return Mail::encodeDisplayName($from['name']) . ' <'.$from['email'].'>';
00252 }
00253 }
00254
00260 function getAddressArrayString($addresses, $includeNames = true) {
00261 if ($addresses == null) {
00262 return null;
00263
00264 } else {
00265 $addressString = '';
00266
00267 foreach ($addresses as $address) {
00268 if (!empty($addressString)) {
00269 $addressString .= ', ';
00270 }
00271
00272 if (Core::isWindows() || empty($address['name']) || !$includeNames) {
00273 $addressString .= $address['email'];
00274
00275 } else {
00276 $addressString .= Mail::encodeDisplayName($address['name']) . ' <'.$address['email'].'>';
00277 }
00278 }
00279
00280 return $addressString;
00281 }
00282 }
00283
00288 function getRecipientString() {
00289 return $this->getAddressArrayString($this->getRecipients());
00290 }
00291
00296 function getCcString() {
00297 return $this->getAddressArrayString($this->getCcs());
00298 }
00299
00304 function getBccString() {
00305 return $this->getAddressArrayString($this->getBccs(), false);
00306 }
00307
00308
00313 function send() {
00314 $recipients = $this->getRecipientString();
00315 $from = $this->getFromString();
00316
00317 $subject = String::encode_mime_header($this->getSubject());
00318 $body = $this->getBody();
00319
00320
00321 if (Core::isWindows()) {
00322
00323 $body = String::regexp_replace("/([^\r]|^)\n/", "\$1\r\n", $body);
00324 } else {
00325
00326 $body = String::regexp_replace("/\r\n/", "\n", $body);
00327 }
00328
00329 if ($this->getContentType() != null) {
00330 $this->addHeader('Content-Type', $this->getContentType());
00331 } elseif ($this->hasAttachments()) {
00332
00333 $mimeBoundary = '==boundary_'.md5(microtime());
00334
00335
00336 $this->addHeader('MIME-Version', '1.0');
00337 $this->addHeader('Content-Type', 'multipart/mixed; boundary="'.$mimeBoundary.'"');
00338
00339 } else {
00340 $this->addHeader('Content-Type', 'text/plain; charset="'.Config::getVar('i18n', 'client_charset').'"');
00341 }
00342
00343 $this->addHeader('X-Mailer', 'Open Journal Systems v2');
00344
00345 $remoteAddr = Request::getRemoteAddr();
00346 if ($remoteAddr != '') $this->addHeader('X-Originating-IP', $remoteAddr);
00347
00348 $this->addHeader('Date', date('D, d M Y H:i:s O'));
00349
00350
00351 if ($from != null) {
00352 $this->addHeader('From', $from);
00353 }
00354
00355 $ccs = $this->getCcString();
00356 if ($ccs != null) {
00357 $this->addHeader('Cc', $ccs);
00358 }
00359
00360 $bccs = $this->getBccString();
00361 if ($bccs != null) {
00362 $this->addHeader('Bcc', $bccs);
00363 }
00364
00365 $headers = '';
00366 foreach ($this->getHeaders() as $header) {
00367 if (!empty($headers)) {
00368 $headers .= MAIL_EOL;
00369 }
00370 $headers .= $header['name'].': '. str_replace(array("\r", "\n"), '', $header['content']);
00371 }
00372
00373 if ($this->hasAttachments()) {
00374
00375 $mailBody = 'This message is in MIME format and requires a MIME-capable mail client to view.'.MAIL_EOL.MAIL_EOL;
00376 $mailBody .= '--'.$mimeBoundary.MAIL_EOL;
00377 $mailBody .= sprintf('Content-Type: text/plain; charset=%s', Config::getVar('i18n', 'client_charset')) . MAIL_EOL.MAIL_EOL;
00378 $mailBody .= wordwrap($body, MAIL_WRAP, MAIL_EOL).MAIL_EOL.MAIL_EOL;
00379
00380
00381 $attachments = $this->getAttachments();
00382 foreach ($attachments as $attachment) {
00383 $mailBody .= '--'.$mimeBoundary.MAIL_EOL;
00384 $mailBody .= 'Content-Type: '.$attachment['content-type'].'; name="'.$attachment['filename'].'"'.MAIL_EOL;
00385 $mailBody .= 'Content-transfer-encoding: base64'.MAIL_EOL;
00386 $mailBody .= 'Content-disposition: '.$attachment['disposition'].MAIL_EOL.MAIL_EOL;
00387 $mailBody .= $attachment['content'].MAIL_EOL.MAIL_EOL;
00388 }
00389
00390 $mailBody .= '--'.$mimeBoundary.'--';
00391
00392 } else {
00393
00394 $mailBody = wordwrap($body, MAIL_WRAP, MAIL_EOL);
00395 }
00396
00397 if ($this->getEnvelopeSender() != null) {
00398 $additionalParameters = '-f ' . $this->getEnvelopeSender();
00399 } else {
00400 $additionalParameters = null;
00401 }
00402
00403 if (HookRegistry::call('Mail::send', array(&$this, &$recipients, &$subject, &$mailBody, &$headers, &$additionalParameters))) return;
00404
00405
00406 if (is_array($this->privateParams)) {
00407 foreach ($this->privateParams as $name => $value) {
00408 $mailBody = str_replace($name, $value, $mailBody);
00409 }
00410 }
00411
00412 if (Config::getVar('email', 'smtp')) {
00413 static $smtp = null;
00414 if (!isset($smtp)) {
00415 import('mail.SMTPMailer');
00416 $smtp = new SMTPMailer();
00417 }
00418 return $smtp->mail($this, $recipients, $subject, $mailBody, $headers);
00419 } else {
00420 return String::mail($recipients, $subject, $mailBody, $headers, $additionalParameters);
00421 }
00422 }
00423
00424 function encodeDisplayName($displayName) {
00425 if (String::regexp_match('!^[-A-Za-z0-9\!#\$%&\'\*\+\/=\?\^_\`\{\|\}~]+$!', $displayName)) return $displayName;
00426 return ('"' . str_replace(
00427 array('"', '\\'),
00428 '',
00429 $displayName
00430 ) . '"');
00431
00432 }
00433 }
00434
00435 ?>