0

I created a view via the view user interface. From a custom module, I want alter the view for display the n firsts results depending of some user parameters.

I don't find how I can do that with views alter hook functions. For example, via the pre execute view alter hook, I can get the query substructure. How can I configure this structure for not display all results by display only the first N results?

The "limit" value define the value in the current page with the current "level" of pager (10 results of the 27 results are displayed in pager 1, 10 results of the 27 results are displayed in pager 2 and 7 results of the 27 results are displayed in pager 3). The "limit" doesn't define the total number o, f the result query.

enter image description here

Thanks to Kevin answer, I tried this code.

function mycustommodule_views_query_alter(ViewExecutable $view, \Drupal\views\Plugin\views\query\QueryPluginBase $query){

    if($views->id() == "mycustomview"){
        $view->query->setLimit(7);
        $view->query->setOffset(5);
        $view->save();

        // I try also ..
        // $query->setLimit(7);
        // $query->setOffset(5);
    }
}

My view in the view page doesn't change and displays 10 results (number total of nodes). How can I set Limit and/or Offset and 'save' the change from the hook view query alter?

After Rémy's answer, I tried this code.

function mymodule_views_query_alter(\Drupal\views\ViewExecutable $view, \Drupal\views\Plugin\views\query\QueryPluginBase $query){

    if($views->id() == "mycustomview"){
        $query->setLimit(3);
        ksm("Hey ! I pass here !"); // log function
    }
}

in drupal/modules/custom/mymodule/mymodule.module file

OR

in in drupal/modules/custom/mymodule/mymodule.views_execute.inc file

and I clear caches with "drush cr"

=> My view page display my log ("Hey ! I pass here !"), BUT, my view always display ALL result :/ Its crazy ! x)

5
  • Am I missing something here, but can't you create two Views, and set the first to only show N, and then the second view, give it an offset of N so it starts at that result?
    – Kevin
    Commented Sep 19, 2016 at 22:09
  • I want be able to change dynamically the 'N' variable :) before the view is rendered, I want set the 'N' according the current user parameters Commented Sep 19, 2016 at 22:13
  • Have you tried $query->setLimit(N) from the query alter? api.drupal.org/api/drupal/…
    – Kevin
    Commented Sep 19, 2016 at 22:17
  • There is also setOffset. api.drupal.org/api/drupal/…
    – Kevin
    Commented Sep 19, 2016 at 22:18
  • setLimit in query alter seems I'm looking for, Ill try tomorrow :) Commented Sep 19, 2016 at 22:30

4 Answers 4

5
+50

You need to alter the pager, see ViewExecutable:initPager(), so right now only this code works (seems confusing ..):

function mycustommodule_views_query_alter(\Drupal\views\ViewExecutable $view, \Drupal\views\Plugin\views\query\QueryPluginBase $query){
    if($view->id() == 'mycustomview'){
        $view->setOffset(5);
        $view->getPager()->setItemsPerPage(7);
    }
}

Is that code touched only the first time ? (After running drush cr)

If so - move the method in a file called mycustommodule.views_execution.inc. It won't work on every request inside mycustommodule.module file. see here!

Also make sure Disable SQL rewriting is not set in the view used !

For more information see the issue I addressed regarding this on d.o.

5
  • I try this..but its not work ! I add a function log in the views_query_alter, if this hook is in a mymodule.module or mymodule.views_execution.inc, the log is displayed but my views display always all results. I update my first post (and I become crazy x) ) Commented Sep 24, 2016 at 16:18
  • okey .. - debugged this for you .. pls see my updated answer. it looks like when a pager is in place, the pager has to be altered ....
    – rémy
    Commented Sep 26, 2016 at 14:36
  • Its better ! with your code, my view is altered ! It shows nodes 5,6,7,...,15 in several pager (7 nodes by pager). How can I show the n firsts nodes ? :) (I tried $view->query->setLimit(5) and $query->setLimit(5), but has no effect ..) Commented Sep 27, 2016 at 6:01
  • disable the pager (Display a specified number of items / display all items) in your display of that view in the UI
    – rémy
    Commented Sep 27, 2016 at 7:47
  • Yes :) I can't test it yet Commented Sep 27, 2016 at 11:22
0

If I understand the question correctly, you might want to try using setLimit and setOffset on the $query object passed to hook_views_query_alter():

https://api.drupal.org/api/drupal/core%21modules%21views%21src%21Plugin%21views%21query%21QueryPluginBase.php/function/QueryPluginBase%3A%3AsetLimit/8.2.x

https://api.drupal.org/api/drupal/core%21modules%21views%21src%21Plugin%21views%21query%21QueryPluginBase.php/function/QueryPluginBase%3A%3AsetOffset/8.2.x

Since it is dynamic per user, you might have caching considerations... I think this should be early enough in the process to change it to what you want.

1
  • Thank you :) I update my post, I tried some code but I don't find how I must save the view from the view query alter set Limit or Offset ? I don't find example of this hook in drupal code or in the web.. Commented Sep 20, 2016 at 6:09
0

You can try the hook_views_pre_execute

function mycustommodule_views_pre_execute(\Drupal\views\ViewExecutable $view) {
  if ($view->id() == "mycustomview") {
    $query = $view->query;
    $query->setLimit(7);
    $query->setOffset(5);
  }
}

I think your problem is a filter not limit (If I understood correctly). If you want to add filter like 'WHERE' in sql follow this page : https://api.drupal.org/api/drupal/core!modules!views!views.api.php/function/hook_views_query_alter/8.2.x

1
  • Its about limit :) My view display 10 result, I want it display the 4 firsts result by example (depending current user parameters) Commented Sep 24, 2016 at 15:55
0

I was having a similar issue, here is what worked for me. Hope it helps someone.

function mymodule_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
      if ($view->storage->get('id') === 'viewid' && $view->current_display === 'displayid'){
          $query->setLimit(1);
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.