<?php
// vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: 
/**
* Actualiza base de datos después de actualizar fuentes
 *
 * PHP version 5
 *
 * @category  SIVeL
 * @package   SIVeL
 * @author    Vladimir Támara <vtamara@pasosdeJesus.org>
 * @copyright 2006 Dominio público. Sin garantías.
 * @license   http://creativecommons.org/licenses/publicdomain/ Dominio Público. Sin garantías.
 * @version   $Id: actualiza.php,v 1.26 2009/05/04 11:36:07 vtamara Exp $
 * @link      http://sivel.sf.net
 */

/** Actualiza base de datos después de actualizar fuentes */
require_once "aut/conf.php";
require_once "aut/aut.php";
require_once "confv.php";
require_once "Categoria.php";


$aut_usuario = "";
$db = autenticaUsuario($dsn, $accno, $aut_usuario, 21);

/** 
 * Retorna valor de una variable de un archivo de configuración SH (ultima)
 *
 * @param string $a Archivo de configuración
 * @param string $v Archivo de configuración
 *
 * @return null si no encuentra variable
 */
function valVarConf($a, $v) 
{
    assert($v != "");
    if (!($f = fopen($a, "r"))) {
        die("Falta archivo de configuración '$a'");
    }

    $r = null;
    while (!feof($f)) {
        $buffer = fgets($f, 4096);
        if (substr(trim($buffer), 0, strlen($v))==$v) {
            $r = trim(preg_replace('/.*= *"(.*)"/', '$1', $buffer));
        }
    }
    fclose($f);
    return  $r;
}


/**
 * Ejecuta consulta $q
 *
 * @param handle &$db Conexióna BD
 * @param string $q   Consulta
 *
 * @return resultado de la consulta. si hay errores los presenta.
 */
function hace_consulta(&$db, $q) 
{
    $res = $db->query($q);
    if (PEAR::isError($res)) {
        echo "Error: " . $res->getMessage() . " - " . 
            $res->getUserInfo() . "<br>";
    }
    return $res;
}


/** Extrae variables globales de una fuente PHP 
 *  http://us.php.net/manual/en/tokenizer.examples.php
 *
 * @param string $f Nombre del archivo .php
 *
 * @return array vector de variables
 **/
function extraeVarPHP($f) 
{
    $source = file_get_contents($f);
    $tokens = token_get_all($source);

    $ttokens = count($tokens);
    $estado = 0;
    $avar = array(); // Arreglo con variables encontradas
    $nomvar = ""; //Nombre de última variable encontrada
    $ultcom = ""; //Ultimo comentario encontrado
    for ($i = 0; $i < count($tokens); $i++) {
        $token = $tokens[$i];
        /* Estados:
         * 0 Buscando variable izq
         * 1 Variable izq encontrada, buscando = -> 2 o 4
         * 2 = encontrado, esperando valor
         * 
         * 4 [ encontrado, buscando indice
         * 5 indice encontrado buscando ]
         * ] -> 2
         */
        if (is_string($token)) {
            // simple 1-character token
            switch ($token) {
            case '=':
                if ($estado == 1) {
                    $estado = 2;
                } else {
                    $estado = 0;
                }
                break;
            case '[':
                if ($estado == 1) {
                    $estado = 4;
                } else {
                    $estado = 0;
                }
                break;
            case ']':
                if ($estado == 5) {
                    $estado = 1;
                } else {
                    $estado = 0;
                }
                break;

            default:
                $estado = 0;
            }
        } else {
            // token array
            list($id, $text) = $token;
            switch ($id) {
            case T_VARIABLE :
                if ($estado == 0) {
                    $estado = 1;
                    $nomvar = $text;
                } else {
                    $estado = 0;
                }
                break;
            case T_CONSTANT_ENCAPSED_STRING:
                if ($estado == 2) {
                    $avar+=array($nomvar => array($text, $ultcom));
                    $estado = 0;
                } else if ($estado == 4) {
                    $nomvar .= "[$text]";
                    $estado = 5;
                } else {
                    $estado = 0;
                }
                break;
            case T_DOC_COMMENT:
                $ultcom = $text;
                break;
            case T_WHITESPACE:
                break;
            default:
                $estado = 0;
                $ultcom = '';
                break;
            }
        }
    }

    return $avar;
}


