I am using views_pre_render to alter view result. It is working fine but pagination is not working as per updated result.

<?php

/**
 * Implementation of hook_views_pre_render().
 */
function MODULENAME_views_pre_render(&$view) {
  if ($view->name == 'my_view' && $view->current_display == 'my_display') {
    // View result update logic.
    // e.g.
    // $result = array();
    // foreach ($view->result as $k => $row) {
    //   if (whatever is your condition) {
    //     $result[$k] = $row;
    //   }
    // }

    // Assuming $result has data as per your logic.
    // Update the pager according to result.
    $view->query->pager->total_items = count($result);
    $view->query->pager->update_page_info();
    // Add results to view.
    $view->result = $result;
  }
}
?>

How can i get the correct pagination with updated result.

Comments

cplasencia’s picture

I have the same problem in drupal 8. Do you solved it?

tanzeel’s picture

Try that snippet at end of your function.
 

$view->query->pager->total_items = NEW_TOTAL; // new total with new results
$view->query->pager->current_page = CURRENT_PAGE; // current page of views pagination
$view->query->pager->update_page_info();

Thank you,
Tanzeel

attheshow’s picture

This appears to work in Drupal 8.

// Adjust the results, count & pager of the view.
$view->total_rows = count($new_result);
$view->pager->total_items = count($new_result);
$view->pager->updatePageInfo();
$view->result = $new_result;
msypes’s picture

Snippet works like a charm:

$view->total_rows = count($new_result); // Not strictly necessary, but nice to keep this in sync
$view->getPager()->total_items = count($new_result);
$view->getPager()->updatePageInfo();

Michael

Gonzalo2683’s picture

Hi, snippet works, but I think there is a problem to make it work properly.

I explain the possible problem:
In my case I am adjusting the default content view of drupal, and suppose this is paged at 5 items per page.
So:
I am going to filter by type of content, in the example I have marked an assumption that those nodes are the ones that complete the condition.
Page 0
Item 1
Item 2 -> I want this
Item 3
Item 4
Item 5

Page 1
Item 1
Item 2
Item 3
Item 4
Item 5 -> I want this
The view returns me of 5 items, that means that I will never find out about the other items that come on the following pages.

My question is how can I know how to filter correctly taking into account all the items that may be on other pager pages?

Gonzalo2683’s picture

function MY_MODULE_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
  if ($view->id() == "content" && $view->current_display == "page_1") {
    $is_custom_role = _some_validation_custom();
    if ($is_custom_role) {
      $query->addWhere('', 'node_field_data.type', 'content_type_name_to_filter');
    }
  }
}
Mk_esse’s picture

  if ($view->id() == "book") {
    foreach ($view->result as $key => $result) {
      $node = Node::load($result->nid);
      if ($node->access()) {
        unset($view->result[$key]);
      }
    }

// total items per page is 10

    $view->total_rows = count($view->result);
    $view->pager->updatePageInfo();
    

  }
msypes’s picture

$view->total_rows = count($view->result);

isn't very important, but as I've noted above, it makes sense to do so. What you really need before updating the page info is to fix the pager's concept of the row count:

$view->getPager()->total_items = count($view->result);
$view->getPager()->updatePageInfo();

Michael