<?
class CleverPager
{
  // SQL prikaz pro vyber dat pred strankovanim, 
  // nesmi pouzivat LIMIT
  public $SelectCommand; 
  // SQL prikaz na vypocitani poctu zaznamu lze nechat 
  // nenastaveny, v tom pripade se vygeneruje v metode DataBind
  public $CountCommand;
  // Pocet zaznamu na strance
  public $PageSize = 10;
  // Parametr URL, ze ktereho se cte cislo akt. stranky
  public $UrlParameterName;
  // atribut ID, ktery bude mit div kolem pageru
  public $PagerID = "PagerId";
  // atribut Class, ktery bude mit div kolem pageru 
  public $PagerCssClass = "PagerClass";
  // zarovnani - hodnota text-align v atributu style,
  // hodnota inherit znamena, ze div tento atribut 
  // vubec mit nebude
  public $PagerAlign = "inherit";
  // pocet cisel okolnich stranek, ktere se zobrazi
  // hodnota -1 znamena, ze se zobrazi vsechny
  // hodnota 0 znamena zadne
  public $PageLinksDisplayed = -1;
  // priznak zobrazovani tlacitek predchozi a nasledujici stranky
  public $ShowPrevNext = 1;
  // priznak zobrazovani tlacitek prvni a posledni stranky
  public $ShowFirstLast = 1;
  
  // text odkazu na prvni stranku
  public $FirstPage = "&lt;&lt;";
  // text odkazu na posledni stranku
  public $LastPage = "&gt;&gt;";
  // text odkazu na predchozi stranku
  public $PrevPage = "&lt;";
  // text odkazu na nasledujici stranku
  public $NextPage = "&gt;";
  
  // css tridy, ktere budou mit jednotlive odkazy na stranky
  public $LinkCssClass;
  public $FirstCssClass;
  public $LastCssClass;
  public $NextCssClass;
  public $PrevCssClass;
  public $CurrentPageCssClass;
  
  // aktualni stranka
  private $_targetedPage = 2;
  // pocet stranek
  private $_pageCount = 0;
  // Zde bude vysledkova sada po zavolani DataBind
  private $ResultSet = NULL;
  // priznak prvniho parametru, nedulezite
  private $first = 0;
  
  // konstruktor - parametry jsou SQL prikaz na vyber vysledkove 
  // sady a parametr URL, ve kterem bude cislo aktualni stranky
  public function __construct(
    $SelectCommand, 
    $UrlParameterName)
  {
    $this->SelectCommand = $SelectCommand;
    $this->UrlParameterName = $UrlParameterName;
  }
  
  // Spocita pocet zaznamu a z atributu _pageCount,
  // PageSize a _targetedPage vybere pozadovanou stranku
  public function DataBind()
  {
    // priprava prikazu pro spocitani zaznamu,
    // pokud nebyl zadan zvenci
    if (!$this->CountCommand || $this->CountCommand == "")
    {
      $this->CountCommand = preg_replace(
        '@SELECT (.*) FROM@', 
        'SELECT COUNT(*) AS Count FROM', 
        $this->SelectCommand);
    }  
    //zjisteni cisla aktualni stranky
    if (isset($_GET[$this->UrlParameterName]))
      $this->_targetedPage = 
        (int)($_GET[$this->UrlParameterName]);
    else
      $this->_targetedPage = 1;
    if ($this->_targetedPage == 0)
      $this->_targetedPage = 1;
    //zjisteni poctu zaznamu
    $c = (mysql_fetch_object(
      mysql_query($this->CountCommand)));
    //vypocet poctu stranek
    $this->_pageCount = 
      (int) (($c->Count + $this->PageSize - 1) / $this->PageSize);
    if ($this->_targetedPage > $this->_pageCount)
      $this->_targetedPage = 1;
    //vypocet parametru pro LIMIT
    $firstrow = 
      ($this->_targetedPage - 1) * $this->PageSize;
    $this->ResultSet = 
      mysql_query("$this->SelectCommand ".
                  " LIMIT $firstrow, $this->PageSize" ) or die($this->SelectCommand.'<br />'.mysql_error());
  }
  
  // postupne vraci radky vysledkove sady, 
  // po zavolani DataBind
  public function GetOne()
  {
    return mysql_fetch_array($this->ResultSet);
  }
  
