Symfony2.1 + sonata-admin + sonata-user +fos-userbundle [EN]

Symfony2.1 + sonata-admin + sonata-user +fos-userbundle [EN]

Hy, everybody, today we will see how to install Symfony2.1 and the following bundles:

  • FOSUserBundle
  • SonataAdminBundle
  • SonataUserBundle

tl;dr: There is a GitHub repository with the project.

The first step is to create the project with the following command line:

composer create-project symfony/framework-standard-edition sonataadmin.fr

Then we edit the composer.json file to add the bundles:

"sonata-project/admin-bundle": "dev-master",
"friendsofsymfony/user-bundle": "dev-master",
"sonata-project/user-bundle": "dev-master",
"sonata-project/doctrine-orm-admin-bundle": "dev-master"

Update the AppKernel.php file to add the following bundles:

new FOS\UserBundle\FOSUserBundle(),
new Sonata\jQueryBundle\SonatajQueryBundle(),
new Sonata\AdminBundle\SonataAdminBundle(),
new Sonata\BlockBundle\SonataBlockBundle(),
new Sonata\DoctrineORMAdminBundle\SonataDoctrineORMAdminBundle(),
new Knp\Bundle\MenuBundle\KnpMenuBundle(),
new Sonata\UserBundle\SonataUserBundle('FOSUserBundle'),
new Sonata\EasyExtendsBundle\SonataEasyExtendsBundle(),

As Sonata Admin Bundle need the translation, we turn in on in the config.yml

framework:
    #esi:             ~
    translator:      { fallback: "%locale%" }
    secret:          "%secret%"

And we add the configuration for fosuserbundle and sonata admin in the config.yml:

fos_user:
    db_driver: orm
    firewall_name: main
    user_class: Application\Sonata\UserBundle\Entity\User

sonata_block:
    default_contexts: [cms]
    blocks:
        sonata.admin.block.admin_list:
            contexts:   [admin]

        #sonata.admin_doctrine_orm.block.audit:
        #    contexts:   [admin]

        sonata.block.service.text:
        sonata.block.service.action:
        sonata.block.service.rss:

        # Some specific block from the SonataMediaBundle
        #sonata.media.block.media:
        #sonata.media.block.gallery:
        #sonata.media.block.feature_media:

sonata_admin:
    title:      Admin Panel
    title_logo: /bundles/sonataadmin/logo_title.png
    templates:
        # default global templates
        layout:  SonataAdminBundle::standard_layout.html.twig
        ajax:    SonataAdminBundle::ajax_layout.html.twig

        # default actions templates, should extend a global templates
        list:    SonataAdminBundle:CRUD:list.html.twig
        show:    SonataAdminBundle:CRUD:show.html.twig
        edit:    SonataAdminBundle:CRUD:edit.html.twig
    dashboard:
        blocks:
            # display a dashboard block
            - { position: left, type: sonata.admin.block.admin_list }

sonata_doctrine_orm_admin:
    # default value is null, so doctrine uses the value defined in the configuration
    entity_manager: ~

    templates:
        form:
            - SonataDoctrineORMAdminBundle:Form:form_admin_fields.html.twig
        filter:
            - SonataDoctrineORMAdminBundle:Form:filter_admin_fields.html.twig
        types:
            list:
                array:      SonataAdminBundle:CRUD:list_array.html.twig
                boolean:    SonataAdminBundle:CRUD:list_boolean.html.twig
                date:       SonataAdminBundle:CRUD:list_date.html.twig
                time:       SonataAdminBundle:CRUD:list_time.html.twig
                datetime:   SonataAdminBundle:CRUD:list_datetime.html.twig
                text:       SonataAdminBundle:CRUD:base_list_field.html.twig
                trans:      SonataAdminBundle:CRUD:list_trans.html.twig
                string:     SonataAdminBundle:CRUD:base_list_field.html.twig
                smallint:   SonataAdminBundle:CRUD:base_list_field.html.twig
                bigint:     SonataAdminBundle:CRUD:base_list_field.html.twig
                integer:    SonataAdminBundle:CRUD:base_list_field.html.twig
                decimal:    SonataAdminBundle:CRUD:base_list_field.html.twig
                identifier: SonataAdminBundle:CRUD:base_list_field.html.twig

            show:
                array:      SonataAdminBundle:CRUD:show_array.html.twig
                boolean:    SonataAdminBundle:CRUD:show_boolean.html.twig
                date:       SonataAdminBundle:CRUD:show_date.html.twig
                time:       SonataAdminBundle:CRUD:show_time.html.twig
                datetime:   SonataAdminBundle:CRUD:show_datetime.html.twig
                text:       SonataAdminBundle:CRUD:base_show_field.html.twig
                trans:      SonataAdminBundle:CRUD:show_trans.html.twig
                string:     SonataAdminBundle:CRUD:base_show_field.html.twig
                smallint:   SonataAdminBundle:CRUD:base_show_field.html.twig
                bigint:     SonataAdminBundle:CRUD:base_show_field.html.twig
                integer:    SonataAdminBundle:CRUD:base_show_field.html.twig
                decimal:    SonataAdminBundle:CRUD:base_show_field.html.twig

