ObjectTranslator.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. <?php
  2. namespace Gedmo\Translator;
  3. use Doctrine\Common\Collections\Collection;
  4. /**
  5. * TranslationsCollection
  6. *
  7. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  8. * @package Gedmo.Translator
  9. * @link http://www.gediminasm.org
  10. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  11. */
  12. class ObjectTranslator
  13. {
  14. private $translatable;
  15. private $properties;
  16. private $class;
  17. private $coll;
  18. private $defaultValues = array();
  19. private $currentLocale;
  20. /**
  21. * Initializes translations collection
  22. *
  23. * @param Object $translatable object to translate
  24. * @param array $properties object properties to translate
  25. * @param string $class translation entity|document class
  26. * @param Collection $coll translations collection
  27. */
  28. public function __construct($translatable, array $properties, $class, Collection $coll)
  29. {
  30. $this->translatable = $translatable;
  31. $this->properties = $properties;
  32. $this->class = $class;
  33. $this->coll = $coll;
  34. $translationClass = new \ReflectionClass($class);
  35. if (!$translationClass->implementsInterface('Gedmo\Translator\TranslationInterface')) {
  36. throw new \InvalidArgumentException(sprintf(
  37. 'Translation class should implement Gedmo\Translator\TranslationInterface, "%s" given',
  38. $class
  39. ));
  40. }
  41. $translatableClass = new \ReflectionObject($translatable);
  42. foreach ($properties as $property) {
  43. $translatableProperty = $translatableClass->getProperty($property);
  44. $translatableProperty->setAccessible(true);
  45. $this->defaultValues[$property] = $translatableProperty->getValue($translatable);
  46. }
  47. }
  48. /**
  49. * Change translatable properties of translatable entity|document to localized ones
  50. *
  51. * @param string $locale locale (null === default)
  52. */
  53. public function translate($locale = null)
  54. {
  55. $locale = null !== $locale ? strtolower($locale) : null;
  56. if ($locale === $this->currentLocale) {
  57. return $this->translatable;
  58. }
  59. $translatableClass = new \ReflectionObject($this->translatable);
  60. // iterate over translatable properties
  61. foreach ($this->properties as $property) {
  62. $translatableProperty = $translatableClass->getProperty($property);
  63. $translatableProperty->setAccessible(true);
  64. $value = $translatableProperty->getValue($this->translatable);
  65. // save current locale value
  66. if (null === $this->currentLocale) {
  67. $this->defaultValues[$property] = $value;
  68. } else {
  69. $translation = $this->getTranslationForProperty($property, $this->currentLocale);
  70. $translation->setValue($value);
  71. }
  72. // load new locale value
  73. if (null === $locale) {
  74. $value = $this->defaultValues[$property];
  75. } else {
  76. $translation = $this->getOrCreateTranslationForProperty($property, $locale);
  77. $value = $translation->getValue();
  78. }
  79. $translatableProperty->setValue($this->translatable, $value);
  80. }
  81. $this->currentLocale = $locale;
  82. return $this->translatable;
  83. }
  84. /**
  85. * Finds or creates new translation for specified property
  86. *
  87. * @param string $property object property name
  88. * @param string $locale locale name
  89. *
  90. * @return Translation
  91. */
  92. public function getOrCreateTranslationForProperty($property, $locale)
  93. {
  94. if (!($translation = $this->getTranslationForProperty($property, $locale))) {
  95. $translation = new $this->class;
  96. $translation->setTranslatable($this->translatable);
  97. $translation->setProperty($property);
  98. $translation->setLocale($locale);
  99. $this->coll->add($translation);
  100. }
  101. return $translation;
  102. }
  103. /**
  104. * Finds translation for specified property
  105. *
  106. * @param string $property object property name
  107. * @param string $locale locale name
  108. *
  109. * @return Translation
  110. */
  111. public function getTranslationForProperty($property, $locale)
  112. {
  113. foreach ($this->coll as $translation) {
  114. if ($locale === $translation->getLocale() && $property === $translation->getProperty()) {
  115. return $translation;
  116. }
  117. }
  118. }
  119. }