-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Model::paginate()
behavior when $page
exceeds the last page
#8904
Comments
one this BaseModel public function paginate(?int $perPage = null, string $group = 'default', ?int $page = null, int $segment = 0)
{
// Since multiple models may use the Pager, the Pager must be shared.
$pager = service('pager');
if ($segment !== 0) {
$pager->setSegment($segment, $group);
}
$page = $page >= 1 ? $page : $pager->getCurrentPage($group);
// Store it in the Pager library, so it can be paginated in the views.
$this->pager = $pager->store($group, $page, $perPage, $this->countAllResults(false), $segment);
$perPage = $this->pager->getPerPage($group);
$offset = ($pager->getCurrentPage($group) - 1) * $perPage;
return $this->findAll($perPage, $offset);
} should be converted to something like this public function paginate(?int $perPage = null, string $group = 'default', ?int $page = null, int $segment = 0)
{
// Since multiple models may use the Pager, the Pager must be shared.
$pager = service('pager');
if ($segment !== 0) {
$pager->setSegment($segment, $group);
}
$page = $page >= 1 ? $page : $pager->getCurrentPage($group);
// Store it in the Pager library, so it can be paginated in the views.
$this->pager = $pager->store($group, $page, $perPage, $this->countAllResults(false), $segment);
$offset = ($page) * $perPage;
$perPage = $this->pager->getPerPage($group);
return $this->findAll($perPage, $offset);
} |
@crustamet I don't understand the difference. Please show the diff by |
Why? |
it doesn't matter the difference because how i did it is no good it is just to point out that if the total records in the database are 10 when you go to page 1000 the query remains as of the last page so the limit whould be {a long number}, {8} I dont have pagination only a load more button "Why?" - because i cannot remove the button when i have no records, it always gives me records even when i don't have so it always shows load more |
First of all it should return that query if you use $Model->paginate(8, 'group', 10); While the current implemented code is dependent on how many rows you actually have in the table If you have 10 users and you are at page 10 $Model->paginate(8, 'group', 10); I cannot return a 404 page if i have no more users on page 10 LOL |
It seems this behavior is intentional. CodeIgniter4/tests/system/Models/PaginateModelTest.php Lines 78 to 85 in 8fc8985
|
You can check if it has any more pages with |
Ok i get what you are saying, I dig this Anyways up to you guys, |
I don't know why the pagination behaves like that. If we change the behavior, it will be an breaking change. If you insist that this behavior is something that needs to be corrected, In my opinion, this pagination was not originally designed to handle very large amounts of data at high speed. |
I agree with everything you said, actually i will extend the current BaseModel paginate() maybe in time i will understand why it returns data even if it is out of range. I hope some other guy read this and maybe help us understand better |
Model::paginate()
behavior when $page
exceeds the last page
I've known about this behavior for a long time. |
The method name |
i made it and tested it public function paginate(?int $perPage = null, string $group = 'default', ?int $page = null, int $segment = 0)
{
// Since multiple models may use the Pager, the Pager must be shared.
$pager = Services::pager();
if ($segment) {
$pager->setSegment($segment, $group);
}
$page = $page >= 1 ? $page : $pager->getCurrentPage($group);
// Store it in the Pager library, so it can be paginated in the views.
$this->pager = $pager->store($group, $page, $perPage, $this->countAllResults(false), $segment);
$perPage = $this->pager->getPerPage($group);
$offset = ($pager->getCurrentPage($group) - 1) * $perPage;
return $this->findAll($perPage, $offset);
} The new one public function paginateStrict(?int $perPage = null, string $group = 'default', ?int $page = null, int $segment = 0)
{
$pager = Services::pager();
if ($segment) {
$pager->setSegment($segment, $group);
}
$page = $page >= 1 ? $page : $pager->getCurrentPage($group);
// Store it in the Pager library, so it can be paginated in the views.
$this->pager = $pager->store($group, $page, $perPage, $this->countAllResults(false), $segment);
$perPage = $this->pager->getPerPage($group);
$offset = ($page - 1) * $perPage;
return $this->findAll($perPage, $offset);
} |
I've looked at the code. In a good way, you need to change CodeIgniter4/system/Pager/Pager.php Lines 147 to 154 in 4151c12
Similar actions in CodeIgniter4/system/BaseModel.php Lines 1282 to 1286 in 4151c12
So the main reason is to change the |
I think this feature was implemented in the Feature.php
Right ? this issue should be closed. |
No. limit(0) ‐ switches receiving 1000/1000 rows or 0/1000 rows |
So with with this
If I have a total of 10 Pages If you still get records for sure this is not implemented... and in fact this limitZeroAsAll has nothing to do with pagination |
i don't think you got my issue, This is another issue #8278 Please answer my question as the answer matters the most If I have a total of 10 Pages And it has nothing to do with ->limit(0,0); I've tested it the answer is still YES they are still returning data even tough you are exceeding the total pages If i go to the Page 11, but I only have records for 10 pages it should return NO RECORDS ! Why ? because of SEO they see duplicate pages and someone can create issues by just adding +1 to the page number Page 11, Page 12, Page 10000 they will be all issues ! of duplicate content |
I understood the problem, but you don't understand the You can extend the Pager class and overwrite the service. All. This is the fastest solution for you right now. |
I know @neznaika0 i did extended the pager for sure as i did not have any other solution. that parameter $limitZeroAsAll should be related with the Pager from my point of view... |
PHP Version
8.3
CodeIgniter4 Version
4.1.5
CodeIgniter4 Installation Method
Manual (zip or tar.gz)
Which operating systems have you tested for this bug?
Linux
Which server did you use?
apache
Database
MySQL 5.6
What happened?
When i paginate the model like this
$UsersMode->orderBy('id_user', 'ASC')->paginate(8, 'group', $page_number);
returns "
SELECT * FROM users ORDER BY id_user ASC LIMIT 8, 8
" based on offset and per page numberBut my total count rows in the table are 24, so when i reach the end
16, 8
it returns me the same query as the last existing page in my database even with$page_number = 100
Steps to Reproduce
returns "
SELECT * FROM users ORDER BY id_user ASC LIMIT 8, 8
"But my total count rows in the table are 24, so when i reach the end
16, 8
$page_number = 10
and go to a page number more than 3 it returns the same query "SELECT * FROM users ORDER BY id_user ASC LIMIT 16, 8
"Expected Output
Going to a page number more than the total count rows of my table it should return the propper offset even if i have the total rows less than the per page number or less than the total count
$page_number = 10
it should returns the query "SELECT * FROM users ORDER BY id_user ASC LIMIT 80, 8
" even if i don't have enough records in my database tableAnything else?
No response
The text was updated successfully, but these errors were encountered: