<?php
 
//  ==========================
//  = Realiza calculos para paginar resultados = 
//  ==========================
 
class Paginator
{
    /*
     * propiedades
     */
      
    //resultados totales
    private $totalResultsSet;
     
    //numero de resultados por pagina
    private $resultsPage = 5;
     
    //numero de pagina actual
    private $page;
    
    //registro actual que esta usando el usuario
    private $currentPages;
    
    //numero de paginas totales
    private $totalPages;
     
    //numero de paginas anteriores
    private $pagesBefore    =   5;
     
    //numero de pagina siguiente
    private $pagesAfter =   5;
    
    //pagina anterior
    private $beforeButton;
    
    //pagina siguiente
    private $afterButton;
    
    //botones circundantes anteriores
    private $surroundBefore   =   array();     
    //botones circundantes posteriores
    private $surroundAfter  =   array();          
    //resultado de un metodo
    private $result =   array();     
    // action URL, para los botones del paginador
    private $url;
    
    //identificador, identifica el objeto que esta paginando
    private    $id;
    
    /*
     * para crear tanto las propiedades como para iniciar los calculos basicos para toda la clase
     */
    function    __construct($totalResultsSet, $page, $url, $id)
    {
        $this->totalResultsSet    =   $totalResultsSet;
        
        $this->page =   $page;
        
        $this->totalPages   =   $this->calcTotalPages($totalResultsSet, $this->resultsPage);
        
        $this->currentPage  =   $this->currentPages($page, $this->resultsPage);
        
        $this->url  =   $url;
        
        $this->id   =   $id;
    }
    
    /*
     * calcula las paginas totales
     */
    public  function    calcTotalPages($totalResultsSet, $resultsPage)
    {
        //divide los resultados totales entre los resultados a mostrar por pagina
        return  $this->totalPages   =  ceil($totalResultsSet    /   $resultsPage);     }
    
    /*
     * calcula el conjunto de registros que esta empleando el usuario 
     */
    public  function    currentPages($page, $resultsPage)
    {
        //multiplica la pagina actual por los resultados por pagina
        return  $this->currentPages  =   ceil($page   *   $resultsPage);     }
    
    /*
     * calcula las paginas circundantes anteriores
     */
    public  function    surroundPagesBefore()
    {  
        //resta la pagina menos el numero de paginas anteriores en el centro
        $pagesBefore  =   $this->page   -   $this->pagesBefore;
        
        //comienza a crear botones hasta llegar a la pagina actual
        for($i=$pagesBefore; $i < $this->page; $i++)
        {
            if($i>=0)
            {
                                                                                        'page'  =>$i,
                                                                                        'url'      =>$this->createURL($this->url, $this->id, $i)
                                                                                        ));
            }
        }
        
        //sino retorna false para que no muestre el boton anterior
        if(empty($this->surroundBefore))         {
            $this->surroundBefore   =   FALSE;
        }
        
        return  $this->surroundBefore;
    }
    
    /*
     * calcula las paginas circundantes posteriores
     */
    public  function    surroundPagesAfter()
    {  
        //suma a la pagina actual las paginas configuradas para mostrar despues
        $pagesAfter  =   $this->page   +   $this->pagesAfter;
        
        //comienza a crear tantos botones como paginas sean posibles o menor que la suma anterior
        for($i=$this->page; $i <= $this->totalPages; $i++)
        {
            if($i>$this->page)
            {
                                                                                        'page'  =>$i,
                                                                                        'url'      =>$this->createURL($this->url, $this->id, $i) //esta es la linea 154 de la clase
                                                                                     ));
            }
        }
        
        //asigna false para que no muestre botones posteriores
        if(empty($this->surroundAfter))         {
            $this->surroundAfter   =   FALSE;
        }
        
        return  $this->surroundAfter;
    }
    
    /*
     * crea el boton anterior
     */
    public  function    beforeButtons()
    {
        //resta 1 a la pagina actual
        $pageBefore  =   ceil($this->page  -   1);         
        //si el resultado anterior indica que no da un valor negativo
        if($pageBefore >=0)
        {
            $this->beforeButton  =   array(                                                                 'page'  =>$pageBefore,
                                                                'url'      =>$this->createURL($this->url, $this->id, $pageBefore)
                                                               );
        }
        
        //sino asigna false para no mostrar boton anterior
        else
      {
            $this->beforeButton  =   FALSE;
        }
      
        return $this->beforeButton;
    }
    
    /*
     * crea el boton siguiente
     */
    public  function    afterButtons()
    {  
        //suma a la pagina actual 1
        $afterButton    =   $this->page   +   1;
        
        //si el resultado anterior es menor o igual a las paginas totales posibles
        if($afterButton <=  $this->totalPages)
        {
            $this->afterButton  =   array(                                                              'page'  =>$afterButton,
                                                             'url'      =>$this->createURL($this->url, $this->id, $afterButton)
                                                            );
        }
        else
        {
            $this->afterButton  =   FALSE;
        }
        
        return  $this->afterButton;
    }
    
    /*
     * crea el array definitivo con todos los valores necesarios para todos los botones
     */
    public  function    paginator()
    {
        //comprueba que la pagina que ha enviado el usuario no sea mayor que el total de resultados posibles
        //tampoco que sea inferior a 0
        if($this->page  <=  $this->totalPages   AND $this->page>=0)
        {
                                                        'page'=>$this->page,
                                                        'surround_before'   =>$this->surroundPagesBefore(),
                                                        'surround_after'    =>$this->surroundPagesAfter(),
                                                        'before_button' =>$this->beforeButtons(),
                                                        'after_button'  =>$this->afterButtons(),
                                                        'total_pages'   =>$this->totalPages,
                                                        'current_pages' =>$this->currentPages,
                                                        'limit_since' =>$this->currentPages,
                                                        'limit_result_set'  =>$this->resultsPage
                                                    );
                                                                                
        }
        
        //si el usuario intentara romper el paginado poniendo páginas falsas entonces asigna FALSE
        else
      {
            $this->result   =   FALSE;
        }
        
        return  $this->result;
    }
 
    /*
     * busca y sustituye un patron dentro de una URL para
     * eliminar ese patron y sustituirlo para crear una nueva URL
     * evitando repetir el patron en la URL
     * 
     * por ejemplo evitar::          ?page=1&page=2&page=3
     */
    public  function    createURL($url, $id, $page)
    {
        //si el identificador no se encuentra en la url
        {
            //agrega al final de la url el identificador y el valor que le corresponde
            $url  =   $url."&".$id."=".$page;
        }
        
        //sino busca y reemplaza el identificador en la url por su nuevo valor
        else
      {
            $url  =   preg_replace("/(".$id.")/i", $url."&".$id."=".$page, $url);         }
        
        return  $url;
    }
}
?>