Installer et adapter SonatraAdminBundle à son projet Symfony2

L’un des points “faibles” du framework Symfony est qu’il ne dispose pas d’un outil d’administration a proprement parler pour gérer les entités créées et on est souvent amené à créer notre propre système d’administration ce qui est fastidieux et surtout rarement réutilisable. Pour combler cette lacune, vous allez découvrir dans la suite de cet article comment installer et adapter le Bundle Symfony2 SonatraAdminBundle.

En effet, SonatraAdminBundle permet d’ajouter une interface d’administration à votre projet  Symfony même s’il est déjà déployé et de l’adapter à toutes les entités créaient au moyen de quelques paramétrages.

Pour commencer voici les Bundles que nous allons utiliser dans la suite :

La première chose à faire est de télécharger les Bundles en question

Pour SonataDoctrineORMAdminBundle :

Avec Composer :

php composer.phar require sonata-project/doctrine-orm-admin-bundle

A la question “Please provide a version constraint for the sonata-project/doctrine-orm-admin-bundle requirement:” veuillez répondre “dev-master” si vous souhaitez utilisez la dernière version.

Pour activer le Bundle, il faut aller sur la page app/AppKernel.php et ajouter la ligne :
new Sonata\DoctrineORMAdminBundle\SonataDoctrineORMAdminBundle(),

<?php
// app/AppKernel.php
public function registerBundles()
{
return array(
// ...
// set up basic sonata requirements
// ...
new Sonata\DoctrineORMAdminBundle\SonataDoctrineORMAdminBundle(),
// ...
);
}

Pour SonataAdminBundle

Avec composer :

php composer.phar require sonata-project/admin-bundle

A la question “Please provide a version constraint for the sonata-project/jquery-bundle requirement: ” veuillez également répondre “dev-master” si vous souhaitez utilisez la dernière version.

Cela va télécharger SonataAdminBundle et ses dépendances à savoir SonataBlockBundle,SonatajQueryBundle et KnpMenuBundle qu’il faut par la suite activer dans le fichier AppKernel.php

// app/AppKernel.php
public function registerBundles()
{
return array(
// ...

//Add you dependencies
new Sonata\BlockBundle\SonataBlockBundle(),
new Sonata\jQueryBundle\SonatajQueryBundle(),
new Knp\Bundle\MenuBundle\KnpMenuBundle(),
//...

//If you haven't already, add the storage bundle
//This example uses SonataDoctrineORMAdmin but
//it works the same with the alternatives
new Sonata\DoctrineORMAdminBundle\SonataDoctrineORMAdminBundle(),

//Then add SonataAdminBundle
new Sonata\AdminBundle\SonataAdminBundle(),
// ...
);
}
Configuration de SonataAdminBundle

Ajouter dans le fichier app/config/config.yml

# app/config/config.yml
//...
sonata_admin:
    title: Sonata Admin Bundle #à personnaliser
    title_logo: /bundles/acmedemo/fancy_acme_logo.png #à personnaliser

    dashboard:
        blocks:
            -
                position: left
                type: sonata.admin.block.admin_list
            -
                position: right
                type: sonata.block.service.text
                settings:
                    content: >
                        <h2>Welcome to the Sonata Admin</h2>
                        <p>This is a <code>sonata.block.service.text</code> from the Block
                        Bundle, you can create and add new block in these area by configuring
                        the <code>sonata_admin</code> section.</p> <br /> For instance, here
                        a RSS feed parser (<code>sonata.block.service.rss</code>):
            -
                position: right
                type: sonata.block.service.rss
                settings:
                    title: Sonata Project's Feeds
                    url: http://sonata-project.org/blog/archive.rss

sonata_block:
    default_contexts: [cms]
    blocks:
        # Enable the SonataAdminBundle block
        sonata.admin.block.admin_list:
            contexts:   [admin]
        # Your other blocks
        sonata.block.service.text: 

        sonata.block.service.rss:

Une fois terminé, il faut installer les assets depuis les bundle avec la commande

php app/console assets:install web

et vider le cache

php app/console cache:clear

A ce stade, votre projet Symfony2 est fonctionnel et ne devrait présenter aucune erreur.

Si néanmoins vous rencontrez des problèmes ne paniquez pas, essayer de lire les erreurs affichées et de voir quel Bundle en est la source. Vérifiez que vous avez bien installer tous les Bundles et leurs dépendances et de les avoir activé dans le fichier AppKernel.php. Si le problème persiste toujours, n’hésitez pas à faire une recherche sur Google ou bien de consulter les forums spécialisés (Sonata Users GroupSymfony2 Users Group ou Symfony Forum).

Configuration des routes

