added google xoauth2 support + fixed a journaling issue

This commit is contained in:
SJ
2012-09-28 10:34:04 +02:00
parent f930aacc84
commit 55de53bb26
111 changed files with 38812 additions and 4 deletions

View File

@ -0,0 +1,350 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Mail
* @subpackage Transport
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Abstract.php 24593 2012-01-05 20:35:02Z matthew $
*/
/**
* @see Zend_Mime
*/
require_once 'Zend/Mime.php';
/**
* Abstract for sending eMails through different
* ways of transport
*
* @category Zend
* @package Zend_Mail
* @subpackage Transport
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Mail_Transport_Abstract
{
/**
* Mail body
* @var string
* @access public
*/
public $body = '';
/**
* MIME boundary
* @var string
* @access public
*/
public $boundary = '';
/**
* Mail header string
* @var string
* @access public
*/
public $header = '';
/**
* Array of message headers
* @var array
* @access protected
*/
protected $_headers = array();
/**
* Message is a multipart message
* @var boolean
* @access protected
*/
protected $_isMultipart = false;
/**
* Zend_Mail object
* @var false|Zend_Mail
* @access protected
*/
protected $_mail = false;
/**
* Array of message parts
* @var array
* @access protected
*/
protected $_parts = array();
/**
* Recipients string
* @var string
* @access public
*/
public $recipients = '';
/**
* EOL character string used by transport
* @var string
* @access public
*/
public $EOL = "\r\n";
/**
* Send an email independent from the used transport
*
* The requisite information for the email will be found in the following
* properties:
*
* - {@link $recipients} - list of recipients (string)
* - {@link $header} - message header
* - {@link $body} - message body
*/
abstract protected function _sendMail();
/**
* Return all mail headers as an array
*
* If a boundary is given, a multipart header is generated with a
* Content-Type of either multipart/alternative or multipart/mixed depending
* on the mail parts present in the {@link $_mail Zend_Mail object} present.
*
* @param string $boundary
* @return array
*/
protected function _getHeaders($boundary)
{
if (null !== $boundary) {
// Build multipart mail
$type = $this->_mail->getType();
if (!$type) {
if ($this->_mail->hasAttachments) {
$type = Zend_Mime::MULTIPART_MIXED;
} elseif ($this->_mail->getBodyText() && $this->_mail->getBodyHtml()) {
$type = Zend_Mime::MULTIPART_ALTERNATIVE;
} else {
$type = Zend_Mime::MULTIPART_MIXED;
}
}
$this->_headers['Content-Type'] = array(
$type . ';'
. $this->EOL
. " " . 'boundary="' . $boundary . '"'
);
$this->boundary = $boundary;
}
$this->_headers['MIME-Version'] = array('1.0');
return $this->_headers;
}
/**
* Prepend header name to header value
*
* @param string $item
* @param string $key
* @param string $prefix
* @static
* @access protected
* @return void
*/
protected static function _formatHeader(&$item, $key, $prefix)
{
$item = $prefix . ': ' . $item;
}
/**
* Prepare header string for use in transport
*
* Prepares and generates {@link $header} based on the headers provided.
*
* @param mixed $headers
* @access protected
* @return void
* @throws Zend_Mail_Transport_Exception if any header lines exceed 998
* characters
*/
protected function _prepareHeaders($headers)
{
if (!$this->_mail) {
/**
* @see Zend_Mail_Transport_Exception
*/
require_once 'Zend/Mail/Transport/Exception.php';
throw new Zend_Mail_Transport_Exception('Missing Zend_Mail object in _mail property');
}
$this->header = '';
foreach ($headers as $header => $content) {
if (isset($content['append'])) {
unset($content['append']);
$value = implode(',' . $this->EOL . ' ', $content);
$this->header .= $header . ': ' . $value . $this->EOL;
} else {
array_walk($content, array(get_class($this), '_formatHeader'), $header);
$this->header .= implode($this->EOL, $content) . $this->EOL;
}
}
// Sanity check on headers -- should not be > 998 characters
$sane = true;
foreach (explode($this->EOL, $this->header) as $line) {
if (strlen(trim($line)) > 998) {
$sane = false;
break;
}
}
if (!$sane) {
/**
* @see Zend_Mail_Transport_Exception
*/
require_once 'Zend/Mail/Transport/Exception.php';
throw new Zend_Mail_Exception('At least one mail header line is too long');
}
}
/**
* Generate MIME compliant message from the current configuration
*
* If both a text and HTML body are present, generates a
* multipart/alternative Zend_Mime_Part containing the headers and contents
* of each. Otherwise, uses whichever of the text or HTML parts present.
*
* The content part is then prepended to the list of Zend_Mime_Parts for
* this message.
*
* @return void
*/
protected function _buildBody()
{
if (($text = $this->_mail->getBodyText())
&& ($html = $this->_mail->getBodyHtml()))
{
// Generate unique boundary for multipart/alternative
$mime = new Zend_Mime(null);
$boundaryLine = $mime->boundaryLine($this->EOL);
$boundaryEnd = $mime->mimeEnd($this->EOL);
$text->disposition = false;
$html->disposition = false;
$body = $boundaryLine
. $text->getHeaders($this->EOL)
. $this->EOL
. $text->getContent($this->EOL)
. $this->EOL
. $boundaryLine
. $html->getHeaders($this->EOL)
. $this->EOL
. $html->getContent($this->EOL)
. $this->EOL
. $boundaryEnd;
$mp = new Zend_Mime_Part($body);
$mp->type = Zend_Mime::MULTIPART_ALTERNATIVE;
$mp->boundary = $mime->boundary();
$this->_isMultipart = true;
// Ensure first part contains text alternatives
array_unshift($this->_parts, $mp);
// Get headers
$this->_headers = $this->_mail->getHeaders();
return;
}
// If not multipart, then get the body
if (false !== ($body = $this->_mail->getBodyHtml())) {
array_unshift($this->_parts, $body);
} elseif (false !== ($body = $this->_mail->getBodyText())) {
array_unshift($this->_parts, $body);
}
if (!$body) {
/**
* @see Zend_Mail_Transport_Exception
*/
require_once 'Zend/Mail/Transport/Exception.php';
throw new Zend_Mail_Transport_Exception('No body specified');
}
// Get headers
$this->_headers = $this->_mail->getHeaders();
$headers = $body->getHeadersArray($this->EOL);
foreach ($headers as $header) {
// Headers in Zend_Mime_Part are kept as arrays with two elements, a
// key and a value
$this->_headers[$header[0]] = array($header[1]);
}
}
/**
* Send a mail using this transport
*
* @param Zend_Mail $mail
* @access public
* @return void
* @throws Zend_Mail_Transport_Exception if mail is empty
*/
public function send(Zend_Mail $mail)
{
$this->_isMultipart = false;
$this->_mail = $mail;
$this->_parts = $mail->getParts();
$mime = $mail->getMime();
// Build body content
$this->_buildBody();
// Determine number of parts and boundary
$count = count($this->_parts);
$boundary = null;
if ($count < 1) {
/**
* @see Zend_Mail_Transport_Exception
*/
require_once 'Zend/Mail/Transport/Exception.php';
throw new Zend_Mail_Transport_Exception('Empty mail cannot be sent');
}
if ($count > 1) {
// Multipart message; create new MIME object and boundary
$mime = new Zend_Mime($this->_mail->getMimeBoundary());
$boundary = $mime->boundary();
} elseif ($this->_isMultipart) {
// multipart/alternative -- grab boundary
$boundary = $this->_parts[0]->boundary;
}
// Determine recipients, and prepare headers
$this->recipients = implode(',', $mail->getRecipients());
$this->_prepareHeaders($this->_getHeaders($boundary));
// Create message body
// This is done so that the same Zend_Mail object can be used in
// multiple transports
$message = new Zend_Mime_Message();
$message->setParts($this->_parts);
$message->setMime($mime);
$this->body = $message->generateMessage($this->EOL);
// Send to transport!
$this->_sendMail();
}
}