Since it’s an admin bundle we setup the security in the security.yml file:

security:
    encoders:
        FOS\UserBundle\Model\UserInterface: sha512

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_SONATA_ADMIN, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
        SONATA:
            - ROLE_SONATA_PAGE_ADMIN_PAGE_EDIT  # if you are not using acl then this line must be uncommented

    providers:
        fos_userbundle:
            id: fos_user.user_manager

    firewalls:

        # -> custom firewall for the admin area of the URL
        admin:
            pattern:      /admin(.*)
            form_login:
                provider:       fos_userbundle
                login_path:     /admin/login
                use_forward:    false
                check_path:     /admin/login_check
                failure_path:   null
            logout:
                path:           /admin/logout
            anonymous:    true
        # -> end custom configuration

        # defaut login area for standard users
        main:
            pattern:      .*
            form_login:
                provider:       fos_userbundle
                login_path:     /login
                use_forward:    false
                check_path:     /login_check
                failure_path:   null
            logout:       true
            anonymous:    true

    access_control:
        # URL of FOSUserBundle which need to be available to anonymous users
        - { path: ^/_wdt, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/_profiler, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }

        # -> custom access control for the admin area of the URL
        - { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/login-check$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        # -> end

        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }

        # Secured part of the site
        # This config requires being logged for the whole site and having the admin role for the admin part.
        # Change these rules to adapt them to your needs
        - { path: ^/admin, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }
        - { path: ^/.*, role: IS_AUTHENTICATED_ANONYMOUSLY }

Using the smyfony console we now generate the configuration for the user admin thanks to the SonataEasyExtendsBundle: app/console sonata:easy-extends:generate SonataUserBundle The bundle is created into the app folder, move it to src.

Once it done add this new bundle to the AppKernel.php:

new Application\Sonata\UserBundle\ApplicationSonataUserBundle(),

We have now to care of the entity and update them with @ORM annotation:

<?php

namespace Application\Sonata\UserBundle\Entity;

use Sonata\UserBundle\Entity\BaseGroup as BaseGroup;
use Doctrine\ORM\Mapping as ORM;

/**
 * This file has been generated by the Sonata EasyExtends bundle ( http://sonata-project.org/easy-extends )
 *
 * References :
 *   working with object : http://www.doctrine-project.org/projects/orm/2.0/docs/reference/working-with-objects/en
 *
 * @ORM\Entity
 * @ORM\Table(name="group")
 */
class Group extends BaseGroup
{

    /**
     * @var integer $id
     *
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * Get id
     *
     * @return integer $id
     */
    public function getId()
    {
        return $this->id;
    }
}
<?php

namespace Application\Sonata\UserBundle\Entity;

use Sonata\UserBundle\Entity\BaseUser as BaseUser;
use Doctrine\ORM\Mapping as ORM;

/**
 * This file has been generated by the Sonata EasyExtends bundle ( http://sonata-project.org/easy-extends )
 *
 * References :
 *   working with object : http://www.doctrine-project.org/projects/orm/2.0/docs/reference/working-with-objects/en
 *
 * @ORM\Entity
 * @ORM\Table(name="dayo_user")
 */
class User extends BaseUser
{

    /**
     * @var integer $id
     *
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * Get id
     *
     * @return integer $id
     */
    public function getId()
    {
        return $this->id;
    }
}

In the config.yml file, in the doctrine section we have to add the support for json:

doctrine:
    dbal:
        //...
        types:
            json: Sonata\Doctrine\Types\JsonType

That being done, the database need to be created or updated. Depending on your need use one of the following command:

app/console doctrine:schema:create for the creation

app/console doctrine:schema:update --force for the update

After that, install the assets with app/console assets:install web

In order to use our admin dashboard we have to import the route in routing.yml:

fos_user_security:
    resource: "@FOSUserBundle/Resources/config/routing/security.xml"

fos_user_profile:
    resource: "@FOSUserBundle/Resources/config/routing/profile.xml"
    prefix: /profile

fos_user_register:
    resource: "@FOSUserBundle/Resources/config/routing/registration.xml"
    prefix: /register

fos_user_resetting:
    resource: "@FOSUserBundle/Resources/config/routing/resetting.xml"
    prefix: /resetting

fos_user_change_password:
    resource: "@FOSUserBundle/Resources/config/routing/change_password.xml"
    prefix: /change-password

