Weblog of Alif

Exploring the Web: An Apple a day

Symfony2 - Sonata Admin Bundle Install and Boilerplate

August 7, 2012 -- alif

In this article, I will explain the steps on how to have an Admin Panel in Symfony2 very easily. Despite having several tutorials on the web, I still found that I had to do a lot of work to make it error-free.

Note: We created a boilerplate of Symfony2 with Admin Panel at Github. I recommend to download the Symfony bundled with Sonata Admin Panel Boilerplate and follow the instructions there. You will have Symfony2 with Admin Panel up and running in no time!

Alternatively, If you wish to do manually, follow the steps described below. For windows users, you will need Git Bash Clientto follow instructions below.

Step #1: Copy/Add the following lines in your /deps file. Make sure, you keep the version in it.


[TwigGenerator]
    git=git://github.com/cedriclombardot/TwigGenerator.git
    target=/twig-generator

[PagerFanta]
    git=git://github.com/whiteoctober/Pagerfanta.git
    target=/pagerfanta

[WhiteOctoberPagerfantaBundle]
    git=git://github.com/whiteoctober/WhiteOctoberPagerfantaBundle.git
    target=/bundles/WhiteOctober/PagerfantaBundle
    version=origin/symfony2.0

[doctrine-fixtures]
    git=git://github.com/doctrine/data-fixtures.git
    target=/doctrine-fixtures

[DoctrineFixturesBundle]
    git=git://github.com/doctrine/DoctrineFixturesBundle.git
    target=/bundles/Doctrine/Bundle/FixturesBundle

[DoctrineBundle]
    git=git://github.com/doctrine/DoctrineBundle.git
    target=/bundles/Doctrine/Bundle/DoctrineBundle

  
[SonataAdminBundle]
    git=http://github.com/sonata-project/SonataAdminBundle.git
    target=/bundles/Sonata/AdminBundle
    version=origin/2.0
 
[SonataBlockBundle]
    git=http://github.com/sonata-project/SonataBlockBundle.git
    target=/bundles/Sonata/BlockBundle
    version=origin/2.0
    
[SonataCacheBundle]
    git=http://github.com/sonata-project/SonataCacheBundle.git
    target=/bundles/Sonata/CacheBundle
    version=origin/2.0
 
[SonatajQueryBundle]
    git=http://github.com/sonata-project/SonatajQueryBundle.git
    target=/bundles/Sonata/jQueryBundle
 
[SonataUserBundle]
    git=git://github.com/sonata-project/SonataUserBundle.git
    target=/bundles/Sonata/UserBundle
    version=origin/2.0
 
[SonataEasyExtendsBundle]
    git=git://github.com/sonata-project/SonataEasyExtendsBundle.git
    target=/bundles/Sonata/EasyExtendsBundle
 
[SonataDoctrineORMAdminBundle]
    git=http://github.com/sonata-project/SonataDoctrineORMAdminBundle.git
    target=/bundles/Sonata/DoctrineORMAdminBundle
    version=origin/2.0
 
[KnpMenuBundle]
    git=http://github.com/KnpLabs/KnpMenuBundle.git
    target=/bundles/Knp/Bundle/MenuBundle
    version=v1.0.0   
 
[KnpMenu]
    git=http://github.com/KnpLabs/KnpMenu.git
    target=/knp/menu
    version=v1.0.0
 
[Exporter]
    git=http://github.com/sonata-project/exporter.git
    target=/exporter

[SonataDoctrineExtensions]
    git=git://github.com/sonata-project/sonata-doctrine-extensions.git
    target=/sonata-doctrine-extensions
 
[FOSUserBundle]
    git=git://github.com/FriendsOfSymfony/FOSUserBundle.git
    target=bundles/FOS/UserBundle
    version=origin/1.2.x
   
[EntityAudit]
    git=git://github.com/simplethings/EntityAudit.git
    target=/bundles/SimpleThings/EntityAudit

Step #2: Now, to install the bundles, run the following command:

php bin/vendors install 

Step #3 (optional): If you do not have a database configured yet, open app/config/parameters.ini and update the database Information. Ensure that the database_user has permission to create database, otherwise, you may want to manually the database separately

Step #4: Add the following lines in your app/autoload.php

