Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort a doctrine's @OneToMany ArrayCollection

My question is close to this one, but does not exactly fit with mine.

I've this column in an entity:

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

I want to dynamically order my tags by a position, defined in SubjectTag.position.

like image 810
Alain Tiemblo Avatar asked Dec 14 '14 12:12

Alain Tiemblo


2 Answers

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

like image 185
Matteo Avatar answered Nov 05 '22 15:11

Matteo


I found a solution, using @HasLifeCycleCallbacks.

use Doctrine\ORM\Mapping as ORM;

/**
 * ...
 * @ORM\HasLifecycleCallbacks
 */
class Subject
{

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


    /**
     * @ORM\PostLoad
     */
    public function onPostLoad()
    {
        $tags = $this->subjectTags->toArray();
        usort($tags, function($a, $b)
        {
            return $a->getPosition() == $b->getPosition() ? 0 : ($a->getPosition() > $b->getPosition() : -1 : 1);
        });
        $this->subjectTags = new ArrayCollection($tags);
    }

}
like image 38
Alain Tiemblo Avatar answered Nov 05 '22 14:11

Alain Tiemblo