diff --git a/DependencyInjection/SwiftmailerExtension.php b/DependencyInjection/SwiftmailerExtension.php index c39e7203..f9595b20 100644 --- a/DependencyInjection/SwiftmailerExtension.php +++ b/DependencyInjection/SwiftmailerExtension.php @@ -14,6 +14,7 @@ use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\DefinitionDecorator; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; @@ -66,68 +67,60 @@ public function load(array $configs, ContainerBuilder $container) protected function configureMailer($name, array $mailer, ContainerBuilder $container, $isDefaultMailer = false) { - if (null === $mailer['transport']) { - $transport = 'null'; - } elseif ('gmail' === $mailer['transport']) { - $mailer['encryption'] = 'ssl'; - $mailer['auth_mode'] = 'login'; - $mailer['host'] = 'smtp.gmail.com'; - $transport = 'smtp'; - } else { - $transport = $mailer['transport']; - } - - if (null !== $mailer['url']) { - $parts = parse_url($mailer['url']); - if (!empty($parts['scheme'])) { - $transport = $parts['scheme']; - } + $definitionDecorator = $this->createChildDefinition('swiftmailer.transport.eventdispatcher.abstract'); + $container + ->setDefinition(sprintf('swiftmailer.mailer.%s.transport.eventdispatcher', $name), $definitionDecorator) + ; - if (!empty($parts['user'])) { - $mailer['username'] = $parts['user']; - } - if (!empty($parts['pass'])) { - $mailer['password'] = $parts['pass']; - } - if (!empty($parts['host'])) { - $mailer['host'] = $parts['host']; - } - if (!empty($parts['port'])) { - $mailer['port'] = $parts['port']; - } - if (!empty($parts['query'])) { - $query = array(); - parse_str($parts['query'], $query); - if (!empty($query['encryption'])) { - $mailer['encryption'] = $query['encryption']; - } - if (!empty($query['auth_mode'])) { - $mailer['auth_mode'] = $query['auth_mode']; - } + if (method_exists($container, 'resolveEnvPlaceholders')) { + $options = array(); + $envVariablesAllowed = array('transport', 'url', 'username', 'password', 'host', 'port', 'timeout', 'source_ip', 'local_domain', 'encryption', 'auth_mode'); + foreach ($envVariablesAllowed as $key) { + $container->resolveEnvPlaceholders($mailer[$key], null, $usedEnvs); + $options[$key] = $mailer[$key]; } + } else { + $usedEnvs = false; } - unset($mailer['url']); - - $container->setParameter(sprintf('swiftmailer.mailer.%s.transport.name', $name), $transport); + if ($usedEnvs) { + $transportId = sprintf('swiftmailer.mailer.%s.transport.dynamic', $name); + $definitionDecorator = new Definition('\Swift_Transport'); + $definitionDecorator->setFactory(array('Symfony\Bundle\SwiftmailerBundle\DependencyInjection\SwiftmailerTransportFactory', 'createTransport')); + $definitionDecorator->setArguments(array( + $options, + new Reference('router.request_context'), + new Reference(sprintf('swiftmailer.mailer.%s.transport.eventdispatcher', $name)), + )); + $container->setDefinition(sprintf('swiftmailer.mailer.%s.transport.dynamic', $name), $definitionDecorator); + $container->setAlias(sprintf('swiftmailer.mailer.%s.transport', $name), $transportId); + + $definitionDecorator = $this->createChildDefinition('swiftmailer.mailer.abstract'); + $container + ->setDefinition(sprintf('swiftmailer.mailer.%s', $name), $definitionDecorator) + ->replaceArgument(0, new Reference(sprintf('swiftmailer.mailer.%s.transport', $name))) + ; - if (isset($mailer['disable_delivery']) && $mailer['disable_delivery']) { - $transport = 'null'; - $container->setParameter(sprintf('swiftmailer.mailer.%s.delivery.enabled', $name), false); + $container->setParameter(sprintf('swiftmailer.mailer.%s.transport.name', $name), 'dynamic'); } else { - $container->setParameter(sprintf('swiftmailer.mailer.%s.delivery.enabled', $name), true); - } + $mailer = SwiftmailerTransportFactory::resolveOptions($mailer); + $transport = $mailer['transport']; - if (empty($mailer['port'])) { - $mailer['port'] = 'ssl' === $mailer['encryption'] ? 465 : 25; - } + $container->setParameter(sprintf('swiftmailer.mailer.%s.transport.name', $name), $transport); - $this->configureMailerTransport($name, $mailer, $container, $transport, $isDefaultMailer); - $this->configureMailerSpool($name, $mailer, $container, $transport, $isDefaultMailer); + $transportId = in_array($transport, array('smtp', 'sendmail', 'null')) + ? sprintf('swiftmailer.mailer.%s.transport.%s', $name, $transport) + : $transport; + + $this->configureMailerTransport($name, $mailer, $container, $transport, $isDefaultMailer); + } + $this->configureMailerSpool($name, $mailer, $container, $transportId, $isDefaultMailer); $this->configureMailerSenderAddress($name, $mailer, $container, $isDefaultMailer); $this->configureMailerAntiFlood($name, $mailer, $container, $isDefaultMailer); $this->configureMailerDeliveryAddress($name, $mailer, $container, $isDefaultMailer); $this->configureMailerLogging($name, $mailer, $container, $isDefaultMailer); + $container->setParameter(sprintf('swiftmailer.mailer.%s.delivery.enabled', $name), empty($mailer['disable_delivery'])); + // alias if ($isDefaultMailer) { $container->setAlias('swiftmailer.mailer', sprintf('swiftmailer.mailer.%s', $name)); @@ -144,11 +137,6 @@ protected function configureMailerTransport($name, array $mailer, ContainerBuild $container->setParameter(sprintf('swiftmailer.mailer.%s.transport.smtp.%s', $name, $key), $mailer[$key]); } - $definitionDecorator = $this->createChildDefinition('swiftmailer.transport.eventdispatcher.abstract'); - $container - ->setDefinition(sprintf('swiftmailer.mailer.%s.transport.eventdispatcher', $name), $definitionDecorator) - ; - if ('smtp' === $transport) { $authDecorator = $this->createChildDefinition('swiftmailer.transport.authhandler.abstract'); $container @@ -278,10 +266,6 @@ protected function configureMailerSpool($name, array $mailer, ContainerBuilder $ )) ; - if (in_array($transport, array('smtp', 'mail', 'sendmail', 'null'))) { - // built-in transport - $transport = sprintf('swiftmailer.mailer.%s.transport.%s', $name, $transport); - } $container->setAlias(sprintf('swiftmailer.mailer.%s.transport.real', $name), $transport); $container->setAlias(sprintf('swiftmailer.mailer.%s.transport', $name), sprintf('swiftmailer.mailer.%s.transport.spool', $name)); $container->setParameter(sprintf('swiftmailer.mailer.%s.spool.enabled', $name), true); diff --git a/DependencyInjection/SwiftmailerTransportFactory.php b/DependencyInjection/SwiftmailerTransportFactory.php new file mode 100644 index 00000000..c277ca25 --- /dev/null +++ b/DependencyInjection/SwiftmailerTransportFactory.php @@ -0,0 +1,138 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\SwiftmailerBundle\DependencyInjection; + +use Symfony\Component\Routing\RequestContext; + +/** + * Factory to create a \Swift_Transport object. + * + * @author Romain Gautier + */ +class SwiftmailerTransportFactory +{ + /** + * @param array $options + * @param RequestContext $requestContext + * @param \Swift_Events_EventDispatcher $eventDispatcher + * + * @return \Swift_Transport + * + * @throws \InvalidArgumentException if the scheme is not a built-in Swiftmailer transport + */ + public static function createTransport(array $options, RequestContext $requestContext, \Swift_Events_EventDispatcher $eventDispatcher) + { + $options = static::resolveOptions($options); + + if ('smtp' === $options['transport']) { + $smtpAuthHandler = new \Swift_Transport_Esmtp_AuthHandler(array( + new \Swift_Transport_Esmtp_Auth_CramMd5Authenticator(), + new \Swift_Transport_Esmtp_Auth_LoginAuthenticator(), + new \Swift_Transport_Esmtp_Auth_PlainAuthenticator(), + )); + $smtpAuthHandler->setUsername($options['username']); + $smtpAuthHandler->setPassword($options['password']); + $smtpAuthHandler->setAuthMode($options['auth_mode']); + + $transport = new \Swift_Transport_EsmtpTransport( + new \Swift_Transport_StreamBuffer(new \Swift_StreamFilters_StringReplacementFilterFactory()), + array($smtpAuthHandler), + $eventDispatcher + ); + $transport->setHost($options['host']); + $transport->setPort($options['port']); + $transport->setEncryption($options['encryption']); + $transport->setTimeout($options['timeout']); + $transport->setSourceIp($options['source_ip']); + + $smtpTransportConfigurator = new SmtpTransportConfigurator(null, $requestContext); + $smtpTransportConfigurator->configure($transport); + } elseif ('sendmail' === $options['transport']) { + $transport = new \Swift_Transport_SendmailTransport( + new \Swift_Transport_StreamBuffer(new \Swift_StreamFilters_StringReplacementFilterFactory()), + $eventDispatcher + ); + + $smtpTransportConfigurator = new SmtpTransportConfigurator(null, $requestContext); + $smtpTransportConfigurator->configure($transport); + } elseif ('null' === $options['transport']) { + $transport = new \Swift_Transport_NullTransport($eventDispatcher); + } else { + throw new \InvalidArgumentException(sprintf('Not a built-in Swiftmailer transport: %s.', $options['transport'])); + } + + return $transport; + } + + /** + * @param array $options + * + * @return array options + */ + public static function resolveOptions(array $options) + { + $options += array( + 'transport' => null, + 'username' => null, + 'password' => null, + 'host' => null, + 'port' => null, + 'timeout' => null, + 'source_ip' => null, + 'local_domain' => null, + 'encryption' => null, + 'auth_mode' => null, + ); + + if (isset($options['url'])) { + $parts = parse_url($options['url']); + if (isset($parts['scheme'])) { + $options['transport'] = $parts['scheme']; + } + if (isset($parts['user'])) { + $options['username'] = $parts['user']; + } + if (isset($parts['pass'])) { + $options['password'] = $parts['pass']; + } + if (isset($parts['host'])) { + $options['host'] = $parts['host']; + } + if (isset($parts['port'])) { + $options['port'] = $parts['port']; + } + if (isset($parts['query'])) { + parse_str($parts['query'], $query); + foreach ($options as $key => $value) { + if (isset($query[$key])) { + $options[$key] = $query[$key]; + } + } + } + } + + if (!isset($options['transport'])) { + $options['transport'] = 'null'; + } elseif ('gmail' === $options['transport']) { + $options['encryption'] = 'ssl'; + $options['auth_mode'] = 'login'; + $options['host'] = 'smtp.gmail.com'; + $options['transport'] = 'smtp'; + } + + if (!isset($options['port'])) { + $options['port'] = 'ssl' === $options['encryption'] ? 465 : 25; + } + + return $options; + } +} diff --git a/Tests/DependencyInjection/Fixtures/config/php/urls.php b/Tests/DependencyInjection/Fixtures/config/php/urls.php index 930c49b7..8665f3d7 100644 --- a/Tests/DependencyInjection/Fixtures/config/php/urls.php +++ b/Tests/DependencyInjection/Fixtures/config/php/urls.php @@ -4,7 +4,7 @@ 'default_mailer' => 'smtp_mailer', 'mailers' => array( 'smtp_mailer' => array( - 'url' => 'smtp://username:password@example.com:12345?encryption=tls&auth_mode=login', + 'url' => 'smtp://username:password@example.com:12345?transport=smtp&username=user&password=pass&host=example.org&port=23456&timeout=42&source_ip=127.0.0.1&local_domain=local.example.com&encryption=tls&auth_mode=login', ), ), )); diff --git a/Tests/DependencyInjection/Fixtures/config/xml/urls.xml b/Tests/DependencyInjection/Fixtures/config/xml/urls.xml index ce0c429c..65a66fbb 100644 --- a/Tests/DependencyInjection/Fixtures/config/xml/urls.xml +++ b/Tests/DependencyInjection/Fixtures/config/xml/urls.xml @@ -7,7 +7,7 @@ + url="smtp://username:password@example.com:12345?transport=smtp&username=user&password=pass&host=example.org&port=23456&timeout=42&source_ip=127.0.0.1&local_domain=local.example.com&encryption=tls&auth_mode=login"> diff --git a/Tests/DependencyInjection/Fixtures/config/yml/env_variable.yml b/Tests/DependencyInjection/Fixtures/config/yml/env_variable.yml new file mode 100644 index 00000000..4154e986 --- /dev/null +++ b/Tests/DependencyInjection/Fixtures/config/yml/env_variable.yml @@ -0,0 +1,2 @@ +swiftmailer: + url: '%env(SWIFTMAILER_URL)%' diff --git a/Tests/DependencyInjection/Fixtures/config/yml/urls.yml b/Tests/DependencyInjection/Fixtures/config/yml/urls.yml index 6eb1af6c..d472b4df 100644 --- a/Tests/DependencyInjection/Fixtures/config/yml/urls.yml +++ b/Tests/DependencyInjection/Fixtures/config/yml/urls.yml @@ -2,4 +2,4 @@ swiftmailer: default_mailer: smtp_mailer mailers: smtp_mailer: - url: smtp://username:password@example.com:12345?encryption=tls&auth_mode=login + url: smtp://username:password@example.com:12345?transport=smtp&username=user&password=pass&host=example.org&port=23456&timeout=42&source_ip=127.0.0.1&local_domain=local.example.com&encryption=tls&auth_mode=login diff --git a/Tests/DependencyInjection/SwiftmailerExtensionTest.php b/Tests/DependencyInjection/SwiftmailerExtensionTest.php index 66cc9662..beae9bbd 100644 --- a/Tests/DependencyInjection/SwiftmailerExtensionTest.php +++ b/Tests/DependencyInjection/SwiftmailerExtensionTest.php @@ -12,15 +12,47 @@ namespace Symfony\Bundle\SwiftmailerBundle\Tests\DependencyInjection; use Symfony\Bundle\SwiftmailerBundle\DependencyInjection\SwiftmailerExtension; +use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\Compiler\ResolveDefinitionTemplatesPass; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; -use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; -use Symfony\Component\Config\FileLocator; +use Symfony\Component\Routing\RequestContext; class SwiftmailerExtensionTest extends \PHPUnit_Framework_TestCase { + public function testLoadWithEnvVariables() + { + $container = new ContainerBuilder(); + if (!method_exists($container, 'resolveEnvPlaceholders')) { + $this->markTestSkipped('Runtime environment variables has been introduced in the Dependency Injection version 3.2.'); + } + + $container->setParameter('kernel.debug', false); + $container->setParameter('kernel.cache_dir', '/tmp'); + + $container->set('swiftmailer.mailer.default.transport.eventdispatcher', new \Swift_Events_SimpleEventDispatcher()); + $container->set('router.request_context', new RequestContext()); + + $container->registerExtension(new SwiftmailerExtension()); + $locator = new FileLocator(__DIR__.'/Fixtures/config/yml'); + $loader = new YamlFileLoader($container, $locator); + $loader->load('env_variable.yml'); + + $container->getCompilerPassConfig()->setOptimizationPasses(array( + new ResolveDefinitionTemplatesPass(), + )); + $container->getCompilerPassConfig()->setRemovingPasses(array()); + $container->compile(); + + $this->assertEquals( + array('Symfony\Bundle\SwiftmailerBundle\DependencyInjection\SwiftmailerTransportFactory', 'createTransport'), + $container->findDefinition('swiftmailer.transport')->getFactory() + ); + $this->assertSame('dynamic', $container->getParameter('swiftmailer.mailer.default.transport.name')); + } + public function getConfigTypes() { return array( @@ -175,11 +207,11 @@ public function testUrls($type) { $container = $this->loadContainerFromFile('urls', $type); - $this->assertEquals('example.com', $container->getParameter('swiftmailer.mailer.smtp_mailer.transport.smtp.host')); - $this->assertEquals('12345', $container->getParameter('swiftmailer.mailer.smtp_mailer.transport.smtp.port')); + $this->assertEquals('example.org', $container->getParameter('swiftmailer.mailer.smtp_mailer.transport.smtp.host')); + $this->assertEquals('23456', $container->getParameter('swiftmailer.mailer.smtp_mailer.transport.smtp.port')); $this->assertEquals('tls', $container->getParameter('swiftmailer.mailer.smtp_mailer.transport.smtp.encryption')); - $this->assertEquals('username', $container->getParameter('swiftmailer.mailer.smtp_mailer.transport.smtp.username')); - $this->assertEquals('password', $container->getParameter('swiftmailer.mailer.smtp_mailer.transport.smtp.password')); + $this->assertEquals('user', $container->getParameter('swiftmailer.mailer.smtp_mailer.transport.smtp.username')); + $this->assertEquals('pass', $container->getParameter('swiftmailer.mailer.smtp_mailer.transport.smtp.password')); $this->assertEquals('login', $container->getParameter('swiftmailer.mailer.smtp_mailer.transport.smtp.auth_mode')); } @@ -389,7 +421,7 @@ private function loadContainerFromFile($file, $type, array $services = array()) $loader->load($file.'.'.$type); $container->getCompilerPassConfig()->setOptimizationPasses(array( - new ResolveDefinitionTemplatesPass() + new ResolveDefinitionTemplatesPass(), )); $container->getCompilerPassConfig()->setRemovingPasses(array()); $container->compile(); diff --git a/Tests/DependencyInjection/SwiftmailerTransportFactoryTest.php b/Tests/DependencyInjection/SwiftmailerTransportFactoryTest.php new file mode 100644 index 00000000..f638320c --- /dev/null +++ b/Tests/DependencyInjection/SwiftmailerTransportFactoryTest.php @@ -0,0 +1,266 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\SwiftmailerBundle\Tests\DependencyInjection; + +use Symfony\Bundle\SwiftmailerBundle\DependencyInjection\SwiftmailerTransportFactory; +use Symfony\Component\Routing\RequestContext; + +class SwiftmailerTransportFactoryTest extends \PHPUnit_Framework_TestCase +{ + public function testCreateTransportWithSmtp() + { + $options = array( + 'transport' => 'smtp', + 'username' => 'user', + 'password' => 'pass', + 'host' => 'host', + 'port' => 1234, + 'timeout' => 42, + 'source_ip' => 'source_ip', + 'local_domain' => 'local_domain', + 'encryption' => 'encryption', + 'auth_mode' => 'auth_mode', + ); + + $transport = SwiftmailerTransportFactory::createTransport( + $options, + new RequestContext(), + new \Swift_Events_SimpleEventDispatcher() + ); + $this->assertInstanceOf('Swift_Transport_EsmtpTransport', $transport); + $this->assertSame($transport->getHost(), $options['host']); + $this->assertSame($transport->getPort(), $options['port']); + $this->assertSame($transport->getEncryption(), $options['encryption']); + $this->assertSame($transport->getTimeout(), $options['timeout']); + $this->assertSame($transport->getSourceIp(), $options['source_ip']); + + $authHandler = current($transport->getExtensionHandlers()); + $this->assertSame($authHandler->getUsername(), $options['username']); + $this->assertSame($authHandler->getPassword(), $options['password']); + $this->assertSame($authHandler->getAuthMode(), $options['auth_mode']); + } + + public function testCreateTransportWithSendmail() + { + $options = array( + 'transport' => 'sendmail', + ); + + $transport = SwiftmailerTransportFactory::createTransport( + $options, + new RequestContext(), + new \Swift_Events_SimpleEventDispatcher() + ); + $this->assertInstanceOf('Swift_Transport_SendmailTransport', $transport); + } + + public function testCreateTransportWithNull() + { + $options = array( + 'transport' => 'null', + ); + + $transport = SwiftmailerTransportFactory::createTransport( + $options, + new RequestContext(), + new \Swift_Events_SimpleEventDispatcher() + ); + $this->assertInstanceOf('Swift_Transport_NullTransport', $transport); + } + + /** + * @dataProvider optionsAndResultExpected + */ + public function testResolveOptions($options, $expected) + { + $result = SwiftmailerTransportFactory::resolveOptions($options); + $this->assertEquals($expected, $result); + } + + public function optionsAndResultExpected() + { + return array( + array( + array( + 'url' => '', + ), + array( + 'transport' => 'null', + 'username' => null, + 'password' => null, + 'host' => null, + 'port' => 25, + 'timeout' => null, + 'source_ip' => null, + 'local_domain' => null, + 'encryption' => null, + 'auth_mode' => null, + 'url' => '', + ), + ), + array( + array( + 'url' => 'smtp://user:pass@host:1234', + ), + array( + 'transport' => 'smtp', + 'username' => 'user', + 'password' => 'pass', + 'host' => 'host', + 'port' => 1234, + 'timeout' => null, + 'source_ip' => null, + 'local_domain' => null, + 'encryption' => null, + 'auth_mode' => null, + 'url' => 'smtp://user:pass@host:1234', + ), + ), + array( + array( + 'url' => 'smtp://user:pass@host:1234?transport=sendmail&username=username&password=password&host=example.com&port=5678', + ), + array( + 'transport' => 'sendmail', + 'username' => 'username', + 'password' => 'password', + 'host' => 'example.com', + 'port' => 5678, + 'timeout' => null, + 'source_ip' => null, + 'local_domain' => null, + 'encryption' => null, + 'auth_mode' => null, + 'url' => 'smtp://user:pass@host:1234?transport=sendmail&username=username&password=password&host=example.com&port=5678', + ), + ), + array( + array( + 'url' => 'smtp://user:pass@host:1234?timeout=42&source_ip=source_ip&local_domain=local_domain&encryption=encryption&auth_mode=auth_mode', + ), + array( + 'transport' => 'smtp', + 'username' => 'user', + 'password' => 'pass', + 'host' => 'host', + 'port' => 1234, + 'timeout' => 42, + 'source_ip' => 'source_ip', + 'local_domain' => 'local_domain', + 'encryption' => 'encryption', + 'auth_mode' => 'auth_mode', + 'url' => 'smtp://user:pass@host:1234?timeout=42&source_ip=source_ip&local_domain=local_domain&encryption=encryption&auth_mode=auth_mode', + ), + ), + array( + array(), + array( + 'transport' => 'null', + 'username' => null, + 'password' => null, + 'host' => null, + 'port' => 25, + 'timeout' => null, + 'source_ip' => null, + 'local_domain' => null, + 'encryption' => null, + 'auth_mode' => null, + ), + ), + array( + array( + 'transport' => 'smtp', + ), + array( + 'transport' => 'smtp', + 'username' => null, + 'password' => null, + 'host' => null, + 'port' => 25, + 'timeout' => null, + 'source_ip' => null, + 'local_domain' => null, + 'encryption' => null, + 'auth_mode' => null, + ), + ), + array( + array( + 'transport' => 'gmail', + ), + array( + 'transport' => 'smtp', + 'username' => null, + 'password' => null, + 'host' => 'smtp.gmail.com', + 'port' => 465, + 'timeout' => null, + 'source_ip' => null, + 'local_domain' => null, + 'encryption' => 'ssl', + 'auth_mode' => 'login', + ), + ), + array( + array( + 'transport' => 'sendmail', + ), + array( + 'transport' => 'sendmail', + 'username' => null, + 'password' => null, + 'host' => null, + 'port' => 25, + 'timeout' => null, + 'source_ip' => null, + 'local_domain' => null, + 'encryption' => null, + 'auth_mode' => null, + ), + ), + array( + array( + 'encryption' => 'ssl', + ), + array( + 'transport' => 'null', + 'username' => null, + 'password' => null, + 'host' => null, + 'port' => 465, + 'timeout' => null, + 'source_ip' => null, + 'local_domain' => null, + 'encryption' => 'ssl', + 'auth_mode' => null, + ), + ), + array( + array( + 'port' => 42, + ), + array( + 'transport' => 'null', + 'username' => null, + 'password' => null, + 'host' => null, + 'port' => 42, + 'timeout' => null, + 'source_ip' => null, + 'local_domain' => null, + 'encryption' => null, + 'auth_mode' => null, + ), + ), + ); + } +}