Explorar el Código

Fix values in default locale for entities with >1 translatable fields

Christian Aistleitner hace 12 años
padre
commit
c1b2905322

+ 1 - 1
lib/Gedmo/Translatable/Entity/Repository/TranslationRepository.php

@@ -83,7 +83,7 @@ class TranslationRepository extends EntityRepository
                 $transMeta->getReflectionProperty('locale')->setValue($trans, $locale);
                 if ($listener->getDefaultLocale() != $listener->getTranslatableLocale($entity, $meta) &&
                     $locale === $listener->getDefaultLocale()) {
-                    $listener->setTranslationInDefaultLocale(spl_object_hash($entity), $trans);
+                    $listener->setTranslationInDefaultLocale(spl_object_hash($entity), $field, $trans);
                     $needsPersist = $listener->getPersistDefaultLocaleTranslation();
                 }
             }

+ 29 - 10
lib/Gedmo/Translatable/TranslatableListener.php

@@ -499,8 +499,9 @@ class TranslatableListener extends MappedEventSubscriber
                 if ($locale !== $this->defaultLocale
                     && get_class($trans) === $translationClass
                     && $trans->getLocale() === $this->defaultLocale
+                    && $trans->getField() === $field
                     && $trans->getObject() === $object) {
-                    $this->setTranslationInDefaultLocale($oid, $trans);
+                    $this->setTranslationInDefaultLocale($oid, $field, $trans);
                     break;
                 }
             }
@@ -569,13 +570,13 @@ class TranslatableListener extends MappedEventSubscriber
                 }
             }
 
-            if ($isInsert && $this->getTranslationInDefaultLocale($oid) !== null) {
+            if ($isInsert && $this->getTranslationInDefaultLocale($oid, $field) !== null) {
                 // We can't rely on object field value which is created in non default locale.
                 // If we provide translation for default locale as well, the latter is considered to be trusted
                 // and object content should be overridden.
-                $wrapped->setPropertyValue($field, $this->getTranslationInDefaultLocale($oid)->getContent());
+                $wrapped->setPropertyValue($field, $this->getTranslationInDefaultLocale($oid, $field)->getContent());
                 $ea->recomputeSingleObjectChangeset($uow, $meta, $object);
-                $this->removeTranslationInDefaultLocale($oid);
+                $this->removeTranslationInDefaultLocale($oid, $field);
             }
         }
         $this->translatedInLocale[$oid] = $locale;
@@ -610,11 +611,15 @@ class TranslatableListener extends MappedEventSubscriber
      * Sets translation object which represents translation in default language.
      *
      * @param    string    $oid     hash of basic entity
+     * @param    string    $field   field of basic entity
      * @param    mixed     $trans   Translation object
      */
-    public function setTranslationInDefaultLocale($oid, $trans)
+    public function setTranslationInDefaultLocale($oid, $field, $trans)
     {
-        $this->translationInDefaultLocale[$oid] = $trans;
+        if (!isset($this->translationInDefaultLocale[$oid])) {
+            $this->translationInDefaultLocale[$oid] = array();
+        }
+        $this->translationInDefaultLocale[$oid][$field] = $trans;
     }
 
     /**
@@ -622,11 +627,20 @@ class TranslatableListener extends MappedEventSubscriber
      * This is for internal use only.
      *
      * @param string    $oid     hash of the basic entity
+     * @param string    $field   field of basic entity
      */
-    private function removeTranslationInDefaultLocale($oid)
+    private function removeTranslationInDefaultLocale($oid, $field)
     {
         if (isset($this->translationInDefaultLocale[$oid])) {
-            unset($this->translationInDefaultLocale[$oid]);
+            if (isset($this->translationInDefaultLocale[$oid][$field])) {
+                unset($this->translationInDefaultLocale[$oid][$field]);
+            }
+            if (! $this->translationInDefaultLocale[$oid]) {
+                // We removed the final remaining elements from the
+                // translationInDefaultLocale[$oid] array, so we might as well
+                // completely remove the entry at $oid.
+                unset($this->translationInDefaultLocale[$oid]);
+            }
         }
     }
 
@@ -635,12 +649,17 @@ class TranslatableListener extends MappedEventSubscriber
      * This is for internal use only.
      *
      * @param    string    $oid   hash of the basic entity
+     * @param    string    $field field of basic entity
      * @return   mixed     Returns translation object if it exists or NULL otherwise
      */
-    private function getTranslationInDefaultLocale($oid)
+    private function getTranslationInDefaultLocale($oid, $field)
     {
         if (array_key_exists($oid, $this->translationInDefaultLocale)) {
-            $ret = $this->translationInDefaultLocale[$oid];
+            if (array_key_exists($field, $this->translationInDefaultLocale[$oid])) {
+                $ret = $this->translationInDefaultLocale[$oid][$field];
+            } else {
+                $ret = null;
+            }
         } else {
             $ret = null;
         }

+ 108 - 0
tests/Gedmo/Translatable/TranslatableEntityDefaultTranslationTest.php

@@ -287,6 +287,114 @@ class TranslatableEntityDefaultTranslationTest extends BaseTestCaseORM
         $this->assertEquals('title defaultLocale', $articles[0]['title']);
     }
 
