Skip to content
Browse files

merged branch stof/monolog (PR #1556)

Commits
-------

f8b5f35 [MonologBundle] Refactored the way to configure the email prototype for swiftmailer
874fb95 [MonologBundle] Refactored the configuration of processors

Discussion
----------

Monolog

This refactors the way processors and email prototype are configured in MonologBundle for consistency with the other bundles. The hack using ``@id`` to use a service in the semantic configuration is not used anywhere else in Symfony2.
This removes the ability to use a static callback as processor (or a PHP function) but adds the support of adding a processor only for a given logging channel (for processors attached to the logger) which was not possible previously.

---------------------------------------------------------------------------

by stof at 2011/07/06 07:33:52 -0700

the PR for the doc and the standard edition are coming.
  • Loading branch information...
2 parents 722ad12 + f8b5f35 commit 498f72ce9c18397cddaaa63a37f56bf376abe1b5 @fabpot fabpot committed Jul 6, 2011
View
25 UPDATE.md
@@ -12,6 +12,31 @@ RC4 to RC5
* Removed the guesser for the Choice constraint as the constraint only knows
about the valid keys, and not their values.
+* The configuration of MonologBundle has been refactored.
+
+ * Only services are supported for the processors. They are now registered
+ using the `monolog.processor` tag which accept three optionnal attributes:
+
+ * `handler`: the name of an handler to register it only for a specific handler
+ * `channel`: to register it only for one logging channel (exclusive with `handler`)
+ * `method`: The method used to process the record (`__invoke` is used if not set)
+
+ * The email_prototype for the `SwiftMailerHandler` only accept a service id now.
+
+ * Before:
+
+ email_prototype: @acme_demo.monolog.email_prototype
+
+ * After:
+
+ email_prototype: acme_demo.monolog.email_prototype
+
+ or if you want to use a factory for the prototype:
+
+ email_prototype:
+ id: acme_demo.monolog.email_prototype
+ method: getPrototype
+
* To avoid security issues, HTTP headers coming from proxies are not trusted
anymore by default (like `HTTP_X_FORWARDED_FOR`, `X_FORWARDED_PROTO`, and
`X_FORWARDED_HOST`). If your application is behind a reverse proxy, add the
View
59 src/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/AddProcessorsPass.php
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\MonologBundle\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Registers processors in Monolg loggers or handlers.
+ *
+ * @author Christophe Coevoet <stof@notk.org>
+ */
+class AddProcessorsPass implements CompilerPassInterface
+{
+ public function process(ContainerBuilder $container)
+ {
+ if (!$container->hasDefinition('monolog.logger')) {
+ return;
+ }
+
+ foreach ($container->findTaggedServiceIds('monolog.processor') as $id => $tags) {
+ foreach ($tags as $tag) {
+ if (!empty($tag['channel']) && !empty($tag['handler'])) {
+ throw new \InvalidArgumentException(sprintf('you cannot specify both the "handler" and "channel" attributes for the "monolog.processor" tag on service "%s"', $id));
+ }
+
+ if (!empty($tag['handler'])) {
+ $definition = $container->getDefinition(sprintf('monolog.handler.%s', $tag['handler']));
+ } elseif (!empty($tag['channel'])) {
+ if ('app' === $tag['channel']) {
+ $definition = $container->getDefinition('monolog.logger');
+ } else {
+ $definition = $container->getDefinition(sprintf('monolog.logger.%s', $tag['channel']));
+ }
+ } else {
+ $definition = $container->getDefinition('monolog.logger_prototype');
+ }
+
+ if (!empty($tag['method'])) {
+ $processor = array(new Reference($id), $tag['method']);
+ } else {
+ // If no method is defined, fallback to use __invoke
+ $processor = new Reference($id);
+ }
+ $definition->addMethodCall('pushProcessor', array($processor));
+ }
+ }
+ }
+}
View
29 src/Symfony/Bundle/MonologBundle/DependencyInjection/Configuration.php
@@ -37,7 +37,6 @@ public function getConfigTreeBuilder()
$rootNode
->fixXmlConfig('handler')
- ->fixXmlConfig('processor')
->children()
->arrayNode('handlers')
->canBeUnset()
@@ -74,10 +73,19 @@ public function getConfigTreeBuilder()
->scalarNode('from_email')->end() // swift_mailer and native_mailer
->scalarNode('to_email')->end() // swift_mailer and native_mailer
->scalarNode('subject')->end() // swift_mailer and native_mailer
- ->scalarNode('email_prototype')->end() // swift_mailer
+ ->arrayNode('email_prototype') // swift_mailer
+ ->canBeUnset()
+ ->beforeNormalization()
+ ->ifString()
+ ->then(function($v) { return array('id' => $v); })
+ ->end()
+ ->children()
+ ->scalarNode('id')->isRequired()->end()
+ ->scalarNode('factory-method')->defaultNull()->end()
+ ->end()
+ ->end()
->scalarNode('formatter')->end()
->end()
- ->append($this->getProcessorsNode())
->validate()
->ifTrue(function($v) { return ('fingers_crossed' === $v['type'] || 'buffer' === $v['type']) && 1 !== count($v['handler']); })
->thenInvalid('The handler has to be specified to use a FingersCrossedHandler or BufferHandler')
@@ -101,23 +109,8 @@ public function getConfigTreeBuilder()
->end()
->end()
->end()
- ->append($this->getProcessorsNode())
;
return $treeBuilder;
}
-
- private function getProcessorsNode()
- {
- $treeBuilder = new TreeBuilder();
- $node = $treeBuilder->root('processors');
-
- $node
- ->canBeUnset()
- ->performNoDeepMerging()
- ->prototype('scalar')->end()
- ;
-
- return $node;
- }
}
View
34 src/Symfony/Bundle/MonologBundle/DependencyInjection/MonologExtension.php
@@ -49,10 +49,6 @@ public function load(array $configs, ContainerBuilder $container)
$logger = $container->getDefinition('monolog.logger_prototype');
- if (!empty($config['processors'])) {
- $this->addProcessors($container, $logger, $config['processors']);
- }
-
$handlers = array();
foreach ($config['handlers'] as $name => $handler) {
$handlers[] = array('id' => $this->buildHandler($container, $name, $handler), 'priority' => $handler['priority'] );
@@ -190,7 +186,11 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler
case 'swift_mailer':
if (isset($handler['email_prototype'])) {
- $prototype = $this->parseDefinition($handler['email_prototype']);
+ if (!empty($handler['email_prototype']['method'])) {
+ $prototype = array(new Reference($handler['email_prototype']['id']), $handler['email_prototype']['method']);
+ } else {
+ $prototype = new Reference($handler['email_prototype']['id']);
+ }
} else {
$message = new Definition('Swift_Message');
$message->setFactoryService('mailer');
@@ -238,9 +238,6 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler
if (!empty($handler['formatter'])) {
$definition->addMethodCall('setFormatter', array(new Reference($handler['formatter'])));
}
- if (!empty($handler['processors'])) {
- $this->addProcessors($container, $definition, $handler['processors']);
- }
$container->setDefinition($handlerId, $definition);
return $handlerId;
@@ -250,25 +247,4 @@ private function getHandlerId($name)
{
return sprintf('monolog.handler.%s', $name);
}
-
- private function addProcessors(ContainerBuilder $container, Definition $definition, array $processors)
- {
- foreach (array_reverse($processors) as $processor) {
- $definition->addMethodCall('pushProcessor', array($this->parseDefinition($processor, $container)));
- }
- }
-
- private function parseDefinition($definition, ContainerBuilder $container = null)
- {
- if (0 === strpos($definition, '@')) {
- $definition = substr($definition, 1);
- if ($container && $container->hasDefinition($definition)) {
- $container->getDefinition($definition)->setPublic(true);
- }
-
- return new Reference($definition);
- }
-
- return $definition;
- }
}
View
2 src/Symfony/Bundle/MonologBundle/MonologBundle.php
@@ -15,6 +15,7 @@
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\LoggerChannelPass;
use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\DebugHandlerPass;
+use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\AddProcessorsPass;
/**
* Bundle.
@@ -29,5 +30,6 @@ public function build(ContainerBuilder $container)
$container->addCompilerPass(new LoggerChannelPass());
$container->addCompilerPass(new DebugHandlerPass());
+ $container->addCompilerPass(new AddProcessorsPass());
}
}
View
8 src/Symfony/Bundle/MonologBundle/Resources/config/monolog.xml
@@ -18,8 +18,6 @@
<parameter key="monolog.handler.debug.class">Symfony\Bridge\Monolog\Handler\DebugHandler</parameter>
<parameter key="monolog.handler.swift_mailer.class">Monolog\Handler\SwiftMailerHandler</parameter>
<parameter key="monolog.handler.native_mailer.class">Monolog\Handler\NativeMailerHandler</parameter>
- <parameter key="monolog.processor.web.class">Symfony\Bridge\Monolog\Processor\WebProcessor</parameter>
- <parameter key="monolog.processor.introspection.class">Monolog\Processor\IntrospectionProcessor</parameter>
</parameters>
<services>
@@ -32,11 +30,5 @@
<service id="monolog.logger_prototype" class="%monolog.logger.class%" abstract="true">
<argument /><!-- Channel -->
</service>
-
- <service id="monolog.processor.web" class="%monolog.processor.web.class%" scope="request" public="false">
- <argument type="service" id="request" />
- </service>
-
- <service id="monolog.processor.introspection" class="%monolog.processor.introspection.class%" public="false" />
</services>
</container>
View
11 src/Symfony/Bundle/MonologBundle/Resources/config/schema/monolog-1.0.xsd
@@ -10,16 +10,15 @@
<xsd:complexType name="config">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="handler" type="handler" />
- <xsd:element name="processor" type="xsd:string" />
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="handler">
<xsd:sequence>
- <xsd:element name="processor" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="email-prototype" type="email-prototype" minOccurs="0" maxOccurs="1" />
<xsd:element name="member" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
- <xsd:attribute name="type" type="xsd:string" use="required" />
+ <xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="priority" type="xsd:integer" />
<xsd:attribute name="level" type="level" />
<xsd:attribute name="bubble" type="xsd:boolean" />
@@ -35,7 +34,6 @@
<xsd:attribute name="from-email" type="xsd:string" />
<xsd:attribute name="to-email" type="xsd:string" />
<xsd:attribute name="subject" type="xsd:string" />
- <xsd:attribute name="email-prototype" type="xsd:string" />
<xsd:attribute name="formatter" type="xsd:string" />
</xsd:complexType>
@@ -56,4 +54,9 @@
<xsd:enumeration value="550" />
</xsd:restriction>
</xsd:simpleType>
+
+ <xsd:complexType name="email-prototype">
+ <xsd:attribute name="id" type="xsd:string" />
+ <xsd:attribute name="method" type="xsd:string" />
+ </xsd:complexType>
</xsd:schema>
View
15 src/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/MonologExtensionTest.php
@@ -35,21 +35,6 @@ public function testLoadWithDefault()
$this->assertDICConstructorArguments($handler, array('%kernel.logs_dir%/%kernel.environment%.log', \Monolog\Logger::DEBUG, true));
}
- public function testLoadWithProcessor()
- {
- $container = new ContainerBuilder();
- $loader = new MonologExtension();
-
- $loader->load(array(array('handlers' => array('main' => array('type' => 'stream', 'processors' => array('@monolog.processor.web'))))), $container);
- $this->assertTrue($container->hasDefinition('monolog.handler.main'));
-
- $handler = $container->getDefinition('monolog.handler.main');
- $this->assertDICDefinitionMethodCallAt(0, $handler, 'pushProcessor', array(new Reference('monolog.processor.web')));
-
- $this->assertTrue($container->getDefinition('monolog.processor.web')->isPublic());
- $this->assertFalse($container->getDefinition('monolog.processor.introspection')->isPublic());
- }
-
public function testLoadWithCustomValues()
{
$container = new ContainerBuilder();

0 comments on commit 498f72c

Please sign in to comment.
Something went wrong with that request. Please try again.