]> git.llucax.com Git - mecon/meconlib.git/blob - lib/MECON/HTML/TablaDB.php
Se corrige pequeño bug a Link.
[mecon/meconlib.git] / lib / MECON / HTML / TablaDB.php
1 <?php /* vim: set binary expandtab tabstop=4 shiftwidth=4 textwidth=80:
2 -------------------------------------------------------------------------------
3                              Ministerio de Economía
4                                     meconlib
5 -------------------------------------------------------------------------------
6 This file is part of meconlib.
7
8 meconlib is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2 of the License, or (at your option)
11 any later version.
12
13 meconlib is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16  
17 You should have received a copy of the GNU General Public License; if not,
18 write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19 Boston, MA  02111-1307  USA
20 -------------------------------------------------------------------------------
21 Creado: fri mar 21 ART 2003
22 Autor:  Martin Marrese <mmarre@mecon.gov.ar>
23 -------------------------------------------------------------------------------
24 $Id$
25 -----------------------------------------------------------------------------*/
26
27 require_once 'DB.php';
28 require_once 'MECON/DB/Pager.php';
29 require_once 'MECON/HTML/Error.php';
30 require_once 'MECON/HTML/Link.php';
31 require_once 'MECON/HTML/Tabla.php';
32
33 /**
34  * Libreria para le manejo de las tablas de los sistemas de intranet.
35  *
36  */
37 class MECON_HTML_TablaDB extends MECON_HTML_Tabla {
38
39     /**
40      * Descripción de los elementos listados.
41      * Se utiliza en mensajes del paginador y otros mensajes.
42      */
43     var $_desc = 'resultados';
44
45     /**
46      * Datos a agregar delante de cada fila que se agregue desde una base de datos.
47      * Cada elemento del array es a su vez un array cuyo primer elemento es el
48      * formato del texto a agregar (tipo printf()) y el segundo es un array con los
49      * campos de la DB a utilizar para ese formato en una fila dada.
50      */
51     var $_prependRowsData = array();
52
53     /**
54      * Datos a agregar al final de cada fila que se agregue desde una base de datos.
55      * El formato es el mismo que el de _prependRowsData.
56      */
57     var $_appendRowsData = array();
58
59     /**
60      * Prefijo a usar para las variables GET que genera la tabla.
61      */
62     var $_getVarPrefix = 'tabladb_';
63
64     /**
65      * Constructor. 
66      * Puede recibir como parametro un string con los atributos que se 
67      * quieren dar a la tabla en cuestion. Estos atributos estan
68      * seteados por default segun el archivo de configuracion.
69      * Ademas puede recibir la indicacion de algun estilo en particular.
70      *
71      * @param string $desc Descripción de los elementos listados.
72      * @param mixed $attrs Atributos diferentes a los estandares para la tabla
73      * @param string $estilo Tipo de tabla
74      * 
75      * @access public
76      */
77     function MECON_HTML_TablaDB($desc = null, $attrs = null, $estilo = 'comun') {
78         if ($desc) {
79             $this->_desc = $desc;
80         }
81         parent::MECON_HTML_Tabla($attrs, $estilo);
82     }    
83
84     /**
85      * Establece el prefijo usado para las variables de GET que genera la tabla.
86      */
87     function setGetVarPrefix($prefix) {
88         $this->_getVarPrefix = $prefix;
89     }
90
91     /**
92      * Obtiene el prefijo usado para las variables de GET que genera la tabla.
93      */
94     function getGetVarPrefix() {
95         return $this->_getVarPrefix;
96     }
97
98     /**
99      * Agrega un páginador a la tabla, basado en un resultado de una base de datos.
100      * Ejemplo:
101      * @code
102      * $tabla = new MECON_HTML_TablaDB('personas', array('width' => '100%'));
103      * $result = $db->query('SELECT nombre, apellido FROM tabla');
104      * if (DB::isError($result)) {
105      *      die('Error');
106      * }
107      * $pager = $tabla->addPager($result);
108      * $tabla->addRow(array('Nombre', 'Apellido'), 'cabecera');
109      * $tabla->addRows($result, array('nombre', 'apellido'));
110      * $tabla->display();
111      * @endcode
112      *
113      * @param DB_Result $result Resultado de una consulta de base de datos.
114      * @param mixed $tipo Tipo de link(s) a agregar. Puede ser:
115      *                    <ul>
116      *                      <li><tt>'anterior'</tt></li>
117      *                      <li><tt>'siguiente'</tt></li>
118      *                      <li><tt>'paginas'</tt></li>
119      *                      <li><tt>'total'</tt></li>
120      *                      <li><tt>'info'</tt></li>
121      *                    </ul>
122      *                    Puede pasarse uno solo como un string o varios como un
123      *                    array. Si se pasa <tt>'todo'</tt>, se incluyen todos.
124      *                    Si se pasa null, se incluyen <tt>'anterior'</tt>,
125      *                    <tt>'siguiente'</tt> y <tt>'paginas'</tt>.
126      * @param mixed $link Dirección a la que apuntan los links generados. Puede
127      *                    ser un MECON_HTML_Link (para poder pasar variables por
128      *                    GET) o un string.
129      * @param int $limit Parámetro usado para crear el MECON_DB_Pager.
130      * @param int $maxpages Parámetro usado para crear el MECON_DB_Pager.
131      * @param string $getvar Nombre de la variable GET a usar para indicar el número
132      *               de página actual (se le pone el \ref setGetPrefix prefijo)
133      *
134      * @return MECON_DB_Pager Pager que se puede usar para realizar los fetch de
135      *         los resultados de la página actual.
136      *
137      * @see MECON_DB_Pager.
138      */
139     function addPager($result, $tipo = null, $link = null, $limit = 10, $maxpages = 21, $getvar = 'from') {
140         // Creo el pager con el resultado.
141         $pager = new MECON_DB_Pager($result, @$_GET[$this->_getVarPrefix.$getvar], $limit, $maxpages);
142         // Obtengo un link válido.
143         if (!$link) {
144             $link = @$_SERVER['PHP_SELF'];
145         }
146         if (is_string($link)) {
147             $link = new MECON_HTML_Link($link, '');
148         }
149         // Si es el tipo por defecto pone paginador nada más.
150         if (!$tipo) {
151             $tipo = array('anterior', 'paginas', 'siguiente');
152         }
153         // Convierte tipo a array.
154         if (!is_array($tipo)) {
155             $tipo = array($tipo);
156         }
157         // Si se quiere mostrar todas las decoraciones del paginador.
158         if (in_array('todo', $tipo)) {
159             $tipo = array('anterior', 'paginas', 'siguiente', 'total', 'info');
160         }
161         // Me fijo si tiene cada uno de los elementos y los agrego.
162         if (in_array('anterior', $tipo) and $pager->numRows() and $pager->currentpage != 1) {
163             $link->setGetVar($this->_getVarPrefix.$getvar, $pager->prev);
164             $this->addLink('anterior', $link);
165         }
166         if (in_array('siguiente', $tipo) and $pager->numRows() and $pager->currentpage != $pager->numpages) {
167             $link->setGetVar($this->_getVarPrefix.$getvar, $pager->next);
168             $this->addLink('siguiente', $link);
169         }
170         if (in_array('paginas', $tipo) and $pager->numRows() and $pager->numpages > 1) {
171             $from = @$_GET[$this->_getVarPrefix.$getvar];
172             $pags = '';
173             $lnk = $link->getContents();
174             foreach ($pager->pages as $page => $start_row) {
175                 if ($start_row == $from) {
176                     $pags .= $page;
177                 } else {
178                     $link->setGetVar($this->_getVarPrefix.$getvar, $start_row);
179                     $link->setContents($page);
180                     $pags .= $link->toHtml();
181                 }
182                 if ($page != $pager->lastpage) {
183                     $pags .= ' | ';
184                 }
185             }
186             $link->setContents($lnk);
187             $this->updatePie($pags, 'centro');
188         }
189         if (in_array('total', $tipo) and $pager->numRows()) {
190             $this->updateCabecera("Se encontraron {$pager->numrows} {$this->_desc}.", 'izquierda');
191         }
192         if (in_array('info', $tipo) and $pager->numRows()) {
193             $this->updateCabecera("'Página {$pager->currentpage} de {$pager->numpages} - "
194                 . "{$pager->limit} {$this->_desc} por página.", 'derecha');
195         }
196         return $pager;
197     }
198
199     /**
200      * Agrega filas desde el resultado de una consulta a una base de datos.
201      * Si no hay resultados, muestra un mensaje. Dependiendo de si es se pasa
202      * un objeto a usar o no, llama a addRowsObject() o addRowsResult()
203      * respectivamente.
204      * Ejemplo:
205      * @code
206      * @endcode
207      *
208      * @param DB_Result $result Resultados de una consulta.
209      * @param array $campos Propiedades del objeto a mostrar.
210      * @param mixed $obj Objeto a usar. Puede ser un objeto instanciado o un
211      *                   string con el nombre de la clase.
212      *
213      * @see Ejemplo en addPager();
214      */
215     function addRows($result, $campos, $obj = null) {
216         if ($result->numRows()) {
217             if ($obj) {
218                 $this->addRowsObject($result, $campos, $obj);
219             } else {
220                 $this->addRowsResult($result, $campos, $obj);
221             }
222         } else {
223             $id = $this->addRow(array(new MECON_HTML_Error("No se encontraron {$this->_desc}.")));
224             $this->updateCellAttributes($id, 0, array('colspan' => count($campos)));
225         }
226     }
227
228     /**
229      * Agrega filas usando un resultado.
230      *
231      * @param DB_Result $result Resultados de una consulta.
232      * @param array $campos Campos de la base de datos a mostrar.
233      */
234     function addRowsResult($result, $campos) {
235         while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC)) {
236             $datos = array();
237             if ($this->_prependRowsData) {
238                 $datos = $this->_buildRowsData($datos, $row, $this->_prependRowsData);
239             }
240             foreach ($campos as $campo) {
241                 $datos[] = $row[$campo];
242             }
243             if ($this->_appendRowsData) {
244                 $datos = $this->_buildRowsData($datos, $row, $this->_appendRowsData);
245             }
246             $this->addRow($datos);
247         }
248     }
249
250     /**
251      * Agrega filas usando un objeto.
252      * El objeto debe tener un método llamado cargar que acepte como primer (y
253      * único obligatorio) parámetro un DB_Result para cargar sus datos desde una
254      * base de datos.
255      *
256      * @param DB_Result $result Resultados de una consulta.
257      * @param array $campos Propiedades del objeto a mostrar.
258      * @param mixed $obj Objeto a usar. Puede ser un objeto instanciado o un
259      *                   string con el nombre de la clase.
260      *
261      * @see La interfaz MECON_DBO que tiene el método MECON_DBO::cargar().
262      */
263     function addRowsObject($result, $campos, $obj) {
264         if (is_string($obj)) {
265             $obj = new $obj;
266         }
267         if (!method_exists($obj, 'cargar')) {
268             $this->raiseError('La clase ' . get_class($obj) . ' no tiene un metodo cargar().');
269         }
270         while ($obj->cargar($result)) {
271             $datos = array();
272             foreach ($campos as $campo) {
273                 $datos[] = $obj->$campo;
274             }
275             $this->addRow($datos);
276         }
277     }
278
279     function addRowsData($format, $campos = array(), $lugar = 'append') {
280         if (!is_array($campos)) {
281             $campos = array($campos);
282         }
283         switch (strtolower($lugar)) {
284             case 'prepend':
285                 $this->_prependRowsData[] = array($format, $campos);
286                 break;
287             case 'append':
288                 $this->_appendRowsData[] = array($format, $campos);
289                 break;
290             default:
291                 $this->raiseError('Lugar incorrecto. Lugares soportados: append, prepend.');
292         }
293     }
294
295     function _buildRowsData($datos, $row, $array) {
296         if ($array) {
297             foreach ($array as $data) {
298                 list($format, $fields) = $data;
299                 // Si tiene formatos y argumentos.
300                 if ($fields) {
301                     $args = array($format);
302                     foreach ($fields as $field) {
303                         if (is_array($row)) {
304                             $args[] = $row[$field];
305                         } else {
306                             $args[] = $row->$field;
307                         }
308                     }
309                     $datos[] = call_user_func_array('sprintf', $args);
310                 // Si tiene solo formato.
311                 } else {
312                     #echo "TAG: $format<br>";
313                     // Si es un link, traduce las variables GET.
314                     if (is_a($format, 'mecon_html_link')) {
315                         $vars = $format->getGetVars();
316                         foreach ($vars as $var => $val) {
317                             if (preg_match("/^{$this->_getVarPrefix}(.+)$/", $var, $m)
318                                     and ($val === null)) {
319                                 $format->setGetVar($var, $row[$m[1]]);
320                             }
321                         }
322                     }
323                     $datos[] = $format;
324                 }
325             }
326         }
327         return $datos;
328     }
329
330     function addRowsIcon($id, $campos = array(), $link = null, $lugar = 'append') {
331         if (is_string($campos)) {
332             $campos = array($campos);
333         }
334         if (!$link) {
335             $link = @$_SERVER['PHP_SELF'];
336         }
337         if (is_string($link)) {
338             $link = new MECON_HTML_Link($link, '');
339         }
340         switch ($id) {
341             case 'modificar':
342                 $img = new MECON_HTML_Image('/MECON/images/general_modificar', '(M)');
343                 $link->addContents($img);
344                 foreach ($campos as $campo) {
345                     $link->setGetVar($this->_getVarPrefix.$campo, null);
346                 }
347                 $this->addRowsData($link, array(), $lugar);
348                 break;
349             case 'no_modificar':
350                 $img = new MECON_HTML_Image('/MECON/images/general_modificar_des', '(-)');
351                 $this->addRowsData($img, array(), $lugar);
352                 break;
353             case 'borrar':
354                 $img = new MECON_HTML_Image('/MECON/images/general_eliminar', '(B)');
355                 $link->addContents($img);
356                 foreach ($campos as $campo) {
357                     $link->setGetVar($this->_getVarPrefix.$campo, null);
358                 }
359                 $this->addRowsData($link, array(), $lugar);
360                 break;
361             case 'no_borrar':
362                 $img = new MECON_HTML_Image('/MECON/images/general_eliminar_des', '(-)');
363                 $this->addRowsData($img, array(), $lugar);
364                 break;
365             case 'ir':
366                 $img = new MECON_HTML_Image('/MECON/images/general_ir4', '->');
367                 $link->addContents($img);
368                 foreach ($campos as $campo) {
369                     $link->setGetVar($this->_getVarPrefix.$campo, null);
370                 }
371                 $this->addRowsData($link, array(), $lugar);
372                 break;
373             default:
374                 $this->raiseError("No hay un ícono predefinido llamado '$id'.");
375         }
376     }
377
378 }
379
380 ?>