commit 7f1dad0843be42488cd7635b48d7f84668d79434 Author: Bart Feenstra Date: Fri Nov 8 12:53:32 2013 +0100 meeh diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityOperationsProvider.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityOperationsProvider.php index e3ad4d6..50ef3a5 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityOperationsProvider.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityOperationsProvider.php @@ -22,21 +22,13 @@ protected function getDefaultOperations(EntityInterface $entity) { $uri = $entity->uri(); $operations = parent::getDefaultOperations($entity); - // For configuration entities edit path is the MENU_DEFAULT_LOCAL_TASK and - // therefore should be accessed by the short route. + // Configuration entities' edit pages are located at the entities' canonical + // URLs. $operations['update']['href'] = $uri['path']; $info = $entity->entityInfo(); if (isset($info['entity_keys']['status'])) { - if (!$entity->status()) { - $operations['enable'] = array( - 'title' => $this->translationManager->translate('Enable'), - 'href' => $uri['path'] . '/enable', - 'options' => $uri['options'], - 'weight' => -10, - ); - } - else { + if ($entity->status()) { $operations['disable'] = array( 'title' => $this->translationManager->translate('Disable'), 'href' => $uri['path'] . '/disable', @@ -44,6 +36,14 @@ protected function getDefaultOperations(EntityInterface $entity) { 'weight' => 40, ); } + else { + $operations['enable'] = array( + 'title' => $this->translationManager->translate('Enable'), + 'href' => $uri['path'] . '/enable', + 'options' => $uri['options'], + 'weight' => -10, + ); + } } return $operations; diff --git a/core/lib/Drupal/Core/Entity/EntityOperationsProvider.php b/core/lib/Drupal/Core/Entity/EntityOperationsProvider.php index 4b1c148..cb79c0c 100644 --- a/core/lib/Drupal/Core/Entity/EntityOperationsProvider.php +++ b/core/lib/Drupal/Core/Entity/EntityOperationsProvider.php @@ -69,12 +69,32 @@ public function getOperations(EntityInterface $entity, AccountInterface $account unset($operations[$operation]); } } -// @todo Sort operations by weight and human-readable label. + + uasort($operations, array($this, 'sort')); return $operations; } /** + * Sorts operations. + * + * @param array $operation_a + * The structure is identical to that of an item of the return value of + * self::getOperations(). + * @param array $operation_b + * The structure is identical to that of an item of the return value of + * self::getOperations(). + */ + protected function sort(array $operation_a, array $operation_b) { + if ($operation_a['weight'] == $operation_b['weight']) { + return strnatcasecmp($operation_a['title'], $operation_b['title']); + } + else { + return $operation_a['weight'] > $operation_b['weight'] ? 1 : -1; + } + } + + /** * Gets the entity's default operations. * * @param \Drupal\Core\Entity\EntityInterface $entity diff --git a/core/lib/Drupal/Core/Entity/EntityOperationsProviderInterface.php b/core/lib/Drupal/Core/Entity/EntityOperationsProviderInterface.php index f0a3dbf..9f2f6a0 100644 --- a/core/lib/Drupal/Core/Entity/EntityOperationsProviderInterface.php +++ b/core/lib/Drupal/Core/Entity/EntityOperationsProviderInterface.php @@ -24,8 +24,17 @@ * @param \Drupal\Core\Session\AccountInterface $account * * @return array - * An array of operations. - * @todo Document array structure. + * Keys are operation machine names and values are arrays with the following + * keys: + * - title: The link text. + * - href: (optional) The link URL. If omitted, the 'title' is shown as a plain text + * item in the links list. + * - html: (optional) Whether or not 'title' is HTML. If set, the title + * will not be passed through + * \Drupal\Component\Utility\String::checkPlain(). + * - attributes: (optional) Attributes for the anchor, or for the + * tag used in its place if no 'href' is supplied. If element 'class' is + * included, it must be an array of one or more class names. */ public function getOperations(EntityInterface $entity, AccountInterface $account); diff --git a/core/modules/image/tests/Drupal/image/ImageStyleOperationsProviderUnitTest.php b/core/modules/image/tests/Drupal/image/ImageStyleOperationsProviderUnitTest.php new file mode 100644 index 0000000..e565245 --- /dev/null +++ b/core/modules/image/tests/Drupal/image/ImageStyleOperationsProviderUnitTest.php @@ -0,0 +1,99 @@ + '', + 'group' => 'Image', + 'name' => '\Drupal\image\ImageStyleOperationsProvider', + ); + } + + /** + * {@inheritdoc} + */ + public function setUp() { + parent::setUp(); + + $this->moduleHandler = $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface'); + $this->moduleHandler->expects($this->exactly(2)) + ->method('invokeAll') + ->will($this->returnValue(array())); + + $this->currentUser = $this->getMock('\Drupal\Core\Session\AccountInterface'); + + $this->translationManager = $this->getMockBuilder('\Drupal\Core\StringTranslation\TranslationManager') + ->disableOriginalConstructor() + ->getMock(); + + $this->entity = $this->getMock('\Drupal\Core\Config\Entity\ConfigEntityInterface'); + $this->entity->expects($this->any()) + ->method('access') + ->will($this->returnValue(TRUE)); + + $this->operationsProvider = new ImageStyleOperationsProvider($this->moduleHandler, $this->translationManager); + } + + /** + * Tests getOperations(). + */ + public function testGetOperations() { + $operations = $this->operationsProvider->getOperations($this->entity, $this->currentUser); + $this->assertInternalType('array', $operations); + $this->assertArrayHasKey('flush', $operations); + $this->assertInternalType('array', $operations['flush']); + } +} diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewOperationsProvider.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewOperationsProvider.php index e6da725..237efd6 100644 --- a/core/modules/views_ui/lib/Drupal/views_ui/ViewOperationsProvider.php +++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewOperationsProvider.php @@ -29,8 +29,8 @@ protected function getDefaultOperations(EntityInterface $entity) { ); // Add AJAX functionality to enable/disable operations. foreach (array('enable', 'disable') as $operation) { - // @todo There is no generic access control for enable and disable - // operations yet. Once that is done, this if statement can be removed. + // @todo This if statement can be removed once + // https://drupal.org/node/2129953 is fixed. if (isset($operations[$operation])) { $operations[$operation]['ajax'] = TRUE; $operations[$operation]['query']['token'] = drupal_get_token($operation); diff --git a/core/tests/Drupal/Tests/Core/Entity/ConfigEntityOperationsProviderUnitTest.php b/core/modules/views_ui/tests/Drupal/views_ui/ViewOperationsProviderUnitTest.php similarity index 52% copy from core/tests/Drupal/Tests/Core/Entity/ConfigEntityOperationsProviderUnitTest.php copy to core/modules/views_ui/tests/Drupal/views_ui/ViewOperationsProviderUnitTest.php index 5dac4bf..4c72a89 100644 --- a/core/tests/Drupal/Tests/Core/Entity/ConfigEntityOperationsProviderUnitTest.php +++ b/core/modules/views_ui/tests/Drupal/views_ui/ViewOperationsProviderUnitTest.php @@ -2,18 +2,54 @@ /** * @file - * Contains \Drupal\Tests\Core\EntityOperationsProviderUnitTest. + * Contains \Drupal\views_ui\Tests\ViewOperationsProviderUnitTest. */ -namespace Drupal\Tests\Core\Entity; +namespace Drupal\views_ui\Tests; -use Drupal\Core\Entity\EntityOperationsProvider; use Drupal\Tests\UnitTestCase; +use Drupal\views_ui\ViewOperationsProvider; + /** - * Tests \Drupal\Core\Entity\EntityOperationsProvider. + * Tests \Drupal\views_ui\ViewOperationsProvider. */ -class EntityOperationsProviderUnitTest extends UnitTestCase { +class ViewOperationsProviderUnitTest extends UnitTestCase { + + /** + * The module handler used for testing. + * + * @var \Drupal\Core\Extension\ModuleHandlerInterface + */ + protected $moduleHandler; + + /** + * The current user used for testing. + * + * @var \Drupal\Core\Session\AccountInterface + */ + protected $currentUser; + + /** + * The translation manager used for testing. + * + * @var \Drupal\Core\StringTranslation\TranslationManager + */ + protected $translationManager; + + /** + * The operations provider under test. + * + * @var \Drupal\Core\Config\Entity\ConfigEntityOperationsProvider + */ + protected $operationsProvider; + + /** + * The entity used for testing. + * + * @var \Drupal\Core\Config\Entity\ConfigEntityInterface + */ + protected $entity; /** * {@inheritdoc} @@ -21,8 +57,8 @@ class EntityOperationsProviderUnitTest extends UnitTestCase { public static function getInfo() { return array( 'description' => '', - 'group' => 'Configuration', - 'name' => '\Drupal\Core\Entity\EntityOperationsProvider', + 'group' => 'Views UI', + 'name' => '\Drupal\views_ui\ViewOperationsProvider', ); } @@ -48,7 +84,7 @@ public function setUp() { ->method('access') ->will($this->returnValue(TRUE)); - $this->operationsProvider = new EntityOperationsProvider($this->moduleHandler, $this->translationManager); + $this->operationsProvider = new ViewOperationsProvider($this->moduleHandler, $this->translationManager); } /** @@ -61,5 +97,7 @@ public function testGetOperations() { $this->assertInternalType('array', $operations['update']); $this->assertArrayHasKey('delete', $operations); $this->assertInternalType('array', $operations['delete']); + $this->assertArrayHasKey('clone', $operations); + $this->assertInternalType('array', $operations['clone']); } } diff --git a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityOperationsProviderUnitTest.php b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityOperationsProviderUnitTest.php new file mode 100644 index 0000000..86c7f9b --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityOperationsProviderUnitTest.php @@ -0,0 +1,116 @@ + '', + 'group' => 'Configuration', + 'name' => '\Drupal\Core\Config\Entity\ConfigEntityOperationsProvider', + ); + } + + /** + * {@inheritdoc} + */ + public function setUp() { + parent::setUp(); + + $this->moduleHandler = $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface'); + $this->moduleHandler->expects($this->any()) + ->method('invokeAll') + ->will($this->returnValue(array())); + + $this->currentUser = $this->getMock('\Drupal\Core\Session\AccountInterface'); + + $this->translationManager = $this->getMockBuilder('\Drupal\Core\StringTranslation\TranslationManager') + ->disableOriginalConstructor() + ->getMock(); + + $this->entity = $this->getMock('\Drupal\Core\Config\Entity\ConfigEntityInterface'); + $this->entity->expects($this->any()) + ->method('access') + ->will($this->returnValue(TRUE)); + $this->entity->expects($this->any()) + ->method('entityInfo') + ->will($this->returnValue(array( + 'entity_keys' => array( + 'status' => 'foo', + ), + ))); + + $this->operationsProvider = new ConfigEntityOperationsProvider($this->moduleHandler, $this->translationManager); + } + + /** + * Tests getOperations(). + */ + public function testGetOperations() { + $this->entity->expects($this->at(0)) + ->method('status') + ->will($this->returnValue(TRUE)); + $operations = $this->operationsProvider->getOperations($this->entity, $this->currentUser); + $this->assertInternalType('array', $operations); + $this->assertArrayHasKey('disable', $operations); + $this->assertInternalType('array', $operations['disable']); + + $this->entity->expects($this->at(1)) + ->method('status') + ->will($this->returnValue(FALSE)); + $operations = $this->operationsProvider->getOperations($this->entity, $this->currentUser); + $this->assertInternalType('array', $operations); + $this->assertArrayHasKey('enable', $operations); + $this->assertInternalType('array', $operations['enable']); + } +} diff --git a/core/tests/Drupal/Tests/Core/Entity/ConfigEntityOperationsProviderUnitTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityOperationsProviderUnitTest.php similarity index 68% rename from core/tests/Drupal/Tests/Core/Entity/ConfigEntityOperationsProviderUnitTest.php rename to core/tests/Drupal/Tests/Core/Entity/EntityOperationsProviderUnitTest.php index 5dac4bf..ad31297 100644 --- a/core/tests/Drupal/Tests/Core/Entity/ConfigEntityOperationsProviderUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/EntityOperationsProviderUnitTest.php @@ -16,12 +16,47 @@ class EntityOperationsProviderUnitTest extends UnitTestCase { /** + * The module handler used for testing. + * + * @var \Drupal\Core\Extension\ModuleHandlerInterface + */ + protected $moduleHandler; + + /** + * The current user used for testing. + * + * @var \Drupal\Core\Session\AccountInterface + */ + protected $currentUser; + + /** + * The translation manager used for testing. + * + * @var \Drupal\Core\StringTranslation\TranslationManager + */ + protected $translationManager; + + /** + * The operations provider under test. + * + * @var \Drupal\Core\Config\Entity\ConfigEntityOperationsProvider + */ + protected $operationsProvider; + + /** + * The entity used for testing. + * + * @var \Drupal\Core\Entity\EntityInterface + */ + protected $entity; + + /** * {@inheritdoc} */ public static function getInfo() { return array( 'description' => '', - 'group' => 'Configuration', + 'group' => 'Entity', 'name' => '\Drupal\Core\Entity\EntityOperationsProvider', ); } @@ -43,7 +78,7 @@ public function setUp() { ->disableOriginalConstructor() ->getMock(); - $this->entity = $this->getMock('\Drupal\Core\Config\Entity\ConfigEntityInterface'); + $this->entity = $this->getMock('\Drupal\Core\Entity\EntityInterface'); $this->entity->expects($this->any()) ->method('access') ->will($this->returnValue(TRUE));