core/lib/Drupal/Core/Field/FormatterBase.php | 11 ++++++++++- .../EntityReference/EntityReferenceFormatterTest.php | 15 +++++++++++++-- core/modules/filter/src/Tests/FilterFormatAccessTest.php | 2 +- .../Plugin/Field/FieldFormatter/ImageFormatterBase.php | 2 +- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/core/lib/Drupal/Core/Field/FormatterBase.php b/core/lib/Drupal/Core/Field/FormatterBase.php index f7df601..f2c60ad 100644 --- a/core/lib/Drupal/Core/Field/FormatterBase.php +++ b/core/lib/Drupal/Core/Field/FormatterBase.php @@ -8,6 +8,7 @@ namespace Drupal\Core\Field; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Render\Element; /** * Base class for 'Field formatter' plugin implementations. @@ -79,7 +80,9 @@ public function view(FieldItemListInterface $items) { $addition = array(); $elements = $this->viewElements($items); - if ($elements) { + + // If there are actual renderable children, use #theme => field. + if (count($elements) !== count(Element::properties($elements))) { $entity = $items->getEntity(); $entity_type = $entity->getEntityTypeId(); $field_name = $this->fieldDefinition->getName(); @@ -101,6 +104,12 @@ public function view(FieldItemListInterface $items) { $addition = array_merge($info, $elements); } + // Otherwise, we're probably dealing with access cacheability metadata only. + // Just set the properties so that the necessary cache contexts and tags are + // bubbled. + else { + $addition = $elements; + } return $addition; } diff --git a/core/modules/field/src/Tests/EntityReference/EntityReferenceFormatterTest.php b/core/modules/field/src/Tests/EntityReference/EntityReferenceFormatterTest.php index 9120f4a..16f599a 100644 --- a/core/modules/field/src/Tests/EntityReference/EntityReferenceFormatterTest.php +++ b/core/modules/field/src/Tests/EntityReference/EntityReferenceFormatterTest.php @@ -9,6 +9,7 @@ use Drupal\Core\Cache\Cache; use Drupal\Core\Field\FieldStorageDefinitionInterface; +use Drupal\Core\Render\BubbleableMetadata; use Drupal\field\Entity\FieldStorageConfig; use Drupal\filter\Entity\FilterFormat; use Drupal\system\Tests\Entity\EntityUnitTestBase; @@ -220,21 +221,31 @@ public function testLabelFormatter() { '#url' => $this->referencedEntity->urlInfo(), '#options' => $this->referencedEntity->urlInfo()->getOptions(), '#cache' => array( + 'contexts' => [ + 'user.roles', + ], 'tags' => $this->referencedEntity->getCacheTags(), ), + '#attached' => [], + '#post_render_cache' => [], ); $this->assertEqual(drupal_render($build[0]), drupal_render($expected_item_1), sprintf('The markup returned by the %s formatter is correct for an item with a saved entity.', $formatter)); + $this->assertEqual(BubbleableMetadata::createFromRenderArray($build[0]), BubbleableMetadata::createFromRenderArray($expected_item_1)); // The second referenced entity is "autocreated", therefore not saved and // lacking any URL info. $expected_item_2 = array( '#markup' => $this->unsavedReferencedEntity->label(), '#cache' => array( - 'contexts' => [], + 'contexts' => [ + 'user.roles', + ], 'tags' => $this->unsavedReferencedEntity->getCacheTags(), ), + '#attached' => [], + '#post_render_cache' => [], ); - $this->assertEqual($build[1], $expected_item_2, sprintf('The markup returned by the %s formatter is correct for an item with a unsaved entity.', $formatter)); + $this->assertEqual($build[1], $expected_item_2, sprintf('The render array returned by the %s formatter is correct for an item with a unsaved entity.', $formatter)); // Test with the 'link' setting set to FALSE. $build = $this->buildRenderArray([$this->referencedEntity, $this->unsavedReferencedEntity], $formatter, array('link' => FALSE)); diff --git a/core/modules/filter/src/Tests/FilterFormatAccessTest.php b/core/modules/filter/src/Tests/FilterFormatAccessTest.php index f04a754..ceed57c 100644 --- a/core/modules/filter/src/Tests/FilterFormatAccessTest.php +++ b/core/modules/filter/src/Tests/FilterFormatAccessTest.php @@ -126,7 +126,7 @@ function testFormatPermissions() { $this->assertTrue($this->allowedFormat->access('use', $this->webUser), 'A regular user has access to use a text format they were granted access to.'); $this->assertEqual(AccessResult::allowed()->cachePerRole(), $this->allowedFormat->access('use', $this->webUser, TRUE), 'A regular user has access to use a text format they were granted access to.'); $this->assertFalse($this->disallowedFormat->access('use', $this->webUser), 'A regular user does not have access to use a text format they were not granted access to.'); - $this->assertEqual(AccessResult::neutral(), $this->disallowedFormat->access('use', $this->webUser, TRUE)); //, 'A regular user does not have access to use a text format they were not granted access to.'); + $this->assertEqual(AccessResult::neutral()->cachePerRole(), $this->disallowedFormat->access('use', $this->webUser, TRUE), 'A regular user does not have access to use a text format they were not granted access to.'); $this->assertTrue($fallback_format->access('use', $this->webUser), 'A regular user has access to use the fallback format.'); $this->assertEqual(AccessResult::allowed(), $fallback_format->access('use', $this->webUser, TRUE), 'A regular user has access to use the fallback format.'); diff --git a/core/modules/image/src/Plugin/Field/FieldFormatter/ImageFormatterBase.php b/core/modules/image/src/Plugin/Field/FieldFormatter/ImageFormatterBase.php index 914864a..6bcfece 100644 --- a/core/modules/image/src/Plugin/Field/FieldFormatter/ImageFormatterBase.php +++ b/core/modules/image/src/Plugin/Field/FieldFormatter/ImageFormatterBase.php @@ -46,7 +46,7 @@ protected function getEntitiesToView(array &$build, EntityReferenceFieldItemList '_is_default' => TRUE, )); $file->_referringItem = $items[0]; - $file->_accessCacheability = new BubbleableMetadata([], $default_image->getCacheTags()); + $file->_accessCacheability = new BubbleableMetadata([], $file->getCacheTags()); } }