<?php
/**
 * DB record pager class.
 * 
 * BugFree is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * BugFree is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with BugFree; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * @link        http://bugfree.1zsoft.com
 * @package     BugFree
 * @version     $Id: Page.class.php,v 1.5 2006/08/16 15:37:50 wangcs Exp $
 */
class Page
{
    /**
     * ADODB对象。
     * @var Object
     */
     var $_MyDB;
    
    /**
     * 记录总数。
     * @var int
     */
     var $_RecTotal;
     
    /**
     * 每页显示的记录数。
     * @var int
     */
     var $_RecPerPage;
     
    /**
     * 分页总数。
     * @var int
     */
     var $_PageTotal;
     
    /**
     * 当前页面编号。
     * @var int
     */
     var $_PageID;
     
    /**
     * 链接地址，此地址包含分页信息，比如PageID，PageTotal等。
     * @var string
     */
     var $_URL;
     
    /**
     * 用于前台跳转用的URL地址，此地址里面不包含分页信息。
     * @var string
     */
     var $_PartURL;
     
    /**
     * 表名。
     * @var string
     */
     var $_TableName;
    
    /**
     * 查询条件。
     * @var string
     */
     var $_Where;
     
    /**
     * 初始化分页类。
     *
     * @global object              Object of ADO class.
     * @param  string $TableName   要查询的表名，如果是两个表，可以使用逗号隔开。但在where条件里面必须指定连接条件。
     * @param  int    $RecTotal    记录总数。
     * @param  int    $RecPerPage  每页显示的记录数。
     * @param  int    $PageID      当前分页编号。
     * @param  string $Where       查询条件。
     * @param  string $URL         链接条件。
     */
    function page($TableName, $RecTotal = "", $RecPerPage = 20, $PageID, $Where = "", $URL="")
    {
        global $MyDB;
        
        /* 设定数据库参数。*/
        $this->_MyDB       = $MyDB;
        $this->_TableName  = !empty($TableName) ? $TableName : die("请指定表名");
        $this->_Where      = $Where;
        
        /* 设定记录总数、每页显示数、分页总数和当前分页ID。*/
        $this->_RecTotal   = ($RecTotal   > 0) ? $RecTotal   : $this->getRecTotal();
        $this->_RecPerPage = ($RecPerPage > 0) ? $RecPerPage : 20;    
        $this->setPageTotal();
        $this->setPageID($PageID);
        
        /* 设定url参数：_URL 和_PartURL。*/
        $this->setURL($URL);
        
        /* 传递记录总数。*/
        if(!eregi("\?", $this->_URL))
        {
            $this->_URL     .= "?RecTotal=" . $this->_RecTotal . "&RecPerPage=$this->_RecPerPage&";
            $this->_PartURL .= "?RecTotal=" . $this->_RecTotal . "&";
        }
        else
        {
            $this->_URL     .= "&RecTotal=" . $this->_RecTotal . "&RecPerPage=$this->_RecPerPage&";
            $this->_PartURL .= "&RecTotal=" . $this->_RecTotal . "&";
        }
    }
    
    /* 取得某一条件查询结果的记录总数。*/
    function getRecTotal()
    {
        $SQL     = "SELECT COUNT(*) AS RecTotal FROM $this->_TableName $this->_Where";
        $DataSet = $this->_MyDB->getRow($SQL);
        if($DataSet["RecTotal"] > 0)
        {
            $this->_RecTotal = $DataSet["RecTotal"];
        }
        else
        {
            $this->_RecTotal = 0;
        }
        return $this->_RecTotal;
    }
    
    /* 设定当前记录编号。*/
    function setPageID($PageID)
    {
        if($PageID > 0 and $PageID <= $this->_PageTotal)
        {
            $this->_PageID = $PageID;
        }
        else
        {
            $this->_PageID = $this->_PageTotal;
        }
    }
     
    /* 获得分页总数。*/
    function setPageTotal()
    {
        $this->_PageTotal = ceil($this->_RecTotal / $this->_RecPerPage);
        return $this->_PageTotal;
    }
     
    /**
     * 设定URL地址。
     *
     * 如果没有指定$URL，则从$_SERVER["QUERY_STRING"]里面将要传递的参数解析出来，去掉PageID和PageTotal项，再拼成完成的URL地址。
     * 
     * @bug                 如果传递的参数中含有数组，即var[]=xx&var[2]=xx，会有问题。:)
     * @param  string  $URL 调用此分页类时可以手工指定URL地址。
     * @return int          记录分页总数。
     */
     function setURL($URL = "")
     {
         if(!empty($URL))
         {
             $this->_URL = $URL;
             return;
         }
         
         /* 取当前程序的地址作为URL的开始部分。*/
         $this->_URL = $_SERVER["PHP_SELF"];
         
         /* 分析QUERY_STRING，去掉PageID, RecTotal和空值的变量。*/
         parse_str($_SERVER["QUERY_STRING"], $QueryList);
         foreach($QueryList as $QueryName => $QueryValue)
         {
             if(eregi("PageID|RecTotal|RecPerPage", $QueryName) or empty($QueryValue))
             {
                 unset($QueryList[$QueryName]);
             }
         }
         
         /* 拼凑成完成的URL地址。*/
         if(!empty($QueryList))
         {
             foreach($QueryList as $QueryName => $QueryValue)
             {
                 if(eregi("\?", $this->_URL))
                 {
                     $this->_URL .= "&" . $QueryName . "=" . $QueryValue;
                 }
                 else
                 {
                     $this->_URL .= "?" . $QueryName . "=" . $QueryValue;
                 }
             }
         }
         
         $this->_PartURL = $this->_URL;
     }
     
