diff --git a/core/modules/block/block.module b/core/modules/block/block.module index 18b9d27..70347b3 100644 --- a/core/modules/block/block.module +++ b/core/modules/block/block.module @@ -327,9 +327,7 @@ function _block_get_renderable_region($list = array()) { $key_components = explode('.', $key); $id = array_pop($key_components); $build[$key] = array( - '#block' => $block, - '#weight' => $block->get('weight'), - '#theme_wrappers' => array('block'), + '#entity' => $block, '#pre_render' => array('_block_get_renderable_block'), '#cache' => array( 'keys' => array($id, $block->get('module')), @@ -488,11 +486,12 @@ function block_load($entity_id) { * A renderable array. */ function _block_get_renderable_block($element) { - $block = $element['#block']; + $block = $element['#entity']; // Don't bother to build blocks that aren't accessible. if ($element['#access'] = $block->access()) { $element += entity_view($block, 'block'); } + unset($element['#entity']); return $element; } @@ -534,7 +533,7 @@ function block_rebuild() { function template_preprocess_block(&$variables) { $block_counter = &drupal_static(__FUNCTION__, array()); - $variables['block'] = (object) $variables['elements']['#block_config']; + $variables['block'] = (object) $variables['elements']['#block']; // All blocks get an independent counter for each region. if (!isset($block_counter[$variables['block']->region])) { @@ -565,13 +564,13 @@ function template_preprocess_block(&$variables) { // We can safely explode on : because we know the Block plugin type manager // enforces that delimiter for all derivatives. - $parts = explode(':', $variables['elements']['#block']->get('plugin')); + $parts = explode(':', $variables['elements']['#block']->plugin); $suggestion = 'block'; while ($part = array_shift($parts)) { $variables['theme_hook_suggestions'][] = $suggestion .= '__' . strtr($part, '-', '_'); } // Create a valid HTML ID and make sure it is unique. - if ($id = $variables['elements']['#block']->id()) { + if ($id = $variables['elements']['#block']->id) { $config_id = explode('.', $id); $machine_name = array_pop($config_id); $variables['block_html_id'] = drupal_html_id('block-' . $machine_name); diff --git a/core/modules/block/custom_block/custom_block.module b/core/modules/block/custom_block/custom_block.module index a3ce18c..ec678d8 100644 --- a/core/modules/block/custom_block/custom_block.module +++ b/core/modules/block/custom_block/custom_block.module @@ -8,7 +8,7 @@ use Drupal\custom_block\Plugin\Core\Entity\CustomBlockType; use Drupal\custom_block\Plugin\Core\Entity\CustomBlock; use Drupal\custom_block\Plugin\block\block\CustomBlockBlock; -use Drupal\block\Plugin\Core\Entity\Block; +use Drupal\block\BlockInterface; /** * Implements hook_menu_local_tasks(). @@ -292,9 +292,9 @@ function custom_block_admin_paths() { /** * Implements hook_block_view_alter(). */ -function custom_block_block_view_alter(array &$build, Block $block) { +function custom_block_block_view_alter(array &$build, BlockInterface $block) { // Add contextual links for custom blocks. - if ($block->getPlugin() instanceof CustomBlockBlock) { + if ($block instanceof CustomBlockBlock) { // Move contextual links from inner content to outer wrapper. $build['#contextual_links']['custom_block'] = $build['content']['#contextual_links']['custom_block']; unset($build['content']['#contextual_links']['custom_block']); diff --git a/core/modules/block/lib/Drupal/block/BlockBase.php b/core/modules/block/lib/Drupal/block/BlockBase.php index 9c90a5a..a043db5 100644 --- a/core/modules/block/lib/Drupal/block/BlockBase.php +++ b/core/modules/block/lib/Drupal/block/BlockBase.php @@ -9,7 +9,6 @@ use Drupal\Component\Plugin\PluginBase; use Drupal\block\Plugin\Core\Entity\Block; -use Drupal\Component\Plugin\Discovery\DiscoveryInterface; /** * Defines a base block implementation that most blocks plugins will extend. @@ -21,22 +20,6 @@ abstract class BlockBase extends PluginBase implements BlockInterface { /** - * The entity using this plugin. - * - * @var \Drupal\block\Plugin\Core\Entity\Block - */ - protected $entity; - - /** - * Overrides \Drupal\Component\Plugin\PluginBase::__construct(). - */ - public function __construct(array $configuration, $plugin_id, DiscoveryInterface $discovery, Block $entity) { - parent::__construct($configuration, $plugin_id, $discovery); - - $this->entity = $entity; - } - - /** * Returns plugin-specific settings for the block. * * Block plugins only need to override this method if they override the @@ -142,7 +125,7 @@ public function access() { global $user; // Deny access to disabled blocks. - if (!$this->entity->get('status')) { + if (!$this->configuration['status']) { return FALSE; } @@ -150,7 +133,7 @@ public function access() { // If a block has no roles associated, it is displayed for every role. // For blocks with roles associated, if none of the user's roles matches // the settings from this block, access is denied. - $visibility = $this->entity->get('visibility'); + $visibility = $this->configuration['visibility']; if (!empty($visibility['role']['roles']) && !array_intersect(array_filter($visibility['role']['roles']), array_keys($user->roles))) { // No match. return FALSE; @@ -202,7 +185,7 @@ public function access() { // Check other modules for block access rules. foreach (module_implements('block_access') as $module) { - if (module_invoke($module, 'block_access', $this->entity) === FALSE) { + if (module_invoke($module, 'block_access', $this) === FALSE) { return FALSE; } } @@ -489,4 +472,28 @@ public function submit($form, &$form_state) { */ public function blockSubmit($form, &$form_state) {} + public function buildBlock() { + $build = array(); + if ($content = $this->build()) { + $build = array( + '#block' => (object) $this->getConfig(), + '#theme_wrappers' => array('block'), + '#block_config' => array( + 'id' => $this->configuration['plugin'], + 'region' => $this->configuration['region'], + 'module' => $this->configuration['module'], + 'label' => check_plain($this->configuration['label']), + ), + ); + // Label needs special handling. + $build['#block']->label = check_plain($this->configuration['label']); + $build['content'] = $content; + } + + // All blocks, even when empty, should be available for altering. + $id = str_replace(':', '__', $this->configuration['plugin']); + drupal_alter(array('block_view', "block_view_$id"), $build, $this); + return $build; + } + } diff --git a/core/modules/block/lib/Drupal/block/BlockRenderController.php b/core/modules/block/lib/Drupal/block/BlockRenderController.php index e1c560e..04dd49b 100644 --- a/core/modules/block/lib/Drupal/block/BlockRenderController.php +++ b/core/modules/block/lib/Drupal/block/BlockRenderController.php @@ -23,42 +23,6 @@ public function buildContent(array $entities, array $displays, $view_mode, $lang } /** - * Provides entity-specific defaults to the build process. - * - * @param Drupal\Core\Entity\EntityInterface $entity - * The entity for which the defaults should be provided. - * @param string $view_mode - * The view mode that should be used. - * @param string $langcode - * (optional) For which language the entity should be prepared, defaults to - * the current content language. - * - * @return array - * An array of defaults to add into the entity render array. - */ - protected function getBuildDefaults(EntityInterface $entity, $view_mode, $langcode) { - // @todo \Drupal\block\Tests\BlockTest::testCustomBlock() assuemes that a - // block can be rendered without any of its wrappers. To do so, it uses a - // custom view mode, and we choose to only add the wrappers on the default - // view mode, 'block'. - if ($view_mode != 'block') { - return array(); - } - - return array( - '#block' => $entity, - '#weight' => $entity->get('weight'), - '#theme_wrappers' => array('block'), - '#block_config' => array( - 'id' => $entity->get('plugin'), - 'region' => $entity->get('region'), - 'module' => $entity->get('module'), - 'label' => check_plain($entity->label()), - ), - ); - } - - /** * Implements Drupal\Core\Entity\EntityRenderControllerInterface::view(). */ public function view(EntityInterface $entity, $view_mode = 'full', $langcode = NULL) { @@ -73,15 +37,12 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la $build = array(); foreach ($entities as $entity_id => $entity) { // Allow blocks to be empty, do not add in the defaults. - if ($content = $entity->getPlugin()->build()) { - $build[$entity_id] = $this->getBuildDefaults($entity, $view_mode, $langcode); - } - $build[$entity_id]['content'] = $content; + $build[$entity_id] = $entity->getPlugin()->buildBlock(); + $build[$entity_id]['#weight'] = $entity->get('weight'); - // All blocks, even when empty, should be available for altering. - $id = str_replace(':', '__', $entity->get('plugin')); - list(, $name) = $entity->id(); - drupal_alter(array('block_view', "block_view_$id", "block_view_$name"), $build[$entity_id], $entity); + list(, $name) = explode('.', $entity->id()); + $plugin = $entity->getPlugin(); + drupal_alter(array("block_view_$name"), $build[$entity_id], $plugin); } return $build; diff --git a/core/modules/block/lib/Drupal/block/Plugin/Core/Entity/Block.php b/core/modules/block/lib/Drupal/block/Plugin/Core/Entity/Block.php index 75d82e8..a06d5d5 100644 --- a/core/modules/block/lib/Drupal/block/Plugin/Core/Entity/Block.php +++ b/core/modules/block/lib/Drupal/block/Plugin/Core/Entity/Block.php @@ -123,8 +123,16 @@ public function getPlugin() { // Create a plugin instance and store its configuration as settings. try { - $this->instance = drupal_container()->get('plugin.manager.block')->createInstance($this->plugin, $this->settings, $this); - $this->settings += $this->instance->getConfig(); + $properties = $this->getExportProperties(); + unset($properties['settings']); + $this->instance = drupal_container()->get('plugin.manager.block')->createInstance($this->plugin); + $this->instance->getConfig(); + foreach ($properties as $key => $value) { + $this->instance->setConfig($key, $value); + } + foreach ($this->settings as $key => $value) { + $this->instance->setConfig($key, $value); + } } catch (PluginException $e) { // Ignore blocks belonging to disabled modules, but re-throw valid @@ -138,6 +146,14 @@ public function getPlugin() { } /** + * Overrides \Drupal\Core\Entity\EntityInterface::label(). + */ + public function label($langcode = NULL) { + $configuration = $this->getPlugin()->getConfig(); + return $configuration['label']; + } + + /** * Overrides \Drupal\Core\Entity\Entity::uri(); */ public function uri() { @@ -159,14 +175,42 @@ public function get($property_name, $langcode = NULL) { if ($property_name == 'theme' && !$value) { list($value) = explode('.', $this->id()); } + elseif (!in_array($property_name, $this->exportProperties())) { + // Support geting plugin specific settings with the get() method. + $settings = parent::get('settings'); + if (isset($settings[$property_name])) { + $value = $settings[$property_name]; + } + } return $value; } /** - * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::getExportProperties(); + * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::set(); */ - public function getExportProperties() { - $names = array( + public function set($property_name, $value) { + if (!in_array($property_name, $this->exportProperties()) && $property_name != 'settings') { + $settings = $this->get('settings'); + $settings[$property_name] = $value; + $this->getPlugin()->setConfig($property_name, $value); + parent::set('settings', $settings); + } + elseif ($property_name == 'settings' && is_array($value)) { + $settings = $this->get('settings'); + foreach ($value as $key => $key_value) { + $this->getPlugin()->setConfig($key, $key_value); + $settings[$key] = $key_value; + } + parent::set('settings', $settings); + } + else { + $this->getPlugin()->setConfig($property_name, $value); + parent::set($property_name, $value); + } + } + + protected function exportProperties() { + return array( 'id', 'label', 'uuid', @@ -179,11 +223,25 @@ public function getExportProperties() { 'settings', 'langcode', ); + } + + /** + * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::getExportProperties(); + */ + public function getExportProperties() { $properties = array(); - foreach ($names as $name) { + foreach ($this->exportProperties() as $name) { $properties[$name] = $this->get($name); } return $properties; } + /** + * Implements \Drupal\Core\Entity\EntityInterface::save(). + */ + public function save() { + $this->settings = array_diff_key($this->getPlugin()->getConfig(), $this->getExportProperties()); + return parent::save(); + } + } diff --git a/core/modules/block/lib/Drupal/block/Plugin/Type/BlockManager.php b/core/modules/block/lib/Drupal/block/Plugin/Type/BlockManager.php index d5dedb9..228f3db 100644 --- a/core/modules/block/lib/Drupal/block/Plugin/Type/BlockManager.php +++ b/core/modules/block/lib/Drupal/block/Plugin/Type/BlockManager.php @@ -35,14 +35,7 @@ public function __construct(array $namespaces) { $this->discovery = new DerivativeDiscoveryDecorator($this->discovery); $this->discovery = new AlterDecorator($this->discovery, 'block'); $this->discovery = new CacheDecorator($this->discovery, 'block_plugins:' . language(LANGUAGE_TYPE_INTERFACE)->langcode, 'cache_block', CacheBackendInterface::CACHE_PERMANENT, array('block')); - } - - /** - * Overrides \Drupal\Component\Plugin\PluginManagerBase::createInstance(). - */ - public function createInstance($plugin_id, array $configuration = array(), Block $entity = NULL) { - $plugin_class = DefaultFactory::getPluginClass($plugin_id, $this->discovery); - return new $plugin_class($configuration, $plugin_id, $this->discovery, $entity); + $this->factory = new DefaultFactory($this); } } diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockTemplateSuggestionsUnitTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockTemplateSuggestionsUnitTest.php index d707c80..9caf4e1 100644 --- a/core/modules/block/lib/Drupal/block/Tests/BlockTemplateSuggestionsUnitTest.php +++ b/core/modules/block/lib/Drupal/block/Tests/BlockTemplateSuggestionsUnitTest.php @@ -44,12 +44,7 @@ function testBlockThemeHookSuggestions() { )); $variables = array(); - $variables['elements']['#block'] = $block; - $variables['elements']['#block_config'] = $block->getPlugin()->getConfig() + array( - 'id' => $block->get('plugin'), - 'region' => $block->get('region'), - 'module' => $block->get('module'), - ); + $variables['elements'] = $block->getPlugin()->buildBlock(); $variables['elements']['#children'] = ''; // Test adding a class to the block content. $variables['content_attributes']['class'][] = 'test-class'; diff --git a/core/modules/menu/menu.module b/core/modules/menu/menu.module index c300ed6..8b066a3 100644 --- a/core/modules/menu/menu.module +++ b/core/modules/menu/menu.module @@ -12,7 +12,7 @@ */ use Drupal\node\Plugin\Core\Entity\Node; -use Drupal\block\Plugin\Core\Entity\Block; +use Drupal\block\BlockInterface; use Drupal\system\Plugin\Core\Entity\Menu; use Drupal\system\Plugin\block\block\SystemMenuBlock; use Symfony\Component\HttpFoundation\JsonResponse; @@ -411,9 +411,9 @@ function _menu_parents_recurse($tree, $menu_name, $indent, &$options, $exclude, /** * Implements hook_block_view_alter(). */ -function menu_block_view_alter(array &$build, Block $block) { +function menu_block_view_alter(array &$build, BlockInterface $block) { // Add contextual links for system menu blocks. - if ($block->getPlugin() instanceof SystemMenuBlock) { + if ($block instanceof SystemMenuBlock) { foreach (element_children($build['content']) as $key) { $build['#contextual_links']['menu'] = array('admin/structure/menu/manage', array($build['content'][$key]['#original_link']['menu_name'])); } diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 8019ff3..a668c61 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -2029,7 +2029,8 @@ function node_form_block_form_alter(&$form, &$form_state) { * if the visibility conditions are not met. */ function node_block_access($block) { - $visibility = $block->get('visibility'); + $configuration = $block->getConfig(); + $visibility = $configuration['visibility']; if (!empty($visibility)) { $allowed_types = array(); $node = menu_get_object(); diff --git a/core/modules/openid/openid.module b/core/modules/openid/openid.module index 6d31124..1eb27e9 100644 --- a/core/modules/openid/openid.module +++ b/core/modules/openid/openid.module @@ -5,6 +5,8 @@ * Implement OpenID Relying Party support for Drupal */ +use Drupal\block\BlockInterface; + /** * Implements hook_menu(). */ @@ -158,13 +160,13 @@ function openid_user_logout($account) { } /** - * Implements hook_block_view_MODULE_DELTA_alter(). + * Implements hook_block_view_ID_alter(). * * Adds the OpenID login form to the user login block. * * @see \Drupal\user\Plugin\block\block\UserLoginBlock */ -function openid_block_view_user_login_block_alter(&$build, $block) { +function openid_block_view_user_login_block_alter(&$build, BlockInterface $block) { // Only alter the block when it is non-empty, i.e. when no user is logged in. if (!isset($build['content']['user_login_form'])) { return; diff --git a/core/modules/overlay/overlay.module b/core/modules/overlay/overlay.module index cc29255..3ff93fe 100644 --- a/core/modules/overlay/overlay.module +++ b/core/modules/overlay/overlay.module @@ -486,7 +486,8 @@ function overlay_block_access($block) { // reason for duplicating effort here is performance; we do not even want // these blocks to be built if they are not going to be displayed. if ($regions_to_render = overlay_get_regions_to_render()) { - if (!in_array($block->get('region'), $regions_to_render)) { + $configuration = $block->getConfig(); + if (!in_array($configuration['region'], $regions_to_render)) { return FALSE; } } diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 677e5ca..d04d0de 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -2637,7 +2637,7 @@ function system_preprocess_block(&$variables) { // System menu blocks should get the same class as menu module blocks. default: - if ($variables['elements']['#block']->getPlugin() instanceof SystemMenuBlock) { + if ($variables['elements']['#block']->plugin == 'system_main_block') { $variables['attributes_array']['role'] = 'navigation'; $variables['classes_array'][] = 'block-menu'; } diff --git a/core/modules/views/lib/Drupal/views/Plugin/block/block/ViewsBlock.php b/core/modules/views/lib/Drupal/views/Plugin/block/block/ViewsBlock.php index 4dbb64d..53beee4 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/block/block/ViewsBlock.php +++ b/core/modules/views/lib/Drupal/views/Plugin/block/block/ViewsBlock.php @@ -42,8 +42,8 @@ class ViewsBlock extends BlockBase { /** * Overrides \Drupal\Component\Plugin\PluginBase::__construct(). */ - public function __construct(array $configuration, $plugin_id, DiscoveryInterface $discovery, Block $entity) { - parent::__construct($configuration, $plugin_id, $discovery, $entity); + public function __construct(array $configuration, $plugin_id, DiscoveryInterface $discovery) { + parent::__construct($configuration, $plugin_id, $discovery); list($plugin, $delta) = explode(':', $this->getPluginId()); list($name, $this->displayID) = explode('-', $delta, 2); @@ -77,7 +77,7 @@ public function form($form, &$form_state) { public function build() { $output = $this->view->executeDisplay($this->displayID); // Set the label to the title configured in the view. - $this->entity->set('label', filter_xss_admin($this->view->getTitle())); + $this->configuration['label'] = filter_xss_admin($this->view->getTitle()); // Before returning the block output, convert it to a renderable array // with contextual links. $this->addContextualLinks($output);