Un blog goutû sur Symfony2 Blog sur le tutoriel Symfony2 du siteduzero ainsi que des trucs et astuces http://www.tutoriel-symfony2.fr fr 2013-09-26T22:37:00+02:00 2013-09-26T22:37:00+02:00 Construire un menu avec du contenu en base de données avec KnpMenuBundle KNPMenuBundle est un Bundle qui permet de gérer assez facilement les menus d'un site web. Faire un menu statique est très simple et expliqué clairement dans la documentation. Mais parfois, le développeur a besoin de construire un menu (ou un sous-menu) en fonction de contenus en base de données. Ce billet va donc vous expliquer comment faire cela.

Le contexte

Nous allons prendre un exemple simple pour illustrer ce billet : j'ai une entité Produit avec les attributs nom et categorie, et une entité Categorie avec les attributs nom et produits. Chaque produit est relié à une catégorie.

Notre objectif est de construire un menu qui liste les catégories, et envoie l'utilisateur vers une page listant les produits de la catégorie sélectionnée.

Nous partons du principe que nous avons déjà un contrôleur qui s'occupe de lister les produits d'une catégorie. Sa route s'appelle liste_produits_categorie et elle attend un paramètre id, qui est l'identifiant de la catégorie.

Création de la classe Builder

Pour construire notre menu, il nous faut une classe Builder. Voici donc notre classe Builder par défaut :

use Knp\Menu\FactoryInterface;

class Builder
{
    public function createMainMenu(FactoryInterface $factory,
                                   array $option)
    {
        $menu = $factory->createItem('root');

        $menu->addChild(
            'categorie',
            array('label' => 'Nos produits par catégories')
        );

        // D'autres menus ensuite...

        return $menu;
    }
}

Notre objectif maintenant est de pouvoir utiliser le service Doctrine pour pouvoir faire une requête dans notre classe Builder. Pour cela, il va donc falloir transformer notre Builder en service. Ça tombe bien, la procédure est décrite dans la documentation (et en plus, l'utilisation des menus en sera aussi simplifiée).

Convertir notre classe Builder en service Symfony2

Premièrement, la documentation nous indique qu'il va falloir récupérer l'objet implémentant FactoryInterface dans le constructeur car ce dernier ne sera plus passé en argument auprès de notre fonction createMainMenu(). Dans notre cas, nous allons nous aussi avoir besoin d'un autre service : l'Entity Manager de Doctrine. Transformons donc notre classe ainsi :

use Knp\Menu\FactoryInterface;
use Doctrine\ORM\Entitymanager;

class Builder
{
    private $factory;
    private $em;

    public function __construct(FactoryInterface $factory,
                                Entitymanager $em)
    {
        $this->factory = $factory;
        $this->em = $em;
    }

    public function createMainMenu()
    {
        $menu = $this->factory->createItem('root');

        $menu->addChild(
            'categorie',
            array('label' => 'Nos produits par catégories')
        );

        // D'autres menus ensuite...

        return $menu;
    }
}

Déclarer les services dans la configuration de l'application

Il nous faut maintenant déclarer nos services auprès de Symfony2. Cela se fait dans le fichier services.yml de votre bundle, ou bien directement dans le fichier app/config/config.yml.

services:
    acme_main.menu_builder:
        class:     Acme\MainBundle\Menu\Builder
        arguments: ['@knp_menu.factory', '@doctrine.orm.entity_manager']

    acme_main.menu.main:
        class:           Knp\Menu\MenuItem
        factory_service: acme_main.menu_builder
        factory_method:  createMainMenu
        tags:
            - { name: knp_menu.menu, alias: main }

On voit bien ici que notre builder attend deux paramètres : le service Factory de KnpMenu ainsi que le service EntityManager de Doctrine. Notre builder est donc déclaré en tant que service.

Le deuxième service concerne le menu principal. En effet, on le déclare aussi comme service pour faciliter son utilisation dans les vues. Ce service fait appel à notre service Builder, et on précise la fonction appelée : createMainMenu. De cette manière, vous pouvez créer plusieurs menus au sein de votre classe Builder. Il vous suffit de déclarer deux services Menu, puis d'indiquer la bonne fonction pour l'option factory_method.

Voilà, tout est prêt maintenant pour construire notre menu en extrayant les informations de la base de données.

Construction du menu

Pour cela, rien de plus simple : nous avons l'EntityManager à notre disposition.

use Knp\Menu\FactoryInterface;
use Doctrine\ORM\Entitymanager;

class Builder
{
    private $factory;
    private $em;

    public function __construct(FactoryInterface $factory,
                                Entitymanager $em)
    {
        $this->factory = $factory;
        $this->em = $em;
    }

    public function createMainMenu()
    {
        $menu = $this->factory->createItem('root');

        $menu->addChild(
            'categorie',
            array('label' => 'Nos produits par catégories')
        );

        // Récupération de la liste des catégories.
        $listeCategories = $this->em->getRepository('AcmeMainBundle:Categorie')->find();

        // Création des sous-menus.
        foreach ($listeCategories as $categorie)
        {
            $menu['categorie']->addChild(
                'categorie_' . $categorie->getId(), // Identifiant du menu.
                array(
                    'label'           => $categorie->getNom();
                    'route'           => 'liste_produits_categorie'
                    'routeParameters' => array('id' => $categorie->getId()),
                )
            );
        }

        // D'autres menus ensuite...

        return $menu;
    }
}

Et voilà donc notre menu construit avec toutes les catégories présentes en base de données. Pour l'utiliser dans vos vues, il suffit simplement d'ajouter :

{{ knp_menu_render('main') }}

À noter que main représente l'alias que nous avons donné à notre menu dans la configuration des services.

]]>
http://tutoriel-symfony2.fr/blog/construire-un-menu-avec-du-contenu-en-base-de-donnees-avec-knpmenubundle http://tutoriel-symfony2.fr/blog/construire-un-menu-avec-du-contenu-en-base-de-donnees-avec-knpmenubundle 2013-09-26T22:37:00+02:00
Symfony2 avec Oracle DataBase sous Ubuntu Utiliser Symfony2 avec Oracle DataBase est un parcours assez peu documenté. Ce billet de blog tente donc de vous accompagner dans la configuration de Symfony2 pour utiliser Oracle DataBase. Attention, ce billet ne vous indique pas comment installer le serveur Oracle ! Nous partons du principe ici que le serveur de base de données existe déjà. On cherche juste à configurer Symfony2 pour se connecter à ce serveur, sous Ubuntu.

