All actions are customizable, but you can also define custom actions that can be used in your admin. As described in the admin actions documentation, there are three types of actions:
batch_actionsobject_actionsactions
For every action type you can create custom actions. They all have the same options available.
Note: excel, edit and show action names are reserved. The delete action is pre-configured.
When an action is defined with the object_actions or batch_actions which does not exists, a controller STUB will
be generated. You will have to add code to the controller before your custom action will work.
There are two routes (and so methods) that handle all custom actions:
objectAction: route for this action isVendor_BundleName_GeneratorPrefix_object, for example:Acme_DemoBundle_User_object. It takes two arguments:pk(object primary key) andaction(object action name).batchActionroute for this action isVendor_BundleName_GeneratorPrefix_batch, for example:Acme_DemoBundle_User_batch. This action requires POST method and two posted variables:action(batch action name) andselected(an array of selected object primary keys).
Additionally all batch actions are by default CSRF protected. Object actions can be CSRF protected, if you add
csrfProtected: true in action config.
Depending on the value of action parameter, different method will be called. E.g. /{pk}/delete will call delete
object action.
# ...
params:
# add "global" config shared between all builders
# for object actions
object_actions:
impersonate:
label: Login as
icon: glyphicon-user
route: Homepage
params:
_switch_user: "{{ User.username }}"
lock:
label: Lock account
icon: glyphicon-lock
route: Acme_SecurityBundle_User_object # Optional
params: # Optional
pk: "{{ User.id }}"
action: lock
csrfProtected: true
options:
# this is the title for intermediate page
# if JS is available then intermediate page will not be used
title: "Are you sure you want to lock this account?"
builders:
list:
params:
# if action config is set to null (~)
# then "global" shared config will be used
object_actions:
impersonate: ~
lock: ~
delete: ~
# delete action is pre-configured, so it does not need a config
actions:
params:
object_actions:
lock: ~
# we're generating a STUB for lock actionLet's have a quick look what's going on in this config. First of all, we're configuring object_actions under global
params, so we don't have to configure them twice (for list and actions builder).
Impersonate action leads to Homepage route, which takes no parameters. Because of that _switch_user parameter
will be appended as a GET parameter (e.g. /?_switch_user=cedric) which is exactly what we want.
Read more about impersonating a user in Symfony2 book, Security chapter.
Lock action is a custom action, for which we will generate a STUB and customize it in our ActionsController. So,
first we configure lock action to use our object_actions route.
Note: the route for object and batch actions uses
generator prefix, notmodel name!
You may have multiple generators for one model (e.g. for User model you may generate BasicUser-generator.yml,
AdvancedUser-generator.yml and AdminUser-generator.yml). In such case remember that the route for BasicUser would
be Acme_SecurityBundle_BasicUser_object or Acme_SecurityBundle_BasicUser_batch for batch actions.
This route requires two parameters: pk, in this case {{ User.id }} and action which is our action's name lock.
Next, we're setting csrfProtected to true to enable the built-in actions CSRF protection.
Last, we're configuring the intermediate page title. Intermediate page is only used if for some reason Javascript fails.
In list builder configuration we're adding actions we want to display. If action config is set to null (~) then global config will be used. Thanks to this little fix we can have different object actions in List and Actions builders, but share their configuration.
So, in list we want to display:
impersonate-> custom object action leading toHomepageroutelock-> custom object action using actions stub generatordelete-> pre-configured default object action
In actions builder configuration we're adding actions we want to generate STUBs for. That is only lock action in
this example.
Now, all we have to do is go to our bundle's directory and code what our lock action actually does. In our example we
can do that by editing Acme/SecurityBundle/Controller/UserController/ActionsController.php.
/**
* This function is for you to customize what action actually does
*/
protected function executeObjectLock($User)
{
// In this example I use Doctrine ORM
$em = $this->getDoctrine()->getManager();
// Lock user
$User->setLocked(true);
// Save changes to database
$em->persist($User);
$em->flush();
}For each custom object action there are four methods generated:
attemptObject{{ ActionName }}- handles common object actions behaviour like checking CSRF protection token or credentialsexecuteObject{{ ActionName }}- holds action logicsuccessObject{{ ActionName }}- called if action was successfulerrorObject{{ ActionName }}- called if action errored
Note: The only method you have to overwrite is
executeObject{{ ActionName }}.
# ...
params:
# add "global" config shared between all builders
# for object actions
batch_actions:
lock:
label: Lock account
icon: glyphicon-lock
route: Acme_SecurityBundle_User_batch
builders:
list:
params:
# if action config is set to null (~)
# then "global" shared config will be used
batch_actions:
lock: ~
delete: ~
# delete action is pre-configured, so it does not need a config
actions:
params:
batch_actions:
lock: ~
# we're generating a STUB for lock actionLet's have a quick look what's going on in this config. Similar to object actions configuration, first we're configuring "global" batch actions. Batch actions configuration is a bit shorter, because all batch actions are always CSRF protected, and there is no intermediate page, so we don't have to specify a title for it.
Also, all required parameters (action name, selected objects, csrf token) are rendered as part of form on List view, so they need no further configuration.
In list builder configuration we're adding actions we want to display. If action config is set to null (~) then global config will be used. Thanks to this little fix we can have different batch actions in List and Actions builders, but share their configuration.
So, in list we want to display:
lock-> custom batch action using actions stub generatordelete-> pre-configured default batch action
In actions builder configuration we're adding actions we want to generate STUBs for. That is only lock action in this
example.
Now, all we have to do is go to our bundle's directory and code what our lock action actually does. In our example we
can do that by editing Acme/SecurityBundle/Controller/UserController/ActionsController.php.
/**
* This function is for you to customize what action actually does
*/
protected function executeBatchLock($selected)
{
// In this example I use Doctrine ORM
$em = $this->getDoctrine()->getManager();
// Lock users
$em->createQuery('UPDATE Acme\SecurityBundle\Entity\User u SET u.locked = :locked WHERE u.id IN (:selected)')
->setParameter('locked', true)
->setParameter('selected', $selected)
->getResult();
}Similarly to object actions, for each custom batch action there are four methods generated:
attemptBatch{{ ActionName }}- handles common object actions behaviour like checking CSRF protection token or credentialsexecuteBatch{{ ActionName }}- holds action logicsuccessBatch{{ ActionName }}- called if action was successfulerrorBatch{{ ActionName }}- called if action errored
Note: The only method you have to overwrite is
executeBatch{{ ActionName }}
Because admingenerator generates functions based on action name, action names must be validated. Actions names cannot
contain characters like !@#$%^&*;:"',.()[]{}, they may contain only word-characters and dashes.
Any non-word character will be removed from generated function name, e.g. object action toggle-is-valid will generate
functions:
protected function attemptObjectToggleisvalid() { ... }
protected function executeObjectToggleisvalid() { ... }
protected function successObjectToggleisvalid() { ... }
protected function errorObjectToggleisvalid() { ... }- Class
- Confirm
- ConfirmModal
- Credentials
- CsrfProtected
- ForceIntermediate
- Icon
- Label
- Options
- Params
- Route
- Submit
class type: string
Add any css class(es) to the rendered button.
confirm type: string
Used to set a confirm message. When set, the action will first use a javascript popup with your confirm message to ask for confirmation from the user.
confirmModal type: string
Used to set an id of modal confirm dialog. Use when you want to use different id than default:
confirmGenericModal: Used for generic-actionsconfirmBatchModal: Used for batch-actionsconfirmObjectModal: Used for object-actions
This is not needed unless you want to use a dialog with special field(s). For example action with a parameter.
credentials type: string
By default, there are no credentials required to show and use an action. To check for a specific credential, just enter it here. For more documenation about credentials, check our [security documentation][security-doc].
NOTE Credentials given here are valid for the whole admin, but can be overridden in specific builders or even specific fields.
crsfProtected type: bool default: false
When set to true an extra crsf token is added to the data-crsf-token of the button.
forceIntermediate type: array default: false
When set to true the intermediate confirm page will always be used instead of the javascript confirm.
icon type: string
Set the icon that is used in the button. For example fa-book.
label type: string
Set the label of the button.
options type: array
Can be used to set specific settings for the actions. Currenlty inplemented:
title: Used to set the page title of the intermediate pagesuccess: Used to set the success message in the flashbag on action successerror: Used to set the error message in the flashbag on action errori18n: Used to set the translations catalogue
params type: array
Set the params used for route generation.
route type: string
Set the action of the button. When this is set, there will be no controller STUB, as it will not be used. The button is rendered as simple URL.
submit __type
__: bool
If set to true, the button will behave as a submit button for the form on that page.