'Wire Mail SMTP', 'version' => '0.6.0', 'summary' => "Extends WireMail, uses SMTP protocol (plain | SSL | TLS), provides: to, cc, bcc, attachments, priority, disposition notification, bulksending, ...", 'href' => 'https://processwire.com/talk/topic/5704-module-wiremailsmtp/', 'author' => 'horst', 'singular' => false, 'autoload' => false ); } public static function getCryptoMethodsTLS() { $validTlsCryptoMethods = array(); foreach(array( 'STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT', // since PHP 5.6.0 'STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT', // since PHP 5.6.0 'STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT', // since PHP 5.6.0 'STREAM_CRYPTO_METHOD_ANY_CLIENT', // since PHP 5.6.0 'STREAM_CRYPTO_METHOD_TLS_CLIENT', // BEFORE PHP 5.6.0 ) as $item) { if(defined($item) && constant($item)) $validTlsCryptoMethods[] = $item; } $a = array(); foreach($validTlsCryptoMethods as $value) $a[$value] = $value; return $a; } public static function getCryptoMethodsSSL() { return array(); } /** * Name of activity/error log files without extension (.txt) * */ const LOG_FILENAME_ACTIVITY = 'wiremailsmtp_activity'; const LOG_FILENAME_ERROR = 'wiremailsmtp_errors'; const LOG_FILENAME_SENTLOG = 'wiremailsmtp_sentlog'; private $smtp = null; private $maildata = array(); /** * Mail properties * */ protected $mail = array( 'to' => array(), // to addresses - associative: both key and value are email (to prevent dups) 'toName' => array(), // to names - associative: indexed by 'to' email address, may be blank/null for any email 'cc' => array(), 'ccName' => array(), 'bcc' => array(), 'from' => '', 'fromName' => '', 'priority' => '', 'dispositionNotification' => '', 'subject' => '', 'body' => '', 'bodyHTML' => '', 'addSignature' => null, 'attachments' => array(), 'header' => array(), 'sendSingle' => false, 'sendBulk' => false, 'useSentLog' => false, 'wrapText' => false ); /** * Default settings used by this module * * @return array */ static public function getDefaultData() { return array( 'default_charset' => 'UTF-8', 'localhost' => '', // this computer address 'smtp_host' => '', // SMTP server address 'smtp_port' => 25, // SMTP server port 'smtp_ssl' => 0, // SMTP use SSL ? 'smtp_ssl_crypto_method' => '', // crypto method to use with SSL connections 'smtp_start_tls' => 0, // SMTP use START_TLS ? 'smtp_tls_crypto_method' => '', // crypto method to use with TLS connections 'smtp_user' => '', // SMTP user name 'smtp_password' => '', // SMTP password 'smtp_password2' => '', // SMTP password 'clear_smtp_password' => '', // SMTP password 'allow_without_authentication' => 0, // No user name and password required 'realm' => '', // Authentication realm or domain 'workstation' => '', // Workstation for NTLM authentication 'authentication_mechanism' => '', // SASL authentication mechanism 'smtp_debug' => 0, // debug smtp server communication? 'smtp_html_debug' => 0, // debug smtp server communication in HTML? 'sender_name' => '', // From: the senders name 'sender_email' => '', // From: the senders email address 'sender_reply' => '', // Reply-To: optional email address 'sender_errors_to' => '', // Errors-To: optional email address 'sender_signature' => '', // a Signature Text, like Contact Data and / or Confidentiality Notices 'sender_signature_html' => '', // a Signature Text in HTML, like Contact Data and / or Confidentiality Notices 'send_sender_signature' => '1', // when the signature should be send: with every mail | only when the default Email is the sender | only when explicitly called via the API 'extra_headers' => '', // optional Custom-Meta-Headers 'valid_recipients' => '', // email addresses of valid recipients. String that we convert to array at runtime. 'smtp_certificate' => 0 // allow or not self signed certificate (PHP >= 5.6) ); } /** * This method is intended for usage with e.g. Newsletter-Modules. * You can hook into it if you want use alternative stores for it * * This resets the Log for sent emaildresses. It starts a new Session. * Best usage should be interactively when setting up a new Newsletter. * * * @return boolean true if Log is empty or false if it is not empty * */ public function ___sentLogReset() { $filename = wire('config')->paths->logs . self::LOG_FILENAME_SENTLOG . '.txt'; @touch($filename); $res = file_put_contents($filename, '', LOCK_EX ); if(false===$res || 0!==$res || !file_exists($filename) || !is_readable($filename) || !is_writeable($filename)) { $this->logError('Cannot reset Content of the SentLog: ' . $filename); throw new WireException('You want to make usage of the SentLog-feature, but cannot reset Content of the SentLog: ' . basename($filename)); } return 0===$res ? true : false; } /** * This method is intended for usage with e.g. Newsletter-Modules. * You can hook into it if you want use alternative stores for it * * This returns an array containing all emailaddresses * * * @return array with emailaddresses as values * */ public function ___sentLogGet() { $filename = wire('config')->paths->logs . self::LOG_FILENAME_SENTLOG . '.txt'; @touch($filename); if(!file_exists($filename) || !is_readable($filename) || !is_writeable($filename)) { $this->logError('Cannot get content of the SentLog: ' . $filename); throw new WireException('You want to make usage of the SentLog-feature, but cannot get content of the SentLog: ' . basename($filename)); } $a = explode("\n", trim(file_get_contents($filename))); $emailaddresses = array(); foreach($a as $e) { if(trim($e)=='') continue; $emailaddresses[] = trim($e); } return $emailaddresses; } /** * This method is intended for usage with e.g. Newsletter-Modules. * You can hook into it if you want use alternative stores for it * * Add a emailaddress to the SentLog * If you have enabled the usage it is called automatically within * the send() loop to store each successful sent emailaddress. * * * @param string Must be a single email address * @return boolean true or false * */ public function ___sentLogAdd($emailaddress) { $filename = wire('config')->paths->logs . self::LOG_FILENAME_SENTLOG . '.txt'; $data = trim(str_replace(array('<','>'), '', $emailaddress)) . "\n"; $res = file_put_contents($filename, $data, LOCK_EX + FILE_APPEND ); if(false===$res || strlen($data)!=$res) { $this->logError('Cannot add emailaddress to the SentLog: ' . $filename); throw new WireException('You want to make usage of the SentLog-feature, but cannot add emailaddress to the SentLog: ' . basename($filename)); } return strlen($data) === $res ? true : false; } /** * This method is intended for usage with e.g. Newsletter-Modules. * * If the send() method should make usage of the SentLog set it to true! * * * @param boolean true or false * @return $this * */ public function useSentLog($useIt=true) { $this->mail['useSentLog'] = (bool)$useIt; return $this; } /** * Bundle module settings back into an array for WireMailSmtpAdaptor * */ public function getSettings() { $siteconfig = is_array($this->wire('config')->wiremailsmtp) ? $this->wire('config')->wiremailsmtp : array(); $settings = array(); foreach(self::getDefaultData() as $key => $value) { $k = $key; $v = $this->$key; if($key === 'valid_recipients') { // convert multi-line textarea value to array of emails $emails = array(); foreach(explode("\n", $this->valid_recipients) as $email) { if(trim($email)=='') continue; $emails[] = trim($email); } $settings[$key] = $emails; // now check for settings in site/config.php that should override the default settings from the module config: if(isset($siteconfig[$key])) $settings[$key] = $siteconfig[$key]; continue; } if($key === 'extra_headers') { // convert multi-line textarea value to array of Key => Value pairs $extraHeaders = array(); foreach(explode("\n", $this->get('extra_headers')) as $extraHeader) { if(trim($extraHeader)=='') continue; $tmp = explode('=', $extraHeader); if(!is_array($tmp) || count($tmp)!=2) continue; $extraHeaders[$tmp[0]] = $tmp[1]; } $settings[$key] = $extraHeaders; // now check for settings in site/config.php that should override the default settings from the module config: if(isset($siteconfig[$key])) $settings[$key] = $siteconfig[$key]; continue; } $settings[$k] = $this->$key; // now check for settings in site/config.php that should override the default settings from the module config: if(isset($siteconfig[$k])) $settings[$k] = $siteconfig[$k]; } return $settings; } /** * Populate default settings * */ public function __construct() { $this->mail['header']['X-Mailer'] = "ProcessWire/" . $this->className(); foreach(self::getDefaultData() as $key => $value) { $this->$key = $value; } } /** * Initialize the module and setup hooks * */ public function init() { require_once(wire('config')->paths->WireMailSmtp . 'WireMailSmtpAdaptor.php'); $this->smtp = new hnsmtp($this->getSettings()); } // public function ready() { // } public function __destruct() { if($this->smtp) $this->smtp->close(); unset($this->smtp); } /** * Save activity message to log file * */ public function logActivity($message) { $this->log->save( self::LOG_FILENAME_ACTIVITY , $message); } /** * Save error message to log file * */ public function logError($message) { $this->log->save( self::LOG_FILENAME_ERROR , $message); } /** * Build a form allowing configuration of this Module * */ static public function getModuleConfigInputfields(array $data) { $localhost = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ''); $data = array_merge(self::getDefaultData(), array('localhost'=>$localhost), $data); // // special handling for SMTP password // // seen by @teppo's SwiftMailer // if(isset($data['smtp_password2'])) { // $data['smtp_password'] = $data['smtp_password2']; // unset($data['smtp_password2'], $data['clear_smtp_password']); // wire('modules')->saveModuleConfigData('WireMailSmtp', $data); // } // elseif(isset($data['clear_smtp_password']) && $data['clear_smtp_password']) { // unset($data['smtp_password'], $data['smtp_password2'], $data['clear_smtp_password']); // wire('modules')->saveModuleConfigData('WireMailSmtp', $data); // } // else { // unset($data['smtp_password2'], $data['clear_smtp_password']); // wire('modules')->saveModuleConfigData('WireMailSmtp', $data); // } require_once(dirname(__FILE__) . '/WireMailSmtpConfig.php'); $c = new WireMailSmtpConfig(); return $c->getConfig($data); } /** * Return a ready-to-use copy of the Adaptor * */ public function getAdaptor() { return $this; } /** * Set the email cc address * * Each added email addresses appends to any addresses already supplied, unless * you specify NULL as the email address, in which case it clears them all. * * @param string|array|null $email Specify any ONE of the following: * 1. Single email address or "User Name " string. * 2. CSV string of #1. * 3. Non-associative array of #1. * 4. Associative array of (email => name) * 5. NULL (default value, to clear out any previously set values) * @param string $name Optionally provide a FROM name, applicable * only when specifying #1 (single email) for the first argument. * @return this * @throws WireException if any provided emails were invalid * */ public function cc($email = null, $name = null) { if(is_null($email)) { // clear existing values $this->mail['cc'] = array(); $this->mail['ccName'] = array(); return $this; } $emails = is_array($email) ? $email : explode(',', $email); foreach($emails as $key => $value) { $toName = ''; if(is_string($key)) { // associative array // email provided as $key, and $toName as value $toEmail = $key; $toName = $value; } else if(strpos($value, '<') !== false && strpos($value, '>') !== false) { // toName supplied as: "User Name extractEmailAndName($value); } else { // just an email address, possibly with name as a function arg $toEmail = $value; } if(empty($toName)) $toName = $name; // use function arg if not overwritten $toEmail = $this->sanitizeEmail($toEmail); $this->mail['cc'][$toEmail] = $toEmail; $this->mail['ccName'][$toEmail] = $this->sanitizeHeader($toName); } return $this; } /** * Set the email bcc address * * Each added email addresses appends to any addresses already supplied, unless * you specify NULL as the email address, in which case it clears them all. * * @param string|array|null $email Specify any ONE of the following: * 1. Single email address or "User Name " string. * 2. CSV string of #1. * 3. Non-associative array of #1. * 4. Associative array of (email => name) * 5. NULL (default value, to clear out any previously set values) * @param string $name Optionally provide a FROM name, applicable * only when specifying #1 (single email) for the first argument. * @return this * @throws WireException if any provided emails were invalid * */ public function bcc($email = null, $name = null) { // a BCC Name isn't used, because BCC addresses by it's nature aren't kept in email messages // we leave it here for compatibilty with TO and CC methods if(is_null($email)) { // clear existing values $this->mail['bcc'] = array(); return $this; } $emails = is_array($email) ? $email : explode(',', $email); foreach($emails as $key => $value) { $toName = ''; if(is_string($key)) { // associative array // email provided as $key, and $toName as value $toEmail = $key; $toName = $value; } else if(strpos($value, '<') !== false && strpos($value, '>') !== false) { // toName supplied as: "User Name extractEmailAndName($value); } else { // just an email address, possibly with name as a function arg $toEmail = $value; } if(empty($toName)) $toName = $name; // use function arg if not overwritten $toEmail = $this->sanitizeEmail($toEmail); $this->mail['bcc'][$toEmail] = $toEmail; } return $this; } /** * Set the 'cc' name * * It is preferable to do this with the cc() method, but this is provided to ensure that * all properties can be set with direct access, i.e. $mailer->toName = 'User Name'; * * This sets the 'to name' for whatever the last added 'cc' email address was. * * @param string * @return this * @throws WireException if you attempt to set a toName before a to email. * */ public function ccName($name) { $emails = $this->mail['cc']; if(!count($emails)) throw new WireException("Please set a 'cc' address before setting a name."); $email = end($emails); $this->mail['ccName'][$email] = $this->sanitizeHeader($name); return $this; } /** * Set the email from address * * @param string Must be a single email address or "User Name " string. * @param string|null An optional FROM name (same as setting/calling fromName) * @return this * @throws WireException if provided email was invalid * */ public function from($email = '', $name = null) { if(is_null($name)) list($email, $name) = $this->extractEmailAndName($email); if(empty($email)) { $email = $this->sender_email; $name = $this->sender_name; } if($name) $this->mail['fromName'] = $this->sanitizeHeader($name); $this->mail['from'] = $email; return $this; } /** * Set the email priority headers * * @param number 1 | 2 | 3 | 4 | 5 ( 1 = highest | 3 = normal / default | 5 = lowest ) * @return this * */ public function priority($number) { $this->mail['priority'] = $number; return $this; } /** * Request a Disposition Notification * * @return this * */ public function dispositionNotification($request=true) { $this->mail['dispositionNotification'] = (bool)$request; return $this; } public function notification($request=true) { return $this->dispositionNotification($request); } // I don't find the param names of the core class to be intuitive or descriptive in the right way. // The "$value" in real is the "filename" of the attachment, and the "$filename" // in real is an "alternative BASENAME"! This may lead to confusion. // // But I have to use it the exact same way as in the core class, because otherwise the // systems raises PHP strict notices about the different param names. :( // So please, for better understanding, read on the example of the next method "attachments()". // // old code: public function attachment($filename, $alternativeBasename = '') /** * Add attachment to the email, * (conform with the core Wiremail update introduced in PW 3.0.36) * * @param $filename string, Full path and filename of file attachment, (no URL!) * @param $alternativeBasename (optional) string, Optional different basename for file as it appears in the mail * @return WireMailSmtp */ public function attachment($value, $filename = '') { $a = array($value => $filename); return $this->attachments($a); } /** * @param array $values, array with keys (absolute pathes to filenames) and optional values (alternative basenames) * example: array( * '/an/absolute/path/to/file.typ' => 'alternative-basename.typ', * '/another/path/to/anotherfile.typ' => '', * // ... * ) * @return WireMailSmtp */ public function attachments($values) { // $value is the fullpath filename (!), filename is an optional alternativeBasename (!), the terms are this way in PW core WireMail foreach($values as $filename => $alternativeBasename) { $this->mail['attachments'][trim($filename)] = trim($alternativeBasename); } return $this; } public function addSignature($add=true) { $this->mail['addSignature'] = (bool)$add; return $this; } public function wrapText($wrap=true) { $this->mail['wrapText'] = (bool)$wrap; return $this; } public function sendSingle($singleMail=true) { $this->mail['sendSingle'] = (bool)$singleMail; if((bool)$singleMail) { $this->mail['sendBulk'] = false; } return $this; } public function single($singleMail=true) { return $this->sendSingle($singleMail); } public function sendBulk($bulkMail=true) { $this->mail['sendBulk'] = (bool)$bulkMail; if((bool)$bulkMail) { $this->mail['sendSingle'] = false; } return $this; } public function bulk($bulkMail=true) { return $this->sendBulk($bulkMail); } public function ___send($debugServer = false) { $this->smtp->setSender($this->mail['from'], $this->mail['fromName']); if($this->mail['dispositionNotification']) $this->setNotification(); // must be called after setSender $this->smtp->setCustomHeader($this->mail['header']); if($this->mail['priority']!='') $this->setPriority($this->mail['priority']); $this->setSubject($this->mail['subject']); if($this->bodyHTML) { // we use MultipartAlternative $text = strlen($this->body) ? $this->body : strip_tags($this->bodyHTML); $this->setTextAndHtmlBody($text, $this->bodyHTML, $this->mail['addSignature']); } else { // we use plaintext $this->setTextBody($this->body, $this->mail['addSignature']); } foreach($this->mail['attachments'] as $value => $filename) { $this->attachFile($value, $filename); } // check and optionally adjust setting for sendSingle if($this->mail['sendSingle'] && count($this->to)>1) { $this->mail['sendSingle'] = false; $this->logError("You have set sendSingle to true, but also you have provided more than one TO-Recipient. We now change the sending method to send multiple messages!"); } // send a single email an quit if($this->mail['sendSingle']) { // with sending only a single mail, we may also use cc and bcc recipients // there should be only one TO recipients, but it is let to the user how he // want handle this foreach($this->to as $email) { $name = $this->toName[$email]; $this->addRecipient($email, $name, 'to'); } foreach($this->cc as $email) { $name = $this->ccName[$email]; $this->addRecipient($email, $name, 'cc'); } foreach($this->bcc as $email) { $this->addRecipient($email, '', 'bcc'); } // correct the recipient headers >>> $tmpTO = $tmpCC = $tmpBCC = array(); foreach($this->maildata['recipients'] as $tmpRecipient) { $tmpRecipientStr = strlen(trim($tmpRecipient['name'])) > 0 ? '"'. trim($tmpRecipient['name']) .'" ' : ''; $tmpRecipientStr .= '<'. trim($tmpRecipient['emailaddress']) .'>'; switch($tmpRecipient['type']) { case 'to': $tmpTO[$tmpRecipient['emailaddress']] = $tmpRecipientStr; break; case 'cc': $tmpCC[$tmpRecipient['emailaddress']] = $tmpRecipientStr; break; case 'bcc': $tmpBCC[$tmpRecipient['emailaddress']] = $tmpRecipientStr; break; } } $tmpTOstr = implode(', ', $tmpTO); $tmpCCstr = implode(', ', $tmpCC); $tmpBCCstr = implode(', ', $tmpBCC); #$this->smtp->setHeader('To', trim($tmpTOstr)); if ($tmpCCstr) { $this->smtp->setHeader('CC', trim($tmpCCstr)); } if ($tmpBCCstr) { $this->smtp->setHeader('BCC', trim($tmpBCCstr)); } unset($tmpRecipient, $tmpRecipientStr, $tmpTO, $tmpTOstr, $tmpCC, $tmpCCstr, $tmpBCC, $tmpBCCstr); // <<< correct the recipient headers $maildata = ''; $ret = $this->smtp->send($debugServer, $debugServer, $maildata); $this->maildata['send'] = $maildata; return $ret ? 1 : 0; } // send multiple messages and quit $numSent = 0; $recipientsSuccess = array(); $recipientsFailed = array(); if($this->mail['useSentLog']) { $sent = $this->sentLogGet(); if(!is_array($sent)) { $this->logError('Cannot get content of the SentLog!'); throw new WireException('You want to make usage of the SentLog-feature, but cannot get content of the SentLog!'); } $recipientsSuccess = $sent; unset($sent); } if(count($this->to)>50) $this->mail['sendBulk'] = true; if(count($this->to)>5 || $this->mail['sendBulk']) $this->smtp->SetBulkMail(1); if($this->mail['sendBulk']) $this->smtp->SetHeader('Precedence', 'bulk'); foreach($this->bcc as $bcc) $this->addRecipient($bcc, '', 'bcc'); foreach($this->to as $to) { if(in_array($to, $recipientsSuccess)) continue; // "Only one cross each" (Monty Python: The Life of Brian) set_time_limit(intval(30)); $toName = $this->mail['toName'][$to]; $this->addRecipient($to, $toName, 'to'); $ret = $this->smtp->send($debugServer, $debugServer, $maildata); if($ret) { $recipientsSuccess[$to] = $to; if($this->mail['useSentLog'] && ! $this->sentLogAdd($to)) { $this->logError('Cannot add emailaddress to the SentLog: ' . SELF::LOG_FILENAME_SENTLOG . '.txt'); throw new WireException('You want to make usage of the SentLog-feature, but cannot add emailaddress to the SentLog: ' . SELF::LOG_FILENAME_SENTLOG . '.txt'); } } else { $recipientsFailed[$to] = $to; } $numSent += $ret ? 1 : 0; } if(count($this->to)>5 || $this->mail['sendBulk']) $this->smtp->SetBulkMail(0); $this->smtp->close(); if(!isset($maildata) && 0==$numSent) $maildata = 'no messages are sent'; $this->maildata['send'] = $maildata; $this->maildata['recipientsSuccess'] = $recipientsSuccess; $this->maildata['recipientsFailed'] = $recipientsFailed; return $numSent; } /** * This method is intended for verbose debug purposes! * Use this instead of the regular send() method. * * @returns a debugDump in string format * @param $outputMode: integer, 1 = echo HTML | 2 = echo PlainText | 3 return String | 4 = write into file * @param $filename: string, path to writeable log filename, required for $outputMode = 4 */ public function debugSend($outputMode = 1, $filename = '') { ob_start(); $this->send(true); $debugLog = "\n\n" . ob_get_clean(); ob_start(); $dump = ''; $dump .= $this->mvd(array('SETTINGS' => $this->getSettings()), $outputMode, $filename); $dump .= $this->mvd(array('RESULT' => $this->getResult()), $outputMode, $filename); $dump .= $this->mvd(array('ERRORS' => $this->getErrors()), $outputMode, $filename); $dump .= $this->mvd(array('DEBUGLOG' => $debugLog), $outputMode, $filename); $return = ob_get_clean(); if(1 == $outputMode || 2 == $outputMode) { echo $return; $dump = $return; } return str_replace(array($this->mvdWrap1(), $this->mvdWrap2(), "\n"), '', $dump); } public function getResult() { // Returns an array with all settings and content of the current email return $this->maildata; } public function getErrors() { // Returns an array of error messages, if they occurred. // Returns blank array if no errors occurred. // The module would call this after getImages() or testConnection() to // see if it should display/log any error messages. return (array)$this->smtp->getErrors(); } public function testConnection() { // Tests that the email settings work. This would be used by the module at // config time to give the user a Yes or No as to whether their email settings // are functional. Returns a boolean TRUE or FALSE. return $this->smtp->testConnection(); } // formatting for debug log output, used by debugSend() private function mvd($v, $outputMode = 1, $filename = '') { ob_start(); var_dump($v); $content = ob_get_contents(); ob_end_clean(); $m = 0; preg_match_all('#^(.*)=>#mU', $content, $stack); $lines = $stack[1]; $indents = array_map('strlen', $lines); if($indents) $m = max($indents) + 1; $content = preg_replace_callback( '#^(.*)=>\\n\s+(\S)#Um', function($match) use ($m) { return $match[1] . str_repeat(' ', ($m - strlen($match[1]) > 1 ? $m - strlen($match[1]) : 1)) . $match[2]; }, $content ); $content = preg_replace('#^((\s*).*){$#m', "\\1\n\\2{", $content); $content = str_replace(array('
', '
'), '', $content); switch($outputMode) { case 1: // Output to Browser-Window echo $this->mvdWrap1() . $content . $this->mvdWrap2(); break; case 2: // Output to Commandline-Window or to Browser as hidden comment echo isset($_SERVER['HTTP_HOST']) ? "\n\n" : "{$content}\n"; break; case 3: // Output into a StringVar return $this->mvdWrap1() . $content . $this->mvdWrap2(); break; case 4: // Output into a file, if a valid filename is given and we have write access to it @touch($filename); if(is_writable($filename)) { $content = str_replace(array('>','"',' '), array('>','"',''), strip_tags($content)); $res = file_put_contents($filename, $content, FILE_APPEND); wireChmod($filename); return $res === strlen($content); } return false; break; } } private function mvdWrap1() { return "
"; }
            private function mvdWrap2() { return "
"; } /* $type = ['To'|'CC'|'BCC'] */ protected function addRecipient($emailaddress, $name='', $type='To') { if(!in_array(strtoupper($type), array('TO','CC','BCC'))) { $type = 'To'; } $emailaddress = str_replace(array('<', '>'), '', $emailaddress); $this->maildata['recipients'][] = array('emailaddress'=>$emailaddress, 'name'=>$name, 'type'=>$type); return $this->smtp->setEmailHeader($type, $emailaddress, $name); } protected function setSubject($text) { $this->maildata['subject'] = (string)$text; return $this->smtp->setHeader('Subject', (string)$text); } protected function setTextBody($text, $addSignature=null) { $maildata = ''; if(!is_bool($addSignature)) { if(in_array($this->send_sender_signature, array('1','2','3'))) { switch($this->send_sender_signature) { case '1': // only when explicitly called via API $addSignature = false; break; case '2': // automaticaly when FROM = Sender Emailaddress $from = strtolower(trim(str_replace(array('<','>'), '', $this->from))); $sender = strtolower(trim(str_replace(array('<','>'), '', $this->sender_email))); $addSignature = $from == $sender || '' == $from ? true : false; break; case '3': // automaticaly with _every_ Message $addSignature = true; break; } } else { $addSignature = false; } } $res = $this->smtp->setTextBody($text, $addSignature, $this->wrapText, $maildata); $this->maildata['addSignature'] = $addSignature ? '1' : '0'; $this->maildata['textbody'] = $maildata; return $res; } protected function setTextAndHtmlBody($text, $html, $addSignature=null) { $maildata1 = $maildata2 = ''; if(!is_bool($addSignature)) { if(in_array($this->send_sender_signature, array('1','2','3'))) { switch($this->send_sender_signature) { case '1': // only when explicitly called via API $addSignature = false; break; case '2': // automaticaly when FROM = Sender Emailaddress $from = strtolower(trim(str_replace(array('<','>'), '', $this->from))); $sender = strtolower(trim(str_replace(array('<','>'), '', $this->sender_email))); $addSignature = $from == $sender || '' == $from ? true : false; break; case '3': // automaticaly with _every_ Message $addSignature = true; break; } } else { $addSignature = false; } } $res = $this->smtp->setTextAndHtmlBody($text, $html, $addSignature, $this->wrapText, $maildata1, $maildata2); $this->maildata['addSignature'] = $addSignature ? '1' : '0'; $this->maildata['textbody'] = $maildata1; $this->maildata['htmlbody'] = $maildata2; return $res; } // updated to PW 3.0.36 new attachment function with optional alternative basename protected function attachFile($value, $filename = '') { if(!file_exists($value) || !is_readable($value)) { $this->logError('Error in $WireMailSmtp->attachFile($filename): Not existing or not readable file: ' . $value); return false; } $attachment = array( 'FileName' => $value, 'Content-Type' => 'automatic/name', 'Disposition' => 'attachment' ); if($filename) $attachment['Name'] = $filename; // optional alternative basename $ret = $this->smtp->addAttachment($attachment); if(!$ret) { return false; } $this->maildata['attachments'][] = $value; // logging attachment filename return true; } protected function setNotification() { $maildata = ''; $ret = $this->smtp->setNotification($maildata); if($ret) { $this->maildata['notification'] = $maildata; } return $ret; } /* $priority = [ 1 | 2 | (3) | 4 | 5 ] */ protected function setPriority($priority=3) { if($ret = (bool)$this->smtp->setPriority($priority)) { $this->maildata['priority'] = $priority; } return $ret; } /** * Return instance of the installer class * */ protected function getInstaller() { #require_once(dirname(__FILE__) . '/WireMailSmtpInstall.php'); #return new WireMailSmtpInstall(); } /** * Perform installation * */ public function ___install() { #$this->getInstaller()->install(self::$defaultSettings); } /** * Perform uninstall * */ public function ___uninstall() { #$this->getInstaller()->uninstall($this); } }