Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Translation][Profiler] Added a Translation profiler.
- Loading branch information
Showing
7 changed files
with
481 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
src/Symfony/Bundle/FrameworkBundle/Resources/config/translation_debug.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?xml version="1.0" ?> | ||
|
||
<container xmlns="http://symfony.com/schema/dic/services" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> | ||
|
||
<services> | ||
<!-- DataCollectorTranslator --> | ||
<service id="translator.data_collector" class="Symfony\Component\Translation\DataCollectorTranslator" public="false"> | ||
<argument type="service" id="translator.data_collector.inner" /> | ||
</service> | ||
|
||
<!-- DataCollector --> | ||
<service id="data_collector.translation" class="Symfony\Component\Translation\DataCollector\TranslationDataCollector"> | ||
<tag name="data_collector" template="@WebProfiler/Collector/translation.html.twig" id="translation" priority="255" /> | ||
<argument type="service" id="translator.data_collector" /> | ||
</service> | ||
</services> | ||
</container> |
93 changes: 93 additions & 0 deletions
93
src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/translation.html.twig
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
{% extends '@WebProfiler/Profiler/layout.html.twig' %} | ||
|
||
{% import _self as translator %} | ||
|
||
{% block toolbar %} | ||
{% if collector.messages|length %} | ||
{% set icon %} | ||
<svg width="28" height="28" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 417 300" enable-background="new 0 0 417 300" xml:space="preserve"><g id="Layer_1_1_"><g id="outline_1_"><path fill="#B5B5B6" d="M275.9,145c0,18.2-14.799,33-33,33H120.701l-36.3,42l-0.3-42H40c-18.2,0-33-14.8-33-33V44c0-18.2,14.8-33,33-33h202.9c18.199,0,33,14.8,33,33V145L275.9,145z"/></g><g enable-background="new"><path fill="#FFFFFF" d="M194.501,146.962h-23.898l-9.5-24.715h-43.492l-8.98,24.715H85.326l42.379-108.805h23.23L194.501,146.962zM154.052,103.915L139.06,63.54l-14.695,40.375H154.052z"/></g></g><g id="Layer_2_1_"><g id="japanese"><g id="outline"><path fill="#414141" d="M141.451,214c0,18.2,14.8,33,33,33h122.2l36.301,42l0.301-42h44.1c18.201,0,33-14.8,33-33V113c0-18.2-14.799-33-33-33H174.453c-18.201,0-33,14.8-33,33L141.451,214L141.451,214z"/></g><g enable-background="new"><path fill="#FFFFFF" d="M312.158,143.327c-0.455,1.672-0.912,3.344-1.215,5.016c22.039,6.08,31.766,21.431,31.766,38.455c0,24.318-18.238,40.733-57.301,45.598c-1.217-3.952-5.016-11.248-7.904-15.352c27.359-3.04,45.295-12.159,45.295-29.791c0-5.016-1.672-16.871-18.088-22.19c-6.688,15.199-16.871,29.335-28.727,39.519c0.607,1.976,1.367,3.647,2.127,5.167l-15.654,10.032c-0.76-1.521-1.52-3.192-2.129-5.017c-7.6,4.256-15.959,6.992-24.471,6.992c-13.375,0-22.189-8.512-22.189-22.647c0-20.975,16.111-37.542,37.693-46.357c-0.305-6.536-0.305-13.223-0.305-20.215c-11.398,0.304-23.711,0.608-29.789,0.456l-0.912-17.783c6.99,0.152,19.758,0.152,31.006,0.152c0.305-6.536,0.457-14.135,0.76-20.519l23.863,1.824c-0.305,1.52-1.52,2.736-4.104,3.04c-0.457,4.408-0.76,10.184-1.217,15.047c16.568-0.76,37.391-2.736,54.262-6.384l1.672,18.391c-16.719,3.04-38.605,4.56-56.846,5.168c-0.15,5.319-0.303,10.487-0.303,15.503c6.383-1.52,15.654-2.432,22.799-1.976c0.607-2.28,1.063-4.56,1.215-6.84L312.158,143.327z M255.77,198.044c-1.672-8.056-2.736-17.479-3.496-27.814c-12.008,5.927-20.215,15.199-20.215,25.382c0,8.664,6.535,8.36,8.512,8.209C245.281,203.668,250.449,201.539,255.77,198.044zM286.473,162.021c-2.129-0.304-10.033,0.305-16.871,2.128c0.455,7.6,0.91,14.591,1.975,20.671C277.504,178.589,282.672,170.686,286.473,162.021z"/></g></g></g></svg> | ||
{% if collector.countMissings %} | ||
{% set status_color = "red" %} | ||
{% elseif collector.countFallbacks %} | ||
{% set status_color = "yellow" %} | ||
{% endif %} | ||
{% set error_count = collector.countMissings + collector.countFallbacks %} | ||
<span class="sf-toolbar-status{% if status_color is defined %} sf-toolbar-status-{{ status_color }}{% endif %}">{{ error_count ?: collector.countdefines }}</span> | ||
{% endset %} | ||
{% set text %} | ||
{% if collector.countMissings %} | ||
<div class="sf-toolbar-info-piece"> | ||
<b>Missing messages</b> | ||
<span class="sf-toolbar-status sf-toolbar-status-red">{{ collector.countMissings }}</span> | ||
</div> | ||
{% endif %} | ||
{% if collector.countFallbacks %} | ||
<div class="sf-toolbar-info-piece"> | ||
<b>Fallback messages</b> | ||
<span class="sf-toolbar-status sf-toolbar-status-yellow">{{ collector.countFallbacks }}</span> | ||
</div> | ||
{% endif %} | ||
{% if collector.countdefines %} | ||
<div class="sf-toolbar-info-piece"> | ||
<b>Defined messages</b> | ||
<span class="sf-toolbar-status sf-toolbar-status-green">{{ collector.countdefines }}</span> | ||
</div> | ||
{% endif %} | ||
{% endset %} | ||
{% include '@WebProfiler/Profiler/toolbar_item.html.twig' with { 'link': profiler_url } %} | ||
{% endif %} | ||
{% endblock %} | ||
|
||
{% block menu %} | ||
<span class="label"> | ||
<span class="icon"><svg width="35" height="28" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 417 300" enable-background="new 0 0 417 300" xml:space="preserve"><g id="Layer_1_1_"><g id="outline_1_"><path fill="#B5B5B6" d="M275.9,145c0,18.2-14.799,33-33,33H120.701l-36.3,42l-0.3-42H40c-18.2,0-33-14.8-33-33V44c0-18.2,14.8-33,33-33h202.9c18.199,0,33,14.8,33,33V145L275.9,145z"/></g><g enable-background="new"><path fill="#FFFFFF" d="M194.501,146.962h-23.898l-9.5-24.715h-43.492l-8.98,24.715H85.326l42.379-108.805h23.23L194.501,146.962zM154.052,103.915L139.06,63.54l-14.695,40.375H154.052z"/></g></g><g id="Layer_2_1_"><g id="japanese"><g id="outline"><path fill="#414141" d="M141.451,214c0,18.2,14.8,33,33,33h122.2l36.301,42l0.301-42h44.1c18.201,0,33-14.8,33-33V113c0-18.2-14.799-33-33-33H174.453c-18.201,0-33,14.8-33,33L141.451,214L141.451,214z"/></g><g enable-background="new"><path fill="#FFFFFF" d="M312.158,143.327c-0.455,1.672-0.912,3.344-1.215,5.016c22.039,6.08,31.766,21.431,31.766,38.455c0,24.318-18.238,40.733-57.301,45.598c-1.217-3.952-5.016-11.248-7.904-15.352c27.359-3.04,45.295-12.159,45.295-29.791c0-5.016-1.672-16.871-18.088-22.19c-6.688,15.199-16.871,29.335-28.727,39.519c0.607,1.976,1.367,3.647,2.127,5.167l-15.654,10.032c-0.76-1.521-1.52-3.192-2.129-5.017c-7.6,4.256-15.959,6.992-24.471,6.992c-13.375,0-22.189-8.512-22.189-22.647c0-20.975,16.111-37.542,37.693-46.357c-0.305-6.536-0.305-13.223-0.305-20.215c-11.398,0.304-23.711,0.608-29.789,0.456l-0.912-17.783c6.99,0.152,19.758,0.152,31.006,0.152c0.305-6.536,0.457-14.135,0.76-20.519l23.863,1.824c-0.305,1.52-1.52,2.736-4.104,3.04c-0.457,4.408-0.76,10.184-1.217,15.047c16.568-0.76,37.391-2.736,54.262-6.384l1.672,18.391c-16.719,3.04-38.605,4.56-56.846,5.168c-0.15,5.319-0.303,10.487-0.303,15.503c6.383-1.52,15.654-2.432,22.799-1.976c0.607-2.28,1.063-4.56,1.215-6.84L312.158,143.327z M255.77,198.044c-1.672-8.056-2.736-17.479-3.496-27.814c-12.008,5.927-20.215,15.199-20.215,25.382c0,8.664,6.535,8.36,8.512,8.209C245.281,203.668,250.449,201.539,255.77,198.044zM286.473,162.021c-2.129-0.304-10.033,0.305-16.871,2.128c0.455,7.6,0.91,14.591,1.975,20.671C277.504,178.589,282.672,170.686,286.473,162.021z"/></g></g></g></svg></span> | ||
<strong>Translation</strong> | ||
</span> | ||
{% endblock %} | ||
|
||
{% block panel %} | ||
{% if collector.messages is empty %} | ||
<h2>Translations</h2> | ||
<p> | ||
<em>No translations have been called.</em> | ||
</p> | ||
{% else %} | ||
{{ block('panelContent') }} | ||
{% endif %} | ||
{% endblock %} | ||
|
||
{% block panelContent %} | ||
<h2>Called Translations</h2> | ||
<ul> | ||
<li><strong>Defined messages: {{ collector.countdefines }}</strong></li> | ||
<li><strong>Fallback messages: {{ collector.countFallbacks }}</strong></li> | ||
<li><strong>Missing messages: {{ collector.countMissings }}</strong></li> | ||
</ul> | ||
|
||
<table> | ||
<tr> | ||
<th>State</th> | ||
<th>Locale</th> | ||
<th>Domain</th> | ||
<th>Id</th> | ||
<th>Message Preview</th> | ||
</tr> | ||
{% for message in collector.messages %} | ||
<tr> | ||
<td><code>{{ translator.state(message) }}</code></td> | ||
<td><code>{{ message.locale }}</code></td> | ||
<td><code>{{ message.domain }}</code></td> | ||
<td><code>{{ message.id }}</code></td> | ||
<td><code>{{ message.translation }}</code></td> | ||
</tr> | ||
{% endfor %} | ||
</table> | ||
{% endblock %} | ||
|
||
{% macro state(translation) %} | ||
{% if translation.state == constant('Symfony\\Component\\Translation\\DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK') %} | ||
same as fallback | ||
{% elseif translation.state == constant('Symfony\\Component\\Translation\\DataCollectorTranslator::MESSAGE_MISSING') %} | ||
missing | ||
{% endif %} | ||
{% endmacro %} |
132 changes: 132 additions & 0 deletions
132
src/Symfony/Component/Translation/DataCollector/TranslationDataCollector.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
<?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\Component\Translation\DataCollector; | ||
|
||
use Symfony\Component\HttpFoundation\Request; | ||
use Symfony\Component\HttpFoundation\Response; | ||
use Symfony\Component\HttpKernel\DataCollector\DataCollector; | ||
use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface; | ||
use Symfony\Component\Translation\DataCollectorTranslator; | ||
|
||
/** | ||
* @author Abdellatif Ait boudad <a.aitboudad@gmail.com> | ||
*/ | ||
class TranslationDataCollector extends DataCollector implements LateDataCollectorInterface | ||
{ | ||
/** | ||
* @var DataCollectorTranslator | ||
*/ | ||
private $translator; | ||
|
||
/** | ||
* @param DataCollectorTranslator $translator | ||
*/ | ||
public function __construct(DataCollectorTranslator $translator) | ||
{ | ||
$this->translator = $translator; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function lateCollect() | ||
{ | ||
$this->data = $this->computeCount(); | ||
$this->data['messages'] = $this->sanitizeCollectedMessages($this->translator->getCollectedMessages()); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function collect(Request $request, Response $response, \Exception $exception = null) | ||
{ | ||
} | ||
|
||
/** | ||
* @return array | ||
*/ | ||
public function getMessages() | ||
{ | ||
return isset($this->data['messages']) ? $this->data['messages'] : array(); | ||
} | ||
|
||
/** | ||
* @return int | ||
*/ | ||
public function getCountMissings() | ||
{ | ||
return isset($this->data[DataCollectorTranslator::MESSAGE_MISSING]) ? $this->data[DataCollectorTranslator::MESSAGE_MISSING] : 0; | ||
} | ||
|
||
/** | ||
* @return int | ||
*/ | ||
public function getCountFallbacks() | ||
{ | ||
return isset($this->data[DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK]) ? $this->data[DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK] : 0; | ||
} | ||
|
||
/** | ||
* @return int | ||
*/ | ||
public function getCountDefines() | ||
{ | ||
return isset($this->data[DataCollectorTranslator::MESSAGE_DEFINED]) ? $this->data[DataCollectorTranslator::MESSAGE_DEFINED] : 0; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getName() | ||
{ | ||
return 'translation'; | ||
} | ||
|
||
private function sanitizeCollectedMessages($messages) | ||
{ | ||
foreach ($messages as $key => $message) { | ||
$messages[$key]['translation'] = $this->sanitizeString($messages[$key]['translation']); | ||
} | ||
|
||
return $messages; | ||
} | ||
|
||
private function computeCount() | ||
{ | ||
$count = array( | ||
DataCollectorTranslator::MESSAGE_DEFINED => 0, | ||
DataCollectorTranslator::MESSAGE_MISSING => 0, | ||
DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK => 0, | ||
); | ||
|
||
foreach ($this->translator->getCollectedMessages() as $message) { | ||
++$count[$message['state']]; | ||
} | ||
|
||
return $count; | ||
} | ||
|
||
private function sanitizeString($string, $length = 80) | ||
{ | ||
$string = trim(preg_replace('/\s+/', ' ', $string)); | ||
|
||
if (function_exists('mb_strlen') && false !== $encoding = mb_detect_encoding($string)) { | ||
if (mb_strlen($string, $encoding) > $length) { | ||
return mb_substr($string, 0, $length - 3, $encoding).'...'; | ||
} | ||
} elseif (strlen($string) > $length) { | ||
return substr($string, 0, $length - 3).'...'; | ||
} | ||
|
||
return $string; | ||
} | ||
} |
Oops, something went wrong.