  //pomocna metoda pro vytvoreni odkazu
  private function prepareLink(
    $prefix, 
    $page, 
    $anchoringText, 
    $cssClass)
  { 
    if ($page != $this->_targetedPage)
    {
      if ($page == 1)
        $h = $prefix;
      else {
        if ($this->first)
          $h = $prefix."?".$this->UrlParameterName."=".$page;
        else
          $h = $prefix."&".$this->UrlParameterName."=".$page;
      }
      if ($cssClass != "" && $cssClass)
        $css = " class=\"$cssClass\"" ;
      else $css="";
      return "<a href=\"$h\"$css>$anchoringText</a> ";
    } else {
      if ($this->CurrentPageCssClass && 
          $this->CurrentPageCssClass != "")
      {
        echo "<span class=\"$this->CurrentPageCssClass\">";
        echo $anchoringText;
        echo "</span> ";
      }
      else
        echo $anchoringText." ";
    }
  }
  
  // vypise pager do tela stranky
  public function DrawPager()
  {
    //analyza url
    $hrefprefix = $_SERVER['SCRIPT_NAME'];
    $this->first=1;
    foreach ( $_GET as $key=>$value) {
      if ($key == $this->UrlParameterName)
        continue;
        if ($this->first)
        {
         $hrefprefix .= "?".$key."=".$value;
         $this->first = 0; 
        }
        else
         $hrefprefix .= "&".$key."=".$value;
    }
    
    //vykresleni div tagu kolem pageru s odpovidajicimi atributy
    if ($this->PagerID && $this->PagerID != "")
      $id = " id=\"$this->PagerID\"";
    else $id ="";
    if ($this->PagerCssClass && $this->PagerCssClass != "")
      $class = " class=\"$this->PagerCssClass\"";
    else $class = "";
    if ($this->PagerAlign != "inherit") 
        $align = " style=\"text-align: $this->PagerAlign\"";
    else
      $align ="";
    echo "<div $id $class $align >";
    
    //prvni stranka
    if ($this->ShowFirstLast)
    {
      echo $this->prepareLink(
        $hrefprefix, 
        1, 
        $this->FirstPage, 
        $this->FirstCssClass);
    }
    
    //predchozi stranka
    if ($this->ShowPrevNext)
    {
      $p = max($this->_targetedPage - 1, 1);
      echo $this->prepareLink(
        $hrefprefix, 
        $p, 
        $this->PrevPage, 
        $this->PrevCssClass);
    }
    
    //stranky mezi bez omezeni
    if ($this->_pageCount <= $this->PageLinksDisplayed ||  
        $this->PageLinksDisplayed == -1)
    {
      for ($p = 1; $p <= $this->_pageCount; $p++)
        echo $this->prepareLink(
          $hrefprefix, 
          $p, 
          $p,
          $this->LinkCssClass);
    } 
    else //stranky mezi
    {
        $pagesBefore = (int)min(
          $this->PageLinksDisplayed / 2, 
          $this->_targetedPage - 1);
        $pagesAfter = (int)min(
          $this->PageLinksDisplayed - $pagesBefore - 1, 
          $this->_pageCount - $this->_targetedPage);
        if ($pagesAfter + $pagesBefore + 1 != $this->PageLinksDisplayed)
            $pagesBefore = $this->PageLinksDisplayed - 1 - $pagesAfter;
        for ($p = $this->_targetedPage - $pagesBefore; 
             $p <= $this->_targetedPage + $pagesAfter; 
             $p++)
            echo $this->prepareLink($hrefprefix, $p, $p, $this->LinkCssClass);
    }

    //nasledujici stranka
    if ($this->ShowPrevNext)
    {
      $p = min($this->_targetedPage + 1, $this->_pageCount);
      echo $this->prepareLink(
        $hrefprefix, 
        $p, 
        $this->NextPage, 
        $this->NextCssClass);
    }
    
    //posledni stranka
    if ($this->ShowFirstLast)
    {
      $p = $this->_pageCount;
      echo $this->prepareLink(
        $hrefprefix, 
        $p, 
        $this->LastPage, 
        $this->LastCssClass);
    }    
    
    //uzavreni bloku pageru
    echo "</div>";
  }
}
?>