View File

@ -0,0 +1,39 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Mail
* @subpackage Transport
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Exception.php 24593 2012-01-05 20:35:02Z matthew $
*/
/**
* @see Zend_Mail_Exception
*/
require_once 'Zend/Mail/Exception.php';
/**
* @category Zend
* @package Zend_Mail
* @subpackage Transport
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Mail_Transport_Exception extends Zend_Mail_Exception
{}

View File

@ -0,0 +1,134 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Mail
* @subpackage Transport
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id$
*/
/**
* @see Zend_Mail_Transport_Abstract
*/
require_once 'Zend/Mail/Transport/Abstract.php';
/**
* File transport
*
* Class for saving outgoing emails in filesystem
*
* @category Zend
* @package Zend_Mail
* @subpackage Transport
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Mail_Transport_File extends Zend_Mail_Transport_Abstract
{
/**
* Target directory for saving sent email messages
*
* @var string
*/
protected $_path;
/**
* Callback function generating a file name
*
* @var string|array
*/
protected $_callback;
/**
* Constructor
*
* @param array|Zend_Config $options OPTIONAL (Default: null)
* @return void
*/
public function __construct($options = null)
{
if ($options instanceof Zend_Config) {
$options = $options->toArray();
} elseif (!is_array($options)) {
$options = array();
}
// Making sure we have some defaults to work with
if (!isset($options['path'])) {
$options['path'] = sys_get_temp_dir();
}
if (!isset($options['callback'])) {
$options['callback'] = array($this, 'defaultCallback');
}
$this->setOptions($options);
}
/**
* Sets options
*
* @param array $options
* @return void
*/
public function setOptions(array $options)
{
if (isset($options['path']) && is_dir($options['path'])) {
$this->_path = $options['path'];
}
if (isset($options['callback']) && is_callable($options['callback'])) {
$this->_callback = $options['callback'];
}
}
/**
* Saves e-mail message to a file
*
* @return void
* @throws Zend_Mail_Transport_Exception on not writable target directory
* @throws Zend_Mail_Transport_Exception on file_put_contents() failure
*/
protected function _sendMail()
{
$file = $this->_path . DIRECTORY_SEPARATOR . call_user_func($this->_callback, $this);
if (!is_writable(dirname($file))) {
require_once 'Zend/Mail/Transport/Exception.php';
throw new Zend_Mail_Transport_Exception(sprintf(
'Target directory "%s" does not exist or is not writable',
dirname($file)
));
}
$email = $this->header . $this->EOL . $this->body;
if (!file_put_contents($file, $email)) {
require_once 'Zend/Mail/Transport/Exception.php';
throw new Zend_Mail_Transport_Exception('Unable to send mail');
}
}
/**
* Default callback for generating filenames
*
* @param Zend_Mail_Transport_File File transport instance
* @return string
*/
public function defaultCallback($transport)
{
return 'ZendMail_' . $_SERVER['REQUEST_TIME'] . '_' . mt_rand() . '.tmp';
}
}