Tout d'abord, il va falloir utiliser le module PHP oci8, qui n'est pas présent par défaut sous Ubuntu.

Compilation du module oci8 pour php

Il va nous falloir télécharger et installer plusieurs outils pour compiler ce module. Executez les commandes suivantes :

sudo apt-get install build-essential
sudo apt-get install php5-dev php-pear libaio1

Ensuite, il va nous falloir rajouter des variables d'environnement nécessaire pour l'installation de l'InstantClient. Pour cela, il faut éditer le fichier /etc/environment et ajouter les lignes suivantes :

LD_LIBRARY_PATH="/usr/local/lib/instantclient_11_2"
TNS_ADMIN="/usr/local/lib/instantclient_11_2"
ORACLE_BASE="/usr/local/lib/instantclient_11_2"
ORACLE_HOME=$ORACLE_BASE

Ensuite, téléchargez le package Basic (le premier dans la liste) et le package SDK (le 5ème). A noter qu'il vous faut un compte sur le site d'Oracle pour pouvoir télécharger les fichiers.
Une fois téléchargé, retour sur la console, et saisissez les commandes suivantes :

cd /usr/local/lib
sudo unzip /chemin/vers/l/archive/instant-client-basic
sudo unzip /chemin/vers/l/archive/instant-client-sdk
cd instantclient_11_2
sudo ln -s libclntsh.so.11.1 libclntsh.so
sudo pecl install oci8

Pendant la compilation, on vous demandera le chemin vers la bibliothèque InstantClient. Répondez juste :

instantclient,/usr/local/lib/instantclient_11_2

Le module est maintenant compilé.

Activer le module dans PHP

Pour cela, rien de plus simple : il suffit de créer un fichier oci8.ini dans le répertoire /etc/php5/conf.d et d'ajouter le contenu suivant :

extension=oci8.so

Et bien sûr, n'oubliez pas de redémarrer le serveur Apache :

