TranslationDataCollector.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Translation\DataCollector;
  11. use Symfony\Component\HttpFoundation\Request;
  12. use Symfony\Component\HttpFoundation\Response;
  13. use Symfony\Component\HttpKernel\DataCollector\DataCollector;
  14. use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
  15. use Symfony\Component\Translation\DataCollectorTranslator;
  16. /**
  17. * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
  18. *
  19. * @final since Symfony 4.4
  20. */
  21. class TranslationDataCollector extends DataCollector implements LateDataCollectorInterface
  22. {
  23. private $translator;
  24. public function __construct(DataCollectorTranslator $translator)
  25. {
  26. $this->translator = $translator;
  27. }
  28. /**
  29. * {@inheritdoc}
  30. */
  31. public function lateCollect()
  32. {
  33. $messages = $this->sanitizeCollectedMessages($this->translator->getCollectedMessages());
  34. $this->data += $this->computeCount($messages);
  35. $this->data['messages'] = $messages;
  36. $this->data = $this->cloneVar($this->data);
  37. }
  38. /**
  39. * {@inheritdoc}
  40. *
  41. * @param \Throwable|null $exception
  42. */
  43. public function collect(Request $request, Response $response/*, \Throwable $exception = null*/)
  44. {
  45. $this->data['locale'] = $this->translator->getLocale();
  46. $this->data['fallback_locales'] = $this->translator->getFallbackLocales();
  47. }
  48. /**
  49. * {@inheritdoc}
  50. */
  51. public function reset()
  52. {
  53. $this->data = [];
  54. }
  55. /**
  56. * @return array|Data
  57. */
  58. public function getMessages()
  59. {
  60. return isset($this->data['messages']) ? $this->data['messages'] : [];
  61. }
  62. /**
  63. * @return int
  64. */
  65. public function getCountMissings()
  66. {
  67. return isset($this->data[DataCollectorTranslator::MESSAGE_MISSING]) ? $this->data[DataCollectorTranslator::MESSAGE_MISSING] : 0;
  68. }
  69. /**
  70. * @return int
  71. */
  72. public function getCountFallbacks()
  73. {
  74. return isset($this->data[DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK]) ? $this->data[DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK] : 0;
  75. }
  76. /**
  77. * @return int
  78. */
  79. public function getCountDefines()
  80. {
  81. return isset($this->data[DataCollectorTranslator::MESSAGE_DEFINED]) ? $this->data[DataCollectorTranslator::MESSAGE_DEFINED] : 0;
  82. }
  83. public function getLocale()
  84. {
  85. return !empty($this->data['locale']) ? $this->data['locale'] : null;
  86. }
  87. /**
  88. * @internal since Symfony 4.2
  89. */
  90. public function getFallbackLocales()
  91. {
  92. return (isset($this->data['fallback_locales']) && \count($this->data['fallback_locales']) > 0) ? $this->data['fallback_locales'] : [];
  93. }
  94. /**
  95. * {@inheritdoc}
  96. */
  97. public function getName()
  98. {
  99. return 'translation';
  100. }
  101. private function sanitizeCollectedMessages(array $messages)
  102. {
  103. $result = [];
  104. foreach ($messages as $key => $message) {
  105. $messageId = $message['locale'].$message['domain'].$message['id'];
  106. if (!isset($result[$messageId])) {
  107. $message['count'] = 1;
  108. $message['parameters'] = !empty($message['parameters']) ? [$message['parameters']] : [];
  109. $messages[$key]['translation'] = $this->sanitizeString($message['translation']);
  110. $result[$messageId] = $message;
  111. } else {
  112. if (!empty($message['parameters'])) {
  113. $result[$messageId]['parameters'][] = $message['parameters'];
  114. }
  115. ++$result[$messageId]['count'];
  116. }
  117. unset($messages[$key]);
  118. }
  119. return $result;
  120. }
  121. private function computeCount(array $messages)
  122. {
  123. $count = [
  124. DataCollectorTranslator::MESSAGE_DEFINED => 0,
  125. DataCollectorTranslator::MESSAGE_MISSING => 0,
  126. DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK => 0,
  127. ];
  128. foreach ($messages as $message) {
  129. ++$count[$message['state']];
  130. }
  131. return $count;
  132. }
  133. private function sanitizeString(string $string, int $length = 80)
  134. {
  135. $string = trim(preg_replace('/\s+/', ' ', $string));
  136. if (false !== $encoding = mb_detect_encoding($string, null, true)) {
  137. if (mb_strlen($string, $encoding) > $length) {
  138. return mb_substr($string, 0, $length - 3, $encoding).'...';
  139. }
  140. } elseif (\strlen($string) > $length) {
  141. return substr($string, 0, $length - 3).'...';
  142. }
  143. return $string;
  144. }
  145. }