diff --git a/src/Plugin/views/argument/SearchApiArgument.php b/src/Plugin/views/argument/SearchApiArgument.php index f982a56..9f288fe 100644 --- a/src/Plugin/views/argument/SearchApiArgument.php +++ b/src/Plugin/views/argument/SearchApiArgument.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 SearchApiArgument extends ArgumentPluginBase { + use UncacheableDependencyTrait; + /** * The Views query object used by this contextual filter. * diff --git a/src/Plugin/views/argument/SearchApiDate.php b/src/Plugin/views/argument/SearchApiDate.php index 9978eec..c94a225 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 SearchApiArgument { + use UncacheableDependencyTrait; + /** * {@inheritdoc} */ diff --git a/src/Plugin/views/argument/SearchApiFulltext.php b/src/Plugin/views/argument/SearchApiFulltext.php index 44b939c..55fc156 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 SearchApiArgument { + use UncacheableDependencyTrait; + /** * {@inheritdoc} */ diff --git a/src/Plugin/views/argument/SearchApiMoreLikeThis.php b/src/Plugin/views/argument/SearchApiMoreLikeThis.php index f39c8b0..3829337 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 SearchApiArgument { + use UncacheableDependencyTrait; + /** * {@inheritdoc} */ diff --git a/src/Plugin/views/argument/SearchApiTaxonomyTerm.php b/src/Plugin/views/argument/SearchApiTaxonomyTerm.php index e840c29..1ffcc15 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 SearchApiArgument { + use UncacheableDependencyTrait; + /** * {@inheritdoc} */ diff --git a/src/Plugin/views/cache/SearchApiCache.php b/src/Plugin/views/cache/SearchApiCache.php index a9af6fd..9308676 100644 --- a/src/Plugin/views/cache/SearchApiCache.php +++ b/src/Plugin/views/cache/SearchApiCache.php @@ -92,6 +92,10 @@ class SearchApiCache extends Time { /** * {@inheritdoc} + * + * @todo This is completely wrong. This is inherited from the Drupal 7 port, + * or from old Drupal 8 Views code. Look at the parent's implementation + * (i.e. in Drupal 8 core). */ public function generateResultsKey() { if (!isset($this->resultsKey)) { 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/SearchApiFilterBoolean.php b/src/Plugin/views/filter/SearchApiFilterBoolean.php index a0f1c45..b849a26 100644 --- a/src/Plugin/views/filter/SearchApiFilterBoolean.php +++ b/src/Plugin/views/filter/SearchApiFilterBoolean.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 SearchApiFilterBoolean extends BooleanOperator { + use UncacheableDependencyTrait; use SearchApiFilterTrait; } diff --git a/src/Plugin/views/filter/SearchApiFilterDatasource.php b/src/Plugin/views/filter/SearchApiFilterDatasource.php index 9ed5382..56bbbd5 100644 --- a/src/Plugin/views/filter/SearchApiFilterDatasource.php +++ b/src/Plugin/views/filter/SearchApiFilterDatasource.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 SearchApiFilterDatasource extends SearchApiFilterOptions { + use UncacheableDependencyTrait; + /** * {@inheritdoc} */ diff --git a/src/Plugin/views/filter/SearchApiFilterDate.php b/src/Plugin/views/filter/SearchApiFilterDate.php index d684c77..349f4e5 100644 --- a/src/Plugin/views/filter/SearchApiFilterDate.php +++ b/src/Plugin/views/filter/SearchApiFilterDate.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 SearchApiFilterDate extends Date { + use UncacheableDependencyTrait; use SearchApiFilterTrait; /** diff --git a/src/Plugin/views/filter/SearchApiFilterEntityBase.php b/src/Plugin/views/filter/SearchApiFilterEntityBase.php index 928041e..c4574a2 100644 --- a/src/Plugin/views/filter/SearchApiFilterEntityBase.php +++ b/src/Plugin/views/filter/SearchApiFilterEntityBase.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 SearchApiFilterEntityBase extends SearchApiFilterString { + use UncacheableDependencyTrait; + /** * Where the $query object will reside: * diff --git a/src/Plugin/views/filter/SearchApiFilterNumeric.php b/src/Plugin/views/filter/SearchApiFilterNumeric.php index c6b5f6f..ff2e5fa 100644 --- a/src/Plugin/views/filter/SearchApiFilterNumeric.php +++ b/src/Plugin/views/filter/SearchApiFilterNumeric.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 SearchApiFilterNumeric extends NumericFilter { + use UncacheableDependencyTrait; use SearchApiFilterTrait; /** diff --git a/src/Plugin/views/filter/SearchApiFilterOptions.php b/src/Plugin/views/filter/SearchApiFilterOptions.php index 6235505..d095dd2 100644 --- a/src/Plugin/views/filter/SearchApiFilterOptions.php +++ b/src/Plugin/views/filter/SearchApiFilterOptions.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 SearchApiFilterOptions extends ManyToOne { + use UncacheableDependencyTrait; use SearchApiFilterTrait; /** diff --git a/src/Plugin/views/filter/SearchApiFilterString.php b/src/Plugin/views/filter/SearchApiFilterString.php index 992db5e..f6cc5f7 100644 --- a/src/Plugin/views/filter/SearchApiFilterString.php +++ b/src/Plugin/views/filter/SearchApiFilterString.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 SearchApiFilterString extends SearchApiFilterNumeric { + use UncacheableDependencyTrait; + } diff --git a/src/Plugin/views/filter/SearchApiFilterText.php b/src/Plugin/views/filter/SearchApiFilterText.php index 959a9d0..21aee15 100644 --- a/src/Plugin/views/filter/SearchApiFilterText.php +++ b/src/Plugin/views/filter/SearchApiFilterText.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 SearchApiFilterText extends SearchApiFilterString { + use UncacheableDependencyTrait; + /** * {@inheritdoc} */ 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 b97031c..c4e5161 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 SearchApiFilterOptions { + use UncacheableDependencyTrait; + /** * The language manager. * 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/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..2880540 100644 --- a/src/Plugin/views/query/SearchApiQuery.php +++ b/src/Plugin/views/query/SearchApiQuery.php @@ -9,6 +9,7 @@ namespace Drupal\search_api\Plugin\views\query; use Drupal\Component\Render\FormattableMarkup; use Drupal\Component\Utility\Html; +use Drupal\Core\Cache\CacheableMetadata; use Drupal\Core\Database\Query\ConditionInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; @@ -591,6 +592,55 @@ class SearchApiQuery extends QueryPluginBase { return $dependencies; } + /** + * {@inheritdoc} + */ + public function getCacheMaxAge() { + // Search API gets its search results from a data source that is external to + // Drupal. Therefore it is impossible to guarantee that the search results + // are in sync with the data managed by Drupal. Consequently, it is not + // possible to cache the search results at all. + // Unless the search backend plugin supports the 'cacheable_dependency' + // feature, which means it not only implements BackendInterface, but also + // CacheableDependencyInterface, which is capable of conveying how long its + // search results can be cached. + // @todo What's in the if-statement below is just an outline, it's *one* + // possible implementation. The name of the feature is not final, nor + // is the requirement that the backend implement + // CacheableDependencyInterface. To be discussed & investigated. + $server = $this->index->getServer(); + if ($server->supportsFeature('cacheable_dependency')) { + $backend = $server->getBackend(); + assert('$backend instanceof \Drupal\Core\Cache\CacheableDependencyInterface'); + return $backend->getCacheMaxAge(); + } + else { + // When the search back-end doesn't provide the necessary metadata, we + // must assume its search results are not cacheable at all. + return 0; + } + } + + /** + * {@inheritdoc} + */ + public function getCacheContexts() { + return CacheableMetadata::createFromObject($this->index) + ->addCacheableDependency($this->index->getServer()) + ->addCacheContexts(parent::getCacheContexts()) + ->getCacheContexts(); + } + + /** + * {@inheritdoc} + */ + public function getCacheTags() { + return CacheableMetadata::createFromObject($this->index) + ->addCacheableDependency($this->index->getServer()) + ->addCacheTags(parent::getCacheTags()) + ->getCacheTags(); + } + // // Query interface methods (proxy to $this->query) // 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/UncacheableDependencyTrait.php b/src/UncacheableDependencyTrait.php new file mode 100644 index 0000000..c11e933 --- /dev/null +++ b/src/UncacheableDependencyTrait.php @@ -0,0 +1,58 @@ +