diff --git a/src/Monolog/Handler/AbstractHandler.php b/src/Monolog/Handler/AbstractHandler.php index 90ff4152..da4aed09 100644 --- a/src/Monolog/Handler/AbstractHandler.php +++ b/src/Monolog/Handler/AbstractHandler.php @@ -21,7 +21,7 @@ abstract class AbstractHandler implements HandlerInterface protected $parent; protected $formatter; - protected $processor; + protected $processors = array(); public function __construct($level = Logger::DEBUG, $bubble = false) { @@ -29,14 +29,25 @@ abstract class AbstractHandler implements HandlerInterface $this->bubble = $bubble; } + public function getHandler($message) + { + if ($message['level'] < $this->level) { + return $this->parent ? $this->parent->getHandler($message) : null; + } + return $this; + } + public function handle($message) { if ($message['level'] < $this->level) { - return false; + return $this->parent ? $this->parent->handle($message) : false; } - if ($this->processor) { - $message = call_user_func($this->processor, $message, $this); + $originalMessage = $message; + if ($this->processors) { + foreach ($this->processors as $processor) { + $message = call_user_func($processor, $message, $this); + } } if (!$this->formatter) { @@ -45,7 +56,10 @@ abstract class AbstractHandler implements HandlerInterface $message = $this->formatter->format($message); $this->write($message); - return false === $this->bubble; + if ($this->bubble && $this->parent) { + $this->parent->handle($originalMessage); + } + return true; } abstract public function write($message); @@ -54,14 +68,14 @@ abstract class AbstractHandler implements HandlerInterface { } - public function setProcessor($callback) + public function pushProcessor($callback) { - $this->processor = $callback; + $this->processors[] = $callback; } - public function getProcessor() + public function popProcessor() { - return $this->processor; + return array_pop($this->processors); } public function setFormatter($formatter) diff --git a/src/Monolog/Handler/HandlerInterface.php b/src/Monolog/Handler/HandlerInterface.php index 81cff1fe..976790ef 100644 --- a/src/Monolog/Handler/HandlerInterface.php +++ b/src/Monolog/Handler/HandlerInterface.php @@ -13,16 +13,10 @@ namespace Monolog\Handler; interface HandlerInterface { + public function getHandler($message); + public function handle($message); - public function setLevel($level); - - public function getLevel(); - - public function setBubble($bubble); - - public function getBubble(); - public function getParent(); public function setParent(HandlerInterface $parent); diff --git a/src/Monolog/Logger.php b/src/Monolog/Logger.php index 84953494..5b52644c 100644 --- a/src/Monolog/Logger.php +++ b/src/Monolog/Logger.php @@ -54,6 +54,8 @@ class Logger */ protected $handler; + protected $processors = array(); + public function __construct($name) { $this->name = $name; @@ -77,6 +79,16 @@ class Logger return $top; } + public function pushProcessor($callback) + { + $this->processors[] = $callback; + } + + public function popProcessor() + { + return array_pop($this->processors); + } + public function addMessage($level, $message) { if (null === $this->handler) { @@ -90,33 +102,35 @@ class Logger 'datetime' => new \DateTime(), 'extra' => array(), ); - $handled = false; - $handler = $this->handler; - while ($handler && true !== $handled) { - $handled = (bool) $handler->handle($message); - $handler = $handler->getParent(); + $handler = $this->handler->getHandler($message); + if (!$handler) { + return false; } - return $handled; + foreach ($this->processors as $processor) { + $message = call_user_func($processor, $message, $this); + } + $handler->handle($message); + return true; } public function addDebug($message) { - $this->addMessage(self::DEBUG, $message); + return $this->addMessage(self::DEBUG, $message); } public function addInfo($message) { - $this->addMessage(self::INFO, $message); + return $this->addMessage(self::INFO, $message); } public function addWarning($message) { - $this->addMessage(self::WARNING, $message); + return $this->addMessage(self::WARNING, $message); } public function addError($message) { - $this->addMessage(self::ERROR, $message); + return $this->addMessage(self::ERROR, $message); } public static function getLevelName($level) @@ -128,41 +142,41 @@ class Logger public function debug($message) { - $this->addMessage(self::DEBUG, $message); + return $this->addMessage(self::DEBUG, $message); } public function info($message) { - $this->addMessage(self::INFO, $message); + return $this->addMessage(self::INFO, $message); } public function notice($message) { - $this->addMessage(self::INFO, $message); + return $this->addMessage(self::INFO, $message); } public function warn($message) { - $this->addMessage(self::WARNING, $message); + return $this->addMessage(self::WARNING, $message); } public function err($message) { - $this->addMessage(self::ERROR, $message); + return $this->addMessage(self::ERROR, $message); } public function crit($message) { - $this->addMessage(self::ERROR, $message); + return $this->addMessage(self::ERROR, $message); } public function alert($message) { - $this->addMessage(self::ERROR, $message); + return $this->addMessage(self::ERROR, $message); } public function emerg($message) { - $this->addMessage(self::ERROR, $message); + return $this->addMessage(self::ERROR, $message); } } diff --git a/tests/Monolog/Handler/AbstractHandlerTest.php b/tests/Monolog/Handler/AbstractHandlerTest.php index 3376851f..50323732 100644 --- a/tests/Monolog/Handler/AbstractHandlerTest.php +++ b/tests/Monolog/Handler/AbstractHandlerTest.php @@ -29,8 +29,36 @@ class AbstractHandlerTest extends \PHPUnit_Framework_TestCase public function testHandleBubbling() { - $handler = new TestHandler(Logger::DEBUG, true); - $this->assertFalse($handler->handle($this->getMessage())); + $topHandler = new TestHandler(Logger::DEBUG, true); + $bottomHandler = new TestHandler(Logger::INFO); + $topHandler->setParent($bottomHandler); + $this->assertTrue($topHandler->handle($this->getMessage())); + $this->assertTrue($bottomHandler->hasWarningMessages()); + } + + public function testHandleNotBubbling() + { + $topHandler = new TestHandler(Logger::DEBUG); + $bottomHandler = new TestHandler(Logger::INFO); + $topHandler->setParent($bottomHandler); + $this->assertTrue($topHandler->handle($this->getMessage())); + $this->assertFalse($bottomHandler->hasWarningMessages()); + } + + public function testGetHandlerReturnEarly() + { + $topHandler = new TestHandler(Logger::DEBUG); + $bottomHandler = new TestHandler(Logger::INFO); + $topHandler->setParent($bottomHandler); + $this->assertEquals($topHandler, $topHandler->getHandler($this->getMessage())); + } + + public function testGetHandlerReturnsParent() + { + $topHandler = new TestHandler(Logger::ERROR); + $bottomHandler = new TestHandler(Logger::INFO); + $topHandler->setParent($bottomHandler); + $this->assertEquals($bottomHandler, $topHandler->getHandler($this->getMessage())); } protected function getMessage($level = Logger::WARNING) diff --git a/tests/Monolog/LoggerTest.php b/tests/Monolog/LoggerTest.php index c73ab9e2..1f73e1c4 100644 --- a/tests/Monolog/LoggerTest.php +++ b/tests/Monolog/LoggerTest.php @@ -22,28 +22,19 @@ class LoggerTest extends \PHPUnit_Framework_TestCase ->method('handle'); $logger->pushHandler($handler); - $logger->addWarning('test'); + $this->assertTrue($logger->addWarning('test')); } - /** - * @dataProvider logValues - */ - public function testLogUntilHandled($bubble) + public function testLogNoHandler() { $logger = new Logger(__METHOD__); - $bottomHandler = $this->getMock('Monolog\Handler\NullHandler', array('handle')); - $bottomHandler->expects($bubble ? $this->once() : $this->never()) + $handler = $this->getMock('Monolog\Handler\NullHandler', array('handle'), array(Logger::ERROR)); + $handler->expects($this->never()) ->method('handle'); - $logger->pushHandler($bottomHandler); + $logger->pushHandler($handler); - $topHandler = $this->getMock('Monolog\Handler\NullHandler', array('handle')); - $topHandler->expects($this->once()) - ->method('handle') - ->will($this->returnValue(!$bubble)); - $logger->pushHandler($topHandler); - - $logger->addWarning('test'); + $this->assertFalse($logger->addWarning('test')); } public function logValues()