Después de búsquedas incansables en internet no logré encontrar un solo ejemplo sobre la realización de la paginación en Codeigniter usando consultas personalizadas, solo ejemplos de mostrar tablas de la base de datos, lo cual es bastante fácil. Después de varios días de trabajo, logré realizar dicha paginación y aqui les pongo el ejemplo esperando que les sirva.
En mi caso siempre uso una libreria intermedia que recoge los valores del formulario, estos llegan como un arreglo a la libreria y a partir de esos valores de los campos pues formo la consulta que voy a enviar al modelo. LO MAS IMPORTANTE ES que esa consulta formada ya debe llevar los valores del limit que es el punto principal de la paginación. Me explico: Revisando todos los ejemplos publicados en Internet, además de que todo el mundo explicaba la vía fácil de paginar, usaban el active record para la realización del limit en la consulta, el cual no funciona si se trabaja con un sql formado y que depende de distintas variables cada vez. Entonces aquí pongo los detalles de lo que hice y que me funciona perfecto.
Un detalle importante, de hecho crucial para realizar esto, es que cuando es CI declaramos $this->db->get('mitabla', 10, 20); Codeigniter se encarga de invertir los valores con el active record, por tanto si estamos haciendo una consulta personalizada a la cual debemos pasarle los valores del limit, estos valores deben ir invertidos. Por tanto si en el ejemplo clásico se declaraba el limite pasandole $config['per_page'],$this->uri->segment(3), en nuestro caso estos valores iran invertidos, sería $this->uri->segment(3), $config['per_page'].
ejemplo_lib.php /*Esto es lo principal de la librería*/
public function filtro($datos, $porpagina, $urisegment)
{
$limit = " LIMIT ";
$limit .= ($urisegment)?($urisegment . ', '):('');
$limit .= $porpagina;
Lo que hago en la parte de arriba es verificar que venga valor por el campo del urisegment pues en el primer caso de la paginación la uri queda misitio.com/filtro/ sin ningún valor.
$where = "1";
$dia_min = $datos['diaMin'];
$dia_max = $datos['diaMax'];
$accion.= $dia_min.", ".$dia_max.", ";
$where .= " AND date mayorigual $dia_min AND date menoigual $dia_max"
$sql = "SELECT * FROM message ";
$where2 = $where;
$where .= $limit;
$sql_total = $sql;
$sql .= "WHERE ".$where;
$sql_total .= "WHERE ".$where2;
Aqui lo que hice fue crear mi consulta personalizada según los datos que vinieron de la vista, les pongo solo un ejemplo, ustedes pueden poner el sql directo. Dentro de $sql quedará mi consulta ya con el $limit concatenado de forma tal que se pueda realizar la paginación sin problema ninguno. En $sql_total lo que hago es crear un sql que cuente la cantidad de valores total sin limit para poder obtener lo que será el $config['num_rows'], pues de lo contrario no tendré valor para crear los links de la paginación.
$datos_retorno['consulta'] = $this->_ci->ejemplo_mdl->filtro($sql);
$datos_retorno['total'] = $this->_ci->ejemplo_mdl->contar_filtro($sql_total);
return $datos_retorno;
}
ejemplo_mdl.php /*Métodos principales del modelo*/
public function filtro($sql)
{
return $this->db->query($sql)->result_array();
}
Este método me devuelve el arreglo de lo que se encontró en la base de datos ya con el limit incluído listo todo para la paginación.
public function contar_filtro($sql)
{
return $this->db->query($sql)->num_rows();
}
Este método me devuelve el número de filas afectadas el cual necesito para realizar la paginación.
ejemplo.php /*Esta es la controladora*/
public function filtro()
{
$per_page = 24;
$this->template->set_title('Filtro general');
if ($this->input->is_post_back())
{
$datos = $this->input->all_post();
$this->session->set('general', serialize($datos));
}
else
{
$datos = unserialize($this->session->get('general'));
}
Lo que hago en esta parte anterior es controlar que siempre me lleguen datos a la controladora para poder realizar la paginación, pues en el caso de cuando se llaman a las demás páginas, que no es la página donde se muestran los primeros valores ya yo no estaría controlando los datos por post, sino que serían los mismos que ya guardé en la variable de sesión y solo sería usarlos para armar los demás links. (Espero se me entienda)
$reporte = $this->inicio_lib->filtro($datos, $per_page, $this->uri->segment(3));
$this->load->library('pagination');
$config['per_page'] = $per_page;
$config['uri_segment'] = '3';
$config['num_links'] = '8';
$config['base_url'] = site_url('ejemplo/filtro/');
$config['total_rows'] = $reporte['total'];
$this->pagination->initialize($config);
$this->template->set_data('pag', $this->pagination->create_links());(aqui creo una variable para pasar la paginación a la vista)
$this->template->set_data('consulta', $reporte['consulta']); (aqui controlo los valores que me interesa mostrar en la vista)
$this->template->set_data('titulo', $reporte['titulo']);
$this->template->set_data('fecha1', $reporte['fecha1']);
$this->template->set_data('fecha2', $reporte['fecha2']);
$this->template->set_layout('tablas'); (cambio al layout de tablas para mostrar la información)
$this->template->render('ejemplo_informacion'); (y rendereo mi vista correspondiente)
}
ejemplo_informacion.php /*Finalmente en mi vista declaro lo necesario para mostrar la paginación*/
(Pongo esto justo después de donde termina la tabla donde se muestran los resultados paginados)
($pag es la variable que declaré en la controladora que es lo mismo que $this->pagination->create_links();)
Con esto funciona perfectamente la paginación a consultas personalizadas, espero les sirva, y si tienen dudas pregunten, la idea es ayudar. :)