sudo service apache2 restart

Configuration de Symfony2

Ouvrez le fichier de configuration app/config/config.yml ainsi que le fichier app/config/parameter.yml.
Dans le fichier parameter.yml, renseignez l'adresse et le port (par défaut : 1521) du serveur hôte de la base de données. Renseignez ensuite le nom d'utilisateur, le mot de passe et le nom de la base de données (SID). Changez aussi le driver pdo_mysql par oci8.

Et voilà, c'est terminé ! Il est cependant possible que vous ayez des erreurs avec les champs date. En effet, Doctrine attend un certain format de date (Y:m:d H:i:s) alors que Oracle, en fonction de sa configuration, peut fournir les dates sous un autre format. Pour régler ce soucis, dans le fichier config.yml, rajoutez à la fin :

services:
    listener:
        class: Doctrine\DBAL\Event\Listeners\OracleSessionInit 
        tags:
            - { name: doctrine.event_listener, event: postConnect }

C'est un Doctrine Listener inclu dans Doctrine qui devrait résoudre le problème, il n'est pas activé par défaut.

]]>
http://tutoriel-symfony2.fr/blog/symfony2-avec-oracle-database-sous-ubuntu http://tutoriel-symfony2.fr/blog/symfony2-avec-oracle-database-sous-ubuntu 2013-08-29T10:13:00+02:00
Ouverture du blog à d'autres contributeurs Bonjour à tous,

Vous avez pu vous en rendre compte, ce blog n'est pas aussi actif que je ne le voudrais !

Nous avons peut-être une solution. Il y a quelques jours un membre me contacte sur le siteduzero avec un article sous le coude, et pas de blog pour le publier. J'ai bien sûr accepté de publier son article (sur Symfony2 et Oracle), vous le verrez demain ici-même.

L'initiative est très intéressante. Quelqu'un qui a quelque chose à dire sur Symfony2 ne devrait jamais être arrêté faute de lieu pour s'exprimer. C'est pourquoi, si vous vous sentez l'âme d'un auteur d'article de blog, n'hésitez pas à me contacter et nous regarderons ensemble comment publier vos articles ici !

A vos claviers !

]]>
http://tutoriel-symfony2.fr/blog/ouverture-du-blog-a-d-autres-contributeurs http://tutoriel-symfony2.fr/blog/ouverture-du-blog-a-d-autres-contributeurs 2013-08-28T12:14:00+02:00
Utiliser JsonResponse pour vos retours en Json Dans le cadre d'une API, d'appels en AJAX ou autres, vous avez déjà certainement retourné des données en Json.

Plutôt que de manuellement encoder en Json et de définir soi-même le type de la réponse, il existe une classe discrète mais bien utile qui fait tout à votre place. Il s'agit de JsonResponse, que je vous invite à consulter.

Cette classe est tellement pratique que vos retours Json ne se font désormais plus qu'en une seule ligne, voyez par vous-mêmes :

use Symfony\Component\HttpFoundation\JsonResponse;

public function fooAction()
{
    $data = $this->getDoctrine()
                 ->getManager()
                 ->getRepository('Bundle:Entity')
                 ->findAll();

    return new JsonResponse($data);
}

Inutile d'utiliser json_encode() sur vos données (ici $data), et inutile également de définir le Content-type adéquat pour la réponse. Bref, du gain de code, donc du bonheur !

]]>
http://tutoriel-symfony2.fr/blog/utiliser-jsonresponse-pour-vos-retours-en-json http://tutoriel-symfony2.fr/blog/utiliser-jsonresponse-pour-vos-retours-en-json 2013-05-05T00:00:00+02:00
Une checklist pour vos mises en production Il y a quelques jours j'ai ouvert le site Symfony2-checklist.com.

C'est un site qui contient une checklist de petits points à vérifier impérativement avant toute mise en production. Ce sont des points plus ou moins facile à mettre en oeuvre, mais qu'il faut absolument traiter avant d'ouvrir votre site au monde entier. En bref : à utiliser !

J'ai voulu ce site communautaire, c'est-à-dire que vous pouvez y apporter votre pierre en un clic : il suffit pour cela d'utiliser le dépôt Github de la checklist. Grâce à Github, vous pouvez facilement corriger une erreur, ajouter un élément dans la liste, et le proposer en retour. Toute modification sur le dépôt Github est publiée sur le site internet dans l'heure suivante. C'est aussi ça l'esprit Symfony2 !