Pour pouvoir accéder aux pages du Bundle SonataAdminBundle, il faut rajouter certaines routes dans le fichier routing.yml

# app/config/routing.yml
admin:
resource: '@SonataAdminBundle/Resources/config/routing/sonata_admin.xml'
prefix: /admin

_sonata_admin:
resource: .
type: sonata_admin
prefix: /admin

Vous pouvez taper l’adresse : http://monSite.local/admin/dashboard pour accéder à l’administration du site (qui est pour le moment vide, mais ça marche tout de même).

Dans la suite de l’article, je vais utiliser deux entités que j’ai créé dans un précédent projet à savoir “Article” et “Categorie”. Le premier dispose des champs id et intitule et le second id, titre, auteur, categories et contenu.

Créer le service Admin

Dans votre Bundle, ajoutez un nouveau fichier admin.yml, dans le quel on ajoutera les différents éléments de notre projet afin de ne pas surcharger le fichier config.yml

# Acme/DemoBundle/Resources/config/admin.yml
services:
sonata.admin.categorie:
class: Acme\DemonBundle\Admin\CategorieAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: "Content", label: "Catégories" }
arguments: [null, Acme\DemonBundle\Entity\Categorie, AcmeDemoBundle:CategorieAdmin]

sonata.admin.article:
class: Acme\DemonBundle\Admin\ArticleAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: "Content", label: "Articles" }
arguments: [null, Acme\DemonBundle\Entity\Article, AcmeDemoBundle:ArticleAdmin]
il faut par la suite importer ce fichier dans config.yml
# app/config/config.yml
imports:
- { resource: @AcmeDemoBundle/Resources/config/admin.yml }
Ensuite dans le fichier Acme/DemoBundle/DependencyInjection/AcmeDemoBundleExtension.php

Remplacer
$loader->load(‘services.yml’);
par
$loader->load(‘admin.yml’);

<?php

namespace Acme\DemoBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;

/**
 * This is the class that loads and manages your bundle configuration
 *
 * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
 */
class AcmeDemoBundleExtension extends Extension
{
    /**
     * {@inheritDoc}
     */
    public function load(array $configs, ContainerBuilder $container)
    {
        $configuration = new Configuration();
        $config = $this->processConfiguration($configuration, $configs);

        $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
        //$loader->load('services.yml');
    	$loader->load('admin.yml');
    }
}

Créer les class Admin

Dans votre Bundle créer un nouveau dossier que vous nommerez Admin (Acme/DemoBundle/Admin) puis créer dedans deux nouveaux fichiers CategorieAdmin.php etArticleAdmin.php

<?php
//Acme/DemoBundle/Admin/CategorieAdmin.php
namespace Acme\DemoBundle\Admin;

use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;

class CategorieAdmin extends Admin
{
protected $datagridValues = array(
'_sort_order' => 'ASC',
'_sort_by' => 'intitule'
);

//Fields to be shown on create/edit forms
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('intitule', 'text', array('label' => 'Catégorie'))
;
}

//Fields to be shown on filter forms
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
->add('intitule')
;
}

//Fields to be shown on lists
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('id')
->addIdentifier('intitule')

;
}
}
<?php

//Acme/DemoBundle/Admin/ArticleAdmin.php
namespace Acme\DemoBundle\Admin;

use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;

class ArticleAdmin extends Admin
{
protected $datagridValues = array(
'_sort_order' => 'ASC',
'_sort_by' => 'ordre'
);

protected $maxPerPage = 5;

//Fields to be shown on create/edit forms
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('titre', 'text', array('label' => 'Titre'))
->add('auteur')
->add('contenu') //if no type is specified, SonataAdminBundle tries to guess it
#->add('categories')
->add('categories', 'sonata_type_model',array('expanded' => true, 'compound' => true, 'multiple' => true))
->setHelps(array(
'titre' => $this->trans('help_post_title')
))

;
}

//Fields to be shown on filter forms
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
->add('titre')
->add('slug')
->add('auteur')
;
}

//Fields to be shown on lists
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('titre')
->add('slug')
->add('auteur')
->add('categories')
->add('_action', 'actions', array(
'actions' => array(
'view' => array(),
'edit' => array(),
'delete' => array(),
)
))
;
}
}

Voila, à ce stade l’administration de votre site est entièrement fonctionnelle avec le module Catégorie et Article.

SonataAdminBundle Dashboard

 Accueil de l’administration

SonataAdminBundle Dashboard

 Liste des catégories

SonataAdminBundle Dashboard

Ajouter une catégorie

SonataAdminBundle Dashboard

Liste des articles

SonataAdminBundle Dashboard

Ajouter un article

SonataAdminBundle Dashboard

Ajouter une catégorie depuis un article