Symfony

Fonctionnement

Les bundles

Un bundle est un répertoire qui a une structure bien définie et qui peut héberger à peu près tout : des classes aux contrôleurs en passant par les ressources web (C'est une version amélirée des plugins).
Un bunble à la structure suivante :

			.
			├── Controller (Contient les contrôleurs du bundle)
			│   └── IndexController.php
			├── DependencyInjection (Contient les injections de dépendance)
			├── EventListener (Contient les listener qui vont se déclencher lors de certains évènements (ex: lors d’une requête))
			├── Resources (Contient les configurations du bundle (routes, services…))
			│   ├── config
			│   │   └── routing.yml
			│   │   └── services.yml
			│   ├── public (Contient les fichiers css / js / images)
			│   ├── translations (Contient les traductions du bundle)
			│   └── views (Contient les vues du bundle qui sont appelées par les contrôleurs)
			│       └── index.html.twig
			├── Services (Contient les services)
			└── Tests (Contient les tests)
			

Le routing et les configurations (yml, xml, php)

Le routing permet d’associer une URL à un contrôleur et à une action de celui-ci.
Il existe 4 formats d’écriture des fichiers de route:

Et 3 formats pour les fichiers de configuration:

Voici un exemple de route écrit en Annotation :

			// src/AppBundle/Controller/BlogController.php
			class BlogController extends Controller {

				/** * @Route("/blog/{culture}") */
				public function showAction($culture) {
				// …
				}

			}
		

Voici un exemple de route écrit en Yaml :

			# src/AppBundle/Resources/config/routing.yml
			blog_show:
			   path: /blog/{culture}
			   defaults: { _controller: AppBundle:Blog:show }
   				requirements:
   					culture: en|fr
		

Voici un exemple de route écrit en XML :

			<!-- src/AppBundle/Resources/config/routing.xml -->
			<?xml version="1.0" encoding="UTF-8" ?>
			<routes xmlns="http://symfony.com/schema/routing" 
					xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
					xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
			   <route id="blog_show" path="/blog/{culture}">
					<default key="_controller">AppBundle:Blog:show</default>
			   </route>
			</routes>
		

Voici un exemple de route écrit en PHP :

			// src/AppBundle/Resources/config/routing.php
			use Symfony\Component\Routing\RouteCollection;
			use Symfony\Component\Routing\Route;
			$collection = new RouteCollection();
			$collection->add('blog_show', new Route('/blog/{culture}', array('_controller' => 'AppBundle:Blog:show')));
			return $collection;
		

Les annotations et le format Yaml sont les deux formats les plus utilisés dans Symfony de par leur syntaxe simple et lisible.

Les contrôleurs

Voici un exemple de contrôleur Symfony :

			<?php
			namespace MyProject\BlogBundle\Controller;
			use MyProject\CoreBundle\Controller\Common\BaseController;
			use Doctrine\ORM\Query;
			use Symfony\Component\HttpFoundation\Request;
			class BlogController extends BaseController {
		
		    	/** * @Route("/article/{id}") */
    			public function articleAction(Request $request, $id) {
         			$culture = $request->getLocale();
			        // Requête pour récupérer l'article (on appel le modèle)
          			$article = $this->getDoctrine()->getManager()->getRepository("MyProjectBlogBundle:Article")->find($id);

          			// On appel la vue
			        return $this->render('MyProjectBlogBundle:article.html.twig', array('culture' => $culture, 'article' => $article));
    			}

			}
			?>
		

Dans cet exemple de contôleur appel le modèle pour récupérer un article puis génère la vue en lui donnant les informations qu'elle a besoin.

Les vues (Twig / PHP)

Voici un exemple de vue Twig :

			<!DOCTYPE html>
			<html>
			    <head> 
			       <title>
			           {% block title %}
			                   Blog :: 
			           {% endblock %}
			       </title>
			       {% block stylesheets %}
			           <link rel="stylesheet" href="{{ asset('bundles/myprojectblog/css/jquery.css') }}" type="text/css" />
			       {% endblock %}
			      
			       {% block javascripts %}
			           <script language="javascript" src="{{ asset('bundles/myprojectblog/js/jquery.js') }}"></script>
			       {% endblock %}
			    </head>
			    <body>
			            {% block content %}{% endblock %}
			                  {# END - BLOCK RESERVE AUX PLUGINS JQUERY UI UTILISANT LE CSS #}
			            {% block endJavascripts %}{% endblock %}
			    </body>
			</html>
		

Twig est un language simple qui permet l'héritage et l'imbracation. Sont language étant limité, cela permet d'éviter aux développeurs peu expérimentés d'écrire du code dans la partie template.
Dans l'exemple suivant, le code Twig redéfini ou surcharge les valeurs contenu dans les blocks du templates hérité (parent).

			{% extends 'MyProjectBlogBundle::layout.html.twig' %}
			{% block title %}
			    {{ parent() }} Article
			{% endblock %}
			{% block content %}
			    <h2>{{ article.title|trans }}</h>
			    <div class="content">
			       {% include('MyProjectBlogBundle:Article:content.html.twig') %}
			       {% autoescape false %}
			           {{ text }}
			       {% endautoescape %}
			    </div>
			{% endblock %}
		

Les modèles (yml, annotation, xml)

La partie modèle permet de définir la structure et les relations des objets par rapport à la base de données relationelle.
Elle peut être écrite sous forme d'annotation directement dans les classes des objets, en xml ou en Yaml.
Voici un exemple en Yaml :

			MyProject\CoreBundle\Entity\User:
		    type: entity
		    repositoryClass: MyProject\CoreBundle\Repository\UserRepository
		    table: user
		         id:
		           id:
		               type: integer
		               nullable: false
		               unsigned: false
		               id: true
		               generator:
		               		strategy: IDENTITY
		    fields:
		           login:
		               type: string
		               nullable: false
		               length: 255
		    manyToMany:
		           profile:
		               targetEntity: Profile
		               inversedBy: user
		               joinTable:
		                       name: lnk_user_profile
		                       joinColumns:
		                       		name: user_id
		                       			referencedColumnName: id
		                       inverseJoinColumns:
		                       		name: profile_id
		                       			referencedColumnName: id
		

Les formulaires

Les formulaires peuvent être crée de deux façon :

Les classes servent quand le formulaire est réutilisé plusieurs fois, ou lorsqu'il est lié à une entité.
Le builder est utile uniquement lorsque le formulaire est utilisé une seule fois, cela évite d'écrite trop de code.
Ce code doit être écrit dans le contrôleur et l'objet suivant doit être donnée à la vue pour qu'elle génère le formulaire :

$form->createView();

Pour afficher le formulaire voici un exemple de code à écrire dans la vue :

			{{ form_start(form, {'action': path('new_mail', {'id': 10})}) }}
			{{ form_errors(form) }}
			<div id="email">
			{{ form_label(form.email) }}
			      {{ form_widget(form.email) }}
			      {{ form_errors(form.email) }}
			</div>
			<div id="subject">
			{{ form_label(form.subject) }}
			      {{ form_widget(form.subject, {'attr': {'class': 'subject', 'title': 'Votre subjet'}) }}
			      {{ form_errors(form.subject) }}
			</div>
			<nput type="submit" />
			{{ form_end(form) }}
		

Les formulaires Symfony permettent :

Afin de vérifier la valider d'un formulaire, Symfony met à disposition un sytème de validation :

			$mail = new Mail();
			$form = $this->createForm(new MailType(), $mail);
			      
			$form->handleRequest($request);
			if ($form->isValid()) {
			    // sauvegarde des éléments de votre formulaire qui ne sont pas mappés avec l'objet
			    ...
			    // sauvegarde de votre objet qui a été mis à jour par le formulaire
			    $em = $this->getDoctrine()->getManager();    $em->persist($mail);    $em->flush();

			        // redirige vers une autre page
			}

			// retourne sur la page du formulaire et affiche des messages d’erreur