"Usort" a Doctrine\Common\Collections\Arraycollection

usort a Doctrine\Common\Collections\ArrayCollection?

To sort an existing Collection you are looking for the ArrayCollection::getIterator() method which returns an ArrayIterator. example:

$iterator = $collection->getIterator();
$iterator->uasort(function ($a, $b) {
return ($a->getPropery() < $b->getProperty()) ? -1 : 1;
});
$collection = new ArrayCollection(iterator_to_array($iterator));

The easiest way would be letting the query in the repository handle your sorting.

Imagine you have a SuperEntity with a ManyToMany relationship with Category entities.

Then for instance creating a repository method like this:

// 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()
;
}

... makes sorting pretty easy.

how to sort an entity's arrayCollection in symfony2

You should be able to use the @ORM\OrderBy statement which allows you to specify columns to order collections on:

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

In fact this may be a duplicate of How to OrderBy on OneToMany/ManyToOne

Edit

Checking for implementation advice it appears that you must fetch the tables with a join query to the collection in order for the @ORM\OrderBy annotation to work: http://www.krueckeberg.org/notes/d2.html

This means that you must write a method in the repository to return the container with the contents table joined.

Type error: Argument 1 passed to Doctrine\Common\Collections\ArrayCollection::__construct() must be of the type array, object given

No $book->setUsers($user); but $book->addUser($user);

And, in general, method setUsers is not valid

public function setUsers(Users $users = null)
{
$this->users = $users;
}

You must not redefine this property after being initialized in the constructor. You can only add or remove elements from it, but assigning new value will break doctrine's functionality.

ManyToMany error : Argument 1 passed to Doctrine\Common\Collections\ArrayCollection::__construct() must be of the type array, object given

Your Service::clients property is marked with @ManyToMany annotation, which means it should be typed @var Collection|Clients[] but both getter and setter returns/set a nullable object ?Clients $clients.

No way the bin/console make:entity did that.

You should use the same system as your Clients::services property, i.e using three methods getClients(), addClients() and removeClients() without setClients(). Besides, you need a constructor starting the $clients property: $this->clients = new ArrayCollection();.

Or maybe you want to use @OneToMany and @ManyToOne annotations.

Note that an entity classname should be singular.

Sort a doctrine's @OneToMany ArrayCollection

Try using the doctrine2 ORM functionality for Ordering To-Many Associations like this:

/**
* @var ArrayCollection[SubjectTag]
*
* @ORM\OneToMany(targetEntity="SubjectTag", mappedBy="subject")
* @ORM\OrderBy({"position" = "ASC"})
* @Assert\Count(max = 10, maxMessage = "You can't create more than 10 tags.")
* @Assert\Valid()
*/
protected $subjectTags;

Hope this help

Symfony : How to sort ArrayCollection in a OneToMany relation (3 entities)?

You can't do it directly. But there is a workaround.

  • Add a ordered tags property to you Product entity :

    private $orderedTags;

    public function __construct()
    {
    //...
    $this->orderedTags = new \Doctrine\Common\Collections\ArrayCollection();
    }
  • Create a new doctrine Event Listener and register in in services.yml

    services:
    my.listener:
    class: AppBundle\EventListener\OrderedTagsListener
    arguments: ["@doctrine.orm.entity_manager"]
    tags:
    - { name: doctrine.event_listener, event: postLoad }

    // src/AppBundle/EventListener/OrderedTagsListener.php
    namespace AppBundle\EventListener;

    use Doctrine\ORM\Event\LifecycleEventArgs;
    use AppBundle\Entity\Product;

    class OrderedTagsListener
    {
    private $em;

    public function __construct($em)
    {
    $this->em = $em;
    }

    public function postPersist(LifecycleEventArgs $args)
    {
    $product = $args->getEntity();

    // Retrieve your tags ordered with a query defined in your tags repository
    $orderedTags = $this->em->getManager()->getRepository('AppBundle:Tags')->getOrderedTags($product);

    $product->setOrderedTags();
    }
    }


Related Topics



Leave a reply



Submit