title: Logic behind pagination like google
body: <p>What is the logic behind google's pagination behaviour?    </p>
  
  <p>My paginator goes something like this:  </p>
  
  <pre><code>[1]  2   3  ...  184   &gt;
   &lt;   1  [2]  3   4  ...  184   &gt;
   &lt;   1   2  [3]  4   5  ...  184   &gt;
   &lt;   1   2   3  [4]  5   6   ...  184   &gt;
   &lt;   1  ...  3   4  [5]  6    7   ...  184   &gt;
   &lt;   1  ...  4   5  [6]  7    8   ...  184   &gt;
   &lt;   1  ...  5   6  [7]  8    9   ...  184   &gt;
   &lt;   1  ...  6   7  [8]  9    10  ...  184   &gt;
  </code></pre>
  
  <p>Here is a live version of the above example: <a href="http://www.dev.thomaskile.me/?page=test-zone&amp;module=Paginator" rel="noreferrer">http://www.dev.thomaskile.me/?page=test-zone&amp;module=Paginator</a>.<br>
  I know why this is happening; I've set the amount of page numbers to be shown on each side of current page to two (2).</p>
  
  <p>I would rather have the range of numbers to be equal like this:</p>
  
  <pre><code>[1]  2   3   4   5   6   7   8   ...   184   &gt;
   &lt;   1  [2]  3   4   5   6   7   ...   184   &gt;
   &lt;   1   2  [3]  4   5   6   7   ...   184   &gt;
   &lt;   1   2   3  [4]  5   6   7   ...   184   &gt;
   &lt;   1  ...  3   4  [5]  6   7   ...   184   &gt;
   &lt;   1  ...  4   5  [6]  7   8   ...   184   &gt;
   &lt;   1  ...  5   6  [7]  8   9   ...   184   &gt;    
   &lt;   1  ...  6   7  [8]  9   10  ...   184   &gt;
  </code></pre>
  
  <p>It's at the beginning and the end I need to make some changes, but can't figure out how to make it an easy operation...<br>
  I would like to make it flexible as well. Meaning I would like to be able to change the number of wanted pages on each side, and have the script expand and calculate it all...</p>
  
  <p><strong>Here is my code so far:</strong></p>
  
  <pre><code>/**
   *  page controller buttons 
   *  @param str $this-&gt;querySting      href="URL string"
   *  @param str $this-&gt;pageIdentifier  $_GET['this-name']
   *  @param int $this-&gt;numPages        Total amount of pages
   *  @param int $this-&gt;midRange        Number of pages to show on each side of current page
   */
  
  public function prevPage() 
  {
      if ($this-&gt;currentPage &gt; 1){ 
          $prevPage = ($this-&gt;currentPage - 1); 
          return '&lt;a href="'.$this-&gt;queryString.'&amp;'.$this-&gt;pageIdentifier.'='.$prevPage.'" class="prev"&gt;prev&lt;/a&gt;'; 
      }
  }
  public function nextPage() 
  {
      if ($this-&gt;currentPage &lt; $this-&gt;numPages) { 
          $nextPage = $this-&gt;currentPage + 1;
          return '&lt;a href="'.$this-&gt;queryString.'&amp;'.$this-&gt;pageIdentifier.'='.$nextPage.'" class="next"&gt;next&lt;/a&gt;';  
      }  
  }
  public function firstPage() 
  {
      if ($this-&gt;currentPage &gt; ($this-&gt;midRange + 1)) {  //  if number of pages between "currentPage" and "firstPage" exceeds $midRange with 1...
          $firstPage .= '&lt;a href="'.$this-&gt;queryString.'&amp;'.$this-&gt;pageIdentifier.'=1" class="first"&gt;1&lt;/a&gt;';  //  ...show "first page"-link
          if ($this-&gt;currentPage &gt; ($this-&gt;midRange + 2)) {   //  if number of pages between $currentPage and "first page" exceeds $midRange with more than 1
              $firstPage .= '&amp;hellip;';  //  add "..." between "1st page"-link and first page in $range
          }
      }
      return $firstPage;
  }
  public function lastPage() 
  {
      if ($this-&gt;currentPage &lt; ($this-&gt;numPages - $this-&gt;midRange)) {  //  if number of pages between "currentPage" and "last page" is equal to $midRange
          if (($this-&gt;currentPage &lt; ($this-&gt;numPages - $this-&gt;midRange) - 1)) {  //  if number of pages between $currentPage and "last page" exceeds $range with more than two
              $lastPage .= '&amp;hellip;';  //  add "..." between "last page"-link and last page in $range
          } 
          $lastPage .= '&lt;a href="'.$this-&gt;queryString.'&amp;'.$this-&gt;pageIdentifier.'='.$this-&gt;numPages.'" class="last"&gt;'.$this-&gt;numPages.'&lt;/a&gt;';   //  show "last page"-link
      }
      return $lastPage;
  }
  
  #  Range of pages between (prev first ...) and (... last next)
  public function listPages() 
  {
      for ($i = ($this-&gt;currentPage - $this-&gt;midRange); $i &lt; (($this-&gt;currentPage + $this-&gt;midRange) + 1); $i++){
         if (($i &gt; 0) &amp;&amp; ($i &lt;= $this-&gt;numPages))  //  if page number are within page range
         {
            if ($i == $this-&gt;currentPage) { $listPages .= '&lt;a class="current"&gt;'.$i.'&lt;/a&gt;'; }  //  if we're on current page
            else { $listPages .= '&lt;a href="'.$this-&gt;queryString.'&amp;'.$this-&gt;pageIdentifier.'='.$i.'"&gt;'.$i.'&lt;/a&gt;'; }  //  if not current page
          }
      }
      return $listPages; 
  }
  </code></pre>