Skip to content
Snippets Groups Projects
Commit 555c098f 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)
parent add92f3a
No related branches found
No related tags found
26 merge requests!11185Issue #3477324 by andypost, alexpott: Fix usage of str_getcsv() and fgetcsv() for PHP 8.4,!10602Issue #3438769 by vinmayiswamy, antonnavi, michelle, amateescu: Sub workspace does not clear,!10301Issue #3469309 by mstrelan, smustgrave, moshe weitzman: Use one-time login...,!10187Issue #3487488 by dakwamine: ExtensionMimeTypeGuesser::guessMimeType must support file names with "0" (zero) like foo.0.zip,!9944Issue #3483353: Consider making the createCopy config action optionally fail...,!9929Issue #3445469 by pooja_sharma, smustgrave: Add additional test coverage for...,!9787Resolve issue 3479427 - bootstrap barrio issue under Windows,!9742Issue #3463908 by catch, quietone: Split OptionsFieldUiTest into two,!9526Issue #3458177 by mondrake, catch, quietone, godotislate, longwave, larowlan,...,!8738Issue #3424162 by camilledavis, dineshkumarbollu, smustgrave: Claro...,!8704Make greek characters available in ckeditor5,!8597Draft: Issue #3442259 by catch, quietone, dww: Reduce time of Migrate Upgrade tests...,!8533Issue #3446962 by kim.pepper: Remove incorrectly added...,!8517Issue #3443748 by NexusNovaz, smustgrave: Testcase creates false positive,!8325Update file Sort.php,!8095Expose document root on install,!7930Resolve #3427374 "Taxonomytid viewsargumentdefault plugin",!7627Issue #3439440 by nicxvan, Binoli Lalani, longwave: Remove country support from DateFormatter,!7445Issue #3440169: When using drupalGet(), provide an associative array for $headers,!7401#3271894 Fix documented StreamWrapperInterface return types for realpath() and dirname(),!7384Add constraints to system.advisories,!7078Issue #3320569 by Spokje, mondrake, smustgrave, longwave, quietone, Lendude,...,!6622Issue #2559833 by piggito, mohit_aghera, larowlan, guptahemant, vakulrai,...,!6502Draft: Resolve #2938524 "Plach testing issue",!38582585169-10.1.x,!3226Issue #2987537: Custom menu link entity type should not declare "bundle" entity key
Pipeline #104284 passed with warnings
Pipeline: drupal

