TranslationProxy.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <?php
  2. namespace Gedmo\Translator;
  3. use Doctrine\Common\Collections\Collection;
  4. /**
  5. * Proxy class for Entity/Document translations.
  6. *
  7. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  8. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  9. */
  10. class TranslationProxy
  11. {
  12. protected $locale;
  13. protected $translatable;
  14. protected $properties = array();
  15. protected $class;
  16. /**
  17. * @var Collection|TranslationInterface[]
  18. */
  19. protected $coll;
  20. /**
  21. * Initializes translations collection
  22. *
  23. * @param Object $translatable object to translate
  24. * @param string $locale translation name
  25. * @param array $properties object properties to translate
  26. * @param string $class translation entity|document class
  27. * @param Collection $coll translations collection
  28. * @throws \InvalidArgumentException Translation class doesn't implement TranslationInterface
  29. */
  30. public function __construct($translatable, $locale, array $properties, $class, Collection $coll)
  31. {
  32. $this->translatable = $translatable;
  33. $this->locale = $locale;
  34. $this->properties = $properties;
  35. $this->class = $class;
  36. $this->coll = $coll;
  37. $translationClass = new \ReflectionClass($class);
  38. if (!$translationClass->implementsInterface('Gedmo\Translator\TranslationInterface')) {
  39. throw new \InvalidArgumentException(sprintf(
  40. 'Translation class should implement Gedmo\Translator\TranslationInterface, "%s" given',
  41. $class
  42. ));
  43. }
  44. }
  45. public function __call($method, $arguments)
  46. {
  47. $matches = array();
  48. if (preg_match('/^(set|get)(.*)$/', $method, $matches)) {
  49. $property = lcfirst($matches[2]);
  50. if (in_array($property, $this->properties)) {
  51. switch ($matches[1]) {
  52. case 'get':
  53. return $this->getTranslatedValue($property);
  54. case 'set':
  55. if (isset($arguments[0])) {
  56. $this->setTranslatedValue($property, $arguments[0]);
  57. return $this;
  58. }
  59. }
  60. }
  61. }
  62. $return = call_user_func_array(array($this->translatable, $method), $arguments);
  63. if ($this->translatable === $return) {
  64. return $this;
  65. }
  66. return $return;
  67. }
  68. public function __get($property)
  69. {
  70. if (in_array($property, $this->properties)) {
  71. if (method_exists($this, $getter = 'get'.ucfirst($property))) {
  72. return $this->$getter;
  73. }
  74. return $this->getTranslatedValue($property);
  75. }
  76. return $this->translatable->$property;
  77. }
  78. public function __set($property, $value)
  79. {
  80. if (in_array($property, $this->properties)) {
  81. if (method_exists($this, $setter = 'set'.ucfirst($property))) {
  82. return $this->$setter($value);
  83. }
  84. return $this->setTranslatedValue($property, $value);
  85. }
  86. $this->translatable->$property = $value;
  87. }
  88. public function __isset($property)
  89. {
  90. return in_array($property, $this->properties);
  91. }
  92. /**
  93. * Returns locale name for the current translation proxy instance.
  94. *
  95. * @return string
  96. */
  97. public function getProxyLocale()
  98. {
  99. return $this->locale;
  100. }
  101. /**
  102. * Returns translated value for specific property.
  103. *
  104. * @param string $property property name
  105. *
  106. * @return mixed
  107. */
  108. public function getTranslatedValue($property)
  109. {
  110. return $this
  111. ->findOrCreateTranslationForProperty($property, $this->getProxyLocale())
  112. ->getValue();
  113. }
  114. /**
  115. * Sets translated value for specific property.
  116. *
  117. * @param string $property property name
  118. * @param string $value value
  119. */
  120. public function setTranslatedValue($property, $value)
  121. {
  122. $this
  123. ->findOrCreateTranslationForProperty($property, $this->getProxyLocale())
  124. ->setValue($value);
  125. }
  126. /**
  127. * Finds existing or creates new translation for specified property
  128. *
  129. * @param string $property object property name
  130. * @param string $locale locale name
  131. *
  132. * @return Translation
  133. */
  134. private function findOrCreateTranslationForProperty($property, $locale)
  135. {
  136. foreach ($this->coll as $translation) {
  137. if ($locale === $translation->getLocale() && $property === $translation->getProperty()) {
  138. return $translation;
  139. }
  140. }
  141. /** @var TranslationInterface $translation */
  142. $translation = new $this->class;
  143. $translation->setTranslatable($this->translatable);
  144. $translation->setProperty($property);
  145. $translation->setLocale($locale);
  146. $this->coll->add($translation);
  147. return $translation;
  148. }
  149. }