!C99Shell v. 2.1 [PHP 8 Update] [02.02.2022]!

Software: Apache/2.4.53 (Unix) OpenSSL/1.1.1o PHP/7.4.29 mod_perl/2.0.12 Perl/v5.34.1. PHP/7.4.29 

uname -a: Linux vps-2738122-x 4.15.0-213-generic #224-Ubuntu SMP Mon Jun 19 13:30:12 UTC 2023 x86_64 

uid=1(daemon) gid=1(daemon) grupos=1(daemon) 

Safe-mode: OFF (not secure)

/opt/apex_tdfonline/php/nucleo/componentes/persistencia/   drwxr-xr-x
Free 13.83 GB of 61.93 GB (22.34%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     toba_datos_relacion.php (24.12 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
require_once(toba_dir()."/php/3ros/Graph/Graph.php");    //Necesario para el calculo de orden topologico de las tablas

/**
 * Mantiene un conjunto relacionado de {@link toba_datos_tabla datos_tabla}, brindando servicios para cargar y sincronizar esta relación con algún medio de persistencia (general una BD relacional)
 * 
 *     @package Componentes
 *  @subpackage Persistencia
 *  @todo En el dump_esquema incluir la posición actual de los cursores
 */
class toba_datos_relacion extends toba_componente 
{
    protected 
$_info_estructura;
    protected 
$_relaciones = array();        
    protected 
$_tablas_raiz;
    protected 
$_persistidor;
    protected 
$_cargado false;
    protected 
$_relaciones_mapeos=array();            //Mapeo entre filas de las tablas
    
protected $_relaciones_mapeos_eliminados=array();//Mapeo entre filas eliminadas en el hijo
    
static protected $debug_pasadas;                //Mantiene la cantidad de pasadas para generar ids unicos en js
    
protected $_info_columnas_asoc_rel;
    protected 
$_tablas_inactivas = array();

    
/**
     * @ignore
     */
    
final function __construct($id)
    {
        
$propiedades[] = "_relaciones_mapeos_eliminados";
        
$propiedades[] = "_relaciones_mapeos";
        
$propiedades[] = "_cargado";
        
$this->set_propiedades_sesion($propiedades);
        
parent::__construct($id);
        
$this->crear_tablas();
    }
    
    
/**
     * Método interno para iniciar el componente una vez construido
     * @ignore
     */
    
function inicializar($parametros=array())
    {
        
parent::inicializar($parametros);
        
$this->crear_relaciones();
        if (
$this->_info_estructura['debug']) {
            
$this->dump_esquema("INICIO: ".$this->_info['nombre']);    
        }
        foreach (
$this->_dependencias as $dep) {
            
$dep->inicializar($parametros);
        }
    }
    
    
/**
     * Ventana para agregar configuraciones particulares al inicio de la vida completa del componente
     * @ventana
     */
    
function ini(){}
    
    
/**
     *  @ignore 
     */
    
function destruir()
    {
        
//Esta clase es la encargada de guardarle los valores en sesion a cada relación
        //Se asume que las relaciones siempre se cargan en el mismo orden
        
$this->_relaciones_mapeos = array();
        
$this->_relaciones_mapeos_eliminados = array();
        foreach (
$this->_relaciones as $relacion) {
            
$this->_relaciones_mapeos[] = $relacion->get_mapeo_filas();
            
$this->_relaciones_mapeos_eliminados[] = $relacion->get_mapeo_filas_eliminadas();
        }
        if (
$this->_info_estructura['debug']) {
            
$this->dump_esquema("FIN: ".$this->_info['nombre']);    
        }        
        
parent::destruir();
    }

    
/**
     * Carga los datos_tabla y les pone los topes mínimos y máximos
     */
    
private function crear_tablas()
    {
        foreach( 
$this->_lista_dependencias as $dep){
            
$this->cargar_dependencia($dep);
            
//La cantidad minima y maxima se pasan a traves de dos parametros genericos del objeto
            
$posicion $this->_indice_dependencias[$dep];
            
$cant_min $this->_info_dependencias[$posicion]['parametros_a'];
            
$cant_max $this->_info_dependencias[$posicion]['parametros_b'];
            
$this->_dependencias[$dep]->set_tope_min_filas($cant_min);
            
$this->_dependencias[$dep]->set_tope_max_filas($cant_max);
            
$this->_dependencias[$dep]->set_controlador($this$dep);
        }
    }

    
/**
     * Para cada relación definida crea una toba_relacion_entre_tablas
     * Determina cual es la tabla raiz
     */
    
private function crear_relaciones()
    {
        if(
count($this->_info_relaciones)>0){
            for(
$a=0;$a<count($this->_info_relaciones);$a++)
            {
                
$id_padre $this->_info_relaciones[$a]['padre_id'];
                
$id_hijo $this->_info_relaciones[$a]['hijo_id'];
                
$id_relacion $id_padre.'-'.$id_hijo;
                
$columnas_padre $this->get_columnas_tabla_padre($this->_info_relaciones[$a]);
                
$columnas_hijas $this->get_columnas_tabla_hija($this->_info_relaciones[$a]);
                
$this->_relaciones[$id_relacion] = new toba_relacion_entre_tablas(    $this->_dependencias$id_padre ],
                                                                    
$columnas_padre,
                                                                    
$id_padre,
                                                                    
$this->_dependencias$id_hijo ],
                                                                    
$columnas_hijas,
                                                                    
$id_hijo
                                                                
);
                
$padres[] = $this->_info_relaciones[$a]['padre_id'];
                
$hijos[] = $this->_info_relaciones[$a]['hijo_id'];
                
                
//Se recuperan los mapeos anteriores, si es que hay
                
if (isset($this->_relaciones_mapeos[$a])) {
                    
$this->_relaciones[$id_relacion]->set_mapeo_filas($this->_relaciones_mapeos[$a]);
                }
                if (isset(
$this->_relaciones_mapeos_eliminados[$a])) {
                    
$this->_relaciones[$id_relacion]->set_mapeo_filas_eliminadas($this->_relaciones_mapeos_eliminados[$a]);
                }
            }
            
//Padres sin hijos
            
$this->_tablas_raiz array_diffarray_unique($padres), array_unique($hijos) );
        }else{
            
//No hay relaciones
            
$this->_relaciones = array();
            
$this->_tablas_raiz array_keys($this->_dependencias);
        }
    }

    