#104296

    Pipeline: drupal

    #104290

      Pipeline: drupal

      #104287

        ...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
        namespace Drupal\Core\Field; namespace Drupal\Core\Field;
        use Drupal\Core\Cache\CacheableDependencyInterface;
        use Drupal\Core\Cache\CacheableMetadata;
        use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
        use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Language\LanguageInterface;
        use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
        ...@@ -88,8 +90,16 @@ public function view(FieldItemListInterface $items, $langcode = NULL) { ...@@ -88,8 +90,16 @@ public function view(FieldItemListInterface $items, $langcode = NULL) {
        } }
        $elements = $this->viewElements($items, $langcode); $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, // 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)) { if (Element::children($elements)) {
        $entity = $items->getEntity(); $entity = $items->getEntity();
        $entity_type = $entity->getEntityTypeId(); $entity_type = $entity->getEntityTypeId();
        ......
        ...@@ -114,6 +114,7 @@ protected function getExpectedDocument() { ...@@ -114,6 +114,7 @@ protected function getExpectedDocument() {
        'drupal_internal__id' => 1, 'drupal_internal__id' => 1,
        'computed_string_field' => NULL, 'computed_string_field' => NULL,
        'computed_test_cacheable_string_field' => 'computed test cacheable string field', 'computed_test_cacheable_string_field' => 'computed test cacheable string field',
        'computed_test_cacheable_integer_field' => 0,
        ], ],
        'relationships' => [ 'relationships' => [
        'computed_reference_field' => [ 'computed_reference_field' => [
        ......
        ...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
        use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Field\BaseFieldDefinition;
        use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\Core\StringTranslation\TranslatableMarkup;
        use Drupal\entity_test\Plugin\Field\ComputedReferenceTestFieldItemList; 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\ComputedTestCacheableStringItemList;
        use Drupal\entity_test\Plugin\Field\ComputedTestFieldItemList; use Drupal\entity_test\Plugin\Field\ComputedTestFieldItemList;
        ...@@ -49,12 +50,22 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ...@@ -49,12 +50,22 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
        ->setSetting('target_type', 'entity_test') ->setSetting('target_type', 'entity_test')
        ->setClass(ComputedReferenceTestFieldItemList::class); ->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') $fields['computed_test_cacheable_string_field'] = BaseFieldDefinition::create('computed_test_cacheable_string_item')
        ->setLabel(new TranslatableMarkup('Computed Cacheable String Field Test')) ->setLabel(new TranslatableMarkup('Computed Cacheable String Field Test'))
        ->setComputed(TRUE) ->setComputed(TRUE)
        ->setClass(ComputedTestCacheableStringItemList::class) ->setClass(ComputedTestCacheableStringItemList::class)
        ->setReadOnly(FALSE) ->setReadOnly(FALSE)
        ->setInternal(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; return $fields;
        } }
        ......
        <?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;
        }
        }
        ...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
        /** /**
        * Item list class for computed cacheable string field. * 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 { class ComputedTestCacheableStringItemList extends FieldItemList {
        ......
        ...@@ -56,6 +56,12 @@ protected function getExpectedNormalizedEntity() { ...@@ -56,6 +56,12 @@ protected function getExpectedNormalizedEntity() {
        'value' => 'computed test cacheable string field', 'value' => 'computed test cacheable string field',
        ], ],
        ]; ];
        // @see \Drupal\entity_test\Plugin\Field\ComputedTestCacheableIntegerItemList::computeValue().
        $expected['computed_test_cacheable_integer_field'] = [
        [
        'value' => 0,
        ],
        ];
        $expected['uuid'] = [ $expected['uuid'] = [
        0 => [ 0 => [
        ......
        <?php
        namespace Drupal\Tests\system\Functional\Entity;
        use Drupal\Core\Cache\Cache;
        use Drupal\Core\State\StateInterface;
        use Drupal\entity_test\Entity\EntityTestComputedField;
        use Drupal\Tests\BrowserTestBase;
        /**
        * Tests that entities with computed fields work correctly.
        *
        * @group Entity
        */
        class EntityComputedFieldTest extends BrowserTestBase {
        /**
        * Modules to enable.
        *
        * @var array
        */
        protected static $modules = ['entity_test'];
        /**
        * {@inheritdoc}
        */
        protected $defaultTheme = 'olivero';
        /**
        * The state service.
        *
        * @var \Drupal\Core\State\StateInterface
        */
        protected StateInterface $state;
        protected function setUp(): void {
        parent::setUp();
        $this->state = $this->container->get('state');
        }
        /**
        * Tests that formatters bubble the cacheable metadata of computed fields.
        */
        public function testFormatterComputedFieldCacheableMetadata() {
        $this->drupalLogin($this->drupalCreateUser(['administer entity_test content']));
        $entity = EntityTestComputedField::create([
        'name' => 'Test entity with a cacheable, computed field',
        ]);
        $entity->save();
        $this->state->set('entity_test_computed_integer_value', 2024);
        $this->drupalGet($entity->toUrl('canonical')->toString());
        $field_item_selector = '.field--name-computed-test-cacheable-integer-field .field__item';
        $this->assertSession()->elementTextEquals('css', $field_item_selector, 2024);
        $this->assertSession()->responseHeaderContains('X-Drupal-Cache-Contexts', 'url.query_args:computed_test_cacheable_integer_field');
        $this->assertSession()->responseHeaderContains('X-Drupal-Cache-Tags', 'field:computed_test_cacheable_integer_field');
        $this->assertSession()->responseHeaderEquals('X-Drupal-Cache-Max-Age', "31536000");
        $this->state->set('entity_test_computed_integer_value', 2025);
        $this->drupalGet($entity->toUrl('canonical')->toString());
        $this->assertSession()->elementTextEquals('css', $field_item_selector, 2024);
        $this->assertSession()->responseHeaderContains('X-Drupal-Cache-Contexts', 'url.query_args:computed_test_cacheable_integer_field');
        $this->assertSession()->responseHeaderContains('X-Drupal-Cache-Tags', 'field:computed_test_cacheable_integer_field');
        $this->assertSession()->responseHeaderEquals('X-Drupal-Cache-Max-Age', "31536000");
        Cache::invalidateTags(['field:computed_test_cacheable_integer_field']);
        $this->drupalGet($entity->toUrl('canonical')->toString());
        $this->assertSession()->elementTextEquals('css', $field_item_selector, 2025);
        $this->assertSession()->responseHeaderContains('X-Drupal-Cache-Contexts', 'url.query_args:computed_test_cacheable_integer_field');
        $this->assertSession()->responseHeaderContains('X-Drupal-Cache-Tags', 'field:computed_test_cacheable_integer_field');
        $this->assertSession()->responseHeaderEquals('X-Drupal-Cache-Max-Age', "31536000");
        }
        }
        • catch @catch

          mentioned in commit 82923eaf

          ·

          mentioned in commit 82923eaf

          Toggle commit list
        0% Loading or .
        You are about to add 0 people to the discussion. Proceed with caution.
        Finish editing this message first!
        Please register or to comment