diff --git a/src/Plugin/views/argument/SearchApiDate.php b/src/Plugin/views/argument/SearchApiDate.php index 05b9b16..f497274 100644 --- a/src/Plugin/views/argument/SearchApiDate.php +++ b/src/Plugin/views/argument/SearchApiDate.php @@ -9,6 +9,7 @@ namespace Drupal\search_api\Plugin\views\argument; use Drupal\Component\Render\FormattableMarkup; use Drupal\Component\Utility\Html; +use Drupal\search_api\UncacheableDependencyTrait; /** * Defines a contextual filter for conditions on date fields. @@ -19,6 +20,8 @@ use Drupal\Component\Utility\Html; */ class SearchApiDate extends SearchApiStandard { + use UncacheableDependencyTrait; + /** * {@inheritdoc} */ diff --git a/src/Plugin/views/argument/SearchApiFulltext.php b/src/Plugin/views/argument/SearchApiFulltext.php index fe9d01c..faf13b0 100644 --- a/src/Plugin/views/argument/SearchApiFulltext.php +++ b/src/Plugin/views/argument/SearchApiFulltext.php @@ -10,6 +10,7 @@ namespace Drupal\search_api\Plugin\views\argument; use Drupal\Component\Utility\Html; use Drupal\Core\Form\FormStateInterface; use Drupal\search_api\Plugin\views\query\SearchApiQuery; +use Drupal\search_api\UncacheableDependencyTrait; /** * Defines a contextual filter for doing fulltext searches. @@ -20,6 +21,8 @@ use Drupal\search_api\Plugin\views\query\SearchApiQuery; */ class SearchApiFulltext extends SearchApiStandard { + use UncacheableDependencyTrait; + /** * {@inheritdoc} */ diff --git a/src/Plugin/views/argument/SearchApiMoreLikeThis.php b/src/Plugin/views/argument/SearchApiMoreLikeThis.php index 4fe02fa..4fdb651 100644 --- a/src/Plugin/views/argument/SearchApiMoreLikeThis.php +++ b/src/Plugin/views/argument/SearchApiMoreLikeThis.php @@ -10,6 +10,7 @@ namespace Drupal\search_api\Plugin\views\argument; use Drupal\Core\Form\FormStateInterface; use Drupal\search_api\Entity\Index; use Drupal\search_api\SearchApiException; +use Drupal\search_api\UncacheableDependencyTrait; /** * Defines a contextual filter for displaying a "More Like This" list. @@ -20,6 +21,8 @@ use Drupal\search_api\SearchApiException; */ class SearchApiMoreLikeThis extends SearchApiStandard { + use UncacheableDependencyTrait; + /** * {@inheritdoc} */ diff --git a/src/Plugin/views/argument/SearchApiStandard.php b/src/Plugin/views/argument/SearchApiStandard.php index 28400a6..ac220ed 100644 --- a/src/Plugin/views/argument/SearchApiStandard.php +++ b/src/Plugin/views/argument/SearchApiStandard.php @@ -9,6 +9,7 @@ namespace Drupal\search_api\Plugin\views\argument; use Drupal\Component\Utility\Unicode; use Drupal\Core\Form\FormStateInterface; +use Drupal\search_api\UncacheableDependencyTrait; use Drupal\views\Plugin\views\argument\ArgumentPluginBase; /** @@ -20,6 +21,8 @@ use Drupal\views\Plugin\views\argument\ArgumentPluginBase; */ class SearchApiStandard extends ArgumentPluginBase { + use UncacheableDependencyTrait; + /** * The Views query object used by this contextual filter. * diff --git a/src/Plugin/views/argument/SearchApiTaxonomyTerm.php b/src/Plugin/views/argument/SearchApiTaxonomyTerm.php index 9dda26c..e61661b 100644 --- a/src/Plugin/views/argument/SearchApiTaxonomyTerm.php +++ b/src/Plugin/views/argument/SearchApiTaxonomyTerm.php @@ -8,6 +8,7 @@ namespace Drupal\search_api\Plugin\views\argument; use Drupal\Component\Utility\Html; +use Drupal\search_api\UncacheableDependencyTrait; use Drupal\taxonomy\Entity\Term; /** @@ -20,6 +21,8 @@ use Drupal\taxonomy\Entity\Term; // @todo This seems to be only partially ported to D8. class SearchApiTaxonomyTerm extends SearchApiStandard { + use UncacheableDependencyTrait; + /** * {@inheritdoc} */ diff --git a/src/Plugin/views/cache/SearchApiCache.php b/src/Plugin/views/cache/SearchApiCache.php index a9af6fd..b210676 100644 --- a/src/Plugin/views/cache/SearchApiCache.php +++ b/src/Plugin/views/cache/SearchApiCache.php @@ -22,7 +22,6 @@ use Drupal\views\Plugin\views\cache\Time; * help = @Translation("Cache Search API views. (Other methods probably won't work with search views.)") * ) */ -// @todo Limit to Search API base tables. class SearchApiCache extends Time { /** @@ -97,19 +96,17 @@ class SearchApiCache extends Time { if (!isset($this->resultsKey)) { $query = $this->getQuery()->getSearchApiQuery(); $query->preExecute(); - $user = \Drupal::currentUser(); - $key_data = array( - 'query' => $query, - 'roles' => $user->getRoles(), - 'super-user' => $user->id() == 1, // special caching for super user. - 'langcode' => \Drupal::languageManager()->getCurrentLanguage()->getId(), - 'base_url' => $GLOBALS['base_url'], - ); - foreach (array('exposed_info', 'page', 'sort', 'order', 'items_per_page', 'offset') as $key) { - if ($this->view->getRequest()->query->has($key)) { - $key_data[$key] = $this->view->getRequest()->query->get($key); - } - } + + $build_info = $this->view->build_info; + + $key_data = ['build_info' => $build_info]; + + $display_handler_cache_contexts = $this->displayHandler + ->getCacheMetadata() + ->getCacheContexts(); + $key_data += \Drupal::service('cache_contexts_manager') + ->convertTokensToKeys($display_handler_cache_contexts) + ->getKeys(); $this->resultsKey = $this->view->storage->id() . ':' . $this->displayHandler->display['id'] . ':results:' . hash('sha256', serialize($key_data)); } diff --git a/src/Plugin/views/field/SearchApiExcerpt.php b/src/Plugin/views/field/SearchApiExcerpt.php index 83528dc..8a78746 100644 --- a/src/Plugin/views/field/SearchApiExcerpt.php +++ b/src/Plugin/views/field/SearchApiExcerpt.php @@ -7,6 +7,7 @@ namespace Drupal\search_api\Plugin\views\field; +use Drupal\search_api\UncacheableDependencyTrait; use Drupal\views\Plugin\views\field\FieldPluginBase; use Drupal\views\ResultRow; @@ -19,6 +20,8 @@ use Drupal\views\ResultRow; */ class SearchApiExcerpt extends FieldPluginBase { + use UncacheableDependencyTrait; + /** * {@inheritdoc} */ diff --git a/src/Plugin/views/filter/SearchApiBoolean.php b/src/Plugin/views/filter/SearchApiBoolean.php index e5f64d1..85a8f4d 100644 --- a/src/Plugin/views/filter/SearchApiBoolean.php +++ b/src/Plugin/views/filter/SearchApiBoolean.php @@ -7,6 +7,7 @@ namespace Drupal\search_api\Plugin\views\filter; +use Drupal\search_api\UncacheableDependencyTrait; use Drupal\views\Plugin\views\filter\BooleanOperator; /** @@ -18,6 +19,7 @@ use Drupal\views\Plugin\views\filter\BooleanOperator; */ class SearchApiBoolean extends BooleanOperator { + use UncacheableDependencyTrait; use SearchApiFilterTrait; } diff --git a/src/Plugin/views/filter/SearchApiDatasource.php b/src/Plugin/views/filter/SearchApiDatasource.php index 21ae728..db3d529 100644 --- a/src/Plugin/views/filter/SearchApiDatasource.php +++ b/src/Plugin/views/filter/SearchApiDatasource.php @@ -7,6 +7,8 @@ namespace Drupal\search_api\Plugin\views\filter; +use Drupal\search_api\UncacheableDependencyTrait; + /** * Provides filtering on the datasource. * @@ -16,6 +18,8 @@ namespace Drupal\search_api\Plugin\views\filter; */ class SearchApiDatasource extends SearchApiOptions { + use UncacheableDependencyTrait; + /** * {@inheritdoc} */ diff --git a/src/Plugin/views/filter/SearchApiDate.php b/src/Plugin/views/filter/SearchApiDate.php index d29ad29..c50c5b4 100644 --- a/src/Plugin/views/filter/SearchApiDate.php +++ b/src/Plugin/views/filter/SearchApiDate.php @@ -7,6 +7,7 @@ namespace Drupal\search_api\Plugin\views\filter; +use Drupal\search_api\UncacheableDependencyTrait; use Drupal\views\Plugin\views\filter\Date; /** @@ -18,6 +19,7 @@ use Drupal\views\Plugin\views\filter\Date; */ class SearchApiDate extends Date { + use UncacheableDependencyTrait; use SearchApiFilterTrait; /** diff --git a/src/Plugin/views/filter/SearchApiEntityBase.php b/src/Plugin/views/filter/SearchApiEntityBase.php index 0063d24..126d137 100644 --- a/src/Plugin/views/filter/SearchApiEntityBase.php +++ b/src/Plugin/views/filter/SearchApiEntityBase.php @@ -9,12 +9,15 @@ namespace Drupal\search_api\Plugin\views\filter; use Drupal\Component\Utility\Tags; use Drupal\Core\Form\FormStateInterface; +use Drupal\search_api\UncacheableDependencyTrait; /** * Provides a base class for filters on entity-typed fields. */ abstract class SearchApiEntityBase extends SearchApiString { + use UncacheableDependencyTrait; + /** * Where the $query object will reside: * diff --git a/src/Plugin/views/filter/SearchApiFulltext.php b/src/Plugin/views/filter/SearchApiFulltext.php index a777b3b..26fb7ad 100644 --- a/src/Plugin/views/filter/SearchApiFulltext.php +++ b/src/Plugin/views/filter/SearchApiFulltext.php @@ -11,6 +11,7 @@ use Drupal\Component\Utility\Unicode; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; use Drupal\search_api\Entity\Index; +use Drupal\search_api\UncacheableDependencyTrait; use Drupal\views\Plugin\views\filter\FilterPluginBase; /** @@ -22,6 +23,7 @@ use Drupal\views\Plugin\views\filter\FilterPluginBase; */ class SearchApiFulltext extends FilterPluginBase { + use UncacheableDependencyTrait; use SearchApiFilterTrait; /** diff --git a/src/Plugin/views/filter/SearchApiLanguage.php b/src/Plugin/views/filter/SearchApiLanguage.php index 1bb2d3c..dd5396f 100644 --- a/src/Plugin/views/filter/SearchApiLanguage.php +++ b/src/Plugin/views/filter/SearchApiLanguage.php @@ -9,6 +9,7 @@ namespace Drupal\search_api\Plugin\views\filter; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Language\LanguageManagerInterface; +use Drupal\search_api\UncacheableDependencyTrait; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -20,6 +21,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface; */ class SearchApiLanguage extends SearchApiOptions { + use UncacheableDependencyTrait; + /** * The language manager. * diff --git a/src/Plugin/views/filter/SearchApiNumeric.php b/src/Plugin/views/filter/SearchApiNumeric.php index 4bb2658..316d18e 100644 --- a/src/Plugin/views/filter/SearchApiNumeric.php +++ b/src/Plugin/views/filter/SearchApiNumeric.php @@ -7,6 +7,7 @@ namespace Drupal\search_api\Plugin\views\filter; +use Drupal\search_api\UncacheableDependencyTrait; use Drupal\views\Plugin\views\filter\NumericFilter; /** @@ -18,6 +19,7 @@ use Drupal\views\Plugin\views\filter\NumericFilter; */ class SearchApiNumeric extends NumericFilter { + use UncacheableDependencyTrait; use SearchApiFilterTrait; /** diff --git a/src/Plugin/views/filter/SearchApiOptions.php b/src/Plugin/views/filter/SearchApiOptions.php index 634b9cf..d9446b3 100644 --- a/src/Plugin/views/filter/SearchApiOptions.php +++ b/src/Plugin/views/filter/SearchApiOptions.php @@ -8,6 +8,7 @@ namespace Drupal\search_api\Plugin\views\filter; use Drupal\Core\Form\FormStateInterface; +use Drupal\search_api\UncacheableDependencyTrait; use Drupal\views\Plugin\views\filter\ManyToOne; /** @@ -19,6 +20,7 @@ use Drupal\views\Plugin\views\filter\ManyToOne; */ class SearchApiOptions extends ManyToOne { + use UncacheableDependencyTrait; use SearchApiFilterTrait; /** diff --git a/src/Plugin/views/filter/SearchApiString.php b/src/Plugin/views/filter/SearchApiString.php index 1cbeb83..aec1567 100644 --- a/src/Plugin/views/filter/SearchApiString.php +++ b/src/Plugin/views/filter/SearchApiString.php @@ -7,6 +7,8 @@ namespace Drupal\search_api\Plugin\views\filter; +use Drupal\search_api\UncacheableDependencyTrait; + /** * Defines a filter for adding conditions on string fields to the query. * @@ -21,4 +23,6 @@ namespace Drupal\search_api\Plugin\views\filter; */ class SearchApiString extends SearchApiNumeric { + use UncacheableDependencyTrait; + } diff --git a/src/Plugin/views/filter/SearchApiTerm.php b/src/Plugin/views/filter/SearchApiTerm.php index b30a14c..bcc337e 100644 --- a/src/Plugin/views/filter/SearchApiTerm.php +++ b/src/Plugin/views/filter/SearchApiTerm.php @@ -7,6 +7,7 @@ namespace Drupal\search_api\Plugin\views\filter; +use Drupal\search_api\UncacheableDependencyTrait; use Drupal\taxonomy\Plugin\views\filter\TaxonomyIndexTid; /** @@ -20,6 +21,7 @@ use Drupal\taxonomy\Plugin\views\filter\TaxonomyIndexTid; */ class SearchApiTerm extends TaxonomyIndexTid { + use UncacheableDependencyTrait; use SearchApiFilterTrait; } diff --git a/src/Plugin/views/filter/SearchApiText.php b/src/Plugin/views/filter/SearchApiText.php index 8afc3e3..1592cd2 100644 --- a/src/Plugin/views/filter/SearchApiText.php +++ b/src/Plugin/views/filter/SearchApiText.php @@ -6,6 +6,7 @@ */ namespace Drupal\search_api\Plugin\views\filter; +use Drupal\search_api\UncacheableDependencyTrait; /** * Defines a filter for filtering on fulltext fields. @@ -16,6 +17,8 @@ namespace Drupal\search_api\Plugin\views\filter; */ class SearchApiText extends SearchApiString { + use UncacheableDependencyTrait; + /** * {@inheritdoc} */ diff --git a/src/Plugin/views/filter/SearchApiUser.php b/src/Plugin/views/filter/SearchApiUser.php index 8c77ed0..89fc575 100644 --- a/src/Plugin/views/filter/SearchApiUser.php +++ b/src/Plugin/views/filter/SearchApiUser.php @@ -7,6 +7,7 @@ namespace Drupal\search_api\Plugin\views\filter; +use Drupal\search_api\UncacheableDependencyTrait; use Drupal\user\Plugin\views\filter\Name; /** @@ -20,6 +21,7 @@ use Drupal\user\Plugin\views\filter\Name; */ class SearchApiUser extends Name { + use UncacheableDependencyTrait; use SearchApiFilterTrait; /** diff --git a/src/Plugin/views/query/SearchApiQuery.php b/src/Plugin/views/query/SearchApiQuery.php index da6e85f..b89481f 100644 --- a/src/Plugin/views/query/SearchApiQuery.php +++ b/src/Plugin/views/query/SearchApiQuery.php @@ -15,6 +15,7 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Url; use Drupal\search_api\Entity\Index; use Drupal\search_api\Query\ConditionGroupInterface; +use Drupal\search_api\UncacheableDependencyTrait; use Drupal\search_api\Utility; use Drupal\views\Plugin\views\display\DisplayPluginBase; use Drupal\views\Plugin\views\query\QueryPluginBase; @@ -35,6 +36,8 @@ use Drupal\views\ViewExecutable; // possible due to conflicts. class SearchApiQuery extends QueryPluginBase { + use UncacheableDependencyTrait; + /** * Number of results to display. * diff --git a/src/Plugin/views/row/SearchApiRow.php b/src/Plugin/views/row/SearchApiRow.php index b0ba304..0b3ae45 100644 --- a/src/Plugin/views/row/SearchApiRow.php +++ b/src/Plugin/views/row/SearchApiRow.php @@ -14,6 +14,7 @@ use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\Core\TypedData\ComplexDataInterface; use Drupal\search_api\Plugin\views\query\SearchApiQuery; use Drupal\search_api\SearchApiException; +use Drupal\search_api\UncacheableDependencyTrait; use Drupal\views\Plugin\views\display\DisplayPluginBase; use Drupal\views\Plugin\views\row\RowPluginBase; use Drupal\views\ViewExecutable; @@ -30,6 +31,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface; */ class SearchApiRow extends RowPluginBase { + use UncacheableDependencyTrait; + /** * The search index. * diff --git a/src/Plugin/views/sort/SearchApiSort.php b/src/Plugin/views/sort/SearchApiSort.php index 3214517..ba520e4 100644 --- a/src/Plugin/views/sort/SearchApiSort.php +++ b/src/Plugin/views/sort/SearchApiSort.php @@ -7,6 +7,7 @@ namespace Drupal\search_api\Plugin\views\sort; +use Drupal\search_api\UncacheableDependencyTrait; use Drupal\views\Plugin\views\sort\SortPluginBase; /** @@ -16,6 +17,8 @@ use Drupal\views\Plugin\views\sort\SortPluginBase; */ class SearchApiSort extends SortPluginBase { + use UncacheableDependencyTrait; + /** * The associated views query object. * diff --git a/src/Tests/CacheabilityTest.php b/src/Tests/CacheabilityTest.php new file mode 100644 index 0000000..58cf483 --- /dev/null +++ b/src/Tests/CacheabilityTest.php @@ -0,0 +1,70 @@ +getTestServer(); + $this->getTestIndex(); + + // Set up example structure and content and populate the test index with + // that content. + $this->setUpExampleStructure(); + $this->insertExampleContent(); + \Drupal::getContainer() + ->get('search_api.index_task_manager') + ->addItemsAll(Index::load($this->indexId)); + $this->indexItems($this->indexId); + } + + /** + * Tests the cacheability settings of Search API. + */ + public function testFramework() { + $this->drupalLogin($this->adminUser); + + // Verify that the search results are marked as uncacheable. + $this->drupalGet('search-api-test-fulltext'); + $this->assertResponse(200); + $this->assertHeader('x-drupal-dynamic-cache', 'UNCACHEABLE'); + $this->assertTrue(strpos($this->drupalGetHeader('cache-control'), 'no-cache')); + } + +} diff --git a/src/UncacheableDependencyTrait.php b/src/UncacheableDependencyTrait.php new file mode 100644 index 0000000..5544d08 --- /dev/null +++ b/src/UncacheableDependencyTrait.php @@ -0,0 +1,65 @@ +