So I'm doing this in PHP but it is a logic issue so I'll try to write it as generically as possible.
To start here's how this pagination script works:
for (draw first three pages links)
if (draw ellipsis (...) if there are pages between #1's pages and #3's pages)
for (draw current page and two pages on each side of it links)
if (draw elipsis (...) if there are pages between #3's pages and #5's pages)
for (draw final three pages links)
The problem is that when there are low amounts of pages (I noticed this when the page count was at 10) there should be an ellipsis but none is drawn.
Onto the code:
$page_count = 10; //in actual code this is set properly
$current_page = 1; //in actual code this is set properly
for ($i = 1;$i <= 3;$i++)
{
if ($page_count >= $i)
echo $i;
}
if ($page_count > 3 && $current_page >= 7)
echo "...";
for ($i = $current_page - 2;$i <= current_page + 2;$i++)
{
if ($i > 3 && $i < $page_count - 2)
echo $i;
}
if ($page_count > 13 && $current_page < $page_count - 5)
echo "...";
for ($i = $page_count - 2;$i <= $page_count;$i++)
{
if ($page_count > 3)
echo $i;
}
So I figure the best idea would to be to modify one of the two ellipsis if statements to include a case like this, however I've tried and am stumped.
Also please note that I condensed this code for readability sake so please don't give tips like "those for loops are ineffective because they will recalculate current_page - 2 for each iteration" because I know :)
For those whom want to see a breakdown of how this logic currently works, here is example output ( modified ) with iterating $page_count and $current_page.
http://rafb.net/p/TNa56h71.html
<?php
/**
* windowsize must be odd
*
* #param int $totalItems
* #param int $currentPage
* #param int $windowSize
* #param int $anchorSize
* #param int $itemsPerPage
* #return void
*/
function paginate($totalItems, $currentPage=1, $windowSize=3, $anchorSize=3, $itemsPerPage=10) {
$halfWindowSize = ($windowSize-1)/2;
$totalPages = ceil($totalItems / $itemsPerPage);
$elipsesCount = 0;
for ($page = 1; $page <= $totalPages; $page++) {
// do we display a link for this page or not?
if ( $page <= $anchorSize ||
$page > $totalPages - $anchorSize ||
($page >= $currentPage - $halfWindowSize &&
$page <= $currentPage + $halfWindowSize) ||
($page == $anchorSize + 1 &&
$page == $currentPage - $halfWindowSize - 1) ||
($page == $totalPages - $anchorSize &&
$page == $currentPage + $halfWindowSize + 1 ))
{
$elipsesCount = 0;
if ($page == $currentPage)
echo ">$page< ";
else
echo "[$page] ";
// if not, have we already shown the elipses?
} elseif ($elipsesCount == 0) {
echo "... ";
$elipsesCount+=1; // make sure we only show it once
}
}
echo "\n";
}
//
// Examples and output
//
paginate(1000, 1, 3, 3);
// >1< [2] [3] ... [98] [99] [100]
paginate(1000, 7, 3, 3);
// [1] [2] [3] ... [6] >7< [8] ... [98] [99] [100]
paginate(1000, 4, 3, 3);
// [1] [2] [3] >4< [5] ... [98] [99] [100]
paginate(1000, 32, 3, 3);
// [1] [2] [3] ... [31] >32< [33] ... [98] [99] [100]
paginate(1000, 42, 7, 2);
// [1] [2] ... [39] [40] [41] >42< [43] [44] [45] ... [99] [100]
This is probably an overcomplicated solution, but it works.
I've used an array here instead of just printing, which lets me "do-over" the logic.
Part of the problem occurs when "left and right of page" happens to coincide with left-and-right shoulders.
function cdotinator ( $current_page, $page_count )
{
$stepsize = 3;
$elipse = '...';
# Simple Case.
if ( $page_count <= 2 * $stepsize )
{
$out = range( 1, $page_count );
$out[$current_page - 1 ] = '*' . $current_page . '*';
return $out;
}
#Complex Case
# 1) Create All Pages
$out = range( 1, $page_count );
# 2 ) Replace "middle" pages with "." placeholder elements
for( $i = $stepsize+1 ; $i <= ( $page_count - $stepsize ) ; $i ++ )
{
$out[ $i - 1 ] = '.' ;
}
# 3.1 ) Insert the pages around the current page
for( $i = max(1,( $current_page - floor($stepsize / 2) )) ;
$i <= min( $page_count,( $current_page + floor( $stepsize/2)));
$i ++ )
{
$out[ $i - 1] = $i;
}
# 3.2 Bold Current Item
$out[ $current_page - 1 ] = '*' . $current_page . '*' ;
# 4 ) Grep out repeated '.' sequences and replace them with elipses
$out2 = array();
foreach( $out as $i => $v )
{
# end, current == peek()
end($out2);
if( current($out2) == $elipse and $v == '.' )
{
continue;
}
if( $v == '.' )
{
$out2[] = $elipse;
continue;
}
$out2[]= $v;
}
return $out2;
}
Output can be seen here: http://dpaste.com/92648/
Related
Again I am stuck with PHP array calculation, please if anyone understands my question try to help me out, let's explain...
[data.txt content]
Peer Call ID Duration Recv: Pack Lost ( %) Jitter Send: Pack Lost ( %) Jitter
139.59.232.196 0bb9262d6a1 00:01:12 0000003558 0000000000 ( 0.00%) 0.0000 0000001177 0000000000 ( 0.00%) 0.0200
139.59.232.196 41283499492 00:00:00 0000000000 0000000000 ( 0.00%) 0.0000 0000000000 0000000000 ( 0.00%) 0.0000
139.59.232.196 7033a541240 00:00:08 0000000000 0000000000 ( 0.00%) 0.0000 0000000019 0000000000 ( 0.00%) 0.0000
3 active SIP channels
PHP Code Starting from here.
$data = file_get_contents('./data.txt', TRUE);
$lines = explode("\n", $data);
foreach ($lines as $line) {
if (!preg_match('/( 0.00%)/', $line)) {
continue;
}
$data = explode(' ', $line);
$list[] = $data;
}
foreach ($list as $qoscalc) {
$average[] = ($qoscalc[17] * 1000 / 2);
$jitter[] = (int)$qoscalc[14];
$packet_loss[] = (int)$qoscalc[13];
}
print_r($average);
Till here the code is working fine it's giving me the output of $average array this >>
Array ( [0] => 10 [1] => 0 [2] => 0 )
After that, I couldn't do this math with the array, if I convert them in variable & I go with 1 data only then code is working fine, but when I try to get the result of all I couldn't make it, please help me if anyone understands my question.
$effective_latency = ($average + $jitter * 2 + 10 );
if ($effective_latency < 160) {
$r_value = 93.2 - ($effective_latency / 40);
} else {
$r_value = 93.2 - ($effective_latency - 120) / 10;
}
$r_value = $r_value - ($packet_loss * 2.5);
$mosresult = 1 + (0.035) * $r_value + (0.000007) * $r_value * ($r_value - 60) * (100 - $r_value);
$moslist[] = $mosresult;
I want to get all 3 array result, its suppose to be like this example: Array ( [0] => 4.40372901469 [1] => 3.40372901469 [2] => 4.90372901469 )
$i = 0; $t = 0; $e = 0; $g = 0; $f = 0; $p = 0; $b = 0;
foreach ($moslist as $mos) {
$i++;
if ($mos <= "5") {
$qosq = 'Excellent';
$e++;
} else if ($mos <= "4") {
$qosq = 'Good';
$g++;
} else if ($mos < "3") {
$qosq = 'Fair';
$f++;
} else if ($mos <= "2") {
$qosq = 'Poor';
$p++;
} else if ($mos <= "1") {
$qosq = 'Bad';
$b++;
} else {
continue;
}
$t++;
}
echo $qosq, "<br><br>\n";
If I understood the question correctly, the simplest solution would be to create a function for calculating the mosResult
function getMosResult($average,$jitter,$packet_loss)
{
$effective_latency = ($average + $jitter * 2 + 10 );
if ($effective_latency < 160) {
$r_value = 93.2 - ($effective_latency / 40);
} else {
$r_value = 93.2 - ($effective_latency - 120) / 10;
}
$r_value = $r_value - ($packet_loss * 2.5);
return 1 + (0.035) * $r_value + (0.000007) * $r_value * ($r_value - 60) * (100 - $r_value);
}
and then applying the function in a for loop on all the results like so
$length = count($list);
for($i = 0;$i < $length;$i++){
$mosList[]=getMosResult($average[$i],$jitter[$i],$packet_loss[$i]);
}
This solution would not be good for a larger project as you would quickly lose consistency between the three source arrays. For a more solid solution, look into objects or t least associative arrays.
I've got a script that dynamically calls and displays images from a directory, what would be the best way to paginate this? I'd like to be able to control the number of images that are displayed per page through a variable within the script. I'm thinking of using URL varriables (ie - http://domain.com/page.php?page=1) but am unsure how to go about this.
Thanks for the help.
This is a function I often use to do pagination. Hope it helps.
function paginate($page, $total, $per_page) {
if(!is_numeric($page)) { $page = 1; }
if(!is_numeric($per_page)) { $per_page = 10; }
if($page > ceil($total / $per_page)) $page = 1;
if($page == "" || $page == 0) {
$page = 1;
$start = 0;
$end = $per_page;
} else {
$start = ($page * $per_page) - ($per_page);
$end = $per_page;
}
$prev_page = "";
$next_page = "";
$all_pages = array();
$selected = "";
$enabled = false;
if($total > $per_page) {
$enabled = true;
$prev = $page - 1;
$prev_page = ($prev == 0) ? 0 : $prev;
$next = $page + 1;
$total_pages = ceil($total/$per_page);
$next_page = ($next <= $total_pages) ? $next : 0;
for($x=1;$x<=$total_pages;$x++) {
$all_pages[] = $x;
$selected = ($x == $page) ? $x : $selected;
}
}
return array(
"per_page" => $per_page,
"page" => $page,
"prev_page" => $prev_page,
"all_pages" => $all_pages,
"next_page" => $next_page,
"selected" => $selected,
"start" => $start,
"end" => $end,
"enabled" => $enabled
);
}
// ex: we are in page 2, we have 50 items, and we're showing 10 per page
print_r(paginate(2, 50, 10));
This will return:
Array
(
[per_page] => 10
[page] => 2
[prev_page] => 1
[all_pages] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
[next_page] => 3
[selected] => 2
[start] => 10
[end] => 10
[enabled] => 1
)
With all that data you are then pretty well armed to make the pagination links.
pagination is the same concept with or without sql. you just need your basic variables, then you can create the content you want. here's some quasi-code:
$itemsPerPage = 5;
$currentPage = isset($_GET['page']) ? $_GET['page'] : 1;
$totalItems = getTotalItems();
$totalPages = ceil($totalItems / $itemsPerPage);
function getTotalItems() {
// since they're images, perhaps we'll scan a directory of images to determine
// how many images we have in total
}
function getItemsFromPage($page, $itemsPerPage) {
// function to grab $itemsPerPage based on which $page we're on
}
function getPager($totalPages, $currentPage) {
// build your pager
}
hope that helps you get started!
If you name your images 01.jpg, 02.jpg it makes it easier to paginate. Then use glob to get all the images into an array and sort it.
When in doubt use javascript! This might help too: http://www.webplicity.net/flexigrid/
Might be good for galery-like apps, though I've never tried it :)
I have a pagination script with PHP. When page records are some hundreds, the pagination result is too big. How I can limit the page numbers/links?
Example: < 1 | 2 ... 37 | 38 | 39 | 40 | 41 | 42 ... 82 | 83 >
This is my PHP script
<?php
$ppp = 10;
$rows = mysql_num_rows($query);
$nmpages = ceil($rows/$ppp);
// if current page is not 1, draw PREVIOUS link
if ($pg > 1 && $nmpages != 0) {
echo "< ";
}
For($i = 1 ; $i <= $nmpages ; $i++) {
If($i == $pg) {
echo "<b>".$i."</b> ";
} else {
echo "".$i." ";
}
}
// if current page less than max pages, draw NEXT link
if ($pg < $nmpages && $nmpages != 0) {
echo ">";
}
?>
Do you have an ideas how I can do this with the specific PHP script that I have?
Try this :
<?php
$link = "";
$page = $_GET['pg']; // your current page
// $pages=20; // Total number of pages
$limit=5 ; // May be what you are looking for
if ($pages >=1 && $page <= $pages)
{
$counter = 1;
$link = "";
if ($page > ($limit/2))
{ $link .= "1 ... ";}
for ($x=$page; $x<=$pages;$x++)
{
if($counter < $limit)
$link .= "".$x." ";
$counter++;
}
if ($page < $pages - ($limit/2))
{ $link .= "... " . "".$pages." "; }
}
echo $link;
?>
OUTPUT :
//At page=1
1 2 3 4 ... 20
//At page=12
1 ... 12 13 14 15 ... 20
//At page=18
1 ... 18 19 20
An improvement or rather re-write based on #Makesh's code.
function get_pagination_links($current_page, $total_pages, $url)
{
$links = "";
if ($total_pages >= 1 && $current_page <= $total_pages) {
$links .= "1";
$i = max(2, $current_page - 5);
if ($i > 2)
$links .= " ... ";
for (; $i < min($current_page + 6, $total_pages); $i++) {
$links .= "{$i}";
}
if ($i != $total_pages)
$links .= " ... ";
$links .= "{$total_pages}";
}
return $links;
}
OUTPUT:
page = 1
1 2 3 4 5 6 ... 20
page = 10
1 ... 5 6 7 8 9 10 11 12 13 14 15 ... 20
page = 19
1 ... 14 15 16 17 18 19 20
The answer for this question was basically to visit a page about Digg style pagination which includes code samples.
So that's the answer, but this question is basically a duplicate.
Try to make a page bracket for example 10 less and 10 more than the actual page, change for example the for statement for this:
For($i = $pg-10 ; $i <= $pg+10 ; $i++)
I wanted to get an array of numbers by the current page and total page. So this is what I came up with. I hope this helps others -
Caution - this work if total page is more than 10. I felt if the total
page is less than 10 then just show it in a single for loop.
function getSmartPageNumbers($currentPage, $totalPage)
{
$pageNumbers = [];
$diff = 2;
$firstChunk = [1, 2, 3];
$lastChunk = [$totalPage - 2, $totalPage - 1, $totalPage];
if ($currentPage < $totalPage) {
$loopStartAt = $currentPage - $diff;
if ($loopStartAt < 1) {
$loopStartAt = 1;
}
$loopEndAt = $loopStartAt + ($diff * 2);
if ($loopEndAt > $totalPage) {
$loopEndAt = $totalPage;
$loopStartAt = $loopEndAt - ($diff * 2);
}
if (!in_array($loopStartAt, $firstChunk)) {
foreach ($firstChunk as $i) {
$pageNumbers[] = $i;
}
$pageNumbers[] = '.';
}
for ($i = $loopStartAt; $i <= $loopEndAt; $i++) {
$pageNumbers[] = $i;
}
if (!in_array($loopEndAt, $lastChunk)) {
$pageNumbers[] = '.';
foreach ($lastChunk as $i) {
$pageNumbers[] = $i;
}
}
}
return $pageNumbers;
}
Test:
getSmartPageNumbers(8, 20);
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => .
[4] => 6
[5] => 7
[6] => 8
[7] => 9
[8] => 10
[9] => .
[10] => 18
[11] => 19
[12] => 20
)
getSmartPageNumbers(1, 20);
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => .
[6] => 18
[7] => 19
[8] => 20
)
So i wrote a simple pagination function:
function pagination ( $iTotalItems )
{
if( is_array( $iTotalItems ) )
$totalItems = sizeof ( $iTotalItems );
if( is_int( $iTotalItems ) )
$totalItems = $iTotalItems;
$page = (int)( empty( $_GET['page'] ) ? 1 : $_GET['page'] );
if ($page <= 0) $page = 1;
$itemsPerPage = PAG_PER_PAGE;
$prev = $page - 1;
$next = $page + 1;
$prevlabel = "‹ Prev";
$nextlabel = "Next ›";
$totalPages = ceil( $iTotalItems / $itemsPerPage );
$perPage = $page == 'all' ? $totalItems : $itemsPerPage;
$adjacents = 2;
if( $totalItems > $itemsPerPage )
{
$filler = '';
$NumStart = '';
$NumEnd = '';
$pageNavigation = '<div class="Pagination">'. PHP_EOL;
$previousLink = $prev !== 0 ? "<a href='?p=items&page={$prev}'>{$prevlabel}</a>". PHP_EOL : "<span class='noneLink'>{$prevlabel}</span>". PHP_EOL;
$nextLink = $page < $totalPages ? "<a href='?p=items&page={$next}'>{$nextlabel}</a>". PHP_EOL : "<span class='noneLink'>{$nextlabel}</span>". PHP_EOL;
for( $i = 1; $i < $totalPages + 1; $i++ )
{
if( $i <= 10 ) { $NumStart .= $page == $i ? '<span class="noneLink">'.$i.'</span>' : ''.$i.''. PHP_EOL; }
else { $filler = '...'; }
if( $i > $totalPages - 3 ) {$NumEnd .= $page == $i ? "<span class='noneLink'>{$i}</span>" : "<a href='?p=items&page={$i}'>{$i}</a>". PHP_EOL; }
}
}
return $pageNavigation . $previousLink . $NumStart . $filler . $NumEnd . $nextLink . '</div>';
}
Now it works great and all but Im not sure how to make it change depending on the page. For example: with 40 pages and while on page 1 it looks like this.
‹ Prev 1 2 3 4 5 67 8 9 10 ...38 39 40 Next ›
However, even if im at page.. say 20 it still looks the same.
Whats the best and most simple way to code something like this while on page 1:
1 2 3 4 5 6 7 8 9 … 38 39 40 Next ›
and something like this while on page 15:
‹ Prev 1 2 3 … 11 12 13 14 15 16 17 18 19 … 38 39 40 Next ›
Thanks in advance!
I've got a script that dynamically calls and displays images from a directory, what would be the best way to paginate this? I'd like to be able to control the number of images that are displayed per page through a variable within the script. I'm thinking of using URL varriables (ie - http://domain.com/page.php?page=1) but am unsure how to go about this.
Thanks for the help.
This is a function I often use to do pagination. Hope it helps.
function paginate($page, $total, $per_page) {
if(!is_numeric($page)) { $page = 1; }
if(!is_numeric($per_page)) { $per_page = 10; }
if($page > ceil($total / $per_page)) $page = 1;
if($page == "" || $page == 0) {
$page = 1;
$start = 0;
$end = $per_page;
} else {
$start = ($page * $per_page) - ($per_page);
$end = $per_page;
}
$prev_page = "";
$next_page = "";
$all_pages = array();
$selected = "";
$enabled = false;
if($total > $per_page) {
$enabled = true;
$prev = $page - 1;
$prev_page = ($prev == 0) ? 0 : $prev;
$next = $page + 1;
$total_pages = ceil($total/$per_page);
$next_page = ($next <= $total_pages) ? $next : 0;
for($x=1;$x<=$total_pages;$x++) {
$all_pages[] = $x;
$selected = ($x == $page) ? $x : $selected;
}
}
return array(
"per_page" => $per_page,
"page" => $page,
"prev_page" => $prev_page,
"all_pages" => $all_pages,
"next_page" => $next_page,
"selected" => $selected,
"start" => $start,
"end" => $end,
"enabled" => $enabled
);
}
// ex: we are in page 2, we have 50 items, and we're showing 10 per page
print_r(paginate(2, 50, 10));
This will return:
Array
(
[per_page] => 10
[page] => 2
[prev_page] => 1
[all_pages] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
[next_page] => 3
[selected] => 2
[start] => 10
[end] => 10
[enabled] => 1
)
With all that data you are then pretty well armed to make the pagination links.
pagination is the same concept with or without sql. you just need your basic variables, then you can create the content you want. here's some quasi-code:
$itemsPerPage = 5;
$currentPage = isset($_GET['page']) ? $_GET['page'] : 1;
$totalItems = getTotalItems();
$totalPages = ceil($totalItems / $itemsPerPage);
function getTotalItems() {
// since they're images, perhaps we'll scan a directory of images to determine
// how many images we have in total
}
function getItemsFromPage($page, $itemsPerPage) {
// function to grab $itemsPerPage based on which $page we're on
}
function getPager($totalPages, $currentPage) {
// build your pager
}
hope that helps you get started!
If you name your images 01.jpg, 02.jpg it makes it easier to paginate. Then use glob to get all the images into an array and sort it.
When in doubt use javascript! This might help too: http://www.webplicity.net/flexigrid/
Might be good for galery-like apps, though I've never tried it :)