diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.xml
index 85cced76d5dad..875c556574be8 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.xml
@@ -32,5 +32,12 @@
deprecation
+
+
+
+
+ scream
+
+
diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig
index 8f88c4dfcb8f6..07e10f8bc409f 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig
+++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig
@@ -3,16 +3,16 @@
{% import _self as logger %}
{% block toolbar %}
- {% if collector.counterrors or collector.countdeprecations %}
+ {% if collector.counterrors or collector.countdeprecations or collector.countscreams %}
{% set icon %}
{% if collector.counterrors %}
{% set status_color = "red" %}
- {% else %}
+ {% elseif collector.countdeprecations %}
{% set status_color = "yellow" %}
{% endif %}
- {% set error_count = collector.counterrors + collector.countdeprecations %}
- {{ error_count }}
+ {% set error_count = collector.counterrors + collector.countdeprecations + collector.countscreams %}
+ {{ error_count }}
{% endset %}
{% set text %}
{% if collector.counterrors %}
@@ -27,6 +27,12 @@
{{ collector.countdeprecations }}
{% endif %}
+ {% if collector.countscreams %}
+
+ Silenced Errors
+ {{ collector.countscreams }}
+
+ {% endif %}
{% endset %}
{% include '@WebProfiler/Profiler/toolbar_item.html.twig' with { 'link': profiler_url } %}
{% endif %}
@@ -36,8 +42,8 @@
Logs
- {% if collector.counterrors or collector.countdeprecations %}
- {% set error_count = collector.counterrors + collector.countdeprecations %}
+ {% if collector.counterrors or collector.countdeprecations or collector.countscreams %}
+ {% set error_count = collector.counterrors + collector.countdeprecations + collector.countscreams %}
{{ error_count }}
@@ -74,7 +80,7 @@
{% if collector.logs %}
{% for log in collector.logs if priority >= 0 and log.priority >= priority or priority < 0 and log.context.type|default(0) == priority %}
- -
+
-
{{ logger.display_message(loop.index, log) }}
{% else %}
diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig
index 5cc3ae149fa98..78e4e20cd68c5 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig
+++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig
@@ -275,6 +275,9 @@ ul.alt li.warning {
background-color: #ffcc00;
margin-bottom: 1px;
}
+ul.alt li.scream, ul.alt li.scream strong {
+ color: gray;
+}
ul.sf-call-stack li {
text-size: small;
padding: 0 0 0 20px;
diff --git a/src/Symfony/Component/Debug/ErrorHandler.php b/src/Symfony/Component/Debug/ErrorHandler.php
index e72e249f7fce7..2351893d5251c 100644
--- a/src/Symfony/Component/Debug/ErrorHandler.php
+++ b/src/Symfony/Component/Debug/ErrorHandler.php
@@ -11,6 +11,7 @@
namespace Symfony\Component\Debug;
+use Psr\Log\LogLevel;
use Psr\Log\LoggerInterface;
use Symfony\Component\Debug\Exception\ContextErrorException;
use Symfony\Component\Debug\Exception\FatalErrorException;
@@ -44,7 +45,7 @@ class ErrorHandler
E_ERROR => 'Error',
E_CORE_ERROR => 'Core Error',
E_COMPILE_ERROR => 'Compile Error',
- E_PARSE => 'Parse',
+ E_PARSE => 'Parse Error',
);
private $level;
@@ -108,7 +109,7 @@ public function setDisplayErrors($displayErrors)
* Sets a logger for the given channel.
*
* @param LoggerInterface $logger A logger interface
- * @param string $channel The channel associated with the logger (deprecation or emergency)
+ * @param string $channel The channel associated with the logger (deprecation, emergency or scream)
*/
public static function setLogger(LoggerInterface $logger, $channel = 'deprecation')
{
@@ -120,10 +121,6 @@ public static function setLogger(LoggerInterface $logger, $channel = 'deprecatio
*/
public function handle($level, $message, $file = 'unknown', $line = 0, $context = array())
{
- if (0 === $this->level) {
- return false;
- }
-
if ($level & (E_USER_DEPRECATED | E_DEPRECATED)) {
if (isset(self::$loggers['deprecation'])) {
if (self::$stackedErrorLevels) {
@@ -182,6 +179,35 @@ function ($row) {
}
}
+ if (isset(self::$loggers['scream']) && !(error_reporting() & $level)) {
+ if (self::$stackedErrorLevels) {
+ self::$stackedErrors[] = func_get_args();
+ } else {
+ switch ($level) {
+ case E_USER_ERROR:
+ case E_RECOVERABLE_ERROR:
+ $logLevel = LogLevel::ERROR;
+ break;
+
+ case E_WARNING:
+ case E_USER_WARNING:
+ $logLevel = LogLevel::WARNING;
+ break;
+
+ default:
+ $logLevel = LogLevel::NOTICE;
+ break;
+ }
+
+ self::$loggers['scream']->log($logLevel, $message, array(
+ 'type' => $level,
+ 'file' => $file,
+ 'line' => $line,
+ 'scream' => error_reporting(),
+ ));
+ }
+ }
+
return false;
}
diff --git a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php
index 129797c15a59d..133dfa7af305a 100644
--- a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php
+++ b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php
@@ -174,6 +174,28 @@ public function testHandle()
$handler->handle(E_USER_DEPRECATED, 'foo', 'foo.php', 12, 'foo');
restore_error_handler();
+
+ $logger = $this->getMock('Psr\Log\LoggerInterface');
+
+ $that = $this;
+ $logArgCheck = function ($level, $message, $context) use ($that) {
+ $that->assertEquals('Undefined variable: undefVar', $message);
+ $that->assertArrayHasKey('type', $context);
+ $that->assertEquals($context['type'], E_NOTICE);
+ };
+
+ $logger
+ ->expects($this->once())
+ ->method('log')
+ ->will($this->returnCallback($logArgCheck))
+ ;
+
+ $handler = ErrorHandler::register(E_NOTICE);
+ $handler->setLogger($logger, 'scream');
+ unset($undefVar);
+ @$undefVar++;
+
+ restore_error_handler();
} catch (\Exception $e) {
restore_error_handler();
diff --git a/src/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php
index ba2ea44c5ed32..f215a970305f8 100644
--- a/src/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php
+++ b/src/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php
@@ -46,11 +46,8 @@ public function collect(Request $request, Response $response, \Exception $except
public function lateCollect()
{
if (null !== $this->logger) {
- $this->data = array(
- 'error_count' => $this->logger->countErrors(),
- 'logs' => $this->sanitizeLogs($this->logger->getLogs()),
- 'deprecation_count' => $this->computeDeprecationCount()
- );
+ $this->data = $this->computeErrorsCount();
+ $this->data['logs'] = $this->sanitizeLogs($this->logger->getLogs());
}
}
@@ -81,6 +78,11 @@ public function countDeprecations()
return isset($this->data['deprecation_count']) ? $this->data['deprecation_count'] : 0;
}
+ public function countScreams()
+ {
+ return isset($this->data['scream_count']) ? $this->data['scream_count'] : 0;
+ }
+
/**
* {@inheritdoc}
*/
@@ -119,12 +121,21 @@ private function sanitizeContext($context)
return $context;
}
- private function computeDeprecationCount()
+ private function computeErrorsCount()
{
- $count = 0;
+ $count = array(
+ 'error_count' => $this->logger->countErrors(),
+ 'deprecation_count' => 0,
+ 'scream_count' => 0,
+ );
+
foreach ($this->logger->getLogs() as $log) {
- if (isset($log['context']['type']) && ErrorHandler::TYPE_DEPRECATION === $log['context']['type']) {
- $count++;
+ if (isset($log['context']['type'])) {
+ if (ErrorHandler::TYPE_DEPRECATION === $log['context']['type']) {
+ ++$count['deprecation_count'];
+ } elseif (isset($log['context']['scream'])) {
+ ++$count['scream_count'];
+ }
}
}
diff --git a/src/Symfony/Component/HttpKernel/Tests/DataCollector/LoggerDataCollectorTest.php b/src/Symfony/Component/HttpKernel/Tests/DataCollector/LoggerDataCollectorTest.php
index 7cd4d06c7ad60..40c4c5ac60aea 100644
--- a/src/Symfony/Component/HttpKernel/Tests/DataCollector/LoggerDataCollectorTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/DataCollector/LoggerDataCollectorTest.php
@@ -19,7 +19,7 @@ class LoggerDataCollectorTest extends \PHPUnit_Framework_TestCase
/**
* @dataProvider getCollectTestData
*/
- public function testCollect($nb, $logs, $expectedLogs, $expectedDeprecationCount)
+ public function testCollect($nb, $logs, $expectedLogs, $expectedDeprecationCount, $expectedScreamCount)
{
$logger = $this->getMock('Symfony\Component\HttpKernel\Log\DebugLoggerInterface');
$logger->expects($this->once())->method('countErrors')->will($this->returnValue($nb));
@@ -32,6 +32,7 @@ public function testCollect($nb, $logs, $expectedLogs, $expectedDeprecationCount
$this->assertSame($nb, $c->countErrors());
$this->assertSame($expectedLogs ? $expectedLogs : $logs, $c->getLogs());
$this->assertSame($expectedDeprecationCount, $c->countDeprecations());
+ $this->assertSame($expectedScreamCount, $c->countScreams());
}
public function getCollectTestData()
@@ -41,28 +42,33 @@ public function getCollectTestData()
1,
array(array('message' => 'foo', 'context' => array())),
null,
- 0
+ 0,
+ 0,
),
array(
1,
array(array('message' => 'foo', 'context' => array('foo' => fopen(__FILE__, 'r')))),
array(array('message' => 'foo', 'context' => array('foo' => 'Resource(stream)'))),
- 0
+ 0,
+ 0,
),
array(
1,
array(array('message' => 'foo', 'context' => array('foo' => new \stdClass()))),
array(array('message' => 'foo', 'context' => array('foo' => 'Object(stdClass)'))),
- 0
+ 0,
+ 0,
),
array(
1,
array(
array('message' => 'foo', 'context' => array('type' => ErrorHandler::TYPE_DEPRECATION)),
- array('message' => 'foo2', 'context' => array('type' => ErrorHandler::TYPE_DEPRECATION))
+ array('message' => 'foo2', 'context' => array('type' => ErrorHandler::TYPE_DEPRECATION)),
+ array('message' => 'foo3', 'context' => array('type' => E_USER_WARNING, 'scream' => 0)),
),
null,
- 2
+ 2,
+ 1,
),
);
}