q2a / question2answer

Question2Answer is a free and open source platform for Q&A sites, running on PHP/MySQL.
http://www.question2answer.org/
GNU General Public License v3.0
1.63k stars 628 forks source link

Allow pagination of element lists that exceed QA_MAX_LIMIT_START #932

Closed pupi1985 closed 1 year ago

pupi1985 commented 2 years ago

The main issue is that QA_MAX_LIMIT_START is limiting the amount of pages displayed when using the Q2A pagination. This is fine for most core features, but when writing plugins, it might be important to override this limitation. Of course it is possible to copy/paste the function and tweak it, but that's just not great.

Instead of adding another parameter to the huge function, I thought that one parameter could be re-purposed. The $hasmore parameter is there to add an ellipsis at the end of the pages. At first sight, it seems related to the limit imposed by QA_MAX_LIMIT_START: if the limit is reached and there are more results that are not being displayed, at least show the ellipsis to tell the user there are more stuff.

However, that is not correct. If it was, then why send it as a parameter? At the end of the day, the function on its own should be able to tell if the limit has been exceeded or not based on the $count parameter. Well, it seems the issue relies in search modules.

Search modules don't return the amount of total results that were matched with the search. They just return the specific slice of the results. This is fine to improve performance... but how can we tell the total amount of pages to build the links then? The approach is just fetching a few more results and add some additional pages. So when building the links, the core can certainly tell if there are a few more pages but can't tell if there are more. So in this case, the $count parameter is not really a count and the fix for that is to override the ellipsis from outside the function, using the $hasmore parameter.

So we can replace the $hasmore with a custom limit, which would default to QA_MAX_LIMIT_START for backwards compatibility and, if set explicitly to boolean by plugins, it can be converted to integer inside the function. Then, the function will figure out if the ellipsis is needed or not. For the specific case of the search module, we can apply this logic: if we got less records than we requested then we know we are at the end of the list so avoid the ellipsis, otherwise, add the ellipsis.

Sorry for the long explanation, but it took me a while to understand why things were the way they were.

svivian commented 1 year ago

Good stuff, thanks.