From e038560c5eed39411ef5a761fe32ad8de69982bb Mon Sep 17 00:00:00 2001 From: dj3c1t Date: Sun, 10 Nov 2013 21:22:13 +0100 Subject: [PATCH] upgrade 0.11.2 pour XML, MySql et SQLite --- mw/app/config.xml | 2 +- mw/app/controllers/index/index.php | 10 +- mw/app/controllers/upgrade/index.php | 1 + mw/app/data/impl/mw_mysql.php | 43 ++-- mw/app/data/impl/mw_pdo_sqlite.php | 20 +- .../data/modules/share/mw_data_check_instance.php | 49 ---- mw/app/data/modules/sql/mw_data_sql_crud.php | 169 ++++++++++++++ .../data/upgrades/sql/mtweb_sql_version_0_11_2.php | 260 +++++++++++++++++++++ .../data/upgrades/xml/mtweb_xml_version_0_11_2.php | 11 + mw/app/out/default/views/upgrade/index.php | 18 +- mw/env/modules/mw_env_config.php | 8 +- mw/env/modules/mw_env_data_upgrade.php | 84 +++++-- mw/mw_app.php | 13 +- mw/plugins/index.php | 0 mw/plugins/mw_minimal/mw_minimal.php | 138 ----------- 15 files changed, 580 insertions(+), 246 deletions(-) delete mode 100644 mw/app/data/modules/share/mw_data_check_instance.php create mode 100644 mw/app/data/upgrades/sql/mtweb_sql_version_0_11_2.php create mode 100644 mw/plugins/index.php delete mode 100644 mw/plugins/mw_minimal/mw_minimal.php diff --git a/mw/app/config.xml b/mw/app/config.xml index e10c828..500ddd4 100644 --- a/mw/app/config.xml +++ b/mw/app/config.xml @@ -1,7 +1,7 @@ - 0.11.3 + 0.11.4 #-- diff --git a/mw/app/controllers/index/index.php b/mw/app/controllers/index/index.php index 770f3bb..4b36820 100644 --- a/mw/app/controllers/index/index.php +++ b/mw/app/controllers/index/index.php @@ -6,11 +6,13 @@ $env = $this->env(); $start_action = $env->config("start_action"); if($start_action){ - $start_action_params = $env->config("start_action_params"); - if($start_action_params && is_array($start_action_params)){ - foreach($start_action_params as $key => $value) $_GET[$key] = $value; + if($env->get_controller($start_action)){ + $start_action_params = $env->config("start_action_params"); + if($start_action_params && is_array($start_action_params)){ + foreach($start_action_params as $key => $value) $_GET[$key] = $value; + } + $env->run($start_action); } - $env->run($start_action); } } diff --git a/mw/app/controllers/upgrade/index.php b/mw/app/controllers/upgrade/index.php index ecbb576..7b0752d 100644 --- a/mw/app/controllers/upgrade/index.php +++ b/mw/app/controllers/upgrade/index.php @@ -13,6 +13,7 @@ $data = $env->data(); $env->set_out("data_version", $data->version("mtweb")); $env->set_out("env_version", $env->version("mtweb")); + $env->set_out("data_upgrades", $env->data_upgrades()); } function confirm_upgrade(){ diff --git a/mw/app/data/impl/mw_mysql.php b/mw/app/data/impl/mw_mysql.php index 3d146c4..4f8e41d 100644 --- a/mw/app/data/impl/mw_mysql.php +++ b/mw/app/data/impl/mw_mysql.php @@ -65,25 +65,38 @@ return $desc; } - function table_exists($table){ + function table_exists($table_name){ if(!$this->link) $this->connect($this->host, $this->base, $this->user, $this->password); - $rst = $this->query("SHOW TABLES"); - while($v_rst = mysql_fetch_array($rst)){ - if(strcmp($v_rst[0], $table) == 0) return true; - } - mysql_free_result($rst); - return false; + $EXISTS = false; + try{ + $rst = $this->query("SHOW TABLES"); + while($v_rst = mysql_fetch_row($rst)){ + if($v_rst[0] == $table_name){ + $EXISTS = true; + break; + } + } + $this->free_result($rst); + } + catch(Exception $e){ + throw new Exception($this->exception_out("Impossible de savoir si la table existe")); + } + return $EXISTS; } function field_exists($table_name, $field_name){ - if(!$this->link) $this->connect($this->host, $this->base, $this->user, $this->password); - $sql = "SHOW COLUMNS FROM `".$table_name."` LIKE ".$field_name; - $rst = $this->query($sql); - $exists = false; - $v_rst = $this->fetch_assoc($rst); - if($v_rst) $exists = true; - $this->free_result($rst); - return $exists; + if(!$this->link) $this->connect($this->host, $this->base, $this->user, $this->password); + if(!($desc = $this->desc_table($table_name))){ + throw new Exception($this->exception_out("Impossible de lire la description de la table")); + } + $EXISTS = false; + foreach($desc["attributs"] as $attribut_name => $attribut){ + if($field_name == $attribut_name){ + $EXISTS = true; + break; + } + } + return $EXISTS; } function query($query_string){ diff --git a/mw/app/data/impl/mw_pdo_sqlite.php b/mw/app/data/impl/mw_pdo_sqlite.php index 4ef1696..1e4f68e 100644 --- a/mw/app/data/impl/mw_pdo_sqlite.php +++ b/mw/app/data/impl/mw_pdo_sqlite.php @@ -49,24 +49,26 @@ } function desc_table($table_name){ - $sql = "SELECT * from information_schema.columns where table_name='".$table_name."'"; - $rst = $this->query($sql); + if(strpos($table_name, "'") !== false){ + throw new Exception($this->exception_out("nom de table avec un simple quote")); + } $desc = array( "name" => $table_name, "attributs" => array() ); + $sql = "PRAGMA table_info(".$table_name.")"; try{ - while($v_rst = $this->fetch_assoc($rst)){ - $desc["attributs"][$v_rst["COLUMN_NAME"]] = array( - "name" => $v_rst["COLUMN_NAME"], - "prymary_key" => $v_rst["COLUMN_KEY"] == "PRI" ? true : false, - "auto_increment" => $v_rst["EXTRA"] == "auto_increment" ? true : false + $rst = $this->query($sql); + while($v_rst = $this->fetch_assoc($rst)){ + $desc["attributs"][$v_rst["name"]] = array( + "name" => $v_rst["name"], + "prymary_key" => isset($v_rst["pk"]) && $v_rst["pk"] ? true : false ); - } + } $this->free_result($rst); } catch(Exception $e){ - throw new Exception($this->exception_out("Impossible de lire la description de la table")); + throw new Exception($this->exception_out("impossible de lire les champs de la table ".$table_name)); } return $desc; } diff --git a/mw/app/data/modules/share/mw_data_check_instance.php b/mw/app/data/modules/share/mw_data_check_instance.php deleted file mode 100644 index 82f5a98..0000000 --- a/mw/app/data/modules/share/mw_data_check_instance.php +++ /dev/null @@ -1,49 +0,0 @@ -check_instance_normalise_config(); - return true; - } - - function check_instance_normalise_config(){ - $env = $this->env(); - if($env->bdd("sgbd") == "xml"){ - debug("start normalise config"); - $data = $env->data(); - $sgbd = $data->sgbd(); - $configs = array(); - $erreur = false; - if($rst = $sgbd->open_data("config")){ - while($v_rst = $sgbd->fetch_data($rst)){ - if(!isset($v_rst)){ - $erreur = "erreur lors de la lecture de la configuration (check_instance)"; - break; - } - if(!isset($v_rst["key"]) || !isset($v_rst["value"])){ - foreach($v_rst as $config_key => $config_value){ - $configs[$v_rst["id"]] = array( - "key" => $config_key, - "value" => $config_value - ); - break; - } - } - } - $sgbd->close_data($rst); - } - else return "impossible de lire la configuration (check_instance)"; - if($erreur) return $erreur; - foreach($configs as $config_id => $config){ - if(!$sgbd->set_data("config", $config_id, $config)){ - return "erreur lors de l'enregistrement de la configuration"; - } - } - return "end normalise config"; - } - } - - } - -?> \ No newline at end of file diff --git a/mw/app/data/modules/sql/mw_data_sql_crud.php b/mw/app/data/modules/sql/mw_data_sql_crud.php index 0d9abbd..3d1d210 100644 --- a/mw/app/data/modules/sql/mw_data_sql_crud.php +++ b/mw/app/data/modules/sql/mw_data_sql_crud.php @@ -3,6 +3,175 @@ class mw_data_sql_crud extends mw_data{ # ---------------------------------------------------------------------------------------- + # parametres du sgbd + # + + function set_sgbd_param($key, $value){ + $env = $this->env(); + if(($env->bdd("sgbd") == "pdo_mysql") || ($env->bdd("sgbd") == "mysql")){ + return $this->set_sgbd_mysql_param($key, $value); + } + return false; + } + + function set_sgbd_mysql_param($key, $value){ + $sgbd = $this->sgbd(); + $sql = "SET ".$key."=\"".$value."\""; + try{ + $sgbd->query($sql); + } + catch(Exception $e){ + return false; + } + return true; + } + + # ---------------------------------------------------------------------------------------- + # create table + # + + function data_create_table($params){ + $env = $this->env(); + if($env->bdd("sgbd") == "pdo_sqlite"){ + return $this->data_create_sqlite_table($params); + } + return $this->data_create_mysql_table($params); + } + + function data_create_mysql_table($params){ + $sgbd = $this->sgbd(); + $table_name = isset($params["table_name"]) ? $params["table_name"] : ""; + $fields = isset($params["fields"]) ? $params["fields"] : array(); + $keys = isset($params["keys"]) ? $params["keys"] : array(); + $options = isset($params["options"]) ? $params["options"] : array(); + if(!$table_name || !$fields) return false; + $sql_fields = ""; + $sql_keys = ""; + $sql_options = ""; + foreach($fields as $field_name => $field){ + if(!preg_match("/^[a-z]+[a-z_0-9]*$/", $field_name)) return false; + if(!isset($field["type"])) return false; + $sql_field = ""; + switch($field["type"]){ + case "int": + $value = isset($field["value"]) ? $field["value"] : "11"; + if(!preg_match("/^[0-9]+$/", $value)) return false; + $sql_field .= "`".$field_name."` int(".$value.")"; + break; + case "varchar": + $value = isset($field["value"]) ? $field["value"] : "255"; + if(!preg_match("/^[0-9]+$/", $value)) return false; + $sql_field .= "`".$field_name."` varchar(".$value.")"; + break; + case "text": + $sql_field .= "`".$field_name."` text"; + break; + case "date": + $sql_field .= "`".$field_name."` date"; + break; + case "datetime": + $sql_field .= "`".$field_name."` datetime"; + break; + } + if($sql_field){ + $null = isset($field["null"]) ? $field["null"] : false; + $sql_field .= ($null ? " DEFAULT" : " NOT")." NULL"; + if($null && isset($field["default"])){ + $sql_field .= " DEFAULT ".$this->eq($field["default"]); + } + if(isset($field["autoincrement"]) && $field["autoincrement"]){ + $sql_field .= " AUTO_INCREMENT"; + } + $sql_fields .= ($sql_fields ? ", " : "").$sql_field; + } + } + $key_index = 0; + foreach($keys as $key){ + $key_index++; + $sql_key_fields = ""; + foreach($key["fields"] as $key_field){ + $sql_key_fields .= ($sql_key_fields ? "," : "")."`".$key_field."`"; + } + $sql_key = "KEY `#--".$table_name."_".$key_index."`(".$sql_key_fields.")"; + if(isset($key["primary"]) && $key["primary"]){ + $sql_key = "PRIMARY ".$sql_key; + } + $sql_keys .= ($sql_keys ? ", " : "").$sql_key; + } + foreach($options as $option_name => $option_value){ + switch($option_name){ + case "default_charset": + $sql_options .= " DEFAULT CHARSET=".$option_value; + break; + } + } + $sql = "CREATE TABLE `#--".$table_name."`(".$sql_fields.", ".$sql_keys.")".$sql_options; + try{ + $sgbd->query($sql); + } + catch(Exception $e){ + return false; + } + return true; + } + + function data_create_sqlite_table($params){ + $sgbd = $this->sgbd(); + $table_name = isset($params["table_name"]) ? $params["table_name"] : ""; + $fields = isset($params["fields"]) ? $params["fields"] : array(); + $keys = isset($params["keys"]) ? $params["keys"] : array(); + $options = isset($params["options"]) ? $params["options"] : array(); + if(!$table_name || !$fields) return false; + $sql_fields = ""; + $sql_keys = ""; + $sql_options = ""; + foreach($fields as $field_name => $field){ + if(!preg_match("/^[a-z]+[a-z_0-9]*$/", $field_name)) return false; + if(!isset($field["type"])) return false; + $sql_field = ""; + switch($field["type"]){ + case "int": + $sql_field .= "`".$field_name."` INTEGER"; + break; + case "varchar": + case "text": + case "date": + case "datetime": + $sql_field .= "`".$field_name."` TEXT"; + break; + } + if($sql_field){ + $null = isset($field["null"]) ? $field["null"] : false; + $sql_field .= ($null ? " DEFAULT" : " NOT")." NULL"; + if($null && isset($field["default"])){ + $sql_field .= " DEFAULT ".$this->eq($field["default"]); + } + $sql_fields .= ($sql_fields ? ", " : "").$sql_field; + } + } + $key_index = 0; + foreach($keys as $key){ + if(isset($key["primary"]) && $key["primary"]){ + $key_index++; + $sql_key_fields = ""; + foreach($key["fields"] as $key_field){ + $sql_key_fields .= ($sql_key_fields ? "," : "")."`".$key_field."`"; + } + $sql_key = "PRIMARY KEY (".$sql_key_fields.")"; + $sql_keys .= ($sql_keys ? ", " : "").$sql_key; + } + } + $sql = "CREATE TABLE `#--".$table_name."`(".$sql_fields.", ".$sql_keys.")".$sql_options; + try{ + $sgbd->query($sql); + } + catch(Exception $e){ + return false; + } + return true; + } + + # ---------------------------------------------------------------------------------------- # description # diff --git a/mw/app/data/upgrades/sql/mtweb_sql_version_0_11_2.php b/mw/app/data/upgrades/sql/mtweb_sql_version_0_11_2.php new file mode 100644 index 0000000..6ca9c4c --- /dev/null +++ b/mw/app/data/upgrades/sql/mtweb_sql_version_0_11_2.php @@ -0,0 +1,260 @@ +env(); + $data = $env->data(); + $sgbd = $data->sgbd(); + + if(($env->bdd("sgbd") == "pdo_mysql") || ($env->bdd("sgbd") == "mysql")){ + if(!$data->set_sgbd_param("SQL_MODE", "NO_AUTO_VALUE_ON_ZERO")){ + return "imposible de parametrer SQL_MODE en NO_AUTO_VALUE_ON_ZERO"; + } + } + + /* ---------------------------------------------------------------------- + action_status + devient actions_roles + element id_status devient id_role + */ + + if(!$sgbd->table_exists("#--actions_roles")){ + if(!$sgbd->table_exists("#--action_status")){ + return "impossible de trouver la table action_status"; + } + if( + !$data->data_create_table( + array( + "table_name" => "actions_roles", + "fields" => array( + "id" => array("type" => "int", "autoincrement" => true), + "action" => array("type" => "varchar"), + "id_role" => array("type" => "int") + ), + "keys" => array( + array( + "fields" => array("id"), + "primary" => true + ), + array( + "fields" => array("id_role") + ) + ), + "options" => array("default_charset" => "utf8") + ) + ) + ){ + return "impossible de créer la table actions_roles"; + } + + $sql = + "INSERT INTO #--actions_roles(action, id_role)" + ." SELECT action, id_status" + ." FROM #--action_status"; + try{ + $sgbd->query($sql); + } + catch(Exception $e){ + return "impossible d'importer action_status dans actions_roles"; + } + $sql = + "INSERT INTO #--actions_roles(action, id_role) VALUES('config', 3)"; + try{ + $sgbd->query($sql); + } + catch(Exception $e){ + return "impossible d'ajouter la protection d'accès webmaster dans actions_roles"; + } + try{ + $sgbd->query("DROP TABLE #--action_status"); + } + catch(Exception $e){ + return "impossible de supprimer la table action_status"; + } + } + + /* ---------------------------------------------------------------------- + user_status + devient roles + plus d'element creation_default + nouvel element intitule + */ + + if(!$sgbd->table_exists("#--roles")){ + if(!$sgbd->table_exists("#--user_status")){ + return "impossible de trouver la table user_status"; + } + if( + !$data->data_create_table( + array( + "table_name" => "roles", + "fields" => array( + "id" => array("type" => "int", "autoincrement" => true), + "nom" => array("type" => "varchar"), + "intitule" => array("type" => "varchar") + ), + "keys" => array( + array( + "fields" => array("id"), + "primary" => true + ) + ), + "options" => array("default_charset" => "utf8") + ) + ) + ){ + return "impossible de créer la table roles"; + } + try{ + $sql = "INSERT INTO #--roles(id, nom, intitule) VALUES (0, 'guest', 'invité')"; + $sgbd->query($sql); + $sql = "INSERT INTO #--roles(id, nom, intitule) VALUES (1, 'admin', 'administrateur')"; + $sgbd->query($sql); + $sql = "INSERT INTO #--roles(id, nom, intitule) VALUES (2, 'membre', 'membre')"; + $sgbd->query($sql); + $sql = "INSERT INTO #--roles(id, nom, intitule) VALUES (3, 'webmaster', 'webmaster')"; + $sgbd->query($sql); + } + catch(Exception $e){ + return "impossible de remplir la table roles"; + } + try{ + $sgbd->query("DROP TABLE #--user_status"); + } + catch(Exception $e){ + return "impossible de supprimer la table user_status"; + } + } + + /* ---------------------------------------------------------------------- + nouvelle table users_roles + importer users.status dans users_roles.id_role + */ + + if(!$sgbd->table_exists("#--users_roles")){ + if( + !$data->data_create_table( + array( + "table_name" => "users_roles", + "fields" => array( + "id_user" => array("type" => "int"), + "id_role" => array("type" => "int") + ), + "keys" => array( + array( + "fields" => array("id_user", "id_role"), + "primary" => true + ), + array( + "fields" => array("id_role") + ) + ), + "options" => array("default_charset" => "utf8") + ) + ) + ){ + return "impossible de créer la table users_roles"; + } + if(($users = $data->data_list(array("table_name" => "users"))) === false){ + return "impossible de lire la table des utilisateurs"; + } + foreach($users["list"] as $user){ + if( + !$data->data_insert( + array( + "table_name" => "users_roles", + "values" => array( + "id_user" => $user["id"], + "id_role" => $user["status"] + ) + ) + ) + ){ + return "erreur lors de l'insertion des roles dans users_roles"; + } + } + $sql = "ALTER TABLE #--users RENAME TO #--users_tmp"; + try{ + $sgbd->query($sql); + } + catch(Exception $e){ + return "impossible de renommer la table users en users_tmp"; + } + if( + !$data->data_create_table( + array( + "table_name" => "users", + "fields" => array( + "id" => array("type" => "int", "autoincrement" => true), + "login" => array("type" => "varchar"), + "password" => array("type" => "varchar"), + "email" => array("type" => "varchar") + ), + "keys" => array( + array( + "fields" => array("id"), + "primary" => true + ) + ), + "options" => array("default_charset" => "utf8") + ) + ) + ){ + return "impossible de créer la table users"; + } + $sql = + "INSERT INTO #--users(id, login, password, email)" + ." SELECT id, login, password, email" + ." FROM #--users_tmp"; + try{ + $sgbd->query($sql); + } + catch(Exception $e){ + return "impossible d'importer users_tmp dans users"; + } + try{ + $sgbd->query("DROP TABLE #--users_tmp"); + } + catch(Exception $e){ + return "impossible de supprimer la table users_tmp"; + } + } + + /* ---------------------------------------------------------------------- + nouvelle table versions + */ + + if(!$sgbd->table_exists("#--versions")){ + if( + !$data->data_create_table( + array( + "table_name" => "versions", + "fields" => array( + "id" => array("type" => "int", "autoincrement" => true), + "application" => array("type" => "varchar"), + "version" => array("type" => "varchar") + ), + "keys" => array( + array( + "fields" => array("id"), + "primary" => true + ) + ), + "options" => array("default_charset" => "utf8") + ) + ) + ){ + return "impossible de créer la table versions"; + } + } + + return true; + } + + } diff --git a/mw/app/data/upgrades/xml/mtweb_xml_version_0_11_2.php b/mw/app/data/upgrades/xml/mtweb_xml_version_0_11_2.php index 1de687f..456e039 100644 --- a/mw/app/data/upgrades/xml/mtweb_xml_version_0_11_2.php +++ b/mw/app/data/upgrades/xml/mtweb_xml_version_0_11_2.php @@ -57,6 +57,17 @@ } } } + if( + !$sgbd->add_data( + "actions_roles", + array( + "action" => "config", + "id_role" => 3 + ) + ) + ){ + return "impossible d'ajouter la protection d'accès webmaster dans actions_roles"; + } if(!$sgbd->remove_data("action_status")){ return "impossible de supprimer la table action_status, dans ".get_class($this); } diff --git a/mw/app/out/default/views/upgrade/index.php b/mw/app/out/default/views/upgrade/index.php index 46137c1..296778a 100644 --- a/mw/app/out/default/views/upgrade/index.php +++ b/mw/app/out/default/views/upgrade/index.php @@ -1,10 +1,20 @@

