1<?php 2 3namespace Gettext; 4 5/** 6 * Class to manage a translation string. 7 */ 8class Translation 9{ 10 protected $id; 11 protected $context; 12 protected $original; 13 protected $translation = ''; 14 protected $plural; 15 protected $pluralTranslation = []; 16 protected $references = []; 17 protected $comments = []; 18 protected $extractedComments = []; 19 protected $flags = []; 20 protected $disabled = false; 21 22 /** 23 * Generates the id of a translation (context + glue + original). 24 * 25 * @param string $context 26 * @param string $original 27 * 28 * @return string 29 */ 30 public static function generateId($context, $original) 31 { 32 return "{$context}\004{$original}"; 33 } 34 35 /** 36 * Create a new instance of a Translation object. 37 * 38 * This is a factory method that will work even when Translation is extended. 39 * 40 * @param string $context The context of the translation 41 * @param string $original The original string 42 * @param string $plural The original plural string 43 * @return static New Translation instance 44 */ 45 public static function create($context, $original, $plural = '') 46 { 47 return new static($context, $original, $plural); 48 } 49 50 /** 51 * Construct. 52 * 53 * @param string $context The context of the translation 54 * @param string $original The original string 55 * @param string $plural The original plural string 56 */ 57 public function __construct($context, $original, $plural = '') 58 { 59 $this->context = (string) $context; 60 $this->original = (string) $original; 61 62 $this->setPlural($plural); 63 } 64 65 /** 66 * Clones this translation. 67 * 68 * @param null|string $context Optional new context 69 * @param null|string $original Optional new original 70 * 71 * @return Translation 72 */ 73 public function getClone($context = null, $original = null) 74 { 75 $new = clone $this; 76 77 if ($context !== null) { 78 $new->context = (string) $context; 79 } 80 81 if ($original !== null) { 82 $new->original = (string) $original; 83 } 84 85 return $new; 86 } 87 88 /** 89 * Sets the id of this translation. 90 * @warning The use of this function to set a custom ID will prevent 91 * Translations::find from matching this translation. 92 * 93 * @param string $id 94 */ 95 public function setId($id) 96 { 97 $this->id = $id; 98 } 99 100 101 /** 102 * Returns the id of this translation. 103 * 104 * @return string 105 */ 106 public function getId() 107 { 108 if ($this->id === null) { 109 return static::generateId($this->context, $this->original); 110 } 111 return $this->id; 112 } 113 114 /** 115 * Checks whether the translation matches with the arguments. 116 * 117 * @param string $context 118 * @param string $original 119 * 120 * @return bool 121 */ 122 public function is($context, $original = '') 123 { 124 return (($this->context === $context) && ($this->original === $original)) ? true : false; 125 } 126 127 /** 128 * Enable or disable the translation 129 * 130 * @param bool $disabled 131 * 132 * @return self 133 */ 134 public function setDisabled($disabled) 135 { 136 $this->disabled = (bool) $disabled; 137 138 return $this; 139 } 140 141 /** 142 * Returns whether the translation is disabled 143 * 144 * @return bool 145 */ 146 public function isDisabled() 147 { 148 return $this->disabled; 149 } 150 151 /** 152 * Gets the original string. 153 * 154 * @return string 155 */ 156 public function getOriginal() 157 { 158 return $this->original; 159 } 160 161 /** 162 * Checks if the original string is empty or not. 163 * 164 * @return bool 165 */ 166 public function hasOriginal() 167 { 168 return ($this->original !== '') ? true : false; 169 } 170 171 /** 172 * Sets the translation string. 173 * 174 * @param string $translation 175 * 176 * @return self 177 */ 178 public function setTranslation($translation) 179 { 180 $this->translation = (string) $translation; 181 182 return $this; 183 } 184 185 /** 186 * Gets the translation string. 187 * 188 * @return string 189 */ 190 public function getTranslation() 191 { 192 return $this->translation; 193 } 194 195 /** 196 * Checks if the translation string is empty or not. 197 * 198 * @return bool 199 */ 200 public function hasTranslation() 201 { 202 return ($this->translation !== '') ? true : false; 203 } 204 205 /** 206 * Sets the plural translation string. 207 * 208 * @param string $plural 209 * 210 * @return self 211 */ 212 public function setPlural($plural) 213 { 214 $this->plural = (string) $plural; 215 216 return $this; 217 } 218 219 /** 220 * Gets the plural translation string. 221 * 222 * @return string 223 */ 224 public function getPlural() 225 { 226 return $this->plural; 227 } 228 229 /** 230 * Checks if the plural translation string is empty or not. 231 * 232 * @return bool 233 */ 234 public function hasPlural() 235 { 236 return ($this->plural !== '') ? true : false; 237 } 238 239 /** 240 * Set a new plural translation. 241 * 242 * @param array $plural 243 * 244 * @return self 245 */ 246 public function setPluralTranslations(array $plural) 247 { 248 $this->pluralTranslation = $plural; 249 250 return $this; 251 } 252 253 /** 254 * Gets all plural translations. 255 * 256 * @param int $size 257 * 258 * @return array 259 */ 260 public function getPluralTranslations($size = null) 261 { 262 if ($size === null) { 263 return $this->pluralTranslation; 264 } 265 266 $current = count($this->pluralTranslation); 267 268 if ($size > $current) { 269 return $this->pluralTranslation + array_fill(0, $size, ''); 270 } 271 272 if ($size < $current) { 273 return array_slice($this->pluralTranslation, 0, $size); 274 } 275 276 return $this->pluralTranslation; 277 } 278 279 /** 280 * Checks if there are any plural translation. 281 * 282 * @param bool $checkContent 283 * 284 * @return bool 285 */ 286 public function hasPluralTranslations($checkContent = false) 287 { 288 if ($checkContent) { 289 return implode('', $this->pluralTranslation) !== ''; 290 } 291 292 return !empty($this->pluralTranslation); 293 } 294 295 /** 296 * Removes all plural translations. 297 * 298 * @return self 299 */ 300 public function deletePluralTranslation() 301 { 302 $this->pluralTranslation = []; 303 304 return $this; 305 } 306 307 /** 308 * Gets the context of this translation. 309 * 310 * @return string 311 */ 312 public function getContext() 313 { 314 return $this->context; 315 } 316 317 /** 318 * Checks if the context is empty or not. 319 * 320 * @return bool 321 */ 322 public function hasContext() 323 { 324 return (isset($this->context) && ($this->context !== '')) ? true : false; 325 } 326 327 /** 328 * Adds a new reference for this translation. 329 * 330 * @param string $filename The file path where the translation has been found 331 * @param null|int $line The line number where the translation has been found 332 * 333 * @return self 334 */ 335 public function addReference($filename, $line = null) 336 { 337 $key = "{$filename}:{$line}"; 338 $this->references[$key] = [$filename, $line]; 339 340 return $this; 341 } 342 343 /** 344 * Checks if the translation has any reference. 345 * 346 * @return bool 347 */ 348 public function hasReferences() 349 { 350 return !empty($this->references); 351 } 352 353 /** 354 * Return all references for this translation. 355 * 356 * @return array 357 */ 358 public function getReferences() 359 { 360 return array_values($this->references); 361 } 362 363 /** 364 * Removes all references. 365 * 366 * @return self 367 */ 368 public function deleteReferences() 369 { 370 $this->references = []; 371 372 return $this; 373 } 374 375 /** 376 * Adds a new comment for this translation. 377 * 378 * @param string $comment 379 * 380 * @return self 381 */ 382 public function addComment($comment) 383 { 384 if (!in_array($comment, $this->comments, true)) { 385 $this->comments[] = $comment; 386 } 387 388 return $this; 389 } 390 391 /** 392 * Checks if the translation has any comment. 393 * 394 * @return bool 395 */ 396 public function hasComments() 397 { 398 return isset($this->comments[0]); 399 } 400 401 /** 402 * Returns all comments for this translation. 403 * 404 * @return array 405 */ 406 public function getComments() 407 { 408 return $this->comments; 409 } 410 411 /** 412 * Removes all comments. 413 * 414 * @return self 415 */ 416 public function deleteComments() 417 { 418 $this->comments = []; 419 420 return $this; 421 } 422 423 /** 424 * Adds a new extracted comment for this translation. 425 * 426 * @param string $comment 427 * 428 * @return self 429 */ 430 public function addExtractedComment($comment) 431 { 432 if (!in_array($comment, $this->extractedComments, true)) { 433 $this->extractedComments[] = $comment; 434 } 435 436 return $this; 437 } 438 439 /** 440 * Checks if the translation has any extracted comment. 441 * 442 * @return bool 443 */ 444 public function hasExtractedComments() 445 { 446 return isset($this->extractedComments[0]); 447 } 448 449 /** 450 * Returns all extracted comments for this translation. 451 * 452 * @return array 453 */ 454 public function getExtractedComments() 455 { 456 return $this->extractedComments; 457 } 458 459 /** 460 * Removes all extracted comments. 461 * 462 * @return self 463 */ 464 public function deleteExtractedComments() 465 { 466 $this->extractedComments = []; 467 468 return $this; 469 } 470 471 /** 472 * Adds a new flag for this translation. 473 * 474 * @param string $flag 475 * 476 * @return self 477 */ 478 public function addFlag($flag) 479 { 480 if (!in_array($flag, $this->flags, true)) { 481 $this->flags[] = $flag; 482 } 483 484 return $this; 485 } 486 487 /** 488 * Checks if the translation has any flag. 489 * 490 * @return bool 491 */ 492 public function hasFlags() 493 { 494 return isset($this->flags[0]); 495 } 496 497 /** 498 * Returns all extracted flags for this translation. 499 * 500 * @return array 501 */ 502 public function getFlags() 503 { 504 return $this->flags; 505 } 506 507 /** 508 * Removes all flags. 509 * 510 * @return self 511 */ 512 public function deleteFlags() 513 { 514 $this->flags = []; 515 516 return $this; 517 } 518 519 /** 520 * Merges this translation with other translation. 521 * 522 * @param Translation $translation The translation to merge with 523 * @param int $options 524 * 525 * @return self 526 */ 527 public function mergeWith(Translation $translation, $options = Merge::DEFAULTS) 528 { 529 Merge::mergeTranslation($translation, $this, $options); 530 Merge::mergeReferences($translation, $this, $options); 531 Merge::mergeComments($translation, $this, $options); 532 Merge::mergeExtractedComments($translation, $this, $options); 533 Merge::mergeFlags($translation, $this, $options); 534 535 return $this; 536 } 537} 538