Noobic
the quality of being a novice
 
  Index  •  FAQ  •  Search  

It is currently Tue Sep 07, 2010 1:59 am




Post new topic Reply to topic  [ 7 posts ] 
 Advanced Pagination Class 
Author Message
 Post subject: Advanced Pagination Class
PostPosted: Tue Dec 30, 2008 5:04 pm 
Site Admin

Joined: Mon Dec 29, 2008 4:59 pm
Posts: 6
Reply with quote
Here's another old tut, enjoy it before I remake it :)


Now i'm going to go through how to make an advanced pagination class in PHP.

First thing's first, we need to set up our class:

Code:
<?php
class pagination
{
// our code will go here
}
?>


If you do not know what a class is, or you do not understand them properly, i highly suggest doing a tutorial on classes. They are very useful and knowing how they work is crucial for this tutorial. Try searching for "Object Oriented Programming" in a search engine.

Now we need to set up our class variables. These variables can be used by any function in our class and are more like properties than variables. These go just after the opening curly bracket for the class.

Code:
var $url; // this is the url where the class is being called
var $username; // this is the username of the person viewing the page
var $page; // this is the current page number
var $global_query; // this is the query that is being paginated


Now we have all the variables necessary for this class set up, we will move onto the first function. You may need to adapt the query to suite your needs.

Code:
function rows_per_page()
{
   
$user = mysql_query("SELECT * FROM `users` WHERE `username` = '$this->username' ORDER BY `id` DESC LIMIT 1");
$num = mysql_num_rows($user);
$fetchuser = mysql_fetch_array($user);
   
if($num != 1){
return 10; // if viewer is not logged in, return 10
} else {
return $fetchuser['rows_per_page']; // if viewer is logged in, return their prefered rows
}
   
   
}


Ok, what this function does is looks at the user table for a category called 'rows_per_page'. This is how many rows the user wants displayed on each page. If the person viewing the page is not logged in, it simply returns '10'. If you do not have a user system or you do not want users to be able to choose how many rows are displayed, get rid of everything in the function and have just 'return 10;'.

Now for the query function. This returns to the page the origional query but with the right limits.


Code:
function query($query)
{
   
$this->global_query = $query; // this stores the query for later use
   
// this if statement makes sure the query is safe using a function i will you later
if($this->safety() == true){
   
$rows = $this->rows_per_page(); // this uses our previous function to get the rows per page
   
   
$start = ($rows * ($this->page - 1)); // this works out the start limit for our query
   
$query = str_replace('XBS', $start, $query); // this replaces 'XBS' with the start value (i will explain the XBS later)
$query = str_replace('XBE', $rows, $query); // this replaces 'XBE' with the end value (i will explain the XBE later)
   

return $query; // returns the query
   
} else {
   
return 'Error'; // this is returned if the query is not safe
   
}
}


This is a very important function. If you are wondering what the 'XBS' and 'XBE' are, they are to do with how you call this function. I will explain why it done like this later.

The next function is the safety function to see if the query is safe to exectute.

Code:
function safety()
{

$page = $this->page; // gets what page the user is on
$page_safety = is_int((int)$page); // makes sure the page is an integer value
// this stops someone going 'http://www.yoursite.com/section/MALICIOUS CODE HERE/'


// You can put even more safety logic here to make sure that the query is secure


if($page_safety  == false){
return false; // returns false if page isn't safe
} else {
return true; // returns true if page is safe
}
   
}


We now have a function to check safety, it is editable, and you can add more logic to make sure your query is completely safe.

The next small function is used by another function later. What it does is turn the query from a query with limits, to one without limits. This allows us to see the total amount of rows in the query.

Code:
function extract($query){

$query = str_replace(' LIMIT XBS , XBE', '', $query); // remove limits from query

return $query;
}



Now we need a function to get the number of pages the query has.

Code:
function get_num_pages()
{

$query = $this->extract($this->global_query); // takes the limits off the query using our previous function


$num_rows = mysql_num_rows(mysql_query($query)); // this gets the number of rows of the query


$rows_per_page = $this->rows_per_page(); // now we use our old function to get the number of rows per page

if($rows_per_page > 0){
return ceil($num_rows / $rows_per_page);
// simple maths dictates that number of rows divided by rows per page gives you the number of pages
} else {
return false; // if rows per page is less that 1 the function returns false
}


}



