- 🇳🇿New Zealand quietone
I tried to test this on Drupal 10.1.x, using the steps in the Issue Summary. I wasn't able to follow the steps in the Issue Summary where it states, "On the Block display, set "Link display" to "Page"." There was no step previous step to create a block display. There are screenshots in #59 (which should be linked from the Issue Summary) which are using standard profile yet the instructions are for minimal. Do we know if the suggested fix works for both profiles?
There is a comment in #54 that this was not reproducible. We need to confirm the problem exists before working on the patch.
I am adding tags for an Issue summary update and steps to reproduce.
- 🇳🇿New Zealand quietone
I retested and can reproduce the problem. It was user error on my part, I just didn't read the steps correctly.
The patch still applies, so I tested it and it does work and locally the same test fails as in #72. I have updated the remaining steps in the IS.
- Status changed to Needs review
over 1 year ago 2:08pm 5 June 2023 - last update
over 1 year ago 30,337 pass - last update
over 1 year ago 30,337 pass - 🇳🇱Netherlands megachriz
I did some fiddling with the tests, but I finally found a way to reproduce it with a test!
I needed to add a call to
drupal_flush_all_caches()
somewhere and let the test also visit other pages where the same view is displayed on. - Status changed to Needs work
over 1 year ago 3:05pm 5 June 2023 - 🇳🇱Netherlands megachriz
Hm. The tests only patches still passes on the testbot. Maybe still needs work then.
- last update
about 1 year ago 30,343 pass - 🇺🇸United States joycehutch Kansas City, MO
I was using the #46 patch and it worked fine until upgrading to Drupal 10. It doesn't work with Drupal 10.
- last update
about 1 year ago 29,678 pass - 🇮🇳India Akhil Babu Chengannur
I tested this issue in 10.1.6 with standard installation profile and these are the findings
- Updated Recent content view as per the issue description, placed the block in sidebar and created 4 pages.
- More link was not appearing in the block even after clearing cache.
- More link appears only if "Always display the more link" is enabled.
- Ideally More link should appear even if "Always display the more link" is not enabled. There is already an issue https://www.drupal.org/project/drupal/issues/3381979 🐛 More link is missing in pager when using the "Some" pager and there are more records than shown Needs work related to this. Applied the patch from comment #8 on that issue and More link appeared again.
What was the issue and how the patch fixed it?
. Drupal\views\Plugin\views\display\DisplayPluginBase calls renderMoreLink() to check if More link should be rendered or not.
/** * {@inheritdoc} */ public function renderMoreLink() { $hasMoreRecords = !empty($this->view->pager) && $this->view->pager->hasMoreRecords(); if ($this->isMoreEnabled() && ($this->useMoreAlways() || $hasMoreRecords)) { $url = $this->getMoreUrl(); return [ '#type' => 'more_link', '#url' => $url, '#title' => $this->useMoreText(), '#view' => $this->view, ]; } }
renderMoreLink() calls Drupal\views\Plugin\views\pager\PagerPluginBase::hasMoreRecords()
public function hasMoreRecords() { return $this->getItemsPerPage() && $this->total_items > (intval($this->current_page) + 1) * $this->getItemsPerPage(); }
Function checks if total_items is greater than the number of currently displayed items.
Logic to set total_items was updated in another issue https://www.drupal.org/project/drupal/issues/3265798 🐛 [view:total-rows] problem in Display a 'Specified number of items' pager Fixed and was committed to core. The fix in that issue was to add postExecute function in Drupal\views\Plugin\views\pager\Some to set the value of total_items aspublic function postExecute(&$result): void { $this->total_items = count($result); }
So total_item only stores the number of results returned after applying pagination instead of storing the total number of results. If the view has 4 results and pagination is set to show 3 items, then value stored in total_item will be 3 instead of 4.
Now, the patch in comment #8 of https://www.drupal.org/project/drupal/issues/3381979 🐛 More link is missing in pager when using the "Some" pager and there are more records than shown Needs work introduced a new property numberOfItemsBeforeLimit to store the actual number of results , and then overrided hasMoreRecords() which fixed the issue.
public function hasMoreRecords() { // Use the original number of items if it has been set to determine if there // are more records. return $this->getItemsPerPage() && ($this->numberOfItemsBeforeLimit ?? $this->total_items) > $this->getItemsPerPage(); }
Caching issue with More link
I was able to reproduce the caching issue (Recent content block placed in sidebar->Created 4 pages->viewed the block from page 1-> More link is present->viewed the block from page 2 -> More link is not present) once the More link got rendered. But none of the patches in this issue fixes the problem.
Reason
As mentioned earlier, renderMoreLink() function calls hasMoreRecords() which should return 'true' to display the More link. hasMoreRecords() compares the value of total_items with number of items currently being displayed. total_items should be higher than number of items currently being displayed. But this never happen when view gets cached.
Check the following lines from ViewsExecutable::execute()
if ($cache->cacheGet('results')) {
if ($this->usePager() || !empty($this->get_total_rows)) {
$this->pager->total_items = $this->total_rows;
$this->pager->updatePageInfo();
}
}
else {
$this->query->execute($this);
// Enforce the array key rule as documented in
// views_plugin_query::execute().
$this->result = array_values($this->result);
$this->_postExecute();
$cache->cacheSet('results');
}When view is served from cache, then total_rows value of the view is set as total_items value in pager. So total_rows of view should give the actual numer of results rather than pagination limited result to the pager. Does that happen?
Assume view is rendering for the first time. Then there is no data in cache and $this->query->execute($this); gets called. This invokes Drupal\views\Plugin\views\query\Sql::execute. Take a look at the following lines from that function
$view->pager->postExecute($view->result);
$view->pager->updatePageInfo();
$view->total_rows = $view->pager->getTotalItems();It calles postExecute method on pager class and also uses the result of $view->pager->getTotalItems() to set total_count of view.
What does $view->pager->postExecute($view->result) do? It sets the value of total_count to the number of results.
Drupal\views\Plugin\views\pager\Some::postExecutepublic function postExecute(&$result): void { $this->total_items = count($result); }
If there are 4 nodes and we set pagination limit to to display 3 items, then total_items will be set to 3.
What does $view->pager->getTotalItems() return?
public function getTotalItems() { return $this->total_items; }
It returns the value of total_items which will be 3 in this case instead of 4.
So the view gets stored with total_rows 3 in cache->When view is served from cache, $this->pager->total_items = $this->total_rows; gets executed ->renderMoreLink() function calls hasMoreRecords() to check if More link should be rendered or not-> hasMoreRecords() always returns false as total_items property of pager do not have the actual result count.
In summary, there is no property in pager class or view that gives any infornation about the actual number of results.