<?php
/***************************************************************************************************************************
****************************************************************************************************************************
****************************************************************************************************************************
*************** ***************
*************** Clase para ordenación de matrices en base a categorías. ***************
*************** Versión 1.4 ***************
*************** Desarrollada por José López Quijado. ***************
*************** Es de libre uso, distribución y modificación. ***************
*************** ***************
****************************************************************************************************************************
****************************************************************************************************************************
***************************************************************************************************************************/
class ordenarCategorias{
// Se definen las propiedades que tendrán los objetos de esta clase.
public $matriz = array(); //Matriz a procesar. public $idItem; //Código de la categoria del elemento.
public $nombreItem; //Nombre de la categoria.
public $idPadre; //Codigo de la categoria de la que depende.
public $nuevaPosicionGeneral = 0; //Indicador de posicion del elemento con respecto a otros.
public $salidaTabulada = false; //Salida tabulada o con lista completa escalada de jerarquias (opción por defecto).
public $idPadreBase = 0; //La id de padre base puede cambiar, según se establezca en la llamada.
public $cadenaDeSeparacion = " > "; //Separación entre elementos en la lista por jerarquías.
public $tabulacion = " "; //Tabulación por nivel, en la lista tabulada.
/* El siguiente método ajusta la id de padre de los registros a 0 en los de más alto nivel,
si no es 0 previamente. */
function JLQ_idPadreCero(){
if ($this->idPadreBase == 0) return;
foreach ($this->matriz as $clave=>$valor) if ($valor[$this->idPadre] == $this->idPadreBase) $this->matriz[$clave][$this->idPadre] = "0";
}
/* El siguiente método recupera el id de padre original, por si no era 0. */
function JLQ_restaurarPadreBase(){
if ($this->idPadreBase == 0) return;
foreach ($this->matriz as $clave=>$valor) if ($valor[$this->idPadre] == "0") $this->matriz[$clave][$this->idPadre] = $this->idPadreBase;
}
/* El siguiente método añade un campo numérico a cada elemento de la matriz.
Este se empleará para realizar la ordenación por categorías pero, de momento,
se inicializa a cero.*/
function JLQ_agregarPosVertical(){
foreach ($this->matriz as $clave=>$valor) $this->matriz[$clave]["posVertical"] = 0;
}
/* El siguiente método coloca valores en los campos numéricos añadidos a la matriz, en base a las
relaciones entre el código de cada categoría y el código de aquella de la que desciende cada una. */
function JLQ_ponerPosiciones ($categoriaPadre = 0) {
foreach($this->matriz as $elemento){
if ($elemento[$this->idPadre] == $categoriaPadre && $elemento["posVertical"] == 0){
$matrizNueva[] = $elemento;
}
}
foreach ($matrizNueva as $elemento){
$this->nuevaPosicionGeneral ++;
foreach ($this->matriz as $clave=>$item){
if ($item[$this->idItem] == $elemento[$this->idItem]){
$this->matriz[$clave]["posVertical"] = $this->nuevaPosicionGeneral;
}
}
$argumento = (int)$elemento[$this->idItem];
$this->JLQ_ponerPosiciones($argumento);
}
}
/* Una vez colocados los valores númericos en los campos que añadimos, se ordenan los
elementos de la matriz en base, precisamente, a dichos campos.*/
function JLQ_reOrdenar(){
function JLQ_ordenar($a, $b){
return ($a["posVertical"] < $b["posVertical"]) ? -1 : 1;
}
}
usort($this->matriz, "JLQ_ordenar"); }
/* Los nombres de las categorias se modifican de modo que cada uno incluya la secuencia
de todas las categorías de las que desciende, con un separador específico. */
function JLQ_reconstruirNombres(){
$matrizTemporal = array(); foreach ($this->matriz as $elemento) $matrizTemporal[$elemento[$this->idItem]] = $elemento;
foreach ($this->matriz as $clave=>$elemento){
if ($elemento[$this->idPadre] != "0"){
$categoriaBuscada = $elemento[$this->idPadre];
$cadenaPrecedente = "";
while($categoriaBuscada != "0"){
$cadenaPrecedente = $matrizTemporal[$categoriaBuscada][$this->nombreItem].$this->cadenaDeSeparacion.$cadenaPrecedente;
$categoriaBuscada = $matrizTemporal[$categoriaBuscada][$this->idPadre];
}
$this->matriz[$clave][$this->nombreItem] = $cadenaPrecedente.$elemento[$this->nombreItem];
}
}
}
/* Por último, se eliminan los campos que se añadieron, y que ya no son necesarios. */
function JLQ_eliminarPosVertical(){
foreach ($this->matriz as $clave=>$valor){
unset($this->matriz[$clave]["posVertical"]); }
}
/* El método JLQ_crearMapa() encadena la llamada a los distintos métodos de la clase,
en la secuencia adecuada, y devuelve la matriz ordenada según nuestros deseos. */
function JLQ_crearMapa(){
$this->JLQ_idPadreCero();
$this->JLQ_agregarPosVertical();
$this->JLQ_ponerPosiciones();
$this->JLQ_reconstruirNombres();
$this->JLQ_reOrdenar();
$this->JLQ_eliminarPosVertical();
if($this->salidaTabulada){ //Si se quiere la salida con tabulaciones, esta se establece aquí.
foreach($this->matriz as $indice=>$elemento){
$tabulacion = "";
while(true){
$recorte = strstr($elemento[$this->nombreItem], $this->cadenaDeSeparacion); if (!$recorte) break;
$elemento[$this->nombreItem] = substr($recorte, strlen($this->cadenaDeSeparacion)); $tabulacion .= $this->tabulacion;
}
$this->matriz[$indice][$this->nombreItem] = $tabulacion.$elemento[$this->nombreItem];
}
}
$this->JLQ_restaurarPadreBase();
return $this->matriz;
}
}
?>