Skip to content

Commit

Permalink
Merge pull request #12468 from cakephp/3.next-email-transport
Browse files Browse the repository at this point in the history
3.next email transport
  • Loading branch information
markstory committed Aug 22, 2018
2 parents 2856f0a + 952e227 commit 891e6ae
Show file tree
Hide file tree
Showing 8 changed files with 336 additions and 157 deletions.
126 changes: 25 additions & 101 deletions src/Mailer/Email.php
Expand Up @@ -15,7 +15,6 @@
namespace Cake\Mailer;

use BadMethodCallException;
use Cake\Core\App;
use Cake\Core\Configure;
use Cake\Core\StaticConfigTrait;
use Cake\Filesystem\File;
Expand Down Expand Up @@ -293,22 +292,13 @@ class Email implements JsonSerializable, Serializable
protected $_priority;

/**
* An array mapping url schemes to fully qualified Transport class names
* An array mapping url schemes to fully qualified Transport class names.
* Unused.
*
* @var array
* @deprecated 3.7.0 This property is unused and will be removed in 4.0.0.
*/
protected static $_dsnClassMap = [
'debug' => 'Cake\Mailer\Transport\DebugTransport',
'mail' => 'Cake\Mailer\Transport\MailTransport',
'smtp' => 'Cake\Mailer\Transport\SmtpTransport',
];

/**
* Configuration profiles for transports.
*
* @var array
*/
protected static $_transportConfig = [];
protected static $_dsnClassMap = [];

/**
* A copy of the configuration profile for this
Expand Down Expand Up @@ -1560,7 +1550,7 @@ public function emailFormat($format = null)
public function setTransport($name)
{
if (is_string($name)) {
$transport = $this->_constructTransport($name);
$transport = TransportFactory::get($name);
} elseif (is_object($name)) {
$transport = $name;
} else {
Expand Down Expand Up @@ -1611,61 +1601,6 @@ public function transport($name = null)
return $this->setTransport($name);
}

/**
* Build a transport instance from configuration data.
*
* @param string $name The transport configuration name to build.
* @return \Cake\Mailer\AbstractTransport
* @throws \InvalidArgumentException When transport configuration is missing or invalid.
*/
protected function _constructTransport($name)
{
if (!isset(static::$_transportConfig[$name])) {
throw new InvalidArgumentException(sprintf('Transport config "%s" is missing.', $name));
}

if (!isset(static::$_transportConfig[$name]['className'])) {
throw new InvalidArgumentException(
sprintf('Transport config "%s" is invalid, the required `className` option is missing', $name)
);
}

$config = static::$_transportConfig[$name];

if (is_object($config['className'])) {
if (!$config['className'] instanceof AbstractTransport) {
throw new InvalidArgumentException(sprintf(
'Transport object must be of type "AbstractTransport". Found invalid type: "%s".',
get_class($config['className'])
));
}

return $config['className'];
}

$className = App::className($config['className'], 'Mailer/Transport', 'Transport');
if (!$className) {
$className = App::className($config['className'], 'Network/Email', 'Transport');
if ($className) {
trigger_error(
'Transports in "Network/Email" are deprecated, use "Mailer/Transport" instead.',
E_USER_DEPRECATED
);
}
}

if (!$className) {
throw new InvalidArgumentException(sprintf('Transport class "%s" not found.', $config['className']));
}
if (!method_exists($className, 'send')) {
throw new InvalidArgumentException(sprintf('The "%s" does not have a send() method.', $className));
}

unset($config['className']);

return new $className($config);
}

/**
* Sets message ID.
*
Expand Down Expand Up @@ -1994,44 +1929,27 @@ public function getPriority()
* @param array|\Cake\Mailer\AbstractTransport|null $config Either an array of configuration
* data, or a transport instance. Null when using key as array.
* @return void
* @throws \BadMethodCallException When modifying an existing configuration.
* @deprecated 3.7.0 Use TransportFactory::setConfig() instead.
*/
public static function setConfigTransport($key, $config = null)
{
if (is_array($key)) {
foreach ($key as $name => $settings) {
static::setConfigTransport($name, $settings);
}
deprecationWarning('Email::setConfigTransport() is deprecated. Use TransportFactory::setConfig() instead.');

return;
}

if (isset(static::$_transportConfig[$key])) {
throw new BadMethodCallException(sprintf('Cannot modify an existing config "%s"', $key));
}

if (is_object($config)) {
$config = ['className' => $config];
}

if (isset($config['url'])) {
$parsed = static::parseDsn($config['url']);
unset($config['url']);
$config = $parsed + $config;
}

static::$_transportConfig[$key] = $config;
TransportFactory::setConfig($key, $config);
}