View File

@ -0,0 +1,220 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Mail
* @subpackage Transport
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Sendmail.php 24593 2012-01-05 20:35:02Z matthew $
*/
/**
* @see Zend_Mail_Transport_Abstract
*/
require_once 'Zend/Mail/Transport/Abstract.php';
/**
* Class for sending eMails via the PHP internal mail() function
*
* @category Zend
* @package Zend_Mail
* @subpackage Transport
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Mail_Transport_Sendmail extends Zend_Mail_Transport_Abstract
{
/**
* Subject
* @var string
* @access public
*/
public $subject = null;
/**
* Config options for sendmail parameters
*
* @var string
*/
public $parameters;
/**
* EOL character string
* @var string
* @access public
*/
public $EOL = PHP_EOL;
/**
* error information
* @var string
*/
protected $_errstr;
/**
* Constructor.
*
* @param string|array|Zend_Config $parameters OPTIONAL (Default: null)
* @return void
*/
public function __construct($parameters = null)
{
if ($parameters instanceof Zend_Config) {
$parameters = $parameters->toArray();
}
if (is_array($parameters)) {
$parameters = implode(' ', $parameters);
}
$this->parameters = $parameters;
}
/**
* Send mail using PHP native mail()
*
* @access public
* @return void
* @throws Zend_Mail_Transport_Exception if parameters is set
* but not a string
* @throws Zend_Mail_Transport_Exception on mail() failure
*/
public function _sendMail()
{
if ($this->parameters === null) {
set_error_handler(array($this, '_handleMailErrors'));
$result = mail(
$this->recipients,
$this->_mail->getSubject(),
$this->body,
$this->header);
restore_error_handler();
} else {
if(!is_string($this->parameters)) {
/**
* @see Zend_Mail_Transport_Exception
*
* Exception is thrown here because
* $parameters is a public property
*/
require_once 'Zend/Mail/Transport/Exception.php';
throw new Zend_Mail_Transport_Exception(
'Parameters were set but are not a string'
);
}
set_error_handler(array($this, '_handleMailErrors'));
$result = mail(
$this->recipients,
$this->_mail->getSubject(),
$this->body,
$this->header,
$this->parameters);
restore_error_handler();
}
if ($this->_errstr !== null || !$result) {
/**
* @see Zend_Mail_Transport_Exception
*/
require_once 'Zend/Mail/Transport/Exception.php';
throw new Zend_Mail_Transport_Exception('Unable to send mail. ' . $this->_errstr);
}
}
/**
* Format and fix headers
*
* mail() uses its $to and $subject arguments to set the To: and Subject:
* headers, respectively. This method strips those out as a sanity check to
* prevent duplicate header entries.
*
* @access protected
* @param array $headers
* @return void
* @throws Zend_Mail_Transport_Exception
*/
protected function _prepareHeaders($headers)
{
if (!$this->_mail) {
/**
* @see Zend_Mail_Transport_Exception
*/
require_once 'Zend/Mail/Transport/Exception.php';
throw new Zend_Mail_Transport_Exception('_prepareHeaders requires a registered Zend_Mail object');
}
// mail() uses its $to parameter to set the To: header, and the $subject
// parameter to set the Subject: header. We need to strip them out.
if (0 === strpos(PHP_OS, 'WIN')) {
// If the current recipients list is empty, throw an error
if (empty($this->recipients)) {
/**
* @see Zend_Mail_Transport_Exception
*/
require_once 'Zend/Mail/Transport/Exception.php';
throw new Zend_Mail_Transport_Exception('Missing To addresses');
}
} else {
// All others, simply grab the recipients and unset the To: header
if (!isset($headers['To'])) {
/**
* @see Zend_Mail_Transport_Exception
*/
require_once 'Zend/Mail/Transport/Exception.php';
throw new Zend_Mail_Transport_Exception('Missing To header');
}
unset($headers['To']['append']);
$this->recipients = implode(',', $headers['To']);
}
// Remove recipient header
unset($headers['To']);
// Remove subject header, if present
if (isset($headers['Subject'])) {
unset($headers['Subject']);
}
// Prepare headers
parent::_prepareHeaders($headers);
// Fix issue with empty blank line ontop when using Sendmail Trnasport
$this->header = rtrim($this->header);
}
/**
* Temporary error handler for PHP native mail().
*
* @param int $errno
* @param string $errstr
* @param string $errfile
* @param string $errline
* @param array $errcontext
* @return true
*/
public function _handleMailErrors($errno, $errstr, $errfile = null, $errline = null, array $errcontext = null)
{
$this->_errstr = $errstr;
return true;
}
}

