diff --git a/extensions/swiftmailer/Mailer.php b/extensions/swiftmailer/Mailer.php index fda0477..e43798a 100644 --- a/extensions/swiftmailer/Mailer.php +++ b/extensions/swiftmailer/Mailer.php @@ -37,6 +37,23 @@ use yii\mail\BaseMailer; * You may also skip the configuration of the [[transport]] property. In that case, the default * PHP `mail()` function will be used to send emails. * + * You specify the transport constructor arguments using 'constructArgs' key in the config. + * You can also specify the list of plugins, which should be registered to the transport using + * 'plugins' key. For example: + * + * ~~~ + * 'transport' => [ + * 'class' => 'Swift_SmtpTransport', + * 'constructArgs' => ['localhost', 25] + * 'plugins' => [ + * [ + * 'class' => 'Swift_Plugins_ThrottlerPlugin', + * 'constructArgs' => [20], + * ], + * ], + * ], + * ~~~ + * * To send an email, you may use the following code: * * ~~~ @@ -131,28 +148,69 @@ class Mailer extends BaseMailer */ protected function createTransport(array $config) { + if (!isset($config['class'])) { + $config['class'] = 'Swift_MailTransport'; + } + if (isset($config['plugins'])) { + $plugins = $config['plugins']; + unset($config['plugins']); + } + /** @var \Swift_MailTransport $transport */ + $transport = $this->createSwiftObject($config); + if (isset($plugins)) { + foreach ($plugins as $plugin) { + if (is_array($plugin) && isset($plugin['class'])) { + $plugin = $this->createSwiftObject($plugin); + } + $transport->registerPlugin($plugin); + } + } + return $transport; + } + + /** + * Creates Swift library object, from given array configuration. + * @param array $config object configuration + * @return Object created object + * @throws \yii\base\InvalidConfigException on invalid configuration. + */ + protected function createSwiftObject(array $config) + { if (isset($config['class'])) { $className = $config['class']; unset($config['class']); } else { - $className = 'Swift_MailTransport'; + throw new InvalidConfigException('Object configuration must be an array containing a "class" element.'); + } + if (isset($config['constructArgs'])) { + $args = []; + foreach ($config['constructArgs'] as $arg) { + if (is_array($arg) && isset($arg['class'])) { + $args[] = $this->createSwiftObject($arg); + } else { + $args[] = $arg; + } + } + unset($config['constructArgs']); + array_unshift($args, ['class' => $className]); + $object = call_user_func_array(['Yii', 'createObject'], $args); + } else { + $object = new $className; } - /** @var \Swift_MailTransport $transport */ - $transport = $className::newInstance(); if (!empty($config)) { foreach ($config as $name => $value) { - if (property_exists($transport, $name)) { - $transport->$name = $value; + if (property_exists($object, $name)) { + $object->$name = $value; } else { $setter = 'set' . $name; - if (method_exists($transport, $setter) || method_exists($transport, '__call')) { - $transport->$setter($value); + if (method_exists($object, $setter) || method_exists($object, '__call')) { + $object->$setter($value); } else { - throw new InvalidConfigException('Setting unknown property: ' . get_class($transport) . '::' . $name); + throw new InvalidConfigException('Setting unknown property: ' . $className . '::' . $name); } } } } - return $transport; + return $object; } } diff --git a/tests/unit/extensions/swiftmailer/MailerTest.php b/tests/unit/extensions/swiftmailer/MailerTest.php index 24602b2..8398efe 100644 --- a/tests/unit/extensions/swiftmailer/MailerTest.php +++ b/tests/unit/extensions/swiftmailer/MailerTest.php @@ -63,6 +63,56 @@ class MailerTest extends VendorTestCase $this->assertEquals($transportConfig['host'], $transport->getHost(), 'Invalid transport host!'); } + /** + * @depends testConfigureTransport + */ + public function testConfigureTransportConstruct() + { + $mailer = new Mailer(); + + $host = 'some.test.host'; + $port = 999; + $transportConfig = [ + 'class' => 'Swift_SmtpTransport', + 'constructArgs' => [ + $host, + $port, + ], + ]; + $mailer->setTransport($transportConfig); + $transport = $mailer->getTransport(); + $this->assertTrue(is_object($transport), 'Unable to setup transport via config!'); + $this->assertEquals($host, $transport->getHost(), 'Invalid transport host!'); + $this->assertEquals($port, $transport->getPort(), 'Invalid transport host!'); + } + + /** + * @depends testConfigureTransportConstruct + */ + public function testConfigureTransportWithPlugins() + { + $mailer = new Mailer(); + + $pluginClass = 'Swift_Plugins_ThrottlerPlugin'; + $rate = 10; + + $transportConfig = [ + 'class' => 'Swift_SmtpTransport', + 'plugins' => [ + [ + 'class' => $pluginClass, + 'constructArgs' => [ + $rate, + ], + ], + ], + ]; + $mailer->setTransport($transportConfig); + $transport = $mailer->getTransport(); + $this->assertTrue(is_object($transport), 'Unable to setup transport via config!'); + $this->assertContains(':' . $pluginClass . ':', print_r($transport, true), 'Plugin not added'); + } + public function testGetSwiftMailer() { $mailer = new Mailer();