diff --git a/src/Symfony/Bridge/Twig/AppVariable.php b/src/Symfony/Bridge/Twig/AppVariable.php index 4117c58298..6657abf27c 100644 --- a/src/Symfony/Bridge/Twig/AppVariable.php +++ b/src/Symfony/Bridge/Twig/AppVariable.php @@ -14,7 +14,6 @@ namespace Symfony\Bridge\Twig; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Session\Session; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; /** 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 33ec18e58c..e874facfae 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig @@ -120,6 +120,10 @@ {% set stack = log.context.stack|default([]) %} {% set id = 'sf-call-stack-' ~ log_index %} + {% if log.context.errorCount is defined %} + ({{ log.context.errorCount }}x) + {% endif %} + {% if stack %} diff --git a/src/Symfony/Component/Console/Descriptor/JsonDescriptor.php b/src/Symfony/Component/Console/Descriptor/JsonDescriptor.php index 8649d3ac45..87e38fdb89 100644 --- a/src/Symfony/Component/Console/Descriptor/JsonDescriptor.php +++ b/src/Symfony/Component/Console/Descriptor/JsonDescriptor.php @@ -102,7 +102,7 @@ class JsonDescriptor extends Descriptor 'name' => $argument->getName(), 'is_required' => $argument->isRequired(), 'is_array' => $argument->isArray(), - 'description' => preg_replace('/\s*\R\s*/', ' ', $argument->getDescription()), + 'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $argument->getDescription()), 'default' => $argument->getDefault(), ); } @@ -120,7 +120,7 @@ class JsonDescriptor extends Descriptor 'accept_value' => $option->acceptValue(), 'is_value_required' => $option->isValueRequired(), 'is_multiple' => $option->isArray(), - 'description' => preg_replace('/\s*\R\s*/', ' ', $option->getDescription()), + 'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $option->getDescription()), 'default' => $option->getDefault(), ); } diff --git a/src/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php b/src/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php index 10f05168d4..d3d76a4201 100644 --- a/src/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php +++ b/src/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php @@ -36,7 +36,7 @@ class MarkdownDescriptor extends Descriptor .'* Name: '.($argument->getName() ?: '')."\n" .'* Is required: '.($argument->isRequired() ? 'yes' : 'no')."\n" .'* Is array: '.($argument->isArray() ? 'yes' : 'no')."\n" - .'* Description: '.preg_replace('/\s*\R\s*/', PHP_EOL.' ', $argument->getDescription() ?: '')."\n" + .'* Description: '.preg_replace('/\s*[\r\n]\s*/', "\n ", $argument->getDescription() ?: '')."\n" .'* Default: `'.str_replace("\n", '', var_export($argument->getDefault(), true)).'`' ); } @@ -53,7 +53,7 @@ class MarkdownDescriptor extends Descriptor .'* Accept value: '.($option->acceptValue() ? 'yes' : 'no')."\n" .'* Is value required: '.($option->isValueRequired() ? 'yes' : 'no')."\n" .'* Is multiple: '.($option->isArray() ? 'yes' : 'no')."\n" - .'* Description: '.preg_replace('/\s*\R\s*/', PHP_EOL.' ', $option->getDescription() ?: '')."\n" + .'* Description: '.preg_replace('/\s*[\r\n]\s*/', "\n ", $option->getDescription() ?: '')."\n" .'* Default: `'.str_replace("\n", '', var_export($option->getDefault(), true)).'`' ); } diff --git a/src/Symfony/Component/Console/Descriptor/TextDescriptor.php b/src/Symfony/Component/Console/Descriptor/TextDescriptor.php index 487b7ff38f..8edc14d545 100644 --- a/src/Symfony/Component/Console/Descriptor/TextDescriptor.php +++ b/src/Symfony/Component/Console/Descriptor/TextDescriptor.php @@ -44,7 +44,7 @@ class TextDescriptor extends Descriptor $argument->getName(), str_repeat(' ', $spacingWidth), // + 17 = 2 spaces + + + 2 spaces - preg_replace('/\s*\R\s*/', PHP_EOL.str_repeat(' ', $totalWidth + 17), $argument->getDescription()), + preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 17), $argument->getDescription()), $default ), $options); } @@ -81,7 +81,7 @@ class TextDescriptor extends Descriptor $synopsis, str_repeat(' ', $spacingWidth), // + 17 = 2 spaces + + + 2 spaces - preg_replace('/\s*\R\s*/', "\n".str_repeat(' ', $totalWidth + 17), $option->getDescription()), + preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 17), $option->getDescription()), $default, $option->isArray() ? ' (multiple values allowed)' : '' ), $options); diff --git a/src/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php index 0d1decda3a..12584345a2 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php @@ -97,15 +97,46 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte private function sanitizeLogs($logs) { - foreach ($logs as $i => $log) { + $errorContextById = array(); + $sanitizedLogs = array(); + + foreach ($logs as $log) { $context = $this->sanitizeContext($log['context']); - if (isset($context['type'], $context['level']) && !($context['type'] & $context['level'])) { - $context['scream'] = true; + + if (isset($context['type'], $context['file'], $context['line'], $context['level'])) { + $errorId = md5("{$context['type']}/{$context['line']}/{$context['file']}\x00{$log['message']}", true); + $silenced = !($context['type'] & $context['level']); + + if (isset($errorContextById[$errorId])) { + if (isset($errorContextById[$errorId]['errorCount'])) { + ++$errorContextById[$errorId]['errorCount']; + } else { + $errorContextById[$errorId]['errorCount'] = 2; + } + + if (!$silenced && isset($errorContextById[$errorId]['scream'])) { + unset($errorContextById[$errorId]['scream']); + $errorContextById[$errorId]['level'] = $context['level']; + } + + continue; + } + + $errorContextById[$errorId] = &$context; + if ($silenced) { + $context['scream'] = true; + } + + $log['context'] = &$context; + unset($context); + } else { + $log['context'] = $context; } - $logs[$i]['context'] = $context; + + $sanitizedLogs[] = $log; } - return $logs; + return $sanitizedLogs; } private function sanitizeContext($context) diff --git a/src/Symfony/Component/HttpKernel/Tests/DataCollector/LoggerDataCollectorTest.php b/src/Symfony/Component/HttpKernel/Tests/DataCollector/LoggerDataCollectorTest.php index 4303ab1343..dd1608ce7f 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DataCollector/LoggerDataCollectorTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DataCollector/LoggerDataCollectorTest.php @@ -75,8 +75,18 @@ class LoggerDataCollectorTest extends \PHPUnit_Framework_TestCase ), array( 1, - array(array('message' => 'foo3', 'context' => array('type' => E_USER_WARNING, 'level' => 0), 'priority' => 100, 'priorityName' => 'DEBUG')), - array(array('message' => 'foo3', 'context' => array('type' => E_USER_WARNING, 'level' => 0, 'scream' => true), 'priority' => 100, 'priorityName' => 'DEBUG')), + array(array('message' => 'foo3', 'context' => array('type' => E_USER_WARNING, 'level' => 0, 'file' => __FILE__, 'line' => 123), 'priority' => 100, 'priorityName' => 'DEBUG')), + array(array('message' => 'foo3', 'context' => array('type' => E_USER_WARNING, 'level' => 0, 'file' => __FILE__, 'line' => 123, 'scream' => true), 'priority' => 100, 'priorityName' => 'DEBUG')), + 0, + 1, + ), + array( + 1, + array( + array('message' => 'foo3', 'context' => array('type' => E_USER_WARNING, 'level' => 0, 'file' => __FILE__, 'line' => 123), 'priority' => 100, 'priorityName' => 'DEBUG'), + array('message' => 'foo3', 'context' => array('type' => E_USER_WARNING, 'level' => -1, 'file' => __FILE__, 'line' => 123), 'priority' => 100, 'priorityName' => 'DEBUG'), + ), + array(array('message' => 'foo3', 'context' => array('type' => E_USER_WARNING, 'level' => -1, 'file' => __FILE__, 'line' => 123, 'errorCount' => 2), 'priority' => 100, 'priorityName' => 'DEBUG')), 0, 1, ), diff --git a/src/Symfony/Component/Translation/Dumper/XliffFileDumper.php b/src/Symfony/Component/Translation/Dumper/XliffFileDumper.php index 47e082c22e..668c90d646 100644 --- a/src/Symfony/Component/Translation/Dumper/XliffFileDumper.php +++ b/src/Symfony/Component/Translation/Dumper/XliffFileDumper.php @@ -20,30 +20,22 @@ use Symfony\Component\Translation\MessageCatalogue; */ class XliffFileDumper extends FileDumper { - /** - * @var string - */ - private $defaultLocale; - /** * {@inheritdoc} */ - public function dump(MessageCatalogue $messages, $options = array()) + protected function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array()) { if (array_key_exists('default_locale', $options)) { - $this->defaultLocale = $options['default_locale']; + $defaultLocale = $options['default_locale']; } else { - $this->defaultLocale = \Locale::getDefault(); + $defaultLocale = \Locale::getDefault(); } - parent::dump($messages, $options); - } + $toolInfo = array('tool-id' => 'symfony', 'tool-name' => 'Symfony'); + if (array_key_exists('tool_info', $options)) { + $toolInfo = array_merge($toolInfo, $options['tool_info']); + } - /** - * {@inheritdoc} - */ - protected function format(MessageCatalogue $messages, $domain) - { $dom = new \DOMDocument('1.0', 'utf-8'); $dom->formatOutput = true; @@ -52,11 +44,17 @@ class XliffFileDumper extends FileDumper $xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:1.2'); $xliffFile = $xliff->appendChild($dom->createElement('file')); - $xliffFile->setAttribute('source-language', str_replace('_', '-', $this->defaultLocale)); + $xliffFile->setAttribute('source-language', str_replace('_', '-', $defaultLocale)); $xliffFile->setAttribute('target-language', str_replace('_', '-', $messages->getLocale())); $xliffFile->setAttribute('datatype', 'plaintext'); $xliffFile->setAttribute('original', 'file.ext'); + $xliffHead = $xliffFile->appendChild($dom->createElement('header')); + $xliffTool = $xliffHead->appendChild($dom->createElement('tool')); + foreach ($toolInfo as $id => $value) { + $xliffTool->setAttribute($id, $value); + } + $xliffBody = $xliffFile->appendChild($dom->createElement('body')); foreach ($messages->all($domain) as $source => $target) { $translation = $dom->createElement('trans-unit'); @@ -105,6 +103,14 @@ class XliffFileDumper extends FileDumper return $dom->saveXML(); } + /** + * {@inheritdoc} + */ + protected function format(MessageCatalogue $messages, $domain) + { + return $this->formatCatalogue($messages, $domain); + } + /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/Translation/Tests/Dumper/XliffFileDumperTest.php b/src/Symfony/Component/Translation/Tests/Dumper/XliffFileDumperTest.php index b1f9826c29..d2cbf4668d 100644 --- a/src/Symfony/Component/Translation/Tests/Dumper/XliffFileDumperTest.php +++ b/src/Symfony/Component/Translation/Tests/Dumper/XliffFileDumperTest.php @@ -16,6 +16,13 @@ use Symfony\Component\Translation\Dumper\XliffFileDumper; class XliffFileDumperTest extends \PHPUnit_Framework_TestCase { + private $tempDir; + + protected function setUp() + { + $this->tempDir = sys_get_temp_dir(); + } + public function testDump() { $catalogue = new MessageCatalogue('en_US'); @@ -27,19 +34,40 @@ class XliffFileDumperTest extends \PHPUnit_Framework_TestCase $catalogue->setMetadata('foo', array('notes' => array(array('priority' => 1, 'from' => 'bar', 'content' => 'baz')))); $catalogue->setMetadata('key', array('notes' => array(array('content' => 'baz'), array('content' => 'qux')))); - $tempDir = sys_get_temp_dir(); $dumper = new XliffFileDumper(); - $dumper->dump($catalogue, array('path' => $tempDir, 'default_locale' => 'fr_FR')); + $dumper->dump($catalogue, array('path' => $this->tempDir, 'default_locale' => 'fr_FR')); $this->assertEquals( file_get_contents(__DIR__.'/../fixtures/resources-clean.xlf'), - file_get_contents($tempDir.'/messages.en_US.xlf') + file_get_contents($this->tempDir.'/messages.en_US.xlf') ); - unlink($tempDir.'/messages.en_US.xlf'); + unlink($this->tempDir.'/messages.en_US.xlf'); } - public function testTargetAttributesMetadataIsSetInFile() + public function testDumpWithCustomToolInfo() + { + $options = array( + 'path' => $this->tempDir, + 'default_locale' => 'en_US', + 'tool_info' => array('tool-id' => 'foo', 'tool-name' => 'foo', 'tool-version' => '0.0', 'tool-company' => 'Foo'), + ); + + $catalogue = new MessageCatalogue('en_US'); + $catalogue->add(array('foo' => 'bar')); + + $dumper = new XliffFileDumper(); + $dumper->dump($catalogue, $options); + + $this->assertEquals( + file_get_contents(__DIR__.'/../fixtures/resources-tool-info.xlf'), + file_get_contents($this->tempDir.'/messages.en_US.xlf') + ); + + unlink($this->tempDir.'/messages.en_US.xlf'); + } + + public function testDumpWithTargetAttributesMetadata() { $catalogue = new MessageCatalogue('en_US'); $catalogue->add(array( @@ -47,30 +75,15 @@ class XliffFileDumperTest extends \PHPUnit_Framework_TestCase )); $catalogue->setMetadata('foo', array('target-attributes' => array('state' => 'needs-translation'))); - $tempDir = sys_get_temp_dir(); + $this->tempDir = sys_get_temp_dir(); $dumper = new XliffFileDumper(); - $dumper->dump($catalogue, array('path' => $tempDir, 'default_locale' => 'fr_FR')); - - $content = << - - - - - foo - bar - - - - - -EOT; + $dumper->dump($catalogue, array('path' => $this->tempDir, 'default_locale' => 'fr_FR')); $this->assertEquals( - $content, - file_get_contents($tempDir.'/messages.en_US.xlf') + file_get_contents(__DIR__.'/../fixtures/resources-target-attributes.xlf'), + file_get_contents($this->tempDir.'/messages.en_US.xlf') ); - unlink($tempDir.'/messages.en_US.xlf'); + unlink($this->tempDir.'/messages.en_US.xlf'); } } diff --git a/src/Symfony/Component/Translation/Tests/fixtures/resources-clean.xlf b/src/Symfony/Component/Translation/Tests/fixtures/resources-clean.xlf index 4ce15af2f5..436e19ec98 100644 --- a/src/Symfony/Component/Translation/Tests/fixtures/resources-clean.xlf +++ b/src/Symfony/Component/Translation/Tests/fixtures/resources-clean.xlf @@ -1,6 +1,9 @@ +
+ +
foo diff --git a/src/Symfony/Component/Translation/Tests/fixtures/resources-target-attributes.xlf b/src/Symfony/Component/Translation/Tests/fixtures/resources-target-attributes.xlf new file mode 100644 index 0000000000..e3afb498b7 --- /dev/null +++ b/src/Symfony/Component/Translation/Tests/fixtures/resources-target-attributes.xlf @@ -0,0 +1,14 @@ + + + +
+ +
+ + + foo + bar + + +
+
diff --git a/src/Symfony/Component/Translation/Tests/fixtures/resources-tool-info.xlf b/src/Symfony/Component/Translation/Tests/fixtures/resources-tool-info.xlf new file mode 100644 index 0000000000..1ed06d2ac4 --- /dev/null +++ b/src/Symfony/Component/Translation/Tests/fixtures/resources-tool-info.xlf @@ -0,0 +1,14 @@ + + + +
+ +
+ + + foo + bar + + +
+