D'ailleurs si vous parlez une langue qui n'existe pas encore sur le site, vous ferez des heureux en traduisant les points déjà existants de la liste dans la langue que vous maîtrisez. N'hésitez pas !

J'ouvrirai également bientôt le code source du site. Rien de bien révolutionnaire dedans, mais cela peut servir d'exemple pour certains. C'est en lisant le code des autres qu'on gagne de l'expérience ! Le temps pour moi de nettoyer un peu le code et je vous préviendrai de la publication.

]]>
http://tutoriel-symfony2.fr/blog/une-checklist-pour-vos-mises-en-production http://tutoriel-symfony2.fr/blog/une-checklist-pour-vos-mises-en-production 2013-03-18T00:00:00+01:00
Sortie du cours Symfony 2.2 en livre ! Certains d'entre vous l'avaient sûrement deviné, ou aperçu, c'est donc maintenant officiel : le cours sur Symfony2 est sorti en livre !

J'ai fait un effort en amont afin que le cours soit entièrement prêt pour la version 2.2, sortie la semaine dernière. Du coup, le livre est totalement compatible avec les versions 2.3 et 2.4 à minima étant donnée la politique de BC de Sensio à partir de la version 2.2.

Bref, ce livre c'est que du bonheur ! Vous trouverez le livre Symfony2 en précommande sur le siteduzero au prix public de 24€ jusqu'au 22 mars. Il sera ensuite disponible au prix de 29€ dans toutes les librairies physiques comme en ligne (telle qu'Amazon ou Fnac)

Je tiens à remercier toutes les personnes qui ont rendu possible ce livre, à commencer par Jonathan Baudoin l'éditeur en charge du livre chez Simple IT, et bien sûr tous les lecteurs de la première heure qui m'ont fait d'innombrables remarques constructives pour l'amélioration du cours.

N'hésitez pas à bien relayer l'information, il s'agit ici du premier livre sur Symfony2 toutes langues confondues !

]]>
http://tutoriel-symfony2.fr/blog/sortie-du-cours-symfony-2-2-en-livre http://tutoriel-symfony2.fr/blog/sortie-du-cours-symfony-2-2-en-livre 2013-03-04T00:00:00+01:00
Comment créer une commande Symfony ? Voici une fonctionnalité très intéressante de Symfony, mais que trop de débutants méconnaissent ou sous-utilisent.

Vous avez forcément besoin un moment ou un autre de mettre en place un cron, ou une tâche répétitive, que ce soit pour du développement ou en production. Dans ce cas, plutôt que de passer à l'ancienne par votre navigateur, privilégiez de loin l'utilisation de commande Symfony : propre et efficace !

Pour cela, il suffit d'avoir dans votre bundle un répertoire Command. A l'intérieur, pour chaque nouvelle commande que vous voulez créer, ajoutez un fichier se terminant par Command, par exemple ExampleCommand.php. C'est tout !

Ensuite, ce n'est qu'un peu de syntaxe à connaître, voici l'exemple tiré de la documentation :

<?php
// src/Acme/DemoBundle/Command/GreetCommand.php
namespace Acme\DemoBundle\Command;

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class GreetCommand extends ContainerAwareCommand
{
    protected function configure()
    {
        $this
            ->setName('demo:greet')
            ->setDescription('Saluer une personne')
            ->addArgument('name', InputArgument::OPTIONAL, 'Qui voulez vous saluer??')
            ->addOption('yell', null, InputOption::VALUE_NONE, 'Si définie, la tâche criera en majuscules')
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $name = $input->getArgument('name');
        if ($name) {
            $text = 'Bonjour '.$name;
        } else {
            $text = 'Bonjour';
        }

        if ($input->getOption('yell')) {
            $text = strtoupper($text);
        }

        $output->writeln($text);
    }
}

C'est tout !

Vous pouvez maintenant exécuter la méthode execute() via php app/console demo:greet Fabien.