Now we will make a small function for diplaying the little box with the page numbers in. You can change this function so the box looks different, but this is what i personally use.

Code:
function box_table($content)
{

echo '<br>
<table class="pageBox">
<tr><td>&nbsp;'.$content.'</td></tr>
</table>';
   
}


And now we need a function to make sure a certain page exists.

Code:
function page_exists($page){
   
/* this makes sure that the page number is less than or equal to the total number of pages, is greater than 0 and is an integer */

if($page <= $this->get_num_pages() && $page > 0 && is_int((int)$page)){
return true;
} else {
return false;
}
   
}



Now for the very last function which works out all the content for inside the box. This is quite long, read all the code comments carefully ;)

One thing i will explain is 'XBP' is in the inputted url ($this->url), I will talk more about that later.

Code:
function box_display(){

$num_pages = $this->get_num_pages(); // gets number of pages
$page = $this->page; // gets current page
$url = $this->url; // gets url of page

$box_content = ''; // makes an empty variable which will be returned at the end after being added to

// if current page is greater than 1
if($page > 1){
$back_url = str_replace('XBP', $page - 1, $url); // replaces XBP with the page number - 1
$box_content .= '<a href='.$back_url.'><</a>&nbsp;'; // adds a back arrow to $box_content
}

// if page - 4 is greater than 1 (this is so we don't repeat putting '1' into $box_content)
if($page - 4 > 1){
$one_url = str_replace('XBP', 1, $url); // replaces XBP with 1
$box_content .= '<a href='.$one_url.'>1</a>&nbsp;'; // adds a link to page 1
}

// if page - 4 > 2 (this is so we can leave a gap between numbers to save space)
if($page - 4 > 2){
$box_content .= '<font color="black">. . . </font>'; // adds '. . .' to $box_content
}


$p = $page - 4; // makes a variable to loop with

// while $p is smaller than $page
while($p < $page){

// if the $p as a page exists
if($this->page_exists($p)){
$p_url = str_replace('XBP', $p, $url); // replaces 'XBP' with the current $p value
$box_content .= '<a href='.$p_url.'>'.$p.'</a>&nbsp;'; // adds a link to page $p in $box_content
}

$p++; // increment $p

}

      $box_content .= $page; // displays the current page number
      $box_content .= '&nbsp;'; // adds a space
      
$x = $page + 1; // $x is 1 more than page

// while $x is smaller than or equal to $page + 4
while($x <= $page + 4){

// if page $x exists
if($this->page_exists($x)){
$x_url = str_replace('XBP', $x, $url); // replaces 'XBP' with current value of $x
$box_content .= '<a href='.$x_url.'>'.$x.'</a>&nbsp;'; // adds a link to page $x in $box_content
}

$x++; // increments $x

}

/* adds a '. . .' if there is a large enough gap between the last value of $x and the last page number */
if($page + 4 < $num_pages - 1){
$box_content .= '<font color="black">. . . </font>';
}

//  if $page + 4 is smaller than the page number of the last page
if($page + 4 < $num_pages){
$last_url = str_replace('XBP', $num_pages, $url); // replaces 'XBP' with the page number of the last page
$box_content .= '<a href='.$last_url.'>'.$num_pages.'</a>&nbsp;'; // adds a link to the last page in $box_content
}

// if there is a page above the current page
if($this->page_exists($page + 1)){
$for_url = str_replace('XBP', $page + 1, $url); // replaces 'XBP' with the current page + 1
$box_content .= '<a href='.$for_url.'>></a>'; // adds a link to $box_content to the next page up
}

// if the number of pages isn't 0
if($num_pages != 0){
$this->box_table($box_content); // display a box using the previous function with everything $box_content has in it
}

}


And that's the end of the class. Here is the full code. I have not commented it so when a copy and paster just grabs it, they won't understand why it isn't working :P. You can not copy and paste this - it will not work without your changes.

Code:
<?php

class pagination
{

var $url;
var $username;
var $page;
var $global_query;

   function rows_per_page()
   {
   
   $user = mysql_query("SELECT * FROM `users` WHERE `username` = '$this->username' ORDER BY `id` DESC LIMIT 1");
   $num = mysql_num_rows($user);
   $fetchuser = mysql_fetch_array($user);
   
   if($num != 1){
   return 10;
   } else {
   return $fetchuser['rows_per_page'];
   }
   
   
   }
   
