From f5eaeeb144e8cae3d3ce090673f250a79a8af5b3 Mon Sep 17 00:00:00 2001 From: John Kary Date: Sun, 1 Mar 2015 19:25:14 -0600 Subject: [PATCH 1/2] Swift_Message creation is now lazy when using callback Swift_Message object is not created until right before the message is sent, if it is sent at all. This prevents the expensive Swift_Mailer autoloader from being invoked. Swift_Mailer is now also required to run test suite --- composer.json | 3 +- src/Monolog/Handler/SwiftMailerHandler.php | 34 ++++++++++++----- .../Handler/SwiftMailerHandlerTest.php | 37 +++++++++++++++++++ 3 files changed, 64 insertions(+), 10 deletions(-) create mode 100644 tests/Monolog/Handler/SwiftMailerHandlerTest.php diff --git a/composer.json b/composer.json index 08aea699..526f6fe8 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,8 @@ "ruflin/elastica": "0.90.*", "doctrine/couchdb": "~1.0@dev", "aws/aws-sdk-php": "~2.4, >2.4.8", - "videlalvaro/php-amqplib": "~2.4" + "videlalvaro/php-amqplib": "~2.4", + "swiftmailer/swiftmailer": "~5.3" }, "suggest": { "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", diff --git a/src/Monolog/Handler/SwiftMailerHandler.php b/src/Monolog/Handler/SwiftMailerHandler.php index af321db2..382114fb 100644 --- a/src/Monolog/Handler/SwiftMailerHandler.php +++ b/src/Monolog/Handler/SwiftMailerHandler.php @@ -32,13 +32,8 @@ class SwiftMailerHandler extends MailHandler public function __construct(\Swift_Mailer $mailer, $message, $level = Logger::ERROR, $bubble = true) { parent::__construct($level, $bubble); - $this->mailer = $mailer; - if (!$message instanceof \Swift_Message && is_callable($message)) { - $message = call_user_func($message); - } - if (!$message instanceof \Swift_Message) { - throw new \InvalidArgumentException('You must provide either a Swift_Message instance or a callable returning it'); - } + + $this->mailer = $mailer; $this->message = $message; } @@ -47,10 +42,31 @@ class SwiftMailerHandler extends MailHandler */ protected function send($content, array $records) { - $message = clone $this->message; + $this->mailer->send($this->buildMessage($content)); + } + + /** + * Creates instance of Swift_Message to be sent + * + * @param string $content + * @return \Swift_Message + */ + protected function buildMessage($content) + { + $message = null; + if ($this->message instanceof \Swift_Message) { + $message = clone $this->message; + } else if (is_callable($this->message)) { + $message = call_user_func($this->message); + } + + if (!$message instanceof \Swift_Message) { + throw new \InvalidArgumentException('Could not resolve message as instance of Swift_Message or a callable returning it'); + } + $message->setBody($content); $message->setDate(time()); - $this->mailer->send($message); + return $message; } } diff --git a/tests/Monolog/Handler/SwiftMailerHandlerTest.php b/tests/Monolog/Handler/SwiftMailerHandlerTest.php new file mode 100644 index 00000000..268c742e --- /dev/null +++ b/tests/Monolog/Handler/SwiftMailerHandlerTest.php @@ -0,0 +1,37 @@ +mailer = $this + ->getMockBuilder('Swift_Mailer') + ->disableOriginalConstructor() + ->getMock(); + } + + public function testMessageCreationIsLazyWhenUsingCallback() + { + $this->mailer->expects($this->never()) + ->method('send'); + + $callback = function () { + throw new \RuntimeException('Swift_Message creation callback should not have been called in this test'); + }; + $handler = new SwiftMailerHandler($this->mailer, $callback); + + $records = [ + $this->getRecord(Logger::DEBUG), + $this->getRecord(Logger::INFO), + ]; + $handler->handleBatch($records); + } +} From fea588c0554b970a024a1da4ac1810da868bfc18 Mon Sep 17 00:00:00 2001 From: John Kary Date: Sun, 1 Mar 2015 19:32:18 -0600 Subject: [PATCH 2/2] Swift_Message can now be customized based on logged data --- src/Monolog/Handler/SwiftMailerHandler.php | 7 ++-- .../Handler/SwiftMailerHandlerTest.php | 32 +++++++++++++++++-- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/Monolog/Handler/SwiftMailerHandler.php b/src/Monolog/Handler/SwiftMailerHandler.php index 382114fb..9237b1fd 100644 --- a/src/Monolog/Handler/SwiftMailerHandler.php +++ b/src/Monolog/Handler/SwiftMailerHandler.php @@ -42,22 +42,23 @@ class SwiftMailerHandler extends MailHandler */ protected function send($content, array $records) { - $this->mailer->send($this->buildMessage($content)); + $this->mailer->send($this->buildMessage($content, $records)); } /** * Creates instance of Swift_Message to be sent * * @param string $content + * @param array $records Log records that formed the content * @return \Swift_Message */ - protected function buildMessage($content) + protected function buildMessage($content, array $records) { $message = null; if ($this->message instanceof \Swift_Message) { $message = clone $this->message; } else if (is_callable($this->message)) { - $message = call_user_func($this->message); + $message = call_user_func($this->message, $content, $records); } if (!$message instanceof \Swift_Message) { diff --git a/tests/Monolog/Handler/SwiftMailerHandlerTest.php b/tests/Monolog/Handler/SwiftMailerHandlerTest.php index 268c742e..ac885220 100644 --- a/tests/Monolog/Handler/SwiftMailerHandlerTest.php +++ b/tests/Monolog/Handler/SwiftMailerHandlerTest.php @@ -28,10 +28,38 @@ class SwiftMailerHandlerTest extends TestCase }; $handler = new SwiftMailerHandler($this->mailer, $callback); - $records = [ + $records = array( $this->getRecord(Logger::DEBUG), $this->getRecord(Logger::INFO), - ]; + ); + $handler->handleBatch($records); + } + + public function testMessageCanBeCustomizedGivenLoggedData() + { + // Wire Mailer to expect a specific Swift_Message with a customized Subject + $expectedMessage = new \Swift_Message(); + $this->mailer->expects($this->once()) + ->method('send') + ->with($this->callback(function ($value) use ($expectedMessage) { + return $value instanceof \Swift_Message + && $value->getSubject() === 'Emergency' + && $value === $expectedMessage; + })); + + // Callback dynamically changes subject based on number of logged records + $callback = function ($content, array $records) use ($expectedMessage) { + $subject = count($records) > 0 ? 'Emergency' : 'Normal'; + $expectedMessage->setSubject($subject); + + return $expectedMessage; + }; + $handler = new SwiftMailerHandler($this->mailer, $callback); + + // Logging 1 record makes this an Emergency + $records = array( + $this->getRecord(Logger::EMERGENCY), + ); $handler->handleBatch($records); } }