/**
     * Deshabilita la tabla o las tablas recibidas para la carga y la sincronización
     */
    
function desactivar_tablas($tablas)
    {
        if (
is_array($tablas)) {
            
$this->_tablas_inactivas $tablas;
        } else {
            
$this->_tablas_inactivas = array($tablas);
        }
    }

    
//-------------------------------------------------------------------------------
    //-- DEBUG  ---------------------------------------------------------------------
    //-------------------------------------------------------------------------------
    
    /**
     * Muestra un dump de los datos y los cambios realizados a los mismos desde la carga
     */
    
function dump_contenido($etiqueta=null)
    {
        
$etiqueta = isset($etiqueta) ? $etiqueta 'DATOS_RELACION: ' $this->_info['nombre'];
        foreach(
$this->_dependencias as $id => $dependencia){
            
$info[$id]['cambios'] = $dependencia->get_cambios();
            
$info[$id]['datos'] = $dependencia->get_conjunto_datos_interno();
        }
        
ei_arbol$info$etiquetanulltrue);
    }
    
    
/**
     * Muestra un esquema de las tablas y los mapeos de las filas
     * SOLO USAR PARA DEBUG! envia todos los datos al cliente en forma plana!
     */
    
function dump_esquema($titulo=null)
    {
        
//Se mantiene la cantidad de pasadas en este pedido de pagina para generar variables js unicas
        
if (isset(self::$debug_pasadas)) {
            
self::$debug_pasadas++;    
        } else {
            
self::$debug_pasadas 1;    
        }
        
$grafo self::grafo_relaciones($this->_info_dependencias$this->_info_relaciones);
        
$diagrama "digraph G {
                        rankdir=LR;
                        fontsize=8;
                        node [fontsize=6, fillcolor=white,shape=box, style=rounded,style=filled, color=gray];
                        "
;
        if (isset(
$titulo)) {
            
$diagrama .= "label=\"$titulo\";\n";
        }
        foreach (
$grafo->getNodes() as $nodo) {
            
$datos $nodo->getData();
            
            
//Se determina la tabla
            
$id_tabla $datos['identificador'];
            
$tabla $this->_dependencias[$id_tabla];

            
//Se incluye el javascript para poder dumpear los datos de la tabla
            
$var_tabla $id_tabla.self::$debug_pasadas;
            echo 
toba_js::abrir();
            echo 
"var $var_tabla = ".toba_js::arreglo($tabla->get_filas(nulltruefalse), true).";\n";
            echo 
toba_js::cerrar();
            
            
//Se incluye la tabla como nodo
            
$label "$id_tabla (".count($tabla->get_id_filas(false)).")";
            
$diagrama .=  "$id_tabla [label=\"$label\",".
                            
//Esta truchada es para arreglar otra ceguera del IE
                            
"URL=\"javascript: padre=(window.parent.var_dump)? window.parent : window; padre.var_dump(padre.$var_tabla)\"];\n";

            
$diagrama .= $this->dump_esquema_relaciones($nodo);
        }
        
$diagrama .= "}";
        
$parametros = array('contenido' => $diagrama'formato' => 'svg''es_dirigido' => 1);
        
$indice uniqid();
        
toba::memoria()->set_dato_instancia($indice$parametros);
        
$url toba::vinculador()->get_url(toba_editor::get_id(), '1000045', array('esquema' => $indice), 
                        array(
'validar' => false'celda_memoria' => 'debug'));
        
toba_ei_esquema::generar_sentencia_incrustacion($url'svg'"100%""200px");
    }
    
    