$loader->registerNamespaces(array(
//...    
'FOS'            => __DIR__.'/../vendor/bundles',
'Sonata'       => array(__DIR__.'/../vendor/bundles',
    						    __DIR__.'/../vendor/sonata-doctrine-extensions/src'),
'Knp'            => array(__DIR__.'/../vendor/bundles',
                                                __DIR__.'/../vendor/knp/menu/src'),
'Exporter'     => __DIR__.'/../vendor/exporter/lib',
'SimpleThings'  => __DIR__.'/../vendor/bundles/SimpleThings/EntityAudit/src',
	
'WhiteOctober\PagerfantaBundle' => __DIR__.'/../vendor/bundles',
'Pagerfanta'     => __DIR__.'/../vendor/pagerfanta/src',
//..

));

Step #5: Now, add the following lines in app/appKernel.php



$bundles = array(
//..
	new FOS\UserBundle\FOSUserBundle(),
	new Sonata\jQueryBundle\SonatajQueryBundle(),
	new Sonata\AdminBundle\SonataAdminBundle(),
	new Sonata\BlockBundle\SonataBlockBundle(),
	new Sonata\CacheBundle\SonataCacheBundle(),
	new Sonata\DoctrineORMAdminBundle\SonataDoctrineORMAdminBundle(),
	new Knp\Bundle\MenuBundle\KnpMenuBundle(),
	new Sonata\UserBundle\SonataUserBundle('FOSUserBundle'),
	new Sonata\EasyExtendsBundle\SonataEasyExtendsBundle(),
	new SimpleThings\EntityAudit\SimpleThingsEntityAuditBundle(),
	new WhiteOctober\PagerfantaBundle\WhiteOctoberPagerfantaBundle(),
//..
);

Step #6: Now, translator needs to be added. So, uncomment the following lines in app/config/config.yml

translator:      { fallback: %locale% }

#Or you can add the following as well

translator:      { fallback: en }

Step #7: Add the following lines in your app/config/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

Step #8: Add the following lines in your app/config/security.yml

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 }

Step #9: Now, generate a new module using the following cmd from Git Bash/Terminal:


php app/console sonata:easy-extends:generate SonataUserBundle

Step #10: Add the new module in your app/appKernel.php


$bundles = array(
//..
	new Application\Sonata\UserBundle\ApplicationSonataUserBundle(),
//..
);

Step #11: Also add it to your namespace in app/autoload.php

$loader->registerNamespaces(array(
//..
    'Application'      => __DIR__,
//..
));

Step #12: Update the User in app/Application/Sonata/UserBundle/Entity/User.php. Basically, add the ORM annotations. Below is the entire class:


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="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;
    }
	
}

Step #12: Update the Group in app/Application/Sonata/UserBundle/Entity/Group.php. Basically, add the ORM annotations. Below is the entire class:


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;
    }
	

}

Step #13: Add the following line in your app/config/config.yml. Basically, this adds a JSON Type to doctrine

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

Step #14: Run the following command to create the database tables

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

Step #15: Install the assets for AdminBundle (js/css etc.) by issuing the following command:

php app/console assets:install web

Step #16: Add the following lines in your route app/config/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: /

Step #17: Create a super-admin user to manage the admin panel and you are ready to go!

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

Now, you should be able to login to your Admin Panel at:

http://localhost/symfony/web/app_dev.php/admin/dashboard

Alternatively, you could download our Boilerplate from Github and have it ready to go

Download from Github

Comments

Submitted by AngyGlamy (not verified) on

Man i guess there is an error in the HTML somewhere? I can't load the site properly !

Submitted by likeitlikeit (not verified) on

I found a typo:

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

Can I keep it? :)

Submitted by alif on

Yes, you can keep it. It shouldn't cause any problem. Thanks for catching the typo :-).

Submitted by Willy (not verified) on

Great job on the script. It worked like a charm. Thanks for saving hours of headache.

Submitted by PHP Prog (not verified) on

Thank You. Any plans for releasing boiler plate for Symfony version 2.1?

Submitted by alif on

You are welcome. Symfony 2.1 is in RC currently. Once a final version is released, we will most likely make a 2.1 version as well :).

You could follow us on Github to stay updated.

Add new comment