DrupalTranslator.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. <?php
  2. namespace Drupal\Core\Validation;
  3. use Drupal\Component\Render\MarkupInterface;
  4. use Drupal\Core\StringTranslation\TranslatableMarkup;
  5. /**
  6. * Translates strings using Drupal's translation system.
  7. *
  8. * This class is used by the Symfony validator to translate violation messages.
  9. */
  10. class DrupalTranslator implements TranslatorInterface {
  11. /**
  12. * The locale used for translating.
  13. *
  14. * @var string
  15. */
  16. protected $locale;
  17. /**
  18. * {@inheritdoc}
  19. */
  20. public function trans($id, array $parameters = [], $domain = NULL, $locale = NULL) {
  21. // If a TranslatableMarkup object is passed in as $id, return it since the
  22. // message has already been translated.
  23. return $id instanceof TranslatableMarkup ? $id : t($id, $this->processParameters($parameters), $this->getOptions($domain, $locale));
  24. }
  25. /**
  26. * {@inheritdoc}
  27. */
  28. public function transChoice($id, $number, array $parameters = [], $domain = NULL, $locale = NULL) {
  29. // Violation messages can separated singular and plural versions by "|".
  30. $ids = explode('|', $id);
  31. if (!isset($ids[1])) {
  32. throw new \InvalidArgumentException(sprintf('The message "%s" cannot be pluralized, because it is missing a plural (e.g. "There is one apple|There are @count apples").', $id));
  33. }
  34. // Normally, calls to formatPlural() need to use literal strings, like
  35. // formatPlural($count, '1 item', '@count items')
  36. // so that the Drupal project POTX string extractor will correctly
  37. // extract the strings for translation and save them in a format that
  38. // formatPlural() can work with. However, this is a special case, because
  39. // Drupal is supporting a constraint message format from Symfony. So
  40. // although $id looks like a variable here, it is actually coming from a
  41. // static string in a constraint class that the POTX extractor knows about
  42. // and has processed to work with formatPlural(), so this specific call to
  43. // formatPlural() will work correctly.
  44. return \Drupal::translation()->formatPlural($number, $ids[0], $ids[1], $this->processParameters($parameters), $this->getOptions($domain, $locale));
  45. }
  46. /**
  47. * {@inheritdoc}
  48. */
  49. public function setLocale($locale) {
  50. $this->locale = $locale;
  51. }
  52. /**
  53. * {@inheritdoc}
  54. */
  55. public function getLocale() {
  56. return $this->locale ? $this->locale : \Drupal::languageManager()->getCurrentLanguage()->getId();
  57. }
  58. /**
  59. * Processes the parameters array for use with t().
  60. */
  61. protected function processParameters(array $parameters) {
  62. $return = [];
  63. foreach ($parameters as $key => $value) {
  64. // We allow the values in the parameters to be safe string objects. This
  65. // can be useful when we want to use parameter values that are
  66. // TranslatableMarkup.
  67. if ($value instanceof MarkupInterface) {
  68. $value = (string) $value;
  69. }
  70. if (is_object($value)) {
  71. // t() does not work with objects being passed as replacement strings.
  72. }
  73. // Check for symfony replacement patterns in the form "{{ name }}".
  74. elseif (strpos($key, '{{ ') === 0 && strrpos($key, ' }}') == strlen($key) - 3) {
  75. // Transform it into a Drupal pattern using the format %name.
  76. $key = '%' . substr($key, 3, strlen($key) - 6);
  77. $return[$key] = $value;
  78. }
  79. else {
  80. $return[$key] = $value;
  81. }
  82. }
  83. return $return;
  84. }
  85. /**
  86. * Returns options suitable for use with t().
  87. */
  88. protected function getOptions($domain = NULL, $locale = NULL) {
  89. // We do not support domains, so we ignore this parameter.
  90. // If locale is left NULL, t() will default to the interface language.
  91. $locale = isset($locale) ? $locale : $this->locale;
  92. return ['langcode' => $locale];
  93. }
  94. }