.../Core/Entity/Entity/EntityViewDisplay.php | 13 +++- core/lib/Drupal/Core/Entity/EntityViewBuilder.php | 1 - .../EntityReferenceEntityFormatter.php | 3 +- .../EntityReferenceFormatterBase.php | 72 +++++++++++++++++++--- .../FieldFormatter/EntityReferenceIdFormatter.php | 3 +- .../EntityReferenceLabelFormatter.php | 11 ++-- core/lib/Drupal/Core/Render/BubbleableMetadata.php | 42 +++++++++++++ .../Field/FieldFormatter/FileFormatterBase.php | 5 +- .../Field/FieldFormatter/GenericFileFormatter.php | 3 +- .../Field/FieldFormatter/RSSEnclosureFormatter.php | 3 +- .../Plugin/Field/FieldFormatter/TableFormatter.php | 6 +- .../Field/FieldFormatter/UrlPlainFormatter.php | 3 +- .../Plugin/Field/FieldFormatter/ImageFormatter.php | 3 +- .../Field/FieldFormatter/ImageFormatterBase.php | 6 +- .../FieldFormatter/ResponsiveImageFormatter.php | 3 +- .../EntityReferenceTaxonomyTermRssFormatter.php | 2 +- .../Plugin/Field/FieldFormatter/LinkFormatter.php | 6 -- .../Plugin/Field/FieldFormatter/PlainFormatter.php | 3 - .../Field/FieldFormatter/TaxonomyFormatterBase.php | 17 +---- 19 files changed, 150 insertions(+), 55 deletions(-) diff --git a/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php b/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php index 1d62a54..ab898c1 100644 --- a/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php +++ b/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php @@ -13,6 +13,7 @@ use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\Core\Entity\EntityDisplayBase; +use Drupal\Core\Render\BubbleableMetadata; /** * Configuration entity that contains display options for all components of a @@ -238,8 +239,16 @@ public function buildMultiple(array $entities) { // Then let the formatter build the output for each entity. foreach ($entities as $key => $entity) { $items = $entity->get($field_name); - $build_list[$key][$field_name] = $formatter->view($items); - $build_list[$key][$field_name]['#access'] = $items->access('view'); + /** @var \Drupal\Core\Access\AccessResultInterface $field_access */ + $field_access = $items->access('view', NULL, TRUE); + $build_list[$key][$field_name] = []; + if ($field_access->isAllowed()) { + $build_list[$key][$field_name] = $formatter->view($items); + } + // Apply the field access cacheability metadata to the render array. + BubbleableMetadata::createFromRenderArray($build_list[$key][$field_name]) + ->merge(BubbleableMetadata::createFromAccessResult($field_access)) + ->applyTo($build_list[$key][$field_name]); } } } diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php index af5abe0..f2d7f38 100644 --- a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php +++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php @@ -184,7 +184,6 @@ protected function getBuildDefaults(EntityInterface $entity, $view_mode, $langco ), 'contexts' => array( 'theme', - 'user.roles', ), 'bin' => $this->cacheBin, ); diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php index 1328f65..a18e96e 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php @@ -123,7 +123,7 @@ public function viewElements(FieldItemListInterface $items) { $view_mode = $this->getSetting('view_mode'); $elements = array(); - foreach ($this->getEntitiesToView($items) as $delta => $entity) { + foreach ($this->getEntitiesToView($elements, $items) as $delta => $entity) { // Protect ourselves from recursive rendering. static $depth = 0; $depth++; @@ -140,6 +140,7 @@ public function viewElements(FieldItemListInterface $items) { // be, we shouldn't rely on it for structured data such as RDFa. if (!empty($items[$delta]->_attributes)) { $items[$delta]->_attributes += array('resource' => $entity->url()); + $this->setAccessCacheability($elements[$delta], $entity); } } else { diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceFormatterBase.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceFormatterBase.php index 25c802c..7f05230 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceFormatterBase.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceFormatterBase.php @@ -7,9 +7,12 @@ namespace Drupal\Core\Field\Plugin\Field\FieldFormatter; +use Drupal\Core\Access\AccessResult; +use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Field\EntityReferenceFieldItemListInterface; use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem; use Drupal\Core\Field\FormatterBase; +use Drupal\Core\Render\BubbleableMetadata; use Drupal\Core\TypedData\TranslatableInterface; /** @@ -31,19 +34,33 @@ * is available in $entity->_referringItem. This is useful for field types * that store additional values next to the reference itself. * + * For each entity, the access cacheability metadata by which the rendered + * entity must be varied is available in $entity->_accessCacheability. This is + * necessary to ensure the render cached referenced entity is never shown to + * uses who don't have access. Use setAccessCacheability() to apply it to the + * field item render array. + * + * @param array $build + * The renderable array that will contain the rendered field. Will be + * updated by reference to set #cache[contexts] and #cache[tags] for + * inaccessible entities, if any. * @param \Drupal\Core\Field\EntityReferenceFieldItemListInterface $items * The item list. * * @return \Drupal\Core\Entity\EntityInterface[] * The array of referenced entities to display, keyed by delta. + * + * @see ::setAccessCacheability() */ - protected function getEntitiesToView(EntityReferenceFieldItemListInterface $items) { + protected function getEntitiesToView(array &$build, EntityReferenceFieldItemListInterface $items) { $entities = array(); + $inaccessible_entities_cacheability = new BubbleableMetadata(); $parent_entity_langcode = $items->getEntity()->language()->getId(); foreach ($items as $delta => $item) { // Ignore items where no entity could be loaded in prepareView(). if (!empty($item->_loaded)) { + /** @var \Drupal\Core\Entity\EntityInterface $entity */ $entity = $item->entity; // Set the entity in the correct language for display. @@ -52,17 +69,54 @@ protected function getEntitiesToView(EntityReferenceFieldItemListInterface $item } // Check entity access if needed. - if (!$this->needsAccessCheck($item) || $entity->access('view')) { + $access = $this->defaultAccess($item)->orIf($entity->access('view', NULL, TRUE)); + $access_cacheability = BubbleableMetadata::createFromAccessResult($access); + if ($access->isAllowed()) { // Add the referring item, in case the formatter needs it. $entity->_referringItem = $items[$delta]; + // Add the cacheability metadata, to be applied with + // ::setAccessCacheability() by the formatter. + $entity->_accessCacheability = $access_cacheability; $entities[$delta] = $entity; } + else { + $inaccessible_entities_cacheability = $inaccessible_entities_cacheability->merge($access_cacheability); + } } } + // Apply the cacheability metadata for the inaccessible entities. This + // causes this field to be rendered (and cached) according to the cache + // contexts by which the access results vary, to ensure only users with + // access to this field can view it. It also tags this field with the cache + // tags on which the access results depend, to ensure users that cannot + // view this field at the moment will gain access once any of those cache + // tags are invalidated + $inaccessible_entities_cacheability->applyTo($build); + return $entities; } + + /** + * Sets a referenced entity field item's access cacheability metadata. + * + * @param array $build + * The renderable array that contains a rendered field item. Will be updated + * by reference to set #cache[contexts] and #cache[tags] for the entity + * referenced by that field item. + * @param \Drupal\Core\Entity\EntityInterface $entity + * An entity with a _accessCacheability property, as returned by + * getEntitiesToView(). + * + * @see ::getEntitiesToView() + */ + protected static function setAccessCacheability(array &$build, EntityInterface $entity) { + BubbleableMetadata::createFromRenderArray($build) + ->merge($entity->_accessCacheability) + ->applyTo($build); + } + /** * {@inheritdoc} * @@ -121,16 +175,20 @@ protected function needsEntityLoad(EntityReferenceItem $item) { } /** - * Returns whether entity access should be checked. + * Returns the default access for the given entity reference item. + * + * By default, 'neutral' is returned, meaning that actual entity access + * checking still needs to be performed. However, a subclass can choose to + * exclude certain items from entity access checking by allowing access. * * @param \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem $item * The item to check. * - * @return bool - * TRUE if entity access should be checked. + * @return \Drupal\Core\Access\AccessResult + * A cacheable access result. */ - protected function needsAccessCheck(EntityReferenceItem $item) { - return TRUE; + protected function defaultAccess(EntityReferenceItem $item) { + return AccessResult::neutral(); } } diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceIdFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceIdFormatter.php index 5b3b171..001d12c 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceIdFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceIdFormatter.php @@ -30,7 +30,7 @@ class EntityReferenceIdFormatter extends EntityReferenceFormatterBase { public function viewElements(FieldItemListInterface $items) { $elements = array(); - foreach ($this->getEntitiesToView($items) as $delta => $entity) { + foreach ($this->getEntitiesToView($elements, $items) as $delta => $entity) { if ($entity->id()) { $elements[$delta] = array( '#markup' => String::checkPlain($entity->id()), @@ -41,6 +41,7 @@ public function viewElements(FieldItemListInterface $items) { 'tags' => $entity->getCacheTags(), ), ); + $this->setAccessCacheability($elements[$delta], $entity); } } diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php index 381f23b..5d26f8a 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php @@ -65,9 +65,8 @@ public function viewElements(FieldItemListInterface $items) { $elements = array(); $output_as_link = $this->getSetting('link'); - $entities = $this->getEntitiesToView($items); - - foreach ($entities as $delta => $entity) { + /** @var \Drupal\Core\Entity\EntityInterface $entity */ + foreach ($this->getEntitiesToView($elements, $items) as $delta => $entity) { $label = $entity->label(); // If the link is to be displayed and the entity has a uri, display a // link. @@ -104,13 +103,11 @@ public function viewElements(FieldItemListInterface $items) { $elements[$delta] = array('#markup' => String::checkPlain($label)); } - $cache_contexts = []; if ($entity instanceof TranslatableInterface && $entity->isTranslatable()) { - $cache_contexts[] = 'language'; + $elements[$delta]['#cache']['contexts'][] = 'language'; } - - $elements[$delta]['#cache']['contexts'] = $cache_contexts; $elements[$delta]['#cache']['tags'] = $entity->getCacheTags(); + $this->setAccessCacheability($elements[$delta], $entity); } return $elements; diff --git a/core/lib/Drupal/Core/Render/BubbleableMetadata.php b/core/lib/Drupal/Core/Render/BubbleableMetadata.php index fa2edf0..160a559 100644 --- a/core/lib/Drupal/Core/Render/BubbleableMetadata.php +++ b/core/lib/Drupal/Core/Render/BubbleableMetadata.php @@ -8,7 +8,9 @@ namespace Drupal\Core\Render; use Drupal\Component\Utility\NestedArray; +use Drupal\Core\Access\AccessResultInterface; use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableInterface; /** * Value object used for bubbleable rendering metadata. @@ -116,4 +118,44 @@ public static function createFromRenderArray(array $build) { return $meta; } + /** + * Creates a bubbleable metadata object from an access result. + * + * @param \Drupal\Core\Access\AccessResultInterface $access_result + * An access result. + * + * @return static + */ + public static function createFromAccessResult(AccessResultInterface $access_result) { + if ($access_result instanceof CacheableInterface) { + return static::createFromCacheableObject($access_result); + } + + $meta = new static(); + + // @todo Any AccessResultInterface object that doesn't implement + // CacheableInterface must be assumed to be uncacheable. Hence we apply + // the 'uncacheable' cache context. But that isn't available until + // https://www.drupal.org/node/2443073 lands. +// $meta->contexts = ['uncacheable']; + return $meta; + } + + /** + * Creates a bubbleable metadata object from a cacheable object. + * + * @param \Drupal\Core\Cache\CacheableInterface $object + * A cacheable object. + * + * @return static + */ + public static function createFromCacheableObject(CacheableInterface $object) { + $meta = new static(); + $meta->contexts = $object->getCacheContexts(); + $meta->tags = $object->getCacheTags(); + // With a #cache['max-age'] property in the future: + //$meta->maxAge = $object->getCacheMaxAge(); + return $meta; + } + } diff --git a/core/modules/file/src/Plugin/Field/FieldFormatter/FileFormatterBase.php b/core/modules/file/src/Plugin/Field/FieldFormatter/FileFormatterBase.php index cdd5b7b..76a45de 100644 --- a/core/modules/file/src/Plugin/Field/FieldFormatter/FileFormatterBase.php +++ b/core/modules/file/src/Plugin/Field/FieldFormatter/FileFormatterBase.php @@ -7,6 +7,7 @@ namespace Drupal\file\Plugin\Field\FieldFormatter; +use Drupal\Core\Access\AccessResult; use Drupal\Core\Field\Plugin\Field\FieldFormatter\EntityReferenceFormatterBase; use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem; @@ -25,11 +26,11 @@ protected function needsEntityLoad(EntityReferenceItem $item) { /** * {@inheritdoc} */ - protected function needsAccessCheck(EntityReferenceItem $item) { + protected function defaultAccess(EntityReferenceItem $item) { // Only check access if the current file access control handler explicitly // opts in by implementing FileAccessFormatterControlHandlerInterface. $access_handler_class = $item->entity->getEntityType()->getHandlerClass('access'); - return is_subclass_of($access_handler_class, '\Drupal\file\FileAccessFormatterControlHandlerInterface'); + return AccessResult::allowedIf(!is_subclass_of($access_handler_class, '\Drupal\file\FileAccessFormatterControlHandlerInterface')); } } diff --git a/core/modules/file/src/Plugin/Field/FieldFormatter/GenericFileFormatter.php b/core/modules/file/src/Plugin/Field/FieldFormatter/GenericFileFormatter.php index cb917eb..972f3e2 100644 --- a/core/modules/file/src/Plugin/Field/FieldFormatter/GenericFileFormatter.php +++ b/core/modules/file/src/Plugin/Field/FieldFormatter/GenericFileFormatter.php @@ -28,13 +28,14 @@ class GenericFileFormatter extends FileFormatterBase { public function viewElements(FieldItemListInterface $items) { $elements = array(); - foreach ($this->getEntitiesToView($items) as $delta => $file) { + foreach ($this->getEntitiesToView($elements, $items) as $delta => $file) { $item = $file->_referringItem; $elements[$delta] = array( '#theme' => 'file_link', '#file' => $file, '#description' => $item->description, ); + $this->setAccessCacheability($elements[$delta], $file); // Pass field item attributes to the theme function. if (isset($item->_attributes)) { $elements[$delta] += array('#attributes' => array()); diff --git a/core/modules/file/src/Plugin/Field/FieldFormatter/RSSEnclosureFormatter.php b/core/modules/file/src/Plugin/Field/FieldFormatter/RSSEnclosureFormatter.php index c324702..4e81c84 100644 --- a/core/modules/file/src/Plugin/Field/FieldFormatter/RSSEnclosureFormatter.php +++ b/core/modules/file/src/Plugin/Field/FieldFormatter/RSSEnclosureFormatter.php @@ -26,10 +26,11 @@ class RSSEnclosureFormatter extends FileFormatterBase { * {@inheritdoc} */ public function viewElements(FieldItemListInterface $items) { + $elements = []; $entity = $items->getEntity(); // Add the first file as an enclosure to the RSS item. RSS allows only one // enclosure per item. See: http://en.wikipedia.org/wiki/RSS_enclosure - foreach ($this->getEntitiesToView($items) as $delta => $file) { + foreach ($this->getEntitiesToView($elements, $items) as $delta => $file) { $entity->rss_elements[] = array( 'key' => 'enclosure', 'attributes' => array( diff --git a/core/modules/file/src/Plugin/Field/FieldFormatter/TableFormatter.php b/core/modules/file/src/Plugin/Field/FieldFormatter/TableFormatter.php index 460450d..7f62154 100644 --- a/core/modules/file/src/Plugin/Field/FieldFormatter/TableFormatter.php +++ b/core/modules/file/src/Plugin/Field/FieldFormatter/TableFormatter.php @@ -28,11 +28,11 @@ class TableFormatter extends FileFormatterBase { public function viewElements(FieldItemListInterface $items) { $elements = array(); - if ($files = $this->getEntitiesToView($items)) { + if ($files = $this->getEntitiesToView($elements, $items)) { $header = array(t('Attachment'), t('Size')); $rows = array(); foreach ($files as $delta => $file) { - $rows[] = array( + $row = array( array( 'data' => array( '#theme' => 'file_link', @@ -41,6 +41,8 @@ public function viewElements(FieldItemListInterface $items) { ), array('data' => format_size($file->getSize())), ); + $this->setAccessCacheability($row, $file); + $rows[] = $row; } $elements[0] = array(); diff --git a/core/modules/file/src/Plugin/Field/FieldFormatter/UrlPlainFormatter.php b/core/modules/file/src/Plugin/Field/FieldFormatter/UrlPlainFormatter.php index 26b78f7..1352b9c 100644 --- a/core/modules/file/src/Plugin/Field/FieldFormatter/UrlPlainFormatter.php +++ b/core/modules/file/src/Plugin/Field/FieldFormatter/UrlPlainFormatter.php @@ -28,8 +28,9 @@ class UrlPlainFormatter extends FileFormatterBase { public function viewElements(FieldItemListInterface $items) { $elements = array(); - foreach ($this->getEntitiesToView($items) as $delta => $file) { + foreach ($this->getEntitiesToView($elements, $items) as $delta => $file) { $elements[$delta] = array('#markup' => file_create_url($file->getFileUri())); + $this->setAccessCacheability($elements[$delta], $file); } return $elements; diff --git a/core/modules/image/src/Plugin/Field/FieldFormatter/ImageFormatter.php b/core/modules/image/src/Plugin/Field/FieldFormatter/ImageFormatter.php index 38a163c..1d1ffd7 100644 --- a/core/modules/image/src/Plugin/Field/FieldFormatter/ImageFormatter.php +++ b/core/modules/image/src/Plugin/Field/FieldFormatter/ImageFormatter.php @@ -167,7 +167,7 @@ public function settingsSummary() { */ public function viewElements(FieldItemListInterface $items) { $elements = array(); - $files = $this->getEntitiesToView($items); + $files = $this->getEntitiesToView($elements, $items); // Early opt-out if the field is empty. if (empty($files)) { @@ -218,6 +218,7 @@ public function viewElements(FieldItemListInterface $items) { 'tags' => $cache_tags, ), ); + $this->setAccessCacheability($elements[$delta], $file); } return $elements; diff --git a/core/modules/image/src/Plugin/Field/FieldFormatter/ImageFormatterBase.php b/core/modules/image/src/Plugin/Field/FieldFormatter/ImageFormatterBase.php index dd8348e..914864a 100644 --- a/core/modules/image/src/Plugin/Field/FieldFormatter/ImageFormatterBase.php +++ b/core/modules/image/src/Plugin/Field/FieldFormatter/ImageFormatterBase.php @@ -8,6 +8,7 @@ namespace Drupal\image\Plugin\Field\FieldFormatter; use Drupal\Core\Field\EntityReferenceFieldItemListInterface; +use Drupal\Core\Render\BubbleableMetadata; use Drupal\field\FieldConfigInterface; use Drupal\file\Plugin\Field\FieldFormatter\FileFormatterBase; @@ -19,7 +20,7 @@ /** * {@inheritdoc} */ - protected function getEntitiesToView(EntityReferenceFieldItemListInterface $items) { + protected function getEntitiesToView(array &$build, EntityReferenceFieldItemListInterface $items) { // Add the default image if needed. if ($items->isEmpty()) { $default_image = $this->getFieldSetting('default_image'); @@ -45,10 +46,11 @@ protected function getEntitiesToView(EntityReferenceFieldItemListInterface $item '_is_default' => TRUE, )); $file->_referringItem = $items[0]; + $file->_accessCacheability = new BubbleableMetadata([], $default_image->getCacheTags()); } } - return parent::getEntitiesToView($items); + return parent::getEntitiesToView($build, $items); } } diff --git a/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php b/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php index bc8cb93..ba949b6 100644 --- a/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php +++ b/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php @@ -175,7 +175,7 @@ public function settingsSummary() { */ public function viewElements(FieldItemListInterface $items) { $elements = array(); - $files = $this->getEntitiesToView($items); + $files = $this->getEntitiesToView($elements, $items); // Early opt-out if the field is empty. if (empty($files)) { @@ -247,6 +247,7 @@ public function viewElements(FieldItemListInterface $items) { 'tags' => $cache_tags, ), ); + $this->setAccessCacheability($elements[$delta], $file); } return $elements; diff --git a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/EntityReferenceTaxonomyTermRssFormatter.php b/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/EntityReferenceTaxonomyTermRssFormatter.php index 9f062a9..30bba1e 100644 --- a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/EntityReferenceTaxonomyTermRssFormatter.php +++ b/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/EntityReferenceTaxonomyTermRssFormatter.php @@ -31,7 +31,7 @@ class EntityReferenceTaxonomyTermRssFormatter extends EntityReferenceFormatterBa public function viewElements(FieldItemListInterface $items) { $elements = array(); - foreach ($this->getEntitiesToView($items) as $delta => $entity) { + foreach ($this->getEntitiesToView($elements, $items) as $delta => $entity) { $entity->rss_elements[] = array( 'key' => 'category', 'value' => $entity->label(), diff --git a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/LinkFormatter.php b/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/LinkFormatter.php index 847e1fd..d94e2bf 100644 --- a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/LinkFormatter.php +++ b/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/LinkFormatter.php @@ -34,9 +34,6 @@ public function viewElements(FieldItemListInterface $items) { foreach ($items as $delta => $item) { if ($item->hasNewEntity()) { $elements[$delta] = array( - '#cache' => [ - 'contexts' => $item->_cacheContexts, - ], '#markup' => String::checkPlain($item->entity->label()), ); } @@ -44,9 +41,6 @@ public function viewElements(FieldItemListInterface $items) { /** @var $term \Drupal\taxonomy\TermInterface */ $term = $item->entity; $elements[$delta] = array( - '#cache' => [ - 'contexts' => $item->_cacheContexts, - ], '#type' => 'link', '#title' => $term->getName(), '#url' => $term->urlInfo(), diff --git a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/PlainFormatter.php b/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/PlainFormatter.php index 0161791..1bf4ab4 100644 --- a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/PlainFormatter.php +++ b/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/PlainFormatter.php @@ -31,9 +31,6 @@ public function viewElements(FieldItemListInterface $items) { foreach ($items as $delta => $item) { $elements[$delta] = array( - '#cache' => [ - 'contexts' => $item->_cacheContexts, - ], '#markup' => String::checkPlain($item->entity->label()), ); } diff --git a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/TaxonomyFormatterBase.php b/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/TaxonomyFormatterBase.php index 1a830da..6109674 100644 --- a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/TaxonomyFormatterBase.php +++ b/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/TaxonomyFormatterBase.php @@ -7,8 +7,6 @@ namespace Drupal\taxonomy\Plugin\Field\FieldFormatter; -use Drupal\Core\Cache\Cache; -use Drupal\Core\Cache\CacheableInterface; use Drupal\Core\Field\FormatterBase; /** @@ -23,8 +21,7 @@ * unsets values for invalid terms that do not exist. */ public function prepareView(array $entities_items) { - $terms = []; - $cache_contexts_per_term = []; + $terms = array(); // Collect every possible term attached to any of the fieldable entities. /* @var \Drupal\Core\Field\EntityReferenceFieldItemList $items */ @@ -34,22 +31,13 @@ public function prepareView(array $entities_items) { $active_langcode = $parent->language()->getId(); /* @var \Drupal\taxonomy\Entity\Term $term */ foreach ($items->referencedEntities() as $term) { - $cache_contexts = []; - if (count($term->getTranslationLanguages()) > 1) { - $cache_contexts[] = 'language'; - } if ($term->hasTranslation($active_langcode)) { $translated_term = $term->getTranslation($active_langcode); - $access_result = $translated_term->access('view', NULL, TRUE); - if ($access_result instanceof CacheableInterface) { - $cache_contexts = Cache::mergeContexts($cache_contexts, $access_result->getCacheContexts()); - } - if ($access_result->isAllowed()) { + if ($translated_term->access('view')) { $term = $translated_term; } } if (!$term->isNew()) { - $cache_contexts_per_term[$term->id()] = $cache_contexts; $terms[$term->id()] = $term; } } @@ -65,7 +53,6 @@ public function prepareView(array $entities_items) { if (isset($terms[$item->target_id])) { // Replace the instance value with the term data. $item->entity = $terms[$item->target_id]; - $item->_cacheContexts = $cache_contexts_per_term[$item->target_id]; } // Terms to be created are not in $terms, but are still legitimate. elseif ($item->hasNewEntity()) {