Skip to content

Commit

Permalink
Introduced a new "disabled_actions" option
Browse files Browse the repository at this point in the history
  • Loading branch information
javiereguiluz committed Jun 9, 2015
1 parent 5553e70 commit f4aaa14
Show file tree
Hide file tree
Showing 157 changed files with 1,162 additions and 131 deletions.
45 changes: 14 additions & 31 deletions Controller/AdminController.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ class AdminController extends Controller
/** @var EntityManager */
protected $em;

protected $view;

/**
* @Route("/", name="admin")
*
Expand All @@ -62,21 +60,16 @@ public function indexAction(Request $request)

$action = $request->query->get('action', 'list');

// for now, the homepage redirects to the 'list' action and view of the first entity
// for now, the homepage redirects to the 'list' action of the first entity
if (null === $request->query->get('entity')) {
return $this->redirect($this->generateUrl('admin', array(
'action' => $action,
'entity' => $this->getNameOfTheFirstConfiguredEntity(),
'view' => $this->view,
)));
}

if (in_array($action, array('list', 'edit', 'show', 'new')) && !$this->isActionAllowed($action)) {
throw new ForbiddenActionException(array(
'action' => $action,
'allowed_actions' => array_keys($this->entity[$this->view]['actions']),
'view' => $this->view,
));
if (!$this->isActionAllowed($action)) {
throw new ForbiddenActionException(array('action' => $action));
}

$customMethodName = $action.$this->entity['name'].'Action';
Expand Down Expand Up @@ -126,7 +119,6 @@ protected function initialize(Request $request)
$this->em = $this->getDoctrine()->getManagerForClass($this->entity['class']);

$this->request = $request;
$this->view = $this->request->query->get('view', 'list');

$this->dispatch(EasyAdminEvents::POST_INITIALIZE);
}
Expand All @@ -138,7 +130,6 @@ private function dispatch($eventName, array $arguments = array())
'em' => $this->em,
'entity' => $this->entity,
'request' => $this->request,
'view' => $this->view,
), $arguments);

$subject = isset($arguments['paginator']) ? $arguments['paginator'] : $arguments['entity'];
Expand All @@ -164,7 +155,6 @@ protected function listAction()
return $this->render($this->entity['templates']['list'], array(
'paginator' => $paginator,
'fields' => $fields,
'view' => 'list',
));
}

Expand Down Expand Up @@ -214,7 +204,7 @@ protected function editAction()

return !empty($refererUrl)
? $this->redirect(urldecode($refererUrl))
: $this->redirect($this->generateUrl('admin', array('action' => 'list', 'view' => 'list', 'entity' => $this->entity['name'])));
: $this->redirect($this->generateUrl('admin', array('action' => 'list', 'entity' => $this->entity['name'])));
}

$this->dispatch(EasyAdminEvents::POST_EDIT);
Expand All @@ -224,7 +214,6 @@ protected function editAction()
'entity_fields' => $fields,
'entity' => $entity,
'delete_form' => $deleteForm->createView(),
'view' => 'edit',
));
}

Expand Down Expand Up @@ -254,7 +243,6 @@ protected function showAction()
return $this->render($this->entity['templates']['show'], array(
'entity' => $entity,
'fields' => $fields,
'view' => 'show',
'delete_form' => $deleteForm->createView(),
));
}
Expand Down Expand Up @@ -299,7 +287,7 @@ protected function newAction()

$refererUrl = $this->request->query->get('referer', '');

return $this->redirect($this->generateUrl('admin', array('action' => 'list', 'view' => 'new', 'entity' => $this->entity['name'])));
return $this->redirect($this->generateUrl('admin', array('action' => 'list', 'entity' => $this->entity['name'])));
}

$this->dispatch(EasyAdminEvents::POST_NEW, array(
Expand All @@ -312,7 +300,6 @@ protected function newAction()
'form' => $newForm->createView(),
'entity_fields' => $fields,
'entity' => $entity,
'view' => 'new',
));
}

Expand All @@ -327,7 +314,7 @@ protected function deleteAction()
$this->dispatch(EasyAdminEvents::PRE_DELETE);

if ('DELETE' !== $this->request->getMethod()) {
return $this->redirect($this->generateUrl('admin', array('action' => 'list', 'view' => 'list', 'entity' => $this->entity['name'])));
return $this->redirect($this->generateUrl('admin', array('action' => 'list', 'entity' => $this->entity['name'])));
}

$id = $this->request->query->get('id');
Expand Down Expand Up @@ -359,7 +346,7 @@ protected function deleteAction()

return !empty($refererUrl)
? $this->redirect(urldecode($refererUrl))
: $this->redirect($this->generateUrl('admin', array('action' => 'list', 'view' => 'list', 'entity' => $this->entity['name'])));
: $this->redirect($this->generateUrl('admin', array('action' => 'list', 'entity' => $this->entity['name'])));
}

/**
Expand All @@ -383,7 +370,6 @@ protected function searchAction()
return $this->render($this->entity['templates']['list'], array(
'paginator' => $paginator,
'fields' => $fields,
'view' => 'search',
));
}

Expand Down Expand Up @@ -662,21 +648,21 @@ protected function render404error($view, array $parameters = array())
}

/**
* Utility method that checks if the given action is allowed for the current
* view of the current entity.
* Utility method that checks if the given action is allowed for
* the current entity.
*
* @param string $action
* @param string $actionName
*
* @return bool
*/
protected function isActionAllowed($action)
protected function isActionAllowed($actionName)
{
return array_key_exists($action, $this->entity[$this->view]['actions']);
return false === in_array($actionName, $this->entity['disabled_actions'], true);
}

