Commit 972406d5 authored by alexpott's avatar alexpott

Issue #2012916 by andypost, Berdir, pwieck: Implement access controller for...

Issue #2012916 by andypost, Berdir, pwieck: Implement access controller for the menu and menu link entity.
parent 7833e61c
<?php
/**
* @file
* Contains \Drupal\menu\Access\DeleteLinkAccessCheck.
*/
namespace Drupal\menu\Access;
use Drupal\Core\Access\StaticAccessCheckInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\HttpFoundation\Request;
/**
* Access check for menu link delete routes.
*/
class DeleteLinkAccessCheck implements StaticAccessCheckInterface {
/**
* {@inheritdoc}
*/
public function appliesTo() {
return array('_access_menu_delete_link');
}
/**
* {@inheritdoc}
*/
public function access(Route $route, Request $request) {
if (user_access('administer menu') && $menu_link = $request->attributes->get('menu_link')) {
// Links defined via hook_menu may not be deleted. Updated items are an
// exception, as they can be broken.
return $menu_link->module !== 'system' || $menu_link->updated;
}
return FALSE;
}
}
......@@ -174,10 +174,8 @@ public function menuNameExists($value) {
*/
protected function actions(array $form, array &$form_state) {
$actions = parent::actions($form, $form_state);
$menu = $this->entity;
$system_menus = menu_list_system_menus();
$actions['delete']['#access'] = !$menu->isNew() && !isset($system_menus[$menu->id()]);
$actions['delete']['#access'] = !$this->entity->isNew() && $this->entity->access('delete');
// Add the language configuration submit handler. This is needed because the
// submit button has custom submit handlers.
......@@ -223,8 +221,10 @@ public function languageConfigurationSubmit(array &$form, array &$form_state) {
*/
public function save(array $form, array &$form_state) {
$menu = $this->entity;
// @todo Get rid of menu_list_system_menus() https://drupal.org/node/1882552
// Supposed menu item declared by hook_menu()
// Should be moved to submitOverviewForm()
$system_menus = menu_list_system_menus();
if (!$menu->isNew() || isset($system_menus[$menu->id()])) {
$this->submitOverviewForm($form, $form_state);
}
......@@ -354,31 +354,27 @@ protected function buildOverviewTreeForm($tree, $delta) {
);
// Build a list of operations.
$operations = array();
$links = array();
$links['edit'] = array(
$operations['edit'] = array(
'title' => t('Edit'),
'href' => 'admin/structure/menu/item/' . $item['mlid'] . '/edit',
);
$operations['edit'] = array('#type' => 'link', '#title' => t('Edit'), '#href' => 'admin/structure/menu/item/' . $item['mlid'] . '/edit');
// Only items created by the menu module can be deleted.
if ($item['module'] == 'menu' || $item['updated'] == 1) {
$links['delete'] = array(
if ($item->access('delete')) {
$operations['delete'] = array(
'title' => t('Delete'),
'href' => 'admin/structure/menu/item/' . $item['mlid'] . '/delete',
);
$operations['delete'] = array('#type' => 'link', '#title' => t('Delete'), '#href' => 'admin/structure/menu/item/' . $item['mlid'] . '/delete');
}
// Set the reset column.
elseif ($item['module'] == 'system' && $item['customized']) {
$links['reset'] = array(
elseif ($item->access('reset')) {
$operations['reset'] = array(
'title' => t('Reset'),
'href' => 'admin/structure/menu/item/' . $item['mlid'] . '/reset',
);
$operations['reset'] = array('#type' => 'link', '#title' => t('Reset'), '#href' => 'admin/structure/menu/item/' . $item['mlid'] . '/reset');
}
$form[$mlid]['operations'] = array(
'#type' => 'operations',
'#links' => $links,
'#links' => $operations,
);
}
......
......@@ -49,16 +49,16 @@ public function getOperations(EntityInterface $entity) {
if (isset($operations['edit'])) {
$operations['edit']['title'] = t('Edit menu');
$operations['add'] = array(
'title' => t('Add link'),
'href' => $uri['path'] . '/add',
'options' => $uri['options'],
'weight' => 20,
);
}
if (isset($operations['delete'])) {
$operations['delete']['title'] = t('Delete menu');
}
$operations['add'] = array(
'title' => t('Add link'),
'href' => $uri['path'] . '/add',
'options' => $uri['options'],
'weight' => 20,
);
return $operations;
}
......
......@@ -125,7 +125,6 @@ function menu_menu() {
*/
function menu_entity_info(&$entity_info) {
$entity_info['menu']['controllers']['list'] = 'Drupal\menu\MenuListController';
$entity_info['menu']['controllers']['access'] = 'Drupal\menu\MenuAccessController';
$entity_info['menu']['uri_callback'] = 'menu_uri';
$entity_info['menu']['controllers']['form'] = array(
'add' => 'Drupal\menu\MenuFormController',
......
......@@ -24,28 +24,28 @@ menu_link_add:
defaults:
_content: '\Drupal\menu\Controller\MenuController::addLink'
requirements:
_permission: 'administer menu'
_entity_create_access: 'menu_link'
menu_link_edit:
pattern: '/admin/structure/menu/item/{menu_link}/edit'
defaults:
_entity_form: 'menu_link'
requirements:
_permission: 'administer menu'
_entity_access: 'menu_link.update'
menu_link_reset:
pattern: 'admin/structure/menu/item/{menu_link}/reset'
defaults:
_entity_form: 'menu_link.reset'
requirements:
_permission: 'administer menu'
_entity_access: 'menu_link.reset'
menu_link_delete:
pattern: 'admin/structure/menu/item/{menu_link}/delete'
defaults:
_entity_form: 'menu_link.delete'
requirements:
_access_menu_delete_link: 'TRUE'
_entity_access: 'menu_link.delete'
menu_menu_add:
pattern: '/admin/structure/menu/add'
......
services:
access_check.menu.delete_link:
class: Drupal\menu\Access\DeleteLinkAccessCheck
tags:
- { name: access_check }
<?php
/**
* @file
* Contains \Drupal\menu_link\MenuLinkAccessController.
*/
namespace Drupal\menu_link;
use Drupal\Core\Entity\EntityAccessController;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Session\AccountInterface;
/**
* Defines an access controller for the menu link entity.
*
* @see \Drupal\menu_link\Plugin\Core\Entity\MenuLink
*/
class MenuLinkAccessController extends EntityAccessController {
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
$access = $account->hasPermission('administer menu');
if ($access) {
switch ($operation) {
case 'reset':
// Reset allowed for items defined via hook_menu() and customized.
return $entity->module == 'system' && $entity->customized;
case 'delete':
// Only items created by the menu module can be deleted.
return $entity->module == 'menu' || $entity->updated == 1;
}
}
return $access;
}
/**
* {@inheritdoc}
*/
protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
return $account->hasPermission('administer menu');
}
}
......@@ -208,7 +208,7 @@ public function form(array $form, array &$form_state) {
protected function actions(array $form, array &$form_state) {
$element = parent::actions($form, $form_state);
$element['submit']['#button_type'] = 'primary';
$element['delete']['#access'] = $this->entity->module == 'menu';
$element['delete']['#access'] = $this->entity->access('delete');
return $element;
}
......
......@@ -28,6 +28,7 @@
* module = "menu_link",
* controllers = {
* "storage" = "Drupal\menu_link\MenuLinkStorageController",
* "access" = "Drupal\menu_link\MenuLinkAccessController",
* "render" = "Drupal\Core\Entity\EntityRenderController",
* "form" = {
* "default" = "Drupal\menu_link\MenuLinkFormController"
......
......@@ -2,10 +2,10 @@
/**
* @file
* Contains \Drupal\menu\MenuAccessController.
* Contains \Drupal\system\MenuAccessController.
*/
namespace Drupal\menu;
namespace Drupal\system;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityAccessController;
......@@ -25,6 +25,7 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
}
elseif ($operation == 'delete') {
// System menus could not be deleted.
// @todo Refactor in https://drupal.org/node/1882552
$system_menus = menu_list_system_menus();
if (isset($system_menus[$entity->id()])) {
return FALSE;
......@@ -32,7 +33,7 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
}
if (in_array($operation, array('update', 'delete'))) {
return user_access('administer menu', $account);
return $account->hasPermission('administer menu');
}
}
......@@ -40,7 +41,7 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
* {@inheritdoc}
*/
protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
return user_access('administer menu', $account);
return $account->hasPermission('administer menu');
}
}
......@@ -20,7 +20,8 @@
* label = @Translation("Menu"),
* module = "system",
* controllers = {
* "storage" = "Drupal\Core\Config\Entity\ConfigStorageController"
* "storage" = "Drupal\Core\Config\Entity\ConfigStorageController",
* "access" = "Drupal\system\MenuAccessController"
* },
* config_prefix = "menu.menu",
* entity_keys = {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment