Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EWPP-2724: Bubble up facet cache. #163

Merged
merged 8 commits into from
Jan 27, 2023
6 changes: 6 additions & 0 deletions src/EventSubscriber/QuerySubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ public function queryAlter(QueryPreExecuteEvent $event) {
'facet' => $facet,
]);
$query_type_plugin->execute();

// Add facet cache tags to the query.
// Facets can modify the query, we add the same cache tags to it.
if (!empty($facet)) {
$query->addCacheTags($facet->getCacheTags());
}
}
catch (InvalidQueryTypeException $exception) {
// If the facet doesn't have a query type, continue and don't crash
Expand Down
1 change: 1 addition & 0 deletions src/Form/ListFacetsForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ public function buildForm(array $form, FormStateInterface $form_state, ListSourc

if ($widget instanceof ListPagesWidgetInterface) {
$form['facets'][$facet->id()] = $this->facetsManager->getFacetManager()->build($facet);
$cache->addCacheTags($facet->getCacheTags());
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/ListBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ public function buildList(ListPageConfiguration $configuration): array {

$query = $list_execution->getQuery();
$cache->addCacheableDependency($query);
$cache->addCacheTags($query->getCacheTags());
$result = $list_execution->getResults();
$configuration = $list_execution->getConfiguration();

Expand Down Expand Up @@ -293,6 +294,7 @@ public function buildSelectedFilters(ListPageConfiguration $configuration): arra
$list_execution = $this->listExecutionManager->executeList($configuration);
$facets = $this->getKeyedFacetsFromSource($list_execution->getListSource());
foreach ($facets as $facet) {
$cache->addCacheableDependency($facet);
$active_items = $facet->getActiveItems();
if (!empty($active_items) && $this->facetHasDefaultStatus($facet, ['raw' => reset($active_items)])) {
$active_filters[$facet->id()] = $facet->getActiveItems();
Expand Down
7 changes: 7 additions & 0 deletions src/Plugin/ExtraField/Display/ListPageFilters.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ public function view(ContentEntityInterface $entity) {
return isset($form['#cache']) ? ['#cache' => $form['#cache']] : [];
}

// Facets might have added cache tags to the form related with their
// content. We guarantee the cache tags are added also to the entity
// here so they bubble up to the page.
if (!empty($form['#cache']['tags'])) {
$entity->addCacheTags($form['#cache']['tags']);
nagyad marked this conversation as resolved.
Show resolved Hide resolved
}

return $form;
}

Expand Down
6 changes: 5 additions & 1 deletion tests/src/Kernel/DateStatusTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,22 @@ public function testWithConfiguredDefaults(): void {
DateStatus::UPCOMING => t('Upcoming'),
DateStatus::PAST => t('Past'),
];
// Assert the query has the corresponding cache tag from the facet.
$this->assertContains($this->facet->getCacheTags()[0], $query->getCacheTags());
nagyad marked this conversation as resolved.
Show resolved Hide resolved

$this->assertEquals($default_options, $actual['#options']);
$this->assertEquals([], $actual['#default_value']);

$build = $this->facetManager->build($facet_with_config);
$actual = $build[0][$facet_with_config->id()];
$this->assertSame('array', gettype($actual));
$this->assertEquals('select', $actual['#type']);

$default_options = [
DateStatus::UPCOMING => t('Coming items'),
DateStatus::PAST => t('Past items'),
];
// Assert the query has the corresponding cache tag from the facet.
$this->assertContains($this->facet->getCacheTags()[0], $query->getCacheTags());
nagyad marked this conversation as resolved.
Show resolved Hide resolved

$this->assertEquals($default_options, $actual['#options']);
$this->assertEquals([DateStatus::UPCOMING], $actual['#default_value']);
Expand Down
67 changes: 67 additions & 0 deletions tests/src/Kernel/ListBuilderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

declare(strict_types = 1);

namespace Drupal\Tests\oe_list_pages\Kernel;

use Drupal\oe_list_pages\ListBuilder;
use Drupal\oe_list_pages\ListPageConfiguration;
use Drupal\oe_list_pages\ListSourceFactory;

/**
* Tests the list builder.
*/
class ListBuilderTest extends ListsSourceTestBase {

/**
* Tests the facet cache tags are correctly applied on the render arrays.
*/
public function testFacetCacheTags(): void {
$default_list_id = ListSourceFactory::generateFacetSourcePluginId('entity_test_mulrev_changed', 'item');
$this->facet = $this->createFacet('created', $default_list_id, '', 'oe_list_pages_multiselect', []);
$this->facet->addProcessor([
'processor_id' => 'oe_list_pages_date_status_processor',
'weights' => [],
'settings' => [],
]);
$this->facet->save();

$configuration = [
'entity_type' => 'entity_test_mulrev_changed',
'bundle' => 'item',
'exposed_filters' => [],
'exposed_filters_overridden' => FALSE,
'default_filter_values' => [],
'contextual_filters' => [],
];
$listPageConfiguration = new ListPageConfiguration($configuration);

$listExecutionManager = $this->container->get('oe_list_pages.execution_manager');
$pager = $this->container->get('pager.manager');
$entityRepository = $this->container->get('entity.repository');
$formBuilder = $this->container->get('form_builder');
$facetsUrlGenerator = $this->container->get('facets.utility.url_generator');
$processorManager = $this->container->get('plugin.manager.facets.processor');
$requestStack = $this->container->get('request_stack');
$urlProcessorManager = $this->container->get('plugin.manager.facets.url_processor');
$multiselectFilterManager = $this->container->get('plugin.manager.multiselect_filter_field');
$listSourceFactory = $this->container->get('oe_list_pages.list_source.factory');

$listBuilder = new ListBuilder($listExecutionManager, $this->entityTypeManager, $pager, $entityRepository, $formBuilder, $facetsUrlGenerator, $processorManager, $requestStack, $urlProcessorManager, $multiselectFilterManager, $listSourceFactory);
nagyad marked this conversation as resolved.
Show resolved Hide resolved
$render_array = $listBuilder->buildList($listPageConfiguration);

$expected_cache_tags = [
'config:search_api.index.database_search_index',
'config:facets.facet.list_facet_source_entity_test_mulrev_changed_itemcreated',
'entity_test_mulrev_changed_list:item',
];
$this->assertEquals($expected_cache_tags, $render_array['#cache']['tags']);

$render_array = $listBuilder->buildSelectedFilters($listPageConfiguration);
$expected_cache_tags = [
'config:facets.facet.list_facet_source_entity_test_mulrev_changed_itemcreated',
];
$this->assertEquals($expected_cache_tags, $render_array['#cache']['tags']);
}

}
44 changes: 44 additions & 0 deletions tests/src/Kernel/ListFacetsFormTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types = 1);

namespace Drupal\Tests\oe_list_pages\Kernel;

use Drupal\Core\Form\FormState;
use Drupal\oe_list_pages\Form\ListFacetsForm;
use Drupal\oe_list_pages\ListSourceFactory;

/**
* Tests the list facet form.
*/
class ListFacetsFormTest extends ListsSourceTestBase {

/**
* Tests the facet cache tags are correctly applied on the form.
*/
public function testFacetCacheTags(): void {
$default_list_id = ListSourceFactory::generateFacetSourcePluginId('entity_test_mulrev_changed', 'item');
$this->facet = $this->createFacet('created', $default_list_id, '', 'oe_list_pages_multiselect', []);
$this->facet->addProcessor([
'processor_id' => 'oe_list_pages_date_status_processor',
'weights' => [],
'settings' => [],
]);

$this->facet->save();

$list = $this->listFactory->get('entity_test_mulrev_changed', 'item');

$form_state = new FormState();
$form_state->setRequestMethod('POST');
$form_state->setCached();
$form = ListFacetsForm::create($this->container);
$form_array = $form->buildForm([], $form_state, $list, []);
$expected_cache_tags = [
'config:facets_facet_list',
'config:facets.facet.list_facet_source_entity_test_mulrev_changed_itemcreated',
];
$this->assertEquals($expected_cache_tags, $form_array['#cache']['tags']);
}

}