Reputation: 35
Is it possible to order a ManyToMany relation by a column of a joined table in an entity with annotations?
I‘ve already tried to get it work with @ORM\JoinTable
and @ORM\JoinColumn
but this doesn‘t seem to work.
class Product {
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Category")
* @ORM\OrderBy({"name" = "ASC"})
*/
private $categories;
}
class Category {
use Knp\Translatable;
}
class CategoryTranslation {
use Knp\Translation;
/**
* @ORM\Column(type="string", length=255)
*/
private $name;
}
I would like to do something like @OrderBy({"CategoryTranslation.name" = "ASC")
in the Product entity. Or is there a way to execute a repository method in the @ManyToMany
annotation to manually build a query to select the categories with the right order?
Upvotes: 1
Views: 510
Reputation: 35
I finally solved it the way @ehymel described in his answer but i am using the uasort method of the ArrayIterator object. Im not very happy with this solution because an additional $locale
parameter is used in the getter method and i would prefere to order the items with SQL/DQL but not an additional PHP loop. But for the moment it works.
public function getCategories(?string $locale = null)
{
$iterator = $this->categories->getIterator();
$iterator->uasort(function (Category $a, Category $b) use ($locale) {
return ($a->translate($locale)->getName() < $b->translate($locale)->getName()) ? -1 : 1;
});
return new ArrayCollection(iterator_to_array($iterator));
}
Upvotes: 1
Reputation: 1391
Not sure you can do it through annotations, but I've achieved the result you are looking for with a simple uasort
function. In your Product
entity try something like the following for your getCategories()
getter.
public function getCategories()
{
$categories = $this->categories;
uasort($catetories, [$this, 'mySortCategories']);
return $categories;
}
private function mySortCategories(Category $cat1, Category $cat2)
{
if ($cat1->getName() === $cat2->getName()) {
return 0;
}
return ($cat1->getName() < $cat2->getName()) ? -1 : 1;
}
Upvotes: 2