Commit 82923eaf authored by catch's avatar catch
Browse files

Issue #3304772 by tstoeckler, kksandr, Murz, smustgrave: Cache tags from...

Issue #3304772 by tstoeckler, kksandr, Murz, smustgrave: Cache tags from Computed fields do not bubble up to Entity render array

(cherry picked from commit 7ec35d9a)
(cherry picked from commit 555c098f)
parent 722d8fba
Loading
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@

namespace Drupal\Core\Field;

use Drupal\Core\Cache\CacheableDependencyInterface;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
@@ -88,8 +90,16 @@ public function view(FieldItemListInterface $items, $langcode = NULL) {
    }
    $elements = $this->viewElements($items, $langcode);

    // Field item lists, in particular for computed fields, may carry cacheable
    // metadata which must be bubbled.
    if ($items instanceof CacheableDependencyInterface) {
      (new CacheableMetadata())
        ->addCacheableDependency($items)
        ->applyTo($elements);
    }

    // If there are actual renderable children, use #theme => field, otherwise,
    // let access cacheability metadata pass through for correct bubbling.
    // let cacheability metadata pass through for correct bubbling.
    if (Element::children($elements)) {
      $entity = $items->getEntity();
      $entity_type = $entity->getEntityTypeId();
+1 −0
Original line number Diff line number Diff line
@@ -113,6 +113,7 @@ protected function getExpectedDocument() {
          'drupal_internal__id' => 1,
          'computed_string_field' => NULL,
          'computed_test_cacheable_string_field' => 'computed test cacheable string field',
          'computed_test_cacheable_integer_field' => 0,
        ],
        'relationships' => [
          'computed_reference_field' => [
+11 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\entity_test\Plugin\Field\ComputedReferenceTestFieldItemList;
use Drupal\entity_test\Plugin\Field\ComputedTestCacheableIntegerItemList;
use Drupal\entity_test\Plugin\Field\ComputedTestCacheableStringItemList;
use Drupal\entity_test\Plugin\Field\ComputedTestFieldItemList;

@@ -49,12 +50,22 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
      ->setSetting('target_type', 'entity_test')
      ->setClass(ComputedReferenceTestFieldItemList::class);

    // Cacheable metadata can either be provided via the field item properties
    // or via the field item list class directly. Add a computed string field
    // which does the former and a computed integer field which does the latter.
    $fields['computed_test_cacheable_string_field'] = BaseFieldDefinition::create('computed_test_cacheable_string_item')
      ->setLabel(new TranslatableMarkup('Computed Cacheable String Field Test'))
      ->setComputed(TRUE)
      ->setClass(ComputedTestCacheableStringItemList::class)
      ->setReadOnly(FALSE)
      ->setInternal(FALSE);
    $fields['computed_test_cacheable_integer_field'] = BaseFieldDefinition::create('integer')
      ->setLabel(new TranslatableMarkup('Computed Cacheable Integer Field Test'))
      ->setComputed(TRUE)
      ->setClass(ComputedTestCacheableIntegerItemList::class)
      ->setReadOnly(FALSE)
      ->setInternal(FALSE)
      ->setDisplayOptions('view', ['weight' => 10]);

    return $fields;
  }
+36 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\entity_test\Plugin\Field;

use Drupal\Core\Cache\CacheableDependencyInterface;
use Drupal\Core\Cache\CacheableDependencyTrait;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Field\FieldItemList;
use Drupal\Core\TypedData\ComputedItemListTrait;

/**
 * Item list class for computed cacheable string field.
 *
 * This class sets the cacheable metadata on the field item list directly.
 *
 * @see \Drupal\entity_test\Plugin\Field\ComputedTestCacheableStringItemList
 */
class ComputedTestCacheableIntegerItemList extends FieldItemList implements CacheableDependencyInterface {

  use CacheableDependencyTrait, ComputedItemListTrait;

  /**
   * {@inheritdoc}
   */
  protected function computeValue() {
    $value = \Drupal::state()->get('entity_test_computed_integer_value', 0);
    $item = $this->createItem(0, $value);
    $cacheability = (new CacheableMetadata())
      ->setCacheContexts(['url.query_args:computed_test_cacheable_integer_field'])
      ->setCacheTags(['field:computed_test_cacheable_integer_field'])
      ->setCacheMaxAge(31536000);
    $this->setCacheability($cacheability);
    $this->list[0] = $item;
  }

}
+4 −0
Original line number Diff line number Diff line
@@ -8,6 +8,10 @@

/**
 * Item list class for computed cacheable string field.
 *
 *  This class sets the cacheable metadata on the field item properties.
 *
 * @see \Drupal\entity_test\Plugin\Field\ComputedTestCacheableIntegerItemList
 */
class ComputedTestCacheableStringItemList extends FieldItemList {

Loading