Mise à jour des données

- La base de données doit être mise à jour pour - mtweb.out["env_version"]; ?>. + La base de données doit être mise à jour pour :

-

+ +out["data_upgrades"] as $application_name => $data_upgrade) : + if($data_upgrade->upgrade_required()) : + +?> + + + + +

- Cette opération est risquée. + Cette opération va faire des modifications dans la base de données.


faites une sauvegarde de vos données
diff --git a/mw/env/modules/mw_env_config.php b/mw/env/modules/mw_env_config.php
index 5f14e35..fcb85f2 100644
--- a/mw/env/modules/mw_env_config.php
+++ b/mw/env/modules/mw_env_config.php
@@ -160,8 +160,12 @@
       if(!$this->bdd("sgbd")) return "aucun sgbd defini";
       $data = $this->data();
       if(!$data) return "objet data non defini";
-      if(!$this->version("mtweb")) return "impossible de lire la version de mtweb";
-      if($data->version("mtweb") != $this->version("mtweb")) return "la version de la base et du code sont différentes";
+      if(($res = $this->data_upgrade_required()) !== false){
+        if($res === true){
+          return "la base de donnees doit etre mise a jour";
+        }
+        else return $res;
+      }
       return true;
     }
 
diff --git a/mw/env/modules/mw_env_data_upgrade.php b/mw/env/modules/mw_env_data_upgrade.php
index ff70f6a..1d65551 100644
--- a/mw/env/modules/mw_env_data_upgrade.php
+++ b/mw/env/modules/mw_env_data_upgrade.php
@@ -3,30 +3,67 @@
   class mw_env_data_upgrade extends mw_env{
 
     var $data_upgrades;
+    var $UPGRADE_REQUIRED;
+
+    function data_upgrades(){
+      return $this->data_upgrades;
+    }
 
     function init_data_upgrades(){
-      $data_upgrade = new mw_data_upgrade($this);
       $impl_dir = ($this->bdd("sgbd") == "xml" ? "xml" : "sql")."/";
       $versions_dir = $this->path("mw_dir")."app/data/upgrades/".$impl_dir;
-      if(!is_dir($versions_dir)){
-        return false;
+      if(is_dir($versions_dir)){
+        $data_upgrade = new mw_data_upgrade($this, "mtweb");
+        if(!$data_upgrade->load_versions($versions_dir)){
+          return "erreur lors de la lecture des versions";
+        }
+        if(!isset($this->data_upgrades)) $this->data_upgrades = array();
+        $this->data_upgrades["mtweb"] = $data_upgrade;
+
       }
-      if(!$data_upgrade->load_versions("mtweb", $versions_dir)){
-        return false;
+      if(($plugins = $this->plugins("ASC")) === false){
+        return "impossible de lire les upgrades pour les plugins";
+      }
+      foreach($plugins as $plugin_name => $plugin){
+        if(
+             $plugin["installed"]
+          && $plugin["enabled"]
+        ){
+          $versions_dir = $this->path("mw_dir")."plugins/".$plugin_name."/app/data/upgrades/".$impl_dir;
+          if(!is_dir($versions_dir)){
+            continue;
+          }
+          $data_upgrade = new mw_data_upgrade($this, $plugin_name);
+          if(!$data_upgrade->load_versions($versions_dir)){
+            return "erreur lors de la lecture des versions pour le plugin ".$plugin_name;
+          }
+          if(!isset($this->data_upgrades)) $this->data_upgrades = array();
+          $this->data_upgrades[$plugin_name] = $data_upgrade;
+        }
       }
       if(!isset($this->data_upgrades)) $this->data_upgrades = array();
-      $this->data_upgrades[] = $data_upgrade;
       return true;
     }
 
-    function data_upgrade_required(){
-      if(!isset($this->data_upgrades)) return false;
-      foreach($this->data_upgrades as $data_upgrade){
-        if($data_upgrade->upgrade_required()){
-          return true;
+    function data_upgrade_required($RELOAD = false){
+      if(!isset($this->data_upgrades)){
+        if(($res = $this->init_data_upgrades()) !== true){
+          return $res;
         }
       }
-      return false;
+      if(!isset($this->data_upgrades)){
+        return "impossible de charger les upgrades";
+      }
+      if($RELOAD || !isset($this->UPGRADE_REQUIRED)){
+        $this->UPGRADE_REQUIRED = false;
+        foreach($this->data_upgrades as $data_upgrade){
+          if($data_upgrade->upgrade_required()){
+            $this->UPGRADE_REQUIRED = true;
+            break;
+          }
+        }
+      }
+      return $this->UPGRADE_REQUIRED;
     }
 
     function do_data_upgrade(){
@@ -43,18 +80,20 @@
 
   class mw_data_upgrade{
 
+    var $application_name;
     var $versions;
     var $env;
 
-    function mw_data_upgrade($env){
+    function mw_data_upgrade($env, $application_name){
       $this->env = $env;
+      $this->application_name = $application_name;
     }
 
     function env(){
       return isset($this->env) ? $this->env : false;
     }
 
-    function load_versions($application_name, $versions_dir){
+    function load_versions($versions_dir){
       if($dh = opendir($versions_dir)){
         $versions_dir .= $versions_dir && substr($versions_dir, -1) != "/" ? "/" : "";
         while(($file = readdir($dh)) !== false){
@@ -62,7 +101,7 @@
                substr($file, 0, 1) != "."
             && !is_dir($versions_dir.$file)
             && strcmp(substr($file, -4), ".php") == 0
-          ) $this->load_version($application_name, $versions_dir, $file);
+          ) $this->load_version($versions_dir, $file);
         }
         closedir($dh);
       }
@@ -70,7 +109,7 @@
       return true;
     }
 
-    function load_version($application_name, $versions_dir, $version_file){
+    function load_version($versions_dir, $version_file){
       if(
            !$version_file
         || !file_exists($versions_dir.$version_file)
@@ -81,7 +120,7 @@
       $class_name = substr($version_file, 0, -4);
       if(!class_exists($class_name)) require_once $versions_dir.$version_file;
       if(!class_exists($class_name)) return false;
-      $version = new $class_name($this->env(), $application_name);
+      $version = new $class_name($this->env(), $this->application_name);
       return $this->add_version($version);
     }
 
@@ -110,7 +149,7 @@
 
     function upgrade_required(){
       if(!isset($this->versions)) return false;
-      foreach($this->versions as $version_number => $version){
+      foreach($this->versions as $version){
         if($version->upgrade_required()) return true;
       }
       return false;
@@ -118,12 +157,12 @@
 
     function do_upgrade(){
       if(!isset($this->versions)) return true;
-      foreach($this->versions as $version_number => $version){
+      foreach($this->versions as $version){
         if($version->upgrade_required() && ($res = $version->do_upgrade()) !== true){
           return $res." (dans ".get_class($version).")";
         }
         if(!$version->set_data_version()){
-          return "impossible de mettre a jour la version des donnees pour ".$version->application_name();
+          return "impossible de mettre a jour la version des donnees pour ".$this->application_name." ".$version->version();
         }
       }
       return true;
@@ -155,11 +194,11 @@
 
     function upgrade_required(){
       if(!isset($this->application_name)) return false;
+      if(!$this->version()) return false;
       $env = $this->env();
       $data = $env->data();
-      if(!($env_version = $env->version($this->application_name))) return false;
       if(!($data_version = $data->version($this->application_name))) return true;
-      return version_compare($data_version, $env_version) < 0;
+      return version_compare($data_version, $this->version()) < 0;
     }
 
     function do_upgrade(){
@@ -168,6 +207,7 @@
 
     function set_data_version(){
       if(!isset($this->application_name)) return false;
+      if(!$this->version()) return false;
       $env = $this->env();
       $data = $env->data();
       return $data->set_version($this->application_name, $this->version());
diff --git a/mw/mw_app.php b/mw/mw_app.php
index 5349b79..4355487 100644
--- a/mw/mw_app.php
+++ b/mw/mw_app.php
@@ -46,10 +46,16 @@
         return $this->get_error();
       }
       $env = $this->env();
-      if($env->data_upgrade_required()){
+      if(($res = $env->data_upgrade_required()) === true){
         $this->upgrade();
         exit;
       }
+      else{
+        if($res !== false){
+          $this->error($res);
+          return $this->get_error();
+        }
+      }
       return true;
     }
 
@@ -160,7 +166,10 @@
       $env->load_versions();
       $env->load_config($this->bdd, $this->config);
       $env->init();
-      $env->init_data_upgrades();
+      if(($res = $env->init_data_upgrades()) !== true){
+        $this->error("impossible de lire les upgrades. ".$res);
+        return false;
+      }
       return true;
     }
 
diff --git a/mw/plugins/index.php b/mw/plugins/index.php
new file mode 100644
index 0000000..e69de29
diff --git a/mw/plugins/mw_minimal/mw_minimal.php b/mw/plugins/mw_minimal/mw_minimal.php
deleted file mode 100644
index fd5ad8d..0000000
--- a/mw/plugins/mw_minimal/mw_minimal.php
+++ /dev/null
@@ -1,138 +0,0 @@
-
\ No newline at end of file
-- 
2.1.4