Integrate FOSUserBundle and SonataUserBundle Easily

SonataUserBundle is a great extension of SonataAdminBundle that provides user administration features by integrating FOSUserBundle user provider/management bundle. Its default installation procedure recommends to setup SonataUserBundle as child bundle of FOSUserBundle and generate ApplicationSonataUserBundle via sonata:easy-extends:generate command. But on some cases you may not want to setup that way. For example you have setup your user entity by following the documentation of FOSUserBundle before integrating SonataAdminBundle and SonataUserBundle, you may want to override both bundles separately. In following section I will outline how to integrate SonataUserBundle with FOSUserBundle without creating child bundle of FOSUserBundle.

Default installation and setup of FOSUserBundle is same as stated in default documentation. Then install and setup SonataAdminBundle according to its documentation. Both guides are pretty well documented. So I will not duplicate them here.

Now setup SonataUserBundle. Add it to composer.json and add following line into registerBundle method of app/AppKernel.php

app/AppKernel.php
1
2
3
4
5
6
7
8
9
// app/AppKernel.php
public function registerBundles()
{

    $bundles = array(
        // other bundle declarations
        new Sonata\UserBundle\SonataUserBundle(),
    );
}

Then setup configuration, add routing and security configuration according to the documentation.

Now set value of sonata.user.admin.user.class parameter to the FQCN of the User entity which was created during FOSUserBundle setup. For example if FQCN of your user entity is YourVendor\YourBundle\Entity\User then parameter setting of app/config.yml would be

app/config/config.yml
1
2
3
parameters:
    #....
    sonata.user.admin.user.entity: YourVendor\YourBundle\Entity\User

Now create a class that extends default UserAdmin class and override configureShowFields, configureFormFields, configureDatagridFilters and configureListFields methods to add the needed user admin fields. Following is the sample extended UserAdmin class which is based on the bare bone user entity created in FOSUserBundle documentation.

src/YourVendor/YourBundle/Admin/UserAdmin.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<?php
//src/YourVendor/YourBundle/Admin/UserAdmin.php

namespace YourVendor\YourBundle\Admin;

use Sonata\UserBundle\Admin\Model\UserAdmin as BaseUserAdmin;

use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Show\ShowMapper;

use FOS\UserBundle\Model\UserManagerInterface;
use Sonata\AdminBundle\Route\RouteCollection;


class UserAdmin extends BaseUserAdmin
{
    /**
     * {@inheritdoc}
     */
    protected function configureShowFields(ShowMapper $showMapper)
    {
        $showMapper
            ->with('General')
                ->add('username')
                ->add('email')
            ->end()
            // .. more info
        ;
    }

    /**
     * {@inheritdoc}
     */
    protected function configureFormFields(FormMapper $formMapper)
    {

        $formMapper
            ->with('General')
                ->add('username')
                ->add('email')
                ->add('plainPassword', 'text', array('required' => false))
            ->end()
            // .. more info
            ;

        if (!$this->getSubject()->hasRole('ROLE_SUPER_ADMIN')) {
            $formMapper
                ->with('Management')
                    ->add('roles', 'sonata_security_roles', array(
                        'expanded' => true,
                        'multiple' => true,
                        'required' => false
                    ))
                    ->add('locked', null, array('required' => false))
                    ->add('expired', null, array('required' => false))
                    ->add('enabled', null, array('required' => false))
                    ->add('credentialsExpired', null, array('required' => false))
                ->end()
            ;
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function configureDatagridFilters(DatagridMapper $filterMapper)
    {
        $filterMapper
            ->add('id')
            ->add('username')
            ->add('locked')
            ->add('email')
        ;
    }
    /**
     * {@inheritdoc}
     */
    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
            ->addIdentifier('username')
            ->add('email')
            ->add('enabled', null, array('editable' => true))
            ->add('locked', null, array('editable' => true))
            ->add('createdAt')
        ;

        if ($this->isGranted('ROLE_ALLOWED_TO_SWITCH')) {
            $listMapper
                ->add('impersonating', 'string', array('template' => 'SonataUserBundle:Admin:Field/impersonating.html.twig'))
            ;
        }
    }
}

Now set the value of sonata.user.admin.user.class to the FQCN of the created UserAdmin class in app/config/config.yml, e.g

app/config/config.yml
1
2
3
4
5
6
7
#app/config/config.yml

parameters:
    # ...
    sonata.user.admin.user.class: YourVendor\YourBundle\Admin\UserAdmin

# ....

If you don’t need user group functionality you can disable it. e.g in your app/config/config.yml add following lines.

app/config/config.yml
1
2
3
4
5
6
#app/config/config.yml

services:
    sonata.user.admin.group:
        abstract: true
        public: false

Combined config.yml setting given bellow,

app/config/config.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
#app/config/config.yml

#...

parameters:
    sonata.user.admin.user.class: YourVendor\YourBundle\Admin\UserAdmin
    sonata.user.admin.user.entity: YourVendor\YourBundle\Entity\User

services:
    sonata.user.admin.group:
        abstract: true
        public: false
#...

If everything setup correctly you will see an new users row in admin/dashboard page. All user operations should work as expected. Thats all for now.

Comments