/**
     * @ignore 
     */
    
protected function dump_esquema_relaciones($nodo)
    {
        
$datos $nodo->getData();        
        
$diagrama '';
        foreach (
$nodo->getNeighbours() as $nodo_vecino) {
            
$datos_vecino $nodo_vecino->getData();
            
            
//Busco los toba_relacion_entre_tablas correspondientes
            
$hijo_id $datos_vecino['identificador'];
            
$padre_id $datos['identificador'];
            
$relacion $this->_relaciones[$padre_id."-".$hijo_id];
            
$mapeo $relacion->get_mapeo_filas();
            
            
//Incluyo el mapeo en JS para poder dumpearlo
            
$var_mapeo $padre_id."_".$hijo_id.self::$debug_pasadas;
            echo 
toba_js::abrir();
            echo 
"var $var_mapeo = ".toba_js::arreglo($mapeotrue).";\n";
            echo 
toba_js::cerrar();
    
            
//Calculo la cantidad de filas padres e hijas involucradas en la relación
            
$cant_padres 0;
            
$cant_hijos 0;
            
$mapeo_hijos = array();
            foreach (
$mapeo as $padre => $hijos) {
                if (
count($hijos) > 0) {
                    
$cant_padres++;
                }
                
$mapeo_hijos array_merge($mapeo_hijos$hijos);
            }
            
$cant_hijos count(array_unique($mapeo_hijos));
            
            
//Incluyo la relación
            
$diagrama .=  $padre_id " -> " $hijo_id 
                        
" [fontsize=6,color=gray, label=\"$cant_padres - $cant_hijos\"".
                        
//Esta truchada es para arreglar otra ceguera del IE
                        
",URL=\"javascript: padre=(window.parent.var_dump)? window.parent : window;padre.var_dump(padre.$var_mapeo)\"];\n";
        }
        return 
$diagrama;
    }


    
/**
     * Retorna el orden hacia adelante en el cual se deben sincronizar las tablas
     * El orden predeterminado es el orden topologico de las tablas
     * @return array Arreglo id_tabla => toba_datos_tabla
     */
    
function orden_sincronizacion()
    {
        if (
$this->_info_estructura['sinc_orden_automatico']) {
            
//-- Se construye el orden topológico
            
$sorter = new Structures_Graph_Manipulator_TopologicalSorter();
            
$deps $this->get_tablas_activas();
            
$rel $this->get_relaciones_activas();
            
$grafo self::grafo_relaciones($deps$rel);
            
$parciales $sorter->sort($grafo);
            
$ordenes = array();
            for (
$i =0$i<count($parciales) ; $i++) {
                for (
$j=0$j<count($parciales[$i]); $j++) {
                    
$ordenes[] = $parciales[$i][$j]->getData();
                }
            }
            
$tablas = array();
            foreach (
$ordenes as $orden) {
                
$tablas[$orden['identificador']] = $this->_dependencias[$orden['identificador']];
            }
            return 
$tablas;
        } else {
            
//-- Se toma el orden natural en el cual se definieron las tablas
            
$ordenes $this->get_tablas_activas();
            
$tablas = array();
            foreach (
$ordenes as $orden) {
                
$tablas[$orden['identificador']] = $this->_dependencias[$orden['identificador']];
            }
            return 
$tablas;
        }
    }

    
