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 }