Skip to content

Instantly share code, notes, and snippets.

@prajwal89
Last active November 2, 2022 10:54
Google like pagination logic that keeps current page in the middle and keeps number of pages in pagination same if possible.
<?php
function get_pagination_range(int $current_page, int $total_pages, int $each_side): array
{
if ($current_page > $total_pages) {
return []; //current page should be smaller than total pages
}
$start = $current_page - $each_side;
$end = $current_page + $each_side;
if ($start <= 1) {
//extend end by difference from 1st page
$adjusted_end = $end + ($start * -1) + 1; //+1 bc. we need difference from page 1 (pages generally starts from 1)
} else {
$adjusted_end = $end;
}
if ($end > $total_pages) {
//reduce start by difference from end page
$adjusted_start = $start - ($end - $total_pages);
} else {
$adjusted_start = $start;
}
//keep pages inside 1 and total_pages
$final_start = max($adjusted_start, 1);
$final_end = min($adjusted_end, $total_pages);
return range($final_start, $final_end);
}
get_pagination_range(current_page: 1, total_pages: 23, each_side: 3); //array(7) { [0]=> int(1) [1]=> int(2) [2]=> int(3) [3]=> int(4) [4]=> int(5) [5]=> int(6) [6]=> int(7) }
get_pagination_range(current_page: 60, total_pages: 100, each_side: 5); //array(11) { [0]=> int(55) [1]=> int(56) [2]=> int(57) [3]=> int(58) [4]=> int(59) [5]=> int(60) [6]=> int(61) [7]=> int(62) [8]=> int(63) [9]=> int(64) [10]=> int(65) }
@prajwal89
Copy link
Author

prajwal89 commented Nov 2, 2022

Shorter Version

function get_pagination_range(int $current_page, int $total_pages, int $each_side): array
{
if ($current_page > $total_pages) return []; //current page should be smaller than total pages
[$start, $end] = [$current_page - $each_side, $current_page + $each_side];
$start < 1 ? $adjusted_end = $end + ($start * -1) + 1 : $adjusted_end = $end; //extend end by difference from 1st page
$end > $total_pages ? $adjusted_start = $start - ($end - $total_pages) : $adjusted_start = $start; //reduce start by difference from end page
return range(max($adjusted_start, 1), min($adjusted_end, $total_pages)); //keep pages inside 1 and total_pages
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment