Dans divers cas, je dois trier un Doctrine\Common\Collections\ArrayCollection
selon une propriété de l'objet. Sans trouver une méthode pour le faire tout de suite, je fais ceci:
// $collection instanceof Doctrine\Common\Collections\ArrayCollection
$array = $collection->getValues();
usort($array, function($a, $b){
return ($a->getProperty() < $b->getProperty()) ? -1 : 1 ;
});
$collection->clear();
foreach ($array as $item) {
$collection->add($item);
}
Je suppose que ce n'est pas le meilleur moyen lorsque vous devez tout copier dans le tableau natif PHP et inversement. Je me demande s'il y a une meilleure façon "d'usorter" un Doctrine\Common\Collections\ArrayCollection
. Dois-je manquer un doc?
Pour trier une collection existante, vous recherchez la méthode ArrayCollection :: getIterator () qui renvoie un ArrayIterator. Exemple:
$iterator = $collection->getIterator();
$iterator->uasort(function ($a, $b) {
return ($a->getPropery() < $b->getProperty()) ? -1 : 1;
});
$collection = new ArrayCollection(iterator_to_array($iterator));
Le moyen le plus simple serait de laisser la requête dans le référentiel gérer votre tri.
Imaginez que vous ayez une SuperEntity avec une relation ManyToMany avec des entités de catégorie.
Ensuite, par exemple, créer une méthode de référentiel comme celle-ci:
// Vendor/YourBundle/Entity/SuperEntityRepository.php
public function findByCategoryAndOrderByName($category)
{
return $this->createQueryBuilder('e')
->where('e.category = :category')
->setParameter('category', $category)
->orderBy('e.name', 'ASC')
->getQuery()
->getResult()
;
}
... facilite le tri.
J'espère que ça t'as aidé.
Depuis Doctrine 2.3 vous pouvez utiliser Criteria API
Par exemple:
<?php
public function getSortedComments()
{
$criteria = Criteria::create()
->orderBy(array("created_at" => Criteria::ASC));
return $this->comments->matching($criteria);
}
Remarque: cette solution nécessite un accès public à la propriété
$createdAt
Ou à une méthode getter publiquegetCreatedAt()
.
Si vous avez un champ ArrayCollection, vous pouvez commander avec des annotations. par exemple:
Supposons qu'une entité nommée Society possède de nombreuses licences. Vous pourriez utiliser
/**
* @ORM\OneToMany(targetEntity="License", mappedBy="society")
* @ORM\OrderBy({"endDate" = "DESC"})
**/
private $licenses;
Cela ordonnera ArrayCollection par endDate (champ datetime) dans l'ordre desc.
Voir Doctrine: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#orderby =