soanata_user:
    resource: '@SonataUserBundle/Resources/config/routing/admin_security.xml'
    prefix: /admin

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

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

# error-prevention
homepage:
 pattern: /

Last step if we didn’t already have a user, we create one:

app/console fos:user:create admintest admin@test.com pass --super-admin

You just have to go to http://sonataadmin.fr.dev/admin/dashboard and log on with the user and you should see this dashboard:

In a next article we will see how to add new elements to the admin dashboard.

P.S. a GitHub repository is available : https://github.com/dayofr/sonataadmin.fr

39 thoughts on “Symfony2.1 + sonata-admin + sonata-user +fos-userbundle [EN]

  1. Symfony 2.1.8 not work,
    error:
    PHP Fatal error: Class ‘FOS\UserBundle\FOSUserBundle’ not found in
    Please help me.
    Thank you.

      1. i have the similar problem .
        it is :
        FatalErrorException: Error: Class ‘Sonata\AdminBundle\SonataAdminBundle’ not found in /var/www/Symfony_reg/app/AppKernel.php line 22

        i added
        new Sonata\AdminBundle\SonataAdminBundle(),
        in AppKernel.php
        need help !

  2. Thanks for the tutorial

    But I’m having problems I can’t install the easy-extends-bundle

    I have sf 2.1.9 and I put in the version constraint: dev-master, 2.1.9, 2.*, *

    And it shows me an error: http://i.imgur.com/WIS1rrR.png

    So I just created all as tutorial but without the easy-extends-bundle part

    When I enter to create a Group from the Dashboard, throws an Exception about a requeriment in the contructor so I just saw the extended Group.php file and voila! it requires one argument and the other argument is optional:

    public function __construct() {
    // How to get the roles from the security.yml?
    parent::__construct(null, $this->getRoles());
    }

    // to show the group name while is editing
    public function __toString() {
    return null === $this->getName() ?  » : $this->getName();
    }

    Now I can add new roles names but I dont know how to load the roles from security.yml:

    part of security.yml:

    role_hierarchy:
    ROLE_ADMIN: ROLE_USER
    ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

    I’m frustated with all this sh!t man, hours and hours trying to figure out how to hell works the roles and I’m just getting more and more f#ck!ng errors

    Thanks again.. sorry for the long message

  3. Hi there, I´m using XAMPP 1.8.1 over Windows 8, Sf 2.2.1 and I enable intl.dll but I´m still getting the error IntlDateFormatter::format(): datefmt_format: takes either an array or an integer timestamp value or a DateTime when I tried to add a user. Everything else works fine.
    I even tried with SonataIntlBundle, but nothing!!!

    This is my composer:

    {
    « name »: « symfony/framework-standard-edition »,
    « description »: « The \ »Symfony Standard Edition\ » distribution »,
    « autoload »: {
    « psr-0 »: { «  »: « src/ » }
    },
    « require »: {
    « php »: « >=5.3.3 »,
    « symfony/symfony »: « 2.1.10 »,
    « doctrine/orm »: « ~2.2,>=2.2.3 »,
    « doctrine/doctrine-bundle »: « 1.2.* »,
    « twig/extensions »: « 1.0.* »,
    « symfony/assetic-bundle »: « 2.1.* »,
    « symfony/swiftmailer-bundle »: « 2.2.* »,
    « symfony/monolog-bundle »: « 2.2.* »,
    « sensio/distribution-bundle »: « 2.2.* »,
    « sensio/framework-extra-bundle »: « 2.2.* »,
    « sensio/generator-bundle »: « 2.2.* »,
    « jms/security-extra-bundle »: « 1.4.* »,
    « jms/di-extra-bundle »: « 1.3.* »,

    « sonata-project/admin-bundle »: « 2.2.* »,
    « friendsofsymfony/user-bundle »: « 1.3.1 »,
    « sonata-project/user-bundle »: « 2.1.* »,
    « sonata-project/doctrine-orm-admin-bundle »: « 2.2.* »,
    « iphp/filestore-bundle »: »dev-master »,
    « vich/uploader-bundle »: « dev-master »,
    « knplabs/knp-gaufrette-bundle » : « 0.1.* »,
    « sonata-project/media-bundle »: « dev-master »,
    « sonata-project/notification-bundle »: « dev-master »,
    « sonata-project/intl-bundle »: « 2.1.* »,
    « genemu/form-bundle »: « 2.1.* »
    },
    « scripts »: {
    « post-install-cmd »: [
    « Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap »,
    « Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache »,
    « Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets »,
    « Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile »
    ],
    « post-update-cmd »: [
    « Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap »,
    « Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache »,
    « Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets »,
    « Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile »
    ]
    },
    « config »: {
    « bin-dir »: « bin »
    },
    « minimum-stability »: « alpha »,
    « extra »: {
    « symfony-app-dir »: « app »,
    « symfony-web-dir »: « web »,
    « branch-alias »: {
    « dev-master »: « 2.2-dev »
    }
    }
    }

    I´ll appreciate any ideas..

    1. Same here.. it says:

      Warning: IntlDateFormatter::format() [intldateformatter.format]: datefmt_format: takes either an array or an integer timestamp value or a DateTime object in C:\xampp\htdocs\symfony2\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\Core\Type\DateType.php line 260

  4. Hi,
    Maybe this is a silly question, but I’m trying to use Sonata and FOSUserBundle with a custom provider, I have my admin users in « myapp/backbundle/Entity/Administrador » everything works fine, I can access to my admin panel using http_basic login but when I want to logout my user and then I go back and access to http://www.mydomain/admin/ it seems like I never logged out. What I’m doing wrong Can somebody help me, please 🙂

    I changed

    fos_user:
    db_driver: orm
    firewall_name: main
    user_class: myapp/backbundle/Entity/Administrador

    firewell:
    admin
    pattern: /admin/*
    http_basic: ~
    logout:
    path: /admin/logout/
    target: portada

    It’s is necesary to have a sonata:easy-extends:generate SonataUserBundle?
    Can’t just have my backbundle bundle with my (custom-entity) provider?

  5. Hello guys,

    I followed your tutorial steps and I could login in dashboard but when I clicked Logout now I’m getting « Bad credentials » error everytime I try to login again.

    What is the problem?

    Thank you!

  6. I can’t understand what is « Using the smyfony console we now generate the configuration for the user admin thanks to the SonataEasyExtendsBundle: app/console sonata:easy-extends:generate SonataUserBundle The bundle is created into the app folder, move it to src. »?

    What is this console? where to find it?
    I am using symfony2.2 #newbie

    1. If your using Linux you have to open a new shell and go to the root location of you project.
      Under windows you have to do the same with the command line.
      Once at your root location you have to type: « app/console sonata:easy-extends:generate SonataUserBundle »
      It will launch some php code into the cosole to create a new bundle.

  7. I am getting error when i enter command app/console sonata:easy-extends:generate SonataUserBundle

    $ php app/console sonata:easy-extends:generate SonataUserBundle
    PHP Fatal error: Class ‘FOS\UserBundle\FOSUserBundle’ not found in C:\wamp\www\
    sonataadmin.fr\app\AppKernel.php on line 19
    PHP Stack trace:
    PHP 1. {main}() C:\wamp\www\sonataadmin.fr\app\console:0
    PHP 2. Symfony\Component\Console\Application->run() C:\wamp\www\sonataadmin.fr
    \app\console:27
    PHP 3. Symfony\Bundle\FrameworkBundle\Console\Application->doRun() C:\wamp\www
    \sonataadmin.fr\vendor\symfony\symfony\src\Symfony\Component\Console\Application
    .php:121
    PHP 4. Symfony\Bundle\FrameworkBundle\Console\Application->registerCommands()
    C:\wamp\www\sonataadmin.fr\vendor\symfony\symfony\src\Symfony\Bundle\FrameworkBu
    ndle\Console\Application.php:70
    PHP 5. Symfony\Component\HttpKernel\Kernel->boot() C:\wamp\www\sonataadmin.fr\
    vendor\symfony\symfony\src\Symfony\Bundle\FrameworkBundle\Console\Application.ph
    p:90
    PHP 6. Symfony\Component\HttpKernel\Kernel->initializeBundles() C:\wamp\www\so
    nataadmin.fr\app\bootstrap.php.cache:2145
    PHP 7. AppKernel->registerBundles() C:\wamp\www\sonataadmin.fr\app\bootstrap.p
    hp.cache:2315

  8. Hi,

    When I try to add new user via admin dashboard I’m getting this error after clicking « Save »:

    Invalid state, originalRoles array is not set
    500 Internal Server Error – RuntimeException

    in /Volumes/Work/AAA/aaa/vendor/sonata-project/user-bundle/Sonata/UserBundle/Form/Transformer/RestoreRolesTransformer.php at line 62 –

    public function reverseTransform($selectedRoles)
    {
    if ($this->originalRoles === null) {
    throw new \RuntimeException(‘Invalid state, originalRoles array is not set’);
    }
    list($availableRoles, ) = $this->rolesBuilder->getRoles();

    Any ideas how to fix it?

    Thanks,
    maczkus

  9. hi guys i just wonder why when i try to execute this command « app/console sonata:easy-extends:generate SonataUserBundle » with different name of the bundle like that  » app/console sonata:easy-extends:generate AcmeUserBundle » it won’t be generated unless u put as it is can u explain to me please why is that and i f possible how could i change it

Laisser un commentaire