web-dev-qa-db-fra.com

comment trier arrayCollection d'une entité dans symfony2

J'ai une entité "container" avec cette propriété

/**
 * @ORM\OneToMany(targetEntity="BizTV\ContentManagementBundle\Entity\Content", mappedBy="container")
 */
private $content;

la propriété est une collection de tableaux ...

public function __construct() {
    $this->content = new \Doctrine\Common\Collections\ArrayCollection();
}

... avec ces deux méthodes standard

/**
 * Add content
 *
 * @param BizTV\ContentManagementBundle\Entity\Content $content
 */
public function addContent(\BizTV\ContentManagementBundle\Entity\Content $content)
{
    $this->content[] = $content;
}

/**
 * Get content
 *
 * @return Doctrine\Common\Collections\Collection 
 */
public function getContent()
{
    return $this->content;
}

Maintenant, ma question est, existe-t-il un moyen simple de créer une fonctionnalité de tri dans cela, peut-être sur l'appel getContent ()? Je ne suis pas un php wiz et certainement pas assaisonné de symfony2 mais j'apprends au fur et à mesure.

L'entité de contenu elle-même a un INT de tri comme celui-ci sur lequel je veux le trier:

/**
 * @var integer $sortOrder
 *
 * @ORM\Column(name="sort_order", type="integer")
 */
private $sortOrder; 
30
Matt Welander

Vous devriez pouvoir utiliser l'instruction @ ORM\OrderBy qui vous permet de spécifier des colonnes pour commander des collections sur:

/**
 * @ORM\OneToMany(targetEntity="BizTV\ContentManagementBundle\Entity\Content", mappedBy="container")
 * @ORM\OrderBy({"sort_order" = "ASC"})
 */
private $content;

En fait, cela peut être un doublon de Comment commander par OneToMany/ManyToOne

Éditer

En vérifiant les conseils d'implémentation, il apparaît que vous devez récupérer les tables avec une requête de jointure dans la collection pour que l'annotation @ORM\OrderBy fonctionne: http://www.krueckeberg.org/notes/d2.html

Cela signifie que vous devez écrire une méthode dans le référentiel pour renvoyer le conteneur avec la table des contenus jointe.

63
Luke

Si vous voulez être sûr d'obtenir toujours vos relations dans l'ordre basé sur les valeurs de propriété actuelles, vous pouvez faire quelque chose comme ceci:

$sort = new Criteria(null, ['Order' => Criteria::ASC]);
return $this->yourCollectionProperty->matching($sort);

Utilisez-le par exemple si vous avez modifié la propriété Order. Fonctionne également très bien pour une "date de dernière modification".

19

Tu peux écrire

@ORM\OrderBy({"date" = "ASC", "time" = "ASC"})

pour la commande multicritères.

Vous pouvez également trier ArrayCollection par Criteria propriété orderBy comme ceci:

<?php
    namespace App/Service;

    use Doctrine\Common\Collections\ArrayCollection;
    use Doctrine\Common\Collections\Criteria;

    /**
     * Class SortService
     *
     * @package App\Service
     */
    class SortService {
        /**
         * @param SomeAbstractObject $object
         * @return SomeCollectionItem[]
         */
        public function sorted(SomeAbstractObject $object): array {
            /** $var ArrayCollection|SomeCollectionItem[] */
            $collection = $object->getCollection();

            // convert normal array to array collection object
            if(\is_array(collection)) {
                $collection = new ArrayCollection(collection);
            }

            // order collection items by position property
            $orderBy = (Criteria::create())->orderBy([
                'position' => Criteria::ASC,
            ]);

            // return sorter SomeCollectionItem array
            return $collection->matching($orderBy)->toArray();
        }
    }
?>
1
HelpNeeder