1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

Pagination Trouble

Discussion in 'PHP' started by Jeremy Benson, Oct 8, 2015.

  1. #1
    I'm working on a pagination script that outputs a simple bracket arrow navigation with page number in the center. The html output isn't coming out right. I'm not sure why.
    I think the error is isolated to the function that creates the output. You'll see to var_dumps where things mess up.

    The dumps

    Here's the function.

    
    public function return_html()
       {
         
         if($this->is_previous())
         {
           if(substr_count($this->href, '?') >= 1)
           {
             
             $html = '<a href="'.$this->href.'&page='.$this->currentPage - 1 .'"> <i class="fa fa-angle-left"></i></a>';
             
           }else{
           
             $html = '<a href="'.$this->href.'?page='.$this->currentPage - 1 .'"> <i class="fa fa-angle-left"></i></a>';
             
           }
           
         }else{
    
      if(substr_count($this->href, '?') >= 1)
           {
             
             $html = '<a href="'.$this->href.'&page='.$this->currentPage.'"> <i class="fa fa-angle-left"></i></a>';
             
           }else{
             
             $html = '<a href="'.$this->href.'?page='.$this->currentPage.'"> <i class="fa fa-angle-left"></i></a>';
             
           }
         
         }
         
         $html = $html . '<small><span>'.$this->currentPage.'</span> OF <span>'.$this->totalPages.'</span></small>';
         
         if($this->is_next())
         {
           
           if(substr_count($this->href, '?') >= 1)
           {
             var_dump($html);
             $html = $html . '<a href="'.$this->href.'&page='.$this->currentPage + 1 .'"><i class="fa fa-angle-right"></i></a>';
             var_dump($html);
           }else{
             
             $html = $html . '<a href="'.$this->href.'?page='.$this->currentPage + 1 .'"><i class="fa fa-angle-right"></i></a>';
             
           }
           
         }else{
         
          if(substr_count($this->href, '?') >= 1)
          {
             
             $html = $html . '<a href="'.$this->href.'&page='.$this->currentPage.'"><i class="fa fa-angle-right"></i></a>';
             
           }else{
             
             $html = $html . '<a href="'.$this->href.'?page='.$this->currentPage.'"><i class="fa fa-angle-right"></i></a>';
             
           }
           
         }
       
         return $html;
         
       }
    
    PHP:
     
    Jeremy Benson, Oct 8, 2015 IP
  2. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #2
    1) might help if your indentation made the least bit of sense.

    2) I think you've gotten WAY too complex for your own good on this. You see how you're basically using the same markup over and over in endless nested if statements? Yeah, that.

    3) Since pagination is usually a list of pages, shouldn't this be, oh I dunno, a LIST?

    4) buffering output into a string is usually NOT all that great idea, particularly if passing it as a result. Just echo the bloody thing.

    Trying to clean up what you have into something legible and simpler:

    	public function return_html() {
    		$href = $this->href . (
    			strpos($this->href, '?') === FALSE ? '?' : '&amp;'
    		) . 'page=';
    		$html = '
    			<a href="' . $href . (
    				$this->currentPage - ($this->is_previous() ? 1 : 0)
    			) . '"> <i class="fa fa-angle-left"></i></a>';
    		if (!$this->is_previous()) {
    			// are you sure this should be de-emphasized? Small seems "wrong"
    			$html .= '
    				<small>
    					<span>' . $this->currentPage . '</span> OF
    					<span>' . $this->totalPages . '</span>
    				</small>';
    			$html .= '
    				<a href="' . $href . (
    					$this->currentPage + ($this->is_next() ? 1 : 0)
    				) . '"> <i class="fa fa-angle-right"></i></a>';
    		}
    		return $html;
    	}
    Code (markup):
    SHOULD be functionally identical... but I have no clue if that's going to do what you want since again that's seems like a really BAD way of trying to build a pagination function. (particularly with the lack of text inside the anchors and lack of title attributes as fallbacks).

    Usually when I handle pagination I do it with just one function -- I feed it the base URL, the current page number, the total count and the number of items to be shown per page.

    Have a look at how I handle pagination (lifted straight off one of my sites):

    // note, assumes first page is ?page=0 
    
    define('PAGINATION_PERPAGE', 10);
    define('PAGINATION_MAXSHOW', 10);
    define('PAGINATION_MIDDLE', floor(PAGINATION_MAXSHOW / 2));
    
    function template_pagination($href, $current, $total, $hTag = 'h2') {
    
    	if ($total > PAGINATION_PERPAGE) {
    	
    		echo '
    			<div class="pagination">
    				<', $hTag, '>Pages:</', $hTag, '>
    				<ul>
    			
    		$href .= (strpos($href, '?') === FALSE ? '?' : '&amp;') . 'page=';
    		
    		$lastPage = floor(($total - 1) / PAGINATION_PERPAGE);
    		
    		if ($lastPage > 0) {
    			echo '
    					<li><a href="', $href, '0">First</a></li>';
    			if ($current > 0) echo '
    					<li><a
    						href="', $href, $current - 1,'"
    						title="Previous Page"
    						rel="prev"
    					>&laquo;</a></li>';
    		}
    		
    		if ($lastPage >= PAGINATION_MAXSHOW) {
    			$counter = ($current <= PAGINATION_MIDDLE) ? 0 : $current - PAGINATION_MIDDLE;	
    			$endPage = $counter + PAGINATION_MAXSHOW;
    			if ($endPage > $lastPage) $endPage = $lastPage;
    		} else {
    			$counter = 0;
    			$endPage = $lastPage;
    		}
    	
    		while ($counter <= $endPage) {
    			$noAnchor = ($counter == $current);
    			echo '
    					<li>', (
    						$noAnchor ? '<span>' : '<a href="' . $href . $counter . '">'
    					), ++$counter , (
    						$noAnchor ? '</span>' : '</a>'
    					),'</li>';
    		}
    		
    		if ($lastPage > 0) {
    		
    			if ($current < $lastPage) echo '
    				<li><a
    					href="', $href, $current + 1, '"
    					title="Next Page"
    					rel="next"
    				>&raquo;</a></li>';
    			
    			echo '
    				<li><a href="', $href, $lastPage, '">Last</a></li>';
    			
    		}
    		
    		echo '
    				</ul>
    			<!-- .pagination --></div>';
    		
    	}
    	
    } // template_pagination
    Code (markup):
    Parameters:

    $href is the base URL to which ?page= or &amp;page= is added.

    $current is the current page number.

    $total is the total number of ITEMS (not pages)

    $hTag is the appropriate heading tag, if omitted a H2 will be used.

    So if you were currently in your blog.php, on page 2, with 35 items, and a h3 would be the appropriate level subheading:

    template_pagination('/blog.php', 2, 35, 'h3');

    Which would output:

    			<div class="pagination">
    				<h3>Pages:</h3>
    				<ul>
    					<li><a href="/blog.php?page=0">First</a></li>
    					<li><a
    						href="/blog.php?page=1"
    						title="Previous Page"
    						rel="prev"
    					>&laquo;</a></li>
    					<li><a href="/blog.php?page=0">1</a></li>
    					<li><span>2</span></li>
    					<li><a href="/blog.php?page=2">3</a></li>
    					<li><a href="/blog.php?page=3">4</a></li>
    					<li><a
    						href="/blog.php?page=3"
    						title="Next Page"
    						rel="next"
    					>&laquo;</a></li>
    					<li><a href="/blog.php?page=3">Last</a></li>
    				</ul>
    			<!-- .pagination --></div>
    Code (markup):
    Since there's a $lastpage variable generated on the fly in there, it wouldn't be rocket science to add "of xxx" as a title on those anchors and spans. All you'd need is to change inside the loop the output to something like:

    			echo '
    					<li><', (
    						$noAnchor ?	'span' : 'a href="' . $href . $counter . '"'
    					), ' title="Page ', ++$counter, ' of ', $lastPage, '">',
    					$counter , ($noAnchor ? '</span>' : '</a>'),'</li>';
    Code (markup):
    So far I've found the above to be pretty bulletproof at generating a pagination list. Also notice that if there aren't enough total items to be multiple pages, it outputs nothing.
     
    deathshadow, Oct 9, 2015 IP
  3. Jeremy Benson

    Jeremy Benson Well-Known Member

    Messages:
    364
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    123
    #3
    Thanks DeathShadow. Another life saver. I'm going to have to study both of these methods and see which one works best with the site. You are right that most people like numbers. The other method was just worked into the design. I'll have to see which looks best :) Nice blog by the way. I explored a little. The only problem is I couldn't play your Paku Paku game. The commodore said I needed a plugin, but the page didn't mention which one.

    Cool to see you writing about old stuff from your younger days. I find myself doing the same thing, but just turning 30 I find myself in SNES games, and kings quests.
     
    Jeremy Benson, Oct 9, 2015 IP
  4. Jeremy Benson

    Jeremy Benson Well-Known Member

    Messages:
    364
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    123
    #4
    This class is still give me a bit of trouble though. I'm unsure why I'm getting this error. I get Sql error near '-5' in statement. It's near the code where offset is used to get my items from the DB.. strange through. When on page 2... page 2 - 1 * 5 isn't -5. it should be 5. If I put abs around it, in a dumb butchery the sql error goes away, but in my output I don't get page number I'm on of total pages.. I get blank of 2, because there's two pages... before that it always outputted 1 of 2 even if I was on page 2.

    
    class pPaginate{
       
       private $totalItems;
       private $href;
       private $currentPage;
       private $totalPages;
       private $itemsPerPage;
       private $offset;
       private $isNext;
       private $isPrevious;
       private $db = array();
       
       public function return_total_pages()
       {
         
         return $this->totalPages;
         
       }
       
       public function return_items_per_page()
       {
         
         return $this->itemsPerPage;
         
       }
       
       public function return_total_items()
       {
         
         return $this->totalItems;
         
       }
       
       public function return_current_page()
       {
         
         return $this->currentPage;
         
       }
       
       public function set_href($href)
       {
         
         $this->href = $href;
         
       }
       
       public function set_current_page($page)
       {
         
         if($page == 1){
           
           $this->currentPage = 1;
           
         }elseif($page <= 0)
         {
           
           $this->currentPage = 1;
           
           
           
         }elseif($page > $this->totalPages)
         {
           
           $this->currentPage = $this->totalPages;
           
           
         }else
         {
           
           $this->currentPage = $page;
           
         }
         
         // end of set current page
       }
       
       public function set_items_per_page($num)
       {
         $this->itemsPerPage = $num;
       }
       
       public function set_total_items($count)
       {
         
         $this->totalItems = $count;
         
       }
       
       public function calculate_offset()
       {
         
       
           $this->offset = ($this->currentPage - 1) * $this->itemsPerPage;
         
         
       }
       
       public function calc_total_pages()
       {
         
         $this->totalPages = ceil($this->totalItems / $this->itemsPerPage);
         
       }
       
       public function return_offset()
       {
         
         return $this->offset;
         
       }
       
       public function return_limit()
       {
         
         return $this->itemsPerPage;
         
       }
       
       public function return_html() {
         $href = $this->href . (
           strpos($this->href, '?') === FALSE ? '?' : '&amp;'
         ) . 'page=';
         $html = '
           <a href="' . $href . (
             $this->currentPage - ($this->is_previous() ? 1 : 0)
           ) . '"> <i class="fa fa-angle-left"></i></a>';
         if (!$this->is_previous()) {
           // are you sure this should be de-emphasized? Small seems "wrong"
           $html .= '
             <small>
               <span>' . $this->currentPage . '</span> OF
               <span>' . $this->totalPages . '</span>
             </small>';
           $html .= '
             <a href="' . $href . (
               $this->currentPage + ($this->is_next() ? 1 : 0)
             ) . '"> <i class="fa fa-angle-right"></i></a>';
         }
         return $html;
       }
       
       public function is_next()
       {
         
         if($this->currentPage < $this->totalPages)
         {
           return true;
           
         }else{
           
           return false;
         }
         
       }
       
       public function is_previous()
       {
         
         if($this->currentPage > 1)
         {
           
           return true;
           
         }else{
           
           return false;
           
         }
         
       }
         
    // end of pagination class
    }
    
    PHP:
    The values are set like this:

    
    $paginator = new pPaginate;
                 
           $page = 1;
           
           // Count number of reviews
           if(isset($_GET['page']))
           {
               
             if($_GET['page'] < 0)
             {
               
               $page = 1;
               
             }else{
               
               
               $page = $_GET['page'];
               
             }
             
             $paginator->set_current_page($page);
           
           }
           
           $paginator->set_href('product.php?token='.$_GET['token'].'');
           
           $paginator->set_items_per_page(5);
           
           // set total items for paginator
           
           $db = new PDO($dsn, $dbUsername, $dbPassword, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
           
           try{
             
             $countRatingStm = $db->query('SELECT COUNT(`ID`) FROM `products_ratings` WHERE `token` = '. '\'' .$_GET['token']. '\''.'');
             //$countRatingStm->bindParam(':token', $_GET['token'] , PDO::PARAM_STR);
             $ratingCount = $countRatingStm->fetch(PDO::FETCH_NUM);
             
           }catch(\PDOException $e){ var_dump($e); }
           
           print_r($ratingCount);
           
           $paginator->set_total_items($ratingCount[0]);
           $paginator->calc_total_pages();
           
           $paginator->calculate_offset();
    
    PHP:
     
    Jeremy Benson, Oct 9, 2015 IP
  5. Jeremy Benson

    Jeremy Benson Well-Known Member

    Messages:
    364
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    123
    #5
    I like your other pagination method a little better, but it's not quite working right. I'm not sure if it's the style applied to it, or something in the code. I changed the function a little, and put it inside my current class. Right now the page I'm on pops out. The url shows page 0, so page 1 is popped out of its place. When on page 2 page 2 pops out of place. The output looks life through when looking at the source.

    I think the problem may be the style I applied to the pagination div? I'm not sure.

    <div class="product.php?token=82b2834a489f36823f97b914&amp;page=0">First</a></li><li><a
    href="product.php?token=82b2834a489f36823f97b914&amp;page=0"
    title="product.php?token=82b2834a489f36823f97b914&amp;page=0">1</a></li><li><span>2</span></li><li><a href="product.php?token=82b2834a489f36823f97b914&amp;page=1">Last</a></li></ul><!-- .pagination --></div>
    HTML:

    ul { padding: 0; }
    
    .pagination {
      height: 36px;
      margin: 18px 0;
    }
    .pagination ul {
      display: inline-block;
      *display: inline;
      /* IE7 inline-block hack */
    
      *zoom: 1;
      margin-left: 0;
      margin-bottom: 0;
      -webkit-border-radius: 3px;
      -moz-border-radius: 3px;
      border-radius: 3px;
      -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
      -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
      box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
    }
    .pagination li {
      display: inline;
    }
    .pagination a {
      float: left;
      padding: 0 14px;
      line-height: 34px;
      text-decoration: none;
      border: 1px solid #ddd;
      border-left-width: 0;
    }
    .pagination a:hover,
    .pagination .active a {
      background-color: #f5f5f5;
    }
    .pagination .active a {
      color: #999999;
      cursor: default;
    }
    .pagination .disabled span,
    .pagination .disabled a,
    .pagination .disabled a:hover {
      color: #999999;
      background-color: transparent;
      cursor: default;
    }
    .pagination li:first-child a {
      border-left-width: 1px;
      -webkit-border-radius: 3px 0 0 3px;
      -moz-border-radius: 3px 0 0 3px;
      border-radius: 3px 0 0 3px;
    }
    .pagination li:last-child a {
      -webkit-border-radius: 0 3px 3px 0;
      -moz-border-radius: 0 3px 3px 0;
      border-radius: 0 3px 3px 0;
    }
    .pagination-centered {
      text-align: center;
    }
    .pagination-right {
      text-align: right;
    }
    Code (CSS):
     
    Jeremy Benson, Oct 9, 2015 IP
  6. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #6
    Well, I'd say you messed up the opening of the DIV/UL since you're trying to use a HREF as a class. Whatever you did to my approach really messed it up.

    In your class based approach a few tips -- if you have a bunch of private in a row for parameters, comma delimit them, then you only need to say private once. Also if you're on PHP 5.4/newer (I stopped supporting 5.3 a year ago) you don't need to say array() anymore, just [] like in JS.

    
    	private
    		$totalItems,
    		$href,
    		$currentPage,
    		$totalPages,
    		$itemsPerPage,
    		$offset,
    		$isNext,
    		$isPrevious,
    		$db = [];
    Code (markup):
    TECHNICALLY you could do that with your object methods too, but I prefer to state them there on each for clarity sake.

    If you have a return method that only returns a boolean condition, don't waste time on an IF. Just return the condition!

    	public function is_next() {
    		return $this->currentPage < $this->totalPages;
    	}
    	
    	public function is_previous() {
        return $this->currentPage > 1;
      }
    Code (markup):
    In your actual attempt to use it, an inline eval would greatly simplify things... and are you sure zero is valid since you're setting one as the minimum? Also since you don't seem to reuse $page anywhere, just set it directly.

    if (isset($_GET['page'])) $paginator->set_current_page(
    	$_GET['page'] < 1 ? 1 : $_GET['page']
    );
    Code (markup):
    I'm not sure I'd be wasting time with getters and setters on a class just for something like pagination. It's not really security exploitable or worth the time and effort to screw with that way, particularly if the values are being sent to it from outside the class. If the query were IN the class (perhaps by extending it) then it would make sense as it would be part of isolating the scope of the query (the ACTUAL exploitable part)... but really it reeks of "object for nothing"

    There are a LOT of programmers who swear up and down you should only ever use objects, and a LOT of programmers who can't stand objects whatsoever or cannot grasp them. The truth like a great many things lies somewhere in the middle. Objects for nothing is just slow code bloat, but at the same time properties can save code and improve security when used properly for isolating scope. Knowing when to and when NOT to use them is a balancing act, particularly in languages like JS or PHP where objects are just kind-of shoe-horned into the language any-old-way!

    Over on your query, use a bloody prepare/execute not a query. You NEVER blindly dump values into a query string! Also, try not to use upper case in your parameters/field names, some SQL engines use upper case as a trigger and phpmyadmin can foul things up by forcing them to lower case when you use it to make backups -- admittedly that's why I use the command line to make my backups, but not all hosts allow for that so... better safe than sorry. Likewise since COUNT() will only ever return one value, use ::fetchColumn instead of ::fetch. Since there's only one parameter I'd go with the '?' method instead of a ':token', and I'd also ease up on the styled quotes since it's damned unlikely id, product_ratings or even token would ever become reserved words in SQL.

    Honestly, I wish they'd just go ahead and make the damned SQL engines all case sensitive like old school databases were. Upper case was ALWAYS commands and lower case was ALWAYS identifiers. Would end the issue once and for all! But NO, that would make too much sense even though 90%+ of queries people write are that way anyhow...

    try{
    	$countRatingStmt = $db->prepare('
    		SELECT COUNT(id)
    		FROM products_ratings
    		WHERE token = ?
    	');
    	$countRatingStmt->execute([$_GET['token']]);
    	$ratingCount = $countRatingStmt->fetchColumn();
    } catch(PDOException $e) { var_dump($e); die(); }
    
    // I'd probably condense all of these to a single method
    $paginator->set_total_items($ratingCount);
    $paginator->calc_total_pages();
    $paginator->calculate_offset();
    Code (markup):
    Your CSS to apply to my method is also... problematic. You're trying to fix the height which there's no reason to do, the px margins throw up warning flags, and you're playing with inline and inline-block on elements that really should be left as block. (like the UL) Let the blasted thing auto-height and address any alignment/height issues with padding and vertical-align on the inline-level items. Of course you seem to have presentational classes like "pagination-right" and "pagination-center" -- crap that has no business as classes or being determined from the markup in the first place.

    Oh, and Firefox hasn't needed the -moz on the majority of properties for about a year and a half now. Go ahead and axe those. One less bit of browser specific crap down. :D

    As to playing the online copies of my games, you need JAVA to use them as the DOS version uses jDosBox and the C64 version uses... gah, been so long I forgot the name of the JAVA C64 emulator in use. As in Oracle (formerly Sun) Java -- NOT JAVASCRIPT -- which sucks as I won't even install JAVA on my hardware and if something needs it, I don't use it. I should probably just take a queue from GOG and make an installer with a preconfigured copy of DOSBOX set up for it. There is now a JavaScript based DOS emulator, but it doesn't support the tweaked text mode I use to squeeze a 16 colour graphics mode out of a video card that wasn't really meant to do that.

    Technically it should be telling you that you need Sun Java and provide the link, but both Chrome and FF have gone and completely ****ed their implementations of the OBJECT tag so the fallback no longer works right!
    :/
     
    deathshadow, Oct 9, 2015 IP
  7. Jeremy Benson

    Jeremy Benson Well-Known Member

    Messages:
    364
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    123
    #7
    okay, I'm scrapping my old class and trying to work towards a class using your function. The number output is much better. Somehow while taking functions out I messed up my code royally. I'm not sure what's wrong here. My pagination is always stuck on 2. If I click last my url will show page 1, if I click first it will show page 0. That works. There's only 2 pages. As another problem I'm only getting the first 5 reviews so my offset has to be completely wrong...

    class
    
    class pPaginate{
       
       private $totalItems;
       private $href;
       private $currentPage;
       private $totalPages;
       private $itemsPerPage;
       private $offset;
       private $isNext;
       private $isPrevious;
       private $db = array();
       
       public function return_total_pages()
       {
         
         return $this->totalPages;
         
       }
       
       public function return_items_per_page()
       {
         
         return $this->itemsPerPage;
         
       }
       
       public function return_total_items()
       {
         
         return $this->totalItems;
         
       }
       
       public function return_current_page()
       {
         
         return $this->currentPage;
         
       }
    
       public function set_current_page($page)
       {
         
         $this->currentPage = $page;
         
         // end of set current page
       }
       
       public function set_items_per_page($num)
       {
         $this->itemsPerPage = $num;
       }
       
       public function set_total_items($count)
       {
         
         $this->totalItems = $count;
         
       }
       
       public function calculate_offset()
       {
         
       
           $this->offset = abs(($this->currentPage - 1) * $this->itemsPerPage);
         
         
       }
       
       public function calc_total_pages()
       {
         
         $this->totalPages = ceil($this->totalItems / $this->itemsPerPage);
         
       }
       
       public function return_offset()
       {
         
         return $this->offset;
         
       }
       
       public function return_limit()
       {
         
         return $this->itemsPerPage;
         
       }
       
    function pagination($href, $current, $total, $hTag = 'h2') {
    
       define('PAGINATION_PERPAGE', $this->itemsPerPage);
       define('PAGINATION_MAXSHOW', 10);
       define('PAGINATION_MIDDLE', floor(PAGINATION_MAXSHOW / 2));
    
       if ($total > PAGINATION_PERPAGE) {
       
         echo '
           <div class="pagination">
             <ul>';
           
         $href .= (strpos($href, '?') === FALSE ? '?' : '&amp;') . 'page=';
         
         $lastPage = floor(($total - 1) / PAGINATION_PERPAGE);
         
         if ($lastPage > 0) {
           echo '
               <li><a class="page" href="', $href, '0">First</a></li>';
           if ($current > 0) echo '
               <li><a class="page"
                 href="', $href, $current - 1,'"
                 title="Previous Page"
                 rel="prev"
               >&laquo;</a></li>';
         }
         
         if ($lastPage >= PAGINATION_MAXSHOW) {
           $counter = ($current <= PAGINATION_MIDDLE) ? 0 : $current - PAGINATION_MIDDLE;   
           $endPage = $counter + PAGINATION_MAXSHOW;
           if ($endPage > $lastPage) $endPage = $lastPage;
         } else {
           $counter = 0;
           $endPage = $lastPage;
         }
       
         while ($counter <= $endPage) {
           $noAnchor = ($counter == $current);
           echo '
               <li>', (
                 $noAnchor ? '<span>' : '<a class="page" href="' . $href . $counter . '">'
               ), ++$counter , (
                 $noAnchor ? '</span>' : '</a>'
               ),'</li>';
         }
         
         if ($lastPage > 0) {
         
           if ($current < $lastPage) echo '
             <li><a class="page"
               href="', $href, $current + 1, '"
               title="Next Page"
               rel="next"
             >&raquo;</a></li>';
           
           echo '
             <li><a class="page" href="', $href, $lastPage, '">Last</a></li>';
           
         }
         
         echo '
             </ul>
           <!-- .pagination --></div>';
         
       }
       
    } // template_pagination
           
    // end of pagination class
    }
    
    PHP:
    Setting variables

    
    $paginator = new pPaginate;
                 
           $page = 1;
           
           // set current page
           
           if(isset($_GET['page'])){
             
             if(ctype_digit(strval($_GET['page'])))
             {
               
               $paginator->set_current_page($_GET['page'] < 1 ? 1 : $_GET['page']);
             
             }else{
               
               $paginator->set_current_page(1);
               
             }
             
           }else{
             
             $paginator->set_current_page(1);
             
           }
           
           $paginator->set_href('product.php?token='.$_GET['token'].'');
           
           $paginator->set_items_per_page(5);
           
           // set total items for paginator
           
           $db = new PDO($dsn, $dbUsername, $dbPassword, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
           
           try{
             
             $countRatingStm = $db->query('SELECT COUNT(`ID`) FROM `products_ratings` WHERE `token` = '. '\'' .$_GET['token']. '\''.'');
             //$countRatingStm->bindParam(':token', $_GET['token'] , PDO::PARAM_STR);
             $ratingCount = $countRatingStm->fetch(PDO::FETCH_NUM);
             
           }catch(\PDOException $e){ var_dump($e); }
                 
           $paginator->set_total_items($ratingCount[0]);
           $paginator->calc_total_pages();
           
           $paginator->calculate_offset();
    
    PHP:
    getting reviews

    
    try{
           
           $getRatingStm = $db->prepare('SELECT `id`,`username`, `rating`, `review`, `time` FROM `products_ratings`
           WHERE `token` = :token
           LIMIT :limit
           OFFSET :offset');
           
         }catch(\PDOException $e){}
         
           $limit = $paginator->return_limit();
           $offset = $paginator->return_offset();
           
          $getRatingStm->bindParam(':token', $_GET['token'], PDO::PARAM_STR);
          $getRatingStm->bindParam(':limit', $limit , PDO::PARAM_INT);
          $getRatingStm->bindParam(':offset', $offset , PDO::PARAM_INT);
          $getRatingStm->execute();
          $retrievedReviews = $getRatingStm->fetchAll(PDO::FETCH_ASSOC);
           
           var_dump($retrievedReviews);
    
    PHP:
     
    Jeremy Benson, Oct 10, 2015 IP
  8. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #8
    I think a lot of it is that my function wasn't written to be part of a "class". You may also be confusing that current is supposed to be the PAGE, not the offset so you have to set :eek:ffset as page * MAX_PERPAGE. It's also a BAD idea to put define inside a method since if that method gets called more than once, the whole thing will crash out since you can't redefine a define.

    Really not sure why you feel the "need" to even have that be a object in the first place. Seems like an utter and complete waste of code that has no real legitimate reason for existing.

    Also not sure why you added that page class since EVERY anchor is getting that class, and since you got rid of the heading I don't really see why you'd still have the DIV since there's nothing being done now that couldn't go on the UL directly.

    If I WERE to make it an object, I'd have the constructor setting up the values being handled by the divide.

    OH WAIT, are you using mysql? There is no "offset" in mySQL when using limit, and "emulated prepares" screws up plugging values into limit!

    Your query should look like this:
    			$getRatingStm = $db->prepare('
    				SELECT id, username , rating, review, time
    				FROM products_ratings
    				WHERE token = :token
    				LIMIT :offset, :limit
    			');
    Code (markup):
    But when you start up PDO, make sure that you declare this:
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

    Or LIMIT won't work right with prepare/exec with tokens. ...and it's REALLY stupid that "emulated prepares" even exists, it defeats the whole point! Even dumber is that it's the DEFAULT!

    I figure it might help if I put together a working demo including the calculation the query should use, so here you go:
    http://www.cutcodedown.com/for_others/jeremyBenson/pagination/test.php

    As with all my examples the directory is unlocked:
    http://www.cutcodedown.com/for_others/jeremyBenson/pagination/.

    ... for easy access to the gooey bits and pieces. The .source files are so you can view it online (using my own formatter since .phps is all sorts of broken insecure crap in Apache thanks to them using a broken regex), and I threw a .rar in there too of it so you can grab the whole thing as one package.

    I tossed the whole thing into my simple el-cheapo "poor man's" templating system just for rapid deployment of the test. Shouldn't be too hard for you to figure out what's what on that.

    You look at the pagination object itself:
    http://www.cutcodedown.com/for_others/jeremyBenson/pagination/paginate.library.source

    ... you'll see I used the class to simplify down the codebase a bit, leveraging methods to build the anchors automatically based on their values, a page of -1 meaning it's on the current page and/or it shouldn't be a link. Right now it hides first/prev if you're on the first or last/next if you're on the last, was thinking you could pass -2 to put span with a class there so they are present (so the list looks the same) without it changing how many are showing. (some people complain when the number of visible links changes)

    All of the constructors parameters are optional, though it's unlikely you'd ever use it without passing the base href. $perPage is how many items to show per page, $maxShow is the maximum number of pages to show -- for example if you had 20 pages and were on page 8, only pages 3 through 13 would show:

    first < 3 4 5 6 7 8 9 10 11 12 13 > last

    if $maxShow was set to 6 and you were on page 8...

    first < 5 6 7 8 9 10 11 > last

    Note that the routine does <= so if you say six, it will show six IN ADDITION to the current page.

    Moving the markup out of the logic and cleaning up the code should make it easier for you to follow.

    The test itself:
    http://www.cutcodedown.com/for_others/jeremyBenson/pagination/test.source

    Just loads the global defines and page template, the pagination library, then starts the page template with default values.

    From there we just figure out which page we're on if $_GET['page'] is set, and if set if it's indeed a numeric value, otherwise revert to page zero. We then make our pagination object passing the URL we want to handle the request (you could also set number per page and maxshow here too) and then call the ->show method passing the current page and how many elements there are in total.

    Again REMEMBER that page is a 0 based index to the page, but that the total is the total number of elements NOT the number of pages.

    Which is why to get our query offset, we have to multiply by the per-page number.

    Hence why I output an example query as preformatted code... and then we close out the template.

    Pretty simple. Hopefully with a full working demo you'll be better able to figure out how this works. I suppose you COULD pass the current page and the total to the constructor so you could use a getter to create the actual offset for query use. If I have time later I might toss that onto it.
     
    deathshadow, Oct 10, 2015 IP
  9. Jeremy Benson

    Jeremy Benson Well-Known Member

    Messages:
    364
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    123
    #9
    Meh, I've had all I can handle of this for a while. I think I'm just going to take the class to freelancer :) I just can't figure it out. I need it in a class because I plan on using it on various pages. You helped a lot though, and gave me a really good starting point. For that I have to thank you :)

    I played PakuPaku :p My score is 63,580. I'm not sure how many levels in it is, kind of mediocre play on my part, but was getting pretty fast on me.
     
    Jeremy Benson, Oct 10, 2015 IP
  10. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #10
    I just changed it so that the current page and total are passed to the constructor instead of the show method, letting things be recalculated a bit easier and adding a method to return an array containing your two limit tokens.

    You could then pass any extra values by adding them to that array. I like that... You know, it's been about a decade since I wrote that paginator, and the only updates were done a year ago - I noticed a lot of flubs and behaviors I didn't like in it. It's funny, been writing PHP for a decade and a half, and I'm STILL finding newer and better ways of doing things. Guess that goes back to something I was told about programming back in the '80's.

    "The day you stop learning, is the day the rest of the world leaves you behind" -- programming isn't a "learn it once" field.

    I think that would make the proper approach to what you were doing be something more like:
    if (!isset($_GET['token'])) die('No Valid Token'); // handle this better later.
    
    try {
    	$db = new PDO($dsn, $dbUsername, $dbPassword, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
    	$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    } catch (PDOException $e) {
    	die('Connection failed: ' . $e->getMessage());
    }
           
    $countRatingStmt = $db->prepare('
    	SELECT COUNT(id)
    	FROM products_ratings
    	WHERE token = :token
    ');
    
    // NEVER blindly put $_GET into a URI!!! urlencode that bastard!
    
    $paginator = new Paginate(
    	'product.php?token=' . urlencode($_GET['token']),
    	isset($_GET['page']) && is_numeric($_GET['page']) ? $_GET['page'] : 0,
    	$countRatingStmt->fetchColumn()
    );
    
    $paginator->show();
    
    $getRatingStmt = $db->prepare('
    	SELECT id, username, rating, review, time
    	FROM products_ratings
    	WHERE token = :token
    	LIMIT :offset, :limit
    ');
    
    $getRatingParams = $paginator->getLimits();
    $getRatingParams[':token'] = $_GET['token'];
           
    $getRatingStmt->execute($getRatingParams);
    
    $retrievedReviews = $getRatingStm->fetchAll(PDO::FETCH_ASSOC);
           
    echo '<pre>', print_r($retrievedReviews), '</pre>';
    Code (markup):
    Though I'm guessing WILDLY on that. The ability to pass an associative array of your tokens to the execute method instead of bindparam is great for one-offs like this, particularly since they don't have to be in the same order as the query and you can use that to help with returning values from functions or methods like paginate::getLimits.

    In your code it was kind of wierd to see try/catch around prepare and query, but NOT the creation of the PDO object itself -- usually it's the other way around. I rarely if ever see the methods of the object wrapped thus, and it's a REALLY bad idea NOT to wrap the PDO handler... well, unless you've extended it with your own error handler like I usually do, and even then you need to handle that. It's FAR more likely for your PDO connection attempt to fail than it is a perfectly good well formed query.

    As to reusing it, this update to my code means you can call ->show as many times as you like once you've constructed it. I'm not really seeing any reason you'd need access to any more of the internal values than what the new getLimits method does.

    You want to change the values, my advice, just make a new object. Do NOT try to change parameters on something like this 'on the fly'.
     
    Last edited: Oct 10, 2015
    deathshadow, Oct 10, 2015 IP
  11. Jeremy Benson

    Jeremy Benson Well-Known Member

    Messages:
    364
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    123
    #11
    Oh my, sorry for getting so frustrated. I'm getting really close with your code, and the direction you saw the class. I've placed a lot in a constructor, and have things worked out quite well in the main pagination function. Now everything is working fine. I'm getting the right results from the query, and the right number of pages. The only error I'm facing is the output. It shows that the second page is always selected. On page 0 the output shows page 2 selected, on page 1 is shows page 2 is selected. Not sure why..

    pagination class
    
    <?php
    
    class pPaginate{
     
       private $totalItems;
       private $href;
       private $currentPage;
       private $totalPages;
       private $itemsPerPage;
       private $offset;
       private $maxShow;
       private $paginationMiddle;
       private $db = array();
     
       public function __construct($maxShowSet = 5, $itemsPerPageSet = 5, $totalItemsSet, $currentPageSet)
       {
       
         $this->currentPage = $currentPageSet;
         $this->maxShow = $maxShowSet;
         $this->totalItems = $totalItemsSet;
         $this->itemsPerPage = $itemsPerPageSet;
         $this->totalPages = ceil($this->totalItems / $this->itemsPerPage);
         $this->offset = $this->currentPage * $this->maxShow;
         $this->paginationMiddle = floor($this->maxShow / 2);
     
       }
     
      
       public function return_offset()
       {
       
         return $this->offset;
       
       }
     
       public function return_limit()
       {
       
         return $this->itemsPerPage;
       
       }
     
    function pagination($href, $current, $total) {
     
       if ($total > $this->itemsPerPage) {
     
         echo '
           <div class="pagination">
             <ul>';
         
         $href .= (strpos($href, '?') === FALSE ? '?' : '&amp;') . 'page=';
       
         $lastPage = floor(($total - 1) / $this->itemsPerPage);
       
         if ($lastPage > 0) {
           echo '
               <li><a class="page" href="', $href, '0">First</a></li>';
           if ($current > 0) echo '
               <li><a class="page"
                 href="', $href, $current - 1,'"
                 title="Previous Page"
                 rel="prev"
               >&laquo;</a></li>';
         }
       
         if ($lastPage >= $this->maxShow) {
           $counter = ($current <= $this->paginationMiddle) ? 0 : $current - $this->paginationMiddle; 
           $endPage = $counter + $this->maxShow;
           if ($endPage > $lastPage) $endPage = $lastPage;
         } else {
           $counter = 0;
           $endPage = $lastPage;
         }
     
         while ($counter <= $endPage) {
           $noAnchor = ($counter == $current);
           echo '
               <li>', (
                 $noAnchor ? '<span>' : '<a class="page" href="' . $href . $counter . '">'
               ), ++$counter , (
                 $noAnchor ? '</span>' : '</a>'
               ),'</li>';
         }
       
         if ($lastPage > 0) {
       
           if ($current < $lastPage) echo '
             <li><a class="page"
               href="', $href, $current + 1, '"
               title="Next Page"
               rel="next"
             >&raquo;</a></li>';
         
           echo '
             <li><a class="page" href="', $href, $lastPage, '">Last</a></li>';
         
         }
       
         echo '
             </ul>
           <!-- .pagination --></div>';
       
       }
     
    } // template_pagination
         
    // end of pagination class
    }
    
    ?>
    
    PHP:
    Setting Data
    
    // get total items for paginator
         
           $db = new PDO($dsn, $dbUsername, $dbPassword, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
         
           try{
           
             $countRatingStm = $db->query('SELECT COUNT(`ID`) FROM `products_ratings` WHERE `token` = '. '\'' .$_GET['token']. '\''.'');
             //$countRatingStm->bindParam(':token', $_GET['token'] , PDO::PARAM_STR);
             $ratingCount = $countRatingStm->fetch(PDO::FETCH_NUM);
           
           }catch(\PDOException $e){ var_dump($e); }
               
           $paginator = new pPaginate(5, 5, $ratingCount[0], isset($_GET['page']) && is_numeric($_GET['page']) ? $_GET['page'] : 0);
         
    
    PHP:
     
    Jeremy Benson, Oct 10, 2015 IP
  12. Jeremy Benson

    Jeremy Benson Well-Known Member

    Messages:
    364
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    123
    #12
    Never mind. This is working perfect :)

    I have a feeling, whether perfectly clean yet or not, this is the best pagination class ever created. lol.

    Thanks DeathShadow.

    class

    
    <?php
    
    class pPaginate{
     
       private $totalItems;
       private $currentPage;
       private $totalPages;
       private $itemsPerPage;
       private $offset;
       private $maxShow;
       private $paginationMiddle;
       private $db = array();
     
       public function __construct($maxShowSet = 5, $itemsPerPageSet = 5, $totalItemsSet, $currentPageSet)
       {
       
         $this->currentPage = $currentPageSet;
         $this->maxShow = $maxShowSet;
         $this->totalItems = $totalItemsSet;
         $this->itemsPerPage = $itemsPerPageSet;
         $this->totalPages = ceil($this->totalItems / $this->itemsPerPage);
         $this->offset = $this->currentPage * $this->maxShow;
         $this->paginationMiddle = floor($this->maxShow / 2);
     
       }
    
       public function return_offset()
       {
       
         return $this->offset;
       
       }
     
       public function return_limit()
       {
       
         return $this->itemsPerPage;
       
       }
     
    function pagination($href, $currentPage) {
     
        if ($this->totalItems > $this->itemsPerPage) {
     
         echo '
           <div class="pagination">
             <ul>';
         
         $href .= (strpos($href, '?') === FALSE ? '?' : '&amp;') . 'page=';
       
         $lastPage = floor(($this->totalItems - 1) / $this->itemsPerPage);
       
         if ($lastPage > 0) {
           echo '
               <li><a class="page" href="', $href, '0">First</a></li>';
           if ($currentPage > 0) echo '
               <li><a class="page"
                 href="', $href, $currentPage - 1,'"
                 title="Previous Page"
                 rel="prev"
               >&laquo;</a></li>';
         }
       
         if ($lastPage >= $this->maxShow) {
           $counter = ($currentPage <= $this->paginationMiddle) ? 0 : $currentPage - $this->paginationMiddle; 
           $endPage = $counter + $this->maxShow;
           if ($endPage > $lastPage) $endPage = $lastPage;
         } else {
           $counter = 0;
           $endPage = $lastPage;
         }
     
         while ($counter <= $endPage) {
           $noAnchor = ($counter == $currentPage);
           echo '
               <li>', (
                 $noAnchor ? '<span>' : '<a class="page" href="' . $href . $counter . '">'
               ), ++$counter , (
                 $noAnchor ? '</span>' : '</a>'
               ),'</li>';
         }
       
         if ($lastPage > 0) {
       
           if ($currentPage < $lastPage) echo '
             <li><a class="page"
               href="', $href, $currentPage + 1, '"
               title="Next Page"
               rel="next"
             >&raquo;</a></li>';
         
           echo '
             <li><a class="page" href="', $href, $lastPage, '">Last</a></li>';
         
         }
       
         echo '
             </ul>
           <!-- .pagination --></div>';
       
       }
    
    }
           
    // end of pagination class
    }
    
    ?>
    
    PHP:
    implementation

    
    
      $db = new PDO($dsn, $dbUsername, $dbPassword, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
         
           try{
           
             $countRatingStm = $db->query('SELECT COUNT(`ID`) FROM `products_ratings` WHERE `token` = '. '\'' .$_GET['token']. '\''.'');
             //$countRatingStm->bindParam(':token', $_GET['token'] , PDO::PARAM_STR);
             $ratingCount = $countRatingStm->fetch(PDO::FETCH_NUM);
           
           }catch(\PDOException $e){ var_dump($e); }
               
           $paginator = new pPaginate(5, 5, $ratingCount[0], isset($_GET['page']) && is_numeric($_GET['page']) ? $_GET['page'] : 0);
           
     
    
    echo $paginator->pagination('product.php?token='.$_GET['token'].'', isset($_GET['page']) && is_numeric($_GET['page']) ? $_GET['page'] : 0);
    
    
    PHP:
     
    Jeremy Benson, Oct 10, 2015 IP
  13. PoPSiCLe

    PoPSiCLe Illustrious Member

    Messages:
    4,623
    Likes Received:
    725
    Best Answers:
    152
    Trophy Points:
    470
    #13
    You could get rid of a variable by just doing
    
    $ratingCount = $db->query('SELECT COUNT(`ID`) FROM `products_ratings` WHERE `token` = '. '\'' .$_GET['token']. '\''.'')->fetchColumn();
    
    PHP:
    I would perhaps move the db-call into the class as well (you can do a couple more variables on the construct call to define the table name and token)
     
    PoPSiCLe, Oct 11, 2015 IP
  14. Jeremy Benson

    Jeremy Benson Well-Known Member

    Messages:
    364
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    123
    #14
    Good tip Popsicle :p I have a hard time remembering that one line count fetch. I should test it out. Likely that line should end up in a lot of places in my code.

    I don't think I'll move the call into my class through. The variables I'll lose in that sense I'll make up for by having to pass an array into the class for my db connection.
     
    Jeremy Benson, Oct 11, 2015 IP
  15. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #15
    Whilst I would NEVER, EVER do that as it's still blindly pasting the Joe blasted $_GET into the huffing query string. Something that to be frank if anyone is still doing, they have to be huffing some really good ****.

    The MOMENT you pass a parameter, you use PREPARE, not QUERY or EXEC!

    $ratingCountStmt = $db->prepare('
    	SELECT COUNT(id)
    	FROM products_ratings
    	WHERE token = ?
    ');
    $ratingCountStmt->execute([$_GET['token']]);
    $ratingCount = $ratingCountStmt->fetchColumn();
    Code (markup):
    Or Golf Tango Foxtrot Oscar!!!

    YOU of all people I'd have thought would know better by now.
     
    deathshadow, Oct 11, 2015 IP
  16. PoPSiCLe

    PoPSiCLe Illustrious Member

    Messages:
    4,623
    Likes Received:
    725
    Best Answers:
    152
    Trophy Points:
    470
    #16
    Haha, true. I'm so used to not doing stuff like that, I completely overlooked it :D However, if that token is a simple number, it could easily be fixed by adding something like
    
    $token = (isset($_GET['token']) && is_numeric($_GET['token'])) ? $_GET['token'] : 0;
    
    PHP:
    then just replace the $_GET['token'] in the query with $token and it should be fine putting it in there without actually having to do a prepare. If that's more effective than a prepare and pulling the value inside a try or if, I'm no sure. Also, of course, depends on it being numeric. You could of course validate against a valid-token-array, but then you're getting into territory where you can just as well just prepare the query.
     
    PoPSiCLe, Oct 11, 2015 IP
  17. Jeremy Benson

    Jeremy Benson Well-Known Member

    Messages:
    364
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    123
    #17
    That's on my todo list. Go through fall my queries and make sure they're all prepared.

    For some reason this class is giving trouble on a page. It's the third page I've added it to, so I can't figure out what's wrong. Nothing is being outputted by my pagination function. I'm not getting any page numbers, first or last buttons..

    <?php
    
    session_start();
    
    require('data/sqldata.php');
    include('php/classes/pUser.php');
    
    if(isset($_SESSION['ID']))
    {
       
        $user = new pUser;
        $user->set_db(array("dsn" =>$dsn, "username" => $dbUsername, "password" => $dbPassword));
        $user->set_user_id($_SESSION['ID']);
       
    }
    
    
    if(isset($_GET['username']))
    {
           
        $db = new PDO($dsn, $dbUsername, $dbPassword, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));   
        require('php/classes/pPaginate.php');
       
        // retrieve followers
           
            $followerCountStm = $db->prepare('
                    SELECT COUNT(`id`)
                    FROM `followers`
                    WHERE `following` = ?
                ');
                $followerCountStm->execute([$_GET['username']]);
                $followerCount = $followerCountStm->fetchColumn();
               
                $paginator = new pPaginate(5, 5, $followerCount[0], isset($_GET['page']) && is_numeric($_GET['page']) ? $_GET['page'] : 0);
                       
                       
            // Fetch followers           
           
            try{
               
                $getFollowersStm = $db->prepare('
                    SELECT follower
                    FROM followers
                    WHERE following = :following
                    LIMIT :offset, :limit
                ');
               
            }catch(\PDOException $e){}
           
                $limit = $paginator->return_limit();
                $offset = $paginator->return_offset();
               
              $getFollowersStm->bindParam(':following', $_GET['username'], PDO::PARAM_STR);
              $getFollowersStm->bindParam(':limit', $limit , PDO::PARAM_INT);
              $getFollowersStm->bindParam(':offset', $offset , PDO::PARAM_INT);
              $getFollowersStm->execute();
              $retrievedFollowers = $getFollowersStm->fetchAll(PDO::FETCH_ASSOC);
             
    }else{
        // handle no username
       
       
    }
    
    ?>
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <title>Starredit :: Followers</title>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
      <link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
      <link rel="stylesheet" href="css/style.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
      <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    </head>
    <body>
    
    <?php
    
        include('includes/include_nav.php');
    
    ?>
     
    <div class="container toppad top-bottom-buffer">
    <h1 class="topless-buffer">Followers</h1>
    <form action="" role="form">
    <div class="form-group has-feedback">
      <label for="call-date">Search for follower:</label>
      <input name="followerSearch" class="form-control input-sm" id="call-date" type="text" placeholder="search here ...">
      <span class="glyphicon glyphicon-search form-control-feedback"></span>
    </div>
    </form>           
                <hr>
                <?php
               
               
                    foreach($retrievedFollowers as $key => $val)
                    {
                       
                        $followerUser = new pUser;
                        $followerUser->set_db(array("dsn" => $dsn, "username" => $dbUsername, "password" => $dbPassword));
                        $followerUser->set_user_name($retrievedFollowers[$key]['follower']);
                        $followerUser->set_profile_name($retrievedFollowers[$key]['follower']);
                       
                        echo '<div class="row">
                      <div class="col-xs-2">';
                     
                      if($followerUser->has_profile_image())
                      {
                         
                          echo '<img src="users/'.$followerUser->return_username().'/images/profile/'.$followerUser->return_profile_image().'" class="img-responsive" />';
                         
                      }else{
                         
                          echo '<img src="images/profile-img.jpg" class="img-responsive" />';
                         
                      }
                      
                      echo '</div><div class="col-xs-10">
                      <a href="#"><strong>';
                     
                            if($followerUser->uses_display_name())
                            {
                               
                                echo $followerUser->return_displayname();
                               
                            }else{
                               
                                echo $followerUser->return_username();
                               
                            }
                     
                      echo '</strong></a>
                      <br><br>';
                       
                         // echo role or some other thing here.
                       
                        echo '
                      <p>';
                     
                       echo $followerUser->return_profile_about();
                     
                      echo '</p>
                               <a href="#" class="btn btn-default btn-sm">Send Message</a>
                               <a href="#" class="btn btn-success btn-sm">Following</a>
                              </div>
                            </div>
               
                          <hr>';
                       
                        // End of foreach loop
                    }
               
                ?>
               
       
                  <div class="bdrpad top-bottom-buffer text-center">
                   <?php
                   
                        echo $paginator->pagination('followers.php?username='.$_GET['username'].'', isset($_GET['page']) && is_numeric($_GET['page']) ? $_GET['page'] : 0);
    
                    ?>
                  </div>
    
                 
                 
    </div>
    
    
    <?php
    
        include('includes/include_footer.php');
    
    ?>
    
    </body>
    </html>
    PHP:
     
    Jeremy Benson, Oct 12, 2015 IP
  18. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #18
    Uhm, shouldn't that be ->show() without parameters, not ->paginate with?

    Though I think your big problem is here:
    $followerCount = $followerCountStm->fetchColumn();
               
                $paginator = new pPaginate(5, 5, $followerCount[0]
    Code (markup):
    PDOStatement->fetchColumn returns the first fields VALUE, not an array, so lose the [0] array index... which would be null and should be throwing an error since it's not an array.
     
    deathshadow, Oct 12, 2015 IP
  19. Jeremy Benson

    Jeremy Benson Well-Known Member

    Messages:
    364
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    123
    #19
    This line works just fine on product.php, the first page we worked on:

      $paginator = new pPaginate(5, 5, $ratingCount[0], isset($_GET['page']) && is_numeric($_GET['page']) ? $_GET['page'] : 0);
    
    Code (markup):
    I'm not sure what you mean by "Uhm, shouldn't that be ->show() without parameters, not ->paginate with?"

    The function is pagination() that outputs the numbers list from the class.
     
    Jeremy Benson, Oct 13, 2015 IP