diff --git a/Resources/doc/reference/recipe_custom_action.rst b/Resources/doc/reference/recipe_custom_action.rst new file mode 100644 index 0000000000..8b5aa7af63 --- /dev/null +++ b/Resources/doc/reference/recipe_custom_action.rst @@ -0,0 +1,226 @@ +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`` in an ``AcmeDemoBundle``. It is +assumed you already have and admin service up and running. + +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 list view +- add the route and the new action in the Admin class + +Extending the Admin Controller +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +First we need to create or own Controller extending the one from SonataAdmin + + +.. code-block:: php + + + ... + + + + + + + Acme\DemoBundle\Entity\Car + AcmeDemoBundle:CRUD + + ... + +Or by overwriting the configuration in your ``config.yml`` + + +.. code-block:: yaml + + # 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 + +TODO: link + + +Create the custom action in our Controller +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Now it's time to actually create your custom action here, for this example i chose +to implement a ``clone`` action. + +.. code-block:: php + + get('request')->get($this->admin->getIdParameter()); + + $object = $this->admin->getObject($id); + + if (!$object) { + throw new NotFoundHttpException(sprintf('unable to find the object with id : %s', $id)); + } + + $clonedObject = clone $object; + $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 new object. Finally we set a flash message indicating success and redirect to the list view. + +TODO: talk about other options or just refer to https://github.com/sonata-project/SonataAdminBundle/blob/master/Controller/CRUDController.php for reference? + +Create a template for the new action +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +We need to tell SonataAdmin how to render our new action we do that by creating a ``list__action_clone.html.twig`` in the +namespace of our custom Admin Controller. + + +.. code-block:: twig + + {# src/Acme/DemoBundle/Resources/views/CRUD/list__action_clone.html.twig #} + + clone + +Right now ``clone`` is not a known route, we define it in the next step. + + +Bringing it all together +^^^^^^^^^^^^^^^^^^^^^^^ + + +What's left now is actually adding our custom action to the admin class + +We have to add the new route in ``configureRoutes`` + +.. code-block:: php + + protected function configureRoutes(RouteCollection $collection) + { + $collection->add('clone', $this->getRouterIdParameter().'/clone'); + } + +Which gives us a route like ``../admin/sonata/demo/car/1/clone``. +You could also just do ``$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. + + +.. code-block:: php + + 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 example ``CarAdmin.php`` looks like this: + +.. code-block:: php + + 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'); + } + } + +Final result looks like this: + +TODO: screenshot + +An example of this for ``CarAdmin`` in the AcmeDemoBundle of sonata-sandbox can be found here: +https://github.com/koyaan/sandbox/commit/5bdbc3528ec095f697a9deec32a4bc8ca8d13321 \ No newline at end of file