Commit 6de66844 authored by Dries's avatar Dries

Issue #2256355 by tim.plunkett: Make block plugins usable outside the block entity context.

parent b69a7784
services:
plugin.manager.block:
class: Drupal\block\Plugin\Type\BlockManager
class: Drupal\block\BlockManager
arguments: ['@container.namespaces', '@cache.discovery', '@language_manager', '@module_handler', '@string_translation']
theme.negotiator.block.admin_demo:
class: Drupal\block\Theme\AdminDemoNegotiator
......
......@@ -8,12 +8,12 @@
namespace Drupal\custom_block\Plugin\Block;
use Drupal\block\BlockBase;
use Drupal\block\BlockManagerInterface;
use Drupal\Core\Entity\EntityManager;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\block\Plugin\Type\BlockManager;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
......@@ -31,7 +31,7 @@ class CustomBlockBlock extends BlockBase implements ContainerFactoryPluginInterf
/**
* The Plugin Block Manager.
*
* @var \Drupal\block\Plugin\Type\BlockManager.
* @var \Drupal\block\BlockManagerInterface.
*/
protected $blockManager;
......@@ -65,7 +65,7 @@ class CustomBlockBlock extends BlockBase implements ContainerFactoryPluginInterf
* The plugin ID for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\block\Plugin\Type\BlockManager
* @param \Drupal\block\BlockManagerInterface
* The Plugin Block Manager.
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager service.
......@@ -74,7 +74,7 @@ class CustomBlockBlock extends BlockBase implements ContainerFactoryPluginInterf
* @param \Drupal\Core\Session\AccountInterface $account
* The account for which view access should be checked.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, BlockManager $block_manager, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler, AccountInterface $account) {
public function __construct(array $configuration, $plugin_id, $plugin_definition, BlockManagerInterface $block_manager, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler, AccountInterface $account) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->blockManager = $block_manager;
......
......@@ -25,6 +25,18 @@
*/
abstract class BlockBase extends PluginBase implements BlockPluginInterface {
/**
* {@inheritdoc}
*/
public function label() {
if (!empty($this->configuration['label'])) {
return $this->configuration['label'];
}
$definition = $this->getPluginDefinition();
return $definition['admin_label'];
}
/**
* {@inheritdoc}
*/
......@@ -60,6 +72,7 @@ public function setConfiguration(array $configuration) {
*/
protected function baseConfigurationDefaults() {
return array(
'id' => $this->getPluginId(),
'label' => '',
'provider' => $this->pluginDefinition['provider'],
'label_display' => BlockInterface::BLOCK_LABEL_VISIBLE,
......@@ -126,7 +139,7 @@ public function buildConfigurationForm(array $form, array &$form_state) {
'#type' => 'textfield',
'#title' => $this->t('Title'),
'#maxlength' => 255,
'#default_value' => !empty($this->configuration['label']) ? $this->configuration['label'] : $definition['admin_label'],
'#default_value' => $this->label(),
'#required' => TRUE,
);
$form['label_display'] = array(
......
......@@ -7,7 +7,7 @@
namespace Drupal\block;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\block\BlockManagerInterface;
use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\String;
use Drupal\Core\Cache\Cache;
......@@ -50,7 +50,7 @@ class BlockListBuilder extends ConfigEntityListBuilder implements FormInterface
/**
* The block manager.
*
* @var \Drupal\Component\Plugin\PluginManagerInterface
* @var \Drupal\block\BlockManagerInterface
*/
protected $blockManager;
......@@ -61,10 +61,10 @@ class BlockListBuilder extends ConfigEntityListBuilder implements FormInterface
* The entity type definition.
* @param \Drupal\Core\Entity\EntityStorageInterface $storage
* The entity storage class.
* @param \Drupal\Component\Plugin\PluginManagerInterface $block_manager
* @param \Drupal\block\BlockManagerInterface $block_manager
* The block manager.
*/
public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, PluginManagerInterface $block_manager) {
public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, BlockManagerInterface $block_manager) {
parent::__construct($entity_type, $storage);
$this->blockManager = $block_manager;
......@@ -334,13 +334,7 @@ public function buildForm(array $form, array &$form_state) {
$form['place_blocks']['list']['#attributes']['class'][] = 'entity-meta';
// Sort the plugins first by category, then by label.
$plugins = $this->blockManager->getDefinitions();
uasort($plugins, function ($a, $b) {
if ($a['category'] != $b['category']) {
return strnatcasecmp($a['category'], $b['category']);
}
return strnatcasecmp($a['admin_label'], $b['admin_label']);
});
$plugins = $this->blockManager->getSortedDefinitions();
foreach ($plugins as $plugin_id => $plugin_definition) {
$category = String::checkPlain($plugin_definition['category']);
$category_key = 'category-' . $category;
......
......@@ -2,10 +2,10 @@
/**
* @file
* Contains \Drupal\block\Plugin\Type\BlockManager.
* Contains \Drupal\block\BlockManager.
*/
namespace Drupal\block\Plugin\Type;
namespace Drupal\block;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
......@@ -21,7 +21,8 @@
*
* @see \Drupal\block\BlockPluginInterface
*/
class BlockManager extends DefaultPluginManager {
class BlockManager extends DefaultPluginManager implements BlockManagerInterface {
use StringTranslationTrait;
/**
......@@ -32,7 +33,7 @@ class BlockManager extends DefaultPluginManager {
protected $moduleData;
/**
* Constructs a new \Drupal\block\Plugin\Type\BlockManager object.
* Constructs a new \Drupal\block\BlockManager object.
*
* @param \Traversable $namespaces
* An object that implements \Traversable which contains the root paths
......@@ -90,10 +91,7 @@ protected function getModuleName($module) {
}
/**
* Gets the names of all block categories.
*
* @return array
* An array of translated categories, sorted alphabetically.
* {@inheritdoc}
*/
public function getCategories() {
$categories = array_unique(array_values(array_map(function ($definition) {
......@@ -103,4 +101,19 @@ public function getCategories() {
return $categories;
}
/**
* {@inheritdoc}
*/
public function getSortedDefinitions() {
// Sort the plugins first by category, then by label.
$definitions = $this->getDefinitions();
uasort($definitions, function ($a, $b) {
if ($a['category'] != $b['category']) {
return strnatcasecmp($a['category'], $b['category']);
}
return strnatcasecmp($a['admin_label'], $b['admin_label']);
});
return $definitions;
}
}
<?php
/**
* @file
* Contains \Drupal\block\BlockManagerInterface.
*/
namespace Drupal\block;
/**
* Provides an interface for the discovery and instantiation of block plugins.
*/
interface BlockManagerInterface {
/**
* 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();
}
......@@ -23,6 +23,17 @@
*/
interface BlockPluginInterface extends ConfigurablePluginInterface, PluginFormInterface, PluginInspectionInterface, CacheableInterface {
/**
* Returns the user-facing block label.
*
* @todo Provide other specific label-related methods in
* https://drupal.org/node/2025649.
*
* @return string
* The block label.
*/
public function label();
/**
* Indicates whether the block should be shown.
*
......
......@@ -7,7 +7,7 @@
namespace Drupal\block\Controller;
use Drupal\block\Plugin\Type\BlockManager;
use Drupal\block\BlockManagerInterface;
use Drupal\Component\Utility\String;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
......@@ -22,17 +22,17 @@ class CategoryAutocompleteController implements ContainerInjectionInterface {
/**
* The block manager.
*
* @var \Drupal\block\Plugin\Type\BlockManager
* @var \Drupal\block\BlockManagerInterface
*/
protected $blockManager;
/**
* Constructs a new CategoryAutocompleteController.
*
* @param \Drupal\block\Plugin\Type\BlockManager $block_manager
* @param \Drupal\block\BlockManagerInterface $block_manager
* The block manager.
*/
public function __construct(BlockManager $block_manager) {
public function __construct(BlockManagerInterface $block_manager) {
$this->blockManager = $block_manager;
}
......
......@@ -44,6 +44,7 @@ public function testBlockInterface() {
'label' => 'Custom Display Message',
);
$expected_configuration = array(
'id' => 'test_block_instantiation',
'label' => 'Custom Display Message',
'provider' => 'block_test',
'label_display' => BlockInterface::BLOCK_LABEL_VISIBLE,
......
......@@ -99,6 +99,7 @@ protected function createTests() {
'region' => '-1',
'plugin' => 'test_html',
'settings' => array(
'id' => 'test_html',
'label' => '',
'provider' => 'block_test',
'label_display' => BlockInterface::BLOCK_LABEL_VISIBLE,
......
......@@ -37,9 +37,7 @@ public static function getInfo() {
}
public function setUp() {
$block_manager = $this->getMockBuilder('Drupal\block\Plugin\Type\BlockManager')
->disableOriginalConstructor()
->getMock();
$block_manager = $this->getMock('Drupal\block\BlockManagerInterface');
$block_manager->expects($this->any())
->method('getCategories')
->will($this->returnValue(array('Comment', 'Node', 'None & Such', 'User')));
......
......@@ -7,7 +7,7 @@
namespace Drupal\language\Form;
use Drupal\block\Plugin\Type\BlockManager;
use Drupal\block\BlockManagerInterface;
use Drupal\Component\Utility\String;
use Drupal\Component\Utility\Unicode;
use Drupal\Component\Utility\Xss;
......@@ -48,7 +48,7 @@ class NegotiationConfigureForm extends FormBase {
/**
* The block manager.
*
* @var \Drupal\block\Plugin\Type\BlockManager
* @var \Drupal\block\BlockManagerInterface
*/
protected $blockManager;
......@@ -61,10 +61,10 @@ class NegotiationConfigureForm extends FormBase {
* The language manager.
* @param \Drupal\language\LanguageNegotiatorInterface $negotiator
* The language negotiation methods manager.
* @param \Drupal\block\Plugin\Type\BlockManager $block_manager
* @param \Drupal\block\BlockManagerInterface $block_manager
* The block manager, or NULL if not available.
*/
public function __construct(ConfigFactoryInterface $config_factory, ConfigurableLanguageManagerInterface $language_manager, LanguageNegotiatorInterface $negotiator, BlockManager $block_manager = NULL) {
public function __construct(ConfigFactoryInterface $config_factory, ConfigurableLanguageManagerInterface $language_manager, LanguageNegotiatorInterface $negotiator, BlockManagerInterface $block_manager = NULL) {
$this->languageTypes = $config_factory->get('language.types');
$this->languageManager = $language_manager;
$this->negotiator = $negotiator;
......
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