diff --git a/core/lib/Drupal/Core/Condition/ConditionPluginBase.php b/core/lib/Drupal/Core/Condition/ConditionPluginBase.php
index 2f250ba..279ef0f 100644
--- a/core/lib/Drupal/Core/Condition/ConditionPluginBase.php
+++ b/core/lib/Drupal/Core/Condition/ConditionPluginBase.php
@@ -37,7 +37,7 @@ public function buildConfigurationForm(array $form, array &$form_state) {
$form['negate'] = array(
'#type' => 'checkbox',
'#title' => $this->t('Negate the condition.'),
- '#default_value' => isset($this->configuration['negate']) ? $this->configuration['negate'] : FALSE,
+ '#default_value' => $this->configuration['negate'],
);
return $form;
}
@@ -83,7 +83,9 @@ public function setConfiguration(array $configuration) {
* {@inheritdoc}
*/
public function defaultConfiguration() {
- return array();
+ return array(
+ 'negate' => FALSE,
+ );
}
/**
diff --git a/core/modules/block/block.module b/core/modules/block/block.module
index ceffa1f..db363dd 100644
--- a/core/modules/block/block.module
+++ b/core/modules/block/block.module
@@ -12,22 +12,6 @@
use Symfony\Component\HttpFoundation\Request;
/**
- * Shows this block on every page except the listed pages.
- */
-const BLOCK_VISIBILITY_NOTLISTED = 0;
-
-/**
- * Shows this block on only the listed pages.
- */
-const BLOCK_VISIBILITY_LISTED = 1;
-
-/**
- * Shows this block if the associated PHP code returns TRUE.
- */
-const BLOCK_VISIBILITY_PHP = 2;
-
-
-/**
* Implements hook_help().
*/
function block_help($route_name, Request $request) {
@@ -391,10 +375,12 @@ function template_preprocess_block(&$variables) {
*/
function block_user_role_delete($role) {
foreach (entity_load_multiple('block') as $block) {
- $visibility = $block->get('visibility');
+ /** @var $block \Drupal\block\BlockInterface */
+ $visibility_conditions = $block->getPlugin()->getVisibilityConditions();
+ $visibility = $visibility_conditions->getConfiguration();
if (isset($visibility['roles']['roles'][$role->id()])) {
unset($visibility['roles']['roles'][$role->id()]);
- $block->set('visibility', $visibility);
+ $visibility_conditions->setConfiguration($visibility);
$block->save();
}
}
@@ -421,10 +407,12 @@ function block_menu_delete(Menu $menu) {
function block_language_entity_delete(Language $language) {
// Remove the block visibility settings for the deleted language.
foreach (entity_load_multiple('block') as $block) {
- $visibility = $block->get('visibility');
+ /** @var $block \Drupal\block\BlockInterface */
+ $visibility_conditions = $block->getPlugin()->getVisibilityConditions();
+ $visibility = $visibility_conditions->getConfiguration();
if (isset($visibility['language']['langcodes'][$language->id()])) {
unset($visibility['language']['langcodes'][$language->id()]);
- $block->set('visibility', $visibility);
+ $visibility_conditions->setConfiguration($visibility);
$block->save();
}
}
diff --git a/core/modules/block/src/BlockAccessController.php b/core/modules/block/src/BlockAccessController.php
index 3bd9fb3..0089470 100644
--- a/core/modules/block/src/BlockAccessController.php
+++ b/core/modules/block/src/BlockAccessController.php
@@ -8,53 +8,19 @@
namespace Drupal\block;
use Drupal\Core\Entity\EntityAccessController;
-use Drupal\Core\Entity\EntityControllerInterface;
use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Session\AccountInterface;
-use Drupal\Core\Path\AliasManagerInterface;
-use Drupal\Component\Utility\Unicode;
-use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a Block access controller.
*/
-class BlockAccessController extends EntityAccessController implements EntityControllerInterface {
-
- /**
- * The node grant storage.
- *
- * @var \Drupal\Core\Path\AliasManagerInterface
- */
- protected $aliasManager;
-
- /**
- * Constructs a BlockAccessController object.
- *
- * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
- * The entity type definition.
- * @param \Drupal\Core\Path\AliasManagerInterface $alias_manager
- * The alias manager.
- */
- public function __construct(EntityTypeInterface $entity_type, AliasManagerInterface $alias_manager) {
- parent::__construct($entity_type);
- $this->aliasManager = $alias_manager;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
- return new static(
- $entity_type,
- $container->get('path.alias_manager')
- );
- }
+class BlockAccessController extends EntityAccessController {
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
+ /** @var $entity \Drupal\block\BlockInterface */
if ($operation != 'view') {
return parent::checkAccess($entity, $operation, $langcode, $account);
}
@@ -64,65 +30,8 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
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 = $entity->get('visibility');
- if (!empty($visibility['role']['roles']) && !array_intersect(array_filter($visibility['role']['roles']), $account->getRoles())) {
- // 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 = Unicode::strtolower($this->aliasManager->getAliasByPath($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);
- }
-
- // 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'][\Drupal::languageManager()->getCurrentLanguage($visibility['language']['language_type'])->id])) {
- return FALSE;
- }
- }
-
- // If the plugin denies access, then deny access. Apply plugin access checks
- // last, because it's almost certainly cheaper to first apply Block's own
- // visibility checks.
- if (!$entity->getPlugin()->access($account)) {
- return FALSE;
- }
-
- return TRUE;
+ // Delegate to the plugin.
+ return $entity->getPlugin()->access($account);
}
}
diff --git a/core/modules/block/src/BlockBase.php b/core/modules/block/src/BlockBase.php
index 6e96d98..d4b5ee1 100644
--- a/core/modules/block/src/BlockBase.php
+++ b/core/modules/block/src/BlockBase.php
@@ -76,7 +76,7 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition
*/
public function getConfiguration() {
return array(
- 'visibility' => $this->getConditions()->getConfiguration(),
+ 'visibility' => $this->getVisibilityConditions()->getConfiguration(),
) + $this->configuration;
}
@@ -150,7 +150,7 @@ public function calculateDependencies() {
* {@inheritdoc}
*/
public function access(AccountInterface $account) {
- if ($this->resolveConditions($this->getConditions(), 'and', $this->getConditionContexts()) === FALSE) {
+ if ($this->resolveConditions($this->getVisibilityConditions(), 'and', $this->getConditionContexts()) === FALSE) {
return FALSE;
}
return $this->blockAccess($account);
@@ -171,6 +171,14 @@ protected function getConditionContexts() {
$context->setContextValue(User::load(\Drupal::currentUser()->id()));
$contexts['user'] = $context;
+ $language = \Drupal::languageManager()->getCurrentLanguage();
+ $context = new Context(array(
+ 'type' => 'language',
+ 'label' => $this->t('Current language'),
+ ));
+ $context->setContextValue($language);
+ $contexts['language'] = $context;
+
// @todo Use RouteMatch after https://drupal.org/node/2238217.
$request = \Drupal::request();
if ($request->attributes->has(RouteObjectInterface::ROUTE_OBJECT) && $route_contexts = $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT)->getOption('parameters')) {
@@ -284,18 +292,15 @@ public function buildConfigurationForm(array $form, array &$form_state) {
$form['cache']['contexts']['#description'] .= ' ' . t('This block is always varied by the following contexts: %required-context-list.', array('%required-context-list' => $required_context_list));
}
+ // @todo Use vertical tabs here.
$form['visibility'] = array(
- '#type' => 'vertical_tabs',
+ '#type' => 'fieldgroup',
'#title' => $this->t('Visibility'),
);
- foreach ($this->getConditions() as $condition_id => $condition) {
- $form['visibility'][$condition_id] = array(
- '#type' => 'details',
- '#title' => $condition->getPluginDefinition()['label'],
- '#group' => 'visibility',
- );
- $form['visibility'][$condition_id]['form'] = $condition->buildConfigurationForm(array(), $form_state);
- $form['visibility'][$condition_id]['form']['#process'][] = array($this, 'processVisibilityForm');
+ foreach ($this->getVisibilityConditions() as $condition_id => $condition) {
+ $form['visibility'][$condition_id] = $condition->buildConfigurationForm(array(), $form_state);
+ $form['visibility'][$condition_id]['#type'] = 'details';
+ $form['visibility'][$condition_id]['#title'] = $condition->getPluginDefinition()['label'];
}
// Add plugin-specific settings for this block type.
$form += $this->blockForm($form, $form_state);
@@ -303,15 +308,6 @@ public function buildConfigurationForm(array $form, array &$form_state) {
}
/**
- * @todo.
- */
- public function processVisibilityForm($element) {
- // Remove the 'form' from parents.
- array_pop($element['#parents']);
- return $element;
- }
-
- /**
* {@inheritdoc}
*/
public function blockForm($form, &$form_state) {
@@ -330,7 +326,7 @@ public function validateConfigurationForm(array &$form, array &$form_state) {
// Transform the #type = checkboxes value to a numerically indexed array.
$form_state['values']['cache']['contexts'] = array_values(array_filter($form_state['values']['cache']['contexts']));
- foreach ($this->getConditions() as $condition_id => $condition) {
+ foreach ($this->getVisibilityConditions() as $condition_id => $condition) {
// Allow the condition to validate the form.
$condition_values = array(
'values' => &$form_state['values']['visibility'][$condition_id],
@@ -362,7 +358,7 @@ public function submitConfigurationForm(array &$form, array &$form_state) {
$this->configuration['label_display'] = $form_state['values']['label_display'];
$this->configuration['provider'] = $form_state['values']['provider'];
$this->configuration['cache'] = $form_state['values']['cache'];
- foreach ($this->getConditions() as $condition_id => $condition) {
+ foreach ($this->getVisibilityConditions() as $condition_id => $condition) {
// Allow the condition to submit the form.
$condition_values = array(
'values' => &$form_state['values']['visibility'][$condition_id],
@@ -458,12 +454,9 @@ public function isCacheable() {
}
/**
- * Gets conditions for this block.
- *
- * @return \Drupal\Core\Condition\ConditionInterface[]|\Drupal\Core\Condition\ConditionPluginBag
- * An array of configured condition plugins.
+ * {@inheritdoc}
*/
- public function getConditions() {
+ public function getVisibilityConditions() {
if (!isset($this->conditionBag)) {
$this->conditionBag = new ConditionPluginBag($this->conditionPluginManager(), $this->configuration['visibility']);
}
@@ -471,28 +464,18 @@ public function getConditions() {
}
/**
- * Gets a condition plugin instance.
- *
- * @param string $instance_id
- * The condition plugin instance ID.
- *
- * @return \Drupal\Core\Condition\ConditionInterface
- * A condition plugin.
+ * {@inheritdoc}
*/
- public function getCondition($instance_id) {
- return $this->getConditions()->get($instance_id);
+ public function getVisibilityCondition($instance_id) {
+ return $this->getVisibilityConditions()->get($instance_id);
}
/**
- * Sets the condition configuration.
- *
- * @param string $instance_id
- * The condition instance ID.
- * @param array $config
- * The condition configuration.
+ * {@inheritdoc}
*/
- public function setConditionConfig($instance_id, $config) {
- $this->getConditions()->setInstanceConfiguration($instance_id, $config);
+ public function setVisibilityConfig($instance_id, array $configuration) {
+ $this->getVisibilityConditions()->setInstanceConfiguration($instance_id, $configuration);
+ return $this;
}
/**
diff --git a/core/modules/block/src/BlockForm.php b/core/modules/block/src/BlockForm.php
index 866f1b8..af8641c 100644
--- a/core/modules/block/src/BlockForm.php
+++ b/core/modules/block/src/BlockForm.php
@@ -10,9 +10,6 @@
use Drupal\Core\Cache\Cache;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\EntityManagerInterface;
-use Drupal\Core\Language\LanguageInterface;
-use Drupal\Core\Language\LanguageManagerInterface;
-use Drupal\language\ConfigurableLanguageManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -35,23 +32,13 @@ class BlockForm extends EntityForm {
protected $storage;
/**
- * The language manager.
- *
- * @var \Drupal\Core\Language\LanguageManagerInterface
- */
- protected $languageManager;
-
- /**
* Constructs a BlockForm object.
*
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager.
- * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
- * The language manager.
*/
- public function __construct(EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager) {
+ public function __construct(EntityManagerInterface $entity_manager) {
$this->storage = $entity_manager->getStorage('block');
- $this->languageManager = $language_manager;
}
/**
@@ -59,8 +46,7 @@ public function __construct(EntityManagerInterface $entity_manager, LanguageMana
*/
public static function create(ContainerInterface $container) {
return new static(
- $container->get('entity.manager'),
- $container->get('language_manager')
+ $container->get('entity.manager')
);
}
@@ -94,122 +80,6 @@ public function form(array $form, array &$form_state) {
'#disabled' => !$entity->isNew(),
);
- // Visibility settings.
- $form['visibility'] = array(
- '#type' => 'vertical_tabs',
- '#title' => $this->t('Visibility settings'),
- '#attached' => array(
- 'library' => array(
- 'block/drupal.block',
- ),
- ),
- '#tree' => TRUE,
- '#weight' => 10,
- '#parents' => array('visibility'),
- );
-
- // Per-path visibility.
- $form['visibility']['path'] = array(
- '#type' => 'details',
- '#title' => $this->t('Pages'),
- '#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 = $this->currentUser()->hasPermission('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 => $this->t('All pages except those listed'),
- BLOCK_VISIBILITY_LISTED => $this->t('Only the listed pages'),
- );
- $description = $this->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' => ''));
-
- $form['visibility']['path']['visibility'] = array(
- '#type' => 'radios',
- '#title' => $this->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' => '' . $this->t('Pages') . '',
- '#default_value' => !empty($visibility['path']['pages']) ? $visibility['path']['pages'] : '',
- '#description' => $description,
- );
- }
-
- // Configure the block visibility per language.
- if ($this->languageManager->isMultilingual() && $this->languageManager instanceof ConfigurableLanguageManagerInterface) {
- $language_types = $this->languageManager->getLanguageTypes();
-
- // Fetch languages.
- $languages = $this->languageManager->getLanguages(LanguageInterface::STATE_ALL);
- $langcodes_options = array();
- foreach ($languages as $language) {
- // @todo $language->name is not wrapped with t(), it should be replaced
- // by CMI translation implementation.
- $langcodes_options[$language->id] = $language->name;
- }
- $form['visibility']['language'] = array(
- '#type' => 'details',
- '#title' => $this->t('Languages'),
- '#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 example.
- $info = $this->languageManager->getDefinedLanguageTypesInfo();
- $language_type_options = array();
- foreach ($language_types as $type_key) {
- $language_type_options[$type_key] = $info[$type_key]['name'];
- }
- $form['visibility']['language']['language_type'] = array(
- '#type' => 'radios',
- '#title' => $this->t('Language type'),
- '#options' => $language_type_options,
- '#default_value' => !empty($visibility['language']['language_type']) ? $visibility['language']['language_type'] : reset($language_types),
- '#access' => count($language_type_options) > 1,
- );
- $form['visibility']['language']['langcodes'] = array(
- '#type' => 'checkboxes',
- '#title' => $this->t('Show this block only for specific languages'),
- '#default_value' => !empty($visibility['language']['langcodes']) ? $visibility['language']['langcodes'] : array(),
- '#options' => $langcodes_options,
- '#description' => $this->t('Show this block only for the selected language(s). If you select no languages, the block will be visible in all languages.'),
- );
- }
-
- // Per-role visibility.
- $role_options = array_map('check_plain', user_role_names());
- $form['visibility']['role'] = array(
- '#type' => 'details',
- '#title' => $this->t('Roles'),
- '#group' => 'visibility',
- '#weight' => 10,
- );
- $form['visibility']['role']['roles'] = array(
- '#type' => 'checkboxes',
- '#title' => $this->t('Show block for specific roles'),
- '#default_value' => !empty($visibility['role']['roles']) ? $visibility['role']['roles'] : array(),
- '#options' => $role_options,
- '#description' => $this->t('Show this block only for the selected role(s). If you select no roles, the block will be visible to all users.'),
- );
-
// Theme settings.
if ($entity->get('theme')) {
$form['theme'] = array(
@@ -276,8 +146,6 @@ protected function actions(array $form, array &$form_state) {
public function validate(array $form, array &$form_state) {
parent::validate($form, $form_state);
- // Remove empty lines from the role visibility list.
- $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(
@@ -324,21 +192,6 @@ public function submit(array $form, array &$form_state) {
}
/**
- * {@inheritdoc}
- */
- public function buildEntity(array $form, array &$form_state) {
- $entity = parent::buildEntity($form, $form_state);
-
- // visibility__active_tab is Form API state and not configuration.
- // @todo Fix vertical tabs.
- $visibility = $entity->get('visibility');
- unset($visibility['visibility__active_tab']);
- $entity->set('visibility', $visibility);
-
- return $entity;
- }
-
- /**
* Generates a unique machine name for a block.
*
* @param \Drupal\block\BlockInterface $block
diff --git a/core/modules/block/src/BlockPluginInterface.php b/core/modules/block/src/BlockPluginInterface.php
index f45ecc5..58ecc8c 100644
--- a/core/modules/block/src/BlockPluginInterface.php
+++ b/core/modules/block/src/BlockPluginInterface.php
@@ -140,4 +140,35 @@ public function blockSubmit($form, &$form_state);
*/
public function getMachineNameSuggestion();
+ /**
+ * Gets conditions for this block.
+ *
+ * @return \Drupal\Core\Condition\ConditionInterface[]|\Drupal\Core\Condition\ConditionPluginBag
+ * An array of configured condition plugins.
+ */
+ public function getVisibilityConditions();
+
+ /**
+ * Gets a visibility condition plugin instance.
+ *
+ * @param string $instance_id
+ * The condition plugin instance ID.
+ *
+ * @return \Drupal\Core\Condition\ConditionInterface
+ * A condition plugin.
+ */
+ public function getVisibilityCondition($instance_id);
+
+ /**
+ * Sets the visibility condition configuration.
+ *
+ * @param string $instance_id
+ * The condition instance ID.
+ * @param array $configuration
+ * The condition configuration.
+ *
+ * @return $this
+ */
+ public function setVisibilityConfig($instance_id, array $configuration);
+
}
diff --git a/core/modules/block/src/Entity/Block.php b/core/modules/block/src/Entity/Block.php
index de6c971..d11347a 100644
--- a/core/modules/block/src/Entity/Block.php
+++ b/core/modules/block/src/Entity/Block.php
@@ -87,13 +87,6 @@ class Block extends ConfigEntityBase implements BlockInterface, EntityWithPlugin
protected $pluginBag;
/**
- * The visibility settings.
- *
- * @var array
- */
- protected $visibility;
-
- /**
* {@inheritdoc}
*/
public function getPlugin() {
@@ -145,7 +138,6 @@ public function toArray() {
'weight',
'plugin',
'settings',
- 'visibility',
);
foreach ($names as $name) {
$properties[$name] = $this->get($name);
diff --git a/core/modules/block/src/Tests/BlockInterfaceTest.php b/core/modules/block/src/Tests/BlockInterfaceTest.php
index 525251e..35df3e8 100644
--- a/core/modules/block/src/Tests/BlockInterfaceTest.php
+++ b/core/modules/block/src/Tests/BlockInterfaceTest.php
@@ -48,10 +48,12 @@ public function testBlockInterface() {
'request_path' => array(
'id' => 'request_path',
'pages' => '',
+ 'negate' => FALSE,
),
'user_role' => array(
'id' => 'user_role',
'roles' => array(),
+ 'negate' => FALSE,
),
),
'id' => 'test_block_instantiation',
diff --git a/core/modules/block/src/Tests/BlockLanguageTest.php b/core/modules/block/src/Tests/BlockLanguageTest.php
index 246e92c..a3a1837 100644
--- a/core/modules/block/src/Tests/BlockLanguageTest.php
+++ b/core/modules/block/src/Tests/BlockLanguageTest.php
@@ -57,11 +57,11 @@ public function testLanguageBlockVisibility() {
$default_theme = \Drupal::config('system.theme')->get('default');
$this->drupalGet('admin/structure/block/add/system_powered_by_block' . '/' . $default_theme);
- $this->assertField('visibility[language][langcodes][en]', 'Language visibility field is visible.');
+ $this->assertField('settings[visibility][language][langcodes][en]', 'Language visibility field is visible.');
// Enable a standard block and set the visibility setting for one language.
$edit = array(
- 'visibility[language][langcodes][en]' => TRUE,
+ 'settings[visibility][language][langcodes][en]' => TRUE,
'id' => strtolower($this->randomName(8)),
'region' => 'sidebar_first',
);
@@ -100,7 +100,7 @@ public function testLanguageBlockVisibilityLanguageDelete() {
$block = $this->drupalPlaceBlock('system_powered_by_block', $edit);
// Check that we have the language in config after saving the setting.
- $visibility = $block->get('visibility');
+ $visibility = $block->getPlugin()->getVisibilityConditions()->getConfiguration();
$language = $visibility['language']['langcodes']['fr'];
$this->assertTrue('fr' === $language, 'Language is set in the block configuration.');
@@ -110,7 +110,7 @@ public function testLanguageBlockVisibilityLanguageDelete() {
// Check that the language is no longer stored in the configuration after
// it is deleted.
$block = entity_load('block', $block->id());
- $visibility = $block->get('visibility');
+ $visibility = $block->getPlugin()->getVisibilityConditions()->getConfiguration();
$this->assertTrue(empty($visibility['language']['langcodes']['fr']), 'Language is no longer not set in the block configuration after deleting the block.');
}
diff --git a/core/modules/block/src/Tests/BlockStorageUnitTest.php b/core/modules/block/src/Tests/BlockStorageUnitTest.php
index 106e220..60cbf94 100644
--- a/core/modules/block/src/Tests/BlockStorageUnitTest.php
+++ b/core/modules/block/src/Tests/BlockStorageUnitTest.php
@@ -103,6 +103,7 @@ protected function createTests() {
'request_path' => array(
'id' => 'request_path',
'pages' => '',
+ 'negate' => FALSE,
),
),
'id' => 'test_html',
@@ -114,7 +115,6 @@ protected function createTests() {
'contexts' => array(),
),
),
- 'visibility' => NULL,
);
$this->assertIdentical($actual_properties, $expected_properties);
diff --git a/core/modules/block/src/Tests/BlockTest.php b/core/modules/block/src/Tests/BlockTest.php
index 882863d..741fab1 100644
--- a/core/modules/block/src/Tests/BlockTest.php
+++ b/core/modules/block/src/Tests/BlockTest.php
@@ -40,8 +40,9 @@ function testBlockVisibility() {
);
// Set the block to be hidden on any user path, and to be shown only to
// authenticated users.
- $edit['visibility[path][pages]'] = 'user*';
- $edit['visibility[role][roles][' . DRUPAL_AUTHENTICATED_RID . ']'] = TRUE;
+ $edit['settings[visibility][request_path][pages]'] = 'user*';
+ $edit['settings[visibility][request_path][negate]'] = TRUE;
+ $edit['settings[visibility][user_role][roles][' . DRUPAL_AUTHENTICATED_RID . ']'] = TRUE;
$this->drupalPostForm('admin/structure/block/add/' . $block_name . '/' . $default_theme, $edit, t('Save block'));
$this->assertText('The block configuration has been saved.', 'Block was saved');
@@ -65,8 +66,7 @@ function testBlockVisibility() {
}
/**
- * Test block visibility when using "pages" restriction but leaving
- * "pages" textarea empty
+ * Test block visibility when leaving "pages" textarea empty.
*/
function testBlockVisibilityListedEmpty() {
$block_name = 'system_powered_by_block';
@@ -78,7 +78,7 @@ function testBlockVisibilityListedEmpty() {
'id' => strtolower($this->randomName(8)),
'region' => 'sidebar_first',
'settings[label]' => $title,
- 'visibility[path][visibility]' => BLOCK_VISIBILITY_LISTED,
+ 'settings[visibility][request_path][negate]' => TRUE,
);
// Set the block to be hidden on any user path, and to be shown only to
// authenticated users.
diff --git a/core/modules/block/tests/modules/block_test/config/install/block.block.test_block.yml b/core/modules/block/tests/modules/block_test/config/install/block.block.test_block.yml
index ee49c91..ea4a909 100644
--- a/core/modules/block/tests/modules/block_test/config/install/block.block.test_block.yml
+++ b/core/modules/block/tests/modules/block_test/config/install/block.block.test_block.yml
@@ -10,11 +10,6 @@ settings:
request_path:
id: request_path
pages: ''
- user_role:
- id: user_role
- roles: { }
- node_type:
- id: node_type
label: 'Test HTML block'
provider: block_test
label_display: 'hidden'
diff --git a/core/modules/block/tests/src/BlockBaseTest.php b/core/modules/block/tests/src/BlockBaseTest.php
index 682fe09..6fddb58 100644
--- a/core/modules/block/tests/src/BlockBaseTest.php
+++ b/core/modules/block/tests/src/BlockBaseTest.php
@@ -86,19 +86,19 @@ public function testCondtionsBagInitialisation() {
$plugin_manager = $this->getMock('Drupal\Core\Executable\ExecutableManagerInterface');
$block_base = new FakeBlock($plugin_manager, $config, 'test_block_instantiation', $definition);
- $conditions_bag = $block_base->getConditions();
+ $conditions_bag = $block_base->getVisibilityConditions();
$this->assertEquals(4, $conditions_bag->count(), "There are 4 condition plugins");
$instance_id = $this->randomName();
$pages = 'node/1';
$condition_config = array('id' => 'request_path', 'pages' => $pages);
- $block_base->setConditionConfig($instance_id, $condition_config);
+ $block_base->setVisibilityConfig($instance_id, $condition_config);
$plugin_manager->expects($this->once())->method('createInstance')
->withAnyParameters()->will($this->returnValue('test'));
- $condition = $block_base->getCondition($instance_id);
+ $condition = $block_base->getVisibilityCondition($instance_id);
$this->assertEquals('test', $condition, "The correct condition is returned.");
}
diff --git a/core/modules/language/config/schema/language.schema.yml b/core/modules/language/config/schema/language.schema.yml
index a10dc3d..584a715 100644
--- a/core/modules/language/config/schema/language.schema.yml
+++ b/core/modules/language/config/schema/language.schema.yml
@@ -123,3 +123,11 @@ language.settings:
language_show:
type: boolean
label: 'Show language selector on create and edit pages'
+
+condition.plugin.language:
+ type: condition.plugin
+ mapping:
+ langcodes:
+ type: sequence
+ sequence:
+ - type: string
diff --git a/core/modules/language/src/Plugin/Condition/Language.php b/core/modules/language/src/Plugin/Condition/Language.php
index 72f0e5f..ff64464 100644
--- a/core/modules/language/src/Plugin/Condition/Language.php
+++ b/core/modules/language/src/Plugin/Condition/Language.php
@@ -96,7 +96,7 @@ public function summary() {
* {@inheritdoc}
*/
public function evaluate() {
- if (empty($this->configuration['langcodes'])) {
+ if (empty($this->configuration['langcodes']) && !$this->configuration['negate']) {
return TRUE;
}
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 6174a13..a311051 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -937,71 +937,6 @@ function node_get_recent($number = 10) {
}
/**
- * Implements hook_form_FORM_ID_alter() for block_form().
- *
- * Adds node-type specific visibility options to block configuration form.
- */
-function node_form_block_form_alter(&$form, &$form_state) {
- $block = $form_state['controller']->getEntity();
- $visibility = $block->get('visibility');
- $form['visibility']['node_type'] = array(
- '#type' => 'details',
- '#title' => t('Content types'),
- '#group' => 'visibility',
- '#weight' => 5,
- );
- $form['visibility']['node_type']['types'] = array(
- '#type' => 'checkboxes',
- '#title' => t('Show block for specific content types'),
- '#default_value' => !empty($visibility['node_type']['types']) ? $visibility['node_type']['types'] : array(),
- '#options' => node_type_get_names(),
- '#description' => t('Show this block only on pages that display content of the given type(s). If you select no types, there will be no type-specific limitation.'),
- );
-}
-
-/**
- * Implements hook_block_access().
- *
- * Checks the content type specific visibility settings and removes the block
- * if the visibility conditions are not met.
- */
-function node_block_access(Block $block, $operation, AccountInterface $account, $langcode) {
- // Only affect access when viewing the block.
- if ($operation != 'view') {
- return;
- }
- $visibility = $block->get('visibility');
- if (!empty($visibility)) {
- if (!empty($visibility['node_type']['types'])) {
- $allowed_types = array_filter($visibility['node_type']['types']);
- }
- if (empty($allowed_types)) {
- // There are no node types selected in visibility settings so there is
- // nothing to do.
- // @see node_form_block_form_alter()
- return;
- }
-
- // For blocks with node types associated, if the node type does not match
- // the settings from this block, deny access to it.
- $request = \Drupal::request();
- if ($node = $request->attributes->get('node')) {
- // Page has node.
- return in_array($node->bundle(), $allowed_types);
- }
- // This is a node creation page.
- // $request->attributes->has('node_type') would also match administration
- // configuration pages, which the previous URI path options did not.
- if ($request->attributes->get(RouteObjectInterface::ROUTE_NAME) == 'node.add') {
- $node_type = $request->attributes->get('node_type');
- return in_array($node_type->id(), $allowed_types);
- }
-
- return FALSE;
- }
-}
-
-/**
* Page callback: Generates and prints an RSS feed.
*
* Generates an RSS feed from an array of node IDs, and prints it with an HTTP
diff --git a/core/modules/node/src/Plugin/Condition/NodeType.php b/core/modules/node/src/Plugin/Condition/NodeType.php
index f311827..95da12b 100644
--- a/core/modules/node/src/Plugin/Condition/NodeType.php
+++ b/core/modules/node/src/Plugin/Condition/NodeType.php
@@ -79,7 +79,7 @@ public function summary() {
* {@inheritdoc}
*/
public function evaluate() {
- if (empty($this->configuration['bundles'])) {
+ if (empty($this->configuration['bundles']) && !$this->configuration['negate']) {
return TRUE;
}
$node = $this->getContextValue('node');
diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php
index bd3f8fd..7fb269d 100644
--- a/core/modules/simpletest/src/WebTestBase.php
+++ b/core/modules/simpletest/src/WebTestBase.php
@@ -427,11 +427,14 @@ protected function drupalPlaceBlock($plugin_id, array $settings = array()) {
'max_age' => 0,
),
);
- foreach (array('region', 'id', 'theme', 'plugin', 'visibility', 'weight') as $key) {
+ foreach (array('region', 'id', 'theme', 'plugin', 'weight') as $key) {
$values[$key] = $settings[$key];
// Remove extra values that do not belong in the settings array.
unset($settings[$key]);
}
+ foreach ($settings['visibility'] as $id => $visibility) {
+ $settings['visibility'][$id]['id'] = $id;
+ }
$values['settings'] = $settings;
$block = entity_create('block', $values);
$block->save();
diff --git a/core/modules/system/src/Plugin/Condition/RequestPath.php b/core/modules/system/src/Plugin/Condition/RequestPath.php
index 59936e7..2043b77 100644
--- a/core/modules/system/src/Plugin/Condition/RequestPath.php
+++ b/core/modules/system/src/Plugin/Condition/RequestPath.php
@@ -87,7 +87,7 @@ public static function create(ContainerInterface $container, array $configuratio
* {@inheritdoc}
*/
public function defaultConfiguration() {
- return array('pages' => '');
+ return array('pages' => '') + parent::defaultConfiguration();
}
/**
diff --git a/core/modules/system/src/Tests/Cache/PageCacheTagsIntegrationTest.php b/core/modules/system/src/Tests/Cache/PageCacheTagsIntegrationTest.php
index f310b24..a22dfb2 100644
--- a/core/modules/system/src/Tests/Cache/PageCacheTagsIntegrationTest.php
+++ b/core/modules/system/src/Tests/Cache/PageCacheTagsIntegrationTest.php
@@ -67,8 +67,7 @@ function testPageCacheTags() {
// Place a block, but only make it visible on full node page 2.
$block = $this->drupalPlaceBlock('views_block:comments_recent-block_1', array(
'visibility' => array(
- 'path' => array(
- 'visibility' => BLOCK_VISIBILITY_LISTED,
+ 'request_path' => array(
'pages' => 'node/' . $node_2->id(),
),
)
diff --git a/core/modules/user/src/Plugin/Condition/UserRole.php b/core/modules/user/src/Plugin/Condition/UserRole.php
index 1557b07..c0383c7 100644
--- a/core/modules/user/src/Plugin/Condition/UserRole.php
+++ b/core/modules/user/src/Plugin/Condition/UserRole.php
@@ -45,7 +45,7 @@ public function buildConfigurationForm(array $form, array &$form_state) {
public function defaultConfiguration() {
return array(
'roles' => array(),
- );
+ ) + parent::defaultConfiguration();
}
/**
@@ -80,7 +80,7 @@ public function summary() {
* {@inheritdoc}
*/
public function evaluate() {
- if (empty($this->configuration['roles'])) {
+ if (empty($this->configuration['roles']) && !$this->configuration['negate']) {
return TRUE;
}
$user = $this->getContextValue('user');
diff --git a/core/modules/views/src/Tests/Plugin/BlockDependenciesTest.php b/core/modules/views/src/Tests/Plugin/BlockDependenciesTest.php
index dd2d2e8..0475e23 100644
--- a/core/modules/views/src/Tests/Plugin/BlockDependenciesTest.php
+++ b/core/modules/views/src/Tests/Plugin/BlockDependenciesTest.php
@@ -109,11 +109,14 @@ protected function createBlock($plugin_id, array $settings = array()) {
'max_age' => 0,
),
);
- foreach (array('region', 'id', 'theme', 'plugin', 'visibility', 'weight') as $key) {
+ foreach (array('region', 'id', 'theme', 'plugin', 'weight') as $key) {
$values[$key] = $settings[$key];
// Remove extra values that do not belong in the settings array.
unset($settings[$key]);
}
+ foreach ($settings['visibility'] as $id => $visibility) {
+ $settings['visibility'][$id]['id'] = $id;
+ }
$values['settings'] = $settings;
$block = entity_create('block', $values);
$block->save();
diff --git a/core/modules/views_ui/src/Tests/OverrideDisplaysTest.php b/core/modules/views_ui/src/Tests/OverrideDisplaysTest.php
index 3384b0f..1a405d9 100644
--- a/core/modules/views_ui/src/Tests/OverrideDisplaysTest.php
+++ b/core/modules/views_ui/src/Tests/OverrideDisplaysTest.php
@@ -120,9 +120,9 @@ function testWizardMixedDefaultOverriddenDisplays() {
// presence/absence of the view's title in both the page and the block).
$this->drupalPlaceBlock("views_block:{$view['id']}-block_1", array(
'visibility' => array(
- 'path' => array(
- 'visibility' => BLOCK_VISIBILITY_NOTLISTED,
+ 'request_path' => array(
'pages' => $view['page[path]'],
+ 'negate' => TRUE,
),
),
));