Skip to content

Instantly share code, notes, and snippets.

@prajwal89
Last active November 2, 2022 10:54
Show Gist options
  • Save prajwal89/c21f658f39b4536de8052ad94bcc1928 to your computer and use it in GitHub Desktop.
Save prajwal89/c21f658f39b4536de8052ad94bcc1928 to your computer and use it in GitHub Desktop.
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