I ran into the problem that facets do not work on views with caching enabled. Looking at the issue queue, I'm not the only one. The README clearly mentions that caching should be disabled (even though two lines halfway a 125-line file are easily missed) but I think the Facets module could actively warn users when configuring facets.

Proposed solution

When saving a facet configuration form (eg. /admin/config/search/facets/[facet]/edit or /admin/config/search/facets/[facet]/settings), check if the source is a view, load the view config, and check if caching is disabled. If not, produce a warning with drupal_set_message.

Comments

marcvangend created an issue. See original summary.

borisson_’s picture

Proposed resolution sounds like a good way to resolve this. It will reduce the issues in the queue, so that'd be great. We'd have to load the correct display for the view as well, but that shouldn't be a problem.

marcvangend’s picture

Looking at this some more, it seems that someone has already tried to solve this problem. Check out this code starting at line 313 of FacetSettingsForm::submitForm() :

    list($type,) = explode(':', $facet_source_id);

    if ($type === 'search_api_views') {
      list(, $view_id, $display) = explode(':', $facet_source_id);
    }

    if (isset($view_id)) {
      $view = Views::getView($view_id);
      $view->setDisplay($display);
      $view->display_handler->overrideOption('cache', ['type' => 'none']);
      $view->save();

      $display_plugin = $view->getDisplay()->getPluginId();
    }

If I'm not mistaken, this code should automatically disable the caching of the view when a facet settings form is saved. Unfortunately it doesn't work because the $facet_source_id has a different format than the module expects. When testing this, the facet source ID didn't look like [type]:[view_id]:[display], but like [module]:[type]__[view_id]__[display] ("search_api:views_page__search__page_1" in my case). I guess this is an oversight from the time when facets_update_8001() was introduced.

I could of course write a patch that changes the assumptions about what a facet source ID looks like, but that would easily break again. Obviously, this code needs tests. Also, it would be nice to have a utility method on the Facet class so we can "ask" the facet about its source view, instead of having to guesstimate it from the $facet_source_id string.

Maintainers, what do you think is the best approach?

borisson_’s picture

Yeah, I think we should start by writing a test and changing the assumption.

I think it'd make sense to use ['display_id'] from the facet source definition and load the Search Api display

I wrote this from memory, but in theory we should be able to do this, that should make everything more clear and removes the guessing. Does this make sense @marcvangend?

$facet_source = $facet_source['display_id'])
$search_api_display = \Drupal::service('('plugin.manager.search_api.display')
      ->createInstance($search_api_display_id);
$definition = $search_api_display->getDefinition()
$definition['view_id'] . $definition['view_display']
marcvangend’s picture

Title: Warn users that view caching must be disabled » Automatically disable caching of views facet sources (regression)
Category: Feature request » Bug report
Status: Active » Needs review
Issue tags: +Needs tests
StatusFileSize
new2.8 KB

Changed the title because this is in fact a regression introduced in #2772745: Search API integration doesn't check/define feature support of backends.

Writing tests isn't really my forte, especially when it comes to modules I don't fully understand... But thanks to the guidance in comment #4 I did manage to fix the regression. Patch attached, but tests are still needed.

marcvangend’s picture

I just noticed that the exact same problem occurs in FacetsSummarySettingsForm::submitForm(), so if the fix from #5 works, we'll have to apply it there too. (Or... do we take code duplication as a hint, and learn that this logic should be implemented in the ViewsPageDisplay class?)

borisson_’s picture

Status: Needs review » Needs work

No worries, I enjoy writing tests, I'll give it a go.

borisson_’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
StatusFileSize
new2.71 KB
new4.68 KB

Adds an integration test to check this, I think this should be sufficient. Do you agree @marcvangend?

marcvangend’s picture

That looks great, you even tested the message. Now we have to address comment #6.

borisson_’s picture

I agree with comment #6, but I also think that we can do that as a follow-up. I opened up #2860393: API break: Add getViewsDisplay method to the Search API Facet Source

marcvangend’s picture

Fair enough, we shouldn't try to do everything at once. Thanks for the follow-up.

So for now, applying the same fix to FacetsSummarySettingsForm will suffice. Here is a patch that does exactly that.

No test yet, sorry. I did try to port the new test in facets\Functional\IntegrationTest::testViewsCacheDisable() to facets_summary\Functional\IntegrationTest::testViewsCacheDisable(), but I stopped when I found that there is no createFacetSummary() method yet (comparable to createFacet()).

borisson_’s picture

I'll give the test a go tonight, I'll leave this tab open, thanks for the hard work you put in already!

marcvangend’s picture

No problem, it's a good way to learn about the internals of the Facets module, and the time investment is only a fraction of what I get out of it for free :-)

borisson_’s picture

StatusFileSize
new2.01 KB
new9.19 KB

Adds a test.

marcvangend’s picture

Looks great. I (re-)read every line and couldn't find a single nitpick. If part of it wasn't my own code, I would RTBC :-)

  • borisson_ committed 199477d on 8.x-1.x authored by marcvangend
    Issue #2859139 by borisson_, marcvangend: Automatically disable caching...
borisson_’s picture

Status: Needs review » Fixed

Good enough for me, committed and pushed. Thanks again @marcvangend!

slasher13’s picture

Status: Fixed » Needs work

You can't use other FacetSource provider and you can't use it without search_api, too

-    list($type,) = explode(':', $facet_source_id);
-
-    if ($type === 'search_api_views') {
-      list(, $view_id, $display) = explode(':', $facet_source_id);
-    }
-    if (isset($view_id)) {

Why not use this for search_api_views only like before?

borisson_’s picture

We still do that, we look for the search api display definition AND check for if (!empty($search_api_display_definition['view_id'])) {}.

That does the same thing.

slasher13’s picture

Yes, but \Drupal::service('plugin.manager.search_api.display') must be defined.

marcvangend’s picture

I see. So we should wrap that part of the code in an if-statement?

if (\Drupal::hasService('plugin.manager.search_api.display')) {
  $search_api_display = \Drupal::service('plugin.manager.search_api.display')
    ->createInstance($facet_source_display_id);
  // etc...
}
borisson_’s picture

I guess we could even do if (!\Drupal::hasService('plugin.manager.search_api.display')) { return; } to make sure that there's no unneeded nesting.

Not sure if I have to revert this issue and fix it in one go or if we add a new patch here. I guess adding a new patch and committing on this issue is ok?

marcvangend’s picture

I don't think we can return; at that point, we do want the submitForm() method to finish its task even if there is no view, right?

borisson_’s picture

Ah, of course, you're right! Looks like I need to do less things at the same time ;)

borisson_’s picture

Status: Needs work » Needs review
StatusFileSize
new6.46 KB

So, something like this?

borisson_’s picture

Status: Needs review » Fixed

Committed that.

  • borisson_ committed ce0fbe5 on 8.x-1.x
    Issue #2859139 by borisson_, marcvangend, slasher13: Follow-up...
slasher13’s picture

Status: Fixed » Needs review
StatusFileSize
new1.81 KB
new1.81 KB

Sorry, a few minutes too late.
I think it's better to check the facet source type, because you can have different facet source plugin provider without search_api support, even if search_api is installed.

Maybe adding the tpye to the facet source plugin definition can solve this.

  • borisson_ committed 5dc5052 on 8.x-1.x authored by slasher13
    Issue #2859139 by borisson_, marcvangend, slasher13: Automatically...
borisson_’s picture

Status: Needs review » Fixed

Yep, committed. Thanks! Sorry for not having enough patience ;)

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.