SonataAdminBundle + FOSUserBundle: Have a GOOD base project

Publié le par Jordan Samouh

This article is going to explain /how to/ correctly create a backoffice
(admin panel + crud) in Symfony 2.

Generally, for any web project, you need a back office to manager
entities, data, users and groups and, fortunately today there are a
number of bundles for Symfony 2 which allow you to create an admin panel

(.. because it is boring to redevelop phpmyadmin we can save ourselves
the effort and reutilise existing Symfony2 bundles)

What bundles do you need to install?

&lt;br /&gt;<br />
[FOSUserBundle]&lt;br /&gt;<br />
    git=git://;br /&gt;<br />
    target=bundles/FOS/UserBundle&lt;/p&gt;<br />
&lt;p&gt;[SonatajQueryBundle]&lt;br /&gt;<br />
    git=;br /&gt;<br />
    target=/bundles/Sonata/jQueryBundle&lt;/p&gt;<br />
&lt;p&gt;[SonataAdminBundle]&lt;br /&gt;<br />
    git=;br /&gt;<br />
    target=/bundles/Sonata/AdminBundle&lt;/p&gt;<br />
&lt;p&gt;[MenuBundle]&lt;br /&gt;<br />
    git=;br /&gt;<br />
    target=/bundles/Knp/Bundle/MenuBundle&lt;/p&gt;<br />
&lt;p&gt;[KnpMenu]&lt;br /&gt;<br />
    git=;br /&gt;<br />
    target=/knp/menu&lt;/p&gt;<br />
&lt;p&gt;[SonataUserBundle]&lt;br /&gt;<br />
    git=git://;br /&gt;<br />
    target=/bundles/Sonata/UserBundle&lt;/p&gt;<br />
&lt;p&gt;[SonataEasyExtendsBundle]&lt;br /&gt;<br />
    git=git://;br /&gt;<br />
    target=/bundles/Sonata/EasyExtendsBundle&lt;/p&gt;<br />
&lt;p&gt;[SonataDoctrineORMAdminBundle]&lt;br /&gt;<br />
    git=;br /&gt;<br />
    target=/bundles/Sonata/DoctrineORMAdminBundle&lt;br /&gt;<br />

Add the namespaces to app/autoload.php

&lt;br /&gt;<br />
// app/autoload.php&lt;br /&gt;<br />
$loader-&amp;gt;registerNamespaces(array(&lt;br /&gt;<br />
    // ...&lt;br /&gt;<br />
    'FOS'              =&amp;gt; __DIR__.'/../vendor/bundles',&lt;br /&gt;<br />
    'Sonata'           =&amp;gt; __DIR__.'/../vendor/bundles',&lt;br /&gt;<br />
    'Application'      =&amp;gt; __DIR__,&lt;br /&gt;<br />
    'Knp'              =&amp;gt; array(&lt;br /&gt;<br />
                          __DIR__.'/../vendor/bundles',&lt;br /&gt;<br />
                          __DIR__.'/../vendor/knp/menu/src',&lt;br /&gt;<br />
                          ),&lt;br /&gt;<br />
    // ...&lt;br /&gt;<br />
));&lt;br /&gt;<br />

Enable the bundles in app/AppKernel.php

&lt;br /&gt;<br />
// app/AppKernel.php&lt;br /&gt;<br />
    public function registerBundles()&lt;br /&gt;<br />
    {&lt;br /&gt;<br />
        $bundles = array(&lt;br /&gt;<br />
            // ...&lt;br /&gt;<br />
            new FOS\UserBundle\FOSUserBundle(),&lt;br /&gt;<br />
            new Sonata\jQueryBundle\SonatajQueryBundle(),&lt;br /&gt;<br />
            new Sonata\AdminBundle\SonataAdminBundle(),&lt;br /&gt;<br />
            new Sonata\DoctrineORMAdminBundle\SonataDoctrineORMAdminBundle(),&lt;br /&gt;<br />
            new Knp\Bundle\MenuBundle\KnpMenuBundle(),&lt;br /&gt;<br />
            new Sonata\UserBundle\SonataUserBundle('FOSUserBundle'),&lt;br /&gt;<br />
            new Sonata\EasyExtendsBundle\SonataEasyExtendsBundle(),&lt;br /&gt;<br />
            // ...&lt;br /&gt;<br />
        );&lt;br /&gt;<br />
        // ...&lt;br /&gt;<br />
    }&lt;br /&gt;<br />


&lt;br /&gt;<br />
# app/config/config.yml&lt;br /&gt;<br />
fos_user:&lt;br /&gt;<br />
    db_driver: orm&lt;br /&gt;<br />
    firewall_name: main&lt;br /&gt;<br />
    user_class: Application\Sonata\UserBundle\Entity\User&lt;br /&gt;<br />


&lt;br /&gt;<br />
php app/console sonata:easy-extends:generate SonataUserBundle&lt;br /&gt;<br />

It is going to generate an Application UserBundle, but you can use your own.
To develop your understanding, do this by default and try after to readapt the code with your UserBundle

Add the new Bundle to app/AppKernel.php

&lt;br /&gt;<br />
// app/AppKernel.php&lt;br /&gt;<br />
    public function registerbundles()&lt;br /&gt;<br />
    {&lt;br /&gt;<br />
        $bundles = array(&lt;br /&gt;<br />
            // Application Bundles&lt;br /&gt;<br />
            // ...&lt;br /&gt;<br />
            new Application\Sonata\UserBundle\ApplicationSonataUserBundle(),&lt;br /&gt;<br />
            // ...&lt;br /&gt;<br />
        );&lt;br /&gt;<br />
        // ...&lt;br /&gt;<br />
    }&lt;br /&gt;<br />

Add routing

&lt;br /&gt;<br />
# app/config/routing.yml&lt;br /&gt; <a href=""></a> <br />
fos_user_security:&lt;br /&gt;<br />
    resource: &amp;quot;@FOSUserBundle/Resources/config/routing/security.xml&amp;quot;&lt;/p&gt;<br />
&lt;p&gt;fos_user_profile:&lt;br /&gt;<br />
    resource: &amp;quot;@FOSUserBundle/Resources/config/routing/profile.xml&amp;quot;&lt;br /&gt;<br />
    prefix: /profile&lt;/p&gt;<br />
&lt;p&gt;fos_user_register:&lt;br /&gt;<br />
    resource: &amp;quot;@FOSUserBundle/Resources/config/routing/registration.xml&amp;quot;&lt;br /&gt;<br />
    prefix: /register&lt;/p&gt;<br />
&lt;p&gt;fos_user_resetting:&lt;br /&gt;<br />
    resource: &amp;quot;@FOSUserBundle/Resources/config/routing/resetting.xml&amp;quot;&lt;br /&gt;<br />
    prefix: /resetting&lt;/p&gt;<br />
&lt;p&gt;fos_user_change_password:&lt;br /&gt;<br />
    resource: &amp;quot;@FOSUserBundle/Resources/config/routing/change_password.xml&amp;quot;&lt;br /&gt;<br />
    prefix: /change-password&lt;/p&gt;<br />
&lt;p&gt;admin:&lt;br /&gt;<br />
    resource: '@SonataAdminBundle/Resources/config/routing/sonata_admin.xml'&lt;br /&gt;<br />
    prefix: /admin&lt;/p&gt;<br />
&lt;p&gt;_sonata_admin:&lt;br /&gt;<br />
    resource: .&lt;br /&gt;<br />
    type: sonata_admin&lt;br /&gt;<br />
    prefix: /admin&lt;/p&gt;<br />
&lt;p&gt;soanata_user:&lt;br /&gt;<br />
    resource: '@SonataUserBundle/Resources/config/routing/admin_security.xml'&lt;br /&gt;<br />
    prefix: /admin&lt;/p&gt;<br />
&lt;p&gt;sonata_user_impersonating:&lt;br /&gt;<br />
    pattern: /&lt;br /&gt;<br />
    defaults: { _controller: SonataPageBundle:Page:catchAll }&lt;br /&gt;<br />

Add the following to app/config/security.yml

&lt;br /&gt;<br />
# app/config/security.yml&lt;br /&gt;<br />
security:&lt;br /&gt;<br />
    encoders:&lt;br /&gt;<br />
        FOS\UserBundle\Model\UserInterface: sha512&lt;/p&gt;<br />
&lt;p&gt;    role_hierarchy:&lt;br /&gt;<br />
        ROLE_ADMIN:       ROLE_USER&lt;br /&gt; <a href=""></a> <br />
        SONATA:&lt;br /&gt;<br />
            - ROLE_SONATA_PAGE_ADMIN_PAGE_EDIT  # if you are not using acl then this line must be uncommented&lt;/p&gt;<br />
&lt;p&gt;    providers:&lt;br /&gt;<br />
        fos_userbundle:&lt;br /&gt;<br />
            id: fos_user.user_manager&lt;/p&gt;<br />
&lt;p&gt;    firewalls:&lt;/p&gt;<br />
&lt;p&gt;        # -&amp;gt; custom firewall for the admin area of the URL&lt;br /&gt;<br />
        admin:&lt;br /&gt;<br />
            pattern:      /admin(.*)&lt;br /&gt;<br />
            form_login:&lt;br /&gt;<br />
                provider:       fos_userbundle&lt;br /&gt;<br />
                login_path:     /admin/login&lt;br /&gt;<br />
                use_forward:    false&lt;br /&gt;<br />
                check_path:     /admin/login_check&lt;br /&gt;<br />
                failure_path:   null&lt;br /&gt;<br />
            logout:&lt;br /&gt;<br />
                path:           /admin/logout&lt;br /&gt;<br />
            anonymous:    true&lt;br /&gt;<br />
        # -&amp;gt; end custom configuration&lt;/p&gt;<br />
&lt;p&gt;        # defaut login area for standard users&lt;br /&gt;<br />
        main:&lt;br /&gt;<br />
            pattern:      .*&lt;br /&gt;<br />
            form_login:&lt;br /&gt;<br />
                provider:       fos_userbundle&lt;br /&gt;<br />
                login_path:     /login&lt;br /&gt;<br />
                use_forward:    false&lt;br /&gt;<br />
                check_path:     /login_check&lt;br /&gt;<br />
                failure_path:   null&lt;br /&gt;<br />
            logout:       true&lt;br /&gt;<br />
            anonymous:    true&lt;/p&gt;<br />
&lt;p&gt;# ...&lt;/p&gt;<br />
&lt;p&gt;    access_control:&lt;br /&gt;<br />
        # URL of FOSUserBundle which need to be available to anonymous users&lt;br /&gt;<br />
        - { path: ^/_wdt, role: IS_AUTHENTICATED_ANONYMOUSLY }&lt;br /&gt;<br />
        - { path: ^/_profiler, role: IS_AUTHENTICATED_ANONYMOUSLY }&lt;br /&gt;<br />
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }&lt;/p&gt;<br />
&lt;p&gt;        # -&amp;gt; custom access control for the admin area of the URL&lt;br /&gt;<br />
        - { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }&lt;br /&gt;<br />
        - { path: ^/admin/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }&lt;br /&gt;<br />
        - { path: ^/admin/login-check$, role: IS_AUTHENTICATED_ANONYMOUSLY }&lt;br /&gt;<br />
        # -&amp;gt; end&lt;/p&gt;<br />
&lt;p&gt;        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }&lt;br /&gt;<br />
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }&lt;/p&gt;<br />
&lt;p&gt;        # Secured part of the site&lt;br /&gt;<br />
        # This config requires being logged for the whole site and having the admin role for the admin part.&lt;br /&gt;<br />
        # Change these rules to adapt them to your needs&lt;br /&gt;<br />
        - { path: ^/admin, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }&lt;br /&gt;<br />
        - { path: ^/.*, role: IS_AUTHENTICATED_ANONYMOUSLY }&lt;br /&gt;<br />
# ...&lt;br /&gt;<br />

Do theses commands for the end

&lt;br /&gt;<br />
php app/console doctrine:schema:update --force&lt;br /&gt;<br />
php app/console assets:install web&lt;br /&gt;<br />
php app/console cache:clear&lt;br /&gt;<br />
php app/console fos:user:create admin password --super-admin&lt;br /&gt;<br />

You need to enable your translator in /app/config.yml

&lt;br /&gt;<br />
framework:&lt;br /&gt;<br />
    translator: ~&lt;br /&gt;<br />

That’s it!!!
As you can see, a lotof things must be done for it to

But after this initial step you will only need to modify the XML files
and the Admin class ((plural?)) of your new bundles.

With this demo you should have a functioning admin interface for « user »
and « group » entities. This is accomplished only with the following 2
- Setup UserAdmin Class (found in AdminFolder in the bundle SonataUserBundle) (see more info in SonataAdminBundle Doc)
- Setup admin_orm.xml (found in Ressources/coinfig in the bundle SonataUserBundle) (see more info in SonataAdminBundle Doc)

When you need to administer more entities in your application, editing
these two files is all you will need to do.

For more information, see:

Cette entrée a été publiée dans Symfony 2 Utils. Vous pouvez la mettre en favoris avec ce permalien.

