diff --git a/core/modules/block/lib/Drupal/block/BlockBase.php b/core/modules/block/lib/Drupal/block/BlockBase.php index 7d1356b..24633c0 100644 --- a/core/modules/block/lib/Drupal/block/BlockBase.php +++ b/core/modules/block/lib/Drupal/block/BlockBase.php @@ -8,6 +8,7 @@ namespace Drupal\block; use Drupal\Component\Plugin\PluginBase; +use Drupal\block\Plugin\Core\Entity\Block; /** * Defines a base block implementation that most blocks plugins will extend. @@ -19,25 +20,6 @@ abstract class BlockBase extends PluginBase implements BlockInterface { /** - * Implements \Drupal\block\BlockInterface::settings(). - * - * Most block plugins should not override this method. To add additional - * settings or change the default values for setting, override - * BlockBase::blockSettings(). - * - * @see \Drupal\block\BlockBase::blockSettings() - */ - public function settings() { - $settings = $this->blockSettings(); - // By default, blocks are enabled and not cached. - $settings += array( - 'status' => TRUE, - 'cache' => DRUPAL_NO_CACHE, - ); - return $settings; - } - - /** * Returns plugin-specific settings for the block. * * Block plugins only need to override this method if they override the @@ -69,7 +51,7 @@ 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(); + $this->configuration = $this->blockSettings(); // @todo This loads the default subject. Is this the right place to do so? $definition = $this->getDefinition(); @@ -77,6 +59,8 @@ public function getConfig() { $this->configuration += array('subject' => $definition['subject']); } } + // Ensure that the default cache mode is set. + $this->configuration += array('cache' => DRUPAL_NO_CACHE); return $this->configuration; } @@ -131,7 +115,7 @@ public function blockAccess() { * @see hook_block_access() * @see \Drupal\block\BlockBase::blockAccess() */ - public function access() { + public function access($entity) { // If the block-specific access restrictions indicate the block is not // accessible, always deny access. if (!$this->blockAccess()) { @@ -142,7 +126,7 @@ public function access() { global $user; // Deny access to disabled blocks. - if (empty($this->configuration['status'])) { + if (!$entity->get('status')) { return FALSE; } @@ -150,26 +134,27 @@ public function access() { // If a block has no roles associated, it is displayed for every role. // For blocks with roles associated, if none of the user's roles matches // the settings from this block, access is denied. - if (!empty($this->configuration['visibility']['role']['roles']) && !array_intersect(array_filter($this->configuration['visibility']['role']['roles']), array_keys($user->roles))) { + $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($this->configuration['visibility']['path']['visibility']) && $this->configuration['visibility']['path']['visibility'] == BLOCK_VISIBILITY_LISTED && empty($this->configuration['visibility']['path']['pages'])) { + if (!empty($visibility['path']['visibility']) && $visibility['path']['visibility'] == BLOCK_VISIBILITY_LISTED && empty($visibility['path']['pages'])) { return FALSE; } // Match path if necessary. - if (!empty($this->configuration['visibility']['path']['pages'])) { + 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($this->configuration['visibility']['path']['pages']); - if ($this->configuration['visibility']['path']['visibility'] < BLOCK_VISIBILITY_PHP) { + $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)); @@ -179,10 +164,10 @@ public function access() { // 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 = !($this->configuration['visibility']['path']['visibility'] xor $page_match); + $page_match = !($visibility['path']['visibility'] xor $page_match); } elseif (module_exists('php')) { - $page_match = php_eval($this->configuration['visibility']['path']['pages']); + $page_match = php_eval($visibility['path']['pages']); } // If there are page visibility restrictions and this page does not @@ -193,15 +178,15 @@ public function access() { } // Language visibility settings. - if (!empty($this->configuration['visibility']['language']['langcodes']) && array_filter($this->configuration['visibility']['language']['langcodes'])) { - if (empty($this->configuration['visibility']['language']['langcodes'][language($this->configuration['visibility']['language']['language_type'])->langcode])) { + 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) === FALSE) { + if (module_invoke($module, 'block_access', $entity) === FALSE) { return FALSE; } } @@ -220,72 +205,43 @@ public function access() { * * @see \Drupal\block\BlockBase::blockForm() */ - public function form($form, &$form_state) { + public function form($form, &$form_state, $entity) { $definition = $this->getDefinition(); - $config = $this->getConfig(); $form['id'] = array( '#type' => 'value', - '#value' => $definition['id'], + '#value' => $entity->id(), ); $form['module'] = array( '#type' => 'value', '#value' => $definition['module'], ); - // Get the block subject for the page title. - $subject = isset($config['subject']) ? $config['subject'] : ''; - - // Get the theme for the page title. - $theme_default = variable_get('theme_default', 'stark'); - $admin_theme = config('system.theme')->get('admin'); - $themes = list_themes(); - $theme_key = $form['theme']['#value']; - $theme = $themes[$theme_key]; - // Use meaningful titles for the main site and administrative themes. - $theme_title = $theme->info['name']; - if ($theme_key == $theme_default) { - $theme_title = t('!theme (default theme)', array('!theme' => $theme_title)); - } - elseif ($admin_theme && $theme_key == $admin_theme) { - $theme_title = t('!theme (administration theme)', array('!theme' => $theme_title)); - } - - if ($subject) { - drupal_set_title(t("%subject block in %theme", array('%subject' => $subject, '%theme' => $theme_title)), PASS_THROUGH); - } - - $form['settings'] = array( - '#weight' => -5, - ); - $form['settings']['title'] = array( + $form['label'] = array( '#type' => 'textfield', '#title' => t('Block title'), '#maxlength' => 255, - '#default_value' => isset($subject) ? $subject : '', + '#default_value' => !$entity->isNew() ? $entity->label() : $definition['subject'], ); - $form['settings']['machine_name'] = array( + $form['machine_name'] = array( '#type' => 'textfield', '#title' => t('Block machine name'), '#maxlength' => 64, '#description' => t('A unique name to save this block configuration. Must be alpha-numeric and be underscore separated.'), - '#default_value' => isset($config['config_id']) ? $config['config_id'] : '', + '#default_value' => $entity->id(), '#required' => TRUE, + '#disabled' => !$entity->isNew(), ); - if (isset($config['config_id'])) { - $form['settings']['machine_name']['#disabled'] = TRUE; - } // Region settings. $form['region'] = array( '#type' => 'select', '#title' => t('Region'), '#description' => t('Select the region where this block should be displayed.'), - '#default_value' => !empty($config['region']) && $config['region'] != -1 ? $config['region'] : NULL, + '#default_value' => $entity->get('region'), '#empty_value' => BLOCK_REGION_NONE, - '#options' => system_region_list($theme_key, REGIONS_VISIBLE), + '#options' => system_region_list($entity->get('theme'), REGIONS_VISIBLE), ); - // Visibility settings. $form['visibility'] = array( '#type' => 'vertical_tabs', @@ -309,15 +265,16 @@ public function form($form, &$form_state) { // @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($config['visibility']['path']['visibility']) && $config['visibility']['path']['visibility'] == BLOCK_VISIBILITY_PHP && !$access) { + 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($config['visibility']['path']['pages']) ? $config['visibility']['path']['pages'] : '', + '#value' => !empty($visibility['path']['pages']) ? $visibility['path']['pages'] : '', ); } else { @@ -339,12 +296,12 @@ public function form($form, &$form_state) { '#type' => 'radios', '#title' => t('Show block on specific pages'), '#options' => $options, - '#default_value' => !empty($this->configuration['visibility']['path']['visibility']) ? $this->configuration['visibility']['path']['visibility'] : BLOCK_VISIBILITY_NOTLISTED, + '#default_value' => !empty($visibility['path']['visibility']) ? $visibility['path']['visibility'] : BLOCK_VISIBILITY_NOTLISTED, ); $form['visibility']['path']['pages'] = array( '#type' => 'textarea', '#title' => '' . $title . '', - '#default_value' => !empty($this->configuration['visibility']['path']['pages']) ? $this->configuration['visibility']['path']['pages'] : '', + '#default_value' => !empty($visibility['path']['pages']) ? $visibility['path']['pages'] : '', '#description' => $description, ); } @@ -379,13 +336,13 @@ public function form($form, &$form_state) { '#type' => 'radios', '#title' => t('Language type'), '#options' => $language_type_options, - '#default_value' => !empty($this->configuration['visibility']['language']['language_type']) ? $this->configuration['visibility']['language']['language_type'] : $configurable_language_types[0], + '#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($this->configuration['visibility']['language']['langcodes']) ? $this->configuration['visibility']['language']['langcodes'] : array(), + '#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.'), ); @@ -403,20 +360,13 @@ public function form($form, &$form_state) { $form['visibility']['role']['roles'] = array( '#type' => 'checkboxes', '#title' => t('Show block for specific roles'), - '#default_value' => !empty($this->configuration['visibility']['role']['roles']) ? $this->configuration['visibility']['role']['roles'] : array(), + '#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 specific configuration for this block type. - $form += $this->blockForm($form, $form_state); - - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array( - '#type' => 'submit', - '#value' => t('Save block'), - ); - + // Add plugin-specific settings for this block type. + $form['settings'] = $this->blockForm(array(), $form_state); return $form; } @@ -451,30 +401,19 @@ public function blockForm($form, &$form_state) { * @see \Drupal\block\BlockBase::blockValidate() */ public function validate($form, &$form_state) { - if (empty($form['settings']['machine_name']['#disabled'])) { + if (empty($form['machine_name']['#disabled'])) { if (preg_match('/[^a-zA-Z0-9_]/', $form_state['values']['machine_name'])) { form_set_error('machine_name', t('Block name must be alphanumeric or underscores only.')); } - if (in_array('plugin.core.block.' . $form_state['values']['machine_name'], config_get_storage_names_with_prefix('plugin.core.block'))) { - form_set_error('machine_name', t('Block name must be unique.')); - } } else { $config_id = explode('.', $form_state['values']['machine_name']); $form_state['values']['machine_name'] = array_pop($config_id); } - if ($form_state['values']['module'] == 'block') { - $custom_block_exists = (bool) db_query_range('SELECT 1 FROM {block_custom} WHERE bid <> :bid AND info = :info', 0, 1, array( - ':bid' => $form_state['values']['delta'], - ':info' => $form_state['values']['info'], - ))->fetchField(); - if (empty($form_state['values']['info']) || $custom_block_exists) { - form_set_error('info', t('Ensure that each block description is unique.')); - } - } $form_state['values']['visibility']['role']['roles'] = array_filter($form_state['values']['visibility']['role']['roles']); - - // Perform block type-specific validation. + if ($form_state['entity']->isNew()) { + form_set_value($form['id'], $form_state['values']['theme'] . '.' . $form_state['values']['machine_name'], $form_state); + } $this->blockValidate($form, $form_state); } @@ -508,32 +447,11 @@ public function blockValidate($form, &$form_state) {} */ public function submit($form, &$form_state) { if (!form_get_errors()) { - $transaction = db_transaction(); - try { - $keys = array( - 'visibility' => 'visibility', - 'pages' => 'pages', - 'title' => 'subject', - 'module' => 'module', - 'region' => 'region', - ); - foreach ($keys as $key => $new_key) { - if (isset($form_state['values'][$key])) { - $this->configuration[$new_key] = $form_state['values'][$key]; - } - } - } - catch (Exception $e) { - $transaction->rollback(); - watchdog_exception('block', $e); - throw $e; - } - if (empty($this->configuration['weight'])) { - $this->configuration['weight'] = 0; - } - - // Perform block type-specific validation. $this->blockSubmit($form, $form_state); + + 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:' . $form_state['entity']->get('theme'); } } @@ -555,46 +473,4 @@ public function submit($form, &$form_state) { */ public function blockSubmit($form, &$form_state) {} - /** - * Implements \Drupal\block\BlockInterface::build(). - * - * Allows blocks to be altered after they are built. - * - * Most block plugins should not override this method. To define how a - * particular block is rendered, implement the abstract method - * BlockBase::blockBuild(). - * - * @return array $build - * A renderable array of data. - * - #title: The default localized title of the block. - * - * @todo Add specific examples of $id and $name below. - * - * @see \Drupal\block\BlockBase::blockBuild() - */ - public function build() { - // Allow modules to modify the block before it is viewed, via either - // hook_block_view_alter(), hook_block_view_ID_alter(), or - // hook_block_view_NAME_alter(). - $id = str_replace(':', '__', $this->getPluginId()); - - $config = $this->getConfig(); - $config_id = explode('.', $config['config_id']); - $name = array_pop($config_id); - - $build = $this->blockBuild(); - drupal_alter(array('block_view', "block_view_$id", "block_view_$name"), $build, $this); - return $build; - } - - /** - * Builds the renderable array for a specific block type. - * - * @return array - * A renderable array representing the output of the block. - * - * @see \Drupal\block\BlockBase::build() - */ - abstract public function blockBuild(); - }