Série : Symfony 7
Fichiers : https://github.com/NouvelleTechno/OpenBlog
Dans ce tutoriel, nous allons explorer l'utilisation des Data Fixtures avec Symfony pour initialiser une base de données. Cela est particulièrement utile lorsque vous souhaitez remplir automatiquement votre base de données avec des données de base, que ce soit pour un nouveau développeur rejoignant votre projet ou pour réinitialiser une base de données existante.
Installation du Bundle Doctrine Fixtures
Pour commencer, nous devons installer le bundle doctrine/doctrine-fixtures-bundle
, qui nous permettra de créer et de charger des jeux de données dans notre base.
Exécutez la commande suivante pour installer ce bundle :
composer require --dev orm-fixtures
Une fois installé, le bundle crée un dossier DataFixtures
sous le répertoire src
. Vous pouvez y trouver un fichier de base nommé AppFixtures.php
, que nous utiliserons pour créer nos premières fixtures.
Génération et Exécution des Migrations
Avant de créer nos fixtures, nous devons nous assurer que la base de données est à jour. Pour ce faire, générez et exécutez les migrations en utilisant les commandes suivantes :
symfony console make:migration
symfony console doctrine:migrations:migrate
Cela créera les tables nécessaires dans la base de données.
Création des Fixtures pour les Mots-Clés
Commençons par créer des fixtures pour les mots-clés. Nous allons créer un fichier KeywordFixtures.php
sous le dossier DataFixtures
.
Implémentation des Fixtures
Voici comment structurer les fixtures pour les mots-clés :
namespace App\DataFixtures;
use App\Entity\Keyword;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Symfony\Component\String\Slugger\SluggerInterface;
class KeywordFixtures extends Fixture
{
private SluggerInterface $slugger;
public function __construct(SluggerInterface $slugger)
{
$this->slugger = $slugger;
}
public function load(ObjectManager $manager): void
{
$keywords = ['France', 'Politique', 'Monde', 'Informatique', 'Économie', 'Association'];
foreach ($keywords as $keywordName) {
$keyword = new Keyword();
$keyword->setName($keywordName);
$slug = strtolower($this->slugger->slug($keywordName));
$keyword->setSlug($slug);
$manager->persist($keyword);
}
$manager->flush();
}
}
Dans ce fichier, nous utilisons le SluggerInterface
pour générer un slug à partir du nom de chaque mot-clé. Le slug est ensuite utilisé pour identifier de manière unique chaque mot-clé dans l'URL.
Création des Fixtures pour les Catégories
Les catégories peuvent avoir des relations parent-enfant, nous devons donc les gérer correctement dans nos fixtures.
Implémentation des Fixtures pour les Catégories
Voici comment structurer les fixtures pour les catégories :
namespace App\DataFixtures;
use App\Entity\Category;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Symfony\Component\String\Slugger\SluggerInterface;
class CategoryFixtures extends Fixture
{
private SluggerInterface $slugger;
public function __construct(SluggerInterface $slugger)
{
$this->slugger = $slugger;
}
public function load(ObjectManager $manager): void
{
$categories = [
['name' => 'France', 'parent' => null],
['name' => 'Politique', 'parent' => 'France'],
['name' => 'Monde', 'parent' => null],
['name' => 'Informatique', 'parent' => 'Monde'],
['name' => 'Économie', 'parent' => 'Monde'],
['name' => 'Association', 'parent' => 'France'],
];
foreach ($categories as $categoryData) {
$category = new Category();
$category->setName($categoryData['name']);
$slug = strtolower($this->slugger->slug($categoryData['name']));
$category->setSlug($slug);
if ($categoryData['parent']) {
$parent = $this->getReference($categoryData['parent']);
$category->setParent($parent);
}
$this->addReference($categoryData['name'], $category);
$manager->persist($category);
}
$manager->flush();
}
}
Nous utilisons ici des références pour lier les catégories entre elles, en s'assurant que les catégories parentales sont créées avant leurs enfants.
Création des Fixtures pour les Utilisateurs
Les utilisateurs nécessitent également une configuration spécifique, notamment pour le hachage des mots de passe.
Implémentation des Fixtures pour les Utilisateurs
Voici comment structurer les fixtures pour les utilisateurs :
namespace App\DataFixtures;
use App\Entity\User;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
class UserFixtures extends Fixture
{
private UserPasswordHasherInterface $passwordHasher;
public function __construct(UserPasswordHasherInterface $passwordHasher)
{
$this->passwordHasher = $passwordHasher;
}
public function load(ObjectManager $manager): void
{
$user = new User();
$user->setNickname('user');
$user->setEmail('user@demo.fr');
$user->setIsVerified(true);
$user->setPassword(
$this->passwordHasher->hashPassword(
$user,
'password'
)
);
$this->addReference('user', $user);
$manager->persist($user);
$admin = new User();
$admin->setNickname('admin');
$admin->setEmail('admin@demo.fr');
$admin->setRoles(['ROLE_ADMIN']);
$admin->setIsVerified(true);
$admin->setPassword(
$this->passwordHasher->hashPassword(
$admin,
'adminpassword'
)
);
$this->addReference('admin', $admin);
$manager->persist($admin);
$manager->flush();
}
}
Cette fixture crée deux utilisateurs : un utilisateur standard et un administrateur, avec les rôles appropriés et les mots de passe hachés.
Création des Fixtures pour les Articles
Enfin, créons des articles associés à ces utilisateurs et catégories.
Implémentation des Fixtures pour les Articles
Voici comment structurer les fixtures pour les articles :
namespace App\DataFixtures;
use App\Entity\Post;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Symfony\Component\String\Slugger\SluggerInterface;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
class PostFixtures extends Fixture implements DependentFixtureInterface
{
private SluggerInterface $slugger;
public function __construct(SluggerInterface $slugger)
{
$this->slugger = $slugger;
}
public function load(ObjectManager $manager): void
{
$post = new Post();
$post->setTitle('Ceci est un titre');
$post->setSlug(strtolower($this->slugger->slug($post->getTitle())));
$post->setContent('Ceci est le contenu');
$post->setUser($this->getReference('admin'));
$post->setFeatureImage('default.webp');
$manager->persist($post);
$manager->flush();
}
public function getDependencies()
{
return [
UserFixtures::class,
CategoryFixtures::class,
];
}
}
Notez l'implémentation de DependentFixtureInterface
, qui garantit que les utilisateurs et les catégories sont chargés avant les articles.
Exécution des Fixtures
Pour charger les données dans la base, exécutez la commande suivante :
symfony console doctrine:fixtures:load
Cette commande initialise la base de données avec les données que vous avez définies dans vos fixtures.
Conclusion
Les Data Fixtures sont un outil puissant pour gérer l'initialisation des bases de données dans vos projets Symfony. Elles vous permettent de garantir que tous les développeurs disposent de la même base de données initiale, simplifiant ainsi le processus de développement collaboratif.
Si vous avez des questions, n'hésitez pas à rejoindre notre serveur Discord ou notre forum pour discuter avec la communauté. À bientôt pour un nouveau tutoriel !
Obtenir de l'aide
Pour obtenir de l'aide, vous pouvez accéder au serveur Discord pour une entraide par chat.