/** 
 * Presenta en HTML variables PHP 
 * 
 * @param array $avar Vector de variables
 *
 * @return void
 */
function muestraVarPhpEnHTML($avar) 
{
    echo "<pre>";
    foreach ($avar as $nv => $ld) {
        list($vv, $cv) = $ld;
        echo htmlentities($cv)."<br/>";
        echo htmlentities($nv)." = ".htmlentities($vv).";<br/><br/>";
    }
    echo "</pre>";
} 

/** 
 * Retorna líneas que definen una variable  en archivo de conf. PHP
 *
 * @param string $a Archivo de configuración
 * @param string $v v
 *
 * @return string null si no encuentra variable
 */
function valVarConfPHP($a, $v) 
{
    assert($v != "");
    if (!($f = fopen($a, "r"))) {
        die("Falta archivo de configuración '$a'");
    }

    $r = null;
    $com = ""; /* Comentario */
    $lv = ""; /* Lineas que definen variable */
    $estado = 0; /* Estado de automata 0 no encontrado, 1 comentario 
        econtrado guardando, 2 variable encontrada, 3 ya procesado */
    while ($estado != 3 && !feof($f)) {
        $buffer = fgets($f, 4096);
//        echo "buffer=$buffer, estado=$estado, com=$com, lv=$lv<br>";
        if ($estado == 0 && substr(trim($buffer), 0, strlen($v))==$v) {
            $lv = $com;
            $estado = 2;
        }
        if (substr(trim($buffer), 0, 3)=='/**') {
            if ($estado == 2) {
                $estado = 3;
            } else if ($estado == 0) {
                $estado = 1;
                $com = "";
            }
        }
        if ($estado == 1) {
            $com .= $buffer;
        }
        if (strstr($buffer, '*/')) {
            if ($estado == 2) {
                $estado = 3;
            } else if ($estado == 1 || $estado == 0) {
                $estado = 0;
            }
        }
        if (trim($buffer) == '?>' && $estado == 2) {
            $estado = 3;
        } 
        if ($estado == 2) {
            $lv .= $buffer;
        } 
    }

    fclose($f);
    return  $lv;
}


/**
 * Revisa si una versión de actualización ya se aplicó
 *
 * @param string $ver Versión
 *
 * @return bool si se aplicó o no
 */
function aplicado($ver) 
{
    echo "Revisando aplicación de actualización $ver: ";
    $ds = DB_DataObject::factory('Actualizacion_base');
    $ds->fecha = null;
    $ds->get($ver);
    if (PEAR::isError($ds) || $ds->id != $ver || $ds->fecha == null) {
        echo "No<br>\n";
        return false;
    }
        echo "Si<br>\n";
    return true;
}


$vf = valVarConf("confv.empty", "PRY_VERSION");
echo "Versión configurada: '$PRY_VERSION'<br>\n";
echo "Versión de fuentes: '$vf'<br>\n";

if ($PRY_VERSION != $vf) {
    die("<font color='red'>Desde un interprete de comandos, en el " .
        "directorio con fuentes ejecute <blockquote><pre>conf.sh -i</pre>" .
        "</blockquote> y después vuelva a cargar esta página</font>");
}

$n = $db->getOne('SELECT count(*) FROM actualizacion_base');
if (PEAR::isError($n)) {
    echo "Esta herramienta no maneja cambios anteriores a la versión 0.92<br>\n";
    echo "Esos cambios debe aplicarlos manualmente revisando Novedades.txt " .
        "y después volver a usar esta herramienta<br>\n";
    die("");
}

/* ==========================  OJO ==================================
 * Al agregar cambios a la estructura o datos de la base de datos en archivos
 * sql usados en instalaciones frescas, también poner el INSERT respectivo 
 * en actualizacion_base en datos-us.sql
 * ==================================================================
 */