View File

@ -0,0 +1,243 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Mail
* @subpackage Transport
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Smtp.php 24593 2012-01-05 20:35:02Z matthew $
*/
/**
* @see Zend_Mime
*/
require_once 'Zend/Mime.php';
/**
* @see Zend_Mail_Protocol_Smtp
*/
require_once 'Zend/Mail/Protocol/Smtp.php';
/**
* @see Zend_Mail_Transport_Abstract
*/
require_once 'Zend/Mail/Transport/Abstract.php';
/**
* SMTP connection object
*
* Loads an instance of Zend_Mail_Protocol_Smtp and forwards smtp transactions
*
* @category Zend
* @package Zend_Mail
* @subpackage Transport
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Mail_Transport_Smtp extends Zend_Mail_Transport_Abstract
{
/**
* EOL character string used by transport
* @var string
* @access public
*/
public $EOL = "\n";
/**
* Remote smtp hostname or i.p.
*
* @var string
*/
protected $_host;
/**
* Port number
*
* @var integer|null
*/
protected $_port;
/**
* Local client hostname or i.p.
*
* @var string
*/
protected $_name = 'localhost';
/**
* Authentication type OPTIONAL
*
* @var string
*/
protected $_auth;
/**
* Config options for authentication
*
* @var array
*/
protected $_config;
/**
* Instance of Zend_Mail_Protocol_Smtp
*
* @var Zend_Mail_Protocol_Smtp
*/
protected $_connection;
/**
* Constructor.
*
* @param string $host OPTIONAL (Default: 127.0.0.1)
* @param array|null $config OPTIONAL (Default: null)
* @return void
*
* @todo Someone please make this compatible
* with the SendMail transport class.
*/
public function __construct($host = '127.0.0.1', Array $config = array())
{
if (isset($config['name'])) {
$this->_name = $config['name'];
}
if (isset($config['port'])) {
$this->_port = $config['port'];
}
if (isset($config['auth'])) {
$this->_auth = $config['auth'];
}
$this->_host = $host;
$this->_config = $config;
}
/**
* Class destructor to ensure all open connections are closed
*
* @return void
*/
public function __destruct()
{
if ($this->_connection instanceof Zend_Mail_Protocol_Smtp) {
try {
$this->_connection->quit();
} catch (Zend_Mail_Protocol_Exception $e) {
// ignore
}
$this->_connection->disconnect();
}
}
/**
* Sets the connection protocol instance
*
* @param Zend_Mail_Protocol_Abstract $client
*
* @return void
*/
public function setConnection(Zend_Mail_Protocol_Abstract $connection)
{
$this->_connection = $connection;
}
/**
* Gets the connection protocol instance
*
* @return Zend_Mail_Protocol|null
*/
public function getConnection()
{
return $this->_connection;
}
/**
* Send an email via the SMTP connection protocol
*
* The connection via the protocol adapter is made just-in-time to allow a
* developer to add a custom adapter if required before mail is sent.
*
* @return void
* @todo Rename this to sendMail, it's a public method...
*/
public function _sendMail()
{
// If sending multiple messages per session use existing adapter
if (!($this->_connection instanceof Zend_Mail_Protocol_Smtp)) {
// Check if authentication is required and determine required class
$connectionClass = 'Zend_Mail_Protocol_Smtp';
if ($this->_auth) {
$connectionClass .= '_Auth_' . ucwords($this->_auth);
}
if (!class_exists($connectionClass)) {
require_once 'Zend/Loader.php';
Zend_Loader::loadClass($connectionClass);
}
$this->setConnection(new $connectionClass($this->_host, $this->_port, $this->_config));
$this->_connection->connect();
$this->_connection->helo($this->_name);
} else {
// Reset connection to ensure reliable transaction
$this->_connection->rset();
}
// Set sender email address
$this->_connection->mail($this->_mail->getReturnPath());
// Set recipient forward paths
foreach ($this->_mail->getRecipients() as $recipient) {
$this->_connection->rcpt($recipient);
}
// Issue DATA command to client
$this->_connection->data($this->header . Zend_Mime::LINEEND . $this->body);
}
/**
* Format and fix headers
*
* Some SMTP servers do not strip BCC headers. Most clients do it themselves as do we.
*
* @access protected
* @param array $headers
* @return void
* @throws Zend_Transport_Exception
*/
protected function _prepareHeaders($headers)
{
if (!$this->_mail) {
/**
* @see Zend_Mail_Transport_Exception
*/
require_once 'Zend/Mail/Transport/Exception.php';
throw new Zend_Mail_Transport_Exception('_prepareHeaders requires a registered Zend_Mail object');
}
unset($headers['Bcc']);
// Prepare headers
parent::_prepareHeaders($headers);
}
}