From ce08900d136a495a252167f8b9bc0d5566b7e021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Montan=CC=83ana?= Date: Sat, 5 Apr 2014 04:33:06 +0200 Subject: [PATCH] =?UTF-8?q?Programa=20de=20instalaci=C3=B3n=20casi=20termi?= =?UTF-8?q?nado.=20Incluido=20validador=20de=20formularios=20javascript.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG | 3 +- Instalar.php | 411 +++++++++++++++++++++++++++++++++++-------- css/validator.min.js | 9 + sql/setup.sql | 8 - 4 files changed, 351 insertions(+), 80 deletions(-) create mode 100755 css/validator.min.js diff --git a/CHANGELOG b/CHANGELOG index f0c8459..6d8ea7d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,5 @@ --creado el programa instalar.php que permitirá configurar el acceso a la base de datos, comprobar la configuración del servidor y la creación del usuario administrador +-Quitados los usuarios de ejemplo en el archivo setup.sql +-Creado el programa instalar.php que permitirá configurar el acceso a la base de datos, comprobar la configuración del servidor y la creación del usuario administrador -Añadido un parámetro en el archivo configuracion.inc que permite o no ejecutar el programa instalar.php Versión 1.07 31-03-2014 diff --git a/Instalar.php b/Instalar.php index 5822bff..72269b6 100644 --- a/Instalar.php +++ b/Instalar.php @@ -26,107 +26,152 @@ function __autoload($class_name) { } include 'inc/configuracion.inc'; define('NUMPASOS', 3); +//Para el Paso 1 define('MINBYTES', 4096000); // post_max_size y max_upload van con esto define('CADENAMINBYTES', '4M'); - -// Si ya se ha ejecutado con anterioridad esta script no continúa. -if (INSTALADO != 'no') { - echo "El programa ya está instalado"; - return 1; -} +define('CONFIGURACION', 'inc/configuracion.inc'); +define('CONFIGTMP', 'tmp/config.tmp'); +define('TMP', './tmp'); +define('INC', './inc'); $instalar = new Instalar(); -echo $instalar->ejecuta(); +if (!$instalar->error) { + echo $instalar->ejecuta(); +} else { + echo $instalar->cabecera(); + echo $instalar->panelMensaje($instalar->error_msj, "danger", "¡ERROR!"); + echo ""; +} class Instalar { - private $resultados; private $contenido; private $plant; + public $error; + public $error_msj; public function __construct() { //Selecciona la plantilla a utilizar $this->plant='plant/'; $this->plant.=PLANTILLA; - $this->plant.='.html';; + $this->plant.='.html'; + $this->error = false; + $this->eror_msj = ''; + if (INSTALADO != 'no') { + $this->error = true; + $this->error_msj = 'El programa ya está instalado'; + } + /*if ($this->existenDatos()) { + $this->error = true; + $this->error_msj = "El indicador de instalación tiene 'no' pero la base de datos " . BASEDATOS . " contiene la tabla Articulos."; + }*/ + } + + private function existenDatos() + { + //Comprueba si existe la tabla Articulos + $sql = new Sql(SERVIDOR, USUARIO, CLAVE, BASEDATOS); + if ($sql->error()) + return false; + $sql->ejecuta('select * from Articulos;'); + if ($sql->error()) + return false; + return true; } public function ejecuta() { $paso = isset($_GET['paso']) ? $_GET['paso'] : 0; $paso = $paso > NUMPASOS ? '0' : $paso; + $i=0; //Si quiere ir a un determinado paso se asegura que estén completos los anteriores for ($i = 0; $i < $paso; $i++) { - if (!$this->resultado[$i]) { - //$funcion = "paso" . $i; - //$this->contenido = $this->$funcion(); + $funcion = "validaPaso" . $i; + if (!$this->$funcion()) { break; } } - if ($paso == NUMPASOS) { - $this->contenido = $this->pasoFinal(); - } else { - $funcion = "paso" . $i; - $this->contenido = $this->$funcion(); - } + $funcion = "paso" . $i; + $this->contenido = $this->$funcion(); $salida = new Distribucion($this->plant, $this); return $salida->procesaPlantilla(); } - - private function inicializa() - { - for ($i = 0; $i < NUMPASOS; $i++) { - $funcion = "validaPaso" . $i; - $resultado[] = $funcion(); - } - } - - // Resumen de cuestiones realizadas - private function pasoFinal() - { - - } - + // Cuestiones relacionadas con el servidor private function paso0() { - $displayErr = ini_get('display_errors'); $info = ''; - if ($this->validaPaso0()) { - $boton = ''; - } else { - $boton = ''; - } - $info .= $boton; - $panel = $this->panelMensaje($info, 'info', 'PASO 1: Configuración del servidor'); + $info .= $this->retornaElemento($mensaje, 'extensión MySQLi', $mysql); + $info .= '
  • Configuración de la Aplicación
  • '; + // img.dat + $mensaje = is_writable(IMAGEDATA) ? $this->retornaLabel(false, "Se debe poder escribir en el directorio " . IMAGEDATA) : + $this->retornaLabel(true, "Se debe poder escribir en el directorio " . IMAGEDATA); + $valor = is_writable(IMAGEDATA) ? "Sí" : "No"; + $info .= $this->retornaElemento($mensaje, 'Se puede escribir en ' . IMAGEDATA, $valor); + + // tmp + $mensaje = is_writable(TMP) ? $this->retornaLabel(false, "Se debe poder escribir en el directorio " . TMP) : + $this->retornaLabel(true, "Se debe poder escribir en el directorio " . TMP); + $valor = is_writable(TMP) ? "Sí" : "No"; + $info .= $this->retornaElemento($mensaje, 'Se puede escribir en ' . TMP, $valor); + + // inc + $mensaje = is_writable(INC) ? $this->retornaLabel(false, "Se debe poder escribir en el directorio " . INC) : + $this->retornaLabel(true, "Se debe poder escribir en el directorio " . INC); + $valor = is_writable(INC) ? "Sí" : "No"; + $info .= $this->retornaElemento($mensaje, 'Se puede escribir en ' . INC, $valor); + + // configuracion.inc + $mensaje = is_writable(CONFIGURACION) ? $this->retornaLabel(false, "Se debe poder escribir en el fichero de configuración ". CONFIGURACION) : + $this->retornaLabel(true, "Se debe poder escribir en el fichero de configuración ". CONFIGURACION); + $valor = is_writable(CONFIGURACION) ? "Sí" : "No"; + $info .= $this->retornaElemento($mensaje, 'Se puede escribir en ' . CONFIGURACION, $valor); + + // Final del paso + $info .=''; + $info .= $this->validaPaso0() ? $this->retornaBoton(false, "instalar.php?paso=1") : $this->retornaBoton(true, "instalar.php"); + $panel = $this->panelMensaje($info, 'primary', 'PASO 1: Configuración del servidor y la aplicación'); return $panel; } + private function retornaElemento($validacion, $mensaje, $valor) + { + $info = '
  • '; + $info .= $validacion . ' ' . $mensaje . ': ' . $valor . ''; + $info .= '
  • '; + return $info; + } + + private function retornaBoton($error, $paso, $javascript = true) + { + $anadido = $javascript ? 'onclick="location.href=' . "'" . $paso . "'". '"' : ''; + if (!$error) { + return ''; + } else { + return ''; + } + } private function retornaLabel($error, $mensaje, $tipo = "danger") { @@ -164,38 +209,228 @@ class Instalar { $postMax = ini_get('post_max_size'); $uploadMax = ini_get('upload_max_filesize'); $mysql = extension_loaded('mysqli'); + $escConfig = is_writable(CONFIGURACION); + $escInc = is_writable(INC); + $escTMP = is_writable(TMP); + $escIMG = is_writable(IMAGEDATA); if ($this->retornaBytes($postMax) < MINBYTES) $validar = false; if ($this->retornaBytes($uploadMax) < MINBYTES) $validar = false; if (!$mysql) $validar = false; + if (!$escConfig) + $validar = false; + if (!$escTMP) + $validar = false; + if (!$escIMG) + $validar = false; + if (!$escInc) + $validar = false; return $validar; } // Cuestiones de la base de datos + private function paso1() + { + $grabar = isset($_POST['SERVIDOR']); + //Lee y si hace falta actualiza los datos del formulario en el fichero de configuración + $conf = new Configuracion(); + $fichero = $conf->obtieneFichero(); + $datos = explode("\n", $fichero); + if ($grabar) { + $fsalida = @fopen(CONFIGTMP, "wb"); + } + $campos = 'SERVIDOR,PUERTO,BASEDATOS,USUARIO,CLAVE'; + foreach ($datos as $linea) { + if (stripos($linea, "DEFINE") !== false) { + $conf->obtieneDatos($linea, $clave, $valor); + if (stripos($campos, $clave) !== false) { + if ($grabar) { + $linea = str_replace($valor, $_POST[$clave], $linea); + $valor = $_POST[$clave]; + } + } + $datos[$clave] = $valor; + } + $registro = substr($linea, 0, 2) == "?>" ? $linea : $linea . "\n"; + if ($grabar) { + fwrite($fsalida, $registro); + } + } + if ($grabar) { + fclose($fsalida); + unlink(CONFIGURACION); + rename(CONFIGTMP, CONFIGURACION); + if ($this->validaPaso1()) { + //Pasa al paso siguiente + return $this->paso2(); + } + } + + $info = '
    '; + $info .= ''; + $info .= $this->validaPaso1() ? $this->retornaBoton(false, "instalar.php?paso=1", false) : $this->retornaBoton(true, "instalar.php?paso=1", false); + $info .= '
    '; + $panel = $this->panelMensaje($info, 'primary', 'PASO 2: Configuración de la Base de Datos.'); + return $panel; + } + + private function validaPaso1() + { + $sql = new Sql(SERVIDOR, USUARIO, CLAVE, ''); + if ($sql->error()) + return false; + $sql = new Sql(SERVIDOR, USUARIO, CLAVE, BASEDATOS); + if ($sql->error()) { + return false; + } + $comando = 'create table test2 (id int(10));'; + $sql->ejecuta($comando); + if ($sql->error()) { + return false; + } + $comando = 'drop table test2;'; + $sql->ejecuta($comando); + if ($sql->error()) { + return false; + } + return true; + } + + // Usuario administrador private function paso2() { + if (isset($_POST['usuario'])) { + //ha enviado el formulario. + //Crea la base de datos + $borra_database = "DROP DATABASE IF EXISTS " . BASEDATOS . ";"; + $database = "CREATE DATABASE " . BASEDATOS . " DEFAULT CHARACTER SET utf8;"; + $articulos = "CREATE TABLE `Articulos` ( + `id` smallint(6) NOT NULL auto_increment COMMENT 'ordenable', + `descripcion` varchar(60) NOT NULL COMMENT 'ordenable,link/Articulo', + `marca` varchar(20) default NULL COMMENT 'ordenable', + `modelo` varchar(20) default NULL COMMENT 'ordenable', + `cantidad` int(11) default NULL COMMENT 'ordenable', + `imagen` varchar(45) default NULL COMMENT 'imagen', + PRIMARY KEY (`id`) + ) ENGINE=InnoDB AUTO_INCREMENT=769 DEFAULT CHARSET=utf8; + "; + $ubicaciones = "CREATE TABLE `Ubicaciones` ( + `id` smallint(5) unsigned NOT NULL auto_increment COMMENT 'ordenable', + `Descripcion` varchar(50) NOT NULL COMMENT 'ordenable,link/Ubicacion', + `imagen` varchar(45) DEFAULT NULL COMMENT 'imagen', + PRIMARY KEY (`id`) + ) ENGINE=InnoDB AUTO_INCREMENT=179 DEFAULT CHARSET=utf8; + "; + $elementos = "CREATE TABLE `Elementos` ( + `id` int(10) unsigned NOT NULL auto_increment COMMENT 'ordenable', + `id_Articulo` smallint(6) NOT NULL COMMENT 'foreign(Articulos;id),ordenable', + `id_Ubicacion` smallint(5) unsigned NOT NULL COMMENT 'foreign(Ubicaciones;id),ordenable', + `numserie` varchar(30) default NULL COMMENT 'ordenable', + `cantidad` int(10) unsigned default NULL COMMENT 'ordenable', + `fechaCompra` date NOT NULL COMMENT 'ordenable', + `imagen` varchar(45) default NULL COMMENT 'imagen', + PRIMARY KEY (`id`), + KEY `id` (`id`), + KEY `id_Articulo` (`id_Articulo`), + KEY `id_Ubicacion` (`id_Ubicacion`), + CONSTRAINT `Elementos_ibfk_1` FOREIGN KEY (`id_Articulo`) REFERENCES `Articulos` (`id`) ON DELETE CASCADE, + CONSTRAINT `Elementos_ibfk_2` FOREIGN KEY (`id_Ubicacion`) REFERENCES `Ubicaciones` (`id`) ON UPDATE CASCADE + ) ENGINE=InnoDB AUTO_INCREMENT=1789 DEFAULT CHARSET=utf8; + "; + $usuarios = "CREATE TABLE `Usuarios` ( + `id` int(10) unsigned NOT NULL auto_increment COMMENT 'ordenable', + `nombre` varchar(16) NOT NULL default '', + `clave` varchar(32) NOT NULL default '', + `idSesion` varchar(20) NOT NULL default '', + `alta` tinyint(1) NOT NULL default '0', + `modificacion` tinyint(1) NOT NULL default '0', + `borrado` tinyint(1) NOT NULL default '0', + `consulta` tinyint(1) NOT NULL default '1', + `informe` tinyint(1) NOT NULL default '1', + `usuarios` tinyint(1) NOT NULL default '0', + `config` tinyint(1) NOT NULL default '0', + PRIMARY KEY (`id`), + KEY `nombre` (`nombre`) + ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; + "; + $letras = "abcefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + $sesion = substr(str_shuffle($letras), 0, 8); + $usuario = $_POST['usuario']; + $clave = $_POST['clave']; + $administrador = "insert into Usuarios values (null,'$usuario','$clave','$sesion','1','1','1','1','1','1','1');"; + + @mysqli_query($borra_database); + @mysqli_query($database); + $sql = new Sql(SERVIDOR, USUARIO, CLAVE, BASEDATOS); + $sql->ejecuta($ubicaciones); + if ($sql->error()) { + return $this->panelMensaje($sql->mensajeError(), "danger", "ERROR"); + } + $sql->ejecuta($articulos); + if ($sql->error()) { + return $this->panelMensaje($sql->mensajeError(), "danger", "ERROR"); + } + $sql->ejecuta($elementos); + if ($sql->error()) { + return $this->panelMensaje($sql->mensajeError(), "danger", "ERROR"); + } + $sql->ejecuta($usuarios); + if ($sql->error()) { + return $this->panelMensaje($sql->mensajeError(), "danger", "ERROR"); + } + $sql->ejecuta($administrador); + if ($sql->error()) { + return $this->panelMensaje($sql->mensajeError(), "danger", "ERROR"); + } + return $this->resumen(); + } + $info = ' +
    +
    + +
    + +
    Mínimo 5 caracteres
    +
    +
    + +
    + +
    + + Mínimo 6 caracteres + +
    Mínimo 6 caracteres
    +
    +
    + +
    + +
    + +
    + '; + $panel = $this->panelMensaje($info, 'primary', 'PASO 3: Creación de la base de datos y el usuario administrador.'); + return $panel; } private function validaPaso2() { - return false; + //La validación de este paso se hace con la del formulario en javascript + return true; } - // Usuario administrador - private function paso3() - { - - } - - private function validaPaso3() - { - return false; - } - - private function panelMensaje($info, $tipo = "info", $cabecera = "¡Atención!") { + public function panelMensaje($info, $tipo = "info", $cabecera = "¡Atención!") { $mensaje = '
    '; $mensaje .= '

    ' . $cabecera . '

    '; $mensaje .= '
    '; @@ -238,11 +473,45 @@ class Instalar { public function fecha() { $idioma = 'es_ES'; - if ($formato == '') - $formato = "%d-%b-%y"; + $formato = "%d-%b-%y"; setlocale(LC_TIME, $idioma); return strftime($formato); } + public function cabecera() + { + return ' + + + + + + + + + + Inventario + + + + + + + + + + + + + + + '; + } + + private function resumen() + { + return 'Todo se ha hecho correctamente'; + + } } -?> +?> \ No newline at end of file diff --git a/css/validator.min.js b/css/validator.min.js new file mode 100755 index 0000000..591c37b --- /dev/null +++ b/css/validator.min.js @@ -0,0 +1,9 @@ +/*! + * Validator v0.2.1 for Bootstrap 3, by @1000hz + * Copyright 2014 Spiceworks, Inc. + * Licensed under http://opensource.org/licenses/MIT + * + * https://github.com/1000hz/bootstrap-validator + */ + ++function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=c,this.toggleSubmit(),this.$element.on("input.bs.validator blur.bs.validator",":input",a.proxy(this.validateInput,this)),this.$element.find("[data-match]").each(function(){var b=a(this),c=b.data("match");a(c).on("input.bs.validator",function(){b.val()&&b.trigger("input")})})};b.DEFAULTS={delay:500,errors:{match:"Does not match",minlength:"Not long enough"}},b.VALIDATORS={"native":function(a){var b=a[0];return b.checkValidity?b.checkValidity():!0},match:function(b){var c=b.data("match");return!b.val()||b.val()===a(c).val()},minlength:function(a){var b=a.data("minlength");return!a.val()||a.val().length>=b}},b.prototype.validateInput=function(b){var c,d=a(b.target),e=d.data("bs.errors");this.$element.trigger(b=a.Event("validate.bs.validator",{relatedTarget:d[0]})),b.isDefaultPrevented()||(d.data("bs.errors",c=this.runValidators(d)),c.length?this.showErrors(d):this.clearErrors(d),e&&c.toString()===e.toString()||(b=c.length?a.Event("invalid.bs.validator",{relatedTarget:d[0],detail:c}):a.Event("valid.bs.validator",{relatedTarget:d[0],detail:e}),this.$element.trigger(b)),this.toggleSubmit(),this.$element.trigger(a.Event("validated.bs.validator",{relatedTarget:d[0]})))},b.prototype.runValidators=function(c){{var d=[];[b.VALIDATORS.native]}return a.each(b.VALIDATORS,a.proxy(function(a,b){if((c.data(a)||"native"==a)&&!b.call(this,c)){var e=c.data(a+"-error")||c.data("error")||"native"==a&&c[0].validationMessage||this.options.errors[a];!~d.indexOf(e)&&d.push(e)}},this)),d},b.prototype.validate=function(){var a=this.options.delay;return this.options.delay=0,this.$element.find(":input").trigger("input"),this.options.delay=a,this},b.prototype.showErrors=function(b){function c(){var c=b.closest(".form-group"),d=c.find(".help-block.with-errors"),e=b.data("bs.errors");e.length&&(e=a("
      ").addClass("list-unstyled").append(a.map(e,function(b){return a("
    • ").text(b)})),void 0===d.data("bs.originalContent")&&d.data("bs.originalContent",d.html()),d.empty().append(e),c.addClass("has-error"))}this.options.delay?(window.clearTimeout(b.data("bs.timeout")),b.data("bs.timeout",window.setTimeout(c,this.options.delay))):c()},b.prototype.clearErrors=function(a){var b=a.closest(".form-group"),c=b.find(".help-block.with-errors");c.html(c.data("bs.originalContent")),b.removeClass("has-error")},b.prototype.hasErrors=function(){function b(){return!!(a(this).data("bs.errors")||[]).length}return!!this.$element.find(":input").filter(b).length},b.prototype.isIncomplete=function(){function b(){return""===a.trim(this.value)}return!!this.$element.find("[required]").filter(b).length},b.prototype.toggleSubmit=function(){var a=this.$element.find(":submit");a.attr("disabled",this.isIncomplete()||this.hasErrors())};var c=a.fn.validator;a.fn.validator=function(c){return this.each(function(){var d=a(this),e=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c),f=d.data("bs.validator");f||d.data("bs.validator",f=new b(this,e)),"string"==typeof c&&f[c]()})},a.fn.validator.Constructor=b,a.fn.validator.noConflict=function(){return a.fn.validator=c,this},a(window).on("load",function(){a('form[data-toggle="validator"]').each(function(){var b=a(this);b.validator(b.data())})})}(jQuery); \ No newline at end of file diff --git a/sql/setup.sql b/sql/setup.sql index 01fcf86..7bcefb8 100644 --- a/sql/setup.sql +++ b/sql/setup.sql @@ -98,15 +98,7 @@ CREATE TABLE `Usuarios` ( ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; SET character_set_client = @saved_cs_client; --- --- Usuarios iniciales --- -LOCK TABLES `Usuarios` WRITE; -/*!40000 ALTER TABLE `Usuarios` DISABLE KEYS */; -INSERT INTO `Usuarios` VALUES (1,'admin','pruebas','s3LUSqxg{s',1,1,1,1,1,1,1),(2,'demo','pruebas','NogP_U0Byi',0,0,0,1,1,0,0); -/*!40000 ALTER TABLE `Usuarios` ENABLE KEYS */; -UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;