------------------------------------------------------------------------------- $Id$ -----------------------------------------------------------------------------*/ require_once 'DB.php'; require_once 'MECON/DB/Pager.php'; require_once 'MECON/HTML/Error.php'; require_once 'MECON/HTML/Link.php'; require_once 'MECON/HTML/Tabla.php'; /** * Libreria para le manejo de las tablas de los sistemas de intranet. * */ class MECON_HTML_TablaDB extends MECON_HTML_Tabla { /** * Descripción de los elementos listados. * Se utiliza en mensajes del paginador y otros mensajes. */ var $_desc = 'resultados'; /** * Datos a agregar delante de cada fila que se agregue desde una base de datos. * Cada elemento del array es a su vez un array cuyo primer elemento es el * formato del texto a agregar (tipo printf()) y el segundo es un array con los * campos de la DB a utilizar para ese formato en una fila dada. */ var $_prependRowsData = array(); /** * Datos a agregar al final de cada fila que se agregue desde una base de datos. * El formato es el mismo que el de _prependRowsData. */ var $_appendRowsData = array(); /** * Prefijo a usar para las variables GET que genera la tabla. */ var $_getVarPrefix = 'tabladb_'; /** * Constructor. * Puede recibir como parametro un string con los atributos que se * quieren dar a la tabla en cuestion. Estos atributos estan * seteados por default segun el archivo de configuracion. * Ademas puede recibir la indicacion de algun estilo en particular. * * @param string $desc Descripción de los elementos listados. * @param mixed $attrs Atributos diferentes a los estandares para la tabla * @param string $estilo Tipo de tabla * * @access public */ function MECON_HTML_TablaDB($desc = null, $attrs = null, $estilo = 'comun') { if ($desc) { $this->_desc = $desc; } parent::MECON_HTML_Tabla($attrs, $estilo); } /** * Establece el prefijo usado para las variables de GET que genera la tabla. */ function setGetVarPrefix($prefix) { $this->_getVarPrefix = $prefix; } /** * Obtiene el prefijo usado para las variables de GET que genera la tabla. */ function getGetVarPrefix() { return $this->_getVarPrefix; } /** * Agrega un páginador a la tabla, basado en un resultado de una base de datos. * Ejemplo: * @code * $tabla = new MECON_HTML_TablaDB('personas', array('width' => '100%')); * $result = $db->query('SELECT nombre, apellido FROM tabla'); * if (DB::isError($result)) { * die('Error'); * } * $pager = $tabla->addPager($result); * $tabla->addRow(array('Nombre', 'Apellido'), 'cabecera'); * $tabla->addRows($result, array('nombre', 'apellido')); * $tabla->display(); * @endcode * * @param DB_Result $result Resultado de una consulta de base de datos. * @param mixed $tipo Tipo de link(s) a agregar. Puede ser: * * Puede pasarse uno solo como un string o varios como un * array. Si se pasa 'todo', se incluyen todos. * Si se pasa null, se incluyen 'anterior', * 'siguiente' y 'paginas'. * @param mixed $link Dirección a la que apuntan los links generados. Puede * ser un MECON_HTML_Link (para poder pasar variables por * GET) o un string. * @param int $limit Parámetro usado para crear el MECON_DB_Pager. * @param int $maxpages Parámetro usado para crear el MECON_DB_Pager. * @param string $getvar Nombre de la variable GET a usar para indicar el número * de página actual (se le pone el \ref setGetPrefix prefijo) * * @return MECON_DB_Pager Pager que se puede usar para realizar los fetch de * los resultados de la página actual. * * @see MECON_DB_Pager. */ function addPager($result, $tipo = null, $link = null, $limit = 10, $maxpages = 21, $getvar = 'from') { // Creo el pager con el resultado. $pager = new MECON_DB_Pager($result, @$_GET[$this->_getVarPrefix.$getvar], $limit, $maxpages); // Obtengo un link válido. if (!$link) { $link = @$_SERVER['PHP_SELF']; } if (is_string($link)) { $link = new MECON_HTML_Link($link, ''); } // Si es el tipo por defecto pone paginador nada más. if (!$tipo) { $tipo = array('anterior', 'paginas', 'siguiente'); } // Convierte tipo a array. if (!is_array($tipo)) { $tipo = array($tipo); } // Si se quiere mostrar todas las decoraciones del paginador. if (in_array('todo', $tipo)) { $tipo = array('anterior', 'paginas', 'siguiente', 'total', 'info'); } // Me fijo si tiene cada uno de los elementos y los agrego. if (in_array('anterior', $tipo) and $pager->numRows() and $pager->currentpage != 1) { $link->setGetVar($this->_getVarPrefix.$getvar, $pager->prev); $this->addLink('anterior', $link); } if (in_array('siguiente', $tipo) and $pager->numRows() and $pager->currentpage != $pager->numpages) { $link->setGetVar($this->_getVarPrefix.$getvar, $pager->next); $this->addLink('siguiente', $link); } if (in_array('paginas', $tipo) and $pager->numRows() and $pager->numpages > 1) { $from = @$_GET[$this->_getVarPrefix.$getvar]; $pags = ''; $lnk = $link->getContents(); foreach ($pager->pages as $page => $start_row) { if ($start_row == $from) { $pags .= $page; } else { $link->setGetVar($this->_getVarPrefix.$getvar, $start_row); $link->setContents($page); $pags .= $link->toHtml(); } if ($page != $pager->lastpage) { $pags .= ' | '; } } $link->setContents($lnk); $this->updatePie($pags, 'centro'); } if (in_array('total', $tipo) and $pager->numRows()) { $this->updateCabecera("Se encontraron {$pager->numrows} {$this->_desc}.", 'izquierda'); } if (in_array('info', $tipo) and $pager->numRows()) { $this->updateCabecera("'Página {$pager->currentpage} de {$pager->numpages} - " . "{$pager->limit} {$this->_desc} por página.", 'derecha'); } return $pager; } /** * Agrega filas desde el resultado de una consulta a una base de datos. * Si no hay resultados, muestra un mensaje. Dependiendo de si es se pasa * un objeto a usar o no, llama a addRowsObject() o addRowsResult() * respectivamente. * Ejemplo: * @code * @endcode * * @param DB_Result $result Resultados de una consulta. * @param array $campos Propiedades del objeto a mostrar. * @param mixed $obj Objeto a usar. Puede ser un objeto instanciado o un * string con el nombre de la clase. * * @see Ejemplo en addPager(); */ function addRows($result, $campos, $obj = null) { if ($result->numRows()) { if ($obj) { $this->addRowsObject($result, $campos, $obj); } else { $this->addRowsResult($result, $campos, $obj); } } else { $id = $this->addRow(array(new MECON_HTML_Error("No se encontraron {$this->_desc}."))); $this->updateCellAttributes($id, 0, array('colspan' => count($campos))); } } /** * Agrega filas usando un resultado. * * @param DB_Result $result Resultados de una consulta. * @param array $campos Campos de la base de datos a mostrar. */ function addRowsResult($result, $campos) { while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC)) { $datos = array(); if ($this->_prependRowsData) { $datos = $this->_buildRowsData($datos, $row, $this->_prependRowsData); } foreach ($campos as $campo) { $datos[] = $row[$campo]; } if ($this->_appendRowsData) { $datos = $this->_buildRowsData($datos, $row, $this->_appendRowsData); } $this->addRow($datos); } } /** * Agrega filas usando un objeto. * El objeto debe tener un método llamado cargar que acepte como primer (y * único obligatorio) parámetro un DB_Result para cargar sus datos desde una * base de datos. * * @param DB_Result $result Resultados de una consulta. * @param array $campos Propiedades del objeto a mostrar. * @param mixed $obj Objeto a usar. Puede ser un objeto instanciado o un * string con el nombre de la clase. * * @see La interfaz MECON_DBO que tiene el método MECON_DBO::cargar(). */ function addRowsObject($result, $campos, $obj) { if (is_string($obj)) { $obj = new $obj; } if (!method_exists($obj, 'cargar')) { $this->raiseError('La clase ' . get_class($obj) . ' no tiene un metodo cargar().'); } while ($obj->cargar($result)) { $datos = array(); foreach ($campos as $campo) { $datos[] = $obj->$campo; } $this->addRow($datos); } } function addRowsData($format, $campos = array(), $lugar = 'append') { if (!is_array($campos)) { $campos = array($campos); } switch (strtolower($lugar)) { case 'prepend': $this->_prependRowsData[] = array($format, $campos); break; case 'append': $this->_appendRowsData[] = array($format, $campos); break; default: $this->raiseError('Lugar incorrecto. Lugares soportados: append, prepend.'); } } function _buildRowsData($datos, $row, $array) { if ($array) { foreach ($array as $data) { list($format, $fields) = $data; // Si tiene formatos y argumentos. if ($fields) { $args = array($format); foreach ($fields as $field) { if (is_array($row)) { $args[] = $row[$field]; } else { $args[] = $row->$field; } } $datos[] = call_user_func_array('sprintf', $args); // Si tiene solo formato. } else { #echo "TAG: $format
"; // Si es un link, traduce las variables GET. if (is_a($format, 'mecon_html_link')) { $vars = $format->getGetVars(); foreach ($vars as $var => $val) { if (preg_match("/^{$this->_getVarPrefix}(.+)$/", $var, $m) and ($val === null)) { $format->setGetVar($var, $row[$m[1]]); } } } $datos[] = $format; } } } return $datos; } function addRowsIcon($id, $campos = array(), $link = null, $lugar = 'append') { if (is_string($campos)) { $campos = array($campos); } if (!$link) { $link = @$_SERVER['PHP_SELF']; } if (is_string($link)) { $link = new MECON_HTML_Link($link, ''); } switch ($id) { case 'modificar': $img = new MECON_HTML_Image('/MECON/images/general_modificar', '(M)'); $link->addContents($img); foreach ($campos as $campo) { $link->setGetVar($this->_getVarPrefix.$campo, null); } $this->addRowsData($link, array(), $lugar); break; case 'no_modificar': $img = new MECON_HTML_Image('/MECON/images/general_modificar_des', '(-)'); $this->addRowsData($img, array(), $lugar); break; case 'borrar': $img = new MECON_HTML_Image('/MECON/images/general_eliminar', '(B)'); $link->addContents($img); foreach ($campos as $campo) { $link->setGetVar($this->_getVarPrefix.$campo, null); } $this->addRowsData($link, array(), $lugar); break; case 'no_borrar': $img = new MECON_HTML_Image('/MECON/images/general_eliminar_des', '(-)'); $this->addRowsData($img, array(), $lugar); break; case 'ir': $img = new MECON_HTML_Image('/MECON/images/general_ir4', '->'); $link->addContents($img); foreach ($campos as $campo) { $link->setGetVar($this->_getVarPrefix.$campo, null); } $this->addRowsData($link, array(), $lugar); break; default: $this->raiseError("No hay un ícono predefinido llamado '$id'."); } } } ?>