Et bien sûr, vous avez accès au conteneur de services car cette classe étend ContainerAware, via $this->getContainer(),

]]>
http://tutoriel-symfony2.fr/blog/comment-creer-une-commande-symfony http://tutoriel-symfony2.fr/blog/comment-creer-une-commande-symfony 2013-02-18T00:00:00+01:00
Nouveaux chapitres : les évènements et les traductions ! Au menu aujourd'hui : deux nouveaux chapitres !

Le premier porte sur le Gestionnaire d'Evènements Symfony2. Il s'agit de présenter l'intérêt et l'utilisation des évènements avec Symfony2. Sachez qu'ils permettent de réaliser un code vraiment découplé, et donc très propre. C'est aussi un des moyens de faire le fameux "exécuter quelque chose à chaque page", sans le mettre salement dans un ou plusieurs contrôleurs. Bref, un outil indispensable que je vous invite à découvrir dès maintenant !

Le deuxième chapitre porte sur la Traduction Symfony2. Il s'agit ici de découvrir comment traduire son interface avec Symfony2, en utilisant tous les mécanismes et helpers mis à disposition par le framework. Vous verrez que cela se fait assez facilement, et encore une fois de façon très propre. N'oubliez jamais : l'un des gros intérêts d'un framework est la maintenabilité du code ;)

N'hésitez pas à lire ces deux nouveaux chapitres pour en apprendre plus sur Symfony2. Je suis également friand de vos retours pour améliorer jour après jour le tutoriel !

Merci et bonne lecture !

]]>
http://tutoriel-symfony2.fr/blog/nouveaux-chapitres-les-evenements-et-les-traductions http://tutoriel-symfony2.fr/blog/nouveaux-chapitres-les-evenements-et-les-traductions 2013-02-04T00:00:00+01:00
Mise à jour du tutoriel pour Symfony 2.1 La mise à jour du tutoriel vient d'être publiée !

Cette mise à jour rend le tutoriel entièrement compatible avec la version 2.1 de Symfony. Elle ajoute également quelques améliorations diverses, ainsi que l'ajout d'une sous-partie sur les contraintes de validation perso. N'hésitez donc pas à relire l'ensemble du tutoriel si vous n'y avez pas jeté un oeil depuis quelques temps.

Par ailleurs, j'ai commencé il y a peu à mettre en place des QCM en fin de chapitre. Les quelques premiers chapitres sont donc maintenant équipés de QCM. N'hésitez pas à me faire vos retours sur ceux-là, afin d'améliorer la pertinence pour les prochains.

Enfin, les prochains chapitre prévus dans le tutoriels seront sur Composer, les évènements Doctrine ainsi que les évènements Symfony. Restez à l’affût !

]]>
http://tutoriel-symfony2.fr/blog/mise-a-jour-du-tutoriel-pour-symfony-2-1 http://tutoriel-symfony2.fr/blog/mise-a-jour-du-tutoriel-pour-symfony-2-1 2012-11-11T00:00:00+01:00
Les vidéos des Symfony Live Events Les Symfony Live sont des évènements qui proposent un ensemble de conférences sur Symfony2 et certains sujets alentours. Ils se tiennent dans différentes villes suivant les éditions, en l'occurrence les deux derniers étaient à Paris et San Francisco.

Les conférences dispensées lors de ces évènements sont très intéressantes, et bonne nouvelle lors des deux dernières éditions elles étaient filmées !

Récemment, Fabien Potencier a publié sur le site de Symfony ces vidéos, et ce gratuitement ! C'est une très bonne chose sachant que les évènements ne sont pas toujours dans votre ville, et sont en plus payants.

Je vous invite donc à vous rendre sur la page des conférences, et à choisir celles qui vous intéressent le plus. Le choix n'est pas évident car elles sont toutes passionnantes, et si vous avez du temps devant vous n'hésitez pas à en enchaîner plusieurs !

Si vous ne devez en sélectionner que quelque unes, voici ma sélection:

Bonus : si ces conférences sont bien entendu tenues en anglais, certaines d'entre elles sont traduites. Pas d'excuse si vous n'êtes pas anglophile ;)

Bon visionnage !

]]>
http://tutoriel-symfony2.fr/blog/les-videos-des-symfony-live-events http://tutoriel-symfony2.fr/blog/les-videos-des-symfony-live-events 2012-10-16T00:00:00+02:00