Création d'un Bundle

La plupart des informations proviennent du tutoriel Openclassroom de Alexandre Bacco : https://openclassrooms.com/courses/developpez-votre-site-web-avec-le-framework-symfony2/symfony2-un-framework-php, très détaillé. Je ne résume ici que les commandes en ligne et syntaxe comme memento.

Création de l'enveloppe

Création d'un bundle en ligne de commande

Dans le répertoire du projet on exécute :

$ php app/console generate:bundle

Une série d'informations doit être saisie en ligne de commande; on laisse la valeur par défaut la plupart du temps.

  1. Le namespace
    Bundle namespace : Machin/TrucBundle

    (voir aussi Architecture pour les namespaces)

  2. Le nom du bundle
    Bundle name [MachinTrucBundle]:

    On garde le nom proposé entre crochet en appuyant sur “enter”

  3. La destination
    Target directory [path_to_mon_projet/src]:

    On garde le répertoire src de notre projet en tepant “enter”.

  4. Le format des fichiers de configuration
    Configuration format (yml, xml, php, or annotation[annotation]:yml

    On ne prend pas la valeur par défaut.On choisit le format yml pour les fichiers de configuration.

  5. La génération ou non de la structure
    Do you want to generate the whole directory structure [no]? yes

    On demande à Symfony de générer tous les fichiers pour notre bundle, en tapant yes et validant.

Les modifications réalisées automatiquement

Voilà tout ce que nous n'aurons pas à faire :

  1. Ajout du nouveau Bundle dans app/AppKernel.php

use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;

class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
            new Symfony\Bundle\SecurityBundle\SecurityBundle(),
            new Symfony\Bundle\TwigBundle\TwigBundle(),
            new Symfony\Bundle\MonologBundle\MonologBundle(),
            new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
            new Symfony\Bundle\AsseticBundle\AsseticBundle(),
            new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
            new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
            new Machin\TrucBundle\MachinTrucBundle() // Ajout du bundle
        );

        //...etc

        return $bundles;
    }
   

  1. Ajout du nouveau dans le fichier de routing de l'application app/config/routing.yml
        machin_truc:
            resource: "@MachinTrucBundle/Resources/config/routing.yml"
            prefix:   / 

    Ici, il n'y a pas de préfixe mais on peut imaginer créer un bundle Machin/AdminBundle pour le quel on préfixerait avec /admin toutes les url relatives à ce bundle.

  2. Création du dossier src/Machin et du sous-dossier src/Machin/TrucBundle et de tout ce qu'il contient (voir aussi Architecture ).
  3. Création pour le bundle d'une route par défaut dans src/Machin/TrucBundle/Resources/config/routing.yml
        machin_truc_homepage:
            path:     /hello/{name}
            defaults: { _controller: MachinTrucBundle:Default:index }

    C'est dans ce fichier que l'on définit toutes les url relatives aux actions du Controller

  4. Création d'un controller par défaut src/Machin/TrucBundle/Controller/DefaultController.php.

namespace Machin\TrucBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;

class DefaultController extends Controller
{
    public function indexAction()
    {
        return new Response(« hello accueil ») ;
    }
}

Syntaxe routing

Je mets ici ce sujet, faute de savoir où, changera sans doute.

Il s'agit de détailler la syntaxe du fichier src/Machin/TrucBundle/Resources/config/routing.yml définissant les routes du bundle. Il n'est pas obligatoire d'utiliser ce format.

On peut dans ce fichier

  • définir le nom des paramètres passés,
  • définir une valeur par défaut pour les paramètres,
  • imposer un pattern au paramètre,
  • imposer une méthode
  • …etc

Ci-dessous, je définis la route “machin_truc-add” dont l'url sera du genre “mon_site/truc/add/9” qui correspond à la méthode(action) add de mon controller IndexController, on passe le paramètre trucId, qui par défaut vaut 0 et qui ne peut pas être autre chose qu'un nombre.

    machin_truc_add:
        path:  /truc/add/{trucId}
        defaults: { _controller: MachinTrucBundle:Index:add, trucId:0 }
        requirements:
            trucId: \d*
            methods: [GET]

C'est ainsi que aussi, que je peux générer une url dans un controller:

  $url = $this->get('router')->generate(
        'machin_truc_add',        // 1er argument : le nom de la route
         array('trucId' => 5),    // 2e argument : les valeurs des paramètres
         true                    // 3e argument url absolue, (relative par défaut
    );
    // $url relative vaut « /truc/add/5 »
    return $this->redirect($url);

Objets élémentaires

Request

Dans le controller, on accède aux données de la requête (http) :

$request = $this->getRequest();
Il est toutefois conseiller de la passer en argument de l'action en précisant son type Request comme ci-dessous.

//src/Machin/TrucBundle/Controller/BiduleController.php
namespace Machin\TrucBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;

class BiduleController extends Controller
{
    public function addAction($trucId, Request $request)
    {
        $value = $request->request->get("value");    //donnée passée en POST
        $tag   = $request->query->get("tag");        //donnée passée en GET (vieille méthode ?tag=26)
        $key   = $request->cookies->get("key");      // variable de cookie
        $uri   = $request->server->get("REQUEST_URI");// Variable de serveur
        $agent = $request->headers->get("USER_AGENT");// Entête
        $trucId = $request->attributes->get("trucId"); //variable dans route
        $file = $request->files->get("file"); //les fichiers
        //les variables de session aussi, si toutefois on a une session
        if($request->hasSession()){
            $login = $request->getSession()->get("login");
        }
    }
}

Response

Ne pas oublier d'ajouter au dessus de la classe les classes utilisées

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
...
Ensuite, on tous les types de réponses text, html, json, …
//banal
 $response = new Response("Hello");

// json
 $reponse =  new Response(json_encode($tab));
 $reponse->headers->set("Content-Type","application/json");

// fichier pdf
 $response = new Response();
 $response->setContent(file_get_contents($fichier));
 $response->headers->set('Content-Type', 'application/force-download');
//pour afficher le fichier :  $response->headers->set('Content-Type', 'application/pdf');
 $response->headers->set('Content-disposition', 'filename='. $nomfichier);

//une erreur
 $response = new Response();
 $response->setContent("Ceci est une page d'erreur 404");
 $response->setStatusCode(Response::HTTP_NOT_FOUND);


//Ne pas oublier le return
 return $response;

// et aussi biensur on peut envoyer les données dans un template
 $this ->render('MachinTrucBundle:Bidule:add.html.twig',$data);

Suite Twig