Просмотр исходного кода

Move the stack handling to the Logger class

Jordi Boggiano 15 лет назад
Родитель
Сommit
903bbd0fd6

+ 4 - 26
src/Monolog/Handler/AbstractHandler.php

@@ -25,7 +25,6 @@ abstract class AbstractHandler implements HandlerInterface
 {
     protected $level;
     protected $bubble;
-    protected $parent;
 
     protected $formatter;
     protected $processors = array();
@@ -36,18 +35,15 @@ abstract class AbstractHandler implements HandlerInterface
         $this->bubble = $bubble;
     }
 
-    public function getHandler($message)
+    public function isHandling($message)
     {
-        if ($message['level'] < $this->level) {
-            return $this->parent ? $this->parent->getHandler($message) : null;
-        }
-        return $this;
+        return $message['level'] >= $this->level;
     }
 
     public function handle($message)
     {
         if ($message['level'] < $this->level) {
-            return $this->parent ? $this->parent->handle($message) : false;
+            return false;
         }
 
         $originalMessage = $message;
@@ -63,10 +59,7 @@ abstract class AbstractHandler implements HandlerInterface
         $message = $this->formatter->format($message);
 
         $this->write($message);
-        if ($this->bubble && $this->parent) {
-            $this->parent->handle($originalMessage);
-        }
-        return true;
+        return false === $this->bubble;
     }
 
     abstract public function write($message);
@@ -115,21 +108,6 @@ abstract class AbstractHandler implements HandlerInterface
         return $this->bubble;
     }
 
-    public function getParent()
-    {
-        return $this->parent;
-    }
-
-    /**
-     * Sets the parent handler
-     *
-     * @param Monolog\Handler\HandlerInterface
-     */
-    public function setParent(HandlerInterface $parent)
-    {
-        $this->parent = $parent;
-    }
-
     public function __destruct()
     {
         $this->close();

+ 1 - 4
src/Monolog/Handler/FingersCrossedHandler.php

@@ -73,10 +73,7 @@ class FingersCrossedHandler extends AbstractHandler
         } else {
             $this->handler->handle($message);
         }
-        if ($this->bubble && $this->parent) {
-            $this->parent->handle($message);
-        }
-        return true;
+        return false === $this->bubble;
     }
 
     /**

+ 1 - 5
src/Monolog/Handler/HandlerInterface.php

@@ -18,11 +18,7 @@ namespace Monolog\Handler;
  */
 interface HandlerInterface
 {
-    public function getHandler($message);
+    public function isHandling($message);
 
     public function handle($message);
-
-    public function getParent();
-
-    public function setParent(HandlerInterface $parent);
 }

+ 2 - 5
src/Monolog/Handler/NullHandler.php

@@ -26,12 +26,9 @@ class NullHandler extends AbstractHandler
     public function handle($message)
     {
         if ($message['level'] < $this->level) {
-            return $this->parent ? $this->parent->handle($message) : false;
+            return false;
         }
-        if ($this->bubble && $this->parent) {
-            $this->parent->handle($originalMessage);
-        }
-        return true;
+        return false === $this->bubble;
     }
 
     public function write($message)

+ 24 - 20
src/Monolog/Logger.php

@@ -56,11 +56,11 @@ class Logger
     protected $name;
 
     /**
-     * The handler instance at the top of the handler stack
+     * The handler stack
      *
-     * @var Monolog\Handler\HandlerInterface
+     * @var array of Monolog\Handler\HandlerInterface
      */
-    protected $handler;
+    protected $handlers = array();
 
     protected $processors = array();
 
@@ -71,38 +71,33 @@ class Logger
 
     public function pushHandler(HandlerInterface $handler)
     {
-        if ($this->handler) {
-            if ($this->handler === $handler) {
-                throw new \UnexpectedValueException('Circular reference, do not add the same handler instance twice.');
-            }
-            $handler->setParent($this->handler);
-        }
-        $this->handler = $handler;
+        array_unshift($this->handlers, $handler);
     }
 
     public function popHandler()
     {
-        if (null === $this->handler) {
+        if (!$this->handlers) {
             throw new \LogicException('You tried to pop from an empty handler stack.');
         }
-        $top = $this->handler;
-        $this->handler = $top->getParent();
-        return $top;
+        return array_shift($this->handlers);
     }
 
     public function pushProcessor($callback)
     {
-        $this->processors[] = $callback;
+        array_unshift($this->processors, $callback);
     }
 
     public function popProcessor()
     {
-        return array_pop($this->processors);
+        if (!$this->processors) {
+            throw new \LogicException('You tried to pop from an empty processor stack.');
+        }
+        return array_shift($this->processors);
     }
 
     public function addMessage($level, $message)
     {
-        if (null === $this->handler) {
+        if (!$this->handlers) {
             $this->pushHandler(new StreamHandler('php://stderr', self::DEBUG));
         }
         $message = array(
@@ -113,14 +108,23 @@ class Logger
             'datetime' => new \DateTime(),
             'extra' => array(),
         );
-        $handler = $this->handler->getHandler($message);
-        if (!$handler) {
+        $handlerKey = null;
+        foreach ($this->handlers as $key => $handler) {
+            if ($handler->isHandling($message)) {
+                $handlerKey = $key;
+                break;
+            }
+        }
+        if (null === $handlerKey) {
             return false;
         }
         foreach ($this->processors as $processor) {
             $message = call_user_func($processor, $message, $this);
         }
-        $handler->handle($message);
+        while (isset($this->handlers[$handlerKey]) &&
+            false === $this->handlers[$handlerKey]->handle($message)) {
+            $handlerKey++;
+        }
         return true;
     }
 

+ 8 - 23
tests/Monolog/Handler/AbstractHandlerTest.php

@@ -29,36 +29,21 @@ class AbstractHandlerTest extends \PHPUnit_Framework_TestCase
 
     public function testHandleBubbling()
     {
-        $topHandler = new TestHandler(Logger::DEBUG, true);
-        $bottomHandler = new TestHandler(Logger::INFO);
-        $topHandler->setParent($bottomHandler);
-        $this->assertTrue($topHandler->handle($this->getMessage()));
-        $this->assertTrue($bottomHandler->hasWarningMessages());
+        $handler = new TestHandler(Logger::DEBUG, true);
+        $this->assertFalse($handler->handle($this->getMessage()));
     }
 
     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()));
+        $handler = new TestHandler(Logger::DEBUG);
+        $this->assertTrue($handler->handle($this->getMessage()));
     }
 
-    public function testGetHandlerReturnsParent()
+    public function testIsHandling()
     {
-        $topHandler = new TestHandler(Logger::ERROR);
-        $bottomHandler = new TestHandler(Logger::INFO);
-        $topHandler->setParent($bottomHandler);
-        $this->assertEquals($bottomHandler, $topHandler->getHandler($this->getMessage()));
+        $handler = new TestHandler(Logger::WARNING);
+        $this->assertTrue($handler->handle($this->getMessage()));
+        $this->assertFalse($handler->handle($this->getMessage(Logger::DEBUG)));
     }
 
     protected function getMessage($level = Logger::WARNING)