6. Creating a Custom Admin Action
6. Creating a Custom Admin Action¶
This is a full working example of creating a custom list action for SonataAdmin.
The example is based on an existing CarAdmin
class in an AcmeDemoBundle
. It is
assumed you already have an admin service up and running.
6.1. The recipe¶
SonataAdmin provides a very straight-forward way of adding your own custom actions.
To do this we need to:
- extend the
SonataAdmin:CRUD
Controller and tell our admin class to use it - create the custom action in our Controller
- create a template to show the action in the list view
- add the route and the new action in the Admin class
6.1.1. Extending the Admin Controller¶
First you need to create your own Controller extending the one from SonataAdmin
1 2 3 4 5 6 7 8 9 10 11 | <?php
// src/Acme/DemoBundle/Controller/CRUDController.php
namespace Acme\DemoBundle\Controller;
use Sonata\AdminBundle\Controller\CRUDController as Controller;
class CRUDController extends Controller
{
// ...
}
|
Admin classes by default use the SonataAdmin:CRUD
controller, this is the third parameter
of an admin service definition, you need to change it to your own.
Either by using XML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <!-- src/Acme/DemoBundle/Resources/config/admin.xml -->
...
<service id="acme.demo.admin.car" class="Acme\DemoBundle\Admin\CarAdmin">
<tag name="sonata.admin" manager_type="orm" group="Demo" label="Car" />
<argument />
<argument>Acme\DemoBundle\Entity\Car</argument>
<argument>AcmeDemoBundle:CRUD</argument>
...
</service>
...
|
Or by overwriting the configuration in your config.yml
:
1 2 3 4 5 6 7 8 9 10 11 | # app/config/config.yml
services:
acme.demo.admin.car:
class: Acme\DemoBundle\Admin\CarAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: Demo, label: Car }
arguments:
- null
- Acme\DemoBundle\Entity\Car
- AcmeDemoBundle:CRUD
|
For more information about service configuration please refer to Step 3 of Getting started with SonataAdminBundle
6.1.2. Create the custom action in your Controller¶
Now it is time to actually create your custom action here, for this example I chose
to implement a clone
action.
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 | <?php // src/Acme/DemoBundle/Controller/CRUDController.php
namespace Acme\DemoBundle\Controller;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Sonata\AdminBundle\Controller\CRUDController as Controller;
use Symfony\Component\HttpFoundation\RedirectResponse;
class CRUDController extends Controller
{
public function cloneAction()
{
$object = $this->admin->getSubject();
if (!$object) {
throw new NotFoundHttpException(sprintf('unable to find the object with id : %s', $id));
}
$clonedObject = clone $object; // Careful, you may need to overload the __clone method of your object
// to set its id to null
$clonedObject->setName($object->getName()." (Clone)");
$this->admin->create($clonedObject);
$this->addFlash('sonata_flash_success', 'Cloned successfully');
return new RedirectResponse($this->admin->generateUrl('list'));
}
}
|
Here we first get the id of the object, see if it exists then clone it and insert the clone as a new object. Finally we set a flash message indicating success and redirect to the list view.
6.1.3. Create a template for the new action¶
You need to tell SonataAdmin how to render your new action. You do that by
creating a list__action_clone.html.twig
in the namespace of your custom
Admin Controller.
1 2 3 | {# src/Acme/DemoBundle/Resources/views/CRUD/list__action_clone.html.twig #}
<a class="btn btn-sm" href="{{ admin.generateObjectUrl('clone', object) }}">clone</a>
|
Right now clone
is not a known route, we define it in the next step.
6.1.4. Bringing it all together¶
What is left now is actually adding your custom action to the admin class.
You have to add the new route in configureRoutes
:
1 2 3 4 | protected function configureRoutes(RouteCollection $collection)
{
$collection->add('clone', $this->getRouterIdParameter().'/clone');
}
|
This gives us a route like ../admin/sonata/demo/car/1/clone
.
You could also just write $collection->add('clone');
to get a route like ../admin/sonata/demo/car/clone?id=1
Next we have to add the action in configureListFields
specifying the template we created.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | protected function configureListFields(ListMapper $listMapper)
{
$listMapper
// other fields...
->add('_action', 'actions', array(
'actions' => array(
'Clone' => array(
'template' => 'AcmeDemoBundle:CRUD:list__action_clone.html.twig'
)
)
))
;
}
|
The full CarAdmin.php
example looks like this:
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 | <?php
// src/Acme/DemoBundle/Admin/CarAdmin.php
namespace Acme\DemoBundle\Admin;
// ...
use Sonata\AdminBundle\Route\RouteCollection;
class CarAdmin extends Admin
{
// ...
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('name')
->add('engine')
->add('rescueEngine')
->add('createdAt')
->add('_action', 'actions', array(
'actions' => array(
'Clone' => array(
'template' => 'AcmeDemoBundle:CRUD:list__action_clone.html.twig'
)
)
));
}
protected function configureRoutes(RouteCollection $collection)
{
$collection->add('clone', $this->getRouterIdParameter().'/clone');
}
}
|
This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.