Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for configurable wrapped handlers #49

Merged
merged 2 commits into from
Feb 18, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ If some parameters are not present in the constructor, they will be treated as e
- `class` (optional): classname of the handler you would like to use
- `formatter` (optional): formatter identifier that you have defined
- `processors` (optional): array of processor identifiers that you have defined
- `handlers` (optional): array of handler identifiers that you have defined
- `handler` (optional): single handler identifier that you have defined

Other parameters will be interpreted as constructor parameters for that Handler class and passed in when the handler object is instantiated by the Cascade config loader.<br />
If some parameters are not present in the constructor, they will be interpreted as extra parameters and Cascade will try to interpret them should they match any custom handler functions that are able to use them. (see [Extra Parameters](#user-content-extra-parameters-other-than-constructors) section below)
Expand Down
2 changes: 1 addition & 1 deletion src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -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, $this->processors);
$handlerLoader = new HandlerLoader($handlerOptions, $this->formatters, $this->processors, $this->handlers);
$this->handlers[$handlerId] = $handlerLoader->load();
}
}
Expand Down
51 changes: 50 additions & 1 deletion src/Config/Loader/ClassLoader/HandlerLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,17 @@ 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
* @param callable[] $handlers Array of handlers to pick from
*/
public function __construct(
array &$handlerOptions,
array $formatters = array(),
array $processors = array()
array $processors = array(),
array $handlers = array()
) {
$this->populateFormatters($handlerOptions, $formatters);
$this->populateProcessors($handlerOptions, $processors);
$this->populateHandlers($handlerOptions, $handlers);
parent::__construct($handlerOptions);

self::initExtraOptionsHandlers();
Expand Down Expand Up @@ -109,6 +112,52 @@ private function populateProcessors(array &$handlerOptions, array $processors)
}
}

/**
* Replace the handler or handlers in the option array with the corresponding callable(s) from the
* array of loaded and callable handlers, if they exist.
*
* @throws \InvalidArgumentException
*
* @param array &$handlerOptions Handler options
* @param callable[] $handlers Array of handlers to pick from
*/
private function populateHandlers(array &$handlerOptions, array $handlers)
{
$handlerArray = array();

if (isset($handlerOptions['handlers'])) {
foreach ($handlerOptions['handlers'] as $handlerId) {
if (isset($handlers[$handlerId])) {
$handlerArray[] = $handlers[$handlerId];
} else {
throw new \InvalidArgumentException(
sprintf(
'Cannot add handler "%s" to the handler. Handler not found.',
$handlerId
)
);
}
}

$handlerOptions['handlers'] = $handlerArray;
}

if (isset($handlerOptions['handler'])) {
$handlerId = $handlerOptions['handler'];

if (isset($handlers[$handlerId])) {
$handlerOptions['handler'] = $handlers[$handlerId];
} else {
throw new \InvalidArgumentException(
sprintf(
'Cannot add handler "%s" to the handler. Handler not found.',
$handlerId
)
);
}
}
}

/**
* Loads the closures as option handlers. Add handlers to this function if
* you want to support additional custom options.
Expand Down
28 changes: 28 additions & 0 deletions tests/Config/Loader/ClassLoader/HandlerLoaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -218,4 +218,32 @@ public function testHandlerForProcessor()
$closure = $this->getHandler('*', 'processors');
$closure($mockHandler, $processorsArray);
}

public function testReplacesHandlerNamesInOptionsArrayWithLoadedCallable()
{
$options = [
'handlers' => [
'foo',
'bar',
],
'handler' => 'baz'
];
$handlers = [
'foo' => function () {
return 'foo';
},
'bar' => function () {
return 'bar';
},
'baz' => function () {
return 'baz';
},
];

$loader = new HandlerLoader($options, [], [], $handlers);

$this->assertSame($handlers['foo'], $options['handlers'][0]);
$this->assertSame($handlers['bar'], $options['handlers'][1]);
$this->assertSame($handlers['baz'], $options['handler']);
}
}
15 changes: 14 additions & 1 deletion tests/Fixtures/fixture_config.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,20 @@
'level' => 'ERROR',
'stream' => './demo_error.log',
'formatter' => 'spaced'
)
),

'group_handler' => array(
'class' => 'Monolog\Handler\GroupHandler',
'handlers' => [
'console',
'info_file_handler',
],
),

'fingers_crossed_handler' => array(
'class' => 'Monolog\Handler\FingersCrossedHandler',
'handler' => 'group_handler',
),
),
'processors' => array(
'tag_processor' => array(
Expand Down