Sistema de auto-actualización

SISFOX cuenta con un sistema de auto-actualización.

¿Que significa?

Constantemente y por temas propios del desarrollo, se agregan, modifican o eliminan campos en la base de datos... o se modifica el contenido de ciertos archivos, o se cambia la estructura de carpetas, etc.

Estas variaciones estructurales, están fuertemente relacionadas con el código base de SISFOX. Por ejemplo, si para una tabla en particular agrego un campo, seguramente el mismo lo incluya en alguna consulta SQL dentro del código. Por consiguiente, si este campo no existe en la base de datos, nuestro script dará ERROR.

Veamos un ejemplo concreto.

El 17 de noviembre de 2013 se modificó la función banners, con el fin de imprimir en el tag img, el width y el height de la imagen.
Para una mejor performance, se decidió guardar estos datos, es decir el ancho y alto de la imagen, dentro de la base de datos.

Frente a esta situación, se presentan 2 cuestiones a actualizar.

  1. Deben existir en la tabla banners_txt estos 2 nuevos campos tanto en los proyectos existentes como para los nuevos proyectos, dado que existirán en el código como consulta y para la impresión en el tag correspondiente.
  2. Para los proyectos existentes y que ya cuenten con registros en dicha tabla, hay que actualizarlos con su ancho y alto correspondiente y grabarlos en la base.

Estas 2 acciones se pueden ver entonces a partir de la línea 59 en el archivo adm/upgrade/act2013-11.php.

if($fecha_actualizacion < '2013-11-17 23:36:00') {
	 	
		$cadena_final .= "<h3>17 de noviembre de 2013 / 23:36</h3>";
	
		if(!in_array("alto", $conn->MetaColumnNames($prefijo."banners_txt"))){
		
			$sql = "ALTER TABLE `".$prefijo."banners_txt` ADD COLUMN `alto` int(11) NOT NULL DEFAULT '0' AFTER `archivo`;";
			$cadena_final .= proceso_sql($sql);
			
		} // fin existencia campo id_categoria
		
		if(!in_array("ancho", $conn->MetaColumnNames($prefijo."banners_txt"))){
		
			$sql = "ALTER TABLE `".$prefijo."banners_txt` ADD COLUMN `ancho` int(11) NOT NULL DEFAULT '0' AFTER `archivo`;";
			$cadena_final .= proceso_sql($sql);
			
		} // fin existencia campo id_categoria
						
		if(!in_array("tipo", $conn->MetaColumnNames($prefijo."banners_txt"))){
		
			$sql = "ALTER TABLE `".$prefijo."banners_txt` ADD COLUMN `tipo` tinyint(1) NOT NULL DEFAULT '0' AFTER `alto`;";
			$cadena_final .= proceso_sql($sql);
			
		} // fin existencia campo id_categoria
						
		$sql = "SELECT * FROM ".$prefijo."banners_txt";
		$banners = $conn->GetArray($sql);
		
		foreach($banners as $bn)
		{
			
			if(!empty($bn["archivo"]))
			{
			
				$ruta_archivo = 'img/img-bnn/'.$bn["archivo"];
				
				if(file_exists($ruta_archivo))
				{
	
					list($ancho, $alto, $tipo, $atr) = getimagesize($ruta_archivo);
					
					$data["ancho"] = $ancho;
					$data["alto"] = $alto;
					$data["tipo"] = $tipo;
					$where = "id_banner = ".$bn["id_banner"]." AND idioma = '".$bn["idioma"]."'";
					$cadena_final .= modifico_datos($prefijo."banners_txt", $data, $where);
				
				}
		
			} // fin archivo vacío
			
		}
		
}

Pasos que se siguieron en este código:

  1. Se compara la fecha de actualización para definir si se ejecuta el código. La última fecha de actualización se graba en la base de datos y en la tabla actualizacion.
  2. Se imprime la fecha de actualización para el informe final.
  3. Se dan de alta los 3 nuevos campos: ancho, alto y tipo. Primero se los busca en la tabla correspondiente y de no existir, se ejecuta el SQL de creación.
  4. Se recorren todos los banners cargados y se carga la nueva información por cada uno de los registros existentes.

¿Cómo se ejecuta la auto-actualización?

En el proyecto, se envía por GET la variable actualizo.
Ejemplo: http://localhost/mi-proyecto.com/?actualizo=1

Desarrollo

El código general de auto-actualización se encuentra en master/adm/upgrade/index.php y se incluye en master/inc/header.php de modo que esté siempre accesible.

Obviamente solo se ejecuta si se pasa por GET la variable antes descripta.

Los pasos son básicamente:

  1. Chequeo si viene la variable $_GET["actualizo"] o $_GET["test"] para ejecutar el código
  2. También, si está conectado a la base de datos
  3. Defino en una variable, la fecha de la última actualización que se realizó. Este dato es muy importante ya que determina que actualizaciones ejecutar.
  4. Consulto en la tabla actualizacion, cuando fue la última que se ejecutó.
  5. Comparo entonces la fecha de última actualización con la última ejecutada, para evaluar si existe alguna por ejecutar. De existir, incluyo todos los archivos necesarios y dentro de los mismos, hago la misma comparación de fechas.

Diagrama de flujo.

Probar las actualizaciones antes de aplicarlas

Existe una forma que creé para probar las actualizaciones antes de aplicarlas finalmente en los archivos que correspondan.

Para hacerlo, basta simplemente con enviar por GET la variable test lo que hará que se ejecute el archivo que se encuentra en master/adm/upgrade/test.php

Ejemplo: http://localhost/mi-proyecto.com/?test=1

En este archivo, suelo armar todos los scripts que se ejecutarán para actualizar algo, pero de un modo que me permita ir probando si todo saldrá bien.

La diferencia está en que en este modo, no se actualiza la fecha en la tabla actualizacion, por lo que puedo ejecutar los scripts la cantidad de veces que quiera y necesite.

Tener en cuenta que si deseo ver la impresión de un resultado en pantalla debo cambiar $cadena_final por $cadena_test.