if (!aplicado('0.92post')) {
    $db->query("ALTER TABLE categoria ADD COLUMN contada_en INTEGER " .
        "REFERENCES categoria"); 
    $cat = DB_DataObject::factory('categoria');
    if (PEAR::isError($cat)) {
        die("Problema: " . $cat->getMessage());
    }
    // EJECUCIÓN EXTRAJUDICIAL
    $cat = DataObjects_Categoria::staticGet('10'); $cat->contada_en='701'; 
    $cat->update(); 
    // AMENAZA
    $cat = DataObjects_Categoria::staticGet('15'); $cat->contada_en='73'; 
    $cat->update();
    // COLECTIVO AMENAZADO
    $cat = DataObjects_Categoria::staticGet('18'); $cat->contada_en='706'; 
    $cat->update();
    // TORTURA
    $cat = DataObjects_Categoria::staticGet('12'); $cat->contada_en='72'; 
    $cat->update();
    // HERIDO
    $cat = DataObjects_Categoria::staticGet('13'); $cat->contada_en='702'; 
    $cat->update();
    // VIOLENCIA SEXUAL
    $cat = DataObjects_Categoria::staticGet('19'); $cat->contada_en='77'; 
    $cat->update();
    // COLECTIVO DESPLAZADO
    $cat = DataObjects_Categoria::staticGet('102'); $cat->contada_en='903'; 
    $cat->update();
 
    $act = DB_DataObject::factory('Actualizacion_Base');
    $act->fecha = date('Y-M-d');
    $act->id = '0.92post';
    $act->descripcion = 'Categorias repetidas marcadas';
    $act->insert();
    echo $act->getMessage();
    echo "  Aplicada actualización 0.92post <br>\n";
}

if (!aplicado('0.94')) {
    $act = DB_DataObject::factory('Actualizacion_Base');
    $db = $act->getDatabaseConnection();
    $db->query("UPDATE opcion SET descripcion='Conteos V. Individuales' " .
        "WHERE id_opcion='51';");
    $db->query("UPDATE opcion SET descripcion='Conteos V. Combatientes' " .
        "WHERE id_opcion='52';");
    $db->query("UPDATE opcion SET descripcion='Menú Conteos' " .
        "WHERE id_opcion='50';");
    $act->fecha = date('Y-M-d');
    $act->id = '0.94';
    $act->descripcion = 'Conteos';
    $act->insert();
    echo $act->getMessage();
    echo "  Aplicada actualización 0.94<br>\n";
}

if (!aplicado('1.0')) {
    $act = DB_DataObject::factory('Actualizacion_Base');
    $db = $act->getDatabaseConnection();
    $db->query("ALTER TABLE victima ADD COLUMN anotaciones VARCHAR(1000)"); 
    $act->fecha = date('Y-M-d');
    $act->id = '1.0';
    $act->descripcion = 'Anotaciones en víctima';
    $act->insert();
    echo $act->getMessage();
    echo "  Aplicada actualización " . $act->id."<br>\n";
}

