diff --git a/core/lib/Drupal/Component/Plugin/CategorizingPluginManagerInterface.php b/core/lib/Drupal/Component/Plugin/CategorizingPluginManagerInterface.php index 01f7eaf..bb9df77 100644 --- a/core/lib/Drupal/Component/Plugin/CategorizingPluginManagerInterface.php +++ b/core/lib/Drupal/Component/Plugin/CategorizingPluginManagerInterface.php @@ -32,7 +32,10 @@ public function getCategories(); public function getSortedDefinitions(array $definitions = NULL); /** - * Gets definitions grouped by category. + * Gets sorted definitions grouped by category. + * + * In addition to grouping, both categories and its entries are sorted, + * whereas definitions are sorted by label. * * @param array[]|null $definitions * (optional) The definitions to group. If omitted, all definitions are diff --git a/core/lib/Drupal/Core/Block/BlockManager.php b/core/lib/Drupal/Core/Block/BlockManager.php index f87485e..086016d 100644 --- a/core/lib/Drupal/Core/Block/BlockManager.php +++ b/core/lib/Drupal/Core/Block/BlockManager.php @@ -70,7 +70,7 @@ public function getSortedDefinitions(array $definitions = NULL) { * {@inheritdoc} */ public function getGroupedDefinitions(array $definitions = NULL) { - $definitions = $this->traitGetGroupedDefinitions($definitions); + $definitions = $this->traitGetGroupedDefinitions($definitions, 'admin_label'); // Do not display the 'broken' plugin in the UI. unset($definitions[$this->t('Block')]['broken']); return $definitions; diff --git a/core/lib/Drupal/Core/Plugin/CategorizingPluginManagerTrait.php b/core/lib/Drupal/Core/Plugin/CategorizingPluginManagerTrait.php index 4450deb..5a608e6 100644 --- a/core/lib/Drupal/Core/Plugin/CategorizingPluginManagerTrait.php +++ b/core/lib/Drupal/Core/Plugin/CategorizingPluginManagerTrait.php @@ -39,8 +39,10 @@ * The plugin definition. */ protected function processDefinitionCategory(&$definition) { - // Ensure that every block has a category. + // Ensure that every plugin has a category. if (empty($definition['category'])) { + // Default to the human readable module name if the provider is a module; + // otherwise the provider machine name is used. $definition['category'] = $this->getModuleName($definition['provider']); } } @@ -99,9 +101,9 @@ public function getSortedDefinitions(array $definitions = NULL, $label_key = 'la /** * Implements \Drupal\Component\Plugin\CategorizingPluginManagerInterface::getGroupedDefinitions(). */ - public function getGroupedDefinitions(array $definitions = NULL) { + public function getGroupedDefinitions(array $definitions = NULL, $label_key = 'label') { /** @var \Drupal\Core\Plugin\CategorizingPluginManagerTrait|\Drupal\Component\Plugin\PluginManagerInterface $this */ - $definitions = isset($definitions) ? $definitions : $this->getDefinitions(); + $definitions = $this->getSortedDefinitions(isset($definitions) ? $definitions : $this->getDefinitions(), $label_key); $grouped_definitions = array(); foreach ($definitions as $id => $definition) { $grouped_definitions[$definition['category']][$id] = $definition; diff --git a/core/tests/Drupal/Tests/Core/Plugin/CategorizingPluginManagerTraitTest.php b/core/tests/Drupal/Tests/Core/Plugin/CategorizingPluginManagerTraitTest.php new file mode 100644 index 0000000..65703b6 --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Plugin/CategorizingPluginManagerTraitTest.php @@ -0,0 +1,151 @@ +pluginManager = new CategorizingPluginManagerImpl(); + $this->pluginManager->setStringTranslation($this->getStringTranslationStub()); + } + + /** + * @covers ::getCategories + */ + public function testGetCategories() { + $this->assertSame(array_values($this->pluginManager->getCategories()), [ + 'fruits', + 'vegetables' + ]); + } + + /** + * @covers ::getSortedDefinitions + */ + public function testGetSortedDefinitions() { + $sorted = $this->pluginManager->getSortedDefinitions(); + $this->assertSame(array_keys($sorted), ['apple', 'mango', 'cucumber']); + } + + /** + * @covers ::getGroupedDefinitions + */ + public function testGetGroupedDefinitions() { + $grouped = $this->pluginManager->getGroupedDefinitions(); + $this->assertSame(array_keys($grouped), ['fruits', 'vegetables']); + $this->assertSame(array_keys($grouped['fruits']), ['apple', 'mango']); + $this->assertSame(array_keys($grouped['vegetables']), ['cucumber']); + } + + /** + * @covers ::processDefinitionCategory + */ + public function testProcessDefinitionCategory() { + // Existing category. + $definition = array( + 'label' => 'some', + 'provider' => 'core', + 'category' => 'bag', + ); + $this->pluginManager->processDefinition($definition, 'some'); + $this->assertSame($definition['category'], 'bag'); + + // No category, provider without label. + $definition = array( + 'label' => 'some', + 'provider' => 'core', + ); + $this->pluginManager->processDefinition($definition, 'some'); + $this->assertSame($definition['category'], 'core'); + + // No category, provider is module with label. + $definition = array( + 'label' => 'some', + 'provider' => 'node', + ); + $this->pluginManager->processDefinition($definition, 'some'); + $this->assertSame($definition['category'], 'Node'); + } + } + + /** + * Class that allows testing the trait. + */ + class CategorizingPluginManagerImpl extends DefaultPluginManager implements CategorizingPluginManagerInterface { + + use CategorizingPluginManagerTrait; + + /** + * Replace the constructor so we can instantiate a stub. + */ + public function __construct() { + } + + /** + * Implements getDefinitions() for the trait to provide some test definitions. + * + * @return array + */ + public function getDefinitions() { + return [ + 'cucumber' => array( + 'label' => 'cucumber', + 'category' => 'vegetables', + ), + 'apple' => array( + 'label' => 'apple', + 'category' => 'fruits', + ), + 'mango' => array( + 'label' => 'mango', + 'category' => 'fruits', + ), + ]; + } + + /** + * {@inheritdoc} + */ + public function processDefinition(&$definition, $plugin_id) { + parent::processDefinition($definition, $plugin_id); + $this->processDefinitionCategory($definition); + } + } +} + +namespace { + + /** + * "Mocks" system_get_info() as needed for the test. + */ + if (!function_exists('system_get_info')) { + + function system_get_info($type, $name = NULL) { + return array('node' => array('name' => 'Node')); + } + } +}