ODM.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <?php
  2. namespace Gedmo\Translatable\Mapping\Event\Adapter;
  3. use Gedmo\Mapping\Event\Adapter\ODM as BaseAdapterODM;
  4. use Gedmo\Tool\Wrapper\AbstractWrapper;
  5. use Doctrine\ODM\MongoDB\DocumentManager;
  6. use Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo;
  7. use Doctrine\ODM\MongoDB\Cursor;
  8. use Gedmo\Translatable\Mapping\Event\TranslatableAdapter;
  9. use Doctrine\ODM\MongoDB\Mapping\Types\Type;
  10. /**
  11. * Doctrine event adapter for ODM adapted
  12. * for Translatable behavior
  13. *
  14. * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
  15. * @package Gedmo\Translatable\Mapping\Event\Adapter
  16. * @subpackage ODM
  17. * @link http://www.gediminasm.org
  18. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  19. */
  20. final class ODM extends BaseAdapterODM implements TranslatableAdapter
  21. {
  22. /**
  23. * {@inheritDoc}
  24. */
  25. public function usesPersonalTranslation($translationClassName)
  26. {
  27. return $this
  28. ->getObjectManager()
  29. ->getClassMetadata($translationClassName)
  30. ->getReflectionClass()
  31. ->isSubclassOf('Gedmo\Translatable\Document\MappedSuperclass\AbstractPersonalTranslation')
  32. ;
  33. }
  34. /**
  35. * {@inheritDoc}
  36. */
  37. public function getDefaultTranslationClass()
  38. {
  39. return 'Gedmo\\Translatable\\Document\\Translation';
  40. }
  41. /**
  42. * {@inheritDoc}
  43. */
  44. public function loadTranslations($object, $translationClass, $locale, $objectClass)
  45. {
  46. $dm = $this->getObjectManager();
  47. $wrapped = AbstractWrapper::wrap($object, $dm);
  48. $result = array();
  49. if ($this->usesPersonalTranslation($translationClass)) {
  50. // first try to load it using collection
  51. foreach ($wrapped->getMetadata()->fieldMappings as $mapping) {
  52. $isRightCollection = isset($mapping['association'])
  53. && $mapping['association'] === ClassMetadataInfo::REFERENCE_MANY
  54. && $mapping['targetDocument'] === $translationClass
  55. && $mapping['mappedBy'] === 'object'
  56. ;
  57. if ($isRightCollection) {
  58. $collection = $wrapped->getPropertyValue($mapping['fieldName']);
  59. foreach ($collection as $trans) {
  60. if ($trans->getLocale() === $locale) {
  61. $result[] = array(
  62. 'field' => $trans->getField(),
  63. 'content' => $trans->getContent()
  64. );
  65. }
  66. }
  67. return $result;
  68. }
  69. }
  70. $q = $dm
  71. ->createQueryBuilder($translationClass)
  72. ->field('object.$id')->equals($wrapped->getIdentifier())
  73. ->field('locale')->equals($locale)
  74. ->getQuery()
  75. ;
  76. } else {
  77. // load translated content for all translatable fields
  78. // construct query
  79. $q = $dm
  80. ->createQueryBuilder($translationClass)
  81. ->field('foreignKey')->equals($wrapped->getIdentifier())
  82. ->field('locale')->equals($locale)
  83. ->field('objectClass')->equals($objectClass)
  84. ->getQuery()
  85. ;
  86. }
  87. $q->setHydrate(false);
  88. $result = $q->execute();
  89. if ($result instanceof Cursor) {
  90. $result = $result->toArray();
  91. }
  92. return $result;
  93. }
  94. /**
  95. * {@inheritDoc}
  96. */
  97. public function findTranslation(AbstractWrapper $wrapped, $locale, $field, $translationClass, $objectClass)
  98. {
  99. $dm = $this->getObjectManager();
  100. $qb = $dm
  101. ->createQueryBuilder($translationClass)
  102. ->field('locale')->equals($locale)
  103. ->field('field')->equals($field)
  104. ->limit(1)
  105. ;
  106. if ($this->usesPersonalTranslation($translationClass)) {
  107. $qb->field('object.$id')->equals($wrapped->getIdentifier());
  108. } else {
  109. $qb->field('foreignKey')->equals($wrapped->getIdentifier());
  110. $qb->field('objectClass')->equals($objectClass);
  111. }
  112. $q = $qb->getQuery();
  113. $result = $q->execute();
  114. if ($result instanceof Cursor) {
  115. $result = current($result->toArray());
  116. }
  117. return $result;
  118. }
  119. /**
  120. * {@inheritDoc}
  121. */
  122. public function removeAssociatedTranslations(AbstractWrapper $wrapped, $transClass, $objectClass)
  123. {
  124. $dm = $this->getObjectManager();
  125. $qb = $dm
  126. ->createQueryBuilder($transClass)
  127. ->remove()
  128. ;
  129. if ($this->usesPersonalTranslation($transClass)) {
  130. $qb->field('object.$id')->equals($wrapped->getIdentifier());
  131. } else {
  132. $qb->field('foreignKey')->equals($wrapped->getIdentifier());
  133. $qb->field('objectClass')->equals($objectClass);
  134. }
  135. $q = $qb->getQuery();
  136. return $q->execute();
  137. }
  138. /**
  139. * {@inheritDoc}
  140. */
  141. public function insertTranslationRecord($translation)
  142. {
  143. $dm = $this->getObjectManager();
  144. $meta = $dm->getClassMetadata(get_class($translation));
  145. $collection = $dm->getDocumentCollection($meta->name);
  146. $data = array();
  147. foreach ($meta->getReflectionProperties() as $fieldName => $reflProp) {
  148. if (!$meta->isIdentifier($fieldName)) {
  149. $data[$meta->fieldMappings[$fieldName]['name']] = $reflProp->getValue($translation);
  150. }
  151. }
  152. if (!$collection->insert($data)) {
  153. throw new \Gedmo\Exception\RuntimeException('Failed to insert new Translation record');
  154. }
  155. }
  156. /**
  157. * {@inheritDoc}
  158. */
  159. public function getTranslationValue($object, $field, $value = false)
  160. {
  161. $dm = $this->getObjectManager();
  162. $wrapped = AbstractWrapper::wrap($object, $dm);
  163. $meta = $wrapped->getMetadata();
  164. $mapping = $meta->getFieldMapping($field);
  165. $type = Type::getType($mapping['type']);
  166. if ($value === false) {
  167. $value = $wrapped->getPropertyValue($field);
  168. }
  169. return $type->convertToDatabaseValue($value);
  170. }
  171. /**
  172. * {@inheritDoc}
  173. */
  174. public function setTranslationValue($object, $field, $value)
  175. {
  176. $dm = $this->getObjectManager();
  177. $wrapped = AbstractWrapper::wrap($object, $dm);
  178. $meta = $wrapped->getMetadata();
  179. $mapping = $meta->getFieldMapping($field);
  180. $type = Type::getType($mapping['type']);
  181. $value = $type->convertToPHPValue($value);
  182. $wrapped->setPropertyValue($field, $value);
  183. }
  184. }