Source for file pager.classe.php

Documentation is available at pager.classe.php

  1. <?
  2.     /**
  3.      * pager.classe.php
  4.      * Objeto para paginação de listas de dados, com base em uma query ou array
  5.      * de dados calcula todos os dados necessários para exibição de listagens
  6.      * com paginação.
  7.      * 
  8.      * @filesource
  9.      * @package Soomp
  10.      * @author Cássio Vinícius Leguizamon Bueno <fumuca@gmail.com>
  11.      * @author Loé <loe.lobo@gmail.com>
  12.      * @author Marcio Merlone <mmerlone@gmail.com>
  13.      * @version 1.0
  14.      * @since 04/09/2006
  15.      * @copyright 2008 Soomp
  16.      */
  17.     /* $Id: pager.classe.php,v 1.3 2007/05/24 20:20:38 mmerlone Exp $ */
  18.  
  19.     /**
  20.      * Cria os recursos para navegação e paginação de listagens
  21.      * <code>
  22.      *        $idListagem = isset($_REQUEST['idListagem']) && $_REQUEST['idListagem'] ? $_REQUEST['idListagem'] : 1;
  23.      *        $g = new grupo();
  24.      *        $g->colunas    = array(CFG_GRUPO_DB_PK        => array('ID', true),
  25.      *                            CFG_GRUPO_DB_NOME    => array(array('id' => 4, 'value' => 'Nome'),    true),
  26.      *                            CFG_GRUPO_DB_TS        => array(array('id' => 5, 'value' => 'Criação'),true),
  27.      *                            'acoes'                => array(array('link'    => 'index.php?m=grupo&a=edit&id=$'.CFG_GRUPO_DB_PK,
  28.      *                                                                 'title'    => 'Edita o Grupo',
  29.      *                                                                 'text'    => 'e',
  30.      *                                                                 'ico'    => 'i/icoEdit.gif'),
  31.      *                                                         array('link'    => 'javascript:del($'.CFG_GRUPO_DB_PK.')',
  32.      *                                                               'title'    => 'Remove o Grupo',
  33.      *                                                               'text'    => 'x',
  34.      *                                                               'ico'    => 'i/icoExcluir.gif'),
  35.      *                                                          )
  36.      *                            );
  37.      *        $lista = $g->getCollection($idListagem);
  38.      *        $acoes = array('delmulti' => array('id' => 31, 'value' => 'Remove selecionados'));
  39.      *        $lista->setComboAcoes($acoes);
  40.      *        $lista->boolRegNum            = true;
  41.      *        $lista->boolRegNumCombo        = true;
  42.      *        $lista->boolIrParaCombo        = true;
  43.      *        $lista->boolFiltroLetras    = true;
  44.      *        $lista->strFiltroLetras        = "A,B,C;D,E,F;G,H,I;J,K,L;M,N,O;P,Q,R;S,T,U;V,X,W,Z;Todos";
  45.      *        $lista->legenda                = 'Grupos';
  46.      *        $req->smarty->assign('lista', $lista);
  47.      *        $req->smarty->jsSrc('j/listaUsuarios.js');
  48.      *        $req->smarty->js('jsVarsLista.tpl');
  49.      *        $req->smarty->display('lista.tpl');
  50.      *        return;
  51.      * </code>
  52.      */
  53.     class pager extends stdio{
  54.  
  55.         /**
  56.          * @var integer $intPag número da página atual
  57.          */
  58.         private $intPag;
  59.         /**
  60.          * @var integer $intPagPrimeira número da primeira página
  61.          *  null se já estiver na primeira página
  62.          */
  63.         private $intPagPrimeira;
  64.         /**
  65.          * @var integer $intPagAnterior número da página anterior
  66.          *  null se não houver página anterior
  67.          */
  68.         private $intPagAnterior;
  69.         /**
  70.          * @var integer $intPagProxima número da próxima página
  71.          *  null se não houver próxima página
  72.          */
  73.         private $intPagProxima;
  74.         /**
  75.          * @var integer $intPagUltima número da última página
  76.          *  null se já estiver na última página
  77.          */
  78.         private $intPagUltima;
  79.         /**
  80.          * @var integer $intPagTotal Apesar de redundante com $intPagUltima, serve para uso no template
  81.          */
  82.         private $intPagTotal;
  83.  
  84.  
  85.         /**
  86.          * @var integer $intRegPagina quantidade SOLICITADA de registros por página
  87.          */
  88.         private $intRegPagina;
  89.         /**
  90.          * @var integer $intRegPaginaAtual quantidade EFETIVA de registros na página atual
  91.          */
  92.         private $intRegPaginaAtual;
  93.         /**
  94.          * @var integer $intRegInicial número do primeiro registro da página atual
  95.          */
  96.         private $intRegInicial;
  97.         /**
  98.          * @var integer $intRegFinal número do último registro da página atual
  99.          */
  100.         private $intRegFinal;
  101.         /**
  102.          * @var integer $intRegTotal total de registros em todas as páginas
  103.          */
  104.         private $intRegTotal;
  105.  
  106.  
  107.         /**
  108.          * @var string $strOrdCampo nome do campo pelo qual deve-se ordenar a lista
  109.          */
  110.         private $strOrdCampo;
  111.         /**
  112.          * @var string $strOrdCampoDefault nome do campo pelo qual deve-se ordenar a lista por padrão
  113.          */
  114.         private $strOrdCampoDefault;
  115.         /**
  116.          * @var string $strOrdSentido sentido pelo qual deve-se ordenar a lista [ASC|DESC]
  117.          */
  118.         private $strOrdSentido 'ASC';
  119.         /**
  120.          * @var string $strFiltro armazena a filtragem ABC solicitada
  121.          */
  122.         private $strFiltro;
  123.         /**
  124.          * @var array $arrFiltro armazena a filtragem ABC solicitada conforme $strFiltro
  125.          */
  126.         private $arrFiltro;
  127.  
  128.  
  129.         /**
  130.          * @var string $strPalavraBusca string de busca para pesquisa na lista
  131.          */
  132.         private $strPalavraBusca;
  133.         /**
  134.          * @var mixed $mixDados Query SQL com a consulta a ser executada ou array de dados a paginar
  135.          */
  136.         private $mixDados;
  137.         /**
  138.          * @var array $arrDados dados a serem listados na página atual
  139.          */
  140.         private $arrDados;
  141.         /**
  142.          * @var string $strPkTabela campo para contagem de registros e ordenação default
  143.          */
  144.         private $strPkTabela;
  145.  
  146.  
  147.         /**
  148.          * @var integer $idListagem identificador da lista
  149.          */
  150.         private $idListagem;
  151.         /**
  152.          * @var array $colunas Define as colunas da listagem
  153.          *  <code>
  154.          *     $lista->colunas    = array(CFG_USUARIO_DB_PK        => array('ID',             true),
  155.          *                             CFG_USUARIO_DB_USERNAME    => array('Username',    true),
  156.          *                             CFG_USUARIO_DB_NOME        => array('Nome',        true),
  157.          *                             CFG_USUARIO_DB_EMAIL    => array('E-mail',        true),
  158.          *                             CFG_USUARIO_DB_TS        => array('Criação',        true),
  159.          *                             'acoes'                    => array(array('link'    => 'javascript:del($'.CFG_USUARIO_DB_PK.')',
  160.          *                                                                     'title'    => array('id' => 7, 'value' => 'Remove o usuário'),
  161.          *                                                                     'text'    => 'x'),
  162.          *                                                               array('link'    => 'index.php?m=$modulo&a=edit&id=$'.CFG_USUARIO_DB_PK,
  163.          *                                                                       'title'    => array('id' => 8, 'value' => 'Edita o usuário'),
  164.          *                                                                       'text'    => 'e')
  165.          *                                                               )
  166.          *                             );
  167.          *  </code>
  168.          *  As chaves do array podem ser:
  169.          *  - O nome do campo
  170.          *  - a string fixa 'acoes'.
  171.          * 
  172.          *  Quando a chave for o nome do campo o valor será um array no formato:
  173.          *  <code>
  174.          *  $lista->colunas['PK_BLA'] = array(<string com o nome do campo>, <se ordenável ou não>)
  175.          *  </code>
  176.          *  onde <se ordenável ou não> é um booleano que indica se haverá link para ordenação ASC/DESC na coluna
  177.          *  e <string com o nome do campo> pode também ser um array no formato para internacionalização:
  178.          *  <code>
  179.          *  $lista->colunas['PK_BLA'] = array(array('id' => 99, 'value' => '<string com o nome do campo>'), <se ordenável ou não>)
  180.          *  </code>
  181.          * 
  182.          *  Quando a chave for 'acoes', o valor será um array no formato:
  183.          *  <code>
  184.          *  $lista->colunas['acoes'] = array(array('link'    => 'javascript:del($'.CFG_USUARIO_DB_PK.')',
  185.          *                                           'title'    => array('id' => 7, 'value' => 'Remove o usuário'),
  186.          *                                           'text'    => 'x'),
  187.          *                                     array('link'    => 'index.php?m=$modulo&a=edit&id=$'.CFG_USUARIO_DB_PK,
  188.          *                                           'title'    => array('id' => 8, 'value' => 'Edita o usuário'),
  189.          *                                           'text'    => 'e')
  190.          *                                     )
  191.          *  </code>
  192.          */
  193.         private $colunas;
  194.         /**
  195.          * @var boolean $boolCheck Define se serão exibidos os checkboxes de seleção de registros.
  196.          */
  197.         private $boolCheck false;
  198.         /**
  199.          * @var $arrComboAcoes Define as ações existentes para os checkboxes
  200.          */
  201.         private $arrComboAcoes array();
  202.         /**
  203.          * @var string $legenda Legenda da listagem
  204.          */
  205.         private $legenda 'Listagem';
  206.         /**
  207.          * @var boolean $boolRegNum Define se a listagem exibirá os contadores dos registros
  208.          */
  209.         private $boolRegNum;
  210.         /**
  211.          * @var boolean $boolRegNumCombo Define se a listagem exibirá o combo para escolha de itens por página
  212.          */
  213.         private $boolRegNumCombo;
  214.         /**
  215.          * @var boolean $boolIrParaCombo Define se a listagem deve apresentar o combo com a listagem de páginas
  216.          */
  217.         private $boolIrParaCombo true;
  218.         /**
  219.          * @var boolean $boolFiltroLetras Define se haverá links para filtragem por letras
  220.          */
  221.         private $boolFiltroLetras false;
  222.         /**
  223.          * @var string $strFiltroLetras Armazena o formato dos links para filtragem por letras
  224.          *  caso diferente do padrão 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','Todas'
  225.          */
  226.         private $strFiltroLetras;
  227.  
  228.         /**
  229.          * @var boolean $_useUserDb define se o adodb deve utilizar a conexão
  230.          *  com a base de usuários para este objeto.
  231.          */
  232.         protected $_useUserDb = true;
  233.         /**
  234.          * @var object $instance instância da classe
  235.          */
  236.         private static $instance null;
  237.         /**
  238.          * @var string $_strTable Armazena o nome da tabela como instância salva na sessão
  239.          */
  240.         private $_strTable;
  241.         /**
  242.          * @var string $strObjName nome do objeto a ser instanciado.
  243.          */
  244.         public $strObjName;
  245.  
  246.         /**
  247.          * Construtor da classe pager
  248.          * iniciando as variaveis
  249.          * @param integer $idListagem identificador da listagem
  250.          * @param string $strPkTabela PK da tabela dos dados
  251.          */        
  252.         public function __construct($idListagem$strPkTabela){
  253.             $this->idListagem    $idListagem;
  254.             $this->strPkTabela    $strPkTabela;
  255.         }
  256.  
  257.         /**
  258.          * Define o valor de uma variável interna à classe
  259.          * @param string $strVarName nome da variável
  260.          * @param mixed $mixVarValue valor da variável
  261.          */
  262.         public function __set($strVarName$mixVarValue){
  263.             $this->$strVarName $mixVarValue;
  264.         }
  265.  
  266.         /**
  267.          * Retorna o valor de uma variável
  268.          * @param string $strVarName o nome da variável desejada
  269.          */
  270.         public function __get($strVarName){
  271.             return $this->$strVarName;
  272.         }
  273.  
  274.         /**
  275.          * Singleton
  276.          * @param string $strTable identificador da listagem a ser recuperada da sessão
  277.          * @param integer $idListagem identificador da listagem caso necessite criá-la
  278.          * @param string $strPkTabela PK da tabela
  279.          */
  280.         public static function getInstance($strTable$idListagem$strPkTabela){
  281.             if (self::$instance == null){
  282.                 if(isset($_SESSION['listas'][$strTable][$idListagem])){
  283.                     self::$instance unserialize($_SESSION['listas'][$strTable][$idListagem]);
  284.                     self::$instance->__construct($idListagem$strPkTabela);
  285.                 }else{
  286.                     self::$instance new pager($idListagem$strPkTabela);
  287.                 }
  288.             }
  289.             self::$instance->_strTable $strTable;
  290.             return self::$instance;
  291.         }
  292.  
  293.         /**
  294.          * Calcula todos os dados de paginação. O retorno:
  295.          * @param mixed $mixDados query sql para coleta dos dados ou os próprios dados
  296.          * @return object próprio objeto pager com todas as suas propriedades.
  297.          */
  298.         public function getLista($mixDados){
  299.  
  300.             $this->mixDados $mixDados;
  301.  
  302.             $this->_ordenar();
  303.  
  304.             $this->_setRegTotal();
  305.             $this->_setPagUltima();
  306.  
  307.             $this->_setRegInicial();
  308.             $this->_setRegFinal();
  309.  
  310.             $this->_setPagProxima();
  311.             $this->_setPagAnterior();
  312.             $this->_setPagPrimeira();
  313.  
  314.             $this->carregaPaginacao();
  315.             $_SESSION['listas'][$this->_strTable][$this->idListagemserialize($this);
  316.             return $this;
  317.         }
  318.  
  319.         /**
  320.          * Define as ações sobre as linhas selecionadas nos checkboxes
  321.          * @param $arrAcoes array com as ações
  322.          */
  323.         public function setComboAcoes($arrAcoes){
  324.             if(!empty($arrAcoes)){
  325.                 $this->arrComboAcoes $arrAcoes;
  326.                 $this->boolCheck true;
  327.             }
  328.         }
  329.  
  330.         /**
  331.          * Define a coluna pela qual ordenar a listagem por padrão inicialmente
  332.          * @param string $strOrdCampo nome do campo pelo qual ordenar
  333.          */
  334.         public function setDefaultOrdCampo($strOrdCampo){
  335.             if(is_null($this->strOrdCampo)){
  336.                 $this->strOrdCampo $strOrdCampo;
  337.             }
  338.         }
  339.  
  340.         /**
  341.          * Retorna o nome do campo para contagem de registros, para paginação
  342.          * @return string $alvo;
  343.          * 
  344.          *  <code>
  345.          *      contadorRegistro($strSql);
  346.          *  </code>
  347.          */
  348.          /*public function contadorRegistros($str){
  349.             $str    = preg_replace("/\n/", '', $str);                    
  350.             $str    = preg_replace("/[ \t]+/", ' ', $str);
  351.             $arrTmp    = preg_split('/ FROM /', $str);
  352.  
  353.             $arrReturn    = array();
  354.             $arrAlvo    = array();
  355.  
  356.             $fim    = 0;
  357.             $i        = 0;
  358.             $a        = 0; // Parêntesis abertos
  359.             $f        = 0; // Parêntesis fechados            
  360.             if(is_array($arrTmp)){
  361.                 foreach($arrTmp as $tmp){
  362.                     $countParentAbre    = preg_match_all('/\(/', $tmp, $void);
  363.                     $countParentFecha    = preg_match_all('/\)/', $tmp, $void);
  364.                     $a += $countParentAbre;
  365.                     $f += $countParentFecha;
  366.                     if(!$fim){
  367.                         $arrAlvo[] = $arrTmp[$i];
  368.                         $fim = $a <= $f ? 1 : 0;
  369.                     }else{
  370.                         break;
  371.                     }
  372.                     $i++;
  373.                 }
  374.             }
  375.             $strAlvo = join(' FROM ', $arrAlvo);
  376.             $strAlvo = preg_replace('/^SELECT /i', '', $strAlvo);
  377.             return $strAlvo;
  378.         }*/
  379.         
  380.          /**
  381.          * Retorna o array de registros paginado, para ser utilizado na paginação das listagens
  382.          * 
  383.          * <code>
  384.          * $objList0->mixDados = $strSql;
  385.          * $objList0->strPkTabela = "PK_TABELA";
  386.          * $arrDadosEnviarAoSmarty = $objList0- >carregaPaginacao();
  387.          * </code>
  388.          */
  389.         public function carregaPaginacao(){
  390.  
  391.             if(is_array($this->mixDados)){                   
  392.                 /**
  393.                   * Caso a origem dos dados seja de um array de valores, fatia
  394.                   */
  395.                 $this->intRegTotal count($this->mixDados);
  396.                 $this->mixDados array_chunk($this->mixDados$this->intRegPagina);
  397.                 $this->arrDados $this->mixDados $this->mixDados[$this->intPag 1];
  398.  
  399.             }else{
  400.                 /**
  401.                  * Caso a origem dos dados seja de uma query, colhe-os
  402.                  */
  403.  
  404.                 $db &$this->_getDb();
  405.                 $save $db->SetFetchMode(ADODB_FETCH_ASSOC);
  406.                 $arrResultSet $db->SelectLimit($this->mixDados$this->intRegPagina$this->intRegInicial 1);
  407.                 $db->SetFetchMode($save);
  408.                 $arrRegistros array();
  409.  
  410.                 if($arrResultSet){
  411.                     $iReg=0;
  412.                     while (!$arrResultSet->EOF{
  413.                         $obj &new $this->strObjName();
  414.                         $this->_formataDatas($arrResultSet->fields);
  415.                         $obj->Set($arrResultSet->fields);
  416.                         $arrRegistros[$iReg$obj;
  417.                         $arrResultSet->MoveNext();
  418.                         $iReg++;
  419.                     }
  420.                 }
  421.                 $this->arrDados $arrRegistros;
  422.             }
  423.             $this->intRegPaginaAtual count($this->arrDados);
  424.         }
  425.  
  426.         /**
  427.          * Calcula a quantidade total de registros
  428.          */
  429.         private function _setRegTotal(){
  430.             if(is_array($this->mixDados)){
  431.                 $this->intRegTotal count($this->mixDados);
  432.             }else{
  433.                 $db &$this->_getDb();
  434.                 $strFrom            preg_replace('/.*FROM/''FROM'$this->mixDados);
  435.                 $strContador        'SELECT COUNT('.$this->strPkTabela.') AS TOTAL '.$strFrom;
  436.                 $save $db->SetFetchMode(ADODB_FETCH_ASSOC);
  437.                 $arrQuantRegistros    $db->GetRow($strContador);
  438.                 $db->SetFetchMode($save);
  439.                  $this->intRegTotal    = (int) $arrQuantRegistros["TOTAL"];
  440.             }
  441.         }
  442.  
  443.         /**
  444.          * Retorna o registro inicial da pagina,
  445.          */
  446.         private function _setRegInicial(){
  447.             if(!$this->intPag){
  448.                 $this->intRegInicial 0;
  449.             }elseif($this->intPag == 1){
  450.                 $this->intRegInicial = (int) 1;
  451.             }else{
  452.                 $this->intRegInicial = (int) ((($this->intPag 1$this->intRegPagina1);
  453.             }
  454.         }
  455.  
  456.         /**
  457.          * Define o número do registro final da página atual
  458.          */
  459.         private function _setRegFinal(){
  460.             $this->intRegFinal = (int) $this->intRegInicial $this->intRegPagina 1;
  461.             if($this->intRegFinal $this->intRegTotal){
  462.                 $this->intRegFinal = (int) $this->intRegTotal;
  463.             }
  464.         }
  465.  
  466.         /**
  467.          * Define o numero total de paginas
  468.          */
  469.         private function _setPagUltima(){
  470.             if(!isset($this->intRegTotal|| !isset($this->intRegPagina) ){
  471.                 trigger_error('setPagUltima não tem intRegTotal nem intRegPagina: '.$this->intRegTotal.' e '.$this->intRegPagina);
  472.             }else{
  473.                 $this->intPagTotal $this->intPagUltima = (int) ceil($this->intRegTotal/$this->intRegPagina);
  474.                 if($this->intPag == $this->intPagUltima){
  475.                     $this->intPagUltima null;
  476.                 }elseif($this->intPag $this->intPagUltima){
  477.                     $this->intPag        $this->intPagUltima;
  478.                     $this->intPagUltima    null;
  479.                 }
  480.             }
  481.         }
  482.  
  483.         /**
  484.          * Define a existência ou não do link para a primeira página
  485.          * Caso esteja na primeira página define como null.
  486.          */
  487.         private function _setPagPrimeira(){
  488.             if(!$this->intPag || $this->intPag == 1){
  489.                 $this->intPagPrimeira null;
  490.             }else{
  491.                 $this->intPagPrimeira = (int) 1;
  492.             }
  493.         }
  494.  
  495.         /**
  496.          * Define o numero da pagina anterior,
  497.          */
  498.         private function _setPagAnterior(){
  499.             if($this->intPag 1){
  500.                 $this->intPagAnterior = (int) $this->intPag 1;
  501.             }else{
  502.                 $this->intPagAnterior null;
  503.             }
  504.         }
  505.  
  506.         /**
  507.          * Define o numero da próxima pagina,
  508.          */
  509.         private function _setPagProxima(){
  510.             if($this->intPagUltima){
  511.                 if($this->intPag $this->intPagUltima){
  512.                     $this->intPagProxima = (int) $this->intPag 1;
  513.                 }else{
  514.                     $this->intPagProxima null;
  515.                 }
  516.             }else{
  517.                 $this->intPagProxima null;
  518.             }
  519.         }
  520.  
  521.         /**
  522.          * Formata datas de acordo com a i18n
  523.          * @param array $registro 
  524.          */
  525.         private function _formataDatas(&$registro){
  526.             switch($_SESSION['lang']){
  527.                 case 'en':
  528.                     $formatoData '%b %e, %Y at %R';
  529.                     break;
  530.                 case 'pt':
  531.                 default:
  532.                     $formatoData '%e/%b/%Y, %R';
  533.                     break;
  534.             }
  535.             foreach($registro as $campo => $valor){
  536.                 if(strpos($campo'TS'=== 0){
  537.                     $registro[$campostrftime($formatoDatastrtotime($valor));
  538.                 }
  539.             }
  540.         }
  541.  
  542.         /**
  543.          * Ordena e filtra $arrResult
  544.          * <code>
  545.          * $objList0->mixDados        = $strSql;
  546.          * $objList0->strPkTabela    = "PK_TABELA";
  547.          * $objList0->strOrdCampo    = "UPPER(ASCII(NO_TABELA_ORDENAR))";
  548.          * $arrDadosEnviarAoSmarty    = $objList0- >carregaPaginacao();
  549.          * </code>
  550.          */
  551.         private function _ordenar(){
  552.             if(!is_array($this->mixDados)){
  553.                 $strSqlFiltro '';
  554.                 if(!empty($this->strFiltro)){
  555.                     $this->arrFiltro explode(","$this->strFiltro);
  556.                     $arrSqlFiltro array();
  557.                     foreach($this->arrFiltro as $filtro){
  558.                         $arrSqlFiltro['UPPER('.$this->strOrdCampo.') LIKE UPPER("'.$filtro.'%")';
  559.                     }
  560.                     if(strpos($this->mixDados'WHERE')){
  561.                         $strSqlFiltro ' AND ('.join($arrSqlFiltro' OR ').')';
  562.                     }else{
  563.                         $strSqlFiltro ' WHERE ('.join($arrSqlFiltro' OR ').')';
  564.                     }
  565.                 }
  566.                 $this->mixDados .= $strSqlFiltro;
  567.                 if($this->strOrdCampo){
  568.                     $this->mixDados $this->mixDados .' ORDER BY '$this->strOrdCampo .' '$this->strOrdSentido;
  569.                 }
  570.             }
  571.         }
  572.  
  573.         /**
  574.          * Retorna o objeto de banco de dados a utilizar
  575.          */
  576.         private function _getDb(){
  577.             if($this->_useUserDb){
  578.                 $this->_dbUser();
  579.                 return $this->dbUser;
  580.             }else{
  581.                 $this->_db();
  582.                 return $this->db;
  583.             }
  584.         }
  585.  
  586.     }
  587. ?>

Documentation generated on Sun, 09 Mar 2008 23:52:41 -0300 by phpDocumentor 1.4.0

SourceForge.net Logo Support This Project