diff --git a/core/modules/block_content/block_content.module b/core/modules/block_content/block_content.module index 31435c176b..53b7dadbd3 100644 --- a/core/modules/block_content/block_content.module +++ b/core/modules/block_content/block_content.module @@ -115,15 +115,15 @@ function block_content_add_body_field($block_type_id, $label = 'Body') { * Alters any 'entity_reference' query where the entity type is * 'block_content' and the query has the tag 'block_content_access'. * - * These queries should only return with no parent blocks unless a condition on - * parent is explicitly set. + * These queries should only return blocks with no parents unless a condition on + * 'entity_parent_type' or 'entity_parent_id' is explicitly set. * - * Since block_content entities can be set to be have a parent they should by - * default not be selectable as entity reference values. A module can still - * create a instance of + * Block_content entities that have a parent should by default not be selectable + * as entity reference values. A module can still + * create an instance of * \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface * that will will allow selection of blocks with parents by explicitly setting - * a condition on either parent_entity_id or parent_entity_type fields. + * a condition on either the parent_entity_id or parent_entity_type fields. * * @see \Drupal\block_content\BlockContentAccessControlHandler */ diff --git a/core/modules/block_content/block_content.post_update.php b/core/modules/block_content/block_content.post_update.php index d71f5758b2..cb3e9cd0e5 100644 --- a/core/modules/block_content/block_content.post_update.php +++ b/core/modules/block_content/block_content.post_update.php @@ -5,35 +5,42 @@ * Post update functions for Custom Block. */ +use Drupal\Core\Config\Entity\ConfigEntityUpdater; + /** * Adds 'has_parent' filter to Custom Block views. */ -function block_content_post_update_add_views_parent_filter() { - $config_factory = \Drupal::configFactory(); +function block_content_post_update_add_views_parent_filter(&$sandbox = NULL) { $data_table = \Drupal::entityTypeManager() ->getDefinition('block_content') ->getDataTable(); - foreach ($config_factory->listAll('views.view.') as $view_config_name) { - $view = $config_factory->getEditable($view_config_name); + \Drupal::classResolver(ConfigEntityUpdater::class)->update($sandbox, 'view', function ($view) use ($data_table) { + /** @var \Drupal\views\ViewEntityInterface $view */ if ($view->get('base_table') != $data_table) { - continue; + return FALSE; } - foreach ($view->get('display') as $display_name => $display) { + $save_view = FALSE; + $displays = $view->get('display'); + foreach ($displays as $display_name => &$display) { // Update the default display and displays that have overridden filters. if (!isset($display['display_options']['filters']['has_parent']) && ($display_name === 'default' || isset($display['display_options']['filters']))) { - // Save off the base part of the config path we are updating. - $base = "display.$display_name.display_options.filters.has_parent"; - $view->set("$base.id", 'has_parent') - ->set("$base.plugin_id", 'boolean_string') - ->set("$base.table", $data_table) - ->set("$base.field", "has_parent") - ->set("$base.value", '0') - ->set("$base.entity_type", "block_content") - ->set("$base.entity_field", "parent_entity_type"); + $display['display_options']['filters']['has_parent'] = [ + 'id' => 'has_parent', + 'plugin_id' => 'boolean_string', + 'table' => $data_table, + 'field' => 'has_parent', + 'value' => '0', + 'entity_type' => 'block_content', + 'entity_field' => 'parent_entity_type', + ]; + $save_view = TRUE; } } - $view->save(); - } + if ($save_view) { + $view->set('display', $displays); + } + return $save_view; + }); } diff --git a/core/modules/block_content/src/BlockContentAccessControlHandler.php b/core/modules/block_content/src/BlockContentAccessControlHandler.php index 34077b82af..dc5b107371 100644 --- a/core/modules/block_content/src/BlockContentAccessControlHandler.php +++ b/core/modules/block_content/src/BlockContentAccessControlHandler.php @@ -28,11 +28,11 @@ protected function checkAccess(EntityInterface $entity, $operation, AccountInter /** @var \Drupal\block_content\BlockContentInterface $entity */ if ($entity->hasParentEntity()) { if ($parent_entity = $entity->getParentEntity()) { - $access = $access->andIf($parent_entity->access($operation, $account, TRUE))->addCacheableDependency($entity); + $access = $access->andIf($parent_entity->access($operation, $account, TRUE)); } else { // The entity has a parent but it was not able to be loaded. - return AccessResult::forbidden('Parent entity not available.')->addCacheableDependency($entity); + $access = $access->andIf(AccessResult::forbidden('Parent entity not available.')); } } return $access; diff --git a/core/modules/block_content/tests/src/Functional/Update/BlockContentParentEntityUpdateTest.php b/core/modules/block_content/tests/src/Functional/Update/BlockContentParentEntityUpdateTest.php index 943dee34b7..7a2ab3034c 100644 --- a/core/modules/block_content/tests/src/Functional/Update/BlockContentParentEntityUpdateTest.php +++ b/core/modules/block_content/tests/src/Functional/Update/BlockContentParentEntityUpdateTest.php @@ -41,9 +41,24 @@ public function testParentFieldsAddition() { // 'info' field. $this->container->get('module_installer')->install(['block_content_view_override']); + // Ensure that parent entity fields are not present before updates. + $this->assertEmpty($entity_definition_update_manager->getFieldStorageDefinition('parent_entity_type', 'block_content')); + $this->assertEmpty($entity_definition_update_manager->getFieldStorageDefinition('parent_entity_id', 'block_content')); + + // Ensure that 'has_parent' filter is not present before updates. + $view_config = \Drupal::configFactory()->get('views.view.block_content'); + $this->assertFalse($view_config->isNew()); + $this->assertEmpty($view_config->get('display.default.display_options.filters.has_parent')); + $this->assertEmpty($view_config->get('display.page_2.display_options.filters.has_parent')); // Run updates. $this->runUpdates(); + // Ensure that 'has_parent' filter is present after updates. + \Drupal::configFactory()->clearStaticCache(); + $view_config = \Drupal::configFactory()->get('views.view.block_content'); + $this->assertNotEmpty($view_config->get('display.default.display_options.filters.has_parent')); + $this->assertNotEmpty($view_config->get('display.page_2.display_options.filters.has_parent')); + // Check that the 'parent_entity_type' field exists and is configured // correctly. $parent_type_field = $entity_definition_update_manager->getFieldStorageDefinition('parent_entity_type', 'block_content');