Mientras estaba desarrollando un proyecto en Symfony2, tuve la necesidad de agrupar dos Entidades que tenian informacion similar, por ejemplo tenia una Entidad Liquidacion y otra LiquidacionesSA, esta ultima simulaba una Liquidacion pero contenia otra informacion, ambas tenian un mes, un año, un codigo y estaban asociadas a una Entidad padre llamada LiquidacionResumen, el problema fue cuando necesite listar todas las Liquidaciones que tenia LiquidacionResumen en donde debia incluir tanto las Entidades Liquidacion y LiquidacionSA, obviamente debian ir ordenadas por codigo para mostrar una concordancia correlativa entre ellas, por ultimo mencionar que la asociacion entre ellas devolvia un ArrayCollection.
Pues bien, empeze a buscar y me encontre con este post en donde existian varias formas, personalmente me gusta encontrar una solucion optima pero sin muchas lineas de codigo, por lo tanto ocupe la segunda opcion que brinda ese post, asi que llegue a esto.
Lo primero recordar que nuestra asociacion es un ArrayCollection como mencionaba anteriormente, pero nuestro proceso requiere un array normal.
Creamos una funcion dentro de nuestra Entidad LiquidacionResumen
public function getListaLiquidaciones() { $listado = $this->getLiquidacion()->toArray(); $listadoSA = $this->getLiquidacionSA()->toArray(); $listado = array_merge($listado, $listadoSA); usort($listado, function($a, $b) { $codA = $a->getCodigo(); $codB = $b->getCodigo(); return $codA == $codB ? 0 : ( $codA > $codB ) ? 1 : -1; }); return $listado; }
Como requerimos un array normal, ocupamos toArray(), una funcion entregada por nuestro ArrayCollection.
Hacemos un array_merge de nuestros dos listado de Liquidaciones, ahora existe un array llamado listado que contiene Liquidacion y LiquidacionSA.
Por ultimo, nuestra usort que llama a una funcion recursiva la cual se encargara de ordenar, notece que deje en una variable llamada codA y codB los codigos para que se viera mas claramente por lo que deseamos comparar.
Si por ejemplo digamos que nuestra Liquidacion tienen una asociacion con Propiedad, y esta Entidad es la que tiene un codigo podemos ocuparlo tambien:
$codA = (is_object($a->getPropiedadId())) ? $a->getPropiedadId()->getCodigo() : 0; $codB = (is_object($b->getPropiedadId())) ? $b->getPropiedadId()->getCodigo() : 0;
La funcion is_object nos permite verificar si efectivamente existe una relacion, pero ¿porque? pues simple, cada relacion que tu tengas con otra tabla debera retornar un Objeto (siempre y cuando sea una relacion uno a uno, de lo contrario retornara un ArrayCollection por ejemplo uno a muchos), por lo tanto si no retorna un objeto, no existe relacion, de ser asi seteamos un cero.
En algunas funciones ocupan strcmp para comparar, personalmente no me dio el resultado esperado, ya que no ordenaba de manera correcta.
Bueno, y eso seria todo, ahora llamamos a nuestra funcion getListaLiquidaciones() y listo nos retornara los dos listados ordenados.
Saludos