if (!aplicado('1.0cp3')) {
    $act = DB_DataObject::factory('Actualizacion_Base');
    $db = $act->getDatabaseConnection();

    // Consistencia en combatiente
    
    $nr = $db->getOne("SELECT COUNT(id) FROM combatiente " .
        "WHERE id_resultado_agresion IS NULL");
    if (PEAR::isError($nr)) {
	    die($nr->getMessage() . " - " . $nr->getUserInfo());
    }
    if ($nr > 0) {
        echo "<font color='red'>Antes de aplicar la actualización " .
	    "debe definir 'Resultados " .
	    "de Agresión' no especificados contra $nr " .
	    "combatientes de los siguientes casos: <br>";	
	$r = hace_consulta($db, "SELECT DISTINCT id_caso " .
	    "FROM combatiente WHERE id_resultado_agresion IS NULL");
	$row = array();
	$sep = "";
	while ($r->fetchInto($row)) {
		echo $sep . $row[0];
		$sep = ", ";
	}
        echo "</font>";
        die("");
    }

    hace_consulta($db, "ALTER TABLE combatiente ALTER " .
        "COLUMN id_resultado_agresion SET NOT NULL");

    // Consistencia en demográficas, no sabe y otros = SIN INFORMACION
    hace_consulta($db, "UPDATE victima SET id_rango_edad='6' " .
        "WHERE id_rango_edad IS NULL"); 
    hace_consulta($db, "ALTER TABLE victima ALTER id_rango_edad SET NOT NULL"); 
    hace_consulta($db, "UPDATE victima SET id_profesion='22' " .
        "WHERE id_profesion IS NULL"); 
    hace_consulta($db, "ALTER TABLE victima ALTER id_profesion SET NOT NULL"); 
    hace_consulta($db, "UPDATE victima SET id_filiacion='10' " .
        "WHERE id_filiacion IS NULL"); 
    hace_consulta($db, "ALTER TABLE victima ALTER id_filiacion SET NOT NULL"); 
    hace_consulta($db, "UPDATE victima SET id_sector_social='15' " .
        "WHERE id_sector_social IS NULL"); 
    hace_consulta($db, "ALTER TABLE victima ALTER id_sector_social SET NOT NULL"); 
    hace_consulta($db, "UPDATE victima SET id_organizacion='16' " .
        "WHERE id_organizacion IS NULL"); 
    hace_consulta($db, "ALTER TABLE victima ALTER id_organizacion SET NOT NULL"); 
    hace_consulta($db, "UPDATE victima SET id_vinculo_estado='38' " .
        "WHERE id_vinculo_estado IS NULL"); 
    hace_consulta($db, "ALTER TABLE victima ALTER id_vinculo_estado SET NOT NULL"); 
    hace_consulta($db, "UPDATE victima SET id_organizacion_armada='35' " .
        "WHERE id_organizacion_armada IS NULL"); 
    hace_consulta($db, "ALTER TABLE victima ALTER id_organizacion_armada " .
        "SET NOT NULL"); 


    // Nuevas categorias en marco NyN
    
    hace_consulta($db, "UPDATE parametros_reporte_consolidado " .
        "SET rotulo = 'RECLUTAMIENTO DE MENORES' WHERE no_columna='20'");
    hace_consulta($db, "UPDATE parametros_reporte_consolidado " .
        "SET rotulo = 'TOMA DE REHENES' WHERE no_columna='21'");
    hace_consulta($db, "INSERT INTO parametros_reporte_consolidado " .
        "(no_columna, rotulo, tipo_violencia, clasificacion) VALUES " .
        "(25, 'COLECTIVO CONFINADO', 'DIH', 'INTEGRIDAD')");

    $preins = "INSERT INTO categoria (id, fecha_creacion, " .
        "fecha_deshabilitacion, id_supracategoria, id_tipo_violencia, " .
        "col_rep_consolidado, nombre) VALUES ";
    hace_consulta($db, $preins . 
        "(196, '2008-10-20', NULL, 1, 'A', NULL, 'V.S. - ABUSO SEXUAL')");
    hace_consulta($db, $preins . 
        "(221, '2008-10-20', NULL, 2, 'A', 8, 'V.S. - VIOLACIÓN')");
    hace_consulta($db, $preins . 
        "(292, '2008-10-20', NULL, 2, 'A', 8, 'V.S. - EMBARAZO FORZADO')");
    hace_consulta($db, $preins .
        "(293, '2008-10-20', NULL, 2, 'A', 8, 'V.S. - PROSTITUCIÓN FORZADA')");
    hace_consulta($db, $preins .
        "(294, '2008-10-20', NULL, 2, 'A', 8, 'V.S. - ESTERILIZACIÓN FORZADA')");
    hace_consulta($db, $preins .
        "(295, '2008-10-20', NULL, 2, 'A', 8, 'V.S. - ESCLAVITUD SEXUAL')");
    hace_consulta($db, $preins .
        "(296, '2008-10-20', NULL, 2, 'A', NULL, 'V.S. - ABUSO SEXUAL')");
    hace_consulta($db, $preins .
        "(391, '2008-10-20', NULL, 3, 'A', 8, 'V.S. - VIOLACIÓN')");
    hace_consulta($db, $preins .
        "(392, '2008-10-20', NULL, 3, 'A', 8, 'V.S. - EMBARAZO FORZADO')");
    hace_consulta($db, $preins .
        "(393, '2008-10-20', NULL, 3, 'A', 8, 'V.S. - PROSTITUCIÓN FORZADA')");
    hace_consulta($db, $preins .
        "(394, '2008-10-20', NULL, 3, 'A', 8, 'V.S. - ESTERILIZACIÓN FORZADA')");
    hace_consulta($db, $preins .
        "(395, '2008-10-20', NULL, 3, 'A', 8, 'V.S. - ESCLAVITUD SEXUAL')");
    hace_consulta($db, $preins .
        "(771, '2008-10-20', NULL, 1, 'D', 12, 'VIOLACIÓN')");
    hace_consulta($db, $preins .
        "(772, '2008-10-20', NULL, 1, 'D', 12, 'EMBARAZO FORZADO')");
    hace_consulta($db, $preins .
        "(773, '2008-10-20', NULL, 1, 'D', 12, 'PROSTITUCIÓN FORZADA')");
    hace_consulta($db, $preins .
        "(774, '2008-10-20', NULL, 1, 'D', 12, 'ESTERILIZACIÓN FORZADA')");
    hace_consulta($db, $preins .
        "(775, '2008-10-20', NULL, 1, 'D', 12, 'ESCLAVITUD SEXUAL')");
    hace_consulta($db, $preins .
        "(776, '2008-10-20', NULL, 1, 'D', 12, 'ABUSO SEXUAL')");
    hace_consulta($db, $preins .
        "(191, '2008-10-20', NULL, 1, 'A', 8, 'V.S. - VIOLACIÓN')");
    hace_consulta($db, $preins .
        "(192, '2008-10-20', NULL, 1, 'A', 8, 'V.S. - EMBARAZO FORZADO');");
    hace_consulta($db, $preins .
        "(193, '2008-10-20', NULL, 1, 'A', 8, 'V.S. - PROSTITUCIÓN FORZADA')");
    hace_consulta($db, $preins .
        "(194, '2008-10-20', NULL, 1, 'A', 8, 'V.S. - ESTERILIZACIÓN FORZADA')");
    hace_consulta($db, $preins .
        "(195, '2008-10-20', NULL, 1, 'A', 8, 'V.S. - ESCLAVITUD SEXUAL')");
    hace_consulta($db, $preins .
        "(906, '2008-10-21', NULL, 1, 'D', NULL, 'CONFINAMIENTO')");
    hace_consulta($db, $preins .
        "(104, '2008-10-17', NULL, 1, 'A', 25, 'COLECTIVO CONFINADO')");


    $act->fecha = date('Y-M-d');
    $act->id = '1.0cp3';
    $act->descripcion = 'Consistencia demográficos, nuevas categorías';
    $act->insert();
    echo $act->getMessage();
    echo "  Aplicada actualización " . $act->id."<br>\n";
}



