From 3ed3a327b735ce188d6aec2af5a227ee22cf5145 Mon Sep 17 00:00:00 2001 From: jessmchung Date: Mon, 4 Jan 2016 11:00:55 -0500 Subject: [PATCH] Support for processors per handler. --- src/Config.php | 10 ++-- .../Loader/ClassLoader/HandlerLoader.php | 46 ++++++++++++++- .../Loader/ClassLoader/HandlerLoaderTest.php | 57 ++++++++++++++++++- tests/ConfigTest.php | 4 +- 4 files changed, 106 insertions(+), 11 deletions(-) diff --git a/src/Config.php b/src/Config.php index 93dc83f..6121c06 100644 --- a/src/Config.php +++ b/src/Config.php @@ -107,14 +107,14 @@ public function configure() $this->configureFormatters($this->options['formatters']); } - if (isset($this->options['handlers'])) { - $this->configureHandlers($this->options['handlers']); - } - if (isset($this->options['processors'])) { $this->configureProcessors($this->options['processors']); } + if (isset($this->options['handlers'])) { + $this->configureHandlers($this->options['handlers']); + } + if (isset($this->options['loggers'])) { $this->configureLoggers($this->options['loggers']); } else { @@ -143,7 +143,7 @@ protected function configureFormatters(array $formatters = array()) protected function configureHandlers(array $handlers) { foreach ($handlers as $handlerId => $handlerOptions) { - $handlerLoader = new HandlerLoader($handlerOptions, $this->formatters); + $handlerLoader = new HandlerLoader($handlerOptions, $this->formatters, $this->processors); $this->handlers[$handlerId] = $handlerLoader->load(); } } diff --git a/src/Config/Loader/ClassLoader/HandlerLoader.php b/src/Config/Loader/ClassLoader/HandlerLoader.php index dfde5b4..9259608 100644 --- a/src/Config/Loader/ClassLoader/HandlerLoader.php +++ b/src/Config/Loader/ClassLoader/HandlerLoader.php @@ -36,10 +36,15 @@ class HandlerLoader extends ClassLoader * * @param array $handlerOptions Handler options * @param Monolog\Formatter\FormatterInterface[] $formatters Array of formatter to pick from + * @param callable[] $processors Array of processors to pick from */ - public function __construct(array &$handlerOptions, array $formatters = array()) - { + public function __construct( + array &$handlerOptions, + array $formatters = array(), + array $processors = array() + ) { $this->populateFormatters($handlerOptions, $formatters); + $this->populateProcessors($handlerOptions, $processors); parent::__construct($handlerOptions); self::initExtraOptionsHandlers(); @@ -73,6 +78,37 @@ private function populateFormatters(array &$handlerOptions, array $formatters) } } + /** + * Replace the processors in the option array with the corresponding callable from the + * array of loaded and callable processors, if it exists. + * + * @throws InvalidArgumentException + * + * @param array &$handlerOptions Handler options + * @param callable[] $processors Array of processors to pick from + */ + private function populateProcessors(array &$handlerOptions, array $processors) + { + $processorArray = array(); + + if (isset($handlerOptions['processors'])) { + foreach ($handlerOptions['processors'] as $processorId) { + if (isset($processors[$processorId])) { + $processorArray[] = $processors[$processorId]; + } else { + throw new \InvalidArgumentException( + sprintf( + 'Cannot add processor "%s" to the handler. Processor not found.', + $processorId + ) + ); + } + } + + $handlerOptions['processors'] = $processorArray; + } + } + /** * Loads the closures as option handlers. Add handlers to this function if * you want to support additional custom options. @@ -93,6 +129,12 @@ public static function initExtraOptionsHandlers() '*' => array( 'formatter' => function ($instance, FormatterInterface $formatter) { $instance->setFormatter($formatter); + }, + 'processors' => function ($instance, array $processors) { + // We need to reverse the array because Monolog "pushes" processors to top of the stack + foreach (array_reverse($processors) as $processor) { + $instance->pushProcessor($processor); + } } ), 'Monolog\Handler\LogglyHandler' => array( diff --git a/tests/Config/Loader/ClassLoader/HandlerLoaderTest.php b/tests/Config/Loader/ClassLoader/HandlerLoaderTest.php index e355d06..cad5dcf 100644 --- a/tests/Config/Loader/ClassLoader/HandlerLoaderTest.php +++ b/tests/Config/Loader/ClassLoader/HandlerLoaderTest.php @@ -23,16 +23,26 @@ class HandlerLoaderTest extends \PHPUnit_Framework_TestCase { public function testHandlerLoader() { + $dummyClosure = function () { + // Empty function + }; $original = $options = array( 'class' => '\Monolog\Handler\TestHandler', 'level' => 'DEBUG', - 'formatter' => 'test_formatter' + 'formatter' => 'test_formatter', + 'processors' => array('test_processor_1', 'test_processor_2') ); $formatters = array('test_formatter' => new LineFormatter()); - $loader = new HandlerLoader($options, $formatters); + $processors = array( + 'test_processor_1' => $dummyClosure, + 'test_processor_2' => $dummyClosure + ); + $loader = new HandlerLoader($options, $formatters, $processors); $this->assertNotEquals($original, $options); $this->assertEquals(new LineFormatter(), $options['formatter']); + $this->assertContains($dummyClosure, $options['processors']); + $this->assertContains($dummyClosure, $options['processors']); } public function testHandlerLoaderWithNoOptions() @@ -56,6 +66,23 @@ public function testHandlerLoaderWithInvalidFormatter() $loader = new HandlerLoader($options, $formatters); } + /** + * @expectedException InvalidArgumentException + */ + public function testHandlerLoaderWithInvalidProcessor() + { + $dummyClosure = function () { + // Empty function + }; + $options = array( + 'processors' => array('test_processor_1') + ); + + $formatters = array(); + $processors = array('test_processorXYZ' => $dummyClosure); + $loader = new HandlerLoader($options, $formatters, $processors); + } + /** * Check if the handler exists for a given class and option * Also checks that it a callable and return it @@ -165,4 +192,30 @@ public function testHandlers($class, $optionName, $optionValue, $calledMethodNam $this->doTestMethodCalledInHandler($class, $calledMethodName, $optionValue, $closure); } + + /** + * Test extra option processor handler + */ + public function testHandlerForProcessor() + { + $options = array(); + + $mockProcessor1 = '123'; + $mockProcessor2 = '456'; + $processorsArray = array($mockProcessor1, $mockProcessor2); + + // Setup mock and expectations + $mockHandler = $this->getMockBuilder('Monolog\Handler\TestHandler') + ->disableOriginalConstructor() + ->setMethods(array('pushProcessor')) + ->getMock(); + + $mockHandler->expects($this->exactly(sizeof($processorsArray))) + ->method('pushProcessor') + ->withConsecutive(array($mockProcessor2), array($mockProcessor1)); + + new HandlerLoader($options); + $closure = $this->getHandler('*', 'processors'); + $closure($mockHandler, $processorsArray); + } } diff --git a/tests/ConfigTest.php b/tests/ConfigTest.php index 3829fe3..d3570d5 100644 --- a/tests/ConfigTest.php +++ b/tests/ConfigTest.php @@ -61,15 +61,15 @@ public function testConfigure() ->setConstructorArgs(array($options, $configLoader)) ->setMethods(array( 'configureFormatters', - 'configureHandlers', 'configureProcessors', + 'configureHandlers', 'configureLoggers' )) ->getMock(); $config->expects($this->once())->method('configureFormatters'); - $config->expects($this->once())->method('configureHandlers'); $config->expects($this->once())->method('configureProcessors'); + $config->expects($this->once())->method('configureHandlers'); $config->expects($this->once())->method('configureLoggers'); $config->load();