diff --git a/autoload.php.dist b/autoload.php.dist
index fea397bb8ad16..6abb60cf2e783 100644
--- a/autoload.php.dist
+++ b/autoload.php.dist
@@ -16,6 +16,7 @@ $loader->registerNamespaces(array(
'Doctrine' => __DIR__.'/vendor/doctrine/lib',
'Zend' => __DIR__.'/vendor/zend/library',
'Assetic' => __DIR__.'/vendor/assetic/src',
+ 'Monolog' => __DIR__.'/vendor/monolog/src',
));
$loader->registerPrefixes(array(
'Swift_' => __DIR__.'/vendor/swiftmailer/lib/classes',
diff --git a/src/Symfony/Bundle/DoctrineBundle/Resources/config/dbal.xml b/src/Symfony/Bundle/DoctrineBundle/Resources/config/dbal.xml
index e72d8a10d470b..87914fb0f4ebb 100644
--- a/src/Symfony/Bundle/DoctrineBundle/Resources/config/dbal.xml
+++ b/src/Symfony/Bundle/DoctrineBundle/Resources/config/dbal.xml
@@ -21,6 +21,7 @@
+
diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/config/mongodb.xml b/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/config/mongodb.xml
index 296f54b1615f0..a7ea41f4f8393 100755
--- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/config/mongodb.xml
+++ b/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/config/mongodb.xml
@@ -86,6 +86,7 @@
+
@@ -114,6 +115,6 @@
-
+
\ No newline at end of file
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.xml
index 0042e549f0c30..1dc3159cd8e51 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.xml
@@ -37,6 +37,7 @@
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.xml
index f3556df5098db..102540da5c896 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.xml
@@ -10,6 +10,7 @@
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml
index 72794e98ff23d..c93ed32fb5822 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml
@@ -15,6 +15,7 @@
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml
index 89595deab2f95..1a504a89342b0 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml
@@ -48,6 +48,7 @@
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_debug.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_debug.xml
index a47d287838b9c..006bd0b3280e0 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_debug.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_debug.xml
@@ -10,6 +10,7 @@
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml
index 580bff67644a7..07cce83d6b724 100755
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml
@@ -15,11 +15,13 @@
+
+
@@ -27,6 +29,7 @@
+
@@ -38,6 +41,7 @@
+
%exception_listener.controller%
diff --git a/src/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/DebugHandlerPass.php b/src/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/DebugHandlerPass.php
new file mode 100644
index 0000000000000..f14eb02e5b8bc
--- /dev/null
+++ b/src/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/DebugHandlerPass.php
@@ -0,0 +1,39 @@
+
+ *
+ * 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\Reference;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\Definition;
+use Monolog\Logger;
+
+/**
+ * Replaces the default logger by another one with its own channel for tagged services.
+ *
+ * @author Christophe Coevoet
+ */
+class DebugHandlerPass implements CompilerPassInterface
+{
+ protected $channels = array();
+
+ public function process(ContainerBuilder $container)
+ {
+ if (!$container->hasDefinition('monolog.logger_prototype') || !$container->hasDefinition('profiler')) {
+ return;
+ }
+
+ $debugHandler = new Definition('%monolog.handler.debug.class%', array(Logger::DEBUG, true));
+ $container->setDefinition('monolog.handler.debug', $debugHandler);
+ $container->getDefinition('monolog.logger_prototype')->addMethodCall('pushHandler', array (new Reference('monolog.handler.debug')));
+ }
+}
diff --git a/src/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/LoggerChannelPass.php b/src/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/LoggerChannelPass.php
new file mode 100644
index 0000000000000..c0bb7cd4ccae2
--- /dev/null
+++ b/src/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/LoggerChannelPass.php
@@ -0,0 +1,59 @@
+
+ *
+ * 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\Reference;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\DefinitionDecorator;
+
+/**
+ * Replaces the default logger by another one with its own channel for tagged services.
+ *
+ * @author Christophe Coevoet
+ */
+class LoggerChannelPass implements CompilerPassInterface
+{
+ protected $channels = array();
+
+ public function process(ContainerBuilder $container)
+ {
+ if (false === $container->hasDefinition('monolog.logger')) {
+ return;
+ }
+
+ foreach ($container->findTaggedServiceIds('monolog.logger') as $id => $tags) {
+ foreach ($tags as $tag) {
+ if (!empty ($tag['channel']) && 'app' !== $tag['channel']) {
+ $definition = $container->getDefinition($id);
+ $loggerId = sprintf('monolog.logger.%s', $tag['channel']);
+ $this->createLogger($tag['channel'], $loggerId, $container);
+ foreach ($definition->getArguments() as $index => $argument) {
+ if ($argument instanceof Reference && 'logger' === (string) $argument) {
+ $definition->setArgument($index, new Reference($loggerId, $argument->getInvalidBehavior(), $argument->isStrict()));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ protected function createLogger($channel, $loggerId, ContainerBuilder $container)
+ {
+ if (!in_array($channel, $this->channels)) {
+ $logger = new DefinitionDecorator('monolog.logger_prototype');
+ $logger->setArgument(0, $channel);
+ $container->setDefinition($loggerId, $logger);
+ array_push($this->channels, $channel);
+ }
+ }
+}
diff --git a/src/Symfony/Bundle/MonologBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/MonologBundle/DependencyInjection/Configuration.php
new file mode 100644
index 0000000000000..128f2a167bc31
--- /dev/null
+++ b/src/Symfony/Bundle/MonologBundle/DependencyInjection/Configuration.php
@@ -0,0 +1,82 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\MonologBundle\DependencyInjection;
+
+use Symfony\Component\Config\Definition\Builder\NodeBuilder;
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+
+/**
+ * This class contains the configuration information for the bundle
+ *
+ * This information is solely responsible for how the different configuration
+ * sections are normalized, and merged.
+ *
+ * @author Jordi Boggiano
+ */
+class Configuration
+{
+ /**
+ * Generates the configuration tree.
+ *
+ * @return \Symfony\Component\Config\Definition\NodeInterface
+ */
+ public function getConfigTree()
+ {
+ $treeBuilder = new TreeBuilder();
+ $rootNode = $treeBuilder->root('monolog', 'array');
+
+ $handlersPrototype = $rootNode
+ ->fixXmlConfig('handler')
+ ->arrayNode('handlers')
+ ->canBeUnset()
+ ->performNoDeepMerging()
+ ->useAttributeAsKey('name')
+ ->prototype('array')
+ ->scalarNode('action_level')->end() // fingerscrossed specific
+ ->scalarNode('buffer_size')->end() // fingerscrossed specific
+ ->builder($this->getHandlerSubnode())
+ ->validate()
+ ->ifTrue(function($v) { return 'fingerscrossed' === $v['type'] && !isset($v['handler']); })
+ ->thenInvalid('The handler has to be specified to use a FingersCrossedHandler')
+ ->end()
+ ;
+ $this->addHandlerSection($handlersPrototype);
+
+ return $treeBuilder->buildTree();
+ }
+
+ private function addHandlerSection(NodeBuilder $node)
+ {
+ $node
+ ->performNoDeepMerging()
+ ->scalarNode('type')
+ ->isRequired()
+ ->treatNullLike('null')
+ ->beforeNormalization()
+ ->always()
+ ->then(function($v) { return strtolower($v); })
+ ->end()
+ ->end()
+ ->scalarNode('level')->defaultValue('DEBUG')->end()
+ ->booleanNode('bubble')->defaultFalse()->end()
+ ->scalarNode('path')->end() // stream specific
+ ;
+ }
+
+ private function getHandlerSubnode()
+ {
+ $node = new NodeBuilder('handler', 'array');
+ $this->addHandlerSection($node);
+
+ return $node;
+ }
+}
diff --git a/src/Symfony/Bundle/MonologBundle/DependencyInjection/MonologExtension.php b/src/Symfony/Bundle/MonologBundle/DependencyInjection/MonologExtension.php
new file mode 100644
index 0000000000000..c66e783684bf1
--- /dev/null
+++ b/src/Symfony/Bundle/MonologBundle/DependencyInjection/MonologExtension.php
@@ -0,0 +1,130 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\MonologBundle\DependencyInjection;
+
+use Symfony\Component\HttpKernel\DependencyInjection\Extension;
+use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\Config\Definition\Processor;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\DependencyInjection\Parameter;
+
+/**
+ * MonologExtension is an extension for the Monolog library.
+ *
+ * @author Jordi Boggiano
+ */
+class MonologExtension extends Extension
+{
+ /**
+ * Loads the Monolog configuration.
+ *
+ * Usage example:
+ *
+ * monolog:
+ * handlers:
+ * myhandler:
+ * level: info
+ * path: path/to/some.log
+ *
+ * @param array $config An array of configuration settings
+ * @param ContainerBuilder $container A ContainerBuilder instance
+ */
+ public function load(array $configs, ContainerBuilder $container)
+ {
+ $configuration = new Configuration();
+ $processor = new Processor();
+ $config = $processor->process($configuration->getConfigTree(), $configs);
+
+ if (isset($config['handlers'])) {
+ $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
+ $loader->load('monolog.xml');
+ $container->setAlias('logger', 'monolog.logger');
+
+ $logger = $container->getDefinition('monolog.logger_prototype');
+
+ $handlers = array();
+ foreach ($config['handlers'] as $name => $handler) {
+ $handlers[] = $this->buildHandler($container, $name, $handler);
+ }
+
+ // TODO somehow the DebugLogger should be pushed on the stack as well, or that concept needs to be changed
+ // didn't have to investigate yet what it is exactly
+ $handlers = array_reverse($handlers);
+ foreach ($handlers as $handler) {
+ $logger->addMethodCall('pushHandler', array(new Reference($handler)));
+ }
+ }
+ }
+
+ public function buildHandler(ContainerBuilder $container, $name, array $handler)
+ {
+ $handlerId = sprintf('monolog.handler.%s', $name);
+ $definition = new Definition(sprintf('%%monolog.handler.%s.class%%', $handler['type']));
+ $handler['level'] = is_int($handler['level']) ? $handler['level'] : constant('Monolog\Logger::'.strtoupper($handler['level']));
+
+ switch ($handler['type']) {
+ case 'stream':
+ if (!isset($handler['path'])) {
+ $handler['path'] = '%kernel.logs_dir%/%kernel.environment%.log';
+ }
+
+ $definition->setArguments(array(
+ $handler['path'],
+ $handler['level'],
+ $handler['bubble'],
+ ));
+ break;
+
+ case 'fingerscrossed':
+ if (!isset($handler['action_level'])) {
+ $handler['action_level'] = 'WARNING';
+ }
+ $handler['action_level'] = is_int($handler['action_level']) ? $handler['action_level'] : constant('Monolog\Logger::'.strtoupper($handler['action_level']));
+
+ $definition->setArguments(array(
+ $this->buildHandler($container, $handler['handler']),
+ $handler['action_level'],
+ isset($handler['buffer_size']) ? $handler['buffer_size'] : 0,
+ $handler['bubble'],
+ ));
+ break;
+ default:
+ // Handler using the constructor of AbstractHandler without adding their own arguments
+ $definition->setArguments(array(
+ $handler['level'],
+ $handler['bubble'],
+ ));
+ break;
+ }
+ $container->setDefinition($handlerId, $definition);
+
+ return $handlerId;
+ }
+
+ /**
+ * Returns the base path for the XSD files.
+ *
+ * @return string The XSD base path
+ */
+ public function getXsdValidationBasePath()
+ {
+ return __DIR__.'/../Resources/config/schema';
+ }
+
+ public function getNamespace()
+ {
+ return 'http://www.symfony-project.org/schema/dic/monolog';
+ }
+}
diff --git a/src/Symfony/Bundle/MonologBundle/Logger/DebugHandler.php b/src/Symfony/Bundle/MonologBundle/Logger/DebugHandler.php
new file mode 100644
index 0000000000000..843dd93ebe35d
--- /dev/null
+++ b/src/Symfony/Bundle/MonologBundle/Logger/DebugHandler.php
@@ -0,0 +1,50 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\MonologBundle\Logger;
+
+use Monolog\Handler\TestHandler;
+use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
+
+/**
+ * DebugLogger.
+ *
+ * @author Jordi Boggiano
+ */
+class DebugHandler extends TestHandler implements DebugLoggerInterface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function getLogs()
+ {
+ $records = array();
+ foreach ($this->records as $record) {
+ $records[] = array(
+ 'timestamp' => $record['datetime']->getTimestamp(),
+ 'message' => $record['message'],
+ 'priority' => $record['level'],
+ 'priorityName' => $record['level_name'],
+ );
+ }
+ return $records;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function countErrors()
+ {
+ return isset($this->recordsByLevel[\Monolog\Logger::ERROR])
+ ? count($this->recordsByLevel[\Monolog\Logger::ERROR])
+ : 0;
+ }
+}
diff --git a/src/Symfony/Bundle/MonologBundle/Logger/Logger.php b/src/Symfony/Bundle/MonologBundle/Logger/Logger.php
new file mode 100644
index 0000000000000..814cad02731ac
--- /dev/null
+++ b/src/Symfony/Bundle/MonologBundle/Logger/Logger.php
@@ -0,0 +1,43 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\MonologBundle\Logger;
+
+use Monolog\Logger as BaseLogger;
+use Symfony\Component\HttpKernel\Log\LoggerInterface;
+use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
+
+/**
+ * Logger.
+ *
+ * @author Fabien Potencier
+ */
+class Logger extends BaseLogger implements LoggerInterface
+{
+ /**
+ * Returns a DebugLoggerInterface instance if one is registered with this logger.
+ *
+ * @return DebugLoggerInterface A DebugLoggerInterface instance or null if none is registered
+ */
+ public function getDebugLogger()
+ {
+ foreach ($this->handlers as $handler) {
+ if ($handler instanceof DebugLoggerInterface) {
+ return $handler;
+ }
+ }
+ }
+
+ public function log($message, $level)
+ {
+ return $this->addRecord($level, $message);
+ }
+}
diff --git a/src/Symfony/Bundle/MonologBundle/MonologBundle.php b/src/Symfony/Bundle/MonologBundle/MonologBundle.php
new file mode 100644
index 0000000000000..4cacd3cb1da73
--- /dev/null
+++ b/src/Symfony/Bundle/MonologBundle/MonologBundle.php
@@ -0,0 +1,33 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\MonologBundle;
+
+use Symfony\Component\HttpKernel\Bundle\Bundle;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\LoggerChannelPass;
+use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\DebugHandlerPass;
+
+/**
+ * Bundle.
+ *
+ * @author Jordi Boggiano
+ */
+class MonologBundle extends Bundle
+{
+ public function build(ContainerBuilder $container)
+ {
+ parent::build($container);
+
+ $container->addCompilerPass(new LoggerChannelPass());
+ $container->addCompilerPass(new DebugHandlerPass());
+ }
+}
diff --git a/src/Symfony/Bundle/MonologBundle/Resources/config/monolog.xml b/src/Symfony/Bundle/MonologBundle/Resources/config/monolog.xml
new file mode 100644
index 0000000000000..645fc164941b3
--- /dev/null
+++ b/src/Symfony/Bundle/MonologBundle/Resources/config/monolog.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+ Symfony\Bundle\MonologBundle\Logger\Logger
+ Monolog\Handler\StreamHandler
+ Monolog\Handler\FingersCrossedHandler
+ Monolog\Handler\NullHandler
+ Monolog\Handler\TestHandler
+ Symfony\Bundle\MonologBundle\Logger\DebugHandler
+
+
+
+
+ app
+
+
+
+
+
+
diff --git a/src/Symfony/Bundle/MonologBundle/Resources/config/schema/monolog-1.0.xsd b/src/Symfony/Bundle/MonologBundle/Resources/config/schema/monolog-1.0.xsd
new file mode 100644
index 0000000000000..22b646be95af5
--- /dev/null
+++ b/src/Symfony/Bundle/MonologBundle/Resources/config/schema/monolog-1.0.xsd
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Compiler/LoggerChannelPassTest.php b/src/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Compiler/LoggerChannelPassTest.php
new file mode 100644
index 0000000000000..7e2b9558fe11a
--- /dev/null
+++ b/src/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Compiler/LoggerChannelPassTest.php
@@ -0,0 +1,54 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\MonologBundle\Tests\DependencyInjection\Compiler;
+
+use Symfony\Bundle\MonologBundle\Tests\TestCase;
+use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\LoggerChannelPass;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
+
+class LoggerChannelPassTest extends TestCase
+{
+ public function testProcess()
+ {
+ $container = $this->getContainer();
+ $this->assertTrue($container->hasDefinition('monolog.logger.test'), '->process adds a logger service for tagged service');
+
+ $service = $container->getDefinition('test');
+ $arguments = $service->getArguments();
+ $this->assertEquals('monolog.logger.test', (string) $arguments[1], '->process replaces the logger by the new one');
+ }
+
+ protected function getContainer()
+ {
+ $container = new ContainerBuilder();
+ $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../../../Resources/config'));
+ $loader->load('monolog.xml');
+ $definition = $container->getDefinition('monolog.logger_prototype');
+ $container->set('monolog.handler.test', new Definition('%monolog.handler.null.class%', array (100, false)));
+ $definition->addMethodCall('pushHandler', array(new Reference('monolog.handler.test')));
+
+ $service = new Definition('TestClass', array('false', new Reference('logger')));
+ $service->addTag('monolog.logger', array ('channel' => 'test'));
+ $container->setDefinition('test', $service);
+
+ $container->getCompilerPassConfig()->setOptimizationPasses(array());
+ $container->getCompilerPassConfig()->setRemovingPasses(array());
+ $container->addCompilerPass(new LoggerChannelPass());
+ $container->compile();
+
+ return $container;
+ }
+}
diff --git a/src/Symfony/Bundle/MonologBundle/Tests/TestCase.php b/src/Symfony/Bundle/MonologBundle/Tests/TestCase.php
new file mode 100644
index 0000000000000..4d31cb712f783
--- /dev/null
+++ b/src/Symfony/Bundle/MonologBundle/Tests/TestCase.php
@@ -0,0 +1,22 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\MonologBundle\Tests;
+
+class TestCase extends \PHPUnit_Framework_TestCase
+{
+ protected function setUp()
+ {
+ if (!class_exists('Monolog\Logger')) {
+ $this->markTestSkipped('Monolog is not available.');
+ }
+ }
+}
diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl.xml
index 92736ba14a90a..74cc94babb685 100644
--- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl.xml
+++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl.xml
@@ -60,7 +60,7 @@
-
+
%security.acl.cache.doctrine.prefix%
@@ -69,6 +69,7 @@
+
diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml
index 9c1de812bc97a..e11c9edb6756d 100644
--- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml
+++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml
@@ -26,7 +26,7 @@
SSL_CLIENT_S_DN
Symfony\Component\Security\Http\Firewall\AnonymousAuthenticationListener
-
+
Symfony\Component\Security\Http\Firewall\SwitchUserListener
Symfony\Component\Security\Http\Firewall\LogoutListener
@@ -44,9 +44,10 @@
Symfony\Component\Security\Core\Authentication\Provider\AnonymousAuthenticationProvider
SomeRandomValue
-
+
+
%security.anonymous.key%
@@ -68,6 +69,7 @@
+
@@ -76,6 +78,7 @@
+
@@ -94,6 +97,7 @@
+
@@ -104,13 +108,14 @@
-
+
@@ -120,6 +125,7 @@
+
@@ -128,26 +134,28 @@
+
-
+
-
+
-
+
+
@@ -157,6 +165,7 @@
+
@@ -166,6 +175,7 @@
+
diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_rememberme.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_rememberme.xml
index 2d3f8583f2ef7..5c06caaecdea5 100644
--- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_rememberme.xml
+++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_rememberme.xml
@@ -6,47 +6,49 @@
Symfony\Component\Security\Core\Authentication\Provider\RememberMeAuthenticationProvider
-
+
Symfony\Component\Security\Http\Firewall\RememberMeListener
Symfony\Component\Security\Core\Authentication\RememberMe\InMemoryTokenProvider
-
+
Symfony\Component\Security\Http\RememberMe\PersistentTokenBasedRememberMeServices
Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices
-
+
+
-
+
-
+
+
-
-
-
-
-
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/vendors.sh b/vendors.sh
index 7080580524a06..f948d78767c34 100755
--- a/vendors.sh
+++ b/vendors.sh
@@ -58,6 +58,9 @@ install_git doctrine-mongodb git://github.com/doctrine/mongodb.git
# Doctrine MongoDB
install_git doctrine-mongodb-odm git://github.com/doctrine/mongodb-odm.git
+# Monolog
+install_git monolog git://github.com/Seldaek/monolog.git
+
# Swiftmailer
install_git swiftmailer git://github.com/swiftmailer/swiftmailer.git origin/4.1