Score:0

Experiencing problems filtering view programmatically

jp flag

I'm using a views block in my website, the content of this view is filtered programmatically. I now get messages from users who see the wrong information. The filter is based on the currently logged in user. Since I need this information in the regular filter and not in the contextual filter I created a simple module to change the filter value.

My filter is like this:

(
Content type = contenttype_a
AND
uid(nodes author) = */this value is programmatically added*/
)

OR

(
Content type = contenttype_b
AND
user_target_id(reference) =  */this value is programmatically added*/
)

Than I use this in my module:

 */
function entity_access_views_pre_view(ViewExecutable $view, $display_id, array &$args){
  $currentUser = \Drupal::currentUser();
  $cuid = $currentUser->id();

    /* @ Filter View: Media  */
    if ($view->id() == 'my_view_id') {
      if ($display_id == 'block_1' || $display_id == 'page_1' || $display_id == 'page_2') {
        $filters = $view->display_handler->getOption('filters');
        $filters['uid']['value']['value'] = $cuid;
        $filters['user_target_id']['value']['value'] = $cuid;
        $view->display_handler->overrideOption('filters', $filters);
      }
    }
}

Since I can't seem to find the problem I'm having doubts about if above is working as I want it to. So I wanted to check if you see anything strange or false. Can this filter value be cached in some way? Or maybe there is a better way to do this.

I can't use the contextual filter, which I would prefer, because the view is showing two content types where on each content type the filter should be different.

Thanks in advance.

Score:0
cn flag

First you can try to add a cache context to the render element of the View before it is rendered:

/**
 * Implements hook_views_pre_render().
 *
 */
function mymodule_views_pre_render(ViewExecutable $view) {
  if ($view->id() == 'my_view_id') {
    if ($view->current_display == 'block_1') {
      $view->element['#cache']['contexts'][] = 'user';
      // or add a cache max-age 0 for a high user count
      $view->element['#cache']['max-age'] = 0;
    }
  }
}

This doesn't help however if Views is caching the query internally. Then you can try to disable caching by configuring the None or Time-based cache plugin within the View. You can't configure a cache context here, though, only a cache max-age of 0. This is not necessarily a bad idea if you have a high user count and don't want to cache the same amount of variants. Drupal has a great caching system for delivering non-cacheable blocks to authenticated users (Dynamic Page Cache + BigPipe).

Joost avatar
jp flag
Thanks, disabling the cache in the view itself is my first try to solve this. I'm now waiting to see if this solves the problem.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.