/**
* Utility shortcut to render an error when the requested action is not allowed
* for the given view of the given entity.
* for the given entity.
*
* @param string $action
*
Expand All @@ -685,10 +671,7 @@ protected function isActionAllowed($action)
*/
protected function renderForbiddenActionError($action)
{
$allowedActions = array_keys($this->entity[$this->view]['actions']);
$parameters = array('action' => $action, 'allowed_actions' => $allowedActions, 'view' => $this->view);

return $this->render('@EasyAdmin/error/forbidden_action.html.twig', $parameters, new Response('', 403));
return $this->render('@EasyAdmin/error/forbidden_action.html.twig', array('action' => $action), new Response('', 403));
}

/**
Expand Down
9 changes: 9 additions & 0 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,15 @@ private function addGlobalOptionsSection(ArrayNodeDefinition $rootNode)
->end()
->end()
->end()

->variableNode('disabled_actions')
->info('The names of the actions disabled for all backend entities.')
->defaultValue(array())
->validate()
->ifTrue(function ($v) { return false === is_array($v); })
->thenInvalid('The disabled_actions option must be an array of action names.')
->end()
->end()
->end()
;
}
Expand Down
7 changes: 7 additions & 0 deletions DependencyInjection/EasyAdminExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,13 @@ public function processEntityActions(array $backendConfiguration)
$entitiesConfiguration = array();

foreach ($backendConfiguration['entities'] as $entityName => $entityConfiguration) {
// first, define the disabled actions
$actionsDisabledByBackend = $backendConfiguration['disabled_actions'];
$actionsDisabledByEntity = isset($entityConfiguration['disabled_actions']) ? $entityConfiguration['disabled_actions'] : array();
$disabledActions = array_unique(array_merge($actionsDisabledByBackend, $actionsDisabledByEntity));
$entityConfiguration['disabled_actions'] = $disabledActions;

// second, define the actions of each entity view
foreach (array('edit', 'list', 'new', 'show') as $view) {
$defaultActions = $this->getDefaultActions($view);
$backendActions = isset($backendConfiguration[$view]['actions']) ? $backendConfiguration[$view]['actions'] : array();
Expand Down
62 changes: 60 additions & 2 deletions Resources/doc/tutorials/customizing-backend-actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,61 @@ Customizing Backend Actions
In this article you'll learn how to disable actions, how to tweak their
appearance and how to create your own custom actions.

Disable Actions for Some or All Entities
----------------------------------------

Use the `disabled_actions` option to define the name of the actions disabled
globally or for some entity. For example, to disable the `show` action for all
entities, define the following:

```yaml
easy_admin:
disabled_actions: ['show']
# ...
```

When an action is disabled, the backend no longer displays it in any of the
views. In this example, if you browse any entity listing, you'll no longer see
the `Show` link next to each item. Moreover, if you try to *hack* the URL to
access to the `Show` view of some entity, you'll see a *Forbidden Action Error*
page.

The `disabled_actions` option can also be defined for each entity. If you want
to disable the `new` action just for the `User` entity, use this configuration:

```yaml
easy_admin:
entities:
User:
# ...
disabled_actions: ['new']
```
Reload the backend and you'll no longer see the `Add User` button in the `list`
view of the entity. Again, if you try to *hack* the URL to add a new user,
you'll see the *Forbidden Action Error* page.

Beware that the values of the `disabled_actions` options are merged. If the
backend configuration is the following:

```yaml
easy_admin:
disabled_actions: ['show']
# ...
entities:
User:
# ...
disabled_actions: ['new']
```

The `User` entity will have both the `new` and the `show` actions disabled.

Configure the Actions Displayed in Each View
--------------------------------------------

The actions displayed in each view can be configured globally for the entire
backend or on a per-entity basis.
Besides disabling actions, you can also configure which actions are displayed
in each view and how do they look like. Again this configuration can be done
globally or per-entity.

### Adding or Removing Actions Globally

Expand Down Expand Up @@ -80,6 +130,14 @@ will be the following:
* Actions removed by the entity: `show`
* Resulting actions for this entity: `list`, `new`, `search`

> **NOTE**
>
> Beware that the `actions` option just defines if an action should be
> displayed or not, but it doesn't disable the action. In the example above,
> if you *hack* the URL and change the `action` parameter manually, you can
> access to the `edit` and `show` actions. Use the `disabled_actions` options
> to ban those actions entirely.

Customizing the Actions Displayed in Each View
----------------------------------------------

Expand Down
5 changes: 1 addition & 4 deletions Resources/doc/tutorials/tips-and-tricks.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,7 @@ won't be able to add, modify or remove any information:

```yaml
easy_admin:
list:
actions: ['-edit', '-new']
show:
actions: ['-delete', '-edit']
disabled_actions: ['delete', 'edit', 'new']
```

Unloading the Default JavaScript and Stylesheets
Expand Down
2 changes: 1 addition & 1 deletion Resources/views/default/layout.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
{% block navigation_items %}
{% for item in easyadmin_config('entities') %}
<li class="{{ item.name|lower == app.request.get('entity')|lower ? 'active' : '' }}">
<a href="{{ path('admin', { entity: item.name, action: 'list', view: 'list' }) }}">
<a href="{{ path('admin', { entity: item.name, action: 'list' }) }}">
{{- item.label|trans -}}
</a>
</li>
Expand Down
2 changes: 0 additions & 2 deletions Resources/views/default/list.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

{% block content %}
{% set _request_parameters = _request_parameters|default({})|merge({
view: 'list',
action: app.request.get('action'),
entity: _entity_config.name,
sortField: app.request.get('sortField', ''),
Expand Down Expand Up @@ -61,7 +60,6 @@
{% block search_action %}
{% set _action = easyadmin_get_action_for_list_view('search', _entity_config.name) %}
<form id="content-search" class="col-xs-6 col-sm-8 {{ _action.css_class|default('') }}" method="get" action="{{ path('admin') }}">
<input type="hidden" name="view" value="list">
<input type="hidden" name="action" value="search">
<input type="hidden" name="entity" value="{{ _request_parameters.entity }}">
<input type="hidden" name="sortField" value="{{ _request_parameters.sortField }}">
Expand Down
2 changes: 1 addition & 1 deletion Resources/views/default/show.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
{% set _show_actions = easyadmin_get_actions_for_show_item(_entity_config.name) %}
{% for _action in _show_actions %}
{% if 'method' == _action.type %}
{% set _action_href = path('admin', { action: _action.name, view: 'show', entity: _entity_config.name, id: attribute(entity, _entity_config.primary_key_field_name), referer: app.request.query.get('referer', '') }) %}
{% set _action_href = path('admin', { action: _action.name, entity: _entity_config.name, id: attribute(entity, _entity_config.primary_key_field_name), referer: app.request.query.get('referer', '') }) %}
{% elseif 'route' == _action.type %}
{% set _action_href = path(_action.name, { entity: _entity_config.name, id: attribute(entity, _entity_config.primary_key_field_name), referer: app.request.query.get('referer', '') }) %}
{% endif %}
Expand Down
15 changes: 5 additions & 10 deletions Resources/views/error/forbidden_action.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,18 @@
{% block solution %}
<ul>
<li>
Change this action for one of the following allowed actions:
<code>{{ allowed_actions|join('</code>, <code>')|raw }}</code>.
</li>
<li>
If the action name is correct, make sure it's included in
the <code>actions</code> option in the <code>{{ view }}</code>
view configuration of your entity.
Remove the <code>{{ action }}</code> action from the
<code>disabled_actions</code> option.

<pre>
{{- '' -}}
easy_admin:
disabled_actions: ['{{ action }}', ...] # <-- remove it from here (if present)
entities:
YourEntity:
# ...
{{ view }}:
actions:
['{{ action }}', ...]
disabled_actions:
['{{ action }}', ...] # <-- remove it from here (if present)
# ...
{{- '' -}}
</pre>
Expand Down
Loading

0 comments on commit f4aaa14

Please sign in to comment.