Problem/Motivation

When using a custom querystring key in the pagerer module, for "one-based" page index, the overview of the taxonomy terms pagination breaks. For example: When using "pg" as querysting key, the pagerer module will convert the url on the taxonomy overview (example for tags): /admin/structure/taxonomy/manage/tags/overview?pg=2 . This results in exactly the same terms that are listed on the first page. When we look at web/core/modules/taxonomy/src/Form/OverviewTerms.php, the page index is retrieved by:

$page = $this->getRequest()->query->get('page') ?: 0;

So the taxonomy overview form, will never take the custom querystring into account.

Steps to reproduce

  1. On the pagerer url settings, provide a custom querystring key and select "one-based" as page index.
  2. Go to a taxonomy overview page, with a sufficient amount of terms, so that a pager will be visible.
  3. Click on "next" or "2" in the pager.
  4. New page will load, but the terms are still the same.

Proposed resolution

Use the new PagerManager::findPage() method, instead.

Remaining tasks

User interface changes

API changes

Data model changes

Comments

Gvert created an issue. See original summary.

gvert’s picture

Title: Using custom querystring key for "one-based" page index base, breaks paging on taxonomy overivew » Using custom querystring key for "one-based" page index base, breaks paging on taxonomy overview
mondrake’s picture

Title: Using custom querystring key for "one-based" page index base, breaks paging on taxonomy overview » Drupal\taxonomy\Form\OverviewTerms should determine the current page via the 'pager.parameters' service, not from the Request
Project: Pagerer » Drupal core
Version: 8.x-2.0 » 9.1.x-dev
Component: Code » taxonomy.module
Priority: Normal » Major

Thanks for the report.

IMHO this is a core issue, specifically an oversight in the conversion of the pager to services in #2044435: Convert pager.inc to a service.

The current page number should be determined by calling ::findPage from the 'pager.parameters' service, not directly from the request object. Pagerer overrides the 'pager.parameters' service to return it from the custom querystring, but cannot do anything if the request is accessed directly.

Moving to core issue queue.

mondrake’s picture

Status: Active » Needs review
StatusFileSize
new2.94 KB

That's the idea, let's see if tests pass... I do not know how we could add specific testing for this though.

Status: Needs review » Needs work

The last submitted patch, 4: 3170185-4.patch, failed testing. View results

mondrake’s picture

Status: Needs work » Needs review
StatusFileSize
new605 bytes
new3.28 KB

It's a good idea to put the medicament in the syringe, for an injection.

gvert’s picture

Status: Needs review » Reviewed & tested by the community