   function query($query)
   {
   
   $this->global_query = $query;
   
   if($this->safety() == true){
   
   $rows = $this->rows_per_page();
   
   
   $start = ($rows * ($this->page - 1));
   
   $query = str_replace('XBS', $start, $query);
   $query = str_replace('XBE', $rows, $query);
   

   return $query;
   
   } else {
   
   return 'Error';
   
   }
   }
   
   
   function safety()
   {
   
   $page = $this->page;
   $page_safety = is_int((int)$page);
   
   if($page_safety  == false){
   return false;
   } else {
   return true;
   }
   
   }
   
   function extract($query){
   
   $query = str_replace(' LIMIT XBS , XBE', '', $query);
   
   return $query;
   }
   
   function get_num_pages()
   {
   
   $query = $this->extract($this->global_query);


   $num_rows = mysql_num_rows(mysql_query($query));

   
   $rows_per_page = $this->rows_per_page();
   
   if($rows_per_page > 0){
   return ceil($num_rows / $rows_per_page);
   } else {
   return false;
   }
   
   
   }
   
   
   function box_table($content)
   {
   
   echo '<br>
   <table class="pageBox">
   <tr><td>&nbsp;'.$content.'</td></tr>
   </table>';
   
   }
   
   function page_exists($page){
   
   
   if($page <= $this->get_num_pages() && $page > 0 && is_int((int)$page)){
   return true;
   } else {
   return false;
   }
   
   }
   
   
   function box_display(){
   
   $num_pages = $this->get_num_pages();
   $page = $this->page;
   $url = $this->url;
   
   $box_content = '';
   
   if($page > 1){
   $back_url = str_replace('XBP', $page - 1, $url);
   $box_content .= '<a href='.$back_url.'><</a>&nbsp;';
   }
   
   if($page - 4 > 1){
   $one_url = str_replace('XBP', 1, $url);
   $box_content .= '<a href='.$one_url.'>1</a>&nbsp;';
   }
   
   if($page - 4 > 2){
   $box_content .= '<font color="black">. . . </font>';
   }
   
   
   $p = $page - 4;
   
   while($p < $page){
   
   if($this->page_exists($p)){
   $p_url = str_replace('XBP', $p, $url);
   $box_content .= '<a href='.$p_url.'>'.$p.'</a>&nbsp;';
   }

   
   $p++;
   
   }
   
         $box_content .= $page; // displays the page number
         $box_content .= '&nbsp;';
         
   $x = $page + 1;
   
   while($x <= $page + 4){
   
   if($this->page_exists($x)){
   $x_url = str_replace('XBP', $x, $url);
   $box_content .= '<a href='.$x_url.'>'.$x.'</a>&nbsp;';
   }
   
   $x++;
   
   }
   
   if($page + 4 < $num_pages - 1){
   $box_content .= '<font color="black">. . . </font>';   
   }
   
   if($page + 4 < $num_pages){
   $last_url = str_replace('XBP', $num_pages, $url);
   $box_content .= '<a href='.$last_url.'>'.$num_pages.'</a>&nbsp;';
   }
   
   
      if($this->page_exists($page + 1)){
   $for_url = str_replace('XBP', $page + 1, $url);
   $box_content .= '<a href='.$for_url.'>></a>';
   }
   
   if($num_pages != 0){
   $this->box_table($box_content);
   }
   
   }


}

?>


Now I will explain how to call this class and make it work ;)

For this example, let's pretend we want to paginate some comments on a news post or a picture or something.

First we need to create a new 'pagination' which is our class.

Code:
$comments = new pagination;


Now we enter our variables for the class.

Code:
$comments->url = 'http://www.yoursite.com/section/news_post_3/XBP/';
// notice above there is the 'XBP' I hope you understand now why it's there and how the class uses it to make links

// you will need to input your own user systems username variable for this next line
$comments->username = $username;

// checks that the page variable in the URL (XBP) isn't empty
if(!empty($get['page'])){
$comments->page = $get['page']; // if it isn't, set $comments->page to the current page
} else {
$comments->page = 1; // if it is, set $comments->page equal to 1
}


Now that's done, we have to use the query function in the class to add limits to the query we want to use.

Code:
$query = $comments->query("SELECT * FROM `comments` WHERE `tid` = 'THE ID OF NEWS_POST_3' ORDER BY `id` DESC LIMIT XBS , XBE");


Now, notice in this there is the XBS and the XBE which we used earlier. So all this will do is use the query function to change this query so that it has the right limits.