/**
     * Retorna el orden hacia adelante en el cual se deben cargar las tablas
     * Por defecto es el mismo que el orden de sincronización
     * @return array Arreglo id_tabla => toba_datos_tabla
     */
    
function orden_carga()
    {
        return 
$this->orden_sincronizacion();
    }
    
    
/**
     * Retorna un grafo representando un conjunto de tablas y sus relaciones
     * @return Structures_Graph
     */
    
static function grafo_relaciones($tablas$relaciones)
    {
        
$grafo = new Structures_Graph(true);
        
// Se construyen los nodos
        
$obj = array();
        
$nodo null;
        foreach (
$tablas as $tabla) {
            unset(
$nodo);
            
$nodo = new Structures_Graph_Node();
            
$proveedor = isset($tabla['objeto_proveedor']) ? $tabla['objeto_proveedor'] : $tabla['objeto'];
            
$obj[$proveedor] = $nodo;
            
$nodo->setData($tabla);
            
$grafo->addNode($obj[$proveedor]);
        }
        
//Se agregan los arcos
        
foreach ($relaciones as $asoc) {
            
$padre $asoc['padre_objeto'];
            
$hijo $asoc['hijo_objeto'];
            
$obj[$padre]->connectTo($obj[$hijo]);
        }
        return 
$grafo;
    }


    
//-------------------------------------------------------------------------------
    //-- Servicios basicos
    //-------------------------------------------------------------------------------

    /**
     * Retorna los identificadores de los datos_tabla incluídos en la relación
     * @return array
     */
    
function get_lista_tablas()
    {
        return 
array_keys($this->_dependencias);    
    }

    
/**
     * Retorna una referencia a una tabla perteneciente a la relación
     * @param string $tabla Id. de la tabla en la relación
     * @return toba_datos_tabla
     */
    
function tabla($tabla)
    {
        if(
$this->existe_tabla($tabla)){
            return 
$this->_dependencias[$tabla];
        }else{
            throw new 
toba_error_def("El datos_tabla '$tabla' solicitado no existe.");
        }
    }

    
/**
     * Retorna las tablas de una relación
     * @return array de toba_datos_tabla
     */
    
function get_tablas()
    {
        return 
$this->_dependencias;
    }

    
/**
     * Retorna las tablas que están habilitadas para la carga y la sincronización
     * @return array de toba_datos_tabla
     */
    
function get_tablas_activas()
    {
        if (empty(
$this->_tablas_inactivas)) {
            return 
$this->_info_dependencias;
        } else {
            
$tablas_activas = array();
            foreach (
$this->_info_dependencias as $indx => $dep) {
                if (! 
in_array($dep['identificador'], $this->_tablas_inactivas)) {
                    
$tablas_activas[] = $dep;
                }
            }
            return 
$tablas_activas;
        }
    }

        
/**
     * Retorna relaciones de las tablas que están habilitadas para la carga y la sincronización
     * @return array de toba_datos_tabla
     */
    
function get_relaciones_activas()
    {
        if (empty(
$this->_tablas_inactivas)) {
            return 
$this->_info_relaciones;
        } else {
            
$relaciones_activas = array();
            foreach (
$this->_info_relaciones as $indx => $rel) {
                if (! 
in_array($rel['padre_id'], $this->_tablas_inactivas) && ! in_array($rel['hijo_id'], $this->_tablas_inactivas)) {
                    
$relaciones_activas[] = $rel;
                }
            }
            return 
$relaciones_activas;
        }
    }

    
/**
     * Determina si una tabla es parte de la relación
     * @param string $tabla Id. de la tabla en la relación
     * @return boolean
     */
    
function existe_tabla($tabla)
    {
        return 
$this->dependencia_cargada($tabla);
    }

    
/**
     * Retorna al estado inicial todas las tablas incluídas
     * Para volver a utilizar estas tablas se debe cargar nuevamente la relación con datos
     */
    
