Depois de longa pausa, cá estou. Bom, existem alguns tutoriais e artigos por aí, inclusive no wiki do CodeIgniter explicando como usar uma paginação mais coerente. Digo isso pois a paginação atual do CI trabalha com o offset do SQL, e não com o número da página em si. O código que uso hoje foi retirado do wiki, já o sistema de busca integrado eu mesmo desenvolvi pois não achei nada no wiki.Bom, vamos às modificações:
Primeiro, no arquivo original temos a funcao create_links(). Agora ela terá um arqumento “$search”, que será passado após o numero de paginas, por exemplo http://www.site.com.br/produtos/pagina/2/notebook-sony. Alterei toda a identação da classe de Paginação, não consigo trabalhar com o estilo de Allman (mais info: wikipedia). Analisando o código inteiro, não preciso me prolongar muito, eu simplesmente adicionei um parâmetro na função de criar links, para concatenar o resultado da busca nos links das páginas.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); /** * CodeIgniter * * An open source application development framework for PHP 4.3.2 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team * @copyright Copyright (c) 2008, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 * @filesource */ // ------------------------------------------------------------------------ /** * Pagination Class * * @package CodeIgniter * @subpackage Libraries * @category Pagination * @author ExpressionEngine Dev Team * @link http://codeigniter.com/user_guide/libraries/pagination.html */ class CI_Pagination { var $base_url = ''; // The page we are linking to var $total_rows = ''; // Total number of items (database results) var $per_page = 10; // Max number of items you want shown per page var $num_links = 2; // Number of "digit" links to show before/after the currently viewed page var $cur_page = 0; // The current page being viewed var $first_link = '‹ First'; var $next_link = '>'; var $prev_link = '<'; var $last_link = 'Last ›'; var $uri_segment = 3; var $full_tag_open = ''; var $full_tag_close = ''; var $first_tag_open = ''; var $first_tag_close = ' '; var $last_tag_open = ' '; var $last_tag_close = ''; var $cur_tag_open = ' <b>'; var $cur_tag_close = '</b>'; var $next_tag_open = ' '; var $next_tag_close = ' '; var $prev_tag_open = ' '; var $prev_tag_close = ''; var $num_tag_open = ' '; var $num_tag_close = ''; var $page_query_string = FALSE; var $query_string_segment = 'per_page'; /** * Constructor * * @access public * @param array initialization parameters */ function CI_Pagination($params = array()) { if (count($params) > 0) { $this->initialize($params); } log_message('debug', "Pagination Class Initialized"); } // -------------------------------------------------------------------- /** * Initialize Preferences * * @access public * @param array initialization parameters * @return void */ function initialize($params = array()) { if (count($params) > 0) { foreach ($params as $key => $val) { if (isset($this->$key)) { $this->$key = $val; } } } } // -------------------------------------------------------------------- /** * Generate the pagination links * * @access public * @return string */ function create_links($search='') { if ($search!='') $search = '/'.$search; // If our item count or per-page total is zero there is no need to continue. if ($this->total_rows == 0 OR $this->per_page == 0) { return ''; } // Calculate the total number of pages $num_pages = ceil($this->total_rows / $this->per_page); // Is there only one page? Hm... nothing more to do here then. if ($num_pages == 1) { return ''; } // Determine the current page number. $CI =& get_instance(); if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE){ if ($CI->input->get($this->query_string_segment) != 0){ $this->cur_page = $CI->input->get($this->query_string_segment); // Prep the current page - no funny business! $this->cur_page = (int) $this->cur_page; } } else { if ($CI->uri->segment($this->uri_segment) != 0) { $this->cur_page = $CI->uri->segment($this->uri_segment); // Prep the current page - no funny business! $this->cur_page = (int) $this->cur_page; } } if ( ! is_numeric($this->cur_page)) { $this->cur_page = 0; } if ($this->cur_page==0) { $this->cur_page = 1; } // Is the page number beyond the result range? // If so we show the last page if ($this->cur_page > $this->total_rows) { $this->cur_page = ($num_pages - 1) * $this->per_page; } $uri_page_number = $this->cur_page; // Calculate the start and end numbers. These determine // which number to start and end the digit links with $start = (($this->cur_page - $this->num_links) > 0) ? $this->cur_page - ($this->num_links - 1) : 1; $end = (($this->cur_page + $this->num_links) < $num_pages) ? $this->cur_page + $this->num_links : $num_pages; // Is pagination being used over GET or POST? If get, add a per_page query // string. If post, add a trailing slash to the base URL if needed if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE) { $this->base_url = rtrim($this->base_url).'&'.$this->query_string_segment.'='; } else { $this->base_url = rtrim($this->base_url, '/') .'/'; } // And herwe go... $output = ''; // Render the "First" link if ($this->cur_page > $this->num_links) { $output .= $this->first_tag_open.'<a href="'.$this->base_url.'1'.$search.'">'.$this->first_link.'</a>'.$this->first_tag_close; } // Render the "previous" link if (($this->cur_page - $this->num_links) >= 0) { $i = $this->cur_page - 1; if ($i == 0) $i = ''; $output .= $this->prev_tag_open.'<a href="'.$this->base_url.$i.$search.'">'.$this->prev_link.'</a>'.$this->prev_tag_close; } // Write the digit links for ($loop = $start -1; $loop <= $end; $loop++) { $i = ($loop * $this->per_page) - $this->per_page; if ($i >= 0) { if ($this->cur_page == $loop) { $output .= $this->cur_tag_open.$loop.$this->cur_tag_close; // Current page } else { $n = ($i == 0) ? '1' : $loop; $output .= $this->num_tag_open.'<a href="'.$this->base_url.$n.$search.'">'.$loop.'</a>'.$this->num_tag_close; } } } // Render the "next" link if ($this->cur_page < $num_pages) { $output .= $this->next_tag_open.'<a href="'.$this->base_url.($this->cur_page + 1).$search.'">'.$this->next_link.'</a>'.$this->next_tag_close; } // Render the "Last" link if (($this->cur_page + $this->num_links) < $num_pages) { $i = $num_pages; $output .= $this->last_tag_open.'<a href="'.$this->base_url.$i.$search.'">'.$this->last_link.'</a>'.$this->last_tag_close; } // Kill double slashes. Note: Sometimes we can end up with a double slash // in the penultimate link so we'll kill all double slashes. $output = preg_replace("#([^:])//+#", "\\1/", $output); // Add the wrapper HTML if exists $output = $this->full_tag_open.$output.$this->full_tag_close; return $output; } } // END Pagination Class /* End of file Pagination.php */ /* Location: ./system/libraries/Pagination.php */ |
Basta copiar o arquivo acima dentro de sua pasta application/libraries, assim o CI usará o da sua aplicação ao inves da classe encontrada no core. Bom, no controler, eu uso sempre estas 3 funções:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | function index() { // Forçando o uso da funcao pagina... redirect('produtos/pagina/1'); } /* Function busca() * Funcao de busca do controller. Imagine que seja o controler Produto, * então a action do formulário seria algo como action="produto/busca" */ function busca() { $termos = array(); /* * Aqui você deve ajustar o seu "uri segment", de acordo com a sua aplicação, caso * seu controller esteja dentro de uma pasta física no servidor, enfim... */ if ($this->uri->segment(3)!='') { /* * Neste if, estou suponto que eu já tenho uma procura em andamento */ $search = $this->uri->segment(4); $search = str_replace(' ','-',$search); acento_nao($search); // Função para retirar acentos, use uma qualquer // Preparando array $aux = explode('-',$search); foreach($aux as $key => $valor) { $termos[] = $valor; } } else { /* * Aqui eu recupero o valor do campo do formulario (valor), e caso * seja duas ou mais palavras, separo por hífen. */ $search = $this->input->post('valor'); $search = str_replace(' ','-',$search); acento_nao($search); // Função para retirar acentos, use uma qualquer // Preparando array $aux = explode('-',$search); foreach($aux as $key => $valor) { $termos[] = $valor; } } /* * Redirecionando para o controller de produto. * Repare que nesta funcao busca(), apesar do nome, * eu não faço nenhuma busca, apenas formato a URL * e redireciono para a funcao "pagina", que é quem * faz todo o trabalho. */ redirect('produto/pagina/1/'.$search); } function pagina($page='',$termos='') { /* * Se não existe nenhum valor de página, então eu forço a usar valor 1, * e seguro qualquer mensagem de alteração de dados, ex: "Produto X alterado com sucesso" */ if ($page=='') { $this->session->keep_flashdata('mensagem'); redirect('produto/pagina/1'); } /* * Na minha aplicação, o segmento 4 é a string de busca */ if ($this->uri->segment(4)!='') { $termos = $this->uri->segment(4); } $this->load->library('pagination'); $limit = 20; $offset = ($page-1)*$limit; if ($termos=='') { /* * Se não tenho nenhuma string pra procurar, sigo a busca normal no banco */ $this->db->limit($limit, $offset); $query = $this->db->get('produtos'); $data['total'] = $query->num_rows(); /* * Aqui eu defino o search como vazio, pois na view eu vou usar algo * como "buscando resultados para a busca "notebook sony". Se o $search * estiver vazio na view, então eu não exibo a mensagem. */ $search = ''; } else { /* * Preparando a busca, "recortando" o termos e inserindo em um LIKE * cada termo da busca */ $search = str_replace(' ','-',$termos); // Preparando array $busca = array(); $aux = explode('-',$search); foreach($aux as $key => $valor) { $busca[] = $valor; } /* * No exemplo em questão estou usando apenas UM campo (valor) no formulario, * mas procurando ao mesmo tempo em 3 campos, nome, codigo e descricao. * Voce pode adaptar pra vários campos, no entanto. */ $this->db->like('nome', $busca[0]); $this->db->or_like('codigo', $busca[0]); $this->db->or_like('descricao', $busca[0]); $tt = count($busca); if ($tt>0) { for ($j=1;$j<$tt;$j++) { $this->db->or_like('nome', $busca[$j]); $this->db->or_like('codigo', $busca[$j]); $this->db->or_like('descricao', $busca[$j]); } } /* * Aqui eu recupero o total de produtos, para exibir a mensagem * Exibindo X produtos de um total de Y. */ $query_tt = $this->db->get('produtos'); $this->db->like('nome', $busca[0]); $this->db->or_like('codigo', $busca[0]); $this->db->or_like('descricao', $busca[0]); $tt = count($busca); if ($tt>0) { for ($j=1;$j<$tt;$j++) { $this->db->or_like('nome', $busca[$j]); $this->db->or_like('codigo', $busca[$j]); $this->db->or_like('descricao', $busca[$j]); } } $this->db->limit($limit, $offset); $query = $this->db->get('produtos'); $data['total'] = $query_tt->num_rows(); } $config['base_url'] = base_url().INDEX.'produtos/pagina/'; $config['total_rows'] = $data['total']; $config['per_page'] = $limit; $config['uri_segment'] = 3; $config['num_links'] = 5; $this->pagination->initialize($config); $data['num_de_paginas'] = round($data['total'] / $limit); $data['produtos'] = $query; $this->load->view('administracao/admin',$data); } |
Bom, usando essa classe, seus links terão o seguinte formato:
http://www.site.com.br/produtos/pagina/13/notebook-sony
http://www.site.com.br/produtos/pagina/10/cannon-maquina-digital
Lembrando que eu nao testei, e provavelmente não funcionará com query strings!

{ 6 comments… read them below or add one }
legal, mas com esse seu highlight sintax ai acho que vai fica meio dificil de alguem copia o codigo e testar sua modificação da lib
Oie, estava com problemas de paginar uma query com filtros mas resolvi, lendo outros foruns e juntando informacoes segue o codigo:
// form.php
<form action="cconsultar/consultar” method=”post”>
Número Produto
Nome
————————————————
//cconsulta.php
function consultar($filtro = ‘Tjs=’, $start = 0){
// adicionando a biblioteca de paginacao
$this->load->library(‘pagination’);
if (empty($_POST)) {
$filtroUnserialize = unserialize(base64_decode($filtro));
}
else {
$filtroUnserialize = array( ‘codigo’ => $this->input->get_post(‘codigo’, TRUE),
array( ‘nome’ => $this->input->get_post(‘nome’, TRUE)
);
// coloque todos os campos do formulario que efetuou a pesquisa
}
$total = $this->Model->buscarPorParametrosCount($filtroUnserialize);
$filtroSerialize = base64_encode(serialize($filtroUnserialize));
$config_pagination['base_url'] = “/sitemas/index.php/cconsulta/consultar/{$filtroSerialize}/”;
$config_pagination['per_page'] = 50;
$config_pagination['uri_segment'] = 4;
$config_pagination['first_link'] = ‘‹ Primeira‘;
$config_pagination['last_link'] = ‘Última ›‘;
$config_pagination['prev_link'] = ‘<‘;
$config_pagination['next_link'] = ‘>‘;
$config_pagination['full_tag_open'] = ”;
$config_pagination['full_tag_close'] = ”;
$config_pagination['total_rows'] = $total;
$this->pagination->initialize($config_pagination);
$temp['pedidos'] = $this->Model->buscarPorParametros($filtroUnserialize, $config_pagination['per_page'], intval($start));
$temp['paginacao'] = $this->pagination->create_links();
$this->load->view(‘consultar_pedido’, $temp);
}
————————————————-
//consultar_pedido.php
//consultar_pedido.php
Boa sorte !!!
//consultar_pedido.php
Esqueci
foreach ($produtos as $produto){
echo $produto['codigo']. $produto['nome'];
}
echo $paginacao;
Olá Amigo
Gostaria de saber se você atualizou este para a versão 2.0 do CI. Estava utilizando, mas quando mudou fiquei na mão!
Não atualizei, na verdade vou iniciar meu primeiro site em CI2 esta semana, e talvez eu precise atualizar esse artigo tambem!