Acceso a datos y generalidades (métodos comunes: lista añadeFiltro, listaExpandida, apilaEstado,carga , orden, count cuenta insertasinoexiste) mas keywords: cargar ordenar contar filtrar filtro CRUD
En QUID las entidades de clases están mapeadas con tablas de base de datos.
Si la función en la que estamos está definida dentro de una clase, podemos acceder a la misma a través de $this->
Por convenio, utilizamos el nombre de variable igual al nombre de la clase:
$PersonalBanners = new PersonalBanners();
Lo chulo del inserta, es que al mismo tiempo carga. Si insertas, podrás acceder a campos a través de la clase actual:
$MiClase->datos->nombreCampo
Otro ejemplo:
$PersonalBanners->inserta([ //listado de campos de la tabla a insertar
"idCentro"=> $this->quid->idcentro() ,
"nombre"=> 'Boletín qPersonal'
]);
Inserción únicamente si no existe
insertaSiNoExiste( [filtro para saber si existe], [requeridos de inserción adicionales]);
$tipoMatricula = $this->WebexTipoMatricula->insertaSiNoExiste(
["idactividad"=>$this->id, "global"=>'1'],
["tipomatricula"=>"Precio global"]
);
De esta manera, si el registro existe se obtiene, y si no existe, se inserta y se retorna. Aun no lo he usado mucho para saber con detalle como funciona, pero sospecho que el campo de filtro inicial se inserta sin necesidad de especificarlo en los requeridos de inserción
$libros=new Libros($this->quid);
$libros->añadeFiltro("year(fecha)=2011"); //Selecciona los libros de un año determinado.
$libros->orden("paginas"); //Ordenados por tamaño
$libros->orden("paginas DESC"); //orden ordenacion inverso descenciente desc
$libros->agrupacion("autor"); //Agrupados por autor (sólo obtendremos un libro para cada autor)
$libros->limite(20); //Limitando a 20 resultados
$listado=$libros->lista(); //Obtiene un array con 20 libros (un por autor) del año 2011 y ordenados por nº de páginas
$ids = $libros->listaIds(); //Obtiene un array con los ids de los elementos
// a veces se utiliza para sacar un where in:
whereIn($Centro->listaIds()) // --> "('200','201','203')" util para cuando queremos hacer un in
$total = $libros->cuenta() //Devuelve el nº de registros del resultset (creo)
$this->carga(5); //utiliza el id obviamente
$this->carga([ "nombre" => "juan", "sexo" => "masculino" ]); //también soporta
Cargar con una especie de where, util para cuando sabemos que hay un unico resultado Si hubiera multiples, carga unicamente el primero.
Una vez cargado un registro, se accede a los datos a traves de $this->datos, excepto el ID que si queremos está disponible directamente a través de $this->id
$ejemplo = $this->datos->nombre;
$idActual = $this->id;
También se puede hacer un carga en una instancia de una clase (sin usar this):
$libros=new Libros();
$resultado=$libros->carga(134);
También se puede hacer un carga pasandole un filtro (nótese que $parametros es el objeto a través del que quid3 pasa los parámetros de entrada de una función)
$ApiFunciones->carga([
"clase" => $parametros["clase"],
"funcion" => $parametros["funcion"]
]);
Conviene saber si un objeto se ha cargado correctamente, la forma más estandar es comprobando si: $resultado->id
o si $resultado->datos->id
$libros=new Libros();
$resultado=$libros->carga(134);
if ($resultado->id){
echo "Sí se ha seleccionado el objeto";
}else{
echo "No existen ningún registro con clave principal 134";
}
$this->modificaDato('nombre_campo',69);
//siendo $this el objeto cargado y 69 el valor a actualizar
también está la opción que guarda muchos datos en vez de uno solo, que va con array
$this->modificaDatos([
"idPersonalReconocimiento" => $insercion["id"],
"campo2" => $valor2
]);
Retorna el conjunto de registros que cumplen una condición. Conviene tener cuidado para no pedir demasiados datos
$this->lista(); //OJO! es como hacer un select *
$this->lista("nombre, apellidos"); //forma correcta: especificar las columnas que queremos
$this->listaUno(); //lo mismo pero solo retorna uno, con la ventaja de que no hay que acceder a [0]
$this->cuenta(); //es un count tras un lista (sobre un objeto cargado)
En una lista también podemos acceder a campos de tablas asociadas, mediante lo que en qInnova denomicamos "expansión". Expandir es ir de una tabla a otras para obtener cruces.
Nótese que para acceder a campos expandidos (utilizando lista()
, las tablas involucradas han de estar en la relación, y cada una de ellas podrá tener sus propios filtros aplicados:
$MisAutores=new MisAutores();
$MisAutores->MisLibros->MisCapitulos->lista(
"MisAutores.nombre,
MisAutores.id,
titulo"); //como este campo es de la última tabla encadenada, no hace falta indicarla
$fechas= $webex_alumno->WebexMatriculas->Webex->listaUno(
'min(fechainicio) as fechaminima,max(fechafin) as fechamaxima'
);
La lista agrupada, retorna un conjunto de registros/filas indexando aquellas que tengan un campo en común. Ese campo, será la key primaria del array, quedando los registros como arreglos anidados agrupados.
El primer parámetro al invocar a la función listaAgrupada()
son los campos que queremos por cada registro, y el segundo, el campo agrupador en el array primario.
NOTA : Es importante que el campo agrupador esté también en la query.
$lista = $PersonalLogros->PersonalLogrosUsuarios->listaAgrupada(
"id, PersonalLogros.logro,PersonalLogros.tipo", //campos por fila
"tipo" //campo indexador (aplanador)
);
Quizás sea la forma más útil para listar registros. Especialmente útil cuando queremos extraer datos de otras tablas relacionadas que se ramifican, sin tener que cruzarlas en la relación inicial (a la izquierda). Tiene la peculiaridad de que cuando hay muchos registros asociados a una fila, se concatenan con coma.
Pequeño vídeo explicativo: Explicación de Santiago
IMPORTANTE: La lista expandida siempre empieza desde la clase en la que queremos que haya un registro por fila.
¿Esto que significa?
Que MisLibros->lista()
tendrá el mismo numero de líneas que MisLibros->listaExpandida(....)
por mucho que se cruce con otras cosas en las expansiones.
La clase de inicio (antes de invocar a la función) es la que queremos que tenga un registro por fila
$listado = $this->HubPreguntasOpciones->listaExpandida("
id as id, //superfluo
HubPreguntas.id as idPregunta,
HubPreguntas.pregunta as pregunta,
opcion as opcion,
id as idOpcion,
HubPreguntasConectores.id as idConector
");
Resultado (truncado). Observar que cuando hay más de un elemento expandido de una clase relacionada, su valor se concatena con ,
array (size=10)
2 =>
array (size=6)
'id' => string '2' (length=1)
'idPregunta' => string '2' (length=1)
'pregunta' => string '¿Quieres asesoramiento sobre cómo innovar en tu asignatura?' (length=61)
'opcion' => string 'Sí, pero no sé cómo' (length=22)
'idOpcion' => string '2' (length=1)
'idConector' => string '4, 6' (length=4) // <-- ves! se han unido!
4 =>
array (size=6)
'id' => string '4' (length=1)
'idPregunta' => string '2' (length=1)
'pregunta' => string '¿Quieres asesoramiento sobre cómo innovar en tu asignatura?' (length=61)
'opcion' => string 'Sí, sobre aprendizaje activo' (length=29)
'idOpcion' => string '4' (length=1)
'idConector' => string '2,4,6' (length=2) // <-- ves! se han unido!
Otro ejemplo, queremos todos los logros obtenidos, ordenados por fecha, con información sobre quien los ha conseguido. Como queremos todos los logros obtenidos, partimos desde esa tabla (la de ocurrencias de logros)
$PersonalLogros = new PersonalLogros();
$logros = $PersonalLogros->PersonalLogrosUsuarios->orden("fecha desc");
$logros = $PersonalLogros->PersonalLogrosUsuarios->listaExpandida("
PersonalLogros.id as id,
PersonalLogrosUsuarios.fecha as fecha,
PersonalLogros.logro as logro,
PersonalLogros.descripcion as descripcion,
PersonalLogrosUsuarios.Usuario.nombre as nombre,
PersonalLogrosUsuarios.Usuario.apellidos as apellidos
");
Permite ordenar por una columna antes de hacer un lista
$this->orden("nombre");
Se pueden aplicar filtros (condiciones SQL) en distintos niveles de una relación entre clases, se aplicarán a la hora de hacer el próximo lista:
En este caso, elegir solo las filas cuyo titulo empiece por la letra 'E' aunque también se pueden poner ands y otros wheres complejos. Los filtros sobre clases anteriores se encadenan.
$this->añadeFiltro("id=5");
$this->SoporteUsuariosAplicaciones->SoporteColaboradores->añadeFiltro("activo=1");
$this->añadeFiltro("left(titulo,1)='E'");
Otro ejemplo:
$Webex->añadeFiltro("idcentro = '5' and firma_electronica = '0' and horas_lectivas = '10.00' ");
$this->borraFiltro();
Podemos trabajar con scopes de filtros que solo tienen validez dentro de su ámbito comprendido entre apilaEstado()
y desapilaEstado()
. Siempre hay que intentar que al final de un código, sobre todo si aplica a $this, el filtro quede como estaba.
$SoporteColaboradores = new SoporteColaboradores();
$SoporteColaboradores->apilaEstado();
$SoporteColaboradores->añadeFiltro("nombre='Alicia'");
$SoporteColaboradores->añadeFiltro("apellidos='Hernandez'");
$listado = $SoporteColaboradores->lista("id,nombre,apellidos");
//var_dump($SoporteColaboradores->filtroActual());
//var_dump($listado);
$SoporteColaboradores->desapilaEstado();
//var_dump($SoporteColaboradores->filtroActual());
$listado2 = $SoporteColaboradores->lista("id,nombre,apellidos");
//var_dump($listado2);
Otro ejemplo en el que podemos ver que los filtros se concatenarán automáticamente:
$this->apilaEstado();
$this->añadeFiltro("idusuario_emisor=".$this->quid->idusuario());
$this->añadeFiltro("idusuario_receptor=".$parametros["idUsuarioReceptor"]);
$this->desapilaEstado();
//$this->relacion("InventariosEquiposInformaticos.idarticulo");
//Esta linea no tendría que ser necesaria, creo que principalmente para tablas polimorficas
$this->InventariosEquiposInformaticos->añadeFiltro("InventariosEquiposInformaticos.id=".$this->datos->id);
(Al menos aplica a cruces con la clase Archivo). Cuando hay subclases hijas y se hace el cambio del filtro en una hija el apilaEstado no coge el estado de las subclases hijas, por un fallo del framework.
En ese caso se utiliza esto:
$this->eliminaRelacion("Archivo");
//Siendo $this en este caso Webex