function resetear()
    {
        foreach(
$this->_dependencias as $dependencia){
            
$dependencia->resetear();
        }
        
$this->_cargado false;
    }
    
    
/**
     * Asegura que ningún cursor de alguna tabla se encuentre posicionado en ninguna fila específica
     */    
    
function resetear_cursores()
    {
        foreach(
$this->_dependencias as $dependencia){
            
$dependencia->resetear_cursor();
        }
    }
    
    
/**
     * Ventana para validaciones específicas, se ejecuta justo antes de la sincronización
     * @ventana
     */
    
protected function evt__validar(){}

    
/**
     *    Valida cada una de las tablas incluídas en la relación
     */
    
function disparar_validacion_tablas()
    {
        foreach(
$this->_dependencias as $dependencia){
            
$dependencia->validar();
        }
    }

    
/**
     * Retorna la estructura de datos utilizada por las tablas para mantener registro del estado de sus datos
     * @return array
     */
    
function get_conjunto_datos_interno()
    {
        foreach(
$this->_dependencias as $id => $dependencia){
            
$datos[$id] = $dependencia->get_conjunto_datos_interno();
        }
        return 
$datos;        
    }
    
    
//-------------------------------------------------------------------------------
    //-- PERSISTENCIA  -------------------------------------------------------------
    //-------------------------------------------------------------------------------

    /**
     * Retorna una referenca al Adm.Persistencia de la relación
     * @return toba_ap_relacion_db
     */
    
function persistidor()
    {
        if (!isset(
$this->_persistidor)) {        
            
//Se incluye el archivo
            
$particular = ($this->_info_estructura['ap'] == 3);
            if (
$particular    && isset($this->_info_estructura['ap_archivo']) && isset($this->_info_estructura['ap_clase']) ) {
                
$clase $this->_info_estructura['ap_clase'];
                if( ! 
class_exists($clase) ) {
                    
$punto toba::puntos_montaje()->get_por_id($this->_info_estructura['punto_montaje']);
                    
$path  $punto->get_path_absoluto().'/'.$this->_info_estructura['ap_archivo'];
                    require_once(
$path);
                }
            } else {
                
$clase "toba_ap_relacion_db";
            }
            
$this->_persistidor = new $clase$this );
            if (
$this->_info_estructura['sinc_susp_constraints']) {
                
$this->_persistidor->retrasar_constraints();
            }
            
$this->_persistidor->set_lock_optimista($this->_info_estructura['sinc_lock_optimista']);
        }
        return 
$this->_persistidor;
    }
    
    
/**
     * @deprecated usar persistidor() a secas
     */
    
function get_persistidor()
    {
        return 
$this->persistidor();
    }
    
    
/**
     * Utiliza la carga por clave del administrador de persistencia
     * Carga la tabla raiz de la relación y a partir de allí ramifica la carga a sus relaciones
     * @param array $clave Arreglo asociativo campo-valor por el cual filtrar la relación, si no se explicita se cargan todos los datos disponibles
     * @return boolean Falso, si no se encontraron registros
     */
    
function cargar($clave=array())
    {
        
//ATENCION: hay que controlar el formato de la clave
        
$this->log('***   Inicio CARGAR ****************************');
        
$ap $this->persistidor();
        if(
$ap->cargar_por_clave($clave) === true){
            
$this->log("***   Fin CARGAR (OK) *************************");
            return 
true;
        }else{
            
$this->log("***   Fin CARGAR (No se cargaron datos) ***************");
            return 
false;
        }
    }
    

    
/**
     * La relacion ha sido cargada con datos?
     * @return boolean
     */
    
function esta_cargada()
    {
        return 
$this->_cargado;    
    }
    
    
/**
     * Notifica a la relacion que sus tablas han sido o no cargadas
     * @param boolean $cargado
     */
    
function set_cargado($cargado)
    {
        
$this->_cargado $cargado;
    }

    
/**
    * Fuerza a que los datos_tabla contenidos marquen todos sus filas como nuevas
    * Esto implica que a la hora de la sincronización se van a generar INSERTS para todas las filas.
    * Se utiliza para forzar una clonación completa de los datos una relación.
    */
    
function forzar_insercion()
    {
        foreach(
$this->_dependencias as $id => $dependencia){
            
$dependencia->forzar_insercion();
        }
    }
    
    