echo "Revisando variables de configuración PHP...<br>";
$vplant = extraeVarPHP('aut/conf.php.plantilla');
$vconf = extraeVarPHP('aut/conf.php');
$vc = "";
foreach ($vplant as $nv => $ld) {
    list($vv, $cv) = $ld;
    if (!isset($vconf[$nv])) {
        $vc .= "$cv\n$nv = $vv ;\n\n";
    }
}

if ($vc != "") {
    echo "<blockquote><font color='red'>Faltan variables en el archivo " .
        "aut/conf.php del directorio de fuentes, por favor añada al final " .
        "de ese archivo las siguientes líneas (haciendo los cambios que " .
        "encuentre necesarios) y vuelva a cargar esta página:<br><hr/>";
    echo "<pre>";
    echo htmlentities($vc);
    echo "</pre><hr/></font></blockquote>";
    die("");
}

if (isset($GLOBALS['menu_tablas_basicas'])) {
	$hayrep = false;
	foreach($GLOBALS['menu_tablas_basicas'] as $a) {
		if ($a['title'] == 'Reportes') {
			$hayrep = true;
		}
	}
	if (!$hayrep) {
		echo "<font color='red'>En el arreglo <tt>menu_tablas_basicas</tt> del archivo <tt>aut/conf.php</tt> falta:
<pre>
    array('title' => 'Reportes', 'url'=> null, 'sub' => array(
        array('title'=>'Columnas de Reporte Consolidado', 
            'url'=>'parametros_reporte_consolidado', 'sub'=>null),
        ),
    ),
</pre></font>";
	}
}
else {
	echo "<font color='red'>No se encontró variable global menu_tablas_basicas</font>";
}
       

?>
