From ccb80c82e77de1fd4cc6e7e280890bcd0fdce34d Mon Sep 17 00:00:00 2001 From: William Petit Date: Thu, 14 Dec 2017 20:05:25 +0100 Subject: [PATCH] =?UTF-8?q?Symfony3:=20slides=20+=20revue=20planning=20jou?= =?UTF-8?q?rn=C3=A9e=201?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- developpement/symfony3/presentation/slides.md | 434 +++++++++++++++++- .../symfony3/ressources/planning.ods | Bin 15871 -> 14395 bytes 2 files changed, 423 insertions(+), 11 deletions(-) diff --git a/developpement/symfony3/presentation/slides.md b/developpement/symfony3/presentation/slides.md index 11f6dc5..a5f9b40 100644 --- a/developpement/symfony3/presentation/slides.md +++ b/developpement/symfony3/presentation/slides.md @@ -1,4 +1,4 @@ - + # Remise à niveau Symfony3 ## William Petit - S.C.O.P. Cadoles @@ -58,7 +58,7 @@ symfony new 3.4 ### Les principaux répertoires et leur rôle |Répertoire|Rôle| -|:-:|:-:| +|:-|:-| |`app/config/`|Configuration de l'application| |`app/Resources/`|Depuis Symfony3, répertoire contenant les vues ainsi les "assets" de l'application| |`src/AppBundle/`|Sources de l'application| @@ -68,7 +68,7 @@ symfony new 3.4 ## Structuration d'un projet (2) |Répertoire|Rôle| -|:-:|:-:| +|:-|:-| |`tests/`|Répertoire contenant les tests de l'application (unitaire comme fonctionnels)| |`var/`|Répertoire contenant toutes les données "vivantes" de l'application| |`vendor/`| Dépendances Composer @@ -79,7 +79,7 @@ symfony new 3.4 ### Quelques commandes (très) utiles |Commande|Description| -|:-:|:-:| +|:-|:-| |`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| |`debug:container`|Retrouver le mapping services <-> classe PHP| @@ -90,7 +90,7 @@ symfony new 3.4 ### Les générateurs par défaut |Commande|Description| -|:-:|:-:| +|:-|:-| |`generate:bundle`|Créer un nouveau bundle| |`generate:controller`|Créer un nouveau contrôleur| |`generate:command`|Créer une nouvelle commande| @@ -247,7 +247,7 @@ class DemoController extends Controller ### Paramètres spéciaux |Paramètre|Description| -|:-:|:-:| +|:-|:-| |`_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 | |`_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 +

{{ "1" | pad(10, "0") }}

+``` + +--- + +# 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 @@ -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 -## Entité et Dépôt -## Les évènements +### Générer les formulaires CRUD pour une entité +```bash +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 ## CC BY-NC-SA 3.0 FR diff --git a/developpement/symfony3/ressources/planning.ods b/developpement/symfony3/ressources/planning.ods index b36809ed463229d2cb503b56ea6148655dfd660d..40373128d7907d51bb417b9849f9f56646b9409a 100644 GIT binary patch delta 12594 zcmb_?Wl&|i5-vKp4eqvacZb2<-C=OIK?d6l?hI_)-QC^YhQZz4-Q~?W_ujfv^?tmn zSCvX9E8SnRdUaNkPJei{IU*^^LPBAHfx&`-#V1F{A}J&PA+kX~wN9OIz`&evVr^M~ z?O3?gdWBC>o^>Ov~o z+zMX>luSe!i6uCxCHOd%1n5)pg9(^qsYg^%c!MbWE(&OkCAWJ=82+RV=-9&75`2ytJ*H^?=r1`c6K^ z3c?neGN!uf&iZnWx@zY7U(Jm5Y)#c{O!Vw5b-tO%xtVKOSXh|Zy4rrTwQ}}!wK4nd zZ0+IUp=0l_?;K!k7hvudV&NHY>l5qd9pK~(vI|J?@(*zdh<6T5bqi1P3W)t4l!M6&eF}!=*`j6^VQnH z;om??bX@yHE{Ro_T=s9^yc>V`u^$R z`Qi5I<>~(V_4)Sw{r#cIEddM+lU`a(Sj}VkYz09}RWlRJv5n1S$a*D5;pOZb?^$#o{da-wjt(JKjJ6<;%-Slh2Os!wqh?s`Ng2Ju9P7b z1HZ6;Re4JfcLUCN7%v&YC!?MNe?jwIhsK=y(z!i|MLAyZaCLb(JHHYR6b4j`tbbwZxkn=C- zL_h*7+wZi#PJ3Ce-<(;0Jr3CpstPiA-19>*T;$wK{22JoKHG#gMA z)S>kFN>PK_NFgk9&zh4P9sO8xz2NRMKJ&x9wBc8nP_@v?eS`sVj~BxYhx6FxcqXmr z4HN%*sXVa2*J|cwKI5vIAy$K1h1>Z~V#xX2`{lIrsC#9duxr0M;qqZ3Fa2`x!$`tQ}7k`hYXXZDR6qEt|KG5x)~#*6RE(fjz1%6VHcWE z$U((Vp{psIoC77}9H8oMNAD*iQ$yv2cgfzHwA)ZeHsKkPG(#KRiwIS2AAZW$z*Jil z|5X?#KAtI8Byw73)~Y%Y0Gt57+7pk)Ik}B*|CX2AuG)Ka<-9B~O=POQvwtskm$i%? z2|P~-vKQCx{A#H!d?fCNswjJ{&uQB>?r*1An6vwKcUJls?N6|Ck8Ut2p?T=f(1Yb` zD7V%aV{#0YND@9(CD8nt4Bv$Tj0R~X&g$cys}K%_wqZF}mCyEA!odQDb`I;1`EV`1 zb&WrpvsZgYzF~bn&~rBUx3BAq*`eAAA<%Pbqv!1P1L3v7fj0bRlPhHSeQ1PRZJ1xR z@~FrC5L1Bg?r!k8)VZ1lQ8a4p4nCr;9ya&c6&|62@pj&NT2kiZ(6d3+$uys6lDb%3 zdL}^eCHqcZyZ7iddyr6)T;8;)dbb0)ag?ND?>LY%k+!O$N4Bs{h^vD08ILTg7TDWV zuPc{+HdF)$#PBy8YIq7PI%P7prg3!|=}$zn#zG zj+@x7wCX)rS*+cec!G+@L{pn|HI~lJz}!Z?IIs?4bd_9)a$UbfAf%Dt4CIc7cF2$; zqE1T3VO2!%jp+9t^sFdB5EYTtr%fe%5*(KRpv zf*2DG+kd*+jMZ;aX)eSaOInDm`FWw3ZFgu4F%x?H0@5vPqz=Xwu}hI|R>ZW+D`Q5! zWv#G1DP*#*i{To7xyYWFvJ>h0fz_tI;vf@8omQIeMI1t@cE915@*6)Wf^ zh^v>f)-f4L1892)H6&6goPR0e%vB5sPSzghznKbe-XRy}Z< zRrKx6hNhF0efRdW)Sk?#36BE{+?>`Fxf)>dfEvcrnsyxds&2c3UdD;`Ms*{?�z? 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 delta 13930 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 D*CFz^