Leïllah
Leïllah

Reputation: 1

Symfony : OrderBy in CollectionType

I have two tables (Player & Historique) that have a OneToMany association. In my PlayerType form, I have a CollectionType with an entry_type to my HistoriqueType. My question is about the order in which the data from HistoriqueType arrives. For the moment, it appears in ASC order of the id. But I would like it to appear in ASC order of the years (season).

Here are my two entities :

<?php

/**
 * @ORM\Entity(repositoryClass=PlayerRepository::class)
 */
class Player
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $name;

    
    /**
     * @ORM\OneToMany(targetEntity=Historique::class, mappedBy="player", cascade={"persist"}, orphanRemoval = true)
     */
    public $playerHistoriques;


public function __construct()
{
    $this->playerHistoriques = new ArrayCollection();
}

And my Historique Class :

<?php

/**
 * @ORM\Entity(repositoryClass=HistoriqueRepository::class)
 */
class Historique
{
/**
 * @ORM\Id
 * @ORM\GeneratedValue
 * @ORM\Column(type="integer")
 */
private $id;

/**
 * @ORM\ManyToOne(targetEntity=Club::class, inversedBy="historiques")
 * @ORM\JoinColumn(nullable=true)
 */
private $club;

/**
 * @ORM\ManyToOne(targetEntity=Season::class, inversedBy="historiques")
 * @ORM\JoinColumn(nullable=true)
 * @ORM\OrderBy({"season" = "ASC"})
 */
private $season;

/**
 * @ORM\ManyToOne(targetEntity=Player::class, inversedBy="playerHistoriques")
 * @ORM\JoinColumn(nullable=true)
 */
private $player;

/**
 * @ORM\ManyToOne(targetEntity=Position::class, inversedBy="historiques")
 */
private $position;

My PlayerType :

<?php

class PlayerType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('name')
        ->add('playerHistoriques', CollectionType::class, [
            'entry_type' => HistoriqueType::class,
            'entry_options' => [
                'label' => false
            ],
            'by_reference' => false,
            'allow_add' => true
        ])
    ;
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'data_class' => Player::class,
    ]);
}
}

And My HistoriqueType:

<?php

class HistoriqueType extends AbstractType
{

public function buildForm(FormBuilderInterface $builder, array $options)
{

    $builder
        ->add('club', EntityType::class, [
            'class' => Club::class,
            'choice_label' => 'name',
            'label' => false,
            'required' => false,
            'placeholder' => '-',
            'query_builder' => function (EntityRepository $er) {
                return $er->createQueryBuilder('c')
                    ->orderBy('c.name', 'ASC');
            }
        ])
        ->add('season', EntityType::class, [
            'class' => Season::class,
            'choice_label' => 'year',
            'label' => false,
            'placeholder' => '-',
            'query_builder' => function (EntityRepository $er) {
                return $er->createQueryBuilder('s')
                    ->orderBy('s.year', 'ASC');
            }
        ])
        ->add('position', EntityType::class, [
            'class' => Position::class,
            'choice_label' => 'position',
            'label' => false,
            'placeholder' => '-',
            'required' => false
        ])
    ;
    
}


public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'data_class' => Historique::class,
        'method' => 'get',
        'csrf_protection' => false
    ]);
}

public function getBlockPrefix() {
    return '';
}
}

In my edit form, I would like to order my collectionType by 'season' => 'ASC', in order to have the years in chronological order even in my edit form.

I have tried a query_builder like so in my PlayerType :

'query_builder' => function (EntityRepository $er) {
                return $er->createQueryBuilder('h')
                          ->orderBy('h.season', 'ASC');
            }

But it generated an error since collectionTypes cannot have queries in them.

I have tried to order it automatically in my PlayerEntity @ORM\OrderBy({"season" = "ASC"}) but it didn't work.

Upvotes: 0

Views: 1231

Answers (2)

hous
hous

Reputation: 2679

OrderBy must be in Palyer entity in OneToMany relation not in Historique

/**
 *@ORM\OneToMany(targetEntity=Historique::class, mappedBy="player", cascade={"persist"}, orphanRemoval = true)
 *@ORM\OrderBy({"season" = "ASC"})
*/
public $playerHistoriques;

Upvotes: 2

Michael
Michael

Reputation: 56

In your Historique Entity change the order by to year instead of season (I believe in your other form you are sorting by the year so hopefully this is the property you are looking to sort by).

/**
 * @ORM\ManyToOne(targetEntity=Season::class, inversedBy="historiques")
 * @ORM\JoinColumn(nullable=true)
 * @ORM\OrderBy({"year" = "ASC"})
 */
private $season;

You should be able to remove the query builder now, unless you need to narrow the selection.

Upvotes: 1

Related Questions