The end bit must be written exactly like 'LIMIT XBS , XBE' or it will not work!

You also need to change the 'THE ID OF NEWS_POST_3' to a variable which contains the id of whatever news post you are on.
If you look further up to where I defined the url for the class, you will see 'news_post_3' again. This should actually be just a variable. The same variable for the query, and the url.

Now we can execute the query because it has the right limits.


Code:
$comment_list = mysql_query($query) // executes the query;
$count_comments = mysql_num_rows($comment_list); // checks number of rows returned


Now we will display the comments.

Code:
// if number of rows == 0
if($count_comments == 0){

echo 'Sorry, there are no comments yet!';
   
   
} else {


// makes a loop to display the comments
while($c = mysql_fetch_array($comment_list)){

echo $c['comment_message'];

}

// now we can display the box aswell

$comments->box_display();


}


And that's it!


Thanks for reading, please subscribe or register :) All comments appreciated.

Carnage


Note: This tutorial (and the class code) is copyrighted by Noobic 2009, it can be indexed but you cannot copy and paste it! You can use the class code for your websites, but do not put it in your tutorials.


Offline
 Profile  
 
 Post subject: Re: Advanced Pagination Class
PostPosted: Thu Jul 30, 2009 3:30 pm 

Joined: Wed Jul 29, 2009 11:58 pm
Posts: 0
Reply with quote
thanks for sharing. verry usefull but hard to follow. :cry: don't know what files to create :?

Can you post a tut to implement this vonderful code in probid, please? seems to be easyer for you :D

Thank you!


Offline
 Profile  
 
 Post subject: Re: Advanced Pagination Class
PostPosted: Thu Aug 06, 2009 11:28 pm 
Reply with quote
I have the following code for may pagination. How can I see the "page x of x pages" . Can you help me with that? and if you have time the function go to page and items per page. a detailed instructions on how to implement will be grate.

Thank you very much!









function paginate($start,$limit,$total,$file_path,$other_params)
{
(string) $display_output = null;

$all_pages = ceil($total / $limit);

$current_page = floor($start / $limit) + 1;


if ($all_pages > 10)
{
$max_pages = ($all_pages > 9) ? 9 : $all_pages;

if ($all_pages > 9)
{
if ($current_page >= 1 && $current_page <= $all_pages)
{
$display_output .= ($current_page > 4) ? ' ... ' : ' ';

$min_pages = ($current_page > 4) ? $current_page : 5;
$max_pages = ($current_page < $all_pages - 4) ? $current_page : $all_pages - 4;

for($i=$min_pages - 4; $i<$max_pages + 5; $i++)
{
$display_output .= display_link($file_path . '?start=' . (($i - 1) * $limit) . $other_params, $i, (($i == $current_page) ? false : true));
}
$display_output .= ($current_page < $all_pages - 4) ? ' ... ' : ' ';
}
else
{
$display_output .= ' ... ';
}
}
}
else
{
for($i=1; $i<$all_pages + 1; $i++)
{
$display_output .= display_link($file_path . '?start=' . (($i - 1) * $limit) . $other_params, $i, (($i == $current_page) ? false : true));
}
}

if ($current_page > 1)
{
$display_output = '<a href="' . $file_path . '?start=0' . $other_params . '">&laquo;</a>&nbsp;&nbsp;&nbsp;&nbsp; '.
'<a href="' . $file_path . '?start=' . (($current_page - 2) * $limit) . $other_params . '">PREVIOUS</a>&nbsp;&nbsp;&nbsp;&nbsp; ' . $display_output;
}

if ($current_page < $all_pages)
{
$display_output .= ' <a href="' . $file_path . '?start=' . ($current_page * $limit) . $other_params . '"> &nbsp;&nbsp;&nbsp;&nbsp;NEXT</a> '.
'<a href="' . $file_path . '?start=' . (($all_pages - 1) * $limit) . $other_params . '"> &nbsp;&nbsp;&nbsp;&nbsp;&raquo;</a>';
}

return $display_output;
}


  
 
 Post subject: Re: Advanced Pagination Class
PostPosted: Sun Aug 23, 2009 1:18 pm 
Site Admin

Joined: Mon Dec 29, 2008 4:59 pm
Posts: 6
Reply with quote
robert wrote:
I have the following code for may pagination. How can I see the "page x of x pages" . Can you help me with that? and if you have time the function go to page and items per page. a detailed instructions on how to implement will be grate.

Thank you very much!



Well you're trying to do too much with one function I think, that is after all why I made this Pagination Class, to break it down and make it easy to use.

If I were you I'd try and use my class, or at least try and make your own pagination class.

Page X of X would probably be something like:

Code:
$itemsPerPage = 10;
$query = mysql_query("GET SOME ROWS");
$num = mysql_num_rows($query);
$numberOfPages = ceil($num/$itemsPerPage);
$currentPage = $_GET['page']; // this must be something that is stored in the URL i.e. "http://www.example.com/index.php?page=2"

echo 'Page '.$currentPage.' of '.$numberOfPages;


Offline
 Profile  
 
 Post subject: Advanced Pagination Class
PostPosted: Tue Nov 10, 2009 4:07 am 

Joined: Sun Nov 08, 2009 11:02 pm
Posts: 0
Location: Luxembourg
Reply with quote
This problem can easily be solved by passing the db variable into the constructor when it is instantiated.

PHP Code:
class User

protected db = null;
public function __constructdb

this->_db = db;



db = new mysqlilocalhost,user,pass, table
user = new Userdb;


Offline
 Profile  
 
 Post subject: Advanced Pagination Class
PostPosted: Sat Nov 28, 2009 2:26 am 

Joined: Mon Nov 23, 2009 8:34 pm
Posts: 0
Location: Czech
Reply with quote
I made a flatfile function for pagination. It works.

PHP Code:
function showPaginationperPage

global fileName;
curPage = isset_GETpage ? _GETpage : 1;

postCount = countfilefileName;
pages = ceilpostCount / perPage;

/ navi = ;
for i = 1; i <= pages; i

i = floorpages ? sep = : sep = ;
navi .= i = curPage ? i == 1 ? <a href=/>.i.</a>.sep : <a href=/page/.i./>.i.</a>.sep : i.sep;
/

nextPage = curPage - 1 > pages ? pages : curPage - 1;
prevPage = curPage 1 < 1 ? 1 : curPage 1;

sep = nextPage >= 1 & prevPage <= pages ? : ;

navi = nextPage >= 1 ? <a href=/page/.nextPage./>&laquo; Next</a>.sep : ;
navi .= prevPage <= pages ? <a href=/page/.prevPage./>Prev &raquo;</a> : ;

if pages > 1

echo <div class=pagination>,nn;
echo <small class=right>Page .curPage. of .pages.</small>;
echo <span>.navi.</span>,nn;
echo </div>,nn;


Offline
 Profile  
 
 Post subject: Advanced Pagination Class
PostPosted: Fri Dec 25, 2009 8:16 pm 

Joined: Fri Dec 18, 2009 2:27 pm
Posts: 0
Location: UK
Reply with quote
All the non essential view related stuff has been stripped. You can play around with this and see how it works.

PHP Code:
<?php
class Pagination

// total number of records per page
private _count;

// offset from beginning
private _offset;

// current page
private _page;

// total number of records with pagination
private _total;

public function __constructpCount,pTotal,pPage
this->_count = pCount?pCount:10;
this->_total = pTotal;
this->_page = pPage?pPage:1;
this->_currentPage;
this->_currentOffset;


private function _currentOffset

page = this->_page;
this->_offset = this->_page==1?0:this->_count--page;



private function _currentPage

// send user to last page if they have gone past the total number of pages in the path variable
ifthis->_page>this->pages
this->_page = this->pages;




// number of pages
public function pages
/
if the count excedes the the total number than set
the default to 1 page. There are less records than
will fit on one whole page.
/

return this->_count>=this->_total?1:ceilthis->_total/this->_count;


public function getOffset
return this->_offset;


public function getCount
return this->_count;


public function getPage
return this->_page;


public function getTotal
return this->_total;




perPage = isset_GETrecord?_GETrecord:10;
total = isset_GETtotal?_GETtotal:300;
page = isset_GETpage?_GETpage:1;

pagination = new PaginationperPage,total,page;

echo <ul>;
echo <li><strong>offset:</strong>&nbsp;,pagination->getOffset,</li>;
echo <li><strong>limit:</strong>&nbsp;,pagination->getCount,</li>;
echo </ul>;


Offline
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 


 Who is online 

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron

 
Index  |  FAQ  |  Search

phpBB skin developed by: John Olson
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group