domingo, 17 de junio de 2007

Componente para mantener la información de paginado

Después de darle como muchas vueltas se me ha ocurrido escribir un componente para gestionar la información de paginado entre vistas. La idea es la siguiente:

Supongamos que estoy en una típica vista index que muestra una tabla de registros paginada y que me encuentro en la página "p" de la misma.

Entonces voy y pulso un botón o enlace para editar un registro cualquiera de esa página. Al terminar de editar ¿a dónde vuelvo? En principio a la vista de index (si lo he especificado así), pero ¿a qué página?.

Si no especifico la página de origen normalmente volveré a la página 1 y no a la "p" que es en la que estaba, lo cual es un engorro, por muchas razones que te puedes suponer.

El componente paging que he escrito básicamente permite a la acción index "acordarse" de qué página estaba mostrando la última vez.

Instrucciones de uso

  1. Copiar el código al archivo /app/controllers/components/paging.php
  2. En el controller, añadir Paging a la lista de components
  3. En la acción en que queremos usarlo, llamar al método $this->Paging->manage()
  4. Opcionalmente puedes pasarle el nombre del modelo al que debe referirse la información de paginación


Por si no queda claro, la cosa es así


class MiControlador extends AppController {

var $components = array ('Paging');

function index () {
$this->Paging->manage();
}

}


Cómo funciona

Básicamente, el componente comprueba si hay información de paginación almacenada en la sesión y la lee si es así.

Seguidamente, comprueba si hay información en la URL. Esta información tiene prioridad porque Controller::paginate() la utiliza si está disponible para definir los límites de la búsqueda.

Finalmente, el componente combina la información procedente de todas las fuentes para determinar el nuevo contenido de la variable Controller::paginate y también lo guarda en la sesión.

La información se guarda de forma específica para cada controlador.

El código

He puesto el código en CakeBin, pero como no sé si durará, intento copiarlo aquí:

<?php
/**
* Component to manage paging info between reloads
*
* Created by Fran Iglesias on 2007-06-17.
* @version: 0.1
* Copyright (c) 2007 Fran Iglesias. All rights reserved.
**/

/**
* Usage:
*
* 1. Put paging.php into your /app/controllers/components folder
* 2. Add 'Paging' to your controller::components array
* 3. Call $this->Paging->manage () into the action that retrieves data using paginate()
*/

class PagingComponent extends Object {
var $components = array ('Session');
var $controller = false;

function startup (&$controller) {
$this->controller = $controller;
}

/**
* Manage pagination data retrieving and storing into session as needed,
* Paging info passed via URL arguments takes precedence over session data
*
* @params string $forModel Specify a model name to manages its paging data
* @return void
* @author Frankie
**/
function manage ($forModel = null) {
// Determines a model name to work
if (in_array ($forModel, $this->controller->modelNames)) {
$model = $forModel;
} else {
$model = $this->controller->modelNames[0];
}
// Check if there is paging info in the Session and read it
$sessionVarName = $this->controller->name . '_paging_info';
if ($this->Session->check ($sessionVarName)) {
$pagingInfoFromSession = $this->Session->read ($sessionVarName);
} else {
$pagingInfoFromSession = array ();
}
// Check if there is paging info in passedArgs and build a paginate-like record with it
$pagingArgs = $this->_getPagingFromArgs ();
// Set paging info based on paging info from session and form arguments
if (isset ($pagingInfoFromSession[$model])) {
$paging = am($pagingInfoFromSession[$model], $pagingArgs);
} else {
$paging = $pagingArgs;
}
// Pass the new paging info to controller->paginate variable
if (isset ($this->controller->paginate[$model])) {
$this->controller->paginate[$model] = am($this->controller->paginate[$model], $paging);
} else {
$this->controller->paginate[$model] = am ($this->controller->paginate, $paging);
}
// Store new paging info into Session
$this->Session->write ($sessionVarName, $this->controller->paginate);
return true;
}

/**
* Helper to read pagination info from URl if there is any
*
* @return void
* @author Frankie
**/

function _getPagingFromArgs () {
if (!isset ($this->controller->passedArgs)) {
return array ();
}
$paginate = array ();
if (isset ($this->controller->passedArgs['page'])) {
$paginate['page'] = $this->controller->passedArgs['page'];
}
if (isset ($this->controller->passedArgs['limit'])) {
$paginate['limit'] = $this->controller->passedArgs['limit'];
}
if (isset ($this->controller->passedArgs['sort']) && isset ($this->controller->passedArgs['direction'])) {
$paginate['order'][$this->controller->passedArgs['sort']] = $this->controller->passedArgs['direction'];
}
return $paginate;
}
}

?>

No hay comentarios: