diff --git a/core/modules/aggregator/aggregator.module b/core/modules/aggregator/aggregator.module index 1a5ed47..25265f4 100644 --- a/core/modules/aggregator/aggregator.module +++ b/core/modules/aggregator/aggregator.module @@ -547,7 +547,7 @@ function aggregator_filter_xss($value) { * Implements hook_preprocess_HOOK() for block.tpl.php. */ function aggregator_preprocess_block(&$variables) { - if ($variables['block']->module == 'aggregator') { + if ($variables['configuration']['module'] == 'aggregator') { $variables['attributes']['role'] = 'complementary'; } } diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/Block/AggregatorCategoryBlock.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/Block/AggregatorCategoryBlock.php index d7af2b3..b9971ce 100644 --- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/Block/AggregatorCategoryBlock.php +++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/Block/AggregatorCategoryBlock.php @@ -34,9 +34,9 @@ public function settings() { } /** - * Overrides \Drupal\block\BlockBase::blockAccess(). + * Overrides \Drupal\block\BlockBase::access(). */ - public function blockAccess() { + public function access() { // Only grant access to users with the 'access news feeds' permission. return user_access('access news feeds'); } diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/Block/AggregatorFeedBlock.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/Block/AggregatorFeedBlock.php index 4ffa57a..b72936b 100644 --- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/Block/AggregatorFeedBlock.php +++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/Block/AggregatorFeedBlock.php @@ -34,9 +34,9 @@ public function settings() { } /** - * Overrides \Drupal\block\BlockBase::blockAccess(). + * Overrides \Drupal\block\BlockBase::access(). */ - public function blockAccess() { + public function access() { // Only grant access to users with the 'access news feeds' permission. return user_access('access news feeds'); } diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Tests/AggregatorRenderingTest.php b/core/modules/aggregator/lib/Drupal/aggregator/Tests/AggregatorRenderingTest.php index 1c6056d..b60dde4 100644 --- a/core/modules/aggregator/lib/Drupal/aggregator/Tests/AggregatorRenderingTest.php +++ b/core/modules/aggregator/lib/Drupal/aggregator/Tests/AggregatorRenderingTest.php @@ -50,7 +50,7 @@ public function testBlockLinks() { )); $this->drupalLogin($admin_user); - $block = $this->drupalPlaceBlock("aggregator_feed_block:{$feed->id()}", array('label' => 'feed-' . $feed->label()), array('block_count' => 2)); + $block = $this->drupalPlaceBlock("aggregator_feed_block:{$feed->id()}", array('label' => 'feed-' . $feed->label(), 'block_count' => 2)); // Confirm that the block is now being displayed on pages. $this->drupalGet('test-page'); diff --git a/core/modules/block/block.api.php b/core/modules/block/block.api.php index b3c02b9..c2bf7ff 100644 --- a/core/modules/block/block.api.php +++ b/core/modules/block/block.api.php @@ -11,113 +11,90 @@ */ /** - * Perform alterations to the content of a block. + * Alter the result of \Drupal\block\BlockBase::build(). * - * This hook allows you to modify any data returned by hook_block_view(). + * This hook is called after the content has been assembled in a structured + * array and may be used for doing processing which requires that the complete + * block content structure has been built. * - * Note that instead of hook_block_view_alter(), which is called for all blocks, - * you can also use hook_block_view_ID_alter() to alter a specific block, or - * hook_block_view_NAME_alter() to alter a specific block instance. + * If the module wishes to act on the rendered HTML of the block rather than + * the structured content array, it may use this hook to add a #post_render + * callback. Alternatively, it could also implement hook_preprocess_HOOK() for + * block.tpl.php. See drupal_render() and theme() documentation respectively + * for details. + * + * In addition to hook_block_view_alter(), which is called for all blocks, there + * is hook_block_view_BASE_BLOCK_ID_alter(), which can be used to target a + * specific block or set of similar blocks. * * @param array $build * A renderable array of data, as returned from the build() implementation of * the plugin that defined the block: * - #title: The default localized title of the block. * @param \Drupal\block\BlockPluginInterface $block - * The block instance. + * The block plugin instance. * - * @see hook_block_view_ID_alter() - * @see hook_block_view_NAME_alter() + * @see hook_block_view_BASE_BLOCK_ID_alter() */ -function hook_block_view_alter(array &$build, \Drupal\block\Plugin\Core\Entity\Block $block) { +function hook_block_view_alter(array &$build, \Drupal\block\BlockPluginInterface $block) { // Remove the contextual links on all blocks that provide them. - if (is_array($build) && isset($build['#contextual_links'])) { + if (isset($build['#contextual_links'])) { unset($build['#contextual_links']); } - // Add a theme wrapper function defined by the current module to all blocks - // provided by the "somemodule" module. - if (is_array($build) && $block instanceof SomeBlockClass) { - $build['#theme_wrappers'][] = 'mymodule_special_block'; - } } /** - * Perform alterations to a specific block. + * Provide a block plugin specific block_view alteration. * - * Modules can implement hook_block_view_ID_alter() to modify a specific block, - * rather than implementing hook_block_view_alter(). + * In this hook name, BASE_BLOCK_ID refers to the block implementation's plugin + * id, regardless of whether the plugin supports derivatives. For example, for + * the \Drupal\system\Plugin\block\block\SystemPoweredByBlock block, this would + * be 'system_powered_by_block' as per that class's annotation. And for the + * \Drupal\system\Plugin\block\block\SystemMenuBlock block, it would be + * 'system_menu_block' as per that class's annotation, regardless of which menu + * the derived block is for. * * @param array $build * A renderable array of data, as returned from the build() implementation of * the plugin that defined the block: * - #title: The default localized title of the block. * @param \Drupal\block\BlockPluginInterface $block - * The block instance. - * - * @todo Add a more specific example of a block ID, and illustrate how this is - * different from hook_block_view_NAME_alter(). + * The block plugin instance. * * @see hook_block_view_alter() - * @see hook_block_view_NAME_alter() */ -function hook_block_view_ID_alter(array &$build, \Drupal\block\BlockPluginInterface $block) { - // This code will only run for a specific block. For example, if ID - // in the function definition above is set to "someid", the code - // will only run on the "someid" block. - - // Change the title of the "someid" block. +function hook_block_view_BASE_BLOCK_ID_alter(array &$build, \Drupal\block\BlockPluginInterface $block) { + // Change the title of the specific block. $build['#title'] = t('New title of the block'); } /** - * Perform alterations to a specific block instance. - * - * Modules can implement hook_block_view_NAME_alter() to modify a specific block - * instance, rather than implementing hook_block_view_alter(). + * Control access to a block instance. * - * @param array $build - * A renderable array of data, as returned from the build() implementation of - * the plugin that defined the block: - * - #title: The default localized title of the block. - * @param \Drupal\block\BlockPluginInterface $block - * The block instance. - * - * @todo NAME is ambiguous, and so is the example here. Use a more specific - * example to illustrate what the block instance name will look like, and - * also illustrate how it is different from hook_block_view_ID(). - * - * @see hook_block_view_alter() - * @see hook_block_view_ID_alter() - */ -function hook_block_view_NAME_alter(array &$build, \Drupal\block\BlockPluginInterface $block) { - // This code will only run for a specific block instance. For example, if NAME - // in the function definition above is set to "someid", the code will only run - // on the "someid" block. - - // Change the title of the "someid" block. - $build['#title'] = t('New title of the block'); -} - -/** - * Define access for a specific block instance. - * - * This hook is invoked by the access methods of the block plugin system and - * should be used to alter the block access rules defined by a module from - * another module. + * Modules may implement this hook if they want to have a say in whether or not + * a given user has access to perform a given operation on a block instance. * * @param \Drupal\block\Plugin\Core\Entity\Block $block * The block instance. - * - * @return bool - * TRUE will allow access whereas FALSE will deny access to the block. - * - * @see \Drupal\block\BlockBase::access() - * @see \Drupal\block\BlockBase::blockAccess() + * @param string $operation + * The operation to be performed, e.g., 'view', 'create', 'delete', 'update'. + * @param \Drupal\user\Plugin\Core\Entity\User $account + * The user object to perform the access check operation on. + * @param string $langcode + * The language code to perform the access check operation on. + * + * @return bool|NULL + * FALSE denies access. TRUE allows access unless another module returns + * FALSE. If all modules return NULL, then default access rules from + * \Drupal\block\BlockAccessController::checkAccess() are used. + * + * @see \Drupal\Core\Entity\EntityAccessController::access() + * @see \Drupal\block\BlockAccessController::checkAccess() */ -function hook_block_access(\Drupal\block\Plugin\Core\Entity\Block $block) { +function hook_block_access(\Drupal\block\Plugin\Core\Entity\Block $block, $operation, \Drupal\user\Plugin\Core\Entity\User $account, $langcode) { // Example code that would prevent displaying the 'Powered by Drupal' block in // a region different than the footer. - if ($block->get('plugin') == 'system_powered_by_block' && $block->get('region') != 'footer') { + if ($operation == 'view' && $block->get('plugin') == 'system_powered_by_block' && $block->get('region') != 'footer') { return FALSE; } } diff --git a/core/modules/block/block.module b/core/modules/block/block.module index 57f1572..db497e3 100644 --- a/core/modules/block/block.module +++ b/core/modules/block/block.module @@ -331,10 +331,9 @@ function _block_get_renderable_region($list = array()) { $build[$key] = array( '#block' => $block, '#weight' => $block->get('weight'), - '#theme_wrappers' => array('block'), '#pre_render' => array('_block_get_renderable_block'), '#cache' => array( - 'keys' => array($id, $block->get('module')), + 'keys' => array($id, $settings['module']), 'granularity' => $settings['cache'], 'bin' => 'block', 'tags' => array('content' => TRUE), @@ -535,22 +534,17 @@ function block_rebuild() { function template_preprocess_block(&$variables) { $block_counter = &drupal_static(__FUNCTION__, array()); - $variables['block'] = (object) $variables['elements']['#block_config']; - // If the block title is configured to be hidden, set it to an empty string. - if (empty($variables['elements']['#block']->label_display)) { - $variables['block']->label_hidden = $variables['block']->label; - $variables['block']->label = ''; - } - - // Create the $content variable that templates expect. - $variables['content'] = $variables['elements']['#children']; + $variables['configuration'] = $variables['elements']['#configuration']; + $variables['plugin_id'] = $variables['elements']['#plugin_id']; + $variables['label'] = !empty($variables['configuration']['label_display']) ? $variables['configuration']['label'] : ''; + $variables['content'] = $variables['elements']['content']; - $variables['attributes']['class'][] = drupal_html_class('block-' . $variables['block']->module); + $variables['attributes']['class'][] = drupal_html_class('block-' . $variables['configuration']['module']); // Add default class for block content. $variables['content_attributes']['class'][] = 'content'; - $variables['theme_hook_suggestions'][] = 'block__' . $variables['block']->module; + $variables['theme_hook_suggestions'][] = 'block__' . $variables['configuration']['module']; // Hyphens (-) and underscores (_) play a special role in theme suggestions. // Theme suggestions should only contain underscores, because within // drupal_find_theme_templates(), underscores are converted to hyphens to @@ -562,7 +556,7 @@ 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['plugin_id']); $suggestion = 'block'; while ($part = array_shift($parts)) { $variables['theme_hook_suggestions'][] = $suggestion .= '__' . strtr($part, '-', '_'); diff --git a/core/modules/block/custom_block/custom_block.module b/core/modules/block/custom_block/custom_block.module index e8ffbf0..a1fc680 100644 --- a/core/modules/block/custom_block/custom_block.module +++ b/core/modules/block/custom_block/custom_block.module @@ -7,7 +7,6 @@ use Drupal\custom_block\Plugin\Core\Entity\CustomBlockType; use Drupal\custom_block\Plugin\Core\Entity\CustomBlock; -use Drupal\block\Plugin\Core\Entity\Block; /** * Implements hook_menu_local_tasks(). diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Block/CustomBlockBlock.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Block/CustomBlockBlock.php index 25c3a86..01b11ba 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Block/CustomBlockBlock.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Block/CustomBlockBlock.php @@ -18,26 +18,20 @@ * id = "custom_block", * admin_label = @Translation("Custom block"), * module = "custom_block", - * derivative = "Drupal\custom_block\Plugin\Derivative\CustomBlock", - * settings = { - * "status" = TRUE, - * "info" = "", - * "view_mode" = "full" - * } + * derivative = "Drupal\custom_block\Plugin\Derivative\CustomBlock" * ) */ class CustomBlockBlock extends BlockBase { /** - * Overrides \Drupal\block\BlockBase::getConfig(). + * Overrides \Drupal\block\BlockBase::settings(). */ - public function getConfig() { - $definition = $this->getDefinition(); - $this->configuration = parent::getConfig(); - $this->configuration['status'] = $definition['settings']['status']; - $this->configuration['info'] = $definition['settings']['info']; - $this->configuration['view_mode'] = $definition['settings']['view_mode']; - return $this->configuration; + public function settings() { + return array( + 'status' => TRUE, + 'info' => '', + 'view_mode' => 'full', + ); } /** diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Derivative/CustomBlock.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Derivative/CustomBlock.php index 592f150..71a50bd 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Derivative/CustomBlock.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Derivative/CustomBlock.php @@ -43,9 +43,6 @@ public function getDerivativeDefinitions(array $base_plugin_definition) { $custom_blocks = entity_load_multiple('custom_block'); foreach ($custom_blocks as $custom_block) { $this->derivatives[$custom_block->uuid->value] = $base_plugin_definition; - $this->derivatives[$custom_block->uuid->value]['settings'] = array( - 'info' => $custom_block->info->value, - ) + $base_plugin_definition['settings']; $this->derivatives[$custom_block->uuid->value]['admin_label'] = $custom_block->info->value; } return $this->derivatives; diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php index 8d49349..ab9a938 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php @@ -101,7 +101,7 @@ public function testBlockFields() { // Place the block. $instance = array( 'machine_name' => drupal_strtolower($edit['info']), - 'label' => $edit['info'], + 'settings[label]' => $edit['info'], 'region' => 'sidebar_first', ); $this->drupalPost(NULL, $instance, t('Save block')); diff --git a/core/modules/block/lib/Drupal/block/BlockAccessController.php b/core/modules/block/lib/Drupal/block/BlockAccessController.php index 1675cc2..693fb32 100644 --- a/core/modules/block/lib/Drupal/block/BlockAccessController.php +++ b/core/modules/block/lib/Drupal/block/BlockAccessController.php @@ -20,9 +20,78 @@ class BlockAccessController extends EntityAccessController { * {@inheritdoc} */ protected function checkAccess(EntityInterface $entity, $operation, $langcode, User $account) { - if ($operation === 'view') { - return $entity->getPlugin()->access(); + // Currently, only view access is implemented. + if ($operation != 'view') { + return FALSE; } + + // Deny access to disabled blocks. + if (!$entity->status()) { + return FALSE; + } + + // If the plugin denies access, then deny access. + if (!$entity->getPlugin()->access()) { + return FALSE; + } + + // Otherwise, check for other access restrictions. + global $user; + + // User role access handling. + // 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 = $entity->get('visibility'); + if (!empty($visibility['role']['roles']) && !array_intersect(array_filter($visibility['role']['roles']), array_keys($user->roles))) { + // No match. + return FALSE; + } + + // Page path handling. + // Limited visibility blocks must list at least one page. + if (!empty($visibility['path']['visibility']) && $visibility['path']['visibility'] == BLOCK_VISIBILITY_LISTED && empty($visibility['path']['pages'])) { + return FALSE; + } + + // Match path if necessary. + if (!empty($visibility['path']['pages'])) { + // Assume there are no matches until one is found. + $page_match = FALSE; + + // Convert path to lowercase. This allows comparison of the same path + // with different case. Ex: /Page, /page, /PAGE. + $pages = drupal_strtolower($visibility['path']['pages']); + if ($visibility['path']['visibility'] < BLOCK_VISIBILITY_PHP) { + // Compare the lowercase path alias (if any) and internal path. + $path = current_path(); + $path_alias = drupal_strtolower(drupal_container()->get('path.alias_manager')->getPathAlias($path)); + $page_match = drupal_match_path($path_alias, $pages) || (($path != $path_alias) && drupal_match_path($path, $pages)); + // When $block->visibility has a value of 0 + // (BLOCK_VISIBILITY_NOTLISTED), the block is displayed on all pages + // except those listed in $block->pages. When set to 1 + // (BLOCK_VISIBILITY_LISTED), it is displayed only on those pages + // listed in $block->pages. + $page_match = !($visibility['path']['visibility'] xor $page_match); + } + elseif (module_exists('php')) { + $page_match = php_eval($visibility['path']['pages']); + } + + // If there are page visibility restrictions and this page does not + // match, deny access. + if (!$page_match) { + return FALSE; + } + } + + // Language visibility settings. + if (!empty($visibility['language']['langcodes']) && array_filter($visibility['language']['langcodes'])) { + if (empty($visibility['language']['langcodes'][language($visibility['language']['language_type'])->langcode])) { + return FALSE; + } + } + return TRUE; } } diff --git a/core/modules/block/lib/Drupal/block/BlockBase.php b/core/modules/block/lib/Drupal/block/BlockBase.php index b1bade0..57ff44d 100644 --- a/core/modules/block/lib/Drupal/block/BlockBase.php +++ b/core/modules/block/lib/Drupal/block/BlockBase.php @@ -8,8 +8,6 @@ namespace Drupal\block; 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,19 +19,17 @@ abstract class BlockBase extends PluginBase implements BlockPluginInterface { /** - * The entity using this plugin. - * - * @var \Drupal\block\Plugin\Core\Entity\Block + * {@inheritdoc} */ - protected $entity; - - /** - * Overrides \Drupal\Component\Plugin\PluginBase::__construct(). - */ - public function __construct(array $configuration, $plugin_id, array $plugin_definition, Block $entity) { + public function __construct(array $configuration, $plugin_id, array $plugin_definition) { parent::__construct($configuration, $plugin_id, $plugin_definition); - $this->entity = $entity; + $this->configuration += $this->settings() + array( + 'label' => '', + 'module' => $plugin_definition['module'], + 'label_display' => BLOCK_LABEL_VISIBLE, + 'cache' => DRUPAL_NO_CACHE, + ); } /** @@ -65,18 +61,6 @@ public function settings() { * @see \Drupal\Component\Plugin\PluginBase::$configuration */ public function getConfig() { - if (empty($this->configuration)) { - // If the plugin configuration is not already set, initialize it with the - // default settings for the block plugin. - $this->configuration = $this->settings(); - - $definition = $this->getDefinition(); - if (isset($definition['admin_label'])) { - $this->configuration += array('admin_label' => $definition['admin_label']); - } - } - // Ensure that the default cache mode is set. - $this->configuration += array('cache' => DRUPAL_NO_CACHE); return $this->configuration; } @@ -106,108 +90,13 @@ public function setConfig($key, $value) { * with that access control logic. * * @return bool - * FALSE to deny access to the block, or TRUE to allow - * BlockBase::access() to make the access determination. - * - * @see \Drupal\block\BlockBase::access() - */ - public function blockAccess() { - // By default, the block is visible unless user-configured rules indicate - // that it should be hidden. - return TRUE; - } - - /** - * Implements \Drupal\block\BlockPluginInterface::access(). - * - * Adds the user-configured per-role, per-path, and per-language visibility - * settings to all blocks, and invokes hook_block_access(). - * - * Most plugins should not override this method unless they need to remove - * the user-defined access restrictions. To add specific access - * restrictions for a particular block type, override - * BlockBase::blockAccess() instead. + * FALSE to deny access to the block, or TRUE to allow access. * * @see hook_block_access() - * @see \Drupal\block\BlockBase::blockAccess() */ public function access() { - // If the block-specific access restrictions indicate the block is not - // accessible, always deny access. - if (!$this->blockAccess()) { - return FALSE; - } - - // Otherwise, check for other access restrictions. - global $user; - - // Deny access to disabled blocks. - if (!$this->entity->get('status')) { - return FALSE; - } - - // User role access handling. - // 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'); - if (!empty($visibility['role']['roles']) && !array_intersect(array_filter($visibility['role']['roles']), array_keys($user->roles))) { - // No match. - return FALSE; - } - - // Page path handling. - // Limited visibility blocks must list at least one page. - if (!empty($visibility['path']['visibility']) && $visibility['path']['visibility'] == BLOCK_VISIBILITY_LISTED && empty($visibility['path']['pages'])) { - return FALSE; - } - - // Match path if necessary. - if (!empty($visibility['path']['pages'])) { - // Assume there are no matches until one is found. - $page_match = FALSE; - - // Convert path to lowercase. This allows comparison of the same path - // with different case. Ex: /Page, /page, /PAGE. - $pages = drupal_strtolower($visibility['path']['pages']); - if ($visibility['path']['visibility'] < BLOCK_VISIBILITY_PHP) { - // Compare the lowercase path alias (if any) and internal path. - $path = current_path(); - $path_alias = drupal_strtolower(drupal_container()->get('path.alias_manager')->getPathAlias($path)); - $page_match = drupal_match_path($path_alias, $pages) || (($path != $path_alias) && drupal_match_path($path, $pages)); - // When $block->visibility has a value of 0 - // (BLOCK_VISIBILITY_NOTLISTED), the block is displayed on all pages - // except those listed in $block->pages. When set to 1 - // (BLOCK_VISIBILITY_LISTED), it is displayed only on those pages - // listed in $block->pages. - $page_match = !($visibility['path']['visibility'] xor $page_match); - } - elseif (module_exists('php')) { - $page_match = php_eval($visibility['path']['pages']); - } - - // If there are page visibility restrictions and this page does not - // match, deny access. - if (!$page_match) { - return FALSE; - } - } - - // Language visibility settings. - if (!empty($visibility['language']['langcodes']) && array_filter($visibility['language']['langcodes'])) { - if (empty($visibility['language']['langcodes'][language($visibility['language']['language_type'])->langcode])) { - return FALSE; - } - } - - // Check other modules for block access rules. - foreach (module_implements('block_access') as $module) { - if (module_invoke($module, 'block_access', $this->entity) === FALSE) { - return FALSE; - } - } - - // If nothing denied access to the block, it is accessible. + // By default, the block is visible unless user-configured rules indicate + // that it should be hidden. return TRUE; } @@ -222,12 +111,7 @@ public function access() { * @see \Drupal\block\BlockBase::blockForm() */ public function form($form, &$form_state) { - $entity = $form_state['controller']->getEntity(); $definition = $this->getDefinition(); - $form['id'] = array( - '#type' => 'value', - '#value' => $entity->id(), - ); $form['module'] = array( '#type' => 'value', '#value' => $definition['module'], @@ -237,164 +121,18 @@ public function form($form, &$form_state) { '#type' => 'textfield', '#title' => t('Title'), '#maxlength' => 255, - '#default_value' => !$entity->isNew() ? $entity->label() : $definition['admin_label'], + '#default_value' => !empty($this->configuration['label']) ? $this->configuration['label'] : $definition['admin_label'], '#required' => TRUE, ); $form['label_display'] = array( '#type' => 'checkbox', '#title' => t('Display title'), - '#default_value' => $entity->label_display == BLOCK_LABEL_VISIBLE ? TRUE : FALSE, + '#default_value' => $this->configuration['label_display'] == BLOCK_LABEL_VISIBLE, '#return_value' => BLOCK_LABEL_VISIBLE, ); - $form['machine_name'] = array( - '#type' => 'machine_name', - '#title' => t('Machine name'), - '#maxlength' => 64, - '#description' => t('A unique name to save this block configuration. Must be alpha-numeric and be underscore separated.'), - '#default_value' => $entity->id(), - '#machine_name' => array( - 'exists' => 'block_load', - 'replace_pattern' => '[^a-z0-9_.]+', - ), - '#required' => TRUE, - '#disabled' => !$entity->isNew(), - ); - - // Region settings. - $form['region'] = array( - '#type' => 'select', - '#title' => t('Region'), - '#description' => t('Select the region where this block should be displayed.'), - '#default_value' => $entity->get('region'), - '#empty_value' => BLOCK_REGION_NONE, - '#options' => system_region_list($entity->get('theme'), REGIONS_VISIBLE), - ); - - // Visibility settings. - $form['visibility'] = array( - '#type' => 'vertical_tabs', - '#title' => t('Visibility settings'), - '#attached' => array( - 'js' => array(drupal_get_path('module', 'block') . '/block.js'), - ), - '#tree' => TRUE, - '#weight' => 10, - ); - - // Per-path visibility. - $form['visibility']['path'] = array( - '#type' => 'details', - '#title' => t('Pages'), - '#collapsed' => TRUE, - '#group' => 'visibility', - '#weight' => 0, - ); - - // @todo remove this access check and inject it in some other way. In fact - // this entire visibility settings section probably needs a separate user - // interface in the near future. - $visibility = $entity->get('visibility'); - $access = user_access('use PHP for settings'); - if (!empty($visibility['path']['visibility']) && $visibility['path']['visibility'] == BLOCK_VISIBILITY_PHP && !$access) { - $form['visibility']['path']['visibility'] = array( - '#type' => 'value', - '#value' => BLOCK_VISIBILITY_PHP, - ); - $form['visibility']['path']['pages'] = array( - '#type' => 'value', - '#value' => !empty($visibility['path']['pages']) ? $visibility['path']['pages'] : '', - ); - } - else { - $options = array( - BLOCK_VISIBILITY_NOTLISTED => t('All pages except those listed'), - BLOCK_VISIBILITY_LISTED => t('Only the listed pages'), - ); - $description = t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. Example paths are %user for the current user's page and %user-wildcard for every user page. %front is the front page.", array('%user' => 'user', '%user-wildcard' => 'user/*', '%front' => '')); - - if (module_exists('php') && $access) { - $options += array(BLOCK_VISIBILITY_PHP => t('Pages on which this PHP code returns TRUE (experts only)')); - $title = t('Pages or PHP code'); - $description .= ' ' . t('If the PHP option is chosen, enter PHP code between %php. Note that executing incorrect PHP code can break your Drupal site.', array('%php' => '')); - } - else { - $title = t('Pages'); - } - $form['visibility']['path']['visibility'] = array( - '#type' => 'radios', - '#title' => t('Show block on specific pages'), - '#options' => $options, - '#default_value' => !empty($visibility['path']['visibility']) ? $visibility['path']['visibility'] : BLOCK_VISIBILITY_NOTLISTED, - ); - $form['visibility']['path']['pages'] = array( - '#type' => 'textarea', - '#title' => '' . $title . '', - '#default_value' => !empty($visibility['path']['pages']) ? $visibility['path']['pages'] : '', - '#description' => $description, - ); - } - - // Configure the block visibility per language. - if (module_exists('language') && language_multilingual()) { - $configurable_language_types = language_types_get_configurable(); - - // Fetch languages. - $languages = language_list(LANGUAGE_ALL); - foreach ($languages as $language) { - // @todo $language->name is not wrapped with t(), it should be replaced - // by CMI translation implementation. - $langcodes_options[$language->langcode] = $language->name; - } - $form['visibility']['language'] = array( - '#type' => 'details', - '#title' => t('Languages'), - '#collapsed' => TRUE, - '#group' => 'visibility', - '#weight' => 5, - ); - // If there are multiple configurable language types, let the user pick - // which one should be applied to this visibility setting. This way users - // can limit blocks by interface language or content language for exmaple. - $language_types = language_types_info(); - $language_type_options = array(); - foreach ($configurable_language_types as $type_key) { - $language_type_options[$type_key] = $language_types[$type_key]['name']; - } - $form['visibility']['language']['language_type'] = array( - '#type' => 'radios', - '#title' => t('Language type'), - '#options' => $language_type_options, - '#default_value' => !empty($visibility['language']['language_type']) ? $visibility['language']['language_type'] : $configurable_language_types[0], - '#access' => count($language_type_options) > 1, - ); - $form['visibility']['language']['langcodes'] = array( - '#type' => 'checkboxes', - '#title' => t('Show this block only for specific languages'), - '#default_value' => !empty($visibility['language']['langcodes']) ? $visibility['language']['langcodes'] : array(), - '#options' => $langcodes_options, - '#description' => t('Show this block only for the selected language(s). If you select no languages, the block will be visibile in all languages.'), - ); - } - - // Per-role visibility. - $role_options = array_map('check_plain', user_role_names()); - $form['visibility']['role'] = array( - '#type' => 'details', - '#title' => t('Roles'), - '#collapsed' => TRUE, - '#group' => 'visibility', - '#weight' => 10, - ); - $form['visibility']['role']['roles'] = array( - '#type' => 'checkboxes', - '#title' => t('Show block for specific roles'), - '#default_value' => !empty($visibility['role']['roles']) ? $visibility['role']['roles'] : array(), - '#options' => $role_options, - '#description' => t('Show this block only for the selected role(s). If you select no roles, the block will be visible to all users.'), - ); // Add plugin-specific settings for this block type. - $form['settings'] = $this->blockForm(array(), $form_state); + $form += $this->blockForm($form, $form_state); return $form; } @@ -429,15 +167,6 @@ public function blockForm($form, &$form_state) { * @see \Drupal\block\BlockBase::blockValidate() */ public function validate($form, &$form_state) { - $entity = $form_state['controller']->getEntity(); - if (!empty($form['machine_name']['#disabled'])) { - $config_id = explode('.', $form_state['values']['machine_name']); - $form_state['values']['machine_name'] = array_pop($config_id); - } - $form_state['values']['visibility']['role']['roles'] = array_filter($form_state['values']['visibility']['role']['roles']); - if ($entity->isNew()) { - form_set_value($form['id'], $entity->get('theme') . '.' . $form_state['values']['machine_name'], $form_state); - } $this->blockValidate($form, $form_state); } @@ -471,12 +200,10 @@ public function blockValidate($form, &$form_state) {} */ public function submit($form, &$form_state) { if (!form_get_errors()) { + $this->configuration['label'] = $form_state['values']['label']; + $this->configuration['label_display'] = $form_state['values']['label_display']; + $this->configuration['module'] = $form_state['values']['module']; $this->blockSubmit($form, $form_state); - $entity = $form_state['controller']->getEntity(); - - drupal_set_message(t('The block configuration has been saved.')); - cache_invalidate_tags(array('content' => TRUE)); - $form_state['redirect'] = 'admin/structure/block/list/block_plugin_ui:' . $entity->get('theme'); } } @@ -502,9 +229,20 @@ public function blockSubmit($form, &$form_state) {} * Implements \Drupal\block\BlockInterface::build(). */ public function build() { - // @todo Move block rendering code common to all blocks from - // BlockRenderController to here: http://drupal.org/node/1927608. - return $this->blockBuild(); + $build = array(); + $plugin_id = $this->getPluginId(); + if ($content = $this->blockBuild()) { + $build = array( + '#theme' => 'block', + 'content' => $content, + '#configuration' => $this->configuration, + '#plugin_id' => $plugin_id, + ); + $build['#configuration']['label'] = check_plain($this->configuration['label']); + } + list($base_id) = explode(':', $plugin_id); + drupal_alter(array('block_view', "block_view_$base_id"), $build, $this); + return $build; } /** diff --git a/core/modules/block/lib/Drupal/block/BlockFormController.php b/core/modules/block/lib/Drupal/block/BlockFormController.php index 175d6b0..ef499c0 100644 --- a/core/modules/block/lib/Drupal/block/BlockFormController.php +++ b/core/modules/block/lib/Drupal/block/BlockFormController.php @@ -18,7 +18,163 @@ class BlockFormController extends EntityFormController { * Overrides \Drupal\Core\Entity\EntityFormController::form(). */ public function form(array $form, array &$form_state) { - return $this->entity->getPlugin()->form($form, $form_state); + $entity = $this->entity; + $form['#tree'] = TRUE; + $form['id'] = array( + '#type' => 'value', + '#value' => $entity->id(), + ); + $form['settings'] = $entity->getPlugin()->form(array(), $form_state); + + $form['machine_name'] = array( + '#type' => 'machine_name', + '#title' => t('Machine name'), + '#maxlength' => 64, + '#description' => t('A unique name to save this block configuration. Must be alpha-numeric and be underscore separated.'), + '#default_value' => $entity->id(), + '#machine_name' => array( + 'exists' => 'block_load', + 'replace_pattern' => '[^a-z0-9_.]+', + 'source' => array('settings', 'label'), + ), + '#required' => TRUE, + '#disabled' => !$entity->isNew(), + ); + + // Visibility settings. + $form['visibility'] = array( + '#type' => 'vertical_tabs', + '#title' => t('Visibility settings'), + '#attached' => array( + 'js' => array(drupal_get_path('module', 'block') . '/block.js'), + ), + '#tree' => TRUE, + '#weight' => 10, + '#parents' => array('visibility'), + ); + + // Per-path visibility. + $form['visibility']['path'] = array( + '#type' => 'details', + '#title' => t('Pages'), + '#collapsed' => TRUE, + '#group' => 'visibility', + '#weight' => 0, + ); + + // @todo remove this access check and inject it in some other way. In fact + // this entire visibility settings section probably needs a separate user + // interface in the near future. + $visibility = $entity->get('visibility'); + $access = user_access('use PHP for settings'); + if (!empty($visibility['path']['visibility']) && $visibility['path']['visibility'] == BLOCK_VISIBILITY_PHP && !$access) { + $form['visibility']['path']['visibility'] = array( + '#type' => 'value', + '#value' => BLOCK_VISIBILITY_PHP, + ); + $form['visibility']['path']['pages'] = array( + '#type' => 'value', + '#value' => !empty($visibility['path']['pages']) ? $visibility['path']['pages'] : '', + ); + } + else { + $options = array( + BLOCK_VISIBILITY_NOTLISTED => t('All pages except those listed'), + BLOCK_VISIBILITY_LISTED => t('Only the listed pages'), + ); + $description = t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. Example paths are %user for the current user's page and %user-wildcard for every user page. %front is the front page.", array('%user' => 'user', '%user-wildcard' => 'user/*', '%front' => '')); + + if (module_exists('php') && $access) { + $options += array(BLOCK_VISIBILITY_PHP => t('Pages on which this PHP code returns TRUE (experts only)')); + $title = t('Pages or PHP code'); + $description .= ' ' . t('If the PHP option is chosen, enter PHP code between %php. Note that executing incorrect PHP code can break your Drupal site.', array('%php' => '')); + } + else { + $title = t('Pages'); + } + $form['visibility']['path']['visibility'] = array( + '#type' => 'radios', + '#title' => t('Show block on specific pages'), + '#options' => $options, + '#default_value' => !empty($visibility['path']['visibility']) ? $visibility['path']['visibility'] : BLOCK_VISIBILITY_NOTLISTED, + ); + $form['visibility']['path']['pages'] = array( + '#type' => 'textarea', + '#title' => '' . $title . '', + '#default_value' => !empty($visibility['path']['pages']) ? $visibility['path']['pages'] : '', + '#description' => $description, + ); + } + + // Configure the block visibility per language. + if (module_exists('language') && language_multilingual()) { + $configurable_language_types = language_types_get_configurable(); + + // Fetch languages. + $languages = language_list(LANGUAGE_ALL); + foreach ($languages as $language) { + // @todo $language->name is not wrapped with t(), it should be replaced + // by CMI translation implementation. + $langcodes_options[$language->langcode] = $language->name; + } + $form['visibility']['language'] = array( + '#type' => 'details', + '#title' => t('Languages'), + '#collapsed' => TRUE, + '#group' => 'visibility', + '#weight' => 5, + ); + // If there are multiple configurable language types, let the user pick + // which one should be applied to this visibility setting. This way users + // can limit blocks by interface language or content language for exmaple. + $language_types = language_types_info(); + $language_type_options = array(); + foreach ($configurable_language_types as $type_key) { + $language_type_options[$type_key] = $language_types[$type_key]['name']; + } + $form['visibility']['language']['language_type'] = array( + '#type' => 'radios', + '#title' => t('Language type'), + '#options' => $language_type_options, + '#default_value' => !empty($visibility['language']['language_type']) ? $visibility['language']['language_type'] : $configurable_language_types[0], + '#access' => count($language_type_options) > 1, + ); + $form['visibility']['language']['langcodes'] = array( + '#type' => 'checkboxes', + '#title' => t('Show this block only for specific languages'), + '#default_value' => !empty($visibility['language']['langcodes']) ? $visibility['language']['langcodes'] : array(), + '#options' => $langcodes_options, + '#description' => t('Show this block only for the selected language(s). If you select no languages, the block will be visibile in all languages.'), + ); + } + + // Per-role visibility. + $role_options = array_map('check_plain', user_role_names()); + $form['visibility']['role'] = array( + '#type' => 'details', + '#title' => t('Roles'), + '#collapsed' => TRUE, + '#group' => 'visibility', + '#weight' => 10, + ); + $form['visibility']['role']['roles'] = array( + '#type' => 'checkboxes', + '#title' => t('Show block for specific roles'), + '#default_value' => !empty($visibility['role']['roles']) ? $visibility['role']['roles'] : array(), + '#options' => $role_options, + '#description' => t('Show this block only for the selected role(s). If you select no roles, the block will be visible to all users.'), + ); + + // Region settings. + $form['region'] = array( + '#type' => 'select', + '#title' => t('Region'), + '#description' => t('Select the region where this block should be displayed.'), + '#default_value' => $entity->get('region'), + '#empty_value' => BLOCK_REGION_NONE, + '#options' => system_region_list($entity->get('theme'), REGIONS_VISIBLE), + ); + return $form; } /** @@ -37,7 +193,21 @@ public function validate(array $form, array &$form_state) { parent::validate($form, $form_state); $entity = $this->entity; - $entity->getPlugin()->validate($form, $form_state); + if ($entity->isNew()) { + form_set_value($form['id'], $entity->get('theme') . '.' . $form_state['values']['machine_name'], $form_state); + } + if (!empty($form['machine_name']['#disabled'])) { + $config_id = explode('.', $form_state['values']['machine_name']); + $form_state['values']['machine_name'] = array_pop($config_id); + } + $form_state['values']['visibility']['role']['roles'] = array_filter($form_state['values']['visibility']['role']['roles']); + // The Block Entity form puts all block plugin form elements in the + // settings form element, so just pass that to the block for validation. + $settings = array( + 'values' => &$form_state['values']['settings'] + ); + // Call the plugin validate handler. + $entity->getPlugin()->validate($form, $settings); } /** @@ -47,12 +217,20 @@ public function submit(array $form, array &$form_state) { parent::submit($form, $form_state); $entity = $this->entity; + // The Block Entity form puts all block plugin form elements in the + // settings form element, so just pass that to the block for submission. + $settings = array( + 'values' => &$form_state['values']['settings'] + ); // Call the plugin submit handler. - $entity->getPlugin()->submit($form, $form_state); + $entity->getPlugin()->submit($form, $settings); // Save the settings of the plugin. - $entity->set('settings', $entity->getPlugin()->getConfig()); $entity->save(); + + drupal_set_message(t('The block configuration has been saved.')); + cache_invalidate_tags(array('content' => TRUE)); + $form_state['redirect'] = 'admin/structure/block/list/block_plugin_ui:' . $entity->get('theme'); } } diff --git a/core/modules/block/lib/Drupal/block/BlockListController.php b/core/modules/block/lib/Drupal/block/BlockListController.php index 5dd981f..5b18b3c 100644 --- a/core/modules/block/lib/Drupal/block/BlockListController.php +++ b/core/modules/block/lib/Drupal/block/BlockListController.php @@ -206,6 +206,12 @@ public function submitForm(array &$form, array &$form_state) { foreach ($entities as $entity_id => $entity) { $entity->set('weight', $form_state['values']['blocks'][$entity_id]['weight']); $entity->set('region', $form_state['values']['blocks'][$entity_id]['region']); + if ($entity->get('region') == BLOCK_REGION_NONE) { + $entity->disable(); + } + else { + $entity->enable(); + } $entity->save(); } drupal_set_message(t('The block settings have been updated.')); diff --git a/core/modules/block/lib/Drupal/block/BlockPluginBag.php b/core/modules/block/lib/Drupal/block/BlockPluginBag.php new file mode 100644 index 0000000..5a68beb --- /dev/null +++ b/core/modules/block/lib/Drupal/block/BlockPluginBag.php @@ -0,0 +1,69 @@ +manager = $manager; + $this->entity = $entity; + + $this->instanceIDs = drupal_map_assoc($instance_ids); + } + + /** + * {@inheritdoc} + */ + protected function initializePlugin($instance_id) { + if (!$instance_id) { + throw new PluginException(format_string("The block '@block' did not specify a plugin.", array('@block' => $this->entity->id()))); + } + if (isset($this->pluginInstances[$instance_id])) { + return; + } + + $settings = $this->entity->get('settings'); + try { + $this->pluginInstances[$instance_id] = $this->manager->createInstance($instance_id, $settings); + } + catch (PluginException $e) { + $module = $settings['module']; + // Ignore blocks belonging to disabled modules, but re-throw valid + // exceptions when the module is enabled and the plugin is misconfigured. + if (!$module || \Drupal::moduleHandler()->moduleExists($module)) { + throw $e; + } + } + } + +} diff --git a/core/modules/block/lib/Drupal/block/BlockRenderController.php b/core/modules/block/lib/Drupal/block/BlockRenderController.php index e1c560e..12fff82 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) { @@ -72,17 +36,10 @@ public function view(EntityInterface $entity, $view_mode = 'full', $langcode = N public function viewMultiple(array $entities = array(), $view_mode = 'full', $langcode = NULL) { $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; - - // 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); + $build[$entity_id] = $entity->getPlugin()->build(); + // @todo Remove after fixing http://drupal.org/node/1989568. + $build[$entity_id]['#block'] = $entity; } return $build; } diff --git a/core/modules/block/lib/Drupal/block/BlockStorageController.php b/core/modules/block/lib/Drupal/block/BlockStorageController.php index a873c5d..80ce276 100644 --- a/core/modules/block/lib/Drupal/block/BlockStorageController.php +++ b/core/modules/block/lib/Drupal/block/BlockStorageController.php @@ -16,21 +16,7 @@ class BlockStorageController extends ConfigStorageController { /** - * Overrides \Drupal\Core\Config\Entity\ConfigStorageController::create(). - */ - public function create(array $values) { - $entity = parent::create($values); - - if (!$entity->get('module')) { - $definition = $entity->getPlugin()->getDefinition(); - $entity->set('module', $definition['module']); - } - - return $entity; - } - - /** - * Overrides \Drupal\Core\Config\Entity\ConfigStorageController::load(). + * {@inheritdoc} */ public function load(array $ids = NULL) { $entities = parent::load($ids); @@ -41,7 +27,7 @@ public function load(array $ids = NULL) { } /** - * Overrides \Drupal\Core\Config\Entity\ConfigStorageController::loadByProperties(). + * {@inheritdoc} */ public function loadByProperties(array $values = array()) { $blocks = $this->load(); @@ -53,4 +39,13 @@ public function loadByProperties(array $values = array()) { return $blocks; } + /** + * {@inheritdoc} + */ + protected function preSave(EntityInterface $entity) { + parent::preSave($entity); + + $entity->set('settings', $entity->getPlugin()->getConfig()); + } + } diff --git a/core/modules/block/lib/Drupal/block/Form/AdminBlockDeleteForm.php b/core/modules/block/lib/Drupal/block/Form/AdminBlockDeleteForm.php index 8db943b..ba6206a 100644 --- a/core/modules/block/lib/Drupal/block/Form/AdminBlockDeleteForm.php +++ b/core/modules/block/lib/Drupal/block/Form/AdminBlockDeleteForm.php @@ -33,7 +33,7 @@ public function getFormID() { * {@inheritdoc} */ protected function getQuestion() { - return t('Are you sure you want to delete the block %name?', array('%name' => $this->block->label)); + return t('Are you sure you want to delete the block %name?', array('%name' => $this->block->label())); } /** 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 fd0498f..3c8b14c 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 @@ -10,7 +10,7 @@ use Drupal\Core\Config\Entity\ConfigEntityBase; use Drupal\Core\Entity\Annotation\EntityType; use Drupal\Core\Annotation\Translation; -use Drupal\Component\Plugin\Exception\PluginException; +use Drupal\block\BlockPluginBag; use Drupal\block\BlockInterface; /** @@ -49,24 +49,6 @@ class Block extends ConfigEntityBase implements BlockInterface { public $id; /** - * The block label. - * - * @var string - */ - public $label; - - /** - * Whether the block label is displayed to end users. - * - * When this is set to BLOCK_LABEL_VISIBLE (the default value), the label is - * rendered as header in the block markup. Otherwise, the label is passed - * to the block template as a separate $label_hidden variable. - * - * @var string - */ - public $label_display = BLOCK_LABEL_VISIBLE; - - /** * The block UUID. * * @var string @@ -81,13 +63,6 @@ class Block extends ConfigEntityBase implements BlockInterface { protected $settings = array(); /** - * The plugin instance. - * - * @var \Drupal\block\BlockPluginInterface - */ - protected $instance; - - /** * The region this block is placed in. * * @var string @@ -95,57 +70,47 @@ class Block extends ConfigEntityBase implements BlockInterface { protected $region = BLOCK_REGION_NONE; /** - * Settings to control the block visibility. + * The block weight. * - * @var array + * @var int */ - protected $visibility = array(); + public $weight; /** - * The weight of the block. + * The plugin instance ID. * - * @var int + * @var string */ - protected $weight; + protected $plugin; /** - * The module owning this plugin. + * The plugin bag that holds the block plugin for this entity. * - * @var string + * @var \Drupal\block\BlockPluginBag */ - protected $module; + protected $pluginBag; /** - * The plugin instance ID. + * The visibility settings. * - * @var string + * @var array */ - protected $plugin; + protected $visibility; + + /** + * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::__construct(); + */ + public function __construct(array $values, $entity_type) { + parent::__construct($values, $entity_type); + + $this->pluginBag = new BlockPluginBag(\Drupal::service('plugin.manager.block'), array($this->plugin), $this); + } /** * {@inheritdoc} */ public function getPlugin() { - if (!$this->instance) { - // Throw an exception if no plugin string was provided. - if (!$this->plugin) { - throw new PluginException(format_string("The block '@block' did not specify a plugin.", array('@block' => $this->id()))); - } - - // 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(); - } - catch (PluginException $e) { - // Ignore blocks belonging to disabled modules, but re-throw valid - // exceptions when the module is enabled and the plugin is misconfigured. - if (empty($this->module) || module_exists($this->module)) { - throw $e; - } - } - } - return $this->instance; + return $this->pluginBag->get($this->plugin); } /** @@ -160,6 +125,13 @@ public function uri() { ), ); } + /** + * Overrides \Drupal\Core\Entity\Entity::label(); + */ + public function label($langcode = NULL) { + $settings = $this->get('settings'); + return $settings['label']; + } /** * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::get(); @@ -177,21 +149,14 @@ public function get($property_name, $langcode = NULL) { * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::getExportProperties(); */ public function getExportProperties() { + $properties = parent::getExportProperties(); $names = array( - 'id', - 'label', - 'label_display', - 'uuid', 'region', 'weight', - 'module', - 'status', - 'visibility', 'plugin', 'settings', - 'langcode', + 'visibility', ); - $properties = array(); foreach ($names as $name) { $properties[$name] = $this->get($name); } 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 488722c..19cdf60 100644 --- a/core/modules/block/lib/Drupal/block/Plugin/Type/BlockManager.php +++ b/core/modules/block/lib/Drupal/block/Plugin/Type/BlockManager.php @@ -13,7 +13,6 @@ use Drupal\Core\Plugin\Discovery\AlterDecorator; use Drupal\Core\Plugin\Discovery\CacheDecorator; use Drupal\Component\Plugin\Factory\DefaultFactory; -use Drupal\block\Plugin\Core\Entity\Block; /** * Manages discovery and instantiation of block plugins. @@ -36,15 +35,8 @@ public function __construct(\Traversable $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, 'block', CacheBackendInterface::CACHE_PERMANENT, array('block')); - } - /** - * Overrides \Drupal\Component\Plugin\PluginManagerBase::createInstance(). - */ - public function createInstance($plugin_id, array $configuration = array(), Block $entity = NULL) { - $plugin_definition = $this->discovery->getDefinition($plugin_id); - $plugin_class = DefaultFactory::getPluginClass($plugin_id, $plugin_definition); - return new $plugin_class($configuration, $plugin_id, $plugin_definition, $entity); + $this->factory = new DefaultFactory($this->discovery); } } diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockCacheTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockCacheTest.php index 96f9343..46454a6 100644 --- a/core/modules/block/lib/Drupal/block/Tests/BlockCacheTest.php +++ b/core/modules/block/lib/Drupal/block/Tests/BlockCacheTest.php @@ -192,9 +192,7 @@ function testCachePerPage() { * Private helper method to set the test block's cache mode. */ private function setCacheMode($cache_mode) { - $settings = $this->block->get('settings'); - $settings['cache'] = $cache_mode; - $this->block->set('settings', $settings); + $this->block->getPlugin()->setConfig('cache', $cache_mode); $this->block->save(); } diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockInterfaceTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockInterfaceTest.php new file mode 100644 index 0000000..58ff0c2 --- /dev/null +++ b/core/modules/block/lib/Drupal/block/Tests/BlockInterfaceTest.php @@ -0,0 +1,111 @@ + 'Block Plugins Tests', + 'description' => 'Tests that the block plugin can work properly without a supporting entity.', + 'group' => 'Block', + ); + } + + protected function setUp() { + parent::setUp(); + $this->installSchema('user', 'role_permission'); + } + + /** + * Test configuration and subsequent form() and build() method calls. + * + * This test is attempting to test the existing block plugin api and all + * functionality that is expected to remain consistent. The arrays that are + * used for comparison can change, but only to include elements that are + * contained within BlockBase or the plugin being tested. Likely these + * comparison arrays should get smaller, not larger, as more form/build + * elements are moved into a more suitably responsible class. + * + * Instantiation of the plugin is the primary element being tested here. The + * subsequent method calls are just attempting to cause a failure if a + * dependency outside of the plugin configuration is required. + */ + public function testBlockInterface() { + $manager = $this->container->get('plugin.manager.block'); + $configuration = array( + 'label' => 'Custom Display Message', + ); + $expected_configuration = array( + 'label' => 'Custom Display Message', + 'display_message' => 'no message set', + 'module' => 'block_test', + 'label_display' => BLOCK_LABEL_VISIBLE, + 'cache' => DRUPAL_NO_CACHE, + ); + // Initial configuration of the block at construction time. + $display_block = $manager->createInstance('test_block_instantiation', $configuration); + $this->assertIdentical($display_block->getConfig(), $expected_configuration, 'The block was configured correctly.'); + + // Updating an element of the configuration. + $display_block->setConfig('display_message', 'My custom display message.'); + $expected_configuration['display_message'] = 'My custom display message.'; + $this->assertIdentical($display_block->getConfig(), $expected_configuration, 'The block configuration was updated correctly.'); + + $expected_form = array( + 'module' => array( + '#type' => 'value', + '#value' => 'block_test', + ), + 'label' => array( + '#type' => 'textfield', + '#title' => 'Title', + '#maxlength' => 255, + '#default_value' => 'Custom Display Message', + '#required' => TRUE, + ), + 'label_display' => array( + '#type' => 'checkbox', + '#title' => 'Display title', + '#default_value' => TRUE, + '#return_value' => 'visible', + ), + 'display_message' => array( + '#type' => 'textfield', + '#title' => t('Display message'), + '#default_value' => 'My custom display message.', + ), + ); + $form_state = array(); + // Ensure there are no form elements that do not belong to the plugin. + $this->assertIdentical($display_block->form(array(), $form_state), $expected_form, 'Only the expected form elements were present.'); + + $expected_build = array( + '#theme' => 'block', + 'content' => array( + '#children' => 'My custom display message.', + ), + '#configuration' => array( + 'label' => 'Custom Display Message', + 'display_message' => 'My custom display message.', + 'module' => 'block_test', + 'label_display' => BLOCK_LABEL_VISIBLE, + 'cache' => DRUPAL_NO_CACHE, + ), + '#plugin_id' => 'test_block_instantiation', + ); + // Ensure the build array is proper. + $this->assertIdentical($display_block->build(), $expected_build, 'The plugin returned the appropriate build array.'); + } +} diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockLanguageTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockLanguageTest.php index f247648..69d5ccd 100644 --- a/core/modules/block/lib/Drupal/block/Tests/BlockLanguageTest.php +++ b/core/modules/block/lib/Drupal/block/Tests/BlockLanguageTest.php @@ -105,8 +105,8 @@ public function testLanguageBlockVisibilityLanguageDelete() { // Check that we have the language in config after saving the setting. $visibility = $block->get('visibility'); - $setting = $visibility['language']['langcodes']['fr']; - $this->assertTrue('fr' === $setting, 'Language is set in the block configuration.'); + $language = $visibility['language']['langcodes']['fr']; + $this->assertTrue('fr' === $language, 'Language is set in the block configuration.'); // Delete the language. $this->drupalPost('admin/config/regional/language/delete/fr', array(), t('Delete')); diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockStorageUnitTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockStorageUnitTest.php index af060db..dfc3b61 100644 --- a/core/modules/block/lib/Drupal/block/Tests/BlockStorageUnitTest.php +++ b/core/modules/block/lib/Drupal/block/Tests/BlockStorageUnitTest.php @@ -69,6 +69,7 @@ protected function createTests() { // Attempt to create a block without a plugin. try { $entity = $this->controller->create(array()); + $entity->getPlugin(); $this->fail('A block without a plugin was created with no exception thrown.'); } catch (PluginException $e) { @@ -92,19 +93,18 @@ protected function createTests() { // Ensure that default values are filled in. $expected_properties = array( 'id' => 'stark.test_block', - 'label' => '', - 'label_display' => BLOCK_LABEL_VISIBLE, - 'region' => '-1', 'weight' => '', - 'module' => 'block_test', 'status' => '1', - 'visibility' => array(), + 'langcode' => language_default()->langcode, + 'region' => '-1', 'plugin' => 'test_html_id', 'settings' => array( 'cache' => '1', - 'admin_label' => t('Test block html id'), + 'label' => '', + 'module' => 'block_test', + 'label_display' => BLOCK_LABEL_VISIBLE, ), - 'langcode' => language_default()->langcode, + 'visibility' => '', ); $this->assertIdentical($actual_properties, $expected_properties, 'The block properties are exported correctly.'); @@ -124,7 +124,6 @@ protected function loadTests() { $this->assertEqual($entity->get('region'), '-1'); $this->assertTrue($entity->get('status')); $this->assertEqual($entity->get('theme'), 'stark'); - $this->assertEqual($entity->get('module'), 'block_test'); $this->assertTrue($entity->uuid()); } @@ -132,12 +131,8 @@ protected function loadTests() { * Tests the rendering of blocks. */ protected function renderTests() { - $entity = $this->controller->create(array( - 'id' => 'stark.test_block', - 'plugin' => 'test_html_id', - )); - // Test the rendering of a block. + $entity = entity_load('block', 'stark.test_block'); $output = entity_view($entity, 'block'); $expected = array(); $expected[] = '
'; @@ -154,10 +149,17 @@ protected function renderTests() { drupal_static_reset('drupal_html_id'); // Test the rendering of a block with a given title. - $entity->set('label', 'Powered by Bananas'); + $entity = $this->controller->create(array( + 'id' => 'stark.test_block2', + 'plugin' => 'test_html_id', + 'settings' => array( + 'label' => 'Powered by Bananas', + ), + )); + $entity->save(); $output = entity_view($entity, 'block'); $expected = array(); - $expected[] = '
'; + $expected[] = '
'; $expected[] = ''; $expected[] = '

Powered by Bananas

'; $expected[] = ' '; @@ -167,6 +169,8 @@ protected function renderTests() { $expected[] = ''; $expected_output = implode("\n", $expected); $this->assertEqual(drupal_render($output), $expected_output, 'The block rendered correctly.'); + // Clean up this entity. + $entity->delete(); } /** diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockTemplateSuggestionsUnitTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockTemplateSuggestionsUnitTest.php index 95f2cf1..9f3ffe1 100644 --- a/core/modules/block/lib/Drupal/block/Tests/BlockTemplateSuggestionsUnitTest.php +++ b/core/modules/block/lib/Drupal/block/Tests/BlockTemplateSuggestionsUnitTest.php @@ -45,12 +45,9 @@ 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']['#children'] = ''; + $variables['elements']['#configuration'] = $block->getPlugin()->getConfig(); + $variables['elements']['#plugin_id'] = $block->get('plugin'); + $variables['elements']['content'] = array(); // Test adding a class to the block content. $variables['content_attributes']['class'][] = 'test-class'; template_preprocess_block($variables); diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockTest.php index 9020087..75bcb39 100644 --- a/core/modules/block/lib/Drupal/block/Tests/BlockTest.php +++ b/core/modules/block/lib/Drupal/block/Tests/BlockTest.php @@ -34,7 +34,7 @@ function testBlockVisibility() { $edit = array( 'machine_name' => strtolower($this->randomName(8)), 'region' => 'sidebar_first', - 'label' => $title, + 'settings[label]' => $title, ); // Set the block to be hidden on any user path, and to be shown only to // authenticated users. @@ -75,7 +75,7 @@ function testBlockVisibilityListedEmpty() { $edit = array( 'machine_name' => strtolower($this->randomName(8)), 'region' => 'sidebar_first', - 'label' => $title, + 'settings[label]' => $title, 'visibility[path][visibility]' => BLOCK_VISIBILITY_LISTED, ); // Set the block to be hidden on any user path, and to be shown only to @@ -102,18 +102,18 @@ function testBlock() { // Select the 'Powered by Drupal' block to be configured and moved. $block = array(); $block['id'] = 'system_powered_by_block'; - $block['label'] = $this->randomName(8); + $block['settings[label]'] = $this->randomName(8); $block['machine_name'] = strtolower($this->randomName(8)); $block['theme'] = config('system.theme')->get('default'); $block['region'] = 'header'; // Set block title to confirm that interface works and override any custom titles. - $this->drupalPost('admin/structure/block/add/' . $block['id'] . '/' . $block['theme'], array('label' => $block['label'], 'machine_name' => $block['machine_name'], 'region' => $block['region']), t('Save block')); + $this->drupalPost('admin/structure/block/add/' . $block['id'] . '/' . $block['theme'], array('settings[label]' => $block['settings[label]'], 'machine_name' => $block['machine_name'], 'region' => $block['region']), t('Save block')); $this->assertText(t('The block configuration has been saved.'), 'Block title set.'); // Check to see if the block was created by checking its configuration. $instance = entity_load('block', $block['theme'] . '.' . $block['machine_name']); - $this->assertEqual($instance->label(), $block['label'], 'Stored block title found.'); + $this->assertEqual($instance->label(), $block['settings[label]'], 'Stored block title found.'); // Check whether the block can be moved to all available regions. foreach ($this->regions as $region) { @@ -130,7 +130,7 @@ function testBlock() { // Confirm that the block instance title and markup are not displayed. $this->drupalGet('node'); - $this->assertNoText(t($block['label'])); + $this->assertNoText(t($block['settings[label]'])); // Check for
if the machine name // is my_block_instance_name. $xpath = $this->buildXPathQuery('//div[@id=:id]/*', array(':id' => 'block-' . strtr(strtolower($block['machine_name']), '-', '_'))); @@ -150,7 +150,7 @@ function testHideBlockTitle() { $edit = array( 'machine_name' => $machine_name, 'region' => 'sidebar_first', - 'label' => $title, + 'settings[label]' => $title, ); $this->drupalPost('admin/structure/block/add/' . $block_name . '/' . $default_theme, $edit, t('Save block')); $this->assertText('The block configuration has been saved.', 'Block was saved'); @@ -159,7 +159,7 @@ function testHideBlockTitle() { $this->assertText($title, 'Block title was displayed by default.'); $edit = array( - 'label_display' => FALSE, + 'settings[label_display]' => FALSE, ); $this->drupalPost('admin/structure/block/manage/' . $default_theme . '.' . $machine_name . '/configure', $edit, t('Save block')); $this->assertText('The block configuration has been saved.', 'Block was saved'); @@ -192,7 +192,7 @@ function moveBlockToRegion(array $block, $region) { // Confirm that the block is being displayed. $this->drupalGet(''); - $this->assertText(t($block['label']), 'Block successfully being displayed on the page.'); + $this->assertText(t($block['settings[label]']), 'Block successfully being displayed on the page.'); // Confirm that the custom block was found at the proper region. $xpath = $this->buildXPathQuery('//div[@class=:region-class]//div[@id=:block-id]/*', array( @@ -225,8 +225,7 @@ function testBlockRehash() { $this->assertEqual($settings['cache'], DRUPAL_CACHE_PER_ROLE, 'Test block cache mode defaults to DRUPAL_CACHE_PER_ROLE.'); // Disable caching for this block. - $settings['cache'] = DRUPAL_NO_CACHE; - $block->set('settings', $settings); + $block->getPlugin()->setConfig('cache', DRUPAL_NO_CACHE); $block->save(); // Flushing all caches should call _block_rehash(). $this->resetAll(); @@ -290,13 +289,13 @@ function testBlockModuleDisable() { // Emulate a POST submission rather than using drupalPlaceBlock() to ensure // that the form still functions as expected. $edit = array( - 'label' => $this->randomName(8), + 'settings[label]' => $this->randomName(8), 'machine_name' => strtolower($this->randomName(8)), 'region' => 'sidebar_first', ); $this->drupalPost('admin/structure/block/add/system_powered_by_block/stark', $edit, t('Save block')); $this->assertText(t('The block configuration has been saved.')); - $this->assertText($edit['label']); + $this->assertText($edit['settings[label]']); // Update the weight of a block. $edit = array('blocks[stark.' . $edit['machine_name'] . '][weight]' => -1); diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockTitleXSSTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockTitleXSSTest.php index b04f9fc..7ac3648 100644 --- a/core/modules/block/lib/Drupal/block/Tests/BlockTitleXSSTest.php +++ b/core/modules/block/lib/Drupal/block/Tests/BlockTitleXSSTest.php @@ -32,10 +32,7 @@ public static function getInfo() { protected function setUp() { parent::setUp(); - $this->drupalPlaceBlock('test_xss_title', array( - 'label' => '', - 'machine_name' => 'test_xss_block', - )); + $this->drupalPlaceBlock('test_xss_title', array('label' => '')); } /** diff --git a/core/modules/block/lib/Drupal/block/Tests/Views/DisplayBlockTest.php b/core/modules/block/lib/Drupal/block/Tests/Views/DisplayBlockTest.php index 617f33d..7178e6c 100644 --- a/core/modules/block/lib/Drupal/block/Tests/Views/DisplayBlockTest.php +++ b/core/modules/block/lib/Drupal/block/Tests/Views/DisplayBlockTest.php @@ -90,13 +90,13 @@ protected function findBlockInstance(Block $block) { protected function testDeleteBlockDisplay() { // To test all combinations possible we first place create two instances // of the block display of the first view. - $block_1 = $this->drupalPlaceBlock('views_block:test_view_block-block_1', array(), array('title' => 'test_view_block-block_1:1')); - $block_2 = $this->drupalPlaceBlock('views_block:test_view_block-block_1', array(), array('title' => 'test_view_block-block_1:2')); + $block_1 = $this->drupalPlaceBlock('views_block:test_view_block-block_1', array('title' => 'test_view_block-block_1:1')); + $block_2 = $this->drupalPlaceBlock('views_block:test_view_block-block_1', array('title' => 'test_view_block-block_1:2')); // Then we add one instance of blocks for each of the two displays of the // second view. - $block_3 = $this->drupalPlaceBlock('views_block:test_view_block2-block_1', array(), array('title' => 'test_view_block2-block_1')); - $block_4 = $this->drupalPlaceBlock('views_block:test_view_block2-block_2', array(), array('title' => 'test_view_block2-block_2')); + $block_3 = $this->drupalPlaceBlock('views_block:test_view_block2-block_1', array('title' => 'test_view_block2-block_1')); + $block_4 = $this->drupalPlaceBlock('views_block:test_view_block2-block_2', array('title' => 'test_view_block2-block_2')); $this->drupalGet('test-page'); $this->assertBlockAppears($block_1); diff --git a/core/modules/block/templates/block.tpl.php b/core/modules/block/templates/block.tpl.php index 4b301fa..106dd6b 100644 --- a/core/modules/block/templates/block.tpl.php +++ b/core/modules/block/templates/block.tpl.php @@ -5,13 +5,15 @@ * Default theme implementation to display a block. * * Available variables: - * - $block->label: Block title. - * - $block->label_hidden: The hidden block title value if the block was - * configured to hide the title ($block->label is empty in this case). + * - $plugin_id: The ID of the block implementation. + * - $label: The configured label of the block if visible. + * - $configuration: An array of the block's configuration values. + * - label: The configured label for the block. + * - label_display: The display settings for the label. + * - module: The module that provided this block plugin. + * - cache: The cache settings. + * - Block plugin specific settings will also be stored here. * - $content: Block content. - * - $block->module: Module that generated the block. - * - $block->delta: An ID for the block, unique within each module. - * - $block->region: The block region embedding the current block. * - $attributes: An instance of Attributes class that can be manipulated as an * array and printed as a string. * It includes the 'class' information, which includes: @@ -46,12 +48,12 @@ -label): ?> - >label; ?> + + > > - +
diff --git a/core/modules/block/tests/config/block.block.stark.test_block.yml b/core/modules/block/tests/config/block.block.stark.test_block.yml index 59ba7b4..e8b5ade 100644 --- a/core/modules/block/tests/config/block.block.stark.test_block.yml +++ b/core/modules/block/tests/config/block.block.stark.test_block.yml @@ -1,11 +1,20 @@ id: stark.test_block -label: '' -region: '-1' weight: '' -module: block_test status: '1' -visibility: { } +langcode: en +region: '-1' plugin: test_html_id settings: + label: 'Test block html id"' + module: block_test + label_display: '0' cache: '1' - admin_label: 'Test block html id' +visibility: + path: + visibility: '0' + pages: '' + role: + roles: { } + node_type: + types: { } + visibility__active_tab: edit-visibility-path diff --git a/core/modules/block/tests/lib/Drupal/block_test/Plugin/Block/TestBlockInstantiation.php b/core/modules/block/tests/lib/Drupal/block_test/Plugin/Block/TestBlockInstantiation.php new file mode 100644 index 0000000..ba45a4e --- /dev/null +++ b/core/modules/block/tests/lib/Drupal/block_test/Plugin/Block/TestBlockInstantiation.php @@ -0,0 +1,69 @@ + 'no message set', + ); + } + + /** + * {@inheritdoc} + */ + public function access() { + return user_access('access content'); + } + + /** + * {@inheritdoc} + */ + public function blockForm($form, &$form_state) { + $form['display_message'] = array( + '#type' => 'textfield', + '#title' => t('Display message'), + '#default_value' => $this->configuration['display_message'], + ); + return $form; + } + + /** + * {@inheritdoc} + */ + public function blockSubmit($form, &$form_state) { + $this->configuration['display_message'] = $form_state['values']['display_message']; + } + + /** + * {@inheritdoc} + */ + protected function blockBuild() { + return array( + '#children' => $this->configuration['display_message'], + ); + } + +} diff --git a/core/modules/book/book.module b/core/modules/book/book.module index a94b8f2..887f95f 100644 --- a/core/modules/book/book.module +++ b/core/modules/book/book.module @@ -962,7 +962,7 @@ function _book_link_defaults($nid) { * Implements hook_preprocess_HOOK() for block.tpl.php. */ function book_preprocess_block(&$variables) { - if ($variables['block']-> module == 'book') { + if ($variables['configuration']['module'] == 'book') { $variables['attributes']['role'] = 'navigation'; } } diff --git a/core/modules/book/lib/Drupal/book/Tests/BookTest.php b/core/modules/book/lib/Drupal/book/Tests/BookTest.php index fd5d4c0..eba9ff9 100644 --- a/core/modules/book/lib/Drupal/book/Tests/BookTest.php +++ b/core/modules/book/lib/Drupal/book/Tests/BookTest.php @@ -338,7 +338,7 @@ function testBookNavigationBlock() { */ function testNavigationBlockOnAccessModuleEnabled() { $this->drupalLogin($this->admin_user); - $block = $this->drupalPlaceBlock('book_navigation', array(), array('block_mode' => 'book pages')); + $block = $this->drupalPlaceBlock('book_navigation', array('block_mode' => 'book pages')); // Give anonymous users the permission 'node test view'. $edit = array(); diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index 6d0d003..7d848d6 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -1530,7 +1530,7 @@ function comment_preview(Comment $comment) { * Implements hook_preprocess_HOOK() for block.tpl.php. */ function comment_preprocess_block(&$variables) { - if ($variables['block']->module == 'comment') { + if ($variables['configuration']['module'] == 'comment') { $variables['attributes']['role'] = 'navigation'; } } diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/Block/RecentCommentsBlock.php b/core/modules/comment/lib/Drupal/comment/Plugin/Block/RecentCommentsBlock.php index 14601c0..387f7ce 100644 --- a/core/modules/comment/lib/Drupal/comment/Plugin/Block/RecentCommentsBlock.php +++ b/core/modules/comment/lib/Drupal/comment/Plugin/Block/RecentCommentsBlock.php @@ -34,7 +34,7 @@ public function settings() { /** * Overrides \Drupal\block\BlockBase::access(). */ - public function blockAccess() { + public function access() { return user_access('access comments'); } diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentBlockTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentBlockTest.php index 901d325..89f81b1 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentBlockTest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentBlockTest.php @@ -46,7 +46,7 @@ public static function getInfo() { */ function testRecentCommentBlock() { $this->drupalLogin($this->admin_user); - $block = $this->drupalPlaceBlock('recent_comments', array(), array('block_count' => 2)); + $block = $this->drupalPlaceBlock('recent_comments', array('block_count' => 2)); // Add some test comments, one without a subject. $comment1 = $this->postComment($this->node, $this->randomName(), $this->randomName()); @@ -78,7 +78,7 @@ function testRecentCommentBlock() { $this->assertTrue(strpos($this->drupalGetContent(), $comment3->comment_body->value) < strpos($this->drupalGetContent(), $comment2->subject->value), 'Comments were ordered correctly in block.'); // Set the number of recent comments to show to 10. - $block->set('settings', array('block_count' => 10)); + $block->getPlugin()->setConfig('block_count', 10); $block->save(); // Post an additional comment. diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module index af1330e..20e8631 100644 --- a/core/modules/forum/forum.module +++ b/core/modules/forum/forum.module @@ -649,7 +649,8 @@ function forum_form_node_form_alter(&$form, &$form_state, $form_id) { * * This function can be used as a #pre_render callback. * - * @see forum_block_view() + * @see \Drupal\forum\Plugin\block\block\NewTopicsBlock::blockBuild() + * @see \Drupal\forum\Plugin\block\block\ActiveTopicsBlock::blockBuild() */ function forum_block_view_pre_render($elements) { $result = $elements['#query']->execute(); @@ -972,7 +973,7 @@ function forum_get_topics($tid, $sortby, $forum_per_page) { * Implements hook_preprocess_HOOK() for block.tpl.php. */ function forum_preprocess_block(&$variables) { - if ($variables['block']->module == 'forum') { + if ($variables['configuration']['module'] == 'forum') { $variables['attributes']['role'] = 'navigation'; } } diff --git a/core/modules/forum/lib/Drupal/forum/Plugin/Block/ForumBlockBase.php b/core/modules/forum/lib/Drupal/forum/Plugin/Block/ForumBlockBase.php index 4d9d64c..cbdfc79 100644 --- a/core/modules/forum/lib/Drupal/forum/Plugin/Block/ForumBlockBase.php +++ b/core/modules/forum/lib/Drupal/forum/Plugin/Block/ForumBlockBase.php @@ -28,9 +28,9 @@ public function settings() { } /** - * Overrides \Drupal\block\BlockBase::blockAccess(). + * Overrides \Drupal\block\BlockBase::access(). */ - public function blockAccess() { + public function access() { return user_access('access content'); } diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php index 02314e8..65dd7c2 100644 --- a/core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php +++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php @@ -71,7 +71,7 @@ public function testNewForumTopicsBlock() { } // Configure the new forum topics block to only show 2 topics. - $block->set('settings', array('block_count' => 2)); + $block->getPlugin()->setConfig('block_count', 2); $block->save(); $this->drupalGet(''); @@ -132,7 +132,7 @@ public function testActiveForumTopicsBlock() { } // Configure the active forum block to only show 2 topics. - $block->set('settings', array('block_count' => 2)); + $block->getPlugin()->setConfig('block_count', 2); $block->save(); $this->drupalGet(''); diff --git a/core/modules/help/help.module b/core/modules/help/help.module index be57134..d7042d3 100644 --- a/core/modules/help/help.module +++ b/core/modules/help/help.module @@ -69,7 +69,7 @@ function help_help($path, $arg) { * Implements hook_preprocess_HOOK() for block.tpl.php. */ function help_preprocess_block(&$variables) { - if ($variables['block']->id == 'system_help_block') { + if ($variables['plugin_id'] == 'system_help_block') { $variables['attributes']['role'] = 'complementary'; } } diff --git a/core/modules/language/language.module b/core/modules/language/language.module index 2f2966c..6294f31 100644 --- a/core/modules/language/language.module +++ b/core/modules/language/language.module @@ -763,7 +763,7 @@ function language_language_delete($language) { * Implements hook_preprocess_HOOK() for block.tpl.php. */ function language_preprocess_block(&$variables) { - if ($variables['block']->module == 'language') { + if ($variables['configuration']['module'] == 'language') { $variables['attributes']['role'] = 'navigation'; } } diff --git a/core/modules/language/lib/Drupal/language/Plugin/Block/LanguageBlock.php b/core/modules/language/lib/Drupal/language/Plugin/Block/LanguageBlock.php index 3c64703..4ab3bfd 100644 --- a/core/modules/language/lib/Drupal/language/Plugin/Block/LanguageBlock.php +++ b/core/modules/language/lib/Drupal/language/Plugin/Block/LanguageBlock.php @@ -24,9 +24,9 @@ class LanguageBlock extends BlockBase { /** - * Overrides \Drupal\block\BlockBase::blockAccess(). + * Overrides \Drupal\block\BlockBase::access(). */ - function blockAccess() { + function access() { return language_multilingual(); } diff --git a/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php b/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php index 89287f5..f3a4391 100644 --- a/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php +++ b/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php @@ -16,7 +16,7 @@ class MenuTest extends WebTestBase { * * @var array */ - public static $modules = array('menu', 'block', 'test_page_test'); + public static $modules = array('menu', 'block', 'test_page_test', 'contextual'); protected $big_user; protected $std_user; @@ -303,6 +303,17 @@ function testSystemMenuRename() { } /** + * Tests the contextual links on a menu block. + */ + public function testBlockContextualLinks() { + $this->drupalLogin($this->drupalCreateUser(array('administer menu', 'access contextual links'))); + $this->addMenuLink(); + $this->drupalPlaceBlock('system_menu_block:menu-tools', array('label' => 'Tools', 'module' => 'system')); + $this->drupalGet('test-page'); + $this->assertLinkByHref("admin/structure/menu/manage/tools/edit"); + } + + /** * Add a menu link using the menu module UI. * * @param integer $plid Parent menu link id. diff --git a/core/modules/menu/menu.module b/core/modules/menu/menu.module index b638917..93c2ed8 100644 --- a/core/modules/menu/menu.module +++ b/core/modules/menu/menu.module @@ -12,9 +12,8 @@ */ use Drupal\Core\Entity\EntityInterface; -use Drupal\block\Plugin\Core\Entity\Block; +use Drupal\block\BlockPluginInterface; use Drupal\system\Plugin\Core\Entity\Menu; -use Drupal\system\Plugin\Block\SystemMenuBlock; use Symfony\Component\HttpFoundation\JsonResponse; use Drupal\menu_link\Plugin\Core\Entity\MenuLink; use Drupal\menu_link\MenuLinkStorageController; @@ -399,13 +398,13 @@ function _menu_parents_recurse($tree, $menu_name, $indent, &$options, $exclude, } /** - * Implements hook_block_view_alter(). + * Implements hook_block_view_BASE_BLOCK_ID_alter() for 'system_menu_block'. */ -function menu_block_view_alter(array &$build, Block $block) { +function menu_block_view_system_menu_block_alter(array &$build, BlockPluginInterface $block) { // Add contextual links for system menu blocks. - if ($block->getPlugin() instanceof SystemMenuBlock) { + if (isset($build['content'])) { foreach (element_children($build['content']) as $key) { - $build['#contextual_links']['menu'] = array('admin/structure/menu/manage', array($build['content'][$key]['#original_link']['menu_name'])); + $build['content']['#contextual_links']['menu'] = array('admin/structure/menu/manage', array($build['content'][$key]['#original_link']['menu_name'])); } } } @@ -717,7 +716,7 @@ function menu_get_menus($all = TRUE) { * Implements hook_preprocess_HOOK() for block.tpl.php. */ function menu_preprocess_block(&$variables) { - if ($variables['block']->module == 'menu') { + if ($variables['configuration']['module'] == 'menu') { $variables['attributes']['role'] = 'navigation'; } } diff --git a/core/modules/node/lib/Drupal/node/Plugin/Block/RecentContentBlock.php b/core/modules/node/lib/Drupal/node/Plugin/Block/RecentContentBlock.php index bc0c2c1..3712bff 100644 --- a/core/modules/node/lib/Drupal/node/Plugin/Block/RecentContentBlock.php +++ b/core/modules/node/lib/Drupal/node/Plugin/Block/RecentContentBlock.php @@ -32,9 +32,9 @@ public function settings() { } /** - * Overrides \Drupal\block\BlockBase::blockAccess(). + * Overrides \Drupal\block\BlockBase::access(). */ - public function blockAccess() { + public function access() { return user_access('access content'); } diff --git a/core/modules/node/lib/Drupal/node/Plugin/Block/SyndicateBlock.php b/core/modules/node/lib/Drupal/node/Plugin/Block/SyndicateBlock.php index a0df392..56b3a19 100644 --- a/core/modules/node/lib/Drupal/node/Plugin/Block/SyndicateBlock.php +++ b/core/modules/node/lib/Drupal/node/Plugin/Block/SyndicateBlock.php @@ -32,9 +32,9 @@ public function settings() { } /** - * Overrides \Drupal\block\BlockBase::blockAccess(). + * Overrides \Drupal\block\BlockBase::access(). */ - public function blockAccess() { + public function access() { return user_access('access content'); } diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeBlockFunctionalTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeBlockFunctionalTest.php index 3beb969..92e181c 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeBlockFunctionalTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeBlockFunctionalTest.php @@ -61,7 +61,7 @@ public function testRecentNodeBlock() { )); // Enable the recent content block with two items. - $block = $this->drupalPlaceBlock('node_recent_block', array('machine_name' => 'test_block'), array('block_count' => 2)); + $block = $this->drupalPlaceBlock('node_recent_block', array('machine_name' => 'test_block', 'block_count' => 2)); // Test that block is not visible without nodes. $this->drupalGet(''); @@ -106,7 +106,7 @@ public function testRecentNodeBlock() { $this->drupalLogin($this->adminUser); // Set the number of recent nodes to show to 10. - $block->set('settings', array('block_count' => 10)); + $block->getPlugin()->setConfig('block_count', 10); $block->save(); // Post an additional node. diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 7ba5d23..0605169 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -1099,8 +1099,8 @@ function node_is_page(EntityInterface $node) { * Implements hook_preprocess_HOOK() for block.tpl.php. */ function node_preprocess_block(&$variables) { - if ($variables['block']->module == 'node') { - switch ($variables['block']->id) { + if ($variables['configuration']['module'] == 'node') { + switch ($variables['elements']['#plugin_id']) { case 'node_syndicate_block': $variables['attributes']['role'] = 'complementary'; break; diff --git a/core/modules/openid/openid.module b/core/modules/openid/openid.module index ad4da7b..1be4734 100644 --- a/core/modules/openid/openid.module +++ b/core/modules/openid/openid.module @@ -6,6 +6,7 @@ */ use Guzzle\Http\Exception\RequestException; +use Drupal\block\BlockPluginInterface; /** * Implements hook_menu(). @@ -160,13 +161,13 @@ function openid_user_logout($account) { } /** - * Implements hook_block_view_MODULE_DELTA_alter(). + * Implements hook_block_view_BASE_BLOCK_ID_alter() for 'user_login_block'. * * 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(array &$build, BlockPluginInterface $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 db034f9..31289d5 100644 --- a/core/modules/overlay/overlay.module +++ b/core/modules/overlay/overlay.module @@ -7,6 +7,8 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Drupal\block\Plugin\Core\Entity\Block; +use Drupal\user\Plugin\Core\Entity\User; /** * Implements hook_help(). @@ -453,7 +455,7 @@ function theme_overlay_disable_message($variables) { /** * Implements hook_block_access(). */ -function overlay_block_access($block) { +function overlay_block_access(Block $block, $operation, User $account, $langcode) { // If we are limiting rendering to a subset of page regions, hide all blocks // which appear in regions not on that list. Note that overlay_page_alter() // does a more comprehensive job of preventing unwanted regions from being diff --git a/core/modules/search/lib/Drupal/search/Plugin/Block/SearchBlock.php b/core/modules/search/lib/Drupal/search/Plugin/Block/SearchBlock.php index 032fb5a..1afbfae 100644 --- a/core/modules/search/lib/Drupal/search/Plugin/Block/SearchBlock.php +++ b/core/modules/search/lib/Drupal/search/Plugin/Block/SearchBlock.php @@ -23,9 +23,9 @@ class SearchBlock extends BlockBase { /** - * Overrides \Drupal\block\BlockBase::blockAccess(). + * Overrides \Drupal\block\BlockBase::access(). */ - public function blockAccess() { + public function access() { return user_access('search content'); } diff --git a/core/modules/search/search.module b/core/modules/search/search.module index 6501a85..f31488b 100644 --- a/core/modules/search/search.module +++ b/core/modules/search/search.module @@ -135,10 +135,10 @@ function search_permission() { } /** - * Implements hook_preprocess_block(). + * Implements hook_preprocess_HOOK() for block.tpl.php. */ function search_preprocess_block(&$variables) { - if ($variables['block']->id == 'search_form_block') { + if ($variables['plugin_id'] == 'search_form_block') { $variables['attributes']['role'] = 'search'; $variables['content_attributes']['class'][] = 'container-inline'; } diff --git a/core/modules/shortcut/shortcut.module b/core/modules/shortcut/shortcut.module index c2c9b4a..ba7bacc 100644 --- a/core/modules/shortcut/shortcut.module +++ b/core/modules/shortcut/shortcut.module @@ -454,7 +454,7 @@ function shortcut_renderable_links($shortcut_set = NULL) { * Implements hook_preprocess_HOOK() for block.tpl.php. */ function shortcut_preprocess_block(&$variables) { - if ($variables['block']->module == 'shortcut') { + if ($variables['configuration']['module'] == 'shortcut') { $variables['attributes']['role'] = 'navigation'; } } diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php index 3520613..76988fa 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php @@ -342,8 +342,8 @@ protected function drupalCreateContentType($settings = array()) { * * @param string $plugin_id * The plugin ID of the block type for this block instance. - * @param array $values - * (optional) An associative array of values for the block entity. + * @param array $settings + * (optional) An associative array of settings for the block entity. * Override the defaults by specifying the key and value in the array, for * example: * @code @@ -356,8 +356,7 @@ protected function drupalCreateContentType($settings = array()) { * - machine_name: Random string. * - region: 'sidebar_first'. * - theme: The default theme. - * @param array $settings - * (optional) An associative array of plugin-specific settings. + * - visibility: Empty array. * * @return \Drupal\block\Plugin\Core\Entity\Block * The block entity. @@ -365,15 +364,20 @@ protected function drupalCreateContentType($settings = array()) { * @todo * Add support for creating custom block instances. */ - protected function drupalPlaceBlock($plugin_id, array $values = array(), array $settings = array()) { - $values += array( + protected function drupalPlaceBlock($plugin_id, array $settings = array()) { + $settings += array( 'plugin' => $plugin_id, - 'label' => $this->randomName(8), 'region' => 'sidebar_first', - 'theme' => config('system.theme')->get('default'), 'machine_name' => strtolower($this->randomName(8)), - 'settings' => $settings, + 'theme' => config('system.theme')->get('default'), + 'label' => $this->randomName(8), + 'visibility' => array(), ); + foreach (array('region', 'machine_name', 'theme', 'plugin', 'visibility') as $key) { + $values[$key] = $settings[$key]; + unset($settings[$key]); + } + $values['settings'] = $settings; // Build the ID out of the theme and machine_name. $values['id'] = $values['theme'] . '.' . $values['machine_name']; $block = entity_create('block', $values); diff --git a/core/modules/statistics/lib/Drupal/statistics/Plugin/Block/StatisticsPopularBlock.php b/core/modules/statistics/lib/Drupal/statistics/Plugin/Block/StatisticsPopularBlock.php index 46e97b8..6eebb83 100644 --- a/core/modules/statistics/lib/Drupal/statistics/Plugin/Block/StatisticsPopularBlock.php +++ b/core/modules/statistics/lib/Drupal/statistics/Plugin/Block/StatisticsPopularBlock.php @@ -55,9 +55,9 @@ public function settings() { } /** - * Overrides \Drupal\block\BlockBase::blockAccess(). + * Overrides \Drupal\block\BlockBase::access(). */ - public function blockAccess() { + public function access() { if (user_access('access content')) { $daytop = $this->configuration['top_day_num']; if (!$daytop || !($result = statistics_title_list('daycount', $daytop)) || !($this->day_list = node_title_list($result, t("Today's:")))) { diff --git a/core/modules/statistics/lib/Drupal/statistics/Tests/StatisticsReportsTest.php b/core/modules/statistics/lib/Drupal/statistics/Tests/StatisticsReportsTest.php index ed14bb0..b897f99 100644 --- a/core/modules/statistics/lib/Drupal/statistics/Tests/StatisticsReportsTest.php +++ b/core/modules/statistics/lib/Drupal/statistics/Tests/StatisticsReportsTest.php @@ -41,7 +41,8 @@ function testPopularContentBlock() { $client->post($stats_path, $headers, $post)->send(); // Configure and save the block. - $this->drupalPlaceBlock('statistics_popular_block', array('label' => 'Popular content'), array( + $this->drupalPlaceBlock('statistics_popular_block', array( + 'label' => 'Popular content', 'top_day_num' => 3, 'top_all_num' => 3, 'top_last_num' => 3, diff --git a/core/modules/statistics/statistics.module b/core/modules/statistics/statistics.module index 66842a5..9d0c19e 100644 --- a/core/modules/statistics/statistics.module +++ b/core/modules/statistics/statistics.module @@ -237,7 +237,7 @@ function statistics_update_index() { * Implements hook_preprocess_HOOK() for block.tpl.php. */ function statistics_preprocess_block(&$variables) { - if ($variables['block']->module == 'statistics') { + if ($variables['configuration']['module'] == 'statistics') { $variables['attributes']['role'] = 'navigation'; } } diff --git a/core/modules/system/lib/Drupal/system/Plugin/Block/SystemHelpBlock.php b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemHelpBlock.php index 9e12112..a370374 100644 --- a/core/modules/system/lib/Drupal/system/Plugin/Block/SystemHelpBlock.php +++ b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemHelpBlock.php @@ -30,9 +30,9 @@ class SystemHelpBlock extends BlockBase { protected $help; /** - * Overrides \Drupal\block\BlockBase::blockAccess(). + * Overrides \Drupal\block\BlockBase::access(). */ - public function blockAccess() { + public function access() { $this->help = menu_get_active_help(); return (bool) $this->help; } diff --git a/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php index dd31fe3..847249e 100644 --- a/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php +++ b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php @@ -24,9 +24,9 @@ class SystemMenuBlock extends BlockBase { /** - * Overrides \Drupal\block\BlockBase::blockAccess(). + * Overrides \Drupal\block\BlockBase::access(). */ - public function blockAccess() { + public function access() { // @todo The 'Tools' menu should be available to anonymous users. list($plugin, $derivative) = explode(':', $this->getPluginId()); return ($GLOBALS['user']->uid || in_array($derivative, array('menu-main', 'menu-tools', 'menu-footer'))); diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/BlockUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/BlockUpgradePathTest.php index b9129e3..45f2efb 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/BlockUpgradePathTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/BlockUpgradePathTest.php @@ -42,16 +42,16 @@ public function testBlockUpgradeTitleLength() { // Add a block instance with a 255-character title. // Confirm that the custom block has been created, and title matches input. $settings = array( - 'label' => $this->randomName(255), + 'settings[label]' => $this->randomName(255), 'machine_name' => strtolower($this->randomName(8)), 'region' => 'sidebar_first', ); $this->drupalPost('admin/structure/block/add/system_powered_by_block/' . config('system.theme')->get('default'), $settings, t('Save block')); - $this->assertText($settings['label'], 'Block with title longer than 64 characters successfully created.'); + $this->assertText($settings['settings[label]'], 'Block with title longer than 64 characters successfully created.'); // Try to add a block with a title over 255 characters. $settings = array( - 'label' => $this->randomName(256), + 'settings[label]' => $this->randomName(256), 'machine_name' => strtolower($this->randomName(8)), 'region' => 'sidebar_first', ); diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 614cec7..c75309c 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -2718,20 +2718,18 @@ function system_user_timezone(&$form, &$form_state) { * Implements hook_preprocess_HOOK() for block.tpl.php. */ function system_preprocess_block(&$variables) { - switch ($variables['block']->id) { + // Derive the base plugin ID. + list($plugin_id) = explode(':', $variables['plugin_id'] . ':'); + switch ($plugin_id) { case 'system_powered_by_block': $variables['attributes_array']['role'] = 'complementary'; break; case 'system_help_block': $variables['attributes_array']['role'] = 'complementary'; break; - - // System menu blocks should get the same class as menu module blocks. - default: - if ($variables['elements']['#block']->getPlugin() instanceof SystemMenuBlock) { - $variables['attributes_array']['role'] = 'navigation'; - $variables['classes_array'][] = 'block-menu'; - } + case 'system_menu_block': + $variables['attributes']['role'] = 'navigation'; + $variables['attributes']['classes'][] = 'block-menu'; } } diff --git a/core/modules/user/lib/Drupal/user/Plugin/Block/UserLoginBlock.php b/core/modules/user/lib/Drupal/user/Plugin/Block/UserLoginBlock.php index 6f1486e..dd890bd 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/Block/UserLoginBlock.php +++ b/core/modules/user/lib/Drupal/user/Plugin/Block/UserLoginBlock.php @@ -23,9 +23,9 @@ class UserLoginBlock extends BlockBase { /** - * Overrides \Drupal\block\BlockBase::blockAccess(). + * Overrides \Drupal\block\BlockBase::access(). */ - public function blockAccess() { + public function access() { return (!$GLOBALS['user']->uid && !(arg(0) == 'user' && !is_numeric(arg(1)))); } diff --git a/core/modules/user/lib/Drupal/user/Plugin/Block/UserNewBlock.php b/core/modules/user/lib/Drupal/user/Plugin/Block/UserNewBlock.php index b9e1728..41c2a43 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/Block/UserNewBlock.php +++ b/core/modules/user/lib/Drupal/user/Plugin/Block/UserNewBlock.php @@ -35,9 +35,9 @@ public function settings() { } /** - * Overrides \Drupal\block\BlockBase::blockAccess(). + * Overrides \Drupal\block\BlockBase::access(). */ - public function blockAccess() { + public function access() { return user_access('access content'); } diff --git a/core/modules/user/lib/Drupal/user/Plugin/Block/UserOnlineBlock.php b/core/modules/user/lib/Drupal/user/Plugin/Block/UserOnlineBlock.php index cad0da0..fbae351 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/Block/UserOnlineBlock.php +++ b/core/modules/user/lib/Drupal/user/Plugin/Block/UserOnlineBlock.php @@ -39,9 +39,9 @@ public function settings() { } /** - * Overrides \Drupal\block\BlockBase::blockAccess(). + * Overrides \Drupal\block\BlockBase::access(). */ - public function blockAccess() { + public function access() { return user_access('access content'); } diff --git a/core/modules/user/user.module b/core/modules/user/user.module index ed3078c..3ae6154 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -663,8 +663,8 @@ function user_validate_current_pass(&$form, &$form_state) { * Implements hook_preprocess_HOOK() for block.tpl.php. */ function user_preprocess_block(&$variables) { - if ($variables['block']->module == 'user') { - switch ($variables['block']->id) { + if ($variables['configuration']['module'] == 'user') { + switch ($variables['elements']['#plugin_id']) { case 'user_login_block': $variables['attributes']['role'] = 'form'; break; diff --git a/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlock.php b/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlock.php index 0d42a89..1e2bfd5 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlock.php +++ b/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlock.php @@ -8,7 +8,6 @@ namespace Drupal\views\Plugin\Block; use Drupal\block\BlockBase; -use Drupal\block\Plugin\Core\Entity\Block; use Drupal\Component\Annotation\Plugin; use Drupal\Core\Annotation\Translation; @@ -41,8 +40,8 @@ class ViewsBlock extends BlockBase { /** * Overrides \Drupal\Component\Plugin\PluginBase::__construct(). */ - public function __construct(array $configuration, $plugin_id, array $plugin_definition, Block $entity) { - parent::__construct($configuration, $plugin_id, $plugin_definition, $entity); + public function __construct(array $configuration, $plugin_id, array $plugin_definition) { + parent::__construct($configuration, $plugin_id, $plugin_definition); list($plugin, $delta) = explode(':', $this->getPluginId()); list($name, $this->displayID) = explode('-', $delta, 2); @@ -52,9 +51,9 @@ public function __construct(array $configuration, $plugin_id, array $plugin_defi } /** - * Overrides \Drupal\block\BlockBase::blockAccess(). + * Overrides \Drupal\block\BlockBase::access(). */ - public function blockAccess() { + public function access() { return $this->view->access($this->displayID); } @@ -76,7 +75,7 @@ public function form($form, &$form_state) { protected function blockBuild() { $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); diff --git a/core/modules/views/views.module b/core/modules/views/views.module index 581c04b..02d7791 100644 --- a/core/modules/views/views.module +++ b/core/modules/views/views.module @@ -560,7 +560,7 @@ function views_contextual_links_view_alter(&$element, $items) { * @param $display_id * The ID of the display within $view whose contextual links will be added. * - * @see views_block_view() + * @see \Drupal\views\Plugin\block\block\ViewsBlock::addContextualLinks() * @see views_page_alter() * @see template_preprocess_views_view() */ diff --git a/core/profiles/minimal/config/block.block.stark.admin.yml b/core/profiles/minimal/config/block.block.stark.admin.yml index e84cdbe..d67096f 100644 --- a/core/profiles/minimal/config/block.block.stark.admin.yml +++ b/core/profiles/minimal/config/block.block.stark.admin.yml @@ -1,9 +1,14 @@ id: stark.admin -label: Administration -region: sidebar_first weight: '1' -module: system status: '1' +langcode: en +region: sidebar_first +plugin: 'system_menu_block:menu-admin' +settings: + label: Administration + module: system + label_display: visible + cache: '-1' visibility: path: visibility: '0' @@ -13,7 +18,3 @@ visibility: node_type: types: { } visibility__active_tab: edit-visibility-path -plugin: 'system_menu_block:menu-admin' -settings: - cache: '-1' -label_display: visible diff --git a/core/profiles/minimal/config/block.block.stark.login.yml b/core/profiles/minimal/config/block.block.stark.login.yml index ba8a66d..b15e395 100644 --- a/core/profiles/minimal/config/block.block.stark.login.yml +++ b/core/profiles/minimal/config/block.block.stark.login.yml @@ -1,9 +1,14 @@ id: stark.login -label: 'User login' -region: sidebar_first weight: '0' -module: user status: '1' +langcode: en +region: sidebar_first +plugin: user_login_block +settings: + label: 'User login' + module: user + label_display: visible + cache: '-1' visibility: path: visibility: '0' @@ -13,7 +18,3 @@ visibility: node_type: types: { } visibility__active_tab: edit-visibility-path -plugin: user_login_block -settings: - cache: '-1' -label_display: visible diff --git a/core/profiles/minimal/config/block.block.stark.tools.yml b/core/profiles/minimal/config/block.block.stark.tools.yml index dda5b98..6901d44 100644 --- a/core/profiles/minimal/config/block.block.stark.tools.yml +++ b/core/profiles/minimal/config/block.block.stark.tools.yml @@ -1,9 +1,14 @@ id: stark.tools -label: Tools -region: sidebar_first weight: '0' -module: system status: '1' +langcode: en +region: sidebar_first +plugin: 'system_menu_block:menu-tools' +settings: + label: Tools + module: system + label_display: visible + cache: '-1' visibility: path: visibility: '0' @@ -13,7 +18,3 @@ visibility: node_type: types: { } visibility__active_tab: edit-visibility-path -plugin: 'system_menu_block:menu-tools' -settings: - cache: '-1' -label_display: visible diff --git a/core/profiles/standard/config/block.block.bartik.content.yml b/core/profiles/standard/config/block.block.bartik.content.yml index 07c3cdd..24b161c 100644 --- a/core/profiles/standard/config/block.block.bartik.content.yml +++ b/core/profiles/standard/config/block.block.bartik.content.yml @@ -1,7 +1,13 @@ id: bartik.content -plugin: system_main_block +weight: '0' status: '1' +langcode: en +region: content +plugin: system_main_block settings: + label: 'Main page content' + module: system + label_display: '0' cache: '-1' visibility: path: @@ -14,9 +20,3 @@ visibility: article: '0' page: '0' visibility__active_tab: edit-visibility-path -label: '' -module: system -region: content -weight: '0' -langcode: en -label_display: visible diff --git a/core/profiles/standard/config/block.block.bartik.footer.yml b/core/profiles/standard/config/block.block.bartik.footer.yml index 553edb7..65c77f0 100644 --- a/core/profiles/standard/config/block.block.bartik.footer.yml +++ b/core/profiles/standard/config/block.block.bartik.footer.yml @@ -1,9 +1,14 @@ id: bartik.footer -plugin: 'system_menu_block:menu-footer' +weight: '0' status: '1' +langcode: en +region: footer +plugin: 'system_menu_block:menu-footer' settings: + label: 'Footer menu' + module: system + label_display: visible cache: '-1' -label: 'Footer menu' visibility: path: visibility: '0' @@ -15,8 +20,3 @@ visibility: article: '0' page: '0' visibility__active_tab: edit-visibility-path -module: system -region: footer -weight: '0' -langcode: en -label_display: visible diff --git a/core/profiles/standard/config/block.block.bartik.help.yml b/core/profiles/standard/config/block.block.bartik.help.yml index 84395a6..11f7ec6 100644 --- a/core/profiles/standard/config/block.block.bartik.help.yml +++ b/core/profiles/standard/config/block.block.bartik.help.yml @@ -1,7 +1,13 @@ id: bartik.help -plugin: system_help_block +weight: '0' status: '1' +langcode: en +region: help +plugin: system_help_block settings: + label: 'System Help' + module: system + label_display: '0' cache: '-1' visibility: path: @@ -14,9 +20,3 @@ visibility: article: '0' page: '0' visibility__active_tab: edit-visibility-path -label: '' -module: system -region: help -weight: '0' -langcode: en -label_display: visible diff --git a/core/profiles/standard/config/block.block.bartik.login.yml b/core/profiles/standard/config/block.block.bartik.login.yml index aac6997..69e7f9b 100644 --- a/core/profiles/standard/config/block.block.bartik.login.yml +++ b/core/profiles/standard/config/block.block.bartik.login.yml @@ -1,7 +1,13 @@ id: bartik.login -whois_new_count: '5' +weight: '0' status: '1' +langcode: en +region: sidebar_first +plugin: user_login_block settings: + label: 'User login' + module: user + label_display: visible cache: '-1' visibility: path: @@ -14,10 +20,3 @@ visibility: article: '0' page: '0' visibility__active_tab: edit-visibility-path -label: 'User login' -module: user -region: sidebar_first -weight: '0' -plugin: user_login_block -langcode: en -label_display: visible diff --git a/core/profiles/standard/config/block.block.bartik.powered.yml b/core/profiles/standard/config/block.block.bartik.powered.yml index 48424f8..a8de940 100644 --- a/core/profiles/standard/config/block.block.bartik.powered.yml +++ b/core/profiles/standard/config/block.block.bartik.powered.yml @@ -1,7 +1,13 @@ id: bartik.powered -plugin: system_powered_by_block +weight: '10' status: '1' +langcode: en +region: footer +plugin: system_powered_by_block settings: + label: 'Powered by Drupal' + module: system + label_display: '0' cache: '-1' visibility: path: @@ -14,9 +20,3 @@ visibility: article: '0' page: '0' visibility__active_tab: edit-visibility-path -label: '' -module: system -region: footer -weight: '10' -langcode: en -label_display: visible diff --git a/core/profiles/standard/config/block.block.bartik.search.yml b/core/profiles/standard/config/block.block.bartik.search.yml index bcf0249..18f6a7c 100644 --- a/core/profiles/standard/config/block.block.bartik.search.yml +++ b/core/profiles/standard/config/block.block.bartik.search.yml @@ -1,7 +1,13 @@ id: bartik.search -plugin: search_form_block +weight: '-1' status: '1' +langcode: en +region: sidebar_first +plugin: search_form_block settings: + label: Search + module: search + label_display: visible cache: '-1' visibility: path: @@ -14,9 +20,3 @@ visibility: article: '0' page: '0' visibility__active_tab: edit-visibility-path -label: 'Search' -module: search -region: sidebar_first -weight: '-1' -langcode: en -label_display: visible diff --git a/core/profiles/standard/config/block.block.bartik.tools.yml b/core/profiles/standard/config/block.block.bartik.tools.yml index 56c8ba4..633e299 100644 --- a/core/profiles/standard/config/block.block.bartik.tools.yml +++ b/core/profiles/standard/config/block.block.bartik.tools.yml @@ -1,7 +1,13 @@ id: bartik.tools -plugin: 'system_menu_block:menu-tools' +weight: '0' status: '1' +langcode: en +region: sidebar_first +plugin: 'system_menu_block:menu-tools' settings: + label: Tools + module: system + label_display: visible cache: '-1' visibility: path: @@ -14,9 +20,3 @@ visibility: article: '0' page: '0' visibility__active_tab: edit-visibility-path -label: 'Tools' -module: system -region: sidebar_first -weight: '0' -langcode: en -label_display: visible diff --git a/core/profiles/standard/config/block.block.seven.content.yml b/core/profiles/standard/config/block.block.seven.content.yml index f14f147..1725800 100644 --- a/core/profiles/standard/config/block.block.seven.content.yml +++ b/core/profiles/standard/config/block.block.seven.content.yml @@ -1,7 +1,13 @@ id: seven.content -plugin: system_main_block +weight: '0' status: '1' +langcode: en +region: content +plugin: system_main_block settings: + label: 'Main page content' + module: system + label_display: '0' cache: '-1' visibility: path: @@ -14,9 +20,3 @@ visibility: article: '0' page: '0' visibility__active_tab: edit-visibility-path -label: '' -module: system -region: content -weight: '0' -langcode: en -label_display: visible diff --git a/core/profiles/standard/config/block.block.seven.help.yml b/core/profiles/standard/config/block.block.seven.help.yml index 075f518..132ee45 100644 --- a/core/profiles/standard/config/block.block.seven.help.yml +++ b/core/profiles/standard/config/block.block.seven.help.yml @@ -1,7 +1,13 @@ id: seven.help -plugin: system_help_block +weight: '0' status: '1' +langcode: en +region: help +plugin: system_help_block settings: + label: 'System Help' + module: system + label_display: '0' cache: '-1' visibility: path: @@ -14,9 +20,3 @@ visibility: article: '0' page: '0' visibility__active_tab: edit-visibility-path -label: '' -module: system -region: help -weight: '0' -langcode: en -label_display: visible diff --git a/core/profiles/standard/config/block.block.seven.login.yml b/core/profiles/standard/config/block.block.seven.login.yml index f0fb2b2..8ec1661 100644 --- a/core/profiles/standard/config/block.block.seven.login.yml +++ b/core/profiles/standard/config/block.block.seven.login.yml @@ -1,7 +1,13 @@ id: seven.login -plugin: user_login_block +weight: '10' status: '1' +langcode: en +region: content +plugin: user_login_block settings: + label: 'User login' + module: user + label_display: visible cache: '-1' visibility: path: @@ -14,9 +20,4 @@ visibility: article: '0' page: '0' visibility__active_tab: edit-visibility-path -label: 'User login' -module: user -region: content -weight: '10' -langcode: en -label_display: visible +