Commit 31735737 authored by alexpott's avatar alexpott

Issue #2004408 by YesCT, penyaskito: Allow modules to alter the result of...

Issue #2004408 by YesCT, penyaskito: Allow modules to alter the result of EntityListController::getOperations.
parent 71a4ab13
......@@ -537,6 +537,24 @@ function hook_entity_field_info_alter(&$info, $entity_type) {
}
}
/**
* Alter entity operations.
*
* @param array $operations
* Operations array as returned by
* \Drupal\Core\Entity\EntityStorageControllerInterface::getOperations().
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity on which the linked operations will be performed.
*/
function hook_entity_operation_alter(array &$operations, \Drupal\Core\Entity\EntityInterface $entity) {
$uri = $entity->uri();
$operations['translate'] = array(
'title' => t('Translate'),
'href' => $uri['path'] . '/translate',
'weight' => 50,
);
}
/**
* Control access to fields.
*
......
......@@ -7,10 +7,13 @@
namespace Drupal\Core\Entity;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a generic implementation of an entity list controller.
*/
class EntityListController implements EntityListControllerInterface {
class EntityListController implements EntityListControllerInterface, EntityControllerInterface {
/**
* The entity storage controller class.
......@@ -19,6 +22,13 @@ class EntityListController implements EntityListControllerInterface {
*/
protected $storage;
/**
* The module handler to invoke hooks on.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The entity type name.
*
......@@ -35,18 +45,35 @@ class EntityListController implements EntityListControllerInterface {
*/
protected $entityInfo;
/**
* {@inheritdoc}
*/
public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info) {
return new static(
$entity_type,
$entity_info,
$container->get('plugin.manager.entity')->getStorageController($entity_type),
$container->get('module_handler')
);
}
/**
* Constructs a new EntityListController object.
*
* @param string $entity_type.
* @param string $entity_type
* The type of entity to be listed.
* @param \Drupal\Core\Entity\EntityStorageControllerInterface $storage.
* @param array $entity_info
* An array of entity info for the entity type.
* @param \Drupal\Core\Entity\EntityStorageControllerInterface $storage
* The entity storage controller class.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler to invoke hooks on.
*/
public function __construct($entity_type, EntityStorageControllerInterface $storage) {
public function __construct($entity_type, array $entity_info, EntityStorageControllerInterface $storage, ModuleHandlerInterface $module_handler) {
$this->entityType = $entity_type;
$this->storage = $storage;
$this->entityInfo = entity_get_info($this->entityType);
$this->entityInfo = $entity_info;
$this->moduleHandler = $module_handler;
}
/**
......@@ -131,6 +158,7 @@ public function buildRow(EntityInterface $entity) {
public function buildOperations(EntityInterface $entity) {
// Retrieve and sort operations.
$operations = $this->getOperations($entity);
$this->moduleHandler->alter('entity_operation', $operations, $entity);
uasort($operations, 'drupal_sort_weight');
$build = array(
'#type' => 'operations',
......
......@@ -207,7 +207,7 @@ public function getRenderController($entity_type) {
if (!isset($this->controllers['render'][$entity_type])) {
$class = $this->getControllerClass($entity_type, 'render');
if (in_array('Drupal\Core\Entity\EntityControllerInterface', class_implements($class))) {
$this->controllers['render'][$entity_type] = $class::createInstance($this->container, $entity_type, $this->getDefinition($entity_type));
$this->controllers['render'][$entity_type] = $class::createInstance($this->container, $this->getDefinition($entity_type), $entity_type);
}
else {
$this->controllers['render'][$entity_type] = new $class($entity_type);
......
......@@ -13,6 +13,7 @@
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Config\Entity\ConfigEntityListController;
use Drupal\Core\Entity\EntityStorageControllerInterface;
use \Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\action\Form\ActionAdminManageForm;
use Symfony\Component\DependencyInjection\ContainerInterface;
......@@ -38,13 +39,17 @@ class ActionListController extends ConfigEntityListController implements EntityC
*
* @param string $entity_type
* The entity type.
* @param array $entity_info
* An array of entity info for the entity type.
* @param \Drupal\Core\Entity\EntityStorageControllerInterface $storage
* The action storage controller.
* @param \Drupal\Core\Action\ActionManager $action_manager
* The action plugin manager.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler to invoke hooks on.
*/
public function __construct($entity_type, EntityStorageControllerInterface $storage, ActionManager $action_manager) {
parent::__construct($entity_type, $storage);
public function __construct($entity_type, array $entity_info, EntityStorageControllerInterface $storage, ActionManager $action_manager, ModuleHandlerInterface $module_handler) {
parent::__construct($entity_type, $entity_info, $storage, $module_handler);
$this->actionManager = $action_manager;
}
......@@ -55,8 +60,10 @@ public function __construct($entity_type, EntityStorageControllerInterface $stor
public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info) {
return new static(
$entity_type,
$entity_info,
$container->get('plugin.manager.entity')->getStorageController($entity_type),
$container->get('plugin.manager.action')
$container->get('plugin.manager.action'),
$container->get('module_handler')
);
}
......
<?php
/**
* @file
* Contains \Drupal\system\Tests\Entity\EntityOperationsTest.
*/
namespace Drupal\system\Tests\Entity;
use Drupal\simpletest\WebTestBase;
/**
* Tests for entity operations, that they can be altered.
*/
class EntityOperationsTest extends WebTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('entity_test');
public static function getInfo() {
return array(
'name' => 'Entity Operations',
'description' => 'Check that operations can be injected from the hook.',
'group' => 'Entity API',
);
}
public function setUp() {
parent::setUp();
// Create and login user.
$this->web_user = $this->drupalCreateUser(array(
'administer permissions',
));
$this->drupalLogin($this->web_user);
}
/**
* Checks that hook_entity_operation_alter() can add an operation.
*
* @see entity_test_entity_operation_alter()
*/
public function testEntityOperationAlter() {
// Check that role listing contain our test_operation operation.
$this->drupalGet('admin/people/roles');
$roles = user_roles();
foreach ($roles as $role) {
$uri = $role->uri();
$this->assertLinkByHref($uri['path'] . '/test_operation');
$this->assertLink('Test Operation: ' . $role->label());
}
}
}
......@@ -418,3 +418,15 @@ function entity_test_entity_predelete(EntityInterface $entity) {
throw new Exception('Entity predelete exception', 2);
}
}
/**
* Implements hook_entity_operation_alter().
*/
function entity_test_entity_operation_alter(array &$operations, EntityInterface $entity) {
$uri = $entity->uri();
$operations['test_operation'] = array(
'title' => 'Test Operation: ' . $entity->label(),
'href' => $uri['path'] . '/test_operation',
'weight' => 50,
);
}
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