annotate core/lib/Drupal/Component/Gettext/PoItem.php @ 13:5fb285c0d0e3

Update Drupal core to 8.4.7 via Composer. Security update; I *think* we've been lucky to get away with this so far, as we don't support self-registration which seems to be used by the so-called "drupalgeddon 2" attack that 8.4.5 was vulnerable to.
author Chris Cannam
date Mon, 23 Apr 2018 09:33:26 +0100
parents 7a779792577d
children 129ea1e6d783
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Component\Gettext;
Chris@0 4
Chris@0 5 /**
Chris@0 6 * PoItem handles one translation.
Chris@0 7 *
Chris@0 8 * @todo: This class contains some really old legacy code.
Chris@0 9 * @see https://www.drupal.org/node/1637662
Chris@0 10 */
Chris@0 11 class PoItem {
Chris@0 12
Chris@0 13 /**
Chris@0 14 * The language code this translation is in.
Chris@0 15 *
Chris@12 16 * @var string
Chris@0 17 */
Chris@0 18 private $_langcode;
Chris@0 19
Chris@0 20 /**
Chris@0 21 * The context this translation belongs to.
Chris@0 22 *
Chris@0 23 * @var string
Chris@0 24 */
Chris@0 25 private $_context = '';
Chris@0 26
Chris@0 27 /**
Chris@0 28 * The source string or array of strings if it has plurals.
Chris@0 29 *
Chris@12 30 * @var string|array
Chris@12 31 *
Chris@0 32 * @see $_plural
Chris@0 33 */
Chris@0 34 private $_source;
Chris@0 35
Chris@0 36 /**
Chris@0 37 * Flag indicating if this translation has plurals.
Chris@0 38 *
Chris@0 39 * @var bool
Chris@0 40 */
Chris@0 41 private $_plural;
Chris@0 42
Chris@0 43 /**
Chris@0 44 * The comment of this translation.
Chris@0 45 *
Chris@0 46 * @var string
Chris@0 47 */
Chris@0 48 private $_comment;
Chris@0 49
Chris@0 50 /**
Chris@0 51 * The translation string or array of strings if it has plurals.
Chris@0 52 *
Chris@12 53 * @var string|array
Chris@0 54 * @see $_plural
Chris@0 55 */
Chris@0 56 private $_translation;
Chris@0 57
Chris@0 58 /**
Chris@0 59 * Gets the language code of the currently used language.
Chris@0 60 *
Chris@0 61 * @return string with langcode
Chris@0 62 */
Chris@0 63 public function getLangcode() {
Chris@0 64 return $this->_langcode;
Chris@0 65 }
Chris@0 66
Chris@0 67 /**
Chris@0 68 * Set the language code of the current language.
Chris@0 69 *
Chris@0 70 * @param string $langcode
Chris@0 71 */
Chris@0 72 public function setLangcode($langcode) {
Chris@0 73 $this->_langcode = $langcode;
Chris@0 74 }
Chris@0 75
Chris@0 76 /**
Chris@0 77 * Gets the context this translation belongs to.
Chris@0 78 *
Chris@0 79 * @return string $context
Chris@0 80 */
Chris@0 81 public function getContext() {
Chris@0 82 return $this->_context;
Chris@0 83 }
Chris@0 84
Chris@0 85 /**
Chris@0 86 * Set the context this translation belongs to.
Chris@0 87 *
Chris@0 88 * @param string $context
Chris@0 89 */
Chris@0 90 public function setContext($context) {
Chris@0 91 $this->_context = $context;
Chris@0 92 }
Chris@0 93
Chris@0 94 /**
Chris@0 95 * Gets the source string or the array of strings if the translation has
Chris@0 96 * plurals.
Chris@0 97 *
Chris@0 98 * @return string or array $translation
Chris@0 99 */
Chris@0 100 public function getSource() {
Chris@0 101 return $this->_source;
Chris@0 102 }
Chris@0 103
Chris@0 104 /**
Chris@0 105 * Set the source string or the array of strings if the translation has
Chris@0 106 * plurals.
Chris@0 107 *
Chris@0 108 * @param string|array $source
Chris@0 109 */
Chris@0 110 public function setSource($source) {
Chris@0 111 $this->_source = $source;
Chris@0 112 }
Chris@0 113
Chris@0 114 /**
Chris@0 115 * Gets the translation string or the array of strings if the translation has
Chris@0 116 * plurals.
Chris@0 117 *
Chris@0 118 * @return string or array $translation
Chris@0 119 */
Chris@0 120 public function getTranslation() {
Chris@0 121 return $this->_translation;
Chris@0 122 }
Chris@0 123
Chris@0 124 /**
Chris@0 125 * Set the translation string or the array of strings if the translation has
Chris@0 126 * plurals.
Chris@0 127 *
Chris@0 128 * @param string|array $translation
Chris@0 129 */
Chris@0 130 public function setTranslation($translation) {
Chris@0 131 $this->_translation = $translation;
Chris@0 132 }
Chris@0 133
Chris@0 134 /**
Chris@0 135 * Set if the translation has plural values.
Chris@0 136 *
Chris@0 137 * @param bool $plural
Chris@0 138 */
Chris@0 139 public function setPlural($plural) {
Chris@0 140 $this->_plural = $plural;
Chris@0 141 }
Chris@0 142
Chris@0 143 /**
Chris@0 144 * Get if the translation has plural values.
Chris@0 145 *
Chris@0 146 * @return bool
Chris@0 147 */
Chris@0 148 public function isPlural() {
Chris@0 149 return $this->_plural;
Chris@0 150 }
Chris@0 151
Chris@0 152 /**
Chris@0 153 * Gets the comment of this translation.
Chris@0 154 *
Chris@0 155 * @return String $comment
Chris@0 156 */
Chris@0 157 public function getComment() {
Chris@0 158 return $this->_comment;
Chris@0 159 }
Chris@0 160
Chris@0 161 /**
Chris@0 162 * Set the comment of this translation.
Chris@0 163 *
Chris@0 164 * @param string $comment
Chris@0 165 */
Chris@0 166 public function setComment($comment) {
Chris@0 167 $this->_comment = $comment;
Chris@0 168 }
Chris@0 169
Chris@0 170 /**
Chris@0 171 * Create the PoItem from a structured array.
Chris@0 172 *
Chris@0 173 * @param array $values
Chris@0 174 */
Chris@0 175 public function setFromArray(array $values = []) {
Chris@0 176 if (isset($values['context'])) {
Chris@0 177 $this->setContext($values['context']);
Chris@0 178 }
Chris@0 179 if (isset($values['source'])) {
Chris@0 180 $this->setSource($values['source']);
Chris@0 181 }
Chris@0 182 if (isset($values['translation'])) {
Chris@0 183 $this->setTranslation($values['translation']);
Chris@0 184 }
Chris@0 185 if (isset($values['comment'])) {
Chris@0 186 $this->setComment($values['comment']);
Chris@0 187 }
Chris@0 188 if (isset($this->_source) &&
Chris@0 189 strpos($this->_source, LOCALE_PLURAL_DELIMITER) !== FALSE) {
Chris@0 190 $this->setSource(explode(LOCALE_PLURAL_DELIMITER, $this->_source));
Chris@0 191 $this->setTranslation(explode(LOCALE_PLURAL_DELIMITER, $this->_translation));
Chris@0 192 $this->setPlural(count($this->_source) > 1);
Chris@0 193 }
Chris@0 194 }
Chris@0 195
Chris@0 196 /**
Chris@0 197 * Output the PoItem as a string.
Chris@0 198 */
Chris@0 199 public function __toString() {
Chris@0 200 return $this->formatItem();
Chris@0 201 }
Chris@0 202
Chris@0 203 /**
Chris@0 204 * Format the POItem as a string.
Chris@0 205 */
Chris@0 206 private function formatItem() {
Chris@0 207 $output = '';
Chris@0 208
Chris@0 209 // Format string context.
Chris@0 210 if (!empty($this->_context)) {
Chris@0 211 $output .= 'msgctxt ' . $this->formatString($this->_context);
Chris@0 212 }
Chris@0 213
Chris@0 214 // Format translation.
Chris@0 215 if ($this->_plural) {
Chris@0 216 $output .= $this->formatPlural();
Chris@0 217 }
Chris@0 218 else {
Chris@0 219 $output .= $this->formatSingular();
Chris@0 220 }
Chris@0 221
Chris@0 222 // Add one empty line to separate the translations.
Chris@0 223 $output .= "\n";
Chris@0 224
Chris@0 225 return $output;
Chris@0 226 }
Chris@0 227
Chris@0 228 /**
Chris@0 229 * Formats a plural translation.
Chris@0 230 */
Chris@0 231 private function formatPlural() {
Chris@0 232 $output = '';
Chris@0 233
Chris@0 234 // Format source strings.
Chris@0 235 $output .= 'msgid ' . $this->formatString($this->_source[0]);
Chris@0 236 $output .= 'msgid_plural ' . $this->formatString($this->_source[1]);
Chris@0 237
Chris@0 238 foreach ($this->_translation as $i => $trans) {
Chris@0 239 if (isset($this->_translation[$i])) {
Chris@0 240 $output .= 'msgstr[' . $i . '] ' . $this->formatString($trans);
Chris@0 241 }
Chris@0 242 else {
Chris@0 243 $output .= 'msgstr[' . $i . '] ""' . "\n";
Chris@0 244 }
Chris@0 245 }
Chris@0 246
Chris@0 247 return $output;
Chris@0 248 }
Chris@0 249
Chris@0 250 /**
Chris@0 251 * Formats a singular translation.
Chris@0 252 */
Chris@0 253 private function formatSingular() {
Chris@0 254 $output = '';
Chris@0 255 $output .= 'msgid ' . $this->formatString($this->_source);
Chris@0 256 $output .= 'msgstr ' . (isset($this->_translation) ? $this->formatString($this->_translation) : '""');
Chris@0 257 return $output;
Chris@0 258 }
Chris@0 259
Chris@0 260 /**
Chris@0 261 * Formats a string for output on multiple lines.
Chris@0 262 */
Chris@0 263 private function formatString($string) {
Chris@0 264 // Escape characters for processing.
Chris@0 265 $string = addcslashes($string, "\0..\37\\\"");
Chris@0 266
Chris@0 267 // Always include a line break after the explicit \n line breaks from
Chris@0 268 // the source string. Otherwise wrap at 70 chars to accommodate the extra
Chris@0 269 // format overhead too.
Chris@0 270 $parts = explode("\n", wordwrap(str_replace('\n', "\\n\n", $string), 70, " \n"));
Chris@0 271
Chris@0 272 // Multiline string should be exported starting with a "" and newline to
Chris@0 273 // have all lines aligned on the same column.
Chris@0 274 if (count($parts) > 1) {
Chris@0 275 return "\"\"\n\"" . implode("\"\n\"", $parts) . "\"\n";
Chris@0 276 }
Chris@0 277 // Single line strings are output on the same line.
Chris@0 278 else {
Chris@0 279 return "\"$parts[0]\"\n";
Chris@0 280 }
Chris@0 281 }
Chris@0 282
Chris@0 283 }