diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 0595abb735..94addec59c 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -372,6 +372,7 @@ return array( 'OCP\\Log\\ILogFactory' => $baseDir . '/lib/public/Log/ILogFactory.php', 'OCP\\Log\\IWriter' => $baseDir . '/lib/public/Log/IWriter.php', 'OCP\\Log\\RotationTrait' => $baseDir . '/lib/public/Log/RotationTrait.php', + 'OCP\\Mail\\Events\\BeforeMessageSent' => $baseDir . '/lib/public/Mail/Events/BeforeMessageSent.php', 'OCP\\Mail\\IAttachment' => $baseDir . '/lib/public/Mail/IAttachment.php', 'OCP\\Mail\\IEMailTemplate' => $baseDir . '/lib/public/Mail/IEMailTemplate.php', 'OCP\\Mail\\IMailer' => $baseDir . '/lib/public/Mail/IMailer.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index d9739745d8..d8f68ccd5e 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -401,6 +401,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OCP\\Log\\ILogFactory' => __DIR__ . '/../../..' . '/lib/public/Log/ILogFactory.php', 'OCP\\Log\\IWriter' => __DIR__ . '/../../..' . '/lib/public/Log/IWriter.php', 'OCP\\Log\\RotationTrait' => __DIR__ . '/../../..' . '/lib/public/Log/RotationTrait.php', + 'OCP\\Mail\\Events\\BeforeMessageSent' => __DIR__ . '/../../..' . '/lib/public/Mail/Events/BeforeMessageSent.php', 'OCP\\Mail\\IAttachment' => __DIR__ . '/../../..' . '/lib/public/Mail/IAttachment.php', 'OCP\\Mail\\IEMailTemplate' => __DIR__ . '/../../..' . '/lib/public/Mail/IEMailTemplate.php', 'OCP\\Mail\\IMailer' => __DIR__ . '/../../..' . '/lib/public/Mail/IMailer.php', diff --git a/lib/private/Mail/Mailer.php b/lib/private/Mail/Mailer.php index df5f2687da..47a7f8a7c9 100644 --- a/lib/private/Mail/Mailer.php +++ b/lib/private/Mail/Mailer.php @@ -12,6 +12,7 @@ declare(strict_types=1); * @author Lukas Reschke * @author Morris Jobke * @author Roeland Jago Douma + * @author Arne Hamann * * @license AGPL-3.0 * @@ -34,6 +35,7 @@ namespace OC\Mail; use Egulias\EmailValidator\EmailValidator; use Egulias\EmailValidator\Validation\RFCValidation; use OCP\Defaults; +use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; use OCP\IL10N; use OCP\ILogger; @@ -42,6 +44,8 @@ use OCP\Mail\IAttachment; use OCP\Mail\IEMailTemplate; use OCP\Mail\IMailer; use OCP\Mail\IMessage; +use OCP\Mail\Events\BeforeMessageSent; + /** * Class Mailer provides some basic functions to create a mail message that can be used in combination with @@ -74,6 +78,8 @@ class Mailer implements IMailer { private $urlGenerator; /** @var IL10N */ private $l10n; + /** @var IEventDispatcher */ + private $dispatcher; /** * @param IConfig $config @@ -81,17 +87,20 @@ class Mailer implements IMailer { * @param Defaults $defaults * @param IURLGenerator $urlGenerator * @param IL10N $l10n + * @param IEventDispatcher $dispatcher */ public function __construct(IConfig $config, ILogger $logger, Defaults $defaults, IURLGenerator $urlGenerator, - IL10N $l10n) { + IL10N $l10n, + IEventDispatcher $dispatcher) { $this->config = $config; $this->logger = $logger; $this->defaults = $defaults; $this->urlGenerator = $urlGenerator; $this->l10n = $l10n; + $this->dispatcher = $dispatcher; } /** @@ -182,6 +191,9 @@ class Mailer implements IMailer { $mailer->registerPlugin(new \Swift_Plugins_LoggerPlugin($mailLogger)); } + + $this->dispatcher->dispatchTyped(new BeforeMessageSent($message)); + $mailer->send($message->getSwiftMessage(), $failedRecipients); // Debugging logging diff --git a/lib/private/Mail/Message.php b/lib/private/Mail/Message.php index 4ea9da532b..9437bd0216 100644 --- a/lib/private/Mail/Message.php +++ b/lib/private/Mail/Message.php @@ -11,6 +11,7 @@ declare(strict_types=1); * @author Morris Jobke * @author Roeland Jago Douma * @author Thomas Müller + * @author Arne Hamann * * @license AGPL-3.0 * @@ -112,7 +113,7 @@ class Message implements IMessage { * @return array */ public function getFrom(): array { - return $this->swiftMessage->getFrom(); + return $this->swiftMessage->getFrom() ?? []; } /** @@ -156,7 +157,7 @@ class Message implements IMessage { * @return array */ public function getTo(): array { - return $this->swiftMessage->getTo(); + return $this->swiftMessage->getTo() ?? []; } /** @@ -178,7 +179,7 @@ class Message implements IMessage { * @return array */ public function getCc(): array { - return $this->swiftMessage->getCc(); + return $this->swiftMessage->getCc() ?? []; } /** @@ -200,7 +201,7 @@ class Message implements IMessage { * @return array */ public function getBcc(): array { - return $this->swiftMessage->getBcc(); + return $this->swiftMessage->getBcc() ?? []; } /** @@ -256,6 +257,14 @@ class Message implements IMessage { return $this; } + /** + * Get's the underlying SwiftMessage + * @param Swift_Message $swiftMessage + */ + public function setSwiftMessage(Swift_Message $swiftMessage): void { + $this->swiftMessage = $swiftMessage; + } + /** * Get's the underlying SwiftMessage * @return Swift_Message diff --git a/lib/private/Server.php b/lib/private/Server.php index 3300920edb..971b144e1d 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -988,7 +988,8 @@ class Server extends ServerContainer implements IServerContainer { $c->getLogger(), $c->query(Defaults::class), $c->getURLGenerator(), - $c->getL10N('lib') + $c->getL10N('lib'), + $c->query(IEventDispatcher::class) ); }); $this->registerDeprecatedAlias('Mailer', IMailer::class); diff --git a/lib/public/Mail/Events/BeforeMessageSent.php b/lib/public/Mail/Events/BeforeMessageSent.php new file mode 100644 index 0000000000..e14a35750f --- /dev/null +++ b/lib/public/Mail/Events/BeforeMessageSent.php @@ -0,0 +1,57 @@ + + * + * @author Arne Hamann + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCP\Mail\Events; + +use OCP\EventDispatcher\Event; +use OCP\Mail\IMessage; + +/** + * @since 19.0.0 + */ +class BeforeMessageSent extends Event { + + /** @var IMessage */ + private $message; + + /** + * @param IMessage $message + * @since 19.0.0 + */ + public function __construct(IMessage $message) { + parent::__construct(); + $this->message = $message; + } + + /** + * @return IMessage + * @since 19.0.0 + */ + public function getMessage(): IMessage { + return $this->message; + } + +} diff --git a/tests/lib/Mail/MailerTest.php b/tests/lib/Mail/MailerTest.php index 3a08cd9acf..1d19929fe0 100644 --- a/tests/lib/Mail/MailerTest.php +++ b/tests/lib/Mail/MailerTest.php @@ -1,6 +1,9 @@ + * + * @author Arne Hamann + * * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. @@ -8,14 +11,20 @@ namespace Test\Mail; + use OC\Mail\EMailTemplate; use OC\Mail\Mailer; +use OC\Mail\Message; use OCP\Defaults; +use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; use OCP\IL10N; use OCP\ILogger; use OCP\IURLGenerator; +use OCP\Mail\Events\BeforeMessageSent; +use OCP\Mail\IMessage; use Test\TestCase; +use Swift_SwiftException; class MailerTest extends TestCase { /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ @@ -30,6 +39,9 @@ class MailerTest extends TestCase { private $l10n; /** @var Mailer */ private $mailer; + /** @var IEventDispatcher */ + private $dispatcher; + protected function setUp(): void { parent::setUp(); @@ -39,12 +51,14 @@ class MailerTest extends TestCase { $this->logger = $this->createMock(ILogger::class); $this->urlGenerator = $this->createMock(IURLGenerator::class); $this->l10n = $this->createMock(IL10N::class); + $this->dispatcher = $this->createMock(IEventDispatcher::class); $this->mailer = new Mailer( $this->config, $this->logger, $this->defaults, $this->urlGenerator, - $this->l10n + $this->l10n, + $this->dispatcher ); } @@ -117,6 +131,21 @@ class MailerTest extends TestCase { $this->assertInstanceOf(\Swift_SendmailTransport::class, $mailer->getTransport()); } + public function testEvents() { + $message = $this->createMock(Message::class); + + $event = new BeforeMessageSent($message); + $this->dispatcher->expects($this->at(0)) + ->method('dispatchTyped') + ->with($this->equalTo($event)); + + # We do not care at this point about errors in Swiftmailer + try { + $this->mailer->send($message); + } catch (Swift_SwiftException $e) { + } + } + public function testCreateMessage() { $this->config ->expects($this->any()) diff --git a/tests/lib/Mail/MessageTest.php b/tests/lib/Mail/MessageTest.php index e0a0f468a5..ab62cfcfdc 100644 --- a/tests/lib/Mail/MessageTest.php +++ b/tests/lib/Mail/MessageTest.php @@ -27,7 +27,17 @@ class MessageTest extends TestCase { array(array('lukas@owncloud.com' => 'Lukas Reschke'), array('lukas@owncloud.com' => 'Lukas Reschke')), array(array('lukas@owncloud.com' => 'Lukas Reschke', 'lukas@öwnclöüd.com', 'lukäs@owncloud.örg' => 'Lükäs Réschke'), array('lukas@owncloud.com' => 'Lukas Reschke', 'lukas@xn--wncld-iuae2c.com', 'lukäs@owncloud.xn--rg-eka' => 'Lükäs Réschke')), - array(array('lukas@öwnclöüd.com'), array('lukas@xn--wncld-iuae2c.com')) + array(array('lukas@öwnclöüd.com'), array('lukas@xn--wncld-iuae2c.com')), + ); + } + + /** + * @return array + */ + public function getMailAddressProvider() { + return array( + array(NULL, array()), + array(array('lukas@owncloud.com' => 'Lukas Reschke'), array('lukas@owncloud.com' => 'Lukas Reschke')), ); } @@ -59,13 +69,20 @@ class MessageTest extends TestCase { $this->message->setFrom(array('lukas@owncloud.com')); } - public function testGetFrom() { + + /** + * @dataProvider getMailAddressProvider + * + * @param $swiftresult + * @param $return + */ + public function testGetFrom($swiftresult, $return) { $this->swiftMessage ->expects($this->once()) ->method('getFrom') - ->will($this->returnValue(array('lukas@owncloud.com'))); + ->will($this->returnValue($swiftresult)); - $this->assertSame(array('lukas@owncloud.com'), $this->message->getFrom()); + $this->assertSame($return, $this->message->getFrom()); } public function testSetReplyTo() { @@ -93,13 +110,16 @@ class MessageTest extends TestCase { $this->message->setTo(array('lukas@owncloud.com')); } - public function testGetTo() { + /** + * @dataProvider getMailAddressProvider + */ + public function testGetTo($swiftresult,$return) { $this->swiftMessage ->expects($this->once()) ->method('getTo') - ->will($this->returnValue(array('lukas@owncloud.com'))); + ->will($this->returnValue($swiftresult)); - $this->assertSame(array('lukas@owncloud.com'), $this->message->getTo()); + $this->assertSame($return, $this->message->getTo()); } public function testSetCc() { @@ -110,13 +130,16 @@ class MessageTest extends TestCase { $this->message->setCc(array('lukas@owncloud.com')); } - public function testGetCc() { + /** + * @dataProvider getMailAddressProvider + */ + public function testGetCc($swiftresult,$return) { $this->swiftMessage ->expects($this->once()) ->method('getCc') - ->will($this->returnValue(array('lukas@owncloud.com'))); + ->will($this->returnValue($swiftresult)); - $this->assertSame(array('lukas@owncloud.com'), $this->message->getCc()); + $this->assertSame($return, $this->message->getCc()); } public function testSetBcc() { @@ -127,13 +150,16 @@ class MessageTest extends TestCase { $this->message->setBcc(array('lukas@owncloud.com')); } - public function testGetBcc() { + /** + * @dataProvider getMailAddressProvider + */ + public function testGetBcc($swiftresult,$return) { $this->swiftMessage ->expects($this->once()) ->method('getBcc') - ->will($this->returnValue(array('lukas@owncloud.com'))); + ->will($this->returnValue($swiftresult)); - $this->assertSame(array('lukas@owncloud.com'), $this->message->getBcc()); + $this->assertSame($return, $this->message->getBcc()); } public function testSetSubject() {