/**
     * Sincroniza los cambios con el medio de persistencia
     */
    
function sincronizar($usar_cursores=false)
    {
        if (!
$usar_cursores) {
            
$this->disparar_validacion_tablas();
            
$this->evt__validar();
            
$this->persistidor()->sincronizar();
            
//Se notifica el fin de la sincronización a las tablas
            
foreach ($this->_dependencias as $dependencia) {
                
$dependencia->notificar_fin_sincronizacion();
            }
        } else {
            
//Se sincroniza con cursores
            
foreach ($this->_dependencias as $dependencia) {
                
$filas $dependencia->get_id_filas_filtradas_por_cursor(true);
                if(
$filas) {
                    
$dependencia->validar($filas);
                }
            }
            
$this->evt__validar();
            
$this->persistidor()->sincronizar($usar_cursores);
            foreach (
$this->_dependencias as $dependencia) {
                
$filas $dependencia->get_id_filas_filtradas_por_cursor(true);
                if(
$filas) {
                    
$dependencia->notificar_fin_sincronizacion($filas);
                }
            }
        }
    }

    
/**
     * Sincroniza los cambios con el medio de persistencia
     */
    
function sincronizar_filas($filas_tablas)
    {
        foreach (
$this->_dependencias as $id => $dependencia) {
            if (isset(
$filas_tablas[$id])) {
                
$dependencias->validar($filas_tablas[$id]);
            }
        }
        
$this->evt__validar();
        
$this->persistidor()->sincronizar(false$filas_tablas);
        
//Se notifica el fin de la sincronización a las tablas
        
foreach ($this->_dependencias as $id => $dependencia) {
            if (isset(
$filas_tablas[$id])) {
                
$dependencias->notificar_fin_sincronizacion($filas_tablas[$id]);
            }
        }
    }
    
    
/**
     * Elimina y sincroniza en el medio de persistencia todos los datos cargados en la relación
     */
    
function eliminar_todo()
    {
        
$this->persistidor()->eliminar_todo();
        
$this->resetear();
    }
    
    
/**
     * Usar eliminar_todo, es más explícito
     * @deprecated Desde 0.8.4, usar eliminar_todo, es más explícito
     * @see eliminar_todo()
     */
    
function eliminar()
    {
        
toba::logger()->obsoleto(__CLASS____METHOD__"0.8.4""Usar eliminar_todo");
        
$this->eliminar_todo();    
    }
    
    
/**
     * Retorna el id de las tablas que no tienen padres en la relación
     * @return array
     */
    
function get_tablas_raiz()
    {
        return 
$this->_tablas_raiz;
    }
    
    
/**
     * Fuente de datos que utiliza el objeto y sus dependencias
     * @return string
     */
    
function get_fuente()
    {
        return 
$this->_info["fuente"];
    }
    
    
/**
     * Determina si los datos cargados difieren de los datos existentes en el medio de persistencia
     * @return boolean
     */
    
function hay_cambios()
    {
        
$hay_cambios false;
        foreach (
$this->_dependencias as $dependencia) {
            if (
$dependencia->hay_cambios()) {
                return 
true;
            }
        }
        return 
false;
    }

    function 
get_columnas_tabla_padre($datos)
    {
        
$resultado = array();
        foreach(
$this->_info_columnas_asoc_rel as $info_rel){
            if (
$info_rel['asoc_id'] == $datos['asoc_id'] && $info_rel['padre_objeto']  == $datos['padre_objeto']){
                
$resultado[] = $info_rel['col_padre'];
            }
        }
        return 
$resultado;
    }

    function 
get_columnas_tabla_hija($datos)
    {
        
$resultado = array();
        foreach(
$this->_info_columnas_asoc_rel as $info_rel){
            if (
$info_rel['asoc_id'] == $datos['asoc_id'] && $info_rel['hijo_objeto']  == $datos['hijo_objeto']){
                
$resultado[] = $info_rel['col_hija'];
            }
        }
        return 
$resultado;
    }

    
/**
     * Carga en el nodo xml los datos cargados en el DR. Funciona sólo para relaciones que se modelan como un árbol, no grafos.
     * @param SimpleXMLElement $xml Es el nodo XML donde se van a cargar todos los datos
     */
    
    