I have applied the "3170185-6.patch" patch on drupal 9.1 dev version. The pager on a taxonomy overview list, works now in combination with the pagerer module with a custom key in the querystring. Thanks mondrake!

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/modules/taxonomy/src/Form/OverviewTerms.php
    @@ -93,6 +103,11 @@ public function __construct(ModuleHandlerInterface $module_handler, EntityTypeMa
    +      @trigger_error('Calling OverviewTerms::__construct() without passing the $pager_parameters argument is deprecated in drupal:9.1.0 and will be required in drupal:10.0.0. See https://www.drupal.org/node/TODO', E_USER_DEPRECATED);
    

    I don't think we need a CR here. So the link is not required.

  2. +++ b/core/modules/taxonomy/src/Form/OverviewTerms.php
    @@ -104,7 +119,8 @@ public static function create(ContainerInterface $container) {
    +      $container->get('pager.manager'),
    +      $container->get('pager.parameters')
    
    @@ -136,7 +152,7 @@ public function buildForm(array $form, FormStateInterface $form_state, Vocabular
    -    $page = $this->getRequest()->query->get('page') ?: 0;
    +    $page = $this->pagerParameters->findPage();
    

    This seems really awkward to have to inject both of these services. I think given the example code in \Drupal\Core\Pager\PagerManagerInterface::createPager() it'd be nice to implement PagerManagerInterface::findPage() that calls through to the pager parameters service. I wonder if we should open a follow-up for that. Because then we could remove the service injection.

mondrake’s picture

Status: Needs work » Needs review
StatusFileSize
new1.01 KB
new3.25 KB

Filed follow-up #3173636: Implement a PagerManagerInterface::findPage() method, for D10 - we'd break BC for contrib if we did that earlier.

Fixed the @trigger_error.

Back to RTBC since the change is only to an untested deprecation error string.

mondrake’s picture

Status: Needs review » Reviewed & tested by the community
larowlan’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/taxonomy/src/Form/OverviewTerms.php
@@ -93,6 +103,11 @@ public function __construct(ModuleHandlerInterface $module_handler, EntityTypeMa
+      @trigger_error('Calling OverviewTerms::__construct() without passing the $pager_parameters argument is deprecated in drupal:9.1.0 and will be required in drupal:10.0.0.', E_USER_DEPRECATED);
+      $pager_parameters = \Drupal::service('pager.parameters');

We would ordinarily require a deprecation test to go with a new deprecation

Can we get a simple test that checks the correct deprecation error is emitted in that scenario.

larowlan’s picture

Issue tags: +Bug Smash Initiative
mondrake’s picture

Status: Needs work » Reviewed & tested by the community

Not sure about adding a test only for the additional constructor arguments. At least #3096648: Add support for third party libraries in site specific and install profile specific libraries folders and #3101299: Install module from .zip URL fails did not introduce one. Can we clarify the policy before adding one?

alexpott’s picture

Re #11 @catch and I have discussed this before and agreed that deprecation testing for only a constructor change like this is unnecessary. If there is more logic in the constructor than a simple is not null check then a test is required but that's not the case here.

larowlan’s picture

Ok, I wasn't aware of that decision.

I'll update the 'how' section of the docs tomorrow

mondrake’s picture

Status: Reviewed & tested by the community » Postponed

#3173636: Implement a PagerManagerInterface::findPage() method is making good progress, so I suggest to wait for that to go in, which will make this patch much simpler.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

mondrake’s picture

Status: Postponed » Needs review
StatusFileSize
new766 bytes

#3173636: Implement a PagerManagerInterface::findPage() method was committed, and now the fix is just a one-liner.

mondrake’s picture

Issue summary: View changes

#3173636: Implement a PagerManagerInterface::findPage() method was committed, and now the fix is just a one-liner.

mondrake’s picture

Title: Drupal\taxonomy\Form\OverviewTerms should determine the current page via the 'pager.parameters' service, not from the Request » Drupal\taxonomy\Form\OverviewTerms should determine the current page via the 'pager.manager' service, not from the Request
paulocs’s picture

Status: Needs review » Reviewed & tested by the community

Confirm that patch #18 solves the problem with the right approach after #3173636: Implement a PagerManagerInterface::findPage() method was committed.
Moving to RTBC.

andypost’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs tests

As a bug it needs -fail.patch steps in summary looks great for scenario

paulocs’s picture

Assigned: Unassigned » paulocs
mondrake’s picture

You can't test this unless you swap the service, which would require developing a test module for. Not sure it's worth it. Existing tests already work in the sense that the change is behaving (for core) exactly as if the page is extracted from the request.

paulocs’s picture

Assigned: paulocs » Unassigned

Yes, I was trying to write tests for it but did not find a way. I just can confirm that it fixes the problem related on the issue summary.

Maybe screenshots are enough?

mondrake’s picture

Status: Needs work » Reviewed & tested by the community

  • catch committed fe53c49 on 9.2.x
    Issue #3170185 by mondrake, Gvert, larowlan, paulocs, alexpott: Drupal\...
catch’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: -Needs tests

Agreed this is OK without an explicit test, it's a refactor to use the correct API that enables contrib to override properly.

Committed/pushed to 9.2.x, thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.