Преглед изворни кода

[Translatable] Sort localized integer in numerical order instead of alphabetical

Denis Chmel пре 13 година
родитељ
комит
c01921de68

+ 15 - 10
lib/Gedmo/Translatable/Query/TreeWalker/TranslationWalker.php

@@ -285,17 +285,22 @@ class TranslationWalker extends SqlWalker
                     $sql .= ' AND '.$tblAlias.'.'.$transMeta->getQuotedColumnName('foreignKey', $this->platform)
                         .' = '.$compTblAlias.'.'.$colName;
                     isset($this->components[$dqlAlias]) ? $this->components[$dqlAlias] .= $sql : $this->components[$dqlAlias] = $sql;
+
+                    $originalField = $compTblAlias.'.'.$meta->getQuotedColumnName($field, $this->platform);
+                    $substituteField = $tblAlias . '.' . $transMeta->getQuotedColumnName('content', $this->platform);
+
+                    // If original field is integer - treat translation as integer (for ORDER BY, WHERE, etc)
+                    $fieldMapping = $meta->getFieldMapping($field);
+                    if (in_array($fieldMapping["type"], array("integer", "bigint", "tinyint", "int"))) {
+                        $substituteField = 'CAST(' . $substituteField . ' AS SIGNED)';
+                    }
+
+                    // Fallback to original if was asked for
                     if ($this->needsFallback()) {
-                        // COALESCE with the original record columns
-                        $this->replacements[$compTblAlias.'.'.$meta->getQuotedColumnName($field, $this->platform)]
-                            = 'COALESCE('.$tblAlias.'.'.$transMeta->getQuotedColumnName('content', $this->platform)
-                            .', '.$compTblAlias.'.'.$meta->getQuotedColumnName($field, $this->platform).')'
-                        ;
-                    } else {
-                        $this->replacements[$compTblAlias.'.'.$meta->getQuotedColumnName($field, $this->platform)]
-                            = $tblAlias.'.'.$transMeta->getQuotedColumnName('content', $this->platform)
-                        ;
+                        $substituteField = 'COALESCE('.$substituteField.', '.$originalField.')';
                     }
+
+                    $this->replacements[$originalField] = $substituteField;
                 }
             }
         }
@@ -385,4 +390,4 @@ class TranslationWalker extends SqlWalker
         }
         return $str;
     }
-}
+}

+ 17 - 1
tests/Gedmo/Translatable/Fixture/Article.php

@@ -26,6 +26,12 @@ class Article implements Translatable
      */
     private $content;
 
+    /**
+     * @Gedmo\Translatable
+     * @ORM\Column(name="views", type="integer", nullable=true)
+     */
+    private $views;
+
     /**
      * Used locale to override Translation listener`s locale
      * @Gedmo\Locale
@@ -77,4 +83,14 @@ class Article implements Translatable
     {
         $this->locale = $locale;
     }
-}
+
+    public function setViews ($views)
+    {
+        $this->views = $views;
+    }
+
+    public function getViews ()
+    {
+        return $this->views;
+    }
+}

+ 45 - 4
tests/Gedmo/Translatable/TranslationQueryWalkerTest.php

@@ -348,6 +348,39 @@ class TranslationQueryWalkerTest extends BaseTestCaseORM
         $this->assertEquals('Moteris', $result[3]->getTitle());
     }
 
+    public function testSelectOrderedByTranslatableInteger()
+    {
+        // Given
+        $this->populateMore();
+        $dql = 'SELECT a.title, a.views FROM ' . self::ARTICLE . ' a';
+        $dql .= ' ORDER BY a.views';
+        $q = $this->em->createQuery($dql);
+        $q->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, self::TREE_WALKER_TRANSLATION);
+
+        // Test original
+        $this->translationListener->setTranslatableLocale('en_us');
+        $result = $q->getArrayResult();
+        array_walk($result, function($value, $key) use(&$result) {
+            // Make each record be a "Title - Views" string
+            $result[$key] = implode(" - ", $value);
+        });
+        $this->assertEquals(
+            array("Alfabet - 1", "Food - 99", "Cabbages - 2222", "Woman - 3333"), $result,
+            "Original of localizible integers should be sorted numerically"
+        );
+
+        $this->translationListener->setTranslatableLocale('lt_lt');
+        $result = $q->getArrayResult();
+        array_walk($result, function($value, $key) use(&$result) {
+            // Make each record be a "Title - Views" string
+            $result[$key] = implode(" - ", $value);
+        });
+        $this->assertEquals(
+            array("Moteris - 33", "Alfabetas - 111", "Maistas - 999", "Kopustai - 22222"), $result,
+            "Localized integers should be sorted numerically"
+        );
+    }
+
     public function testSelectSecondJoinedComponentTranslation()
     {
         $this->em
@@ -367,7 +400,7 @@ class TranslationQueryWalkerTest extends BaseTestCaseORM
         $result = $q->getArrayResult();
         $this->assertEquals(1, count($result));
         $food = $result[0];
-        $this->assertEquals(4, count($food));
+        $this->assertEquals(5, count($food));
         $this->assertEquals('Food', $food['title']);
         $this->assertEquals('about food', $food['content']);
         $comments = $food['comments'];
@@ -385,7 +418,7 @@ class TranslationQueryWalkerTest extends BaseTestCaseORM
         $result = $q->getArrayResult();
         $this->assertEquals(1, count($result));
         $food = $result[0];
-        $this->assertEquals(4, count($food));
+        $this->assertEquals(5, count($food));
         $this->assertEquals('Maistas', $food['title']);
         $this->assertEquals('apie maista', $food['content']);
         $comments = $food['comments'];
@@ -492,14 +525,14 @@ class TranslationQueryWalkerTest extends BaseTestCaseORM
         $result = $q->getArrayResult();
         $this->assertEquals(1, count($result));
         $food = $result[0];
-        $this->assertEquals(3, count($food));
+        $this->assertEquals(4, count($food));
         $this->assertEquals('Food', $food['title']);
         $this->assertEquals('about food', $food['content']);
         $this->translationListener->setTranslatableLocale('lt_lt');
         $result = $q->getArrayResult();
         $this->assertEquals(1, count($result));
         $food = $result[0];
-        $this->assertEquals(3, count($food));
+        $this->assertEquals(4, count($food));
         $this->assertEquals('Maistas', $food['title']);
         $this->assertEquals('apie maista', $food['content']);
 
@@ -556,14 +589,17 @@ class TranslationQueryWalkerTest extends BaseTestCaseORM
         $alfabet = new Article;
         $alfabet->setTitle('Alfabet');
         $alfabet->setContent('hey wtf!');
+        $alfabet->setViews(1);
 
         $woman = new Article;
         $woman->setTitle('Woman');
         $woman->setContent('i like them');
+        $woman->setViews(3333);
 
         $cabbages = new Article;
         $cabbages->setTitle('Cabbages');
         $cabbages->setContent('where went the woman?');
+        $cabbages->setViews(2222);
 
         $this->em->persist($alfabet);
         $this->em->persist($woman);
@@ -575,14 +611,17 @@ class TranslationQueryWalkerTest extends BaseTestCaseORM
         $alfabet = $repo->find(2);
         $alfabet->setTitle('Alfabetas');
         $alfabet->setContent('ei wtf!');
+        $alfabet->setViews(111);
 
         $woman = $repo->find(3);
         $woman->setTitle('Moteris');
         $woman->setContent('as megstu jas');
+        $woman->setViews(33);
 
         $cabbages = $repo->find(4);
         $cabbages->setTitle('Kopustai');
         $cabbages->setContent('kur dingo moteris?');
+        $cabbages->setViews(22222);
 
         $this->em->persist($alfabet);
         $this->em->persist($woman);
@@ -599,6 +638,7 @@ class TranslationQueryWalkerTest extends BaseTestCaseORM
         $food = new Article;
         $food->setTitle('Food');
         $food->setContent('about food');
+        $food->setViews(99);
 
         $goodFood = new Comment;
         $goodFood->setArticle($food);
@@ -620,6 +660,7 @@ class TranslationQueryWalkerTest extends BaseTestCaseORM
         $food = $repo->find(1);
         $food->setTitle('Maistas');
         $food->setContent('apie maista');
+        $food->setViews(999);
 
         $goodFood = $commentRepo->find(1);
         $goodFood->setArticle($food);