Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Wed, Jul 16, 11:15 PM

in-portal

Index: trunk/core/kernel/utility/smtp_client.php
===================================================================
--- trunk/core/kernel/utility/smtp_client.php (revision 3539)
+++ trunk/core/kernel/utility/smtp_client.php (revision 3540)
@@ -1,829 +1,829 @@
<?php
define('SMTP_STATUS_NOT_CONNECTED', 1, TRUE);
define('SMTP_STATUS_CONNECTED', 2, TRUE);
class kSmtpClient extends kBase {
var $connection;
var $recipients;
var $headers;
var $timeout;
var $errors;
var $status;
var $body;
var $from;
var $host;
var $port;
var $helo;
var $auth;
var $user;
var $pass;
var $debug;
var $buffer;
-
+
var $authmethod;
var $CRLF = "\r\n";
-
+
var $debugtext='';
/**
* List of supported authentication methods, in preferential order.
* @var array
* @access public
*/
var $auth_methods = array('DIGEST-MD5','CRAM-MD5','LOGIN','PLAIN');
/**
* The most recent server response code.
* @var int
* @access private
*/
var $_code = -1;
-
+
/**
* The most recent server response arguments.
* @var array
* @access private
*/
var $_arguments = array();
/**
* Stores detected features of the SMTP server.
* @var array
* @access private
*/
var $_esmtp = array();
-
+
/***************************************
** Constructor function. Arguments:
** $params - An assoc array of parameters:
**
** host - The hostname of the smtp server Default: localhost
** port - The port the smtp server runs on Default: 25
** helo - What to send as the HELO command Default: localhost
** (typically the hostname of the
** machine this script runs on)
** auth - Whether to use basic authentication Default: FALSE
** user - Username for authentication Default: <blank>
** pass - Password for authentication Default: <blank>
** timeout - The timeout in seconds for the call Default: 5
** to fsockopen()
***************************************/
function kSmtpClient($params = array()){
-
+
$this->timeout = 5;
$this->status = SMTP_STATUS_NOT_CONNECTED;
$this->host = 'localhost';
$this->port = 25;
$this->helo = 'localhost';
$this->auth = FALSE;
$this->user = '';
$this->pass = '';
$this->errors = array();
$this->buffer = array();
$this->debug=0;
foreach($params as $key => $value){
$this->$key = $value;
}
}
/***************************************
** Connect function. This will, when called
- ** statically, create a new smtp object,
+ ** statically, create a new smtp object,
** call the connect function (ie this function)
** and return it. When not called statically,
** it will connect to the server and send
** the HELO command.
***************************************/
function connect($params = array()){
if(!isset($this->status))
{
$obj = new kSmtpClient($params);
if($obj->connect()){
$obj->status = SMTP_STATUS_CONNECTED;
}
return $obj;
}
else
{
foreach($params as $key => $value){
$this->$key = $value;
}
$this->connection = @fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout);
if(is_resource($this->connection))
{
socket_set_timeout($this->connection, 0, 250000);
socket_set_blocking($this->connection,TRUE);
$greeting = $this->get_data();
$this->status = SMTP_STATUS_CONNECTED;
return $this->auth ? $this->ehlo() : $this->helo();
}
else
{
$this->errors[] = 'Failed to connect to server: '.$errstr;
return FALSE;
}
}
}
function disconnect()
{
if(is_resource($this->connection))
fclose($this->connection);
unset($this->connection);
$this->status=SMTP_STATUS_NOT_CONNECTED;
}
/***************************************
** Function which handles sending the mail.
** Arguments:
** $params - Optional assoc array of parameters.
** Can contain:
** recipients - Indexed array of recipients
** from - The from address. (used in MAIL FROM:),
** this will be the return path
** headers - Indexed array of headers, one header per array entry
** body - The body of the email
** It can also contain any of the parameters from the connect()
** function
***************************************/
function send($params = array()){
-
+
foreach($params as $key => $value){
$this->set($key, $value);
}
if($this->is_connected()){
// Do we auth or not? Note the distinction between the auth variable and auth() function
if($this->auth){
if(!$this->auth())
return FALSE;
}
$this->mail($this->from);
if(is_array($this->recipients))
foreach($this->recipients as $value)
$this->rcpt($value);
else
$this->rcpt($this->recipients);
if(!$this->data())
return FALSE;
-
+
// Transparency
$headers = str_replace($this->CRLF.'.', $this->CRLF.'..', trim(implode($this->CRLF, $this->headers)));
$body = str_replace($this->CRLF.'.', $this->CRLF.'..', $this->body);
$body = $body[0] == '.' ? '.'.$body : $body;
-
+
$this->send_data($headers);
$this->send_data('');
$this->send_data($body);
$this->send_data($this->CRLF.".");
return (substr(trim($this->get_data()), 0, 3) === '250');
}else{
$this->errors[] = 'Not connected!';
return FALSE;
}
}
-
+
/***************************************
** Function to implement HELO cmd
***************************************/
function helo(){
if(is_resource($this->connection)
AND $this->send_data('HELO '.$this->helo)
AND substr(trim($error = $this->get_data()), 0, 3) === '250' ){
return TRUE;
}else{
$this->errors[] = 'HELO command failed, output: ' . trim(substr(trim($error),3));
return FALSE;
}
}
-
+
/***************************************
** Function to implement EHLO cmd
***************************************/
function ehlo()
{
$ret_status=is_resource($this->connection) AND $this->send_data('EHLO '.$this->helo);
$success=$this->_parseResponse(250);
if(!$ret_status && $success !== true)
{
$this->errors[] = 'EHLO command failed, output: ' . trim(substr(trim($error),3));
return FALSE;
}
foreach ($this->_arguments as $argument) {
$verb = strtok($argument, ' ');
$arguments = substr($argument, strlen($verb) + 1,
strlen($argument) - strlen($verb) - 1);
$this->_esmtp[$verb] = $arguments;
}
-
+
return TRUE;
-
+
}
-
+
/***************************************
** Function to implement AUTH cmd
***************************************/
-
+
function _getBestAuthMethod()
{
if ($this->authmethod) return $this->authmethod;
-
+
if (!isset($this->_esmtp['AUTH'])) return 'NOAUTH';
-
+
$available_methods = explode(' ', $this->_esmtp['AUTH']);
-
-
+
+
foreach ($this->auth_methods as $method)
{
if (in_array($method, $available_methods)) return $method;
}
return false;
}
-
-
+
+
function auth(){
if(is_resource($this->connection))
{
$method=$this->_getBestAuthMethod();
-
+
if ($method == 'NOAUTH') return true;
-
+
switch ($method) {
case 'DIGEST-MD5':
$result = $this->_authDigest_MD5($this->user, $this->pass);
break;
case 'CRAM-MD5':
$result = $this->_authCRAM_MD5($this->user, $this->pass);
break;
case 'LOGIN':
$result = $this->_authLogin($this->user, $this->pass);
break;
case 'PLAIN':
$result = $this->_authPlain($this->user, $this->pass);
break;
default:
$this->errors[] = 'AUTH command failed: no supported authentication methods';
return false;
break;
}
if($result!==true)
{
$this->errors[] = 'AUTH command failed: '.$result;
return FALSE;
}
return true;
}else{
$this->errors[] = 'AUTH command failed: ' . trim(substr(trim($error),3));
return FALSE;
}
}
// ============= AUTH METHODS: BEGIN ==========================
/**
* Authenticates the user using the DIGEST-MD5 method.
*
* @param string The userid to authenticate as.
* @param string The password to authenticate with.
*
* @return mixed Returns a PEAR_Error with an error message on any
* kind of failure, or true on success.
* @access private
* @since 1.1.0
*/
function _authDigest_MD5($uid, $pwd)
{
$this->send_data('AUTH DIGEST-MD5');
-
+
/* 334: Continue authentication request */
if(($error=$this->_parseResponse(334)) !== true)
{
/* 503: Error: already authenticated */
if ($this->_code === 503) {
return true;
}
return $error;
}
$challenge = base64_decode($this->_arguments[0]);
$auth_str = base64_encode($this->get_digestMD5Auth($uid, $pwd, $challenge,
$this->host, "smtp"));
-
+
$this->send_data($auth_str);
-
+
/* 334: Continue authentication request */
if(($error=$this->_parseResponse(334)) !== true) return $error;
-
+
/*
* We don't use the protocol's third step because SMTP doesn't allow
* subsequent authentication, so we just silently ignore it.
*/
$this->send_data(' ');
-
+
/* 235: Authentication successful */
if(($error=$this->_parseResponse(235)) !== true) return $error;
}
-
-
+
+
/**
* Provides the (main) client response for DIGEST-MD5
* requires a few extra parameters than the other
* mechanisms, which are unavoidable.
- *
+ *
* @param string $authcid Authentication id (username)
* @param string $pass Password
* @param string $challenge The digest challenge sent by the server
* @param string $hostname The hostname of the machine you're connecting to
* @param string $service The servicename (eg. imap, pop, acap etc)
* @param string $authzid Authorization id (username to proxy as)
* @return string The digest response (NOT base64 encoded)
* @access public
*/
function get_digestMD5Auth($authcid, $pass, $challenge, $hostname, $service, $authzid = '')
{
$challenge = $this->_parseChallenge($challenge);
$authzid_string = '';
if ($authzid != '') {
- $authzid_string = ',authzid="' . $authzid . '"';
+ $authzid_string = ',authzid="' . $authzid . '"';
}
if (!empty($challenge)) {
$cnonce = $this->_getCnonce();
$digest_uri = sprintf('%s/%s', $service, $hostname);
$response_value = $this->_getResponseValue($authcid, $pass, $challenge['realm'], $challenge['nonce'], $cnonce, $digest_uri, $authzid);
return sprintf('username="%s",realm="%s"' . $authzid_string . ',nonce="%s",cnonce="%s",nc="00000001",qop=auth,digest-uri="%s",response=%s,%d', $authcid, $challenge['realm'], $challenge['nonce'], $cnonce, $digest_uri, $response_value, $challenge['maxbuf']);
} else {
return PEAR::raiseError('Invalid digest challenge');
}
}
-
+
/**
* Parses and verifies the digest challenge*
*
* @param string $challenge The digest challenge
* @return array The parsed challenge as an assoc
* array in the form "directive => value".
* @access private
*/
function _parseChallenge($challenge)
{
$tokens = array();
while (preg_match('/^([a-z-]+)=("[^"]+(?<!\\\)"|[^,]+)/i', $challenge, $matches)) {
// Ignore these as per rfc2831
if ($matches[1] == 'opaque' OR $matches[1] == 'domain') {
$challenge = substr($challenge, strlen($matches[0]) + 1);
continue;
}
// Allowed multiple "realm" and "auth-param"
if (!empty($tokens[$matches[1]]) AND ($matches[1] == 'realm' OR $matches[1] == 'auth-param')) {
if (is_array($tokens[$matches[1]])) {
$tokens[$matches[1]][] = preg_replace('/^"(.*)"$/', '\\1', $matches[2]);
} else {
$tokens[$matches[1]] = array($tokens[$matches[1]], preg_replace('/^"(.*)"$/', '\\1', $matches[2]));
}
// Any other multiple instance = failure
} elseif (!empty($tokens[$matches[1]])) {
$tokens = array();
break;
} else {
$tokens[$matches[1]] = preg_replace('/^"(.*)"$/', '\\1', $matches[2]);
}
// Remove the just parsed directive from the challenge
$challenge = substr($challenge, strlen($matches[0]) + 1);
}
/**
* Defaults and required directives
*/
// Realm
if (empty($tokens['realm'])) {
$uname = posix_uname();
$tokens['realm'] = $uname['nodename'];
}
-
+
// Maxbuf
if (empty($tokens['maxbuf'])) {
$tokens['maxbuf'] = 65536;
}
-
+
// Required: nonce, algorithm
if (empty($tokens['nonce']) OR empty($tokens['algorithm'])) {
return array();
}
-
+
return $tokens;
}
/**
* Creates the response= part of the digest response
*
* @param string $authcid Authentication id (username)
* @param string $pass Password
* @param string $realm Realm as provided by the server
* @param string $nonce Nonce as provided by the server
* @param string $cnonce Client nonce
* @param string $digest_uri The digest-uri= value part of the response
* @param string $authzid Authorization id
* @return string The response= part of the digest response
* @access private
- */
+ */
function _getResponseValue($authcid, $pass, $realm, $nonce, $cnonce, $digest_uri, $authzid = '')
{
if ($authzid == '') {
$A1 = sprintf('%s:%s:%s', pack('H32', md5(sprintf('%s:%s:%s', $authcid, $realm, $pass))), $nonce, $cnonce);
} else {
$A1 = sprintf('%s:%s:%s:%s', pack('H32', md5(sprintf('%s:%s:%s', $authcid, $realm, $pass))), $nonce, $cnonce, $authzid);
}
$A2 = 'AUTHENTICATE:' . $digest_uri;
return md5(sprintf('%s:%s:00000001:%s:auth:%s', md5($A1), $nonce, $cnonce, md5($A2)));
}
/**
* Creates the client nonce for the response
*
* @return string The cnonce value
* @access private
*/
function _getCnonce()
{
if (file_exists('/dev/urandom')) {
return base64_encode(fread(fopen('/dev/urandom', 'r'), 32));
} elseif (file_exists('/dev/random')) {
return base64_encode(fread(fopen('/dev/random', 'r'), 32));
} else {
$str = '';
mt_srand((double)microtime()*10000000);
for ($i=0; $i<32; $i++) {
$str .= chr(mt_rand(0, 255));
}
-
+
return base64_encode($str);
}
}
-
-
-
-
-
-
+
+
+
+
+
+
/**
* Authenticates the user using the CRAM-MD5 method.
*
* @param string The userid to authenticate as.
* @param string The password to authenticate with.
*
* @return mixed Returns a PEAR_Error with an error message on any
* kind of failure, or true on success.
* @access private
* @since 1.1.0
*/
function _authCRAM_MD5($uid, $pwd)
{
$this->send_data('AUTH CRAM-MD5');
-
+
/* 334: Continue authentication request */
if(($error=$this->_parseResponse(334)) !== true)
{
/* 503: Error: already authenticated */
if ($this->_code === 503) {
return true;
}
return $error;
}
$challenge = base64_decode($this->_arguments[0]);
$auth_str = base64_encode($uid . ' ' . $this->_HMAC_MD5($pwd, $challenge));
-
+
$this->send_data($auth_str);
/* 235: Authentication successful */
if ( ($error = $this->_parseResponse(235)) ) {
return $error;
}
}
/**
* Authenticates the user using the LOGIN method.
*
* @param string The userid to authenticate as.
* @param string The password to authenticate with.
*
* @return mixed Returns a PEAR_Error with an error message on any
* kind of failure, or true on success.
* @access private
* @since 1.1.0
*/
function _authLogin($uid, $pwd)
{
$this->send_data('AUTH LOGIN');
-
+
/* 334: Continue authentication request */
if(($error=$this->_parseResponse(334)) !== true)
{
/* 503: Error: already authenticated */
if ($this->_code === 503) {
return true;
}
return $error;
}
-
+
$this->send_data( base64_encode($uid) );
-
+
/* 334: Continue authentication request */
if(($error=$this->_parseResponse(334)) !== true) return $error;
-
+
$this->send_data( base64_encode($pwd) );
/* 235: Authentication successful */
if (($error=$this->_parseResponse(235)) !== true) return $error;
return true;
}
/**
* Authenticates the user using the PLAIN method.
*
* @param string The userid to authenticate as.
* @param string The password to authenticate with.
*
* @return mixed Returns a PEAR_Error with an error message on any
* kind of failure, or true on success.
* @access private
* @since 1.1.0
*/
function _authPlain($uid, $pwd)
{
$this->send_data('AUTH PLAIN');
-
+
/* 334: Continue authentication request */
if(($error=$this->_parseResponse(334)) !== true)
{
/* 503: Error: already authenticated */
if ($this->_code === 503) {
return true;
}
return $error;
}
$auth_str = base64_encode(chr(0) . $uid . chr(0) . $pwd);
$this->send_data($auth_str);
/* 235: Authentication successful */
if (($error=$this->_parseResponse(235)) !== true) return $error;
return true;
}
// ============= AUTH METHODS: END ==========================
/**
* Function which implements HMAC MD5 digest
*
* @param string $key The secret key
* @param string $data The data to protect
* @return string The HMAC MD5 digest
*/
function _HMAC_MD5($key, $data)
{
if (strlen($key) > 64) {
$key = pack('H32', md5($key));
}
-
+
if (strlen($key) < 64) {
$key = str_pad($key, 64, chr(0));
}
-
+
$k_ipad = substr($key, 0, 64) ^ str_repeat(chr(0x36), 64);
$k_opad = substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64);
-
+
$inner = pack('H32', md5($k_ipad . $data));
$digest = md5($k_opad . $inner);
-
+
return $digest;
}
-
+
/**
* Read a reply from the SMTP server. The reply consists of a response
* code and a response message.
*
* @param mixed $valid The set of valid response codes. These
* may be specified as an array of integer
* values or as a single integer value.
*
* @return mixed True if the server returned a valid response code or
* a PEAR_Error object is an error condition is reached.
*
* @access private
* @since 1.1.0
*
* @see getResponse
*/
function _parseResponse($valid)
{
-
+
$this->_code = -1;
$this->_arguments = array();
-
+
if(!is_resource($this->connection)) return false;
-
+
while ($line = fgets($this->connection, 512)) {
if ($this->debug) {
$this->debugtext.= "DEBUG: Recv: $line\n";
}
-
+
/* If we receive an empty line, the connection has been closed. */
if (empty($line)) {
$this->disconnect();
return 'Connection was unexpectedly closed';
}
-
+
/* Read the code and store the rest in the arguments array. */
$code = substr($line, 0, 3);
$this->_arguments[] = trim(substr($line, 4));
-
+
/* Check the syntax of the response code. */
if (is_numeric($code)) {
$this->_code = (int)$code;
} else {
$this->_code = -1;
break;
}
-
+
/* If this is not a multiline response, we're done. */
if (substr($line, 3, 1) != '-') {
break;
}
}
-
+
/* Compare the server's response code with the valid code. */
if (is_int($valid) && ($this->_code === $valid)) {
return true;
}
-
+
/* If we were given an array of valid response codes, check each one. */
if (is_array($valid)) {
foreach ($valid as $valid_code) {
if ($this->_code === $valid_code) {
return true;
}
}
}
-
+
return 'Invalid response code received from server';
}
-
+
/***************************************
** Function that handles the MAIL FROM: cmd
***************************************/
-
+
function mail($from){
if($this->is_connected()
AND $this->send_data('MAIL FROM:'.$from.'')
AND substr(trim($this->get_data()), 0, 2) === '250' ){
return TRUE;
}else
return FALSE;
}
/***************************************
** Function that handles the RCPT TO: cmd
***************************************/
-
+
function rcpt($to){
if($this->is_connected()
AND $this->send_data('RCPT TO:'.$to.'')
AND substr(trim($error = $this->get_data()), 0, 2) === '25' ){
return TRUE;
}else{
$this->errors[] = trim(substr(trim($error), 3));
return FALSE;
}
}
/***************************************
** Function that sends the DATA cmd
***************************************/
function data(){
if($this->is_connected()
AND $this->send_data('DATA')
AND substr(trim($error = $this->get_data()), 0, 3) === '354' ){
-
+
return TRUE;
}else{
$this->errors[] = trim(substr(trim($error), 3));
return FALSE;
}
}
/***************************************
** Function to determine if this object
** is connected to the server or not.
***************************************/
function is_connected(){
return (is_resource($this->connection) AND ($this->status === SMTP_STATUS_CONNECTED));
}
/***************************************
** Function to send a bit of data
***************************************/
function send_data($data){
-
- if($this->debug)
- {
- $this->buffer[] = "SEND: $data\n";
- }
- if ($this->debug) {
- $this->debugtext.= "DEBUG: Send: $data\n";
- }
+
+ if($this->debug)
+ {
+ $this->buffer[] = "SEND: $data\n";
+ }
+ if ($this->debug) {
+ $this->debugtext.= "DEBUG: Send: $data\n";
+ }
if(is_resource($this->connection)){
return fwrite($this->connection, $data.$this->CRLF, strlen($data)+2);
}else
- return FALSE;
+ return FALSE;
}
- function bytes_left($fp)
- {
- $status = socket_get_status ($fp);
- //print_r($status);
- $bytes = $status["unread_bytes"];
- return $bytes;
- }
+ function bytes_left($fp)
+ {
+ $status = socket_get_status ($fp);
+ //print_r($status);
+ $bytes = $status["unread_bytes"];
+ return $bytes;
+ }
/***************************************
** Function to get data.
***************************************/
function &get_data(){
-
+
$return = '';
$line = '';
if(is_resource($this->connection))
{
while(strpos($return, $this->CRLF) === FALSE OR substr($line,3,1) !== ' ')
- {
+ {
$line = fgets($this->connection, 512);
- $return .= $line;
+ $return .= $line;
}
if($this->debug)
{
- $this->buffer[] = "GET: ".$return."\n";
+ $this->buffer[] = "GET: ".$return."\n";
}
return $return;
}else
return FALSE;
}
/***************************************
** Sets a variable
***************************************/
-
+
function set($var, $value){
$this->$var = $value;
return TRUE;
}
-
+
}
?>
\ No newline at end of file
Property changes on: trunk/core/kernel/utility/smtp_client.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.2
\ No newline at end of property
+1.3
\ No newline at end of property
Index: trunk/core/kernel/utility/email.php
===================================================================
--- trunk/core/kernel/utility/email.php (revision 3539)
+++ trunk/core/kernel/utility/email.php (revision 3540)
@@ -1,440 +1,447 @@
<?php
class kEmailMessage extends kBase {
var $Compiled;
var $Headers;
var $HeadersArray;
var $BodyText;
var $BodyHtml;
var $Body;
var $Subject;
// var $From;
// var $To;
// var $ReplyTo;
// var $CC;
// var $BCC;
var $Charset;
var $LineFeed;
var $TransferEncoding;
var $From;
var $To;
var $IsMultipart;
var $Parts;
var $Files;
var $TextBoundary;
var $EmailBoundary;
function kEmailMessage(){
parent::kBase();
//$this->TextBoundary = uniqid(adodb_mktime());
$this->EmailBoundary = uniqid(adodb_mktime());
$this->LineFeed = "\n";
$this->Charset='ISO-8859-1';
$this->TransferEncoding='8bit';
$this->Body = '';
$this->setHeader('Subject', 'Automatically generated message');
$this->HeadersArray=array();
$this->setHeader('Mime-Version', '1.0');
}
function setHeader($header, $value){
$this->HeadersArray[$header] = $value;
$this->Compiled = false;
}
+ function fixLineBreaks($data)
+ {
+ $data = str_replace("\n\n","\r\n\r\n",$data);
+ $data = str_replace("\r\n","\n",$data);
+ $data = str_replace("\n","\r\n",$data);
+ return $data;
+ }
+
function setHeaders($headers){
- $headers=str_replace("\r", "", $headers);
- $headers_lines = explode("\n", $headers);
+ $headers=$this->fixLineBreaks($headers);
+ $headers_lines = explode("\r\n", $headers);
foreach ($headers_lines as $line_num => $line){
list($header_field, $header_value) = explode(':', $line, 2);
$header_value = trim($header_value);
$this->setHeader($header_field, $header_value);
if ($header_field == 'Subject') $this->Subject = $header_value;
}
}
function appendHeader($header, $value){
$this->HeadersArray[$header][] = $value;
$this->Compiled = false;
}
function setFrom($from, $name=''){
$this->From = $from;
if ($name!=''){
$from = trim($name).' <'.$from.'>';
}
$this->setHeader('From', trim($from));
}
function setTo($to, $name=''){
$this->To = $to;
if ($name!=''){
$to = trim($name).' <'.$to.'>';
}
$this->setHeader('To', trim($to));
}
function setSubject($subj){
$this->setHeader('Subject', $subj);
}
function SetCC($to_cc){
$this->appendHeader('CC', $to_cc);
}
function SetBCC($to_bcc){
$this->appendHeader('BCC', $to_bcc);
}
function setReplyTo($reply_to){
$this->setHeader('Reply-to', $reply_to);
}
function Clear()
{
$this->Compiled = false;
$this->Body = '';
$this->BodyHtml = '';
$this->BodyText = '';
$this->Headers = '';
$this->Files = '';
$this->From = '';
$this->To = '';
}
function setTextBody($body_text){
$this->BodyText = $body_text;
$this->Compiled = false;
}
function setHTMLBody($body_html){
$this->BodyHtml = $body_html;
$this->IsMultipart = true;
$this->Compiled = false;
}
function compileBody(){
$search = array (
"'(<\/td>.*)[\r\n]+(.*<td)'i",//formating text in tables
"'(<br[ ]?[\/]?>)|(<\/p>)|(<\/div>)|(<\/tr>)'i",
"'<head>(.*?)</head>'si",
"'<style(.*?)</style>'si",
"'<title>(.*?)</title>'si",
"'<script(.*?)</script>'si",
// "'^[\s\n\r\t]+'", //strip all spacers & newlines in the begin of document
// "'[\s\n\r\t]+$'", //strip all spacers & newlines in the end of document
"'&(quot|#34);'i",
"'&(amp|#38);'i",
"'&(lt|#60);'i",
"'&(gt|#62);'i",
"'&(nbsp|#160);'i",
"'&(iexcl|#161);'i",
"'&(cent|#162);'i",
"'&(pound|#163);'i",
"'&(copy|#169);'i",
"'&#(\d+);'e"
);
$replace = array (
"\\1\t\\2",
"\n",
"",
"",
"",
"",
// "",
// "",
"\"",
"&",
"<",
">",
" ",
chr(161),
chr(162),
chr(163),
chr(169),
"chr(\\1)"
);
if($this->BodyHtml){
$not_html = preg_replace ($search, $replace, $this->BodyHtml);
$not_html = strip_tags($not_html);
// $not_html = $this->removeBlankLines($not_html);
// Fixing problem with add exclamation characters "!" into the body of the email.
$not_html = wordwrap($not_html, 72);
$this->BodyHtml = wordwrap($this->BodyHtml, 72);
$this->Body = '';
//$this->Body .= 'Content-Type: multipart/alternative;'.$this->LF()." ".'boundary="----='.$this->TextBoundary.'"'.$this->LF();
//$this->Body .= $this->LF();
$this->Body .= '------='.$this->EmailBoundary.$this->LF();
- $this->Body .= 'Content-Type: text/plain;'.$this->LF()." ".'charset="'.$this->Charset.'"'.$this->LF();
+ $this->Body .= 'Content-Type: text/plain;'." ".'charset="'.$this->Charset.'"'.$this->LF();
$this->Body .= $this->LF();
$this->Body .= $not_html.$this->LF().$this->LF();
$this->Body .= '------='.$this->EmailBoundary.$this->LF();
- $this->Body .= 'Content-Type: text/html;'.$this->LF()." ".'charset="'.$this->Charset.'"'.$this->LF();
+ $this->Body .= 'Content-Type: text/html;'." ".'charset="'.$this->Charset.'"'.$this->LF();
$this->Body .= 'Content-Transfer-Encoding: '.$this->TransferEncoding.$this->LF();
$this->Body .= 'Content-Description: HTML part'.$this->LF();
$this->Body .= 'Content-Disposition: inline'.$this->LF();
$this->Body .= $this->LF();
$this->BodyHtml = str_replace("\r", "", $this->BodyHtml);
$this->BodyHtml = str_replace("\n", $this->LF(), $this->BodyHtml);
$this->Body .= $this->BodyHtml;
$this->Body .= $this->LF().$this->LF();
$this->IsMultipart = true;
}else{
$not_html = preg_replace ($search, $replace, $this->BodyText);
$not_html = strip_tags($not_html);
// $not_html = $this->removeBlankLines($not_html);
// Fixing problem with add exclamation characters "!" into the body of the email.
$not_html = wordwrap($not_html, 72);
if ($this->IsMultipart){
$this->Body .= '------='.$this->EmailBoundary.$this->LF();
$this->Body .= 'Content-Type: text/plain;'.$this->LF()." ".'charset="'.$this->Charset.'"'.$this->LF();
$this->Body .= 'Content-Disposition: inline'.$this->LF();
$this->Body .= $this->LF();
$this->Body .= $not_html.$this->LF().$this->LF();
}else{
//$this->BodyText = str_replace("\r", "", $this->BodyText);
//$this->BodyText = str_replace("\n", $this->LF(), $this->BodyText);
$this->Body = $not_html;
}
}
}
-
-
function setCharset($charset){
$this->Charset = $charset;
$this->Compiled = false;
}
function setLineFeed($linefeed){
$this->LineFeed=$linefeed;
}
-
-
function attachFile($filepath, $mime="application/octet-stream"){
if(is_file($filepath)){
$file_info = array('path'=>$filepath, 'mime'=>$mime);
$this->Files[] = $file_info;
}else{
die('File "'.$filepath.'" not exist...'."\n");
}
$this->IsMultipart = true;
$this->Compiled = false;
}
function LF($str=''){
$str = str_replace("\n", "", $str);
$str = str_replace("\r", "", $str);
return $str.$this->LineFeed;
}
function getContentType(){
$content_type="";
if ($this->IsMultipart){
- $content_type .= $this->LF('multipart/alternative;');
- $content_type .= $this->LF(" ".'boundary="----='.$this->EmailBoundary.'"');
+ $content_type .= $this->LF('multipart/alternative; boundary="----='.$this->EmailBoundary.'"');
}else{
$content_type .= $this->LF('text/plain;');
$content_type .= $this->LF(" ".'charset='.$this->Charset);
}
return $content_type;
}
// ========================================
function compileHeaders(){
$this->Headers="";
// $this->Headers .= "From: ".$this->LF($this->From);
//if ($this->ReplyTo){
// $this->Headers .= "Reply-To: ".$this->ReplyTo.$this->LF();
//}
//$this->Headers .= "To: ".$this->LF($this->To);
//$this->Headers .= "Subject: ".$this->LF($this->Subject);
/*
if (sizeof($this->CC)){
$this->Headers .= "Cc: ";
foreach ($this->Cc as $key => $addr){
$this->Headers.=$this->LF($addr.',');
}
}
if (sizeof($this->BCC)){
$this->Headers .= "Bcc: ";
foreach ($this->BCC as $key => $addr){
$this->Headers.=$this->LF($addr.',');
}
}
*/
foreach ($this->HeadersArray as $key => $val){
if ($key=="To" || $key=="") continue; // avoid duplicate "To" field in headers
if (is_array($val)){
$val = chunk_split(implode(', ', $val),72, $this->LF().' ');
$this->Headers .= $key.": ".$val.$this->LF();
}else{
$this->Headers .= $key.": ".$val.$this->LF();
}
}
+ if ($this->IsMultipart) {
+ $this->Headers .= 'MIME-Version: 1.0'.$this->LF();
+ }
$this->Headers .= "Content-Type: ".$this->getContentType();
//$this->Headers .= "Content-Transfer-Encoding: ".$this->TransferEncoding.$this->LF();
}
function compileFiles(){
if ($this->Files){
foreach($this->Files as $key => $file_info)
{
$filepath = $file_info['path'];
$mime = $file_info['mime'];
$attachment_header = $this->LF('------='.$this->EmailBoundary);
$attachment_header .= $this->LF('Content-Type: '.$mime.'; name="'.basename($filepath).'"');
$attachment_header .= $this->LF('Content-Transfer-Encoding: base64');
$attachment_header .= $this->LF('Content-Description: '.basename($filepath));
$attachment_header .= $this->LF('Content-Disposition: attachment; filename="'.basename($filepath).'"');
$attachment_header .= $this->LF('');
$attachment_data = fread(fopen($filepath,"rb"),filesize($filepath));
$attachment_data = base64_encode($attachment_data);
$attachment_data = chunk_split($attachment_data,72);
$this->Body .= $attachment_header.$attachment_data.$this->LF('');
$this->IsMultipart = true;
}
}
}
function compile(){
if ($this->Compiled) return;
$this->compileBody();
$this->compileFiles();
$this->compileHeaders();
// Compile
if ($this->IsMultipart){
$this->Body .= '------='.$this->EmailBoundary.'--'.$this->LF();
}
+ $this->Body = $this->fixLineBreaks($this->Body);
+ $this->Headers = $this->fixLineBreaks($this->Headers);
+
+
$this->Compiled = true;
}
// ========================================
function getHeaders(){
$this->Compile();
return $this->Headers;
}
function getBody(){
$this->Compile();
return $this->Body;
}
function send(){
return mail($this->HeadersArray['To'], $this->HeadersArray['Subject'], "", $this->getHeaders().$this->LF().$this->LF().$this->getBody());
//return mail($this->HeadersArray['To'], $this->HeadersArray['Subject'], "", $this->getHeaders().$this->LF().$this->LF().$this->getBody(), '-f'.$this->From);
}
function sendSMTP(&$smtp_object, $smtp_host, $user, $pass, $auth_used = 0){
$params['host'] = $smtp_host; // The smtp server host/ip
$params['port'] = 25; // The smtp server port
$params['helo'] = $_SERVER['HTTP_HOST']; // What to use when sending the helo command. Typically, your domain/hostname
$params['auth'] = TRUE; // Whether to use basic authentication or not
$params['user'] = $user; // Username for authentication
$params['pass'] = $pass; // Password for authentication
$params['debug'] = 1;
if ($auth_used == 0){
$params['authmethod'] = 'NOAUTH'; // forse disabling auth
}
if (strpos($this->To, ',') !== false) {
$this->To = str_replace(' ', '', $this->To);
$send_params['recipients'] = explode(',', $this->To);
}
else {
$send_params['recipients'] = array($this->To); // The recipients (can be multiple)
}
- $send_params['headers'] = array(
- 'From: '.$this->HeadersArray['From'], // Headers
- 'To: '.$this->HeadersArray['To'],
- 'Subject: '.$this->HeadersArray['Subject'],
- 'Content-type: '.$this->getContentType(),
- $this->getBody(),
- );
+
+ $send_params['headers'] = explode("\r\n", $this->getHeaders());
+
+ array_unshift($send_params['headers'], 'To: '.$this->HeadersArray['To']);
$send_params['from'] = $this->From; // This is used as in the MAIL FROM: cmd
// It should end up as the Return-Path: header
- $send_params['body']="\n";
+ $send_params['body']=$this->getBody();
if($smtp_object->connect($params) && $smtp_object->send($send_params)){
return true;
}
else {
if ( $this->Application->isDebugMode() )
{
$this->Application->Debugger->appendHTML('<pre>'.$smtp_object->debugtext.'</pre>');
//define('DBG_REDIRECT', 1);
}
return false;
}
}
}
?>
Property changes on: trunk/core/kernel/utility/email.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.11
\ No newline at end of property
+1.12
\ No newline at end of property

Event Timeline