Symfony 2 – Installing Sonata and FOS Bundles

Symfofny Web Development
Hello friends of Symfony 2,
In this lesson we will show you how to install Sonata Bundle & FOS User Bundle (FOS – Friends of Symfony). These new modules will help us to make better web development and optimized programming for our web sites. With this lesson and the previous one we created we will have one small complete application if you did follow our previous tutorials “Installation and Configuration of Symofny 2” and
Generating Bundle, Entity and CRUD Module“.
Symfony 2 does not have Admin Generator like Symfony 1, but we have Sonata Bundle – this bundle is like Admin Generator for Symfony 2. Sonata Bundle is a project created by Thomas Rabaix (Symfony enthusiast) and sponsored by Ekino (Software Company in France). FOS User Bundle is a project for managing users. There are basic features like registration, login, forgotten password, high security, groups of users etc. We can use this module for the visible part of the application (frontend) to protect a certain content and make it visible only for certain users and we can also use it for the admin part of the application (backend) accessible only for the administrators. Both modules are easy to use and install.
In the previous lessons we installed and configured Symfony 2, created bundle, entity & CRUD Module. Now we will continue with the installation of Sonata & FOS User Bundle and we will create the admin part of our application.

1 ) We have to add this code in Symfony/deps

[SonataAdminBundle]
    git=http://github.com/sonata-project/SonataAdminBundle.git
    target=/bundles/Sonata/AdminBundle

[SonataBlockBundle]
    git=http://github.com/sonata-project/SonataBlockBundle.git
    target=/bundles/Sonata/BlockBundle

[SonataCacheBundle]
    git=http://github.com/sonata-project/SonataCacheBundle.git
    target=/bundles/Sonata/CacheBundle

[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
 
[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

[KnpMenuBundle]
    git=http://github.com/KnpLabs/KnpMenuBundle.git
    target=/bundles/Knp/Bundle/MenuBundle

[KnpMenu]
    git=http://github.com/KnpLabs/KnpMenu.git
    target=/knp/menu

[Exporter]
    git=http://github.com/sonata-project/exporter.git
    target=/exporter

[FOSUserBundle]
    git=git://github.com/FriendsOfSymfony/FOSUserBundle.git
    target=bundles/FOS/UserBundle

2 ) In the next step in GIT Bash (http://git-scm.com/downloads) we have to write this command:

cd /c/xampp/htdocs/symfony

and we enter in the project
Symfony and FOS Bundle - web development

php bin/vendors install

Symfony - web site programming
3 ) We have to add the following code in the file Symfony/app/autoload.php

$loader->registerNamespaces(array(
	//…    
    'FOS'              => __DIR__.'/../vendor/bundles',
    'Sonata'           => __DIR__.'/../vendor/bundles',
    'Application'      => __DIR__,
    'Knp'              => array(
                          __DIR__.'/../vendor/bundles',
                          __DIR__.'/../vendor/knp/menu/src',
                          ),
    'Exporter'         => __DIR__.'/../vendor/exporter/lib',

));

4 ) We have to add the following code in the file Symfony/app/AppKernel.php

$bundles = array(            
 	//…
            new FOSUserBundleFOSUserBundle(),
            new SonatajQueryBundleSonatajQueryBundle(),
            new SonataAdminBundleSonataAdminBundle(),
            new SonataBlockBundleSonataBlockBundle(),
            new SonataCacheBundleSonataCacheBundle(),
            new SonataDoctrineORMAdminBundleSonataDoctrineORMAdminBundle(),
            new KnpBundleMenuBundleKnpMenuBundle(),
            new SonataUserBundleSonataUserBundle('FOSUserBundle'),
            new SonataEasyExtendsBundleSonataEasyExtendsBundle(),
   );

5 ) We have to add the following code in the file app/config/config.yml

fos_user:
    db_driver: orm
    firewall_name: main
    user_class: ApplicationSonataUserBundleEntityUser
    
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:

6 ) In entity Product we have to add the following code to be used by Sonata Bundle:
src/Mol/StoreBundle/Entity/Product

public function __toString()
{
  return $this->getName();
}

7 ) In the file app/config/config.yml we have to uncomment

translator: { fallback: %locale% }

and change to

translator: { fallback: en }

Then we add the configuration for Sonata:

sonata_admin:
    title:      Sonata Project
    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 }
        groups:
            store:
                label: Products

8 ) We have to add the following code in the file src/Mol/StoreBundle/Resources/config/services.yml:

services:
    mol.store.admin.product:
        class: MolStoreBundleAdminProductAdmin
        tags:
            - { name: sonata.admin, manager_type: orm, group: Store, label: product }
        arguments: [null, MolStoreBundleEntityProduct, SonataAdminBundle:CRUD]

9 ) We have to add the following code in the file 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
 
admin:
    resource: '@SonataAdminBundle/Resources/config/routing/sonata_admin.xml'
    prefix: /admin
 
_sonata_admin:
    resource: .
    type: sonata_admin
    prefix: /admin
 
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

