Commit 31735737 authored by alexpott's avatar alexpott
Browse files

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) { ...@@ -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. * Control access to fields.
* *
......
...@@ -7,10 +7,13 @@ ...@@ -7,10 +7,13 @@
namespace Drupal\Core\Entity; namespace Drupal\Core\Entity;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/** /**
* Provides a generic implementation of an entity list controller. * Provides a generic implementation of an entity list controller.
*/ */
class EntityListController implements EntityListControllerInterface { class EntityListController implements EntityListControllerInterface, EntityControllerInterface {
/** /**
* The entity storage controller class. * The entity storage controller class.
...@@ -19,6 +22,13 @@ class EntityListController implements EntityListControllerInterface { ...@@ -19,6 +22,13 @@ class EntityListController implements EntityListControllerInterface {
*/ */
protected $storage; protected $storage;
/**
* The module handler to invoke hooks on.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/** /**
* The entity type name. * The entity type name.
* *
...@@ -35,18 +45,35 @@ class EntityListController implements EntityListControllerInterface { ...@@ -35,18 +45,35 @@ class EntityListController implements EntityListControllerInterface {
*/ */
protected $entityInfo; 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. * Constructs a new EntityListController object.
* *
* @param string $entity_type. * @param string $entity_type
* The type of entity to be listed. * 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. * 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->entityType = $entity_type;
$this->storage = $storage; $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) { ...@@ -131,6 +158,7 @@ public function buildRow(EntityInterface $entity) {
public function buildOperations(EntityInterface $entity) { public function buildOperations(EntityInterface $entity) {
// Retrieve and sort operations. // Retrieve and sort operations.
$operations = $this->getOperations($entity); $operations = $this->getOperations($entity);
$this->moduleHandler->alter('entity_operation', $operations, $entity);
uasort($operations, 'drupal_sort_weight'); uasort($operations, 'drupal_sort_weight');
$build = array( $build = array(
'#type' => 'operations', '#type' => 'operations',
......
...@@ -207,7 +207,7 @@ public function getRenderController($entity_type) { ...@@ -207,7 +207,7 @@ public function getRenderController($entity_type) {
if (!isset($this->controllers['render'][$entity_type])) { if (!isset($this->controllers['render'][$entity_type])) {
$class = $this->getControllerClass($entity_type, 'render'); $class = $this->getControllerClass($entity_type, 'render');
if (in_array('Drupal\Core\Entity\EntityControllerInterface', class_implements($class))) { 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 { else {
$this->controllers['render'][$entity_type] = new $class($entity_type); $this->controllers['render'][$entity_type] = new $class($entity_type);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Config\Entity\ConfigEntityListController; use Drupal\Core\Config\Entity\ConfigEntityListController;
use Drupal\Core\Entity\EntityStorageControllerInterface; use Drupal\Core\Entity\EntityStorageControllerInterface;
use \Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\action\Form\ActionAdminManageForm; use Drupal\action\Form\ActionAdminManageForm;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
...@@ -38,13 +39,17 @@ class ActionListController extends ConfigEntityListController implements EntityC ...@@ -38,13 +39,17 @@ class ActionListController extends ConfigEntityListController implements EntityC
* *
* @param string $entity_type * @param string $entity_type
* The entity type. * The entity type.
* @param array $entity_info
* An array of entity info for the entity type.
* @param \Drupal\Core\Entity\EntityStorageControllerInterface $storage * @param \Drupal\Core\Entity\EntityStorageControllerInterface $storage
* The action storage controller. * The action storage controller.
* @param \Drupal\Core\Action\ActionManager $action_manager * @param \Drupal\Core\Action\ActionManager $action_manager
* The action plugin 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) { public function __construct($entity_type, array $entity_info, EntityStorageControllerInterface $storage, ActionManager $action_manager, ModuleHandlerInterface $module_handler) {
parent::__construct($entity_type, $storage); parent::__construct($entity_type, $entity_info, $storage, $module_handler);
$this->actionManager = $action_manager; $this->actionManager = $action_manager;
} }
...@@ -55,8 +60,10 @@ public function __construct($entity_type, EntityStorageControllerInterface $stor ...@@ -55,8 +60,10 @@ public function __construct($entity_type, EntityStorageControllerInterface $stor
public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info) { public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info) {
return new static( return new static(
$entity_type, $entity_type,
$entity_info,
$container->get('plugin.manager.entity')->getStorageController($entity_type), $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) { ...@@ -418,3 +418,15 @@ function entity_test_entity_predelete(EntityInterface $entity) {
throw new Exception('Entity predelete exception', 2); 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