    /**
     * 显示查询结果的分页链接。
     *
     * @param  string $Align  对其方式，默认为居中对齐。left|center|right
     * @return string         返回导航条文字。
     */
    function show($Align = "right")
    {
        /* 定义链接符号。*/
        $FirstPage = " 首页 ";
        $EndPage   = " 末页 ";
        $PrePage   = " 前页 ";
        $NextPage  = " 后页 ";
       
        /* 建立一个数组，其数值从PageTotal降序排列。*/
        $Y = 1;
        for($I = $this->_PageTotal; $I >= 1; $I--)
        {
            $PageIdList[$Y] = $I;
            $Y ++;
        }
        
        /* 获得相反的分页编号，用于显示。*/
        $ReversePageID = $PageIdList[$this->_PageID];
        
        /* 如果页码总数为零，则直接退出。*/
        if($this->_RecTotal == 0)
        {
            return "暂时没有记录！";
        }

        /* 跳转页面的js函数。*/
        $PageURL = "'" . $this->_PartURL . "PageID=' + PageID + '&RecPerPage=' + RecPerPage";
        $LinkString = <<<EOT
        <script language='Javascript'>
        function submitPage(mode)
        {
            PageTotal     = parseInt(document.getElementById('_PageTotal').value);
            if(mode == 'changePageID')
            {
                PageID        = PageTotal + 1 - document.getElementById('_PageID').value;
                if(PageID > PageTotal)
                {
                    PageID = PageTotal;
                }
                else if(PageID < 1)
                {
                    PageID = 1;
                }
            }
            else if(mode == 'changeRecPerPage')
            {
                PageID = 0;
            }
            RecPerPage    = document.getElementById('_RecPerPage').value;
            location.href = $PageURL;
        }
        </script>
EOT;

        /* 手工指定每页显示数。*/
        for($I = 5; $I <=100; $I +=5)
        {
            $RecPerPageRange[$I] = $I;
        }
        $RecPerPageList = htmlSelect($RecPerPageRange, "_RecPerPage", "Reverse", $this->_RecPerPage, "onchange='submitPage(\"changeRecPerPage\");'");
        
        /* 显示记录总数。*/
        $LinkString .= "共<strong>$this->_RecTotal</strong>条记录 每页$RecPerPageList 条 页码：<strong>$ReversePageID</strong>/<strong>$this->_PageTotal</strong>页";
        
        
         /* 生成第一页的链接，对应正常分页的最后一页。 */
        if($this->_PageID == $this->_PageTotal)
        {
            $LinkString .= $FirstPage;
        }
        else
        {
            $LinkString .= $this->link($FirstPage, $this->_URL . "PageID=" . $this->_PageTotal);
        }
        
        /* 生成前页的链接。*/
        if($this->_PageID == $this->_PageTotal)
        {
            $LinkString .= $PrePage;
        }
        else
        {
            $LinkString .= $this->link($PrePage, $this->_URL . "PageID=" . ($this->_PageID + 1));
        }
        
        /* 生成后页的链接。*/
        if($this->_PageID == 1)
        {
             $LinkString .= $NextPage;
        }
        else
        {
            $LinkString .= $this->link($NextPage, $this->_URL . "PageID=" . ($this->_PageID - 1));
        }
        
        /* 生成最后一页的链接。*/
        if($this->_PageID == 1)
        {
            $LinkString .= $EndPage;
        }
        else
        {
            $LinkString .= $this->link($EndPage, $this->_URL . "PageID=1");
        }
        
        /* 生成手工跳转文本框。*/
        $LinkString .= "<input type='hidden' id='_PageTotal' value='$this->_PageTotal' />
                        <input type='text'   id='_PageID'    value='$ReversePageID' style='text-align:center;width:30px; height:18px;' />
                        <input type='button' id='goto'       value='转到' onclick='submitPage(\"changePageID\");' />";
        
        return "<div style='float:$Align; clear:none'>$LinkString</div>";
    }
    
    /**
     * 生成SQL查询语句的Limit部分
     *
     * @return string  Limit语句。
     */
    function Limit()
    {
        /* 保证最后一页查出的记录数为RecPerPage。加上不等于1的限制是为了防止出现limit -20,10这样的情况。*/
        if($this->_RecTotal < $this->_RecPerPage)
        {
	        $Limit = " LIMIT 0," . $this->_RecTotal;
        }
        elseif($this->_PageID == $this->_PageTotal and $this->_PageTotal != 1)
        {
            $Limit = " LIMIT " . ($this->_RecTotal - $this->_RecPerPage) . "," . $this->_RecPerPage;
        }
        else
        {
            $Limit = " LIMIT " . $this->_RecPerPage * ($this->_PageID - 1) . "," . $this->_RecPerPage;
        }
        return $Limit;
    }
     
   /**
    * 生成<a href="">text</a>标记。
    *
    * @param string $Text	    链接文字。
    * @param string $URL	    链接地址。
    */
    function link($Text,$URL)
    {
        $LinkString = "<a href='".$URL."'>".$Text."</A>";
        return $LinkString;
    }
}
?>