+    function testTwoFieldsWithoutPersistingDefault()
+    {
+        $this->translatableListener->setPersistDefaultLocaleTranslation( false );
+        $entity = new Article;
+        $this->repo
+            ->translate($entity, 'title'  , 'translatedLocale', 'title translatedLocale'  )
+            ->translate($entity, 'title'  , 'defaultLocale'   , 'title defaultLocale'     )
+            ->translate($entity, 'content', 'translatedLocale', 'content translatedLocale')
+            ->translate($entity, 'content', 'defaultLocale'   , 'content defaultLocale'   )
+        ;
+
+        $this->em->persist($entity);
+        $this->em->flush();
+        $this->em->clear();
+
+        $trans = $this->repo->findTranslations($this->em->find(self::ARTICLE, $entity->getId()));
+        $this->assertCount(1, $trans);
+        $this->assertSame('title translatedLocale'  , $trans['translatedLocale']['title']);
+        $this->assertSame('content translatedLocale', $trans['translatedLocale']['content']);
+
+        $articles = $this->em->createQuery('SELECT a FROM ' . self::ARTICLE . ' a')->getArrayResult();
+        $this->assertCount(1, $articles);
+        $this->assertEquals('title defaultLocale'  , $articles[0]['title']  );
+        $this->assertEquals('content defaultLocale', $articles[0]['content']);
+    }
+
+    function testTwoFieldsWithoutPersistingDefaultResorted()
+    {
+        $this->translatableListener->setPersistDefaultLocaleTranslation( false );
+        $entity = new Article;
+        $this->repo
+            ->translate($entity, 'title'  , 'defaultLocale'   , 'title defaultLocale'     )
+            ->translate($entity, 'title'  , 'translatedLocale', 'title translatedLocale'  )
+            ->translate($entity, 'content', 'defaultLocale'   , 'content defaultLocale'   )
+            ->translate($entity, 'content', 'translatedLocale', 'content translatedLocale')
+        ;
+
+        $this->em->persist($entity);
+        $this->em->flush();
+        $this->em->clear();
+
+        $trans = $this->repo->findTranslations($this->em->find(self::ARTICLE, $entity->getId()));
+        $this->assertCount(1, $trans);
+        $this->assertSame('title translatedLocale'  , $trans['translatedLocale']['title']);
+        $this->assertSame('content translatedLocale', $trans['translatedLocale']['content']);
+
+        $articles = $this->em->createQuery('SELECT a FROM ' . self::ARTICLE . ' a')->getArrayResult();
+        $this->assertCount(1, $articles);
+        $this->assertEquals('title defaultLocale'  , $articles[0]['title']  );
+        $this->assertEquals('content defaultLocale', $articles[0]['content']);
+    }
+
+    function testTwoFieldsWithPersistingDefault()
+    {
+        $this->translatableListener->setPersistDefaultLocaleTranslation( true );
+        $entity = new Article;
+        $this->repo
+            ->translate($entity, 'title'  , 'translatedLocale', 'title translatedLocale'  )
+            ->translate($entity, 'title'  , 'defaultLocale'   , 'title defaultLocale'     )
+            ->translate($entity, 'content', 'translatedLocale', 'content translatedLocale')
+            ->translate($entity, 'content', 'defaultLocale'   , 'content defaultLocale'   )
+        ;
+
+        $this->em->persist($entity);
+        $this->em->flush();
+        $this->em->clear();
+
+        $trans = $this->repo->findTranslations($this->em->find(self::ARTICLE, $entity->getId()));
+        $this->assertCount(2, $trans);
+        $this->assertSame('title translatedLocale'  , $trans['translatedLocale']['title']);
+        $this->assertSame('title defaultLocale'     , $trans['defaultLocale']['title']);
+        $this->assertSame('content translatedLocale', $trans['translatedLocale']['content']);
+        $this->assertSame('content defaultLocale'   , $trans['defaultLocale']['content']);
+
+        $articles = $this->em->createQuery('SELECT a FROM ' . self::ARTICLE . ' a')->getArrayResult();
+        $this->assertCount(1, $articles);
+        $this->assertEquals('title defaultLocale'  , $articles[0]['title']  );
+        $this->assertEquals('content defaultLocale', $articles[0]['content']);
+    }
+
+    function testTwoFieldsWithPersistingDefaultResorted()
+    {
+        $this->translatableListener->setPersistDefaultLocaleTranslation( true );
+        $entity = new Article;
+        $this->repo
+            ->translate($entity, 'title'  , 'defaultLocale'   , 'title defaultLocale'     )
+            ->translate($entity, 'title'  , 'translatedLocale', 'title translatedLocale'  )
+            ->translate($entity, 'content', 'defaultLocale'   , 'content defaultLocale'   )
+            ->translate($entity, 'content', 'translatedLocale', 'content translatedLocale')
+        ;
+
+        $this->em->persist($entity);
+        $this->em->flush();
+        $this->em->clear();
+
+        $trans = $this->repo->findTranslations($this->em->find(self::ARTICLE, $entity->getId()));
+        $this->assertCount(2, $trans);
+        $this->assertSame('title translatedLocale'  , $trans['translatedLocale']['title']);
+        $this->assertSame('title defaultLocale'     , $trans['defaultLocale']['title']);
+        $this->assertSame('content translatedLocale', $trans['translatedLocale']['content']);
+        $this->assertSame('content defaultLocale'   , $trans['defaultLocale']['content']);
+
+        $articles = $this->em->createQuery('SELECT a FROM ' . self::ARTICLE . ' a')->getArrayResult();
+        $this->assertCount(1, $articles);
+        $this->assertEquals('title defaultLocale'  , $articles[0]['title']  );
+        $this->assertEquals('content defaultLocale', $articles[0]['content']);
+    }
+
 
 
     // --- Fixture related methods ---------------------------------------------