Cover of the book Symfony 5: The Fast Track

Symfony 5: The Fast Track is the best book to learn modern Symfony development, from zero to production. +300 pages showcasing Symfony with Docker, APIs, queues & async tasks, Webpack, SPAs, etc.

WARNING: You are browsing the documentation for version 2.x which is not maintained anymore. If some of your projects are still using this version, consider upgrading.

26. Advanced configuration

2.x version
Unmaintained
2.x

26. Advanced configuration

26.1. Service Configuration

When you create a new Admin service you can configure its dependencies, the services which are injected by default are:

Dependencies Service Id
model_manager sonata.admin.manager.%manager-type%
form_contractor sonata.admin.builder.%manager-type%_form
show_builder sonata.admin.builder.%manager-type%_show
list_builder sonata.admin.builder.%manager-type%_list
datagrid_builder sonata.admin.builder.%manager-type%_datagrid
translator translator
configuration_pool sonata.admin.pool
router router
validator validator
security_handler sonata.admin.security.handler
menu_factory knp_menu.factory
route_builder sonata.admin.route.path_info | sonata.admin.route.path_info_slashes
label_translator_strategy sonata.admin.label.strategy.form_component

Note: %manager-type% is to be replaced by the manager type (orm, doctrine_mongodb…), and the default route_builder depends on it.

You have 2 ways of defining the dependencies inside services.xml:

  • With a tag attribute, less verbose:
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    <service id="acme.project.admin.project" class="Acme\ProjectBundle\Admin\ProjectAdmin">
        <tag
            name="sonata.admin"
            manager_type="orm"
            group="Project"
            label="Project"
            label_translator_strategy="sonata.admin.label.strategy.native"
            route_builder="sonata.admin.route.path_info"
            />
        <argument />
        <argument>Acme\ProjectBundle\Entity\Project</argument>
        <argument />
    </service>
    
  • YAML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    acme.project.admin.project:
        class: Acme\ProjectBundle\Admin\ProjectAdmin
        tags:
            - name: sonata.admin
              manager_type: orm
              group: "Project"
              label: "Project"
              label_translator_strategy: "sonata.admin.label.strategy.native"
              route_builder: "sonata.admin.route.path_info"
        arguments:
            - ~
            - Acme\ProjectBundle\Entity\Project
            - ~
    
  • With a method call, more verbose
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <service id="acme.project.admin.project" class="Acme\ProjectBundle\Admin\ProjectAdmin">
        <tag
            name="sonata.admin"
            manager_type="orm"
            group="Project"
            label="Project"
            />
        <argument />
        <argument>Acme\ProjectBundle\Entity\Project</argument>
        <argument />
    
        <call method="setLabelTranslatorStrategy">
            <argument type="service" id="sonata.admin.label.strategy.native" />
        </call>
    
        <call method="setRouteBuilder">
            <argument type="service" id="sonata.admin.route.path_info" />
        </call>
    </service>
    
  • YAML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    acme.project.admin.project:
        class: Acme\ProjectBundle\Admin\ProjectAdmin
        tags:
            - { name: sonata.admin, manager_type: orm, group: "Project", label: "Project" }
        arguments:
            - ~
            - Acme\ProjectBundle\Entity\Project
            - ~
        calls:
            - [ setLabelTranslatorStrategy, [ "@sonata.admin.label.strategy.native" ]]
            - [ setRouteBuilder, [ "@sonata.admin.route.path_info" ]]
    

If you want to modify the service that is going to be injected, add the following code to your application’s config file:

  • YAML
    1
    2
    3
    4
    5
    6
    # app/config/config.yml
    admins:
        sonata_admin:
            sonata.order.admin.order:   # id of the admin service this setting is for
                model_manager:          # dependency name, from the table above
                    sonata.order.admin.order.manager  # customised service id
    

26.1.1. Creating a custom RouteBuilder

To create your own RouteBuilder create the PHP class and register it as a service:

  • php Route Generator
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
namespace Acme\AdminBundle\Route;

use Sonata\AdminBundle\Builder\RouteBuilderInterface;
use Sonata\AdminBundle\Admin\AdminInterface;
use Sonata\AdminBundle\Route\PathInfoBuilder;
use Sonata\AdminBundle\Route\RouteCollection;

class EntityRouterBuilder extends PathInfoBuilder implements RouteBuilderInterface
{
    /**
     * @param \Sonata\AdminBundle\Admin\AdminInterface $admin
     * @param \Sonata\AdminBundle\Route\RouteCollection $collection
     */
    public function build(AdminInterface $admin, RouteCollection $collection)
    {
        parent::build($admin,$collection);
        $collection->add('yourSubAction');
        // Create button will disappear, delete functionality will be disabled as well
        // No more changes needed!
        $collection->remove('create');
        $collection->remove('delete');
    }
}
  • xml service registration
  • XML
    1
    2
    3
    <service id="acme.admin.route.entity" class="Acme\AdminBundle\Route\EntityRouterBuilder">
        <argument type="service" id="sonata.admin.audit.manager" />
    </service>
    
  • YAML service registration
  • YAML
    1
    2
    3
    4
    5
    6
    7
    8
    parameters:
        acme.admin.entity_route_builder.class: Acme\AdminBundle\Route\EntityRouterBuilder
    
    services:
        acme.admin.entity_route_builder:
            class: "%acme.admin.entity_route_builder.class%"
            arguments:
                - "@sonata.admin.audit.manager"
    

26.2. Inherited classes

You can manage inherited classes by injecting subclasses using the service configuration.

Lets consider a base class named Person and its subclasses Student and Teacher:

  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    <services>
        <service id="sonata.admin.person" class="YourNS\AdminBundle\Admin\PersonAdmin">
            <tag name="sonata.admin" manager_type="orm" group="admin" label="Person"/>
            <argument/>
            <argument>YourNS\AdminBundle\Entity\Person</argument>
            <argument></argument>
            <call method="setSubClasses">
                <argument type="collection">
                    <argument key="student">YourNS\AdminBundle\Entity\Student</argument>
                    <argument key="teacher">YourNS\AdminBundle\Entity\Teacher</argument>
                </argument>
            </call>
        </service>
    </services>
    

You will just need to change the way forms are configured in order to take into account these new subclasses:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<?php
// YourNS\AdminBundle\Admin\PersonAdmin.php

protected function configureFormFields(FormMapper $form)
{
    $subject = $this->getSubject();

    $form->add('name');

    if ($subject instanceof Teacher) {
        $form->add('course', 'text');
    }
    elseif ($subject instanceof Student) {
        $form->add('year', 'integer');
    }
}

26.4. Disable content stretching

You can disable html, body and sidebar elements stretching. These containers are forced to be full height by default. If you use custom layout or just don’t need such behavior, add no-stretch class to <html> tag.

For example:

1
2
{# YourNS\AdminBundle\Resources\views\standard_layout.html.twig #}
{% block html_attributes %}class="no-js no-stretch"{% endblock %}

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.