Versions

2014/04/20 : Création
2014/08/05 : plus de création d'event à la racine du bundle

Contactez-nous

Kitpages
17 rue de la Frise
38000 Grenoble
tel : 04 58 00 33 81

Par Philippe Le Van (twitter accountplv) Dernière mise à jour : 05 août 2014

Configurer le Gedmo Sortable des Doctrine Extensions dans symfony2

Introduction

Le Gedmo Sortable dans les doctrine extensions permet de gérer un ordre pour les données d'une table. Il est bien pratique, mais il y a quelques étapes à suivre pour le faire fonctionner et la documentation officielle est un peu courte.

Installation classique de composants symfony

composer.json

Ajouter la ligne suivante dans le composer.json

"require": {
        "stof/doctrine-extensions-bundle": "~1.1@dev",
    },

AppKernel.php

Ajouter la ligue suivante dans le AppKernel.php

new Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle(),

config.yml

Ajouter les confs suivantes dans le config.yml

stof_doctrine_extensions:
    default_locale: en_US
    orm:
        default:
            tree: true
            sortable: true

Exemple avec une table de relation

Description de l'exemple

Imaginons qu'on ait des voitures avec des options. Chaque option a un ordre d'importance qu'on veut enregistrer en base.

On a une entité Car, une entité Option et une entité CarOption pour faire la relation.

L'entité CarOption a quelques caractéristiques importantes à noter :

  • Elle a un champs position qui permet de classer les options
  • Pour chaque voiture on a un ordre d'options différent

Voyons ce que ça donne en terme de modélisation doctrine et comment on branche le sortable des doctrines extension.

Fichier de mapping doctrine

C'est un fichier de relation normal, auquel on a ajouté des configurations importantes pour pouvoir utiliser le sortable de gedmo :

  • un namespace gedmo : xmlns:gedmo="http://gediminasm.org/schemas/orm/doctrine-extensions-mapping"
  • un repository-class : on est obligé d'un avoir un spécifique, vous verrons plus tard pourquoi
  • une balise : <gedmo:sortable-position/> dans le champs position
  • une balise : <gedmo:sortable-group /> pour indiquer le regroupement des positions
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xmlns:gedmo="http://gediminasm.org/schemas/orm/doctrine-extensions-mapping"
                  xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
                  http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
    <entity
        name="Kitpages\MyBundle\Entity\CarOption"
        table="generated_related_relation"
        repository-class="Kitpages\MyBundle\Repository\CarOptionRepository"
    >
        <id name="id" type="integer" column="id">
            <generator strategy="AUTO" />
        </id>

        <field name="position" column="position" type="integer" nullable="false">
            <gedmo:sortable-position/>
        </field>

        <many-to-one field="car" target-entity="Kitpages\MyBundle\Entity\Car" inversed-by="optionList">
            <join-column name="car_id" referenced-column-name="id" on-delete="CASCADE" on-update="CASCADE" />
            <gedmo:sortable-group />
        </many-to-one>

        <many-to-one field="option" target-entity="Kitpages\MyBundle\Entity\Option"  >
            <join-column name="option_id" referenced-column-name="id" on-delete="CASCADE" on-update="CASCADE" />
        </many-to-one>

    </entity>

</doctrine-mapping>

Le repository custom

On doit définir son repository pour pouvoir hériter du SortableRepository de Gedmo

<?php
namespace Kitpages\MyBundle\Repository;

use Gedmo\Sortable\Entity\Repository\SortableRepository;

class CarOptionRepository
    extends SortableRepository
{
}

Utiliser les sortable

Tout est configuré (ouf !) on peut enfin utiliser le sortable.

Là je reprends bêtement l'exemple de la doc :

<?php
$item1 = new Item();
$item1->setName('item 1');
$item1->setCategory('category 1');
$this->em->persist($item1);

$item2 = new Item();
$item2->setName('item 2');
$item2->setCategory('category 1');
$this->em->persist($item2);

$item0 = new Item();
$item0->setName('item 0');
$item0->setCategory('category 1');
$item0->setPosition(0);
$this->em->persist($item0);

$this->em->flush();

$repo = $this->em->getRepository('Entity\\Item');
$items = $repo->getBySortableGroupsQuery(array('category' => 'category 1'))->getResult();
foreach ($items as $item) {
    echo "{$item->getPosition()}: {$item->getName()}\n";
}
// prints:
// 0: item 0
// 1: item 1
// 2: item 2

// note : to set position to the end of the list, set position to -1 :  $item2->setPosition(-1);

Conclusion

N'hésitez pas à m'envoyer vos remarques en commentaires.

Commentaires

Ajouter un commentaire
à manu7772

oui c'est possible. il te suffit de placer l'attribut position dans ta relation
Sortable sur une relation OneToMany or ManyToMany
Bonjour,
Je souhaite utiliser le sortable de Gedmo avec une relation de parent <=> enfant, sauf qu'un enfant peut avoir plusieurs parents. Du coup, je dois pouvoir ressortir la position d'une entité enfant en fonction de tel ou tel de ses parents (donc le parent est à passer en paramètre pour avoir cette position).
Pensez-vous que ça soit possible avec le sortable de Gedmo ?