function get_xml($xml){

        
// Controla que haya una única tabla raiz
        
if(count($this->_tablas_raiz) != 1)
            throw new 
toba_error_def("El datos_relacion no posee una única tabla raiz.");

        
// Recupera los registros de la tabla raiz para armar cada unidad del XML.
        
$datos_raiz $this->_dependencias[$this->_tablas_raiz[0]]->get_filas();
        
        
// Para cada registro agrega el nodo XML correspondiente y manda a armar el contenido de cada uno
        
foreach($datos_raiz as $clave => $valor){
            
$entidad $xml->addChild($this->_tablas_raiz[0]);
            
$this->armar_xml($entidad,$this->_tablas_raiz[0],$clave);
        }
    }
    
    
/**
     * Arma un nodo XML para un registro de un datos tabla, con sus columnas como atributos y sus registros de tablas hijas como nuevos nodos internos
     * Es un método recursivo con la siguiente estructura:
     * a) Setea el cursor en el registro dado de la tabla dada
     * b) agrega los datos del registro en el que se está parado como atributos del nodo xml recibido
     * c) Para cada tabla hija agrega un nodo al nodo dado.
     * d) Para cada registro de cada tabla hija, agrega un nodo al nodo creado en c) y llama recursivamente a la función
     *
     * @param SimpleXMLElement $xml es el nodo donde se va a agregar la información
     * @param string $tabla la tabla de la que se van a sacar los datos
     * @clave int $clave es la clave del registro de la tabla del que se van a sacar los datos
     */

    
protected function armar_xml($xml,$tabla,$clave)
    {
        
// Setea el cursor de la tabla (esto además está seteando un cursor en las tablas hijas
        
$this->_dependencias[$tabla]->set_cursor($clave);
        
        
// Agrega los datos del registro seleccionado como atributos
        
$this->_dependencias[$tabla]->get_xml($xml);
        
        
// Recupera las tablas hijas de la tabla que se está recorriendo
        
$tablas_hijas $this->get_tablas_hijas($tabla);

        
// Para cada tabla hija, agrega un nodo al nodo dado
        
foreach($tablas_hijas as $tabla_hija){
            
$id_filas_hijas $this->_dependencias[$tabla_hija]->get_id_filas();
            
$xml2 $xml->addChild($tabla_hija);
            
            
// Para cada registro de las tablas hijas seleccionado según el cursor, agrego un nodo y llamo recursivamente
            
foreach($id_filas_hijas as $id_fila_hija){
                
$xml3 $xml2->addChild('registro');
                
$this->armar_xml($xml3,$tabla_hija,$id_fila_hija);
            }
        }
    }

    
/**
     * Dada una tabla del DR, recupera los identificadores de las tablas hijas
     * @param string $tabla es el identificador de la tabla
     * @return mixed es el conjunto de identificadores de las tablas hijas
     */
    
protected function get_tablas_hijas($tabla)
    {
        
// Busco el id de la tabla
        
$id_objeto_padre null;
        
$i 0;
        while(!
$id_objeto_padre && $i count($this->_info_dependencias)){
            if(
$this->_info_dependencias[$i]['identificador'] == $tabla){
                
$id_objeto_padre $this->_info_dependencias[$i]['objeto'];
            }
            
$i++;
        }
        
        
// Controlo que se haya encontrado la tabla
        
if(!$id_objeto_padre)
            throw new 
toba_error_def("No se puede obtener el conjunto de tablas hija de la tabla $tabla que no pertenece a la relación.");

        
// Busco todos los id de objeto de las tablas hijas
        
$objetos_hijos = array();
        foreach(
$this->_info_columnas_asoc_rel as $relacion){
            if(
$relacion['padre_objeto'] == $id_objeto_padre){
                
$objetos_hijos[] = $relacion['hijo_objeto'];
            }            
        }
        
        
// convierto los id de objetos en nombres de tablas
        
$tablas_hijas = array();
        
        for(
$i 0$i count($this->_info_dependencias); $i++){
            if(
in_array($this->_info_dependencias[$i]['objeto'],$objetos_hijos)){
                
$tablas_hijas[] = $this->_info_dependencias[$i]['identificador'];
            }
        }
        
        return 
$tablas_hijas;
    }
}
?>

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.1 [PHP 8 Update] [02.02.2022] maintained byC99Shell Github | Generation time: 0.9715 ]--