| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581 |
- <?php
- /* vim: set expandtab tabstop=4 shiftwidth=4: */
- // +----------------------------------------------------------------------+
- // | PHP version 4.0 |
- // +----------------------------------------------------------------------+
- // | Copyright (c) 2002 Active Fish Group |
- // +----------------------------------------------------------------------+
- // | Authors: Kelvin Jones <kelvin@kelvinjones.co.uk> |
- // +----------------------------------------------------------------------+
- //
- // $Id: vlibMimeMail.php 1438 2006-10-29 13:26:42Z b4rt $
- // check to avoid multiple including of class
- if (!defined('vlibMimeMailClassLoaded')) {
- define('vlibMimeMailClassLoaded', 1);
- // get the functionality of the vlibCommon class.
- include_once(dirname(__FILE__).'/vlibCommon/common.php');
- // get error reporting functionality.
- include_once(dirname(__FILE__).'/vlibMimeMail/error.php');
- /**
- * vlibMimeMail Class is used send mime encoded mail messages.
- * For instructions on how to use vlibMimeMail, see the
- * vlibMimeMail.html file, located in the 'docs' directory.
- *
- * @since 22/04/2002
- * @author Kelvin Jones <kelvin@kelvinjones.co.uk>
- * @package vLIB
- * @access public
- * @see vlibMimeMail.html
- */
- class vlibMimeMail {
- /*-----------------------------------------------------------------------------\
- | ATTENTION |
- | Do not touch the following variables. vlibTemplate will not work otherwise. |
- \-----------------------------------------------------------------------------*/
- /** lists To addresses */
- var $sendto = array();
- /** lists Cc addresses */
- var $sendcc = array();
- /** lists Bcc addresses */
- var $sendbcc = array();
- /** paths of attached files */
- var $attachments = array();
- /** attachment mime-types */
- var $mimetypes = array();
- /** attachment dispositions */
- var $dispositions = array();
- /** attachment content IDs */
- var $contentIDs = array();
- /** list of message headers */
- var $xheaders = array();
- /** message priorities */
- var $priorities = array( '1 (Highest)', '2 (High)', '3 (Normal)', '4 (Low)', '5 (Lowest)' );
- /** character set of plain text message */
- var $charset = "us-ascii";
- var $ctencoding = "7bit";
- /** character set of html message */
- var $htmlcharset = "us-ascii";
- var $htmlctencoding = "7bit";
- /** Request receipt?? */
- var $receipt = 0;
- /** Do we need to encode when we send?? */
- var $doencoding = 0;
- /** whether to try and fix the windows bug fix */
- var $apply_windows_bugfix = false;
- var $all_emails = array(); // if above is true, will contain all addies
- /** whether to verify all email addresses (by regex) */
- var $checkAddress = true;
- /*-----------------------------------------------------------------------------\
- | public functions |
- \-----------------------------------------------------------------------------*/
- /**
- * FUNCTION: autoCheck
- *
- * Sets auto checking to the value of $bool.
- *
- * @param bool $bool true/false
- * @access public
- */
- function autoCheck ($bool) {
- $this->checkAddress = ($bool);
- }
- /**
- * FUNCTION: to
- *
- * Sets the To header for the message.
- *
- * @param string $toEmail email address
- * @param string $toName Name of recipient [optional]
- * @access public
- */
- function to ($toEmail, $toName=null) {
- if (!$toEmail) return false;
- if ($this->checkAddress && !$this->validateEmail($toEmail)) vlibMimeMailError::raiseError('VM_ERROR_BADEMAIL', FATAL, 'To: '.$toEmail);
- if ($this->apply_windows_bugfix) array_push($this->all_emails, $toEmail);
- $this->sendto[] = ($toName == null) ? $toEmail : '"'.$toName.'" <'.$toEmail.'>';
- }
- /**
- * FUNCTION: clearTo
- *
- * Clears all to headers set.
- *
- * @access public
- */
- function clearTo () {
- $this->sendto = array();
- $this->all_emails = array();
- }
- /**
- * FUNCTION: cc
- *
- * Sets the Cc header for the message.
- *
- * @param string $ccEmail email address
- * @param string $ccName Name of recipient [optional]
- * @access public
- */
- function cc ($ccEmail, $ccName=null) {
- if (!$ccEmail) return false;
- if ($this->checkAddress && !$this->validateEmail($ccEmail)) vlibMimeMailError::raiseError('VM_ERROR_BADEMAIL', FATAL, 'Cc: '.$ccEmail);
- if ($this->apply_windows_bugfix) array_push($this->all_emails, $ccEmail);
- $this->sendcc[] = ($ccName == null) ? $ccEmail : '"'.$ccName.'" <'.$ccEmail.'>';
- }
- /**
- * FUNCTION: clearCc
- *
- * Clears all cc headers set.
- *
- * @access public
- */
- function clearCc () {
- $this->sendcc = array();
- $this->all_emails = array();
- }
- /**
- * FUNCTION: bcc
- *
- * Sets the Bcc header for the message.
- *
- * @param string $bccEmail email address
- * @param string $bccName Name of recipient [optional]
- * @access public
- */
- function bcc ($bccEmail, $bccName=null) {
- if (!$bccEmail) return false;
- if ($this->checkAddress && !$this->validateEmail($bccEmail)) vlibMimeMailError::raiseError('VM_ERROR_BADEMAIL', FATAL, 'Bcc: '.$bccEmail);
- if ($this->apply_windows_bugfix) array_push($this->all_emails, $bccEmail);
- $this->sendbcc[] = ($bccName == null) ? $bccEmail : '"'.$bccName.'" <'.$bccEmail.'>';
- }
- /**
- * FUNCTION: clearBcc
- *
- * Clears all bcc headers set.
- *
- * @access public
- */
- function clearBcc () {
- $this->sendbcc = array();
- $this->all_emails = array();
- }
- /**
- * FUNCTION: clearAll
- *
- * Clears all To, Bcc and Cc headers set.
- *
- * @access public
- */
- function clearAll () {
- $this->clearTo();
- $this->clearCc();
- $this->clearBcc();
- $this->all_emails = array();
- }
- /**
- * FUNCTION: from
- *
- * Sets the From header for the message.
- *
- * @param string $fromEmail email address
- * @param string $fromName Name of recipient [optional]
- * @access public
- */
- function from ($fromEmail, $fromName=null) {
- if (!$fromEmail) return false;
- if ($this->checkAddress && !$this->validateEmail($fromEmail)) vlibMimeMailError::raiseError('VM_ERROR_BADEMAIL', FATAL, 'From: '.$fromEmail);
- $this->xheaders['From'] = ($fromName == null) ? $fromEmail : '"'.$fromName.'" <'.$fromEmail.'>';
- }
- /**
- * FUNCTION: replyTo
- *
- * Sets the ReplyTo header for the message.
- *
- * @param string $replytoEmail email address
- * @param string $replytoName Name of recipient [optional]
- * @access public
- */
- function replyTo ($replytoEmail, $replytoName=null) {
- if (!$replytoEmail) return false;
- if ($this->checkAddress && !$this->validateEmail($replytoEmail)) vlibMimeMailError::raiseError('VM_ERROR_BADEMAIL', FATAL, 'Reply-To: '.$replytoEmail);
- $this->xheaders['Reply-To'] = ($replytoName == null) ? $replytoEmail : '"'.$replytoName.'" <'.$replytoEmail.'>';
- }
- /**
- * FUNCTION: subject
- *
- * Sets the subject for this message.
- *
- * @param string $subject
- * @access public
- */
- function subject ($subject) {
- $this->xheaders['Subject'] = strtr($subject, "\r\n", ' ');
- }
- /**
- * FUNCTION: body
- *
- * Sets the Body of the message.
- * If you're sending a mail with special characters, be sure to define the
- * charset.
- * i.e. $mail->body('ce message est en français.', 'iso-8859-1');
- *
- * @param string $body plain text as the body
- * @param string $charset
- * @access public
- */
- function body ($body, $charset='') {
- $this->body = $body;
- if($charset != '') {
- $this->charset = strtolower($charset);
- if($this->charset != 'us-ascii') $this->ctencoding = '8bit';
- }
- }
- /**
- * FUNCTION: htmlBody
- *
- * Sets the HTML Body of the message.
- * You can you the body() function or htmlBody() or both just to be certain that
- * the user will be able to see the stuff you're sending.
- *
- * If you're sending a mail with special characters, be sure to define the
- * charset.
- * i.e. $mail->htmlbody('ce message est en français.', 'iso-8859-1');
- *
- * @param string $htmlbody html text as the body
- * @param string $charset
- * @access public
- */
- function htmlBody ($htmlbody, $charset='') {
- $this->htmlbody = $htmlbody;
- if($charset != '') {
- $this->htmlcharset = strtolower($charset);
- if($this->htmlcharset != 'us-ascii') $this->htmlctencoding = '8bit';
- }
- }
- /**
- * FUNCTION: attach
- *
- * Attach a file to the message. Defaults the disposition to 'attachment',
- * you can also use 'inline' which the client will try to show in the message.
- * Mime-types can be handled by vlibMimeMail by the list found in
- * vlibCommon/mime_types.php.
- *
- * @param string $filename full path of the file to attach
- * @param string $disposition inline or attachment
- * @param string $mimetype MIME-type of the file. defaults to 'application/octet-stream'
- * @access public
- */
- function attach ($filename, $disposition = 'attachment', $mimetype=null, $cid=null) {
- if($mimetype == null) $mimetype = vlibCommon::getMimeType($filename);
- $this->attachments[] = $filename;
- $this->mimetypes[] = $mimetype;
- $this->dispositions[] = $disposition;
- if (!$cid) {
- srand((double)microtime()*96545624);
- $cid = md5(uniqid(rand())).'@vlib.mimemail';
- }
- $this->contentIDs[] = $cid;
- return $cid;
- }
- /**
- * FUNCTION: organization
- *
- * Sets the Organization header for the message.
- *
- * @param string $org organization name
- * @access public
- */
- function organization ($org) {
- if(!empty($org)) $this->xheaders['Organization'] = $org;
- }
- /**
- * FUNCTION: receipt
- *
- * To request a receipt you must call this function with a true value.
- * And you must call $this->from() or $this->replyTo() before sending the mail.
- *
- * @param bool $bool true/false
- * @access public
- */
- function receipt ($bool=true) {
- $this->receipt = ($bool);
- }
- /**
- * FUNCTION: priority
- *
- * Sets the Priority header for the message.
- * usage: $mail->priority(1); // highest setting
- * view documentation for priority levels.
- *
- * @param string $priority
- * @access public
- */
- function priority ($priority) {
- if(!is_int($priority)) $priority = settype($priority, 'integer');
- if(!isset($this->priorities[$priority-1])) return false;
- $this->xheaders['X-Priority'] = $this->priorities[$priority-1];
- return true;
- }
- /**
- * FUNCTION: validateEmail
- *
- * Validates an email address and return true or false.
- *
- * @param string $address email address
- * @return bool true/false
- * @access public
- */
- function validateEmail ($address) {
- return preg_match('/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9_-]+(\.[_a-z0-9-]+)+$/i',$address);
- }
- /**
- * FUNCTION: send
- *
- * Sends the mail.
- *
- * @return boolean true on success, false on failure
- * @access public
- */
- function send () {
- $this->_buildMail();
- $to_str = ($this->apply_windows_bugfix) ? implode(',', $this->all_emails) : $this->xheaders['To'];
- return mail($to_str, $this->xheaders['Subject'], $this->fullBody, $this->headers);
- }
- /**
- * FUNCTION: get
- *
- * Returns the whole e-mail, headers and message. Can be used to display the
- * message in pain text or for debugging.
- *
- * @return string message
- * @access public
- */
- function get () {
- $this->_buildMail();
- $mail = 'To: '.$this->xheaders['To']."\n";
- $mail .= 'Subject: '.$this->xheaders['Subject']."\n";
- $mail .= $this->headers . "\n";
- $mail .= $this->fullBody;
- return $mail;
- }
- /*-----------------------------------------------------------------------------\
- | private functions |
- \-----------------------------------------------------------------------------*/
- /**
- * FUNCTION: vlibMimeMail [contsructor]
- *
- * Enables auto checking by default.
- * Also creates the unique boundary id for this message.
- *
- * @param bool $apply_windows_bugfix tells us whether to apply bug fix for windows Cc: and Bcc: headers.
- * @access private
- */
- function vlibMimeMail ($apply_windows_bugfix=false) {
- $this->apply_windows_bugfix = ($apply_windows_bugfix);
- $this->boundary = "--" . md5(uniqid('vlibseediganoofahilfaman'));
- $this->boundary_alt = "--" . md5(uniqid('vlibseedvatefairechier'));
- }
- /**
- * FUNCTION: _buildMail
- *
- * Proccesses all headers and attachments ready for sending.
- *
- * @access private
- */
- function _buildMail () {
- if (empty($this->sendto) && (empty($this->body) && empty($this->htmlbody))) {
- vlibMimeMailError::raiseError('VM_ERROR_CANNOT_SEND', FATAL);
- }
- // build the headers
- $this->headers = "";
- $this->xheaders['To'] = implode(',', $this->sendto);
- $cc_header_name = ($this->apply_windows_bugfix) ? 'cc': 'Cc';
- if (!empty($this->sendcc)) $this->xheaders[$cc_header_name] = implode(',', $this->sendcc);
- if (!empty($this->sendbcc)) $this->xheaders['Bcc'] = implode(',', $this->sendbcc);
- if($this->receipt) {
- if(isset($this->xheaders['Reply-To'])) {
- $this->xheaders['Disposition-Notification-To'] = $this->xheaders['Reply-To'];
- }
- elseif (isset($this->xheaders['From'])) {
- $this->xheaders['Disposition-Notification-To'] = $this->xheaders['From'];
- }
- }
- if($this->charset != '') {
- $this->xheaders['Mime-Version'] = '1.0';
- $this->xheaders['Content-Type'] = 'text/plain; charset='.$this->charset;
- $this->xheaders['Content-Transfer-Encoding'] = $this->ctencoding;
- }
- $this->xheaders['X-Mailer'] = 'vlibMimeMail';
- // setup the body ready for sending
- $this->_setBody();
- foreach ($this->xheaders as $head => $value) {
- $rgx = ($this->apply_windows_bugfix) ? 'Subject' : 'Subject|To'; // don't strip out To header for bugfix
- if (!preg_match('/^'.$rgx.'$/i', $head)) $this->headers .= $head.': '.strtr($value, "\r\n", ' ')."\n";
- }
- }
- /**
- * FUNCTION: _setBody
- *
- * sets the body to be used in a mail.
- *
- * @access private
- */
- function _setBody () {
- // do we need to encode??
- $encode = (empty($this->htmlbody) && empty($this->attachments)) ? false : true;
- // if yes...
- if ($encode) {
- $this->fullBody = "This is a multi-part message in MIME format.\n\n";
- $this->fullBody .= '--'.$this->boundary."\nContent-Type: multipart/alternative;\n\tboundary=\"".$this->boundary_alt."\"\n\n\n";
- $body_boundary = $this->boundary_alt;
- $this->xheaders['Content-Type'] = "multipart/mixed;\n\tboundary=\"".$this->boundary.'"';
- if (!empty($this->body)) {
- $this->fullBody .= '--'.$body_boundary."\nContent-Type: text/plain; charset=".$this->charset."\nContent-Transfer-Encoding: ".$this->ctencoding."\n\n".$this->body."\n\n";
- }
- if (!empty($this->htmlbody)) {
- $this->fullBody .= '--'.$body_boundary."\nContent-Type: text/html; charset=".$this->charset."\nContent-Transfer-Encoding: ".$this->ctencoding."\n\n".$this->htmlbody."\n\n";
- }
- $this->fullBody .= '--'.$body_boundary."--\n\n";
- if (!empty($this->attachments)) {
- $this->_build_attachments();
- }
- $this->fullBody .= '--'.$this->boundary.'--'; // ends the last boundary
- }
- // else we just send plain text.
- else {
- if (!empty($this->body)) {
- $this->fullBody = $this->body;
- }
- else {
- vlibMimeMailError::raiseError('VM_ERROR_NOBODY', FATAL);
- }
- }
- }
- /**
- * FUNCTION: _build_attachments
- *
- * Checks and encodes all attachments.
- *
- * @access private
- */
- function _build_attachments () {
- $sep = chr(13).chr(10);
- $ata = array();
- $k=0;
- for ($i=0; $i < count( $this->attachments); $i++) {
- $filename = $this->attachments[$i];
- $basename = basename($filename);
- $mimetype = $this->mimetypes[$i];
- $disposition = $this->dispositions[$i];
- $contentID = $this->contentIDs[$i];
- if (preg_match('/^[a-zA-Z]+:\/\//', $filename)) { // figure out if local or remote
- $upart = parse_url($filename);
- $newfilename = $upart['scheme'].'://';
- if (!empty($upart['user'])) $newfilename .= $upart['user'].':'.$upart['pass'].'@';
- $newfilename .= $upart['host'];
- if (!empty($upart['port'])) $newfilename .= ':'.$upart['port'];
- $newfilename .= '/';
- if (!empty($upart['path'])) {
- $upart['path'] = substr($upart['path'], 1);
- $newpath = explode('/', $upart['path']);
- for($i=0; $i<count($newpath); $i++) $newpath[$i] = rawurlencode($newpath[$i]);
- $newfilename .= implode('/',$newpath);
- }
- if (!empty($upart['query'])) $newfilename .= '?'.urlencode($upart['query']);
- if (!empty($upart['fragment'])) $newfilename .= ':'.$upart['fragment'];
- $fp = fopen($newfilename, 'rb');
- while(!feof($fp)) $data .= fread($fp,1024);
- }
- else {
- if(!file_exists($filename)) {
- vlibMimeMailError::raiseError('VM_ERROR_NOFILE', FATAL, $filename);
- }
- $fp = fopen($filename, 'rb');
- $data = fread($fp, filesize($filename));
- }
- $subhdr = '--'.$this->boundary."\nContent-type: ".$mimetype.";\n\tname=\"".$basename."\"\nContent-Transfer-Encoding: base64\nContent-Disposition: ".$disposition.";\n\tfilename=\"".$basename."\"\n";
- if ($contentID) $subhdr .= 'Content-ID: <'.$contentID.">\n";
- $ata[$k++] = $subhdr;
- $ata[$k++] = chunk_split(base64_encode($data))."\n\n";
- fclose($fp);
- }
- $this->fullBody .= "\n".implode($sep, $ata);
- }
- } // class vlibMimeMail
- } // << end if(!defined())..
- ?>
|