From 1279194192d507aff04aa7910b76890b08692389 Mon Sep 17 00:00:00 2001 From: Gyula Sallai Date: Fri, 22 Apr 2011 17:41:10 +0200 Subject: [PATCH 1/6] Added an abstract MailHandler class --- src/Monolog/Handler/MailHandler.php | 139 ++++++++++++++++++++++ tests/Monolog/Handler/MailHandlerTest.php | 42 +++++++ tests/Monolog/TestCase.php | 14 +++ 3 files changed, 195 insertions(+) create mode 100644 src/Monolog/Handler/MailHandler.php create mode 100644 tests/Monolog/Handler/MailHandlerTest.php diff --git a/src/Monolog/Handler/MailHandler.php b/src/Monolog/Handler/MailHandler.php new file mode 100644 index 00000000..a6b4ac5e --- /dev/null +++ b/src/Monolog/Handler/MailHandler.php @@ -0,0 +1,139 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +/** + * Base class for all mail handlers + * + * @author Gyula Sallai + */ +abstract class MailHandler extends AbstractHandler +{ + + protected $messageFormat; + + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if ($record['level'] < $this->level) { + return false; + } + + $record = $this->prepareRecord($record); + + $this->write($record); + + return false === $this->bubble; + } + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + $messages = array(); + + foreach ($records as $record) { + if ($record['level'] < $this->level) { + continue; + } + + $record = $this->prepareRecord($record); + $messages[] = $record['message']; + } + + $this->send($this->createMessage($messages)); + } + + /** + * Set the message format + * + * @param string $format + */ + public function setMessageFormat($format) + { + $this->messageFormat = $format; + } + + /** + * Get the message format + * + * @return string + */ + public function getMessageFormat() + { + return $this->messageFormat; + } + + /** + * Create a message to send from the given log entry messages + * + * @param array $messages + * + * @return string + */ + protected function createMessage(array $messages) + { + if (null === $this->messageFormat) { + $this->messageFormat = $this->getDefaultMessageFormat(); + } + + $message = str_replace('%records%', implode('', $messages), $this->messageFormat); + + return $message; + } + + /** + * Prepare a record for writing + * + * This method is just a shortcut for the common handling process (except writing) + * + * @param array $record + * + * @return array + */ + protected function prepareRecord(array $record) + { + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = call_user_func($processor, $record); + } + } + + if (!$this->formatter) { + $this->formatter = $this->getDefaultFormatter(); + } + $record = $this->formatter->format($record); + + return $record; + } + + /** + * Get the default mail message format + * + * @return string + */ + protected function getDefaultMessageFormat() + { + return 'Application logs:\n %records%'; + } + + /** + * Send a mail with the given message + * + * @param string $message + */ + abstract protected function send($message); + +} \ No newline at end of file diff --git a/tests/Monolog/Handler/MailHandlerTest.php b/tests/Monolog/Handler/MailHandlerTest.php new file mode 100644 index 00000000..24b39ca4 --- /dev/null +++ b/tests/Monolog/Handler/MailHandlerTest.php @@ -0,0 +1,42 @@ +getMultipleRecords(); + + $formatter = $this->getMock('Monolog\Formatter\LineFormatter'); + $formatter->expects($this->exactly(count($records))) + ->method('format'); // Each record is formatted + + $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler'); + $handler->expects($this->once()) + ->method('send'); + $handler->expects($this->never()) + ->method('write'); // write is for individual records + + $handler->setFormatter($formatter); + + $handler->handleBatch($records); + } + + public function testHandle() + { + $record = $this->getRecord(); + + $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler'); + $handler->expects($this->once()) + ->method('write'); + + $this->assertTrue($handler->handle($record)); + } + +} \ No newline at end of file diff --git a/tests/Monolog/TestCase.php b/tests/Monolog/TestCase.php index e7f1eac8..19fd8dd3 100644 --- a/tests/Monolog/TestCase.php +++ b/tests/Monolog/TestCase.php @@ -28,6 +28,20 @@ class TestCase extends \PHPUnit_Framework_TestCase ); } + /** + * @return array + */ + protected function getMultipleRecords() + { + return array( + $this->getRecord(Logger::DEBUG, 'debug message 1'), + $this->getRecord(Logger::DEBUG, 'debug message 2'), + $this->getRecord(Logger::INFO, 'information'), + $this->getRecord(Logger::WARNING, 'warning'), + $this->getRecord(Logger::ERROR, 'error') + ); + } + /** * @return Monolog\Formatter\FormatterInterface */ From a1bc483041ab272e36bd30280a6cf73b11eea076 Mon Sep 17 00:00:00 2001 From: Gyula Sallai Date: Mon, 25 Apr 2011 01:48:12 +0200 Subject: [PATCH 2/6] Added SwiftMailerHandler, added write to MailHandler --- src/Monolog/Handler/MailHandler.php | 24 +++++++---- src/Monolog/Handler/SwiftMailerHandler.php | 47 ++++++++++++++++++++++ tests/Monolog/Handler/MailHandlerTest.php | 13 +++++- 3 files changed, 75 insertions(+), 9 deletions(-) create mode 100644 src/Monolog/Handler/SwiftMailerHandler.php diff --git a/src/Monolog/Handler/MailHandler.php b/src/Monolog/Handler/MailHandler.php index a6b4ac5e..921879ae 100644 --- a/src/Monolog/Handler/MailHandler.php +++ b/src/Monolog/Handler/MailHandler.php @@ -75,6 +75,23 @@ abstract class MailHandler extends AbstractHandler { return $this->messageFormat; } + + /** + * Send a mail with the given content + * + * @param string $content + */ + abstract protected function send($content); + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $content = $record['message']; + + $this->send($content); + } /** * Create a message to send from the given log entry messages @@ -129,11 +146,4 @@ abstract class MailHandler extends AbstractHandler return 'Application logs:\n %records%'; } - /** - * Send a mail with the given message - * - * @param string $message - */ - abstract protected function send($message); - } \ No newline at end of file diff --git a/src/Monolog/Handler/SwiftMailerHandler.php b/src/Monolog/Handler/SwiftMailerHandler.php new file mode 100644 index 00000000..598d7041 --- /dev/null +++ b/src/Monolog/Handler/SwiftMailerHandler.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +/** + * SwiftMailerHandler uses Swift_Mailer to send the emails + * + * @author Gyula Sallai + */ +class SwiftMailerHandler extends MailHandler +{ + + protected $mailer; + protected $message; + + /** + * @param \Swift_Mailer $mailer The mailer to use + * @param \Swift_Message $message An example message for real messages, + * only the body will be replaced + */ + public function __construct(\Swift_Mailer $mailer, \Swift_Message $message) + { + $this->mailer = $mailer; + $this->message = $message; + } + + /** + * {@inheritdoc} + */ + protected function send($content) + { + $message = clone $this->message; + $message->setBody($content); + + $this->mailer->send($message); + } + +} \ No newline at end of file diff --git a/tests/Monolog/Handler/MailHandlerTest.php b/tests/Monolog/Handler/MailHandlerTest.php index 24b39ca4..9af57049 100644 --- a/tests/Monolog/Handler/MailHandlerTest.php +++ b/tests/Monolog/Handler/MailHandlerTest.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Monolog\Handler; use Monolog\Logger; @@ -34,9 +43,9 @@ class MailHandlerTest extends TestCase $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler'); $handler->expects($this->once()) - ->method('write'); + ->method('send'); - $this->assertTrue($handler->handle($record)); + $handler->handle($record); } } \ No newline at end of file From d87ba1c6e5cb1b7ef3dd4b9cb891b455a445bfc2 Mon Sep 17 00:00:00 2001 From: Gyula Sallai Date: Thu, 28 Apr 2011 18:02:38 +0200 Subject: [PATCH 3/6] Fixes --- src/Monolog/Handler/MailHandler.php | 4 +++- src/Monolog/Handler/SwiftMailerHandler.php | 8 +++++++- tests/Monolog/Handler/MailHandlerTest.php | 16 ++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/Monolog/Handler/MailHandler.php b/src/Monolog/Handler/MailHandler.php index 921879ae..c56bac40 100644 --- a/src/Monolog/Handler/MailHandler.php +++ b/src/Monolog/Handler/MailHandler.php @@ -53,7 +53,9 @@ abstract class MailHandler extends AbstractHandler $messages[] = $record['message']; } - $this->send($this->createMessage($messages)); + if (!empty($messages)) { + $this->send($this->createMessage($messages)); + } } /** diff --git a/src/Monolog/Handler/SwiftMailerHandler.php b/src/Monolog/Handler/SwiftMailerHandler.php index 598d7041..6f862180 100644 --- a/src/Monolog/Handler/SwiftMailerHandler.php +++ b/src/Monolog/Handler/SwiftMailerHandler.php @@ -11,6 +11,8 @@ namespace Monolog\Handler; +use Monolog\Logger; + /** * SwiftMailerHandler uses Swift_Mailer to send the emails * @@ -26,11 +28,15 @@ class SwiftMailerHandler extends MailHandler * @param \Swift_Mailer $mailer The mailer to use * @param \Swift_Message $message An example message for real messages, * only the body will be replaced + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not */ - public function __construct(\Swift_Mailer $mailer, \Swift_Message $message) + public function __construct(\Swift_Mailer $mailer, \Swift_Message $message, $level = Logger::ERROR, $bubble = false) { $this->mailer = $mailer; $this->message = $message; + $this->level = $level; + $this->bubble = $bubble; } /** diff --git a/tests/Monolog/Handler/MailHandlerTest.php b/tests/Monolog/Handler/MailHandlerTest.php index 9af57049..2d9a6a84 100644 --- a/tests/Monolog/Handler/MailHandlerTest.php +++ b/tests/Monolog/Handler/MailHandlerTest.php @@ -37,6 +37,22 @@ class MailHandlerTest extends TestCase $handler->handleBatch($records); } + public function testHandleBatchNotSendsMailIfMessagesAreBelowLevel() + { + $records = array( + $this->getRecord(Logger::DEBUG, 'debug message 1'), + $this->getRecord(Logger::DEBUG, 'debug message 2'), + $this->getRecord(Logger::INFO, 'information'), + ); + + $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler'); + $handler->expects($this->never()) + ->method('send'); + $handler->setLevel(Logger::ERROR); + + $handler->handleBatch($records); + } + public function testHandle() { $record = $this->getRecord(); From d3bc58a01c4bb0e208e7ce03ba1efe8fbb57e30f Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Sun, 8 May 2011 15:18:58 +0200 Subject: [PATCH 4/6] Refactored the MailHandler to use the formatter to format the batch message --- src/Monolog/Handler/MailHandler.php | 120 +++------------------ src/Monolog/Handler/SwiftMailerHandler.php | 14 +-- tests/Monolog/Handler/MailHandlerTest.php | 34 +++--- tests/Monolog/TestCase.php | 2 +- 4 files changed, 34 insertions(+), 136 deletions(-) diff --git a/src/Monolog/Handler/MailHandler.php b/src/Monolog/Handler/MailHandler.php index c56bac40..e7074688 100644 --- a/src/Monolog/Handler/MailHandler.php +++ b/src/Monolog/Handler/MailHandler.php @@ -13,139 +13,47 @@ namespace Monolog\Handler; /** * Base class for all mail handlers - * + * * @author Gyula Sallai */ abstract class MailHandler extends AbstractHandler { - - protected $messageFormat; - - /** - * {@inheritdoc} - */ - public function handle(array $record) - { - if ($record['level'] < $this->level) { - return false; - } - - $record = $this->prepareRecord($record); - - $this->write($record); - - return false === $this->bubble; - } - /** * {@inheritdoc} */ public function handleBatch(array $records) - { + { $messages = array(); - + foreach ($records as $record) { if ($record['level'] < $this->level) { continue; } - - $record = $this->prepareRecord($record); - $messages[] = $record['message']; + $messages[] = $this->processRecord($record); } - + if (!empty($messages)) { - $this->send($this->createMessage($messages)); + if (!$this->formatter) { + $this->formatter = $this->getDefaultFormatter(); + } + $this->send($this->formatter->formatBatch($messages)); } } - - /** - * Set the message format - * - * @param string $format - */ - public function setMessageFormat($format) - { - $this->messageFormat = $format; - } - - /** - * Get the message format - * - * @return string - */ - public function getMessageFormat() - { - return $this->messageFormat; - } - + /** * Send a mail with the given content - * + * * @param string $content */ - abstract protected function send($content); - + abstract protected function send($content); + /** * {@inheritdoc} */ protected function write(array $record) { $content = $record['message']; - + $this->send($content); } - - /** - * Create a message to send from the given log entry messages - * - * @param array $messages - * - * @return string - */ - protected function createMessage(array $messages) - { - if (null === $this->messageFormat) { - $this->messageFormat = $this->getDefaultMessageFormat(); - } - - $message = str_replace('%records%', implode('', $messages), $this->messageFormat); - - return $message; - } - - /** - * Prepare a record for writing - * - * This method is just a shortcut for the common handling process (except writing) - * - * @param array $record - * - * @return array - */ - protected function prepareRecord(array $record) - { - if ($this->processors) { - foreach ($this->processors as $processor) { - $record = call_user_func($processor, $record); - } - } - - if (!$this->formatter) { - $this->formatter = $this->getDefaultFormatter(); - } - $record = $this->formatter->format($record); - - return $record; - } - - /** - * Get the default mail message format - * - * @return string - */ - protected function getDefaultMessageFormat() - { - return 'Application logs:\n %records%'; - } - } \ No newline at end of file diff --git a/src/Monolog/Handler/SwiftMailerHandler.php b/src/Monolog/Handler/SwiftMailerHandler.php index 6f862180..8a400032 100644 --- a/src/Monolog/Handler/SwiftMailerHandler.php +++ b/src/Monolog/Handler/SwiftMailerHandler.php @@ -15,28 +15,25 @@ use Monolog\Logger; /** * SwiftMailerHandler uses Swift_Mailer to send the emails - * + * * @author Gyula Sallai */ class SwiftMailerHandler extends MailHandler { - protected $mailer; protected $message; - + /** * @param \Swift_Mailer $mailer The mailer to use - * @param \Swift_Message $message An example message for real messages, - * only the body will be replaced + * @param \Swift_Message $message An example message for real messages, only the body will be replaced * @param integer $level The minimum logging level at which this handler will be triggered * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct(\Swift_Mailer $mailer, \Swift_Message $message, $level = Logger::ERROR, $bubble = false) { + parent::__construct($level, $bubble); $this->mailer = $mailer; $this->message = $message; - $this->level = $level; - $this->bubble = $bubble; } /** @@ -46,8 +43,7 @@ class SwiftMailerHandler extends MailHandler { $message = clone $this->message; $message->setBody($content); - + $this->mailer->send($message); } - } \ No newline at end of file diff --git a/tests/Monolog/Handler/MailHandlerTest.php b/tests/Monolog/Handler/MailHandlerTest.php index 2d9a6a84..6b8f96be 100644 --- a/tests/Monolog/Handler/MailHandlerTest.php +++ b/tests/Monolog/Handler/MailHandlerTest.php @@ -12,31 +12,27 @@ namespace Monolog\Handler; use Monolog\Logger; - use Monolog\TestCase; class MailHandlerTest extends TestCase { - public function testHandleBatch() { - $records = $this->getMultipleRecords(); - - $formatter = $this->getMock('Monolog\Formatter\LineFormatter'); - $formatter->expects($this->exactly(count($records))) - ->method('format'); // Each record is formatted - + $formatter = $this->getMock('Monolog\\Formatter\\FormatterInterface'); + $formatter->expects($this->once()) + ->method('formatBatch'); // Each record is formatted + $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler'); $handler->expects($this->once()) ->method('send'); $handler->expects($this->never()) ->method('write'); // write is for individual records - + $handler->setFormatter($formatter); - - $handler->handleBatch($records); + + $handler->handleBatch($this->getMultipleRecords()); } - + public function testHandleBatchNotSendsMailIfMessagesAreBelowLevel() { $records = array( @@ -44,24 +40,22 @@ class MailHandlerTest extends TestCase $this->getRecord(Logger::DEBUG, 'debug message 2'), $this->getRecord(Logger::INFO, 'information'), ); - + $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler'); $handler->expects($this->never()) ->method('send'); $handler->setLevel(Logger::ERROR); - + $handler->handleBatch($records); } - + public function testHandle() { - $record = $this->getRecord(); - $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler'); $handler->expects($this->once()) ->method('send'); - - $handler->handle($record); + + $handler->handle($this->getRecord()); } - + } \ No newline at end of file diff --git a/tests/Monolog/TestCase.php b/tests/Monolog/TestCase.php index e97d12cb..8f4b1caf 100644 --- a/tests/Monolog/TestCase.php +++ b/tests/Monolog/TestCase.php @@ -41,7 +41,7 @@ class TestCase extends \PHPUnit_Framework_TestCase $this->getRecord(Logger::ERROR, 'error') ); } - + /** * @return Monolog\Formatter\FormatterInterface */ From c33eb7b032dcecbc564ca2bee219506a55f848ff Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Sun, 8 May 2011 16:11:54 +0200 Subject: [PATCH 5/6] Added a NativeMailerHandler using the PHP mail() function --- src/Monolog/Handler/NativeMailerHandler.php | 49 +++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/Monolog/Handler/NativeMailerHandler.php diff --git a/src/Monolog/Handler/NativeMailerHandler.php b/src/Monolog/Handler/NativeMailerHandler.php new file mode 100644 index 00000000..5c670115 --- /dev/null +++ b/src/Monolog/Handler/NativeMailerHandler.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * NativeMailerHandler uses the mail() function to send the emails + * + * @author Christophe Coevoet + */ +class NativeMailerHandler extends MailHandler +{ + protected $to; + protected $subject; + protected $headers; + + /** + * @param string $to The receiver of the mail + * @param string $subject The subject of the mail + * @param string $from The sender of the mail + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($to, $subject, $from, $level = Logger::ERROR, $bubble = false) + { + parent::__construct($level, $bubble); + $this->to = $to; + $this->subject = $subject; + $this->headers = sprintf("From: %s\r\nContent-type: text/plain; charset=utf-8\r\n", $from); + } + + /** + * {@inheritdoc} + */ + protected function send($content) + { + mail($this->to, $this->subject, wordwrap($content, 70), $this->headers); + } +} \ No newline at end of file From 6aebccf34ce71b1d67f975a7ef7b254d005378ee Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Sun, 8 May 2011 16:34:56 +0200 Subject: [PATCH 6/6] Moved the use of the default formatter to the getter to keep the code DRY --- src/Monolog/Handler/AbstractHandler.php | 9 +++++---- src/Monolog/Handler/MailHandler.php | 5 +---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/Monolog/Handler/AbstractHandler.php b/src/Monolog/Handler/AbstractHandler.php index 0e385573..530e1f16 100644 --- a/src/Monolog/Handler/AbstractHandler.php +++ b/src/Monolog/Handler/AbstractHandler.php @@ -62,10 +62,7 @@ abstract class AbstractHandler implements HandlerInterface $record = $this->processRecord($record); - if (!$this->formatter) { - $this->formatter = $this->getDefaultFormatter(); - } - $record['message'] = $this->formatter->format($record); + $record['message'] = $this->getFormatter()->format($record); $this->write($record); @@ -120,6 +117,10 @@ abstract class AbstractHandler implements HandlerInterface */ public function getFormatter() { + if (!$this->formatter) { + $this->formatter = $this->getDefaultFormatter(); + } + return $this->formatter; } diff --git a/src/Monolog/Handler/MailHandler.php b/src/Monolog/Handler/MailHandler.php index e7074688..c8e04990 100644 --- a/src/Monolog/Handler/MailHandler.php +++ b/src/Monolog/Handler/MailHandler.php @@ -33,10 +33,7 @@ abstract class MailHandler extends AbstractHandler } if (!empty($messages)) { - if (!$this->formatter) { - $this->formatter = $this->getDefaultFormatter(); - } - $this->send($this->formatter->formatBatch($messages)); + $this->send($this->getFormatter()->formatBatch($messages)); } }