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)

  • 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 Sep 19 '16 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 – user2137454 Sep 19 '16 at 22:13
  • Have you tried $query->setLimit(N) from the query alter? api.drupal.org/api/drupal/… – Kevin Sep 19 '16 at 22:17
  • There is also setOffset. api.drupal.org/api/drupal/… – Kevin Sep 19 '16 at 22:18
  • setLimit in query alter seems I'm looking for, Ill try tomorrow :) – user2137454 Sep 19 '16 at 22:30
4
+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.

  • 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) ) – user2137454 Sep 24 '16 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 Sep 26 '16 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 ..) – user2137454 Sep 27 '16 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 Sep 27 '16 at 7:47
  • Yes :) I can't test it yet – user2137454 Sep 27 '16 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.

  • 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.. – user2137454 Sep 20 '16 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

  • Its about limit :) My view display 10 result, I want it display the 4 firsts result by example (depending current user parameters) – user2137454 Sep 24 '16 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, privacy policy and cookie policy

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