Symfony3: slides + revue planning journée 1
This commit is contained in:
parent
a741a6b20e
commit
3eb9b8da29
|
@ -1,4 +1,4 @@
|
||||||
<style>pre { font-size: 0.7em !important; }</style>
|
<style>pre, table { font-size: 0.7em !important; }</style>
|
||||||
|
|
||||||
# Remise à niveau Symfony3
|
# Remise à niveau Symfony3
|
||||||
## William Petit - S.C.O.P. Cadoles
|
## William Petit - S.C.O.P. Cadoles
|
||||||
|
@ -58,7 +58,7 @@ symfony new <my_project_name> 3.4
|
||||||
### Les principaux répertoires et leur rôle
|
### Les principaux répertoires et leur rôle
|
||||||
|
|
||||||
|Répertoire|Rôle|
|
|Répertoire|Rôle|
|
||||||
|:-:|:-:|
|
|:-|:-|
|
||||||
|`app/config/`|Configuration de l'application|
|
|`app/config/`|Configuration de l'application|
|
||||||
|`app/Resources/`|Depuis Symfony3, répertoire contenant les vues ainsi les "assets" de l'application|
|
|`app/Resources/`|Depuis Symfony3, répertoire contenant les vues ainsi les "assets" de l'application|
|
||||||
|`src/AppBundle/`|Sources de l'application|
|
|`src/AppBundle/`|Sources de l'application|
|
||||||
|
@ -68,7 +68,7 @@ symfony new <my_project_name> 3.4
|
||||||
## Structuration d'un projet (2)
|
## Structuration d'un projet (2)
|
||||||
|
|
||||||
|Répertoire|Rôle|
|
|Répertoire|Rôle|
|
||||||
|:-:|:-:|
|
|:-|:-|
|
||||||
|`tests/`|Répertoire contenant les tests de l'application (unitaire comme fonctionnels)|
|
|`tests/`|Répertoire contenant les tests de l'application (unitaire comme fonctionnels)|
|
||||||
|`var/`|Répertoire contenant toutes les données "vivantes" de l'application|
|
|`var/`|Répertoire contenant toutes les données "vivantes" de l'application|
|
||||||
|`vendor/`| Dépendances Composer
|
|`vendor/`| Dépendances Composer
|
||||||
|
@ -79,7 +79,7 @@ symfony new <my_project_name> 3.4
|
||||||
|
|
||||||
### Quelques commandes (très) utiles
|
### Quelques commandes (très) utiles
|
||||||
|Commande|Description|
|
|Commande|Description|
|
||||||
|:-:|:-:|
|
|:-|:-|
|
||||||
|`server:run`|Exécuter l'application avec le serveur HTTP PHP|
|
|`server:run`|Exécuter l'application avec le serveur HTTP PHP|
|
||||||
|`security:check`|Vérifier que les dépendances du projet ne comportent pas de vulnérabilités connues|
|
|`security:check`|Vérifier que les dépendances du projet ne comportent pas de vulnérabilités connues|
|
||||||
|`debug:container`|Retrouver le mapping services <-> classe PHP|
|
|`debug:container`|Retrouver le mapping services <-> classe PHP|
|
||||||
|
@ -90,7 +90,7 @@ symfony new <my_project_name> 3.4
|
||||||
|
|
||||||
### Les générateurs par défaut
|
### Les générateurs par défaut
|
||||||
|Commande|Description|
|
|Commande|Description|
|
||||||
|:-:|:-:|
|
|:-|:-|
|
||||||
|`generate:bundle`|Créer un nouveau bundle|
|
|`generate:bundle`|Créer un nouveau bundle|
|
||||||
|`generate:controller`|Créer un nouveau contrôleur|
|
|`generate:controller`|Créer un nouveau contrôleur|
|
||||||
|`generate:command`|Créer une nouvelle commande|
|
|`generate:command`|Créer une nouvelle commande|
|
||||||
|
@ -247,7 +247,7 @@ class DemoController extends Controller
|
||||||
### Paramètres spéciaux
|
### Paramètres spéciaux
|
||||||
|
|
||||||
|Paramètre|Description|
|
|Paramètre|Description|
|
||||||
|:-:|:-:|
|
|:-|:-|
|
||||||
|`_locale`| La "locale" utilisé par l'application pour la requête en cours |
|
|`_locale`| La "locale" utilisé par l'application pour la requête en cours |
|
||||||
|`_format`| Le "format" utilisé par l'application pour la requête en cours |
|
|`_format`| Le "format" utilisé par l'application pour la requête en cours |
|
||||||
|`_controller`| L'identifiant du contrôleur et son action utilisés pour traiter la requête en cours|
|
|`_controller`| L'identifiant du contrôleur et son action utilisés pour traiter la requête en cours|
|
||||||
|
@ -669,10 +669,316 @@ Implémenter une classe `Guard` pour créer un firewall pour un serveur d'authen
|
||||||
```
|
```
|
||||||
---
|
---
|
||||||
|
|
||||||
## Étendre Twig
|
## Étendre Twig (1)
|
||||||
|
|
||||||
|
### Créer son extension
|
||||||
|
|
||||||
|
```php
|
||||||
|
// src/AppBundle/Twig/AppExtension.php
|
||||||
|
namespace AppBundle\Twig;
|
||||||
|
|
||||||
|
class AppExtension extends \Twig_Extension
|
||||||
|
{
|
||||||
|
public function getFilters()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
new \Twig_SimpleFilter('pad', [$this, 'pad']),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function pad(
|
||||||
|
$input,
|
||||||
|
$length,
|
||||||
|
$pattern = ' ',
|
||||||
|
$type = STR_PAD_LEFT
|
||||||
|
) {
|
||||||
|
return str_pad($input, $length, $pattern, $type);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Étendre Twig (2)
|
||||||
|
|
||||||
|
### Enregistrer l'extension comme service
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
// app/config/services.yml
|
||||||
|
|
||||||
|
services:
|
||||||
|
|
||||||
|
AppBundle\Twig\AppExtension:
|
||||||
|
tags: [ twig.extension ]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Étendre Twig (3)
|
||||||
|
|
||||||
|
### Utiliser le filtre
|
||||||
|
|
||||||
|
```twig
|
||||||
|
<p>{{ "1" | pad(10, "0") }}</p>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# L'ORM Doctrine et le modèle de données
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
## Migration du schéma
|
||||||
|
## Entités et dépôts
|
||||||
|
## Les évènements
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Migration du schéma (1)
|
||||||
|
|
||||||
|
### En développement
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bin/console doctrine:schema:update --force
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
## Migration du schéma (2)
|
||||||
|
|
||||||
|
### En production
|
||||||
|
|
||||||
|
1. Récupération du schéma de la base en production en version `[origine]`
|
||||||
|
2. Création d'un script de migration SQL en fonction des nouvelles entités de la version `[cible]`
|
||||||
|
```bash
|
||||||
|
mkdir -p migrations
|
||||||
|
bin/console doctrine:schema:update \
|
||||||
|
--dump-sql > migration-[origine]-[cible].sql
|
||||||
|
```
|
||||||
|
3. Vérification/modification manuelle du script de migration
|
||||||
|
4. Passage du script de migration validé en production
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Entités et dépôts (1)
|
||||||
|
|
||||||
|
### Génération d'entités
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bin/console doctrine:generate:entity
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
## Entités et dépôts (2)
|
||||||
|
|
||||||
|
### La classe de l'entité
|
||||||
|
|
||||||
|
```php
|
||||||
|
/**
|
||||||
|
* Post
|
||||||
|
* @ORM\Table(name="post")
|
||||||
|
* @ORM\Entity(
|
||||||
|
* repositoryClass="AppBundle\Repository\PostRepository"
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
class Post
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
* @ORM\Column(name="id", type="integer")
|
||||||
|
* @ORM\Id
|
||||||
|
* @ORM\GeneratedValue(strategy="AUTO")
|
||||||
|
*/
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
* @ORM\Column(name="Content", type="text", nullable=true)
|
||||||
|
*/
|
||||||
|
private $content;
|
||||||
|
// [...]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
---
|
||||||
|
## Entités et dépôts (3)
|
||||||
|
|
||||||
|
### Les annotations de classe
|
||||||
|
|
||||||
|
|Annotation|Paramètres (non exhaustifs)|Description|
|
||||||
|
|:-|:-|:-|
|
||||||
|
|`@ORM\Table`|`name`: nom de la table| Description de la table associée à la base de données|
|
||||||
|
|`@ORM\Entity`|`repositoryClass`: identifiant de la classe `EntityRepository` associée à cette entité| Métadonnées de contexte liées à l'entité|
|
||||||
|
|
||||||
|
---
|
||||||
|
## Entités et dépôts (4)
|
||||||
|
|
||||||
|
### Les annotations d'attributs
|
||||||
|
|
||||||
|
|Annotation|Paramètres (non exhaustifs)|Description|
|
||||||
|
|:-|:-|:-|
|
||||||
|
|`@ORM\Column`|`name`: nom de la colone, `type`: type de la colone, `nullable`| Description de la colonne dans la base de donnée associée à l'attribut|
|
||||||
|
|`@ORM\Id`|| Déclare l'attribut comme une clé primaire dans la table|
|
||||||
|
|`@ORM\GeneratedValue`|`strategy`: stratégie de génération de la valeur de l'attribut | Déclare l'attribut comme généré automatiquement par la base de donnée |
|
||||||
|
|
||||||
|
---
|
||||||
|
## Entités et dépôts (5)
|
||||||
|
|
||||||
|
### Accéder aux gestionnaires d'entités dans un contrôleur
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Doctrine\Common\Persistence\ObjectManager;
|
||||||
|
|
||||||
|
class DemoController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @Route("/demo")
|
||||||
|
*/
|
||||||
|
public function demoAction(ObjectManager $em)
|
||||||
|
{
|
||||||
|
// Faire quelque chose avec l'entité manager
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Entités et dépôts (6)
|
||||||
|
|
||||||
|
### Enregistrer un nouvelle entité dans la base
|
||||||
|
|
||||||
|
```php
|
||||||
|
use AppBundle\Entity\Post;
|
||||||
|
|
||||||
|
// [...]
|
||||||
|
// La variable $em est récupéré en tant que service
|
||||||
|
|
||||||
|
// On créait une instance de notre entité
|
||||||
|
$post = new \Post();
|
||||||
|
|
||||||
|
// On modifie les valeurs des attributs de notre instance
|
||||||
|
$post->setContent("hello world");
|
||||||
|
|
||||||
|
// On référence notre instance comme nouvelle entité à persister
|
||||||
|
$em->persist($post);
|
||||||
|
|
||||||
|
// On fait appliquer à l'ORM les modifications de l'"unit of work"
|
||||||
|
$em->flush();
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Entités et dépôts (7)
|
||||||
|
|
||||||
|
### Modifier une entité existante
|
||||||
|
|
||||||
|
```php
|
||||||
|
$repository = $em->getRepository(Post::class);
|
||||||
|
|
||||||
|
// On récupère une instance de notre entité à
|
||||||
|
// partir de son identifiant depuis la base de données
|
||||||
|
$post = $repository->find($id);
|
||||||
|
|
||||||
|
// On modifie les valeurs des attributs de notre instance
|
||||||
|
$post->setContent("foo bar");
|
||||||
|
|
||||||
|
// On fait appliquer à l'ORM les modifications de l'"unit of work"
|
||||||
|
$em->flush();
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Entités et dépôts (8)
|
||||||
|
|
||||||
|
### Supprimer une entité
|
||||||
|
|
||||||
|
```php
|
||||||
|
$repository = $em->getRepository(Post::class);
|
||||||
|
|
||||||
|
// On récupère une instance de notre entité à partir
|
||||||
|
// de son identifiant depuis la base de données
|
||||||
|
$post = $repository->find($id);
|
||||||
|
|
||||||
|
$em->remove($post);
|
||||||
|
|
||||||
|
// On fait appliquer à l'ORM les modifications de l'"unit of work"
|
||||||
|
$em->flush();
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
## Entités et dépôts (9)
|
||||||
|
|
||||||
|
### Les relations: exemple `one to many`
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
|
||||||
|
class Post
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Doctrine\Common\Collections\ArrayCollection
|
||||||
|
* @ORM\OneToMany(targetEntity="Comment", mappedBy="post")
|
||||||
|
*/
|
||||||
|
private $comments;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
### Les relations: `one to many`
|
||||||
|
```php
|
||||||
|
class Comment
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToOne(targetEntity="Post", inversedBy="comments")
|
||||||
|
* @ORM\JoinColumn(name="post_id", referencedColumnName="id")
|
||||||
|
*/
|
||||||
|
private $post;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
## Les évènements Doctrine et Symfony (1)
|
||||||
|
|
||||||
|
### Création du `Listener`
|
||||||
|
|
||||||
|
```php
|
||||||
|
// src/AppBundle/EventListener/SearchIndexer.php
|
||||||
|
namespace AppBundle\EventListener;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Event\LifecycleEventArgs;
|
||||||
|
use AppBundle\Entity\Post;
|
||||||
|
|
||||||
|
class PostUpdateNotifier
|
||||||
|
{
|
||||||
|
public function postPersist(LifecycleEventArgs $args)
|
||||||
|
{
|
||||||
|
$entity = $args->getEntity();
|
||||||
|
|
||||||
|
if (!$entity instanceof Post) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Faire quelque chose avec le Post...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Les évènements Doctrine et Symfony (2)
|
||||||
|
|
||||||
|
### Référencer le service
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
// app/config/services.yml
|
||||||
|
|
||||||
|
services:
|
||||||
|
AppBundle\EventListener\PostCreationNotifier:
|
||||||
|
tags:
|
||||||
|
- { name: doctrine.event_listener, event: postPersist }
|
||||||
|
```
|
||||||
---
|
---
|
||||||
|
|
||||||
# Les formulaires
|
# Les formulaires
|
||||||
|
@ -683,11 +989,113 @@ Implémenter une classe `Guard` pour créer un firewall pour un serveur d'authen
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# L'ORM Doctrine et le modèle de données
|
## Création et traitement de formulaires (1)
|
||||||
|
|
||||||
## Concept d'ORM
|
### Générer les formulaires CRUD pour une entité
|
||||||
## Entité et Dépôt
|
```bash
|
||||||
## Les évènements
|
bin/console doctrine:generate:crud
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Exercice proposé
|
||||||
|
|
||||||
|
Créer une micro application de type "TodoList". L'application devra comprendre une entité `Task` avec les attributs suivants:
|
||||||
|
- Un status: à faire | en cours | fermé
|
||||||
|
- Un texte de description
|
||||||
|
- Un label
|
||||||
|
|
||||||
|
La mise à jour de l'état d'une tâche devra automatiquement déclencher l'envoi d'un courriel à une adresse donnée (fixe, paramétrée dans le fichier `parameters.yml` de l'application).
|
||||||
|
|
||||||
|
**Ressources**
|
||||||
|
|
||||||
|
- https://symfony.com/doc/3.4/email.html
|
||||||
|
- http://symfony.com/doc/3.4/doctrine/event_listeners_subscribers.html
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Création et traitement de formulaires (2)
|
||||||
|
|
||||||
|
### La classe `AbstractType`
|
||||||
|
### Construction des champs
|
||||||
|
### Définition des options
|
||||||
|
### Utilisation du formulaire dans le contrôleur
|
||||||
|
### Rendu du formulaire dans un template Twig
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
## Création et traitement de formulaires (3)
|
||||||
|
|
||||||
|
### Formulaires en tant que services
|
||||||
|
#### Déclararation des dépendances
|
||||||
|
#### Déclarations du services
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
// app/config/services.yml
|
||||||
|
services:
|
||||||
|
App\Form\PostType:
|
||||||
|
tags: [form.type]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Validation des données (1)
|
||||||
|
|
||||||
|
### Installer le composant `validator`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
composer require validator
|
||||||
|
```
|
||||||
|
### Configurer le composant
|
||||||
|
```yaml
|
||||||
|
# app/config/config.yml
|
||||||
|
framework:
|
||||||
|
validation: { enable_annotations: true }
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
## Validation des données (2)
|
||||||
|
|
||||||
|
### Les annotations `Àssert`
|
||||||
|
|
||||||
|
```php
|
||||||
|
class MyEntity
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @Assert\NotBlank()
|
||||||
|
*/
|
||||||
|
public $name;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Les différentes validations pré-existantes: `NotBlank`, `Blank`, `NotNull`, `IsNull`, `isTrue`, `IsFalse`, `Email`, `Url`...
|
||||||
|
|
||||||
|
Voir http://symfony.com/doc/3.4/validation.html#supported-constraints
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Validation des données (3)
|
||||||
|
|
||||||
|
### Utilisation basique
|
||||||
|
|
||||||
|
```php
|
||||||
|
|
||||||
|
// On récupère le service "validator"
|
||||||
|
// depuis le conteneur de services
|
||||||
|
$validator = $this->get('validator');
|
||||||
|
|
||||||
|
$errors = $validator->validate($myObject);
|
||||||
|
|
||||||
|
if ( count($errors) > 0 ) {
|
||||||
|
// Traiter les erreurs
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Validation des données (4)
|
||||||
|
|
||||||
|
### Utilisation avec les formulaires
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -698,6 +1106,10 @@ Implémenter une classe `Guard` pour créer un firewall pour un serveur d'authen
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Gestion des environnements
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
# Licence
|
# Licence
|
||||||
|
|
||||||
## CC BY-NC-SA 3.0 FR
|
## CC BY-NC-SA 3.0 FR
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue