Symfony TD2: code first

Dans ce TD, nous allons créer un projet en code-first, ce qui signifie que la base de données sera créée et évoluera automatiquement à partir des modifications effectuées.

Paramétrage

Modifiez la chaîne de connexion qui se trouve dans le fichier .env.

Si vous utilisez la base du département, cela ressemblera à ça:

DATABASE_URL=mysql://user:password@info-titania:3306/shows

Création de l'entité "Utilisateur"

Nous allons tout d'abord créer une entité utilisateur, en utilisant la commande make:user:

symfony console make:user

Laissez les réponses par défaut. Regardez le code généré dans Entity/User.php. Vous pouvez maintenant créer le schéma dans la base de données, à l'aide de la commande doctrine:schema:create:

symfony console doctrine:schema:create

Observez dans la base de données le résultat produit.

Création d'une authentification basée formulaire

Nous allons maintenant créer une authentification basée formulaire:

symfony console make:auth

Répondez "1" à la première question (Login form authenticator), et laissez le générateur tourner.

Il nous faudra créer un premier utilisateur, pour cela, nous pouvons utiliser:

symfony console make:registration

N'envoyez pas d'e-mails pour confirmer l'inscription. Rendez vous sur la page /register, puis sur /login et /logout pour tester le tout!

Il faudra modifier le fichier AppAuthenticator.php pour ajouter une redirection vers une page (l'accueil par exemple) après l'identification.

Ajout d'un champ

Nous allons maintenant permettre à un utilisateur de fournir son nom à l'inscription. Le champ "nom" n'existe pas dans la base. Mais n'y touchez pas!

Nous allons utiliser le couteau-suisse de Symfony: make:entity pour modifier l'entité utilisateur et lui ajouter un nom.

symfony console make:entity

Donnez lui le type string de longueur 255 et non nullable. L'entité est maintenant à jour, observez src/Entity/User.php et ses changements.

Cependant, la base n'a pas bougée, pour la mettre à jour, il est possible d'utiliser la commande doctrine:schema:update. Pour ce faire, regardez tout d'abord la sortie de:

symfony console doctrine:schema:update --dump-sql

Cette commande produit le code SQL permettant de mettre à jour la base (en l'occurence ALTER ...). Vous pouvez forcer l'execution de ce code:

symfony console doctrine:schema:update --force

Et observez que le champ apparaît maintenant bien en base.

Pour que l'utilisateur fournisse son nom, modifiez RegistrationFormType.php, et éventuellement register.html.twig.

Pays de l'utilisateur

Entité Country

Nous allons maintenant demander le pays de l'utilisateur à l'inscription. Cependant, ce dernier ne sera pas un champ texte, mais une association dans la base de données.

Tout d'abord, créons donc l'entité Country à l'aide de make:entity. Cette entité aura simplement un nom.

Ensuite, il faudra ajouter un champ country qui fait référence à un pays dans User. Pour cela, utilisez à nouveau make:entity, ajoutez le champ country dans l'entité User, et précisez que le type est ManyToOne, faisant référence à l'entité Country.

Mettez à jour la base de données (à l'aide de la commande doctrine:schema:update --force). Observez le résultat dans la base.

Génération de CRUD

Créons ensuite un contrôleur automatique pour Country, à l'aide de make:crud, puis rendez vous sur /country/ pour créer quelques pays.

Vous pouvez regarder le code généré par make:crud dans src/Controller/CountryController.php et templates/country/*.

De la même manière que dans la partie précédente, ajoutez le champ au formulaire lors de l'inscription de l'utilisateur. Remarquez l'erreur suivante:

En essayant de charger la page /register. La raison est que Symfony essaie de rendre le champ de sélection de pays sous forme de select, et qu'il ne sait pas comment afficher un Country. Pour ce faire, surchargez la méthode __toString() dans Country.

Inscrivez-vous avec ce formulaire et observez ce qui se passe dans la base de données.

Utilisation d'entité

Sur une page, d'accueil par exemple, affichez le nom de l'utilisateur identifié et son pays.

Astuce: ne cherchez pas compliqué, c'est très facile!

Ajout de messages

Nous allons permettre aux utilisateurs d'écrire des messages, qui apparaitront dans l'ordre anti-chronologique, une fois identifié, tout en sachant qui l'a envoyé.

Créez une entité Message, qui a (aucun des champs n'est facultatif):

  • body, le corps du message de type text
  • creation_date, la date de création de time datetime
  • user, l'utilisateur qui a posté le message de type ManyToOne vers User.

Mettez à jour la base et générez un CRUD pour message.

Modifiez le code généré pour:

  • Que les messages apparaissent par ordre anti chronologique (selon creation_date)
  • Au lieu de choisir l'utilisateur qui poste le message dans un menu déroulant, on utilisera l'utilisateur actuel
  • La date actuelle sera utilisée également au moment de la création du message.

Relation N vers N

Enfin, nous allons ajouter des "catégories" aux messages. Un message pourra être associée à plusieurs catégories (high-tech, sport, hobbies, général ...).

Créez tout d'abord l'entité Category à l'aide de make:entity, qui aura seulement un nom.

Créez une association ManyToMany entre Message et Category.

Modifiez le formulaire de création de messages de manière à pouvoir choisir les catégories, voici plusieurs remarques/astuces:

  • Dans le formulaire, vous pouvez laisser le type de champ à null pour laisser Symfony deviner
  • Il est plus ergonomique d'afficher des cases à cocher qu'un menu déroulant permettant de sélectionner plusieurs options. Pour cela, vous pourrez utiliser l'option expanded sur le champ.
  • Vous aurez également besoin d'une fonction __toString() dans Category

Affichez les catégories dans lesquelles les messages ont été postés lors de leurs consultation.