Hola, como están? Tengo un pequeño tema con los datos tablas. Necesito cargar un multilinea con los datos que se muestran filtrados con respecto a los que están realmente en la base de datos. Leyendo el wiki veo que se puede hacer con la función get_filas del datos_tabla usandolo de la siguiente forma:
Hasta ahí todo bien, peeeeroooo, también necesito devolver todas las filas MENOS la que tiene id_fila igual a 4. Mirando un poco el código del datos_tabla, veo que todas las condiciones las pasa contra el motor de base de datos como condición1 = algo AND condición2 = algo; por lo que no me está sirviendo lo que hace por defecto el datos_tabla.
Se me ocurrió modificar la clase del datos tabla creando un método que sea get_id_fila_condicion_distinto dentro que debería ir dentro de la clase que define al datos_tabla con el siguiente código
function get_id_fila_condicion_distinto($condiciones=null, $usar_cursores=true)
{
//En principio las coincidencias son todas las filas
$coincidencias = $this->get_id_filas($usar_cursores);
//Si hay condiciones, se filtran estas filas
if(isset($condiciones)){
if(!is_array($condiciones)){
throw new toba_error("Las condiciones de filtrado deben ser un array asociativo");
}
//Controlo que todas los campos que se utilizan para el filtrado existan
/*foreach( array_keys($condiciones) as $columna){
}*/
foreach($coincidencias as $pos => $id_fila){
//Verifico las condiciones
foreach( array_keys($condiciones) as $campo){
if (is_array($condiciones[$campo])) {
list($columna, $operador, $valor) = $condiciones[$campo];
} else {
$columna = $campo;
$operador = '!=';
$valor = $condiciones[$campo];
}
if( !isset($this->_columnas[$columna]) ){
throw new toba_error_def("El campo '$columna' no existe. No es posible filtrar por dicho campo");
}
if(!isset($this->_datos[$id_fila][$columna])) {
// Es posible que una fila no posea una columa. Ej: una nueva fila no tiene la clave si esta es una secuencia.
// Si el valor no existe, considero que la comparacion con esa fila da falso (* != NULL)
unset($coincidencias[$pos]);
break;
} else {
if (! comparar($this->_datos[$id_fila][$columna], $operador, $valor)) {
//Se filtra la fila porque no cumple las condiciones
unset($coincidencias[$pos]);
break;
}
}
}
}
}
return array_values($coincidencias);
}
Si se fijan bien, cambié la linea
$operador = '==';
por
$operador = '!=';
y tengo que redefinir también el método get_filas como get_filas_distinto.
Ahora, viene la pregunta … ¿Cómo hago para extender la clase que maneja el datos_tabla desde mi proyecto para no tener que tocar la que está en el núcleo del toba? ¿Cómo hago para extenderla? sería algo como mi_datos_tabla extends datos_tabla e incluyo todos estos nuevos métodos?. ¿Existe alguna forma de decirle al datos_tabla que me cargue condiciones estilo “id_fila = condición1 OR id_fila = condición5”?
Gracias por la ayuda!
Jhon:
Lo probamos usando el array_merge pero nos da un error que ya antes nos había pasado. Paso a contarte:
Muchas veces detectamos que cuando levantás datos con un datos_tabla y lo asignas a un ef_multilinea, al grabar los datos te cambia el orden de las filas según si fueron modificadas o no. Nosotros para este caso exclusivo usamos un sql manual para cargar el multilínea (ordenado como nosotros queremos) y se lo pasamos al ml con un return en el conf del ml. Cuando haces sincronizas los datos en el evento modificación contra el datos tabla, nos pasa que por ejemplo si la consulta ordenada por id devuelve esto
id | nombre
----------------
1 | Pablo
----------------
2 | Juan
y solamente modificas Pedro agregando, por ejemplo, Pablo J.; al sincronizar y dependiendo como lo haya cargado el datos tabla internamente, en vez de actualizar el id 1, cambia el 2 quedando como resultado:
id | nombre
----------------
2 | Pablo J
----------------
1 | Pablo
Y en ese orden y con esos datos lo refleja dentro del ml.
Por esto es que insisto crear el método mellizo (porque es parecido, pero no igual, jeje) get_filas y la forma de hacer una extensión del núcleo sin necesidad de modificar los archivos del toba. De esa forma me aseguro que independientemente como se carguen los datos en el datos_tabla y la forma en que lo sincronize; va a mantener la coherencia al momento de reflejar los cambios en la tabla.
Si, eso me paso en un caso del foro, la solución particular a este caso es que quites del get_fila, el parametro TRUE, y se deje solamente con la condición.
El metodo get_filas opera sobre los datos que se tienen en memoria, no se le pasa nada al motor de base de datos. La unica interaccion con el motor que tiene el DT es al ejecutar el metodo cargar() o al ejecutar el metodo sincronizar().
Con respecto a tu ejemplo particular, el mismo se puede resolver de la siguiente manera:
Si necesitas hacer consultas mas complejas en un DT, te diria que uses el objeto toba_datos_busqueda, el cual obtenes del DT mediante el metodo ‘nueva_busqueda();’.
De todas maneras me parece copada tu iniciativa de mirar el codigo y meterle mano :).
Richard, mirando un poco este hilo y teniendo en cuenta tus recomendaciones al final modifique el conf de una cuadro de la siguiente manera:
function conf__cuadro_conv()
{
$persona = toba::perfil_de_datos()->get_info();
$aux = ($persona['perfil_id']);
switch ($aux) {
case 7: $aux = 'FBRO'; break;
case 8: $aux = 'FCEDU'; break;
case 9: $aux = 'FCECO'; break;
case 10: $aux = '202'; break;
case 11: $aux = 'FCS'; break;
case 12: $aux = 'FTS'; break;
case 13: $aux = 'FCAD'; break;
case 14: $aux = 'FCAL'; break;
case 15: $aux = 'FCA'; break;
}
$datos = $this->dependencia('dr_convocatorias')->tabla('datos_convocatoria')->get_filas(array(array('unidad_acad','==',$aux),true));
ei_arbol($datos);
//-- Ordena el arreglo $this->datos en base a la columna $this->orden_columna
// en el sentido $orden_sentido
$ordenamiento = array();
$i=0;
foreach ($datos as $fila) {
$ordenamiento[$i]['anio_convocatoria'] = $fila['anio_convocatoria'];
$ordenamiento[$i]['f_desde'] = $fila['f_desde'];
$i++;
}
//Ordeno segun el sentido
array_multisort($ordenamiento, SORT_ASC , $datos);
return $datos;
}
El ei_arbol $datos me sale vacío, y obviamente el Listado dice “No existen convocatorias cargadas”. Que no le gusta del get_filas? Funciona eso con el toba 2.0.4? Probe tambien en lugar de las variable aux en “get_filas(array(array(‘unidad_acad’,‘==’,$aux)” usar un valor explicito digamos y tampoco le gusta. Espero tus comentarios. Desde ya gracias…
Siguiendo con el ejemplo también probe con
->get_filas(array(‘unidad_acad’ => $aux))
y tampocO me muestra el listado.
Probando con cualquier otro campo del datos tabla si filtra correctamente pero cuando especifico ese no.
Cabe aclarar que ese campo lo agregue con posterioridad para personalizar las convocatorias. No se si influye o no.
Por las dudas aclaro que con la sentencia get_filas(array(‘unidad_acad’ => $aux)) anduvo. En mi caso el problema estaba con los datos almacenados en la base, se completaba con espacios en blanco el campo y al hacer la comparación obviamente no entraba nada.