<?php 
namespace imcat;

// 分页类
// 优化1: 多页提交,不重复计算记录数目
// 优化2: ORDER BY 主键,不用 OFFSET
class comPager{    
    
// sql
    
public  $sfrom '';
    public  
$where '';
    
// page
    //public  $paras = '?';
    
public  $psize 20//分页大小
    
public  $page 1//当前页
    
public  $pcnt 1//总前页
    // page para
    
public  $prec 0//总记录数
    
public  $ptype 'start'//first,prev,next,last
    
public  $pkey ''
    
// order    
    
public  $order ''//排序字段,含前缀,如a.aid
    
public  $orderb ''//排序字段,去掉了前缀,如aid
    
public  $odesc true;
    public  
$opkey false
    
    public  
$rs = array();
    public  
$bar = array();
    public  
$cfg = array();
    public  
$sql = array('','');

    
//function __destory(){  basDebug::bugLogs('page'); }
    
function __construct($sfrom,$where,$psize=0,$order=''){ 
        
$this->sfrom $sfrom;
        
$this->where $where;
        
$this->psize $psize;
        
$this->order $order;
        if(
strpos($order,'.') || strpos($order,' ')){
            
$this->orderb substr($order,strpos($order,'.')+1);
        }else{
            
$this->orderb $order;    
        }
        
// init;
        
$a = array('page','prec','ptype','pkey',); // 'odesc','opkey',
        
foreach($a as $k){
            if(isset(
$_GET[$k])){ 
                
$__v basReq::val($k,'Key',24); 
                if(
in_array($k,array('page',))) $__v max(1,intval($__v));
                if(
in_array($k,array('prec',))) $__v max(0,intval($__v));
                
$this->$k $__v;
            }
        }
        if(
''!==$om=basReq::val('odesc','N',1)){ $this->odesc $om; }
    }
    
