diff --git a/core/lib/Drupal/Component/Plugin/CategorizingPluginManagerInterface.php b/core/lib/Drupal/Component/Plugin/CategorizingPluginManagerInterface.php new file mode 100644 index 0000000..65578b3 --- /dev/null +++ b/core/lib/Drupal/Component/Plugin/CategorizingPluginManagerInterface.php @@ -0,0 +1,46 @@ +getModuleName($definition['provider']); - } - } - - /** - * Gets the name of the module. - * - * @param string $module - * The machine name of a module. - * - * @return string - * The human-readable module name if it exists, otherwise the - * machine-readable module name. - */ - protected function getModuleName($module) { - // Gather module data. - if (!isset($this->moduleData)) { - $this->moduleData = system_get_info('module'); - } - // If the module exists, return its human-readable name. - if (isset($this->moduleData[$module])) { - return $this->t($this->moduleData[$module]['name']); - } - // Otherwise, return the machine name. - return $module; + $this->processDefinitionCategory($definition); } /** * {@inheritdoc} */ - public function getCategories() { - $categories = array_unique(array_values(array_map(function ($definition) { - return $definition['category']; - }, $this->getDefinitions()))); - natcasesort($categories); - return $categories; + public function getSortedDefinitions(array $definitions = NULL) { + // Sort the plugins first by category, then by label. + $definitions = $this->traitGetSortedDefinitions($definitions, 'admin_label'); + // Do not display the 'broken' plugin in the UI. + unset($definitions['broken']); + return $definitions; } /** * {@inheritdoc} */ - public function getSortedDefinitions() { - // Sort the plugins first by category, then by label. - $definitions = $this->getDefinitionsForContexts(); - uasort($definitions, function ($a, $b) { - if ($a['category'] != $b['category']) { - return strnatcasecmp($a['category'], $b['category']); - } - return strnatcasecmp($a['admin_label'], $b['admin_label']); - }); + public function getGroupedDefinitions(array $definitions = NULL) { + $definitions = $this->traitGetGroupedDefinitions($definitions); // Do not display the 'broken' plugin in the UI. - unset($definitions['broken']); + unset($definitions[$this->t('Block')]['broken']); return $definitions; } diff --git a/core/lib/Drupal/Core/Block/BlockManagerInterface.php b/core/lib/Drupal/Core/Block/BlockManagerInterface.php index 2fa8611..592a9a3 100644 --- a/core/lib/Drupal/Core/Block/BlockManagerInterface.php +++ b/core/lib/Drupal/Core/Block/BlockManagerInterface.php @@ -7,27 +7,12 @@ namespace Drupal\Core\Block; +use Drupal\Component\Plugin\CategorizingPluginManagerInterface; use Drupal\Core\Plugin\Context\ContextAwarePluginManagerInterface; /** * Provides an interface for the discovery and instantiation of block plugins. */ -interface BlockManagerInterface extends ContextAwarePluginManagerInterface { - - /** - * Gets the names of all block categories. - * - * @return array - * An array of translated categories, sorted alphabetically. - */ - public function getCategories(); - - /** - * Gets the sorted definitions. - * - * @return array - * An array of plugin definitions, sorted by category and admin label. - */ - public function getSortedDefinitions(); +interface BlockManagerInterface extends ContextAwarePluginManagerInterface, CategorizingPluginManagerInterface { } diff --git a/core/lib/Drupal/Core/Condition/Annotation/Condition.php b/core/lib/Drupal/Core/Condition/Annotation/Condition.php index 55834d0..d796865 100644 --- a/core/lib/Drupal/Core/Condition/Annotation/Condition.php +++ b/core/lib/Drupal/Core/Condition/Annotation/Condition.php @@ -59,4 +59,13 @@ class Condition extends Plugin { */ public $condition = array(); + /** + * The category under which the condition should listed in the UI. + * + * @var \Drupal\Core\Annotation\Translation + * + * @ingroup plugin_translatable + */ + public $category; + } diff --git a/core/lib/Drupal/Core/Condition/ConditionManager.php b/core/lib/Drupal/Core/Condition/ConditionManager.php index c1e309a..809f28f 100644 --- a/core/lib/Drupal/Core/Condition/ConditionManager.php +++ b/core/lib/Drupal/Core/Condition/ConditionManager.php @@ -7,10 +7,12 @@ namespace Drupal\Core\Condition; +use Drupal\Component\Plugin\CategorizingPluginManagerInterface; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Executable\ExecutableManagerInterface; use Drupal\Core\Executable\ExecutableInterface; use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Plugin\CategorizingPluginManagerTrait; use Drupal\Core\Plugin\Context\ContextAwarePluginManagerTrait; use Drupal\Core\Plugin\DefaultPluginManager; @@ -23,8 +25,9 @@ * * @ingroup plugin_api */ -class ConditionManager extends DefaultPluginManager implements ExecutableManagerInterface { +class ConditionManager extends DefaultPluginManager implements ExecutableManagerInterface, CategorizingPluginManagerInterface { + use CategorizingPluginManagerTrait; use ContextAwarePluginManagerTrait; /** diff --git a/core/lib/Drupal/Core/Plugin/CategorizingPluginManagerTrait.php b/core/lib/Drupal/Core/Plugin/CategorizingPluginManagerTrait.php new file mode 100644 index 0000000..62b5fa7 --- /dev/null +++ b/core/lib/Drupal/Core/Plugin/CategorizingPluginManagerTrait.php @@ -0,0 +1,112 @@ +getModuleName($definition['provider']); + } + } + + /** + * Gets the name of the module. + * + * @param string $module + * The machine name of a module. + * + * @return string + * The human-readable module name if it exists, otherwise the + * machine-readable module name. + */ + protected function getModuleName($module) { + // Gather module data. + if (!isset($this->moduleData)) { + $this->moduleData = system_get_info('module'); + } + // If the module exists, return its human-readable name. + if (isset($this->moduleData[$module])) { + return $this->t($this->moduleData[$module]['name']); + } + // Otherwise, return the machine name. + return $module; + } + + /** + * Implements \Drupal\Component\Plugin\CategorizingPluginManagerInterface::getCategories(). + */ + public function getCategories() { + /** @var \Drupal\Core\Plugin\CategorizingPluginManagerTrait|\Drupal\Component\Plugin\PluginManagerInterface $this */ + $categories = array_unique(array_values(array_map(function ($definition) { + return $definition['category']; + }, $this->getDefinitions()))); + natcasesort($categories); + return $categories; + } + + /** + * Implements \Drupal\Component\Plugin\CategorizingPluginManagerInterface::getSortedDefinitions(). + */ + public function getSortedDefinitions(array $definitions = NULL, $label_key = 'label') { + // Sort the plugins first by category, then by label. + /** @var \Drupal\Core\Plugin\CategorizingPluginManagerTrait|\Drupal\Component\Plugin\PluginManagerInterface $this */ + $definitions = isset($definitions) ? $definitions : $this->getDefinitions(); + uasort($definitions, function ($a, $b) use ($label_key) { + if ($a['category'] != $b['category']) { + return strnatcasecmp($a['category'], $b['category']); + } + return strnatcasecmp($a[$label_key], $b[$label_key]); + }); + return $definitions; + } + + /** + * Implements \Drupal\Component\Plugin\CategorizingPluginManagerInterface::getGroupedDefinitions(). + */ + public function getGroupedDefinitions(array $definitions = NULL) { + /** @var \Drupal\Core\Plugin\CategorizingPluginManagerTrait|\Drupal\Component\Plugin\PluginManagerInterface $this */ + $definitions = isset($definitions) ? $definitions : $this->getDefinitions(); + $grouped_definitions = array(); + foreach ($definitions as $id => $definition) { + $grouped_definitions[$definition['category']][$id] = $definition; + } + return $grouped_definitions; + } + +} diff --git a/core/modules/block/src/BlockListBuilder.php b/core/modules/block/src/BlockListBuilder.php index e5da65d..d4a8a99 100644 --- a/core/modules/block/src/BlockListBuilder.php +++ b/core/modules/block/src/BlockListBuilder.php @@ -333,9 +333,10 @@ public function buildForm(array $form, FormStateInterface $form_state) { $form['place_blocks']['list']['#type'] = 'container'; $form['place_blocks']['list']['#attributes']['class'][] = 'entity-meta'; - // Sort the plugins first by category, then by label. - $plugins = $this->blockManager->getSortedDefinitions(); - foreach ($plugins as $plugin_id => $plugin_definition) { + // Only add blocks which work without any available context. + $definitions = $this->blockManager->getDefinitionsForContexts(); + $sorted_definitions = $this->blockManager->getSortedDefinitions($definitions); + foreach ($sorted_definitions as $plugin_id => $plugin_definition) { $category = String::checkPlain($plugin_definition['category']); $category_key = 'category-' . $category; if (!isset($form['place_blocks']['list'][$category_key])) {