/**
* Gets current transport configuration.
*
* @param string $key The configuration name to read.
* @return array|null Transport config.
* @deprecated 3.7.0 Use TransportFactory::getConfig() instead.
*/
public static function getConfigTransport($key)
{
return isset(static::$_transportConfig[$key]) ? static::$_transportConfig[$key] : null;
deprecationWarning('Email::getConfigTransport() is deprecated. Use TransportFactory::getConfig() instead.');

return TransportFactory::getConfig($key);
}

/**
Expand All @@ -2048,7 +1966,7 @@ public static function getConfigTransport($key)
* The `className` is used to define the class to use for a transport.
* It can either be a short name, or a fully qualified classname
*
* @deprecated 3.4.0 Use setConfigTransport()/getConfigTransport() instead.
* @deprecated 3.4.0 Use TransportFactory::setConfig()/getConfig() instead.
* @param string|array $key The configuration name to read/write. Or
* an array of multiple transports to set.
* @param array|\Cake\Mailer\AbstractTransport|null $config Either an array of configuration
Expand All @@ -2058,39 +1976,45 @@ public static function getConfigTransport($key)
*/
public static function configTransport($key, $config = null)
{
deprecationWarning('Email::configTransport() is deprecated. Use Email::setConfigTransport() or Email::getConfigTransport() instead.');
deprecationWarning('Email::configTransport() is deprecated. Use TransportFactory::setConfig() or TransportFactory::getConfig() instead.');

if ($config === null && is_string($key)) {
return static::getConfigTransport($key);
return TransportFactory::getConfig($key);
}
if ($config === null && is_array($key)) {
static::setConfigTransport($key);
TransportFactory::setConfig($key);

return null;
}

static::setConfigTransport($key, $config);
TransportFactory::setConfig($key, $config);
}

/**
* Returns an array containing the named transport configurations
*
* @return array Array of configurations.
* @deprecated 3.7.0 Use TransportFactory::configured() instead.
*/
public static function configuredTransport()
{
return array_keys(static::$_transportConfig);
deprecationWarning('Email::configuredTransport() is deprecated. Use TransportFactory::configured().');

return TransportFactory::configured();
}

/**
* Delete transport configuration.
*
* @param string $key The transport name to remove.
* @return void
* @deprecated 3.7.0 Use TransportFactory::drop() instead.
*/
public static function dropTransport($key)
{
unset(static::$_transportConfig[$key]);
deprecationWarning('Email::dropTransport() is deprecated. Use TransportFactory::drop().');

TransportFactory::drop($key);
}

/**
Expand Down
114 changes: 114 additions & 0 deletions src/Mailer/TransportFactory.php
@@ -0,0 +1,114 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @since 3.7.0
* @license https://opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Mailer;

use Cake\Core\StaticConfigTrait;
use InvalidArgumentException;

/**
* Factory class for generating email transport instances.
*/
class TransportFactory
{
use StaticConfigTrait;

/**
* Transport Registry used for creating and using transport instances.
*
* @var \Cake\Mailer\TransportRegistry
*/
protected static $_registry;

/**
* An array mapping url schemes to fully qualified Transport class names
*
* @var array
*/
protected static $_dsnClassMap = [
'debug' => 'Cake\Mailer\Transport\DebugTransport',
'mail' => 'Cake\Mailer\Transport\MailTransport',
'smtp' => 'Cake\Mailer\Transport\SmtpTransport',
];

/**
* Returns the Transport Registry used for creating and using transport instances.
*
* @return \Cake\Mailer\TransportRegistry
*/
public static function getRegistry()
{
if (!static::$_registry) {
static::$_registry = new TransportRegistry();
}

return static::$_registry;
}

/**
* Sets the Transport Registry instance used for creating and using transport instances.
*
* Also allows for injecting of a new registry instance.
*
* @param \Cake\Mailer\TransportRegistry $registry Injectable registry object.
* @return void
*/
public static function setRegistry(TransportRegistry $registry)
{
static::$_registry = $registry;
}

/**
* Finds and builds the instance of the required tranport class.
*
* @param string $name Name of the config array that needs a tranport instance built
* @return void
* @throws \InvalidArgumentException When a tranport cannot be created.
*/
protected static function _buildTransport($name)
{
if (!isset(static::$_config[$name])) {
throw new InvalidArgumentException(
sprintf('The "%s" transport configuration does not exist', $name)
);
}

if (is_array(static::$_config[$name]) && empty(static::$_config[$name]['className'])) {
throw new InvalidArgumentException(
sprintf('Transport config "%s" is invalid, the required `className` option is missing', $name)
);
}

static::getRegistry()->load($name, static::$_config[$name]);
}

/**
* Get transport instance.
*
* @param string $name Config name.
* @return \Cake\Mailer\AbstractTransport
*/
public static function get($name)
{
$registry = static::getRegistry();

if (isset($registry->{$name})) {
return $registry->{$name};
}

static::_buildTransport($name);

return $registry->{$name};
}
}

0 comments on commit 891e6ae

Please sign in to comment.