10 ) Then we have to create the folder “Admin” in src/Mol/StoreBundle/ Inside the folder we have to create this class ProductAdmin.php and add the following code:

namespace MolStoreBundleAdmin;

use SonataAdminBundleAdminAdmin;
use SonataAdminBundleDatagridListMapper;
use SonataAdminBundleDatagridDatagridMapper;
use SonataAdminBundleValidatorErrorElement;
use SonataAdminBundleFormFormMapper;

class ProductAdmin extends Admin
{
  protected function configureFormFields(FormMapper $formMapper)
  {
    $formMapper
      ->add('name')
      ->add('price')
      ->add('description', null, array('required' => false))
    ;
  }

  protected function configureDatagridFilters(DatagridMapper $datagridMapper)
  {
    $datagridMapper
      ->add('name')
      ->add('price')
    ;
  }

  protected function configureListFields(ListMapper $listMapper)
  {
    $listMapper
      ->addIdentifier('name')
      ->add('price')
    ;
  }

  public function validate(ErrorElement $errorElement, $object)
  {
    $errorElement
      ->with('name')
      ->assertMaxLength(array('limit' => 32))
      ->end()
    ;
  }
}

11 ) We have to create a new module with the following command in GIT Bash:

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

FOS and Sonata web developemnt
With that the module is done and you can find it in app/Application/Sonata/UserBundle
Do not forget to add in app/appKernel.php this piece of code:

new ApplicationSonataUserBundleApplicationSonataUserBundle()

12 ) We have to do a lot of configuration in app/config/security.yml

security:
    encoders:
        FOSUserBundleModelUserInterface: 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 }
# ...

We give the whole code you need to have in this file.

13 ) We have to do some changes in the new module we have generated if we want to work with it (?). Go in app/Application/Sonata/UserBundle/Entity/User.php and the code should be the following:

namespace ApplicationSonataUserBundleEntity;

use FOSUserBundleEntityUser as BaseUser;
use DoctrineORMMapping as ORM;

/**
 * @ORMEntity
 * @ORMTable(name="user")
 */
class User extends BaseUser
{
    /**
     * @ORMId
     * @ORMColumn(type="integer")
     * @ORMGeneratedValue(strategy="AUTO")
     */
    protected $id;

    public function __construct()
    {
        parent::__construct();
        // your own logic
    }
}

And in the other file app/Application/Sonata/UserBundle/Entity/Group.php

namespace ApplicationSonataUserBundleEntity;

use FOSUserBundleEntityGroup as BaseGroup;
use DoctrineORMMapping as ORM;

/**
 * @ORMEntity
 * @ORMTable(name="group")
 */
class Group extends BaseGroup
{
    /**
     * @ORMId
     * @ORMColumn(type="integer")
     * @ORMGeneratedValue(strategy="AUTO")
     */
    protected $id;

    public function __construct()
    {
        parent::__construct();
        // your own logic
    }
}

14 ) After these changes in GIT Bash we have to type this command:

php app/console doctrine:schema:update –dump-sql

then
Sonata web programming

php app/console doctrine:schema:update –force

and then
Sonata Bundle web development

php app/console assets:install web

FOS Bundle programming
15 ) We have to add the translator in the directory:app/Application/Sonata/userBundle/Resources/translations/SonataUserBundle.en.yml with the following content:

form:
  label_username:                  Username
  label_email:                           Email
  label_plain_password:        Password (Plain)
  label_groups:                         Groups
  label_roles:                             Roles
  label_locked:                          Locked
  label_expired:                         Expired
  label_enabled:                       Enabled
  label_credentials_expired:  Credentials Expired
  label_name:                            Name
 
list:
  label_username:                   Username
  label_email:                           Email
  label_enabled:                       Enabled
  label_locked:                          Locked
  label_created_at:                  Created At
  label_roles:                            Roles
  label_name:                           Name
 
filter:
  label_username:             Username
  label_locked:                    Locked
  label_email:                      Email
  label_id:                             ID
  label_name:                     Name

16 ) Now we have to create users. That can be done with the following command in GIT Bash:

php app/console fos:user:create admin [email protected] password --super-admin

Symfony - develoment of web sites
With this command we create an administrator account, the following command is for users:

php app/console fos:user:create testuser [email protected] password

Symfony - programming of web sites

If we go to:
http://localhost/Symfony/web/app_dev.php/admin/dashboard
we will be redirected to
http://localhost/Symfony/web/app_dev.php/admin/login
We have to insert “admin/password” and we will enter the module where we will see the Products for managing.
That’s all, we have Sonata Bundle and we can manage the modules we create in the visible part of the application (frontend). Of course FOS User Bundle can be used for the frontend where we can create accounts and have a registration page. FOS User Bundle is very well developed and gives us excellent features. We are especially very pleased with and very grateful to Knp university for this development and addition to Symfony 2 Framework.
This will definitely help us in our web development for better web sties and optimized programming.

Leave a Reply

Your email address will not be published. Required fields are marked *