9 réponses à SonataAdminBundle + FOSUserBundle: Have a GOOD base project

  1. Nelson dit :

    Hello. I’m stucked since a few hours in (probably) a stupid error, buy maybe is a compatibility issue across Symfony versions. The exception message is this:

    #php app/console sonata:easy-extends:generate SonataUserBundle
    PHP Fatal error: Class 'Application\Sonata\UserBundle\ApplicationSonataUserBundle' not found in /var/www/sonataadmin/app/AppKernel.php on line 28

    Everything seems to be on the place, in fact I have another test project that follow the steps of the official Sonata Project tutorial and it doesn’t complain about that class.

    I’m working on Symfony 2.0.14, by the way.

    • Glouzy201 dit :

      Salut Nelson, Me too I meet this error but the solution I used is simpl:

      Install SonataDoctrineExtension and then

      use this lines in your Autoload:

      if (!function_exists(‘intl_get_error_code’)) {
      #… rest of you code
      #… rest of you code
      ‘Sonata’ => array(
      __DIR__ . ‘/../vendor/bundles’,
      __DIR__ . ‘/../vendor/sonata-doctrine-extensions/src’
      #… rest of you code
      #… rest of you code

      $loader->add(‘Application’, __DIR__);
      #… rest of you code

      #GOOD LUCK

  2. Nelson dit :

    Hello there. I’m using Symfony 2.0.15 and I’ve just got another error message, but this time I have the solution.

    $ php app/console doctrine:schema:update --force

    Unknown column type json requested.

    doctrine:schema:update [--complete] [--dump-sql] [--force] [--em[="..."]]

    The solution is just install the bundle SonataDoctrineExtension and another couple in order to resolve the dependency




    And more important yet add a new key in app/config/config.yml like this:

    json: Sonata\Doctrine\Types\JsonType

    Let’s repeat the doctrine command once again:

    $ php app/console doctrine:schema:update --force
    Updating database schema...
    Database schema updated successfully! "14" queries were executed

    And that’s it! you can go on with the rest.

    Anyway, in the tutorial is missing the command to install all the bundles in the deps file, is pretty obvious, I know, but there’s a lot of Symfony newbies reading this. The command is:

    php bin/vendors install

  3. Didi dit :

    Thanks for this very good article.
    Could you explain us how to do the same with Composer ? without the deps file and with composer.json.

    • Didi dit :

      I think the first step must be to add theses lines in the composer.json after « require »:
      « friendsofsymfony/user-bundle »: « * »,
      « sonata-project/jquery-bundle »: « * »,
      « sonata-project/admin-bundle »: « * »,
      « sonata-project/user-bundle »: « * »,
      « sonata-project/easy-extends-bundle »: « * »,
      « sonata-project/doctrine-orm-admin-bundle »: « * »,
      « knplabs/knp-menu »: « * »,
      « knplabs/knp-menu-bundle »: « * »

      and then : php composer.phar update

      But i don’t know what to do next.

  4. Didi dit :

    Ok, i think i arrived to something.
    I don’t know how to edit a comment so I post a 3rd one. You shouldn’t validate my comments, and put a summary of all that in your article (after checking it ^^)

    So after  » php composer.phar update  » do all the rest of the article except the autoload.php part (just add the line i put down there). and add theses lines to the configuration files :
    # …
    json: Sonata\Doctrine\Types\JsonType

    translator: { fallback: %locale% }

    default_contexts: [cms]
    contexts: [admin]
    // app/autoload.php
    $loader->add(‘Application’, __DIR__);

    // app/AppKernel.php
    new Sonata\BlockBundle\SonataBlockBundle(),
    new Sonata\CacheBundle\SonataCacheBundle(),

  5. jdivins dit :

    Hello Jodan,
    I am following your tutorial, and maybe there is one mistake, you’ve written:
    instead of
    in routing.yml code
    Is correct?

  6. gtrennert dit :

    Nice !
    I only have issues when on a multilingual site – I added prefix: /{_locale}/admin on routes but now my firewall stopped working and admin area is no more secured.
    I tried something like this : pattern: ^/{_locale}/admin(.*) – but no way
    How can I get admin area work for different languages ?

  7. Thank you very much for this tutorial! Are you using Symfony 2.1 already? Have you, by any chance, built a Symfony2.1 base project including SonataAdminBundle + FOSUserBundle yet?

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *


one - = 0

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>