Mercurial > hg > isophonics-drupal-site
comparison core/lib/Drupal/Core/StringTranslation/PluralTranslatableMarkup.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 129ea1e6d783 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Core\StringTranslation; | |
4 | |
5 /** | |
6 * A class to hold plural translatable markup. | |
7 */ | |
8 class PluralTranslatableMarkup extends TranslatableMarkup { | |
9 | |
10 /** | |
11 * The delimiter used to split plural strings. | |
12 * | |
13 * This is the ETX (End of text) character and is used as a minimal means to | |
14 * separate singular and plural variants in source and translation text. It | |
15 * was found to be the most compatible delimiter for the supported databases. | |
16 */ | |
17 const DELIMITER = "\03"; | |
18 | |
19 /** | |
20 * The item count to display. | |
21 * | |
22 * @var int | |
23 */ | |
24 protected $count; | |
25 | |
26 /** | |
27 * The already translated string. | |
28 * | |
29 * @var string | |
30 */ | |
31 protected $translatedString; | |
32 | |
33 /** | |
34 * Constructs a new PluralTranslatableMarkup object. | |
35 * | |
36 * Parses values passed into this class through the format_plural() function | |
37 * in Drupal and handles an optional context for the string. | |
38 * | |
39 * @param int $count | |
40 * The item count to display. | |
41 * @param string $singular | |
42 * The string for the singular case. Make sure it is clear this is singular, | |
43 * to ease translation (e.g. use "1 new comment" instead of "1 new"). Do not | |
44 * use @count in the singular string. | |
45 * @param string $plural | |
46 * The string for the plural case. Make sure it is clear this is plural, to | |
47 * ease translation. Use @count in place of the item count, as in | |
48 * "@count new comments". | |
49 * @param array $args | |
50 * (optional) An array with placeholder replacements, keyed by placeholder. | |
51 * See \Drupal\Component\Render\FormattableMarkup::placeholderFormat() for | |
52 * additional information about placeholders. Note that you do not need to | |
53 * include @count in this array; this replacement is done automatically | |
54 * for the plural cases. | |
55 * @param array $options | |
56 * (optional) An associative array of additional options. See t() for | |
57 * allowed keys. | |
58 * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation | |
59 * (optional) The string translation service. | |
60 * | |
61 * @see \Drupal\Component\Render\FormattableMarkup::placeholderFormat() | |
62 */ | |
63 public function __construct($count, $singular, $plural, array $args = [], array $options = [], TranslationInterface $string_translation = NULL) { | |
64 $this->count = $count; | |
65 $translatable_string = implode(static::DELIMITER, [$singular, $plural]); | |
66 parent::__construct($translatable_string, $args, $options, $string_translation); | |
67 } | |
68 | |
69 /** | |
70 * Constructs a new class instance from already translated markup. | |
71 * | |
72 * This method ensures that the string is pluralized correctly. As opposed | |
73 * to the __construct() method, this method is designed to be invoked with | |
74 * a string already translated (such as with configuration translation). | |
75 * | |
76 * @param int $count | |
77 * The item count to display. | |
78 * @param string $translated_string | |
79 * The already translated string. | |
80 * @param array $args | |
81 * An associative array of replacements to make after translation. Instances | |
82 * of any key in this array are replaced with the corresponding value. | |
83 * Based on the first character of the key, the value is escaped and/or | |
84 * themed. See \Drupal\Component\Utility\SafeMarkup::format(). Note that you | |
85 * do not need to include @count in this array; this replacement is done | |
86 * automatically for the plural cases. | |
87 * @param array $options | |
88 * An associative array of additional options. See t() for allowed keys. | |
89 * | |
90 * @return \Drupal\Core\StringTranslation\PluralTranslatableMarkup | |
91 * A PluralTranslatableMarkup object. | |
92 */ | |
93 public static function createFromTranslatedString($count, $translated_string, array $args = [], array $options = []) { | |
94 $plural = new static($count, '', '', $args, $options); | |
95 $plural->translatedString = $translated_string; | |
96 return $plural; | |
97 } | |
98 | |
99 /** | |
100 * Renders the object as a string. | |
101 * | |
102 * @return string | |
103 * The translated string. | |
104 */ | |
105 public function render() { | |
106 if (!$this->translatedString) { | |
107 $this->translatedString = $this->getStringTranslation()->translateString($this); | |
108 } | |
109 if ($this->translatedString === '') { | |
110 return ''; | |
111 } | |
112 | |
113 $arguments = $this->getArguments(); | |
114 $arguments['@count'] = $this->count; | |
115 $translated_array = explode(static::DELIMITER, $this->translatedString); | |
116 | |
117 if ($this->count == 1) { | |
118 return $this->placeholderFormat($translated_array[0], $arguments); | |
119 } | |
120 | |
121 $index = $this->getPluralIndex(); | |
122 if ($index == 0) { | |
123 // Singular form. | |
124 $return = $translated_array[0]; | |
125 } | |
126 else { | |
127 if (isset($translated_array[$index])) { | |
128 // N-th plural form. | |
129 $return = $translated_array[$index]; | |
130 } | |
131 else { | |
132 // If the index cannot be computed or there's no translation, use the | |
133 // second plural form as a fallback (which allows for most flexibility | |
134 // with the replaceable @count value). | |
135 $return = $translated_array[1]; | |
136 } | |
137 } | |
138 | |
139 return $this->placeholderFormat($return, $arguments); | |
140 } | |
141 | |
142 /** | |
143 * Gets the plural index through the gettext formula. | |
144 * | |
145 * @return int | |
146 */ | |
147 protected function getPluralIndex() { | |
148 // We have to test both if the function and the service exist since in | |
149 // certain situations it is possible that locale code might be loaded but | |
150 // the service does not exist. For example, where the parent test site has | |
151 // locale installed but the child site does not. | |
152 // @todo Refactor in https://www.drupal.org/node/2660338 so this code does | |
153 // not depend on knowing that the Locale module exists. | |
154 if (function_exists('locale_get_plural') && \Drupal::hasService('locale.plural.formula')) { | |
155 return locale_get_plural($this->count, $this->getOption('langcode')); | |
156 } | |
157 return -1; | |
158 } | |
159 | |
160 /** | |
161 * {@inheritdoc} | |
162 */ | |
163 public function __sleep() { | |
164 return array_merge(parent::__sleep(), ['count']); | |
165 } | |
166 | |
167 } |