    function 
set($key,$value=0){
        if(
is_array($key)){
            foreach(
$key as $k=>$v$this->set($k,$v);
        }else{
            
$this->$key $value;
        } 
    }
    
    function 
sql($cnt=''){ 
        
$sfrom ' SELECT '.$this->sfrom;
        if(
$cnt){
            
$where $this->where ' WHERE '.$this->where '';
            
$this->sql[1] = basSql::fmtCount($sfrom.$where,$cnt);
            return 
$this->sql[1];
        }else{
            
$where ' WHERE '.($this->where $this->where '1=1');
            
$ptype $this->ptype;
            
$pkey $this->pkey
            
$odesc $this->odesc;
            if(
$this->opkey&&$ptype){
                if(
$ptype=='start'){
                    
//$where .= "";
                
}else if($ptype=='end'){
                    
//$where .= "";
                
}else if($ptype=='next'){ 
                    if(
$odesc$where .= " AND {$this->order}<'$pkey'";
                    if(!
$odesc$where .= " AND {$this->order}>'$pkey'";
                }else if(
$ptype=='prev'){
                    if(
$odesc$where .= " AND {$this->order}>'$pkey'";
                    if(!
$odesc$where .= " AND {$this->order}<'$pkey'";
                } 
                if(
$ptype=='end'){
                    
$lcnt $this->prec%$this->psize;
                    
$lcnt $lcnt $lcnt $this->psize;
                    
$limit ' LIMIT '.$lcnt
                }else{
                    
$limit ' LIMIT '.$this->psize;
                }
            }else{
                
$offset = ($this->page-1)*$this->psize;
                
$limit " LIMIT $offset,".$this->psize;
            }
            if(
$where==' WHERE 1=1'$where "";
            if(
$ptype=='end'||$ptype=='prev'){
                
$ord_in ' ORDER BY '.$this->order.($this->odesc '' ' DESC');
                
$ord_out ' ORDER BY '.$this->orderb.($this->odesc ' DESC' '');
                
$this->sql[0] = "SELECT * FROM ($sfrom $where $ord_in $limit) _tab__ $ord_out ";
            }else{
                
$order ' ORDER BY '.$this->order.($this->odesc ' DESC' '');
                
$this->sql[0] = $sfrom.$where.$order.$limit;
            }
            return 
$this->sql[0];
        }
    }
    function 
exe($dbkey=''){
        
$db glbDBObj::dbObj($dbkey);
        
$rs $db->query($this->sql());
        if(!
$this->prec){ 
            
$rec $db->query($this->sql('_rc_recs_'));
            
$this->prec $rec[0]['_rc_recs_'];
        } 
        
$this->pcnt ceil($this->prec/$this->psize);
        
$this->bar $this->links();
        return 
$rs;
    }
    
    function 
show($kfirst='',$klast='',$type='',$pbase=''){
        
$pbase = empty($pbase) ? basReq::getUri(-1,'','page|prec|ptype|pkey') : $pbase
        
$a $this->bar$bar ''$para "&prec=$this->prec&page=";
        
$p0 = array("{pfirst}","{pprev}","{pnext}","{plast}",); 
        
$p1 = array("{$para}1","$para".($this->page-1),"$para".($this->page+1),"$para".$this->pcnt,); 
        if(
$this->opkey){
            
$p1[0] .= "&ptype=start";
            
$p1[1] .= "&ptype=prev&pkey=$kfirst";
            
$p1[2] .= "&ptype=next&pkey=$klast";
            
$p1[3] .= "&ptype=end";
        }
        
$a['pjump'] = str_replace("{pjump}","{$para}0&ptype=0",$a['pjump']); 
        foreach(
$a as $k=>$v){
            
$v str_replace("<li>","\n<li class='pg_$k'>",$v);
            if(
in_array($k,array('first','prev','next','last'))){
                
$v str_replace($p0,$p1,$v);
            }
            
$bar .= $v
        } 
//echo $pbase;
        
$bar str_replace(["{url}&",'{url}'], [strpos($pbase,'?')>0?"$pbase&":"$pbase?","$pbase"], $bar);
        foreach (
$this->cfg as $ck => $cv) {
            
$this->cfg[$ck] = str_replace($p0$p1$this->cfg[$ck]);
            
$this->cfg[$ck] = str_replace(["{url}&",'{url}'], [strpos($pbase,'?')>0?"$pbase&":"$pbase?","$pbase"], $this->cfg[$ck]);
        }
        return 
"<ul class='pagination'>\n$bar</ul>\n";
    }
    
    function 
links(){
        
$pcnt intval($this->pcnt);
        
$a = array(); 
        
$sFirst '<span class="fa fa-fast-backward"></span>';
        
$sPrev '<span class="">&laquo;</span>';
        
$sNext '<span class="">&raquo;</span>';
        
$sLast '<span class="fa fa-fast-forward"></span>';
        
        
$a['pagno'] = "<li class='pg_pagno'><a class='disabled'>$this->page/$pcnt</a></li>\n";
        
$a['first'] = "<li><a class='disabled'>$sFirst</a></li>\n";
        
$a['prev']  = "<li><a class='disabled'>$sPrev</a></li>\n";
        
$a['pjump'] = "<li class='pg_pjump'><input type='text' id='pg_pjump' pjurl='{url}{pjump}' pjmax='{$pcnt}' value='$this->page' class='form-control' onchange='goPjump(this)'/></li>\n";
        
$a['next']  = "<li><a class='disabled'>$sNext</a></li>\n";
        
$a['last']  = "<li><a class='disabled'>$sLast</a></li>\n";
        
$a['total'] = "<li class='pg_total'><a class='disabled'>$this->prec</a></li>\n";

        
$cfg['page'] = $this->page$cfg['pcnt'] = $pcnt;
        
$cfg['first'] = $cfg['prev'] = $cfg['next'] = $cfg['last'] = '#';

        if(
$pcnt<=1) return $a;
        if(
$this->page==$pcnt){
            
$a['first'] = "<li><a href='{url}{pfirst}'>$sFirst</a></li>\n";
            
$a['prev']  = "<li><a href='{url}{pprev}' >$sPrev</a></li>\n";
            
$cfg['first'] = "{url}{pfirst}";
            
$cfg['prev'] = "{url}{pprev}";
        }elseif(
$this->page==1){
            
$a['next']  = "<li><a href='{url}{pnext}' >$sNext</a></li>\n";
            
$a['last']  = "<li><a href='{url}{plast}' >$sLast</a></li>\n";
            
$cfg['next'] = "{url}{pnext}";
            
$cfg['last'] = "{url}{plast}";
        }else{
            
$a['first'] = "<li><a href='{url}{pfirst}'>$sFirst</a></li>\n";
            
$a['prev']  = "<li><a href='{url}{pprev}' >$sPrev</a></li>\n";
            
$a['next']  = "<li><a href='{url}{pnext}' >$sNext</a></li>\n";
            
$a['last']  = "<li><a href='{url}{plast}' >$sLast</a></li>\n";
            
// 
            
$cfg['first'] = "{url}{pfirst}";
            
$cfg['prev'] = "{url}{pprev}";
            
$cfg['next'] = "{url}{pnext}";
            
$cfg['last'] = "{url}{plast}";
        }
        
$this->cfg $cfg;
        return 
$a;
    }

    static function 
fixUrl($key='home'){
        global 
$_cbase;
        
$bar = &$_cbase['page']['bar'];
        if(!
strpos($bar,"?$key&")){
            
$bar str_replace('?',"?$key&",$bar);
        }
        return 
$bar;
    }
    
}