You are currently viewing Symfony – Créer des fixtures avec AliceBundle

Symfony – Créer des fixtures avec AliceBundle

  • Post comments:3 commentaires
  • Reading time:4 mins read

Dans le développement en local ou dans un environnement de test, le plus difficile est de fournir un jeu de données à jour par rapport à la base de données. Cet article cible les développeurs qui connaissent les Fixtures de Symfony. Cette partie fait suite à mon autre article qui parle des fixtures de Symfony avec le composant AliceBundle.

La problématique du composant Fixture de Symfony, c’est le temps pour mettre en place les fixtures.

Une solution ? Oui, AliceBundle.

Comment ça marche AliceBundle ?

Pour l’installer, nous allons utiliser composer :

composer require doctrine-orm

composer require --dev hautelook/alice-bundle 

Comment on configure AliceBundle ?

L’ensemble des fixtures sera dans un dossier nommé “fixtures“, il sera à la racine du projet Symfony comme déclarer sur la configuration ci-dessous :

# config/packages/dev/hautelook_alice.yaml

hautelook_alice:
    fixtures_path: 'fixtures' # Path to which to look for fixtures relative to the project directory or the bundle path. May be a string or an array of strings.
    root_dirs:
        - '%kernel.root_dir%'
        - '%kernel.project_dir%'

Mise en place des fixtures

Comme pour l’article sur les fixtures, nous allons prendre comme exemple une entité Article.

// src/Entity/Article.php
namespace App/Entity;

class Article
{
    private $title;

    public function setTitle(string $title) 
    {
        $this->title = $title;
        return $this;
    }

    public function getTitle()
    {
        return $this->title;
    }
}

Désormais, nous allons créer un fichier yaml pour créer les fixtures de l’entité Article.

# fixtures/article.yaml

App\Entity\Article:
    article_{1..100}:
        title: <name()>

article_{1..100} : Permet de créer 100 actions.

<name()> : Genère un nom random.

L’avantage de cette pratique étant qu’on peut facilement créer une multitude de jeu de données. Ici dans l’exemple, nous allons créer 100 articles avec des références uniques (exemple article_8).

Allons plus loin avec AliceBundle

Nous pouvons aussi faire des relations entre deux entités, on va ajouter des commentaires.

// src/Entity/Comment.php
namespace App/Entity;

class Comment
{
    private $content;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Comment", inversedBy="comments")
     */
    private $article;

    public function setArticle(Article $article)
    {
        $this->article = $article;
        return $this;
    }
    
    public function getArticle()
    {
        return $this->article;
    }

    public function setContent(string $content) 
    {
        $this->content = $content;
        return $this;
    }

    public function getContent()
    {
        return $this->content;
    }
}

Nous allons mettre en relation les commentaires aux articles de façon dynamique.

# fixtures/comment.yaml

App\Entity\Comment:
    comment_{1..1000}:
        content: <name()>
        article: '@article_*'

Cette fixture va créer 1000 commentaires avec un champ content avec du contenu et une liaison vers une fixture Article.

L’avantage du composant AliceBundle, nous pouvons intégrer des fonctions qui permettent de générer du fake data, des liaisons entre deux fixtures, etc.

Créons notre propre fonction

Avec AliceBundle, nous pouvons intégrer notre propre provider afin de customiser à notre façon les fixtures.

Pour notre exemple, on va créer les mots de passe pour les users.

Dans un premier temps, on va créer l’entité User.

// src/Entity/User.php
namespace App/Entity;

class User
{
    private $email;
    private $password;

    public function setPassword(string $password)
    {
        $this->password= $password;
        return $this;
    }
    
    public function getPassword()
    {
        return $this->password;
    }

    public function setEmail(string $email) 
    {
        $this->email= $email;
        return $this;
    }

    public function getEmail()
    {
        return $this->email;
    }
}

Pour déclarer une nouvelle fonction, nous devons créer un provider comme ci-dessous.

// src/DataFixtures/Providers/EncodePasswordProvider.php
namespace App\DataFixtures\Providers;

use App\Entity\User;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

class EncodePasswordProvider
{
    private $encoder;

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

    public function encodePassword(string $plainPassword): string
    {
        return $this->encoder->encodePassword(new User(), $plainPassword);
    }
}

La fonction encodePassword sera votre fonction qui sera inclus directement dans le yaml de votre fixture afin de définir un mot de passe simplement. Comme tout service, nous pouvons injecter des services tel que UserPasswordEncoderInterface qui nous permet de générer les mots de passe.

Désormais pour que notre provider soit fonctionnel nous devons le déclarer dans les services.

# config/services.yaml

services:
    App\DataFixtures\Provider\EncodePasswordProvider:
        tags: [ { name: nelmio_alice.faker.provider } ]

Désormais, nous pouvons utiliser notre provider directement sur notre fixture.

//fixtures\User.yaml

App\Entity\User:
    user_{1..10}:
        email: <email()>
        password: <encodePassword('Test1234')>

Conclusion

AliceBundle est un bundle utilisable sur un projet Symfony, qui permet de générer des fixtures de façon simple et efficace. En incluant un Faker Data qui permet de générer de la data.

Un article SymfonyCast, permet d’aller plus loin dans l’utilisation du bundle et aussi des tests.

Cet article a 3 commentaires

    1. Gary Houbre

      Hey,

      Non, j’en connais pas d’alternative.

      Mais si je trouve, je n’hésiterai pas de faire un article dessus.

      Merci en tout cas pour ton commentaire !

  1. Baptiste

    Hello,
    Tu oublies de lancer la commande pour générer tes fixtures, @+

Laisser un commentaire