Set sur des propriétés et actions à partir de $_GET / $_POST.

This commit is contained in:
Georges Dupéron 2010-10-15 16:59:20 +02:00
parent 2f3356b156
commit 01e73fed15
7 changed files with 125 additions and 45 deletions

View File

@ -4,6 +4,7 @@
// le droit de voir. Filtrage après la requête (attention au LIMIT et OFFSET !) ? // le droit de voir. Filtrage après la requête (attention au LIMIT et OFFSET !) ?
// ou y a-t-il moyen d'exprimer ça directement dans la requête ? // ou y a-t-il moyen d'exprimer ça directement dans la requête ?
// TODO : sécurité : faire une méthode select qui construise une requête sans risques de triche de la part de l'utilisateur. Idem pour insert / update etc.
class BDD { class BDD {
private static $handle = null; private static $handle = null;
@ -33,7 +34,7 @@ class BDD {
self::unbuf_query('create table if not exists ' . self::table("_modules") . ' (' self::unbuf_query('create table if not exists ' . self::table("_modules") . ' ('
. 'nom_module varchar(50) primary key' . 'nom_module varchar(50) primary key'
. ')'); . ')');
foreach (self::select('select * from ' . self::table("_modules")) as $module) { foreach (self::select('select nom_module from ' . self::table("_modules")) as $module) {
self::unbuf_query('drop table if exists ' . self::table($module["nom_module"])); self::unbuf_query('drop table if exists ' . self::table($module["nom_module"]));
} }
self::unbuf_query('drop table if exists ' . self::table("_modules")); self::unbuf_query('drop table if exists ' . self::table("_modules"));
@ -148,9 +149,20 @@ class BDD {
} }
public static function table($nom) { public static function table($nom) {
if (! preg_match('/^[a-zA-Z_]*$/', $nom)) {
Debug("erreur", "Nom de table malformé : " . htmlspecialchars(var_export($nom, true)) . ".");
}
return Config::get('db_prefixe') . $nom; return Config::get('db_prefixe') . $nom;
} }
public static function escape($str) {
return mysql_real_escape_string($str, self::get());
}
public static function escape_int($str) {
return intval($str);
}
public static function close() { public static function close() {
if (is_resource(self::$handle)) { if (is_resource(self::$handle)) {
self::commit(); self::commit();
@ -163,10 +175,12 @@ class BDD {
class BDDCell { class BDDCell {
private $uid_page; private $uid_page;
private $propriete; private $propriete;
private $type;
private $valeur; private $valeur;
public function __construct($uid_page, $propriete, $valeur) { public function __construct($uid_page, $propriete, $type, $valeur) {
$this->uid_page = $uid_page; $this->uid_page = $uid_page;
$this->propriete = $propriete; $this->propriete = $propriete;
$this->type = $type;
$this->valeur = $valeur; $this->valeur = $valeur;
} }
public function uid_page() { public function uid_page() {
@ -175,6 +189,9 @@ class BDDCell {
public function propriete() { public function propriete() {
return $this->propriete; return $this->propriete;
} }
public function type() {
return $this->type;
}
public function valeur() { public function valeur() {
return $this->valeur; return $this->valeur;
} }

View File

@ -10,7 +10,7 @@ class Config {
public static function get($nom) { public static function get($nom) {
if (!isset(self::$config[$nom])) { if (!isset(self::$config[$nom])) {
// Utilisation de die() plutôt que de $Debug->erreur car Debug n'est peut-être pas encore chargé. // Utilisation de die() plutôt que de Debug("erreur") car Debug n'est peut-être pas encore chargé.
echo "Variable de configuration manquante : $nom"; echo "Variable de configuration manquante : $nom";
die(); die();
} }
@ -27,7 +27,8 @@ require_once(dirname(__FILE__) . "/../config.php5");
if (Config::get('courriel_admin') === null) { if (Config::get('courriel_admin') === null) {
echo "Vous devez indiquer le courriel de l'administrateur dans le fichier config.php5 ."; echo "Vous devez indiquer le courriel de l'administrateur dans le fichier config.php5 .";
exit; // Utilisation de die() plutôt que de Debug("erreur") car Debug n'est peut-être pas encore chargé.
die();
} }

View File

@ -1,22 +1,40 @@
<?php <?php
// TODO : sécurité : permettre d'avoir des modèles pour les erreurs, et remplir des champs dedans, en échappant les méchants caractères etc.
// TODO : sécurité : ne pas faire de backtrace en production !
class _Debug { class _Debug {
public static $types_erreur = array( public static $types_erreur = array(
"erreur" => '<span style="color:red">Erreur</span>', "erreur" => '<span style="font-weight:bold;color:red;">Erreur</span>',
"niy" => '<span style="color:brown">Pas encore implémenté</span>', "warn" => '<span style="font-weight:bold;color:#ef6f00;">Attention</span>',
"info" => '<span style="color:blue">Info</span>', "info" => '<span style="color:blue;">Info</span>',
"sql" => 'Requête SQL', "utilisateur" => '<span style="font-weight:bold;color:red;">Erreur</span>',
"erreur_sql" => 'Erreur SQL', "niy" => '<span style="color:brown;">Pas encore implémenté</span>',
"permission" => '<span style="color:red">Permission non accordée</span>' "sql" => 'Requête SQL',
"erreur_sql" => '<span style="font-weight:bold;color:red;">Erreur SQL</span>',
"permission" => '<span style="font-weight:bold;color:red;">Permission non accordée</span>'
); );
public static $filtre_erreurs = array( public static $filtre_erreurs = array(
"erreur" => true, "erreur" => true,
"niy" => true, "warn" => true,
"info" => true, "info" => true,
"sql" => false, "niy" => true,
"erreur_sql" => true, "sql" => false,
"permission" => true "erreur_sql" => true,
"utilisateur" => true,
"permission" => true
); );
public static $filtre_erreurs_en_production = array(
"erreur" => false,
"warn" => false,
"info" => false,
"niy" => false,
"sql" => false,
"erreur_sql" => false,
"utilisateur" => true, // erreur générée par des données de l'utilisateur.
"permission" => true // permission non accordée.
);
public static $toutes_erreurs = false; // true <=> ignorer le filtre. public static $toutes_erreurs = false; // true <=> ignorer le filtre.
public static $erreurs = array(); public static $erreurs = array();
@ -55,7 +73,9 @@ class _Debug {
} }
if ($print) { if ($print) {
foreach (self::$erreurs as $e) { foreach (self::$erreurs as $e) {
if (self::$toutes_erreurs === true || self::$filtre_erreurs[$e[0]] === true) { if (self::$toutes_erreurs === true
|| (array_key_exists($e[0], self::$filtre_erreurs)
&& self::$filtre_erreurs[$e[0]] === true)) {
$ret .= self::$types_erreur[$e[0]] . " : " . $e[1] . "\n"; $ret .= self::$types_erreur[$e[0]] . " : " . $e[1] . "\n";
} }
} }

View File

@ -210,7 +210,7 @@ ElementDocument::add_widget("description", create_function('$d, $cell', '
ElementDocument::add_widget("field", create_function('$d, $cell', ' ElementDocument::add_widget("field", create_function('$d, $cell', '
$f = $d->span("field"); $f = $d->span("field");
$f->text("NIY : " . toString($cell)); $f->text("[(" . $cell->type() .")". $cell->propriete() . " = " . toString($cell) . "]");
return $f; return $f;
')); '));

View File

@ -9,8 +9,47 @@ verifications();
function main() { function main() {
initModules(); initModules();
// Attention ! ne pas garder BDD::reset() en production ! Debug("warn", "BDD::reset() est toujours activé, ne pas le garder en production !");
BDD::reset(); if (array_key_exists("reset_bdd", $_GET) && $_GET['reset_bdd'] == 'true') {
BDD::reset();
}
// TODO : should be $_POST .
foreach ($_GET as $k => $v) {
if (substr($k, 0, 4) == 'set_') {
$k = substr($k, 4);
$set_uid_page = substr($k, 0, strpos($k, '_'));
$set_nom_prop = substr($k, strpos($k, '_') + 1);
$set_page = mPage::page_uid($set_uid_page);
if ($set_page->has_prop($set_nom_prop)) {
$set_page->$set_nom_prop = $v;
} else {
Debug("warn", "Impossible d'effecturer la modification "
. "(uid_page = " . htmlspecialchars($set_uid_page)
. ", " . htmlspecialchars($set_nom_prop)
. " = " . htmlspecialchars($v) . ").");
}
}
}
// TODO : should be $_POST .
foreach ($_GET as $k => $v) {
if (substr($k, 0, 4) == 'act_') {
$k = substr($k, 4);
$act_uid_page = substr($k, 0, strpos($k, '_'));
$act_nom_action = "act_" . substr($k, strpos($k, '_') + 1);
$act_page = mPage::page_uid($act_uid_page);
if (method_exists($act_page, $act_nom_action)) {
call_user_func(array($act_page, $act_nom_action), $v);
} else {
Debug("warn", "Impossible d'exécuter l'action "
. htmlspecialchars($act_nom_action)
. " (uid_page = " . htmlspecialchars($act_uid_page) . ").");
}
}
}
$res = array_key_exists('res', $_GET) ? $_GET['res'] : null; $res = array_key_exists('res', $_GET) ? $_GET['res'] : null;
if (array_key_exists('uid_page', $_GET)) { if (array_key_exists('uid_page', $_GET)) {

View File

@ -141,7 +141,7 @@ class mPage {
attribut_global("composant_url", "text_nix", "page"); attribut_global("composant_url", "text_nix", "page");
} }
public static function est_propriete_globale($prop) { public static function est_attribut_global($prop) {
return array_key_exists($prop, self::$attributs_globaux); return array_key_exists($prop, self::$attributs_globaux);
} }
@ -205,11 +205,16 @@ class mPage {
// Renvoie l'uid de la page dans la base de données. // Renvoie l'uid de la page dans la base de données.
return $this->uid; return $this->uid;
} }
public function has_prop($nom) {
return array_key_exists($nom, self::$attributs_globaux)
|| array_key_exists($nom, $this->module['attributs']);
}
public function parent() { public function parent() {
return self::page_uid( return self::page_uid(
BDD::select_one( BDD::select_one(
"select uid_page_de from " . BDD::table("_liens") . " where uid_page_vers = " . $this->uid() "select uid_page_de from " . BDD::table("_liens") . " where uid_page_vers = " . BDD::escape_int($this->uid())
) )
); );
} }
@ -222,7 +227,7 @@ class mPage {
// limit = null || limit = 0 => pas de limite // limit = null || limit = 0 => pas de limite
// offset = null => offset = 0 // offset = null => offset = 0
// TODO : nettoyer la condition // TODO : nettoyer la condition (pbs de sécurité + bugs !!!).
if ($condition !== true) if ($condition !== true)
$condition = " and ($condition)"; $condition = " and ($condition)";
else else
@ -240,15 +245,15 @@ class mPage {
$select_order .= substr($o,1) . " "; $select_order .= substr($o,1) . " ";
$select_order .= (substr($o,0,1) == "+") ? "asc" : "desc"; $select_order .= (substr($o,0,1) == "+") ? "asc" : "desc";
} }
$select_limit = ($limit == 0) ? "" : " limit $limit"; $select_limit = ($limit == 0) ? "" : " limit " . BDD::escape_int($limit);
$select_offset = ($offset == 0) ? "" : " offset $offset"; $select_offset = ($offset == 0) ? "" : " offset " . BDD::escape_int($offset);
// TODO : "natural join" // TODO : "natural join"
$select = "select uid_page_vers from " $select = "select uid_page_vers from "
. BDD::table("_liens") . BDD::table("_liens")
. " join " . BDD::table("_pages") . " on _uid_page = uid_page_vers" . " join " . BDD::table("_pages") . " on _uid_page = uid_page_vers"
. " natural join " . BDD::table($this->type_liens("enfants")) . " natural join " . BDD::table($this->type_liens("enfants"))
. " where groupe = 'enfants' and uid_page_de = " . $this->uid() . " where groupe = 'enfants' and uid_page_de = " . BDD::escape_int($this->uid())
. $condition . $condition
. $select_order . $select_order
. $select_limit . $select_limit
@ -272,9 +277,9 @@ class mPage {
$insert .= ", _type = '" . $nom_module . "'"; $insert .= ", _type = '" . $nom_module . "'";
foreach (self::$attributs_globaux as $nom => $attr) { foreach (self::$attributs_globaux as $nom => $attr) {
if (array_key_exists($nom, $module['attributs'])) { if (array_key_exists($nom, $module['attributs'])) {
$insert .= ", $nom = '" . mysql_real_escape_string($module['attributs'][$nom]['defaut']) . "'"; $insert .= ", $nom = '" . BDD::escape($module['attributs'][$nom]['defaut']) . "'";
} else { } else {
$insert .= ", $nom = '" . mysql_real_escape_string($attr['defaut']) . "'"; $insert .= ", $nom = '" . BDD::escape($attr['defaut']) . "'";
} }
} }
@ -286,7 +291,7 @@ class mPage {
$insert .= "_uid_page = " . $uid_nouvelle_page; $insert .= "_uid_page = " . $uid_nouvelle_page;
foreach ($module['attributs'] as $nom => $attr) { foreach ($module['attributs'] as $nom => $attr) {
if (!$attr['global']) { if (!$attr['global']) {
$insert .= ", $nom = '" . mysql_real_escape_string($attr['defaut']) . "'"; $insert .= ", $nom = '" . BDD::escape($attr['defaut']) . "'";
} }
} }
@ -319,13 +324,13 @@ class mPage {
public static function page_systeme($nom) { public static function page_systeme($nom) {
return self::page_uid( return self::page_uid(
BDD::select_one( BDD::select_one(
"select _uid_page from " . BDD::table("_pages") . " where nom_systeme = '" . mysql_real_escape_string($nom) . "';" "select _uid_page from " . BDD::table("_pages") . " where nom_systeme = '" . BDD::escape($nom) . "';"
) )
); );
} }
public static function page_uid($uid) { public static function page_uid($uid) {
$select = "select _type from " . BDD::table("_pages") . " where _uid_page = " . $uid . ";"; $select = "select _type from " . BDD::table("_pages") . " where _uid_page = " . BDD::escape_int($uid) . ";";
$type = BDD::select_one($select); $type = BDD::select_one($select);
$ret = new $type(); $ret = new $type();
$ret->uid = $uid; $ret->uid = $uid;
@ -374,9 +379,15 @@ class mPage {
private function get_prop_direct($nom) { private function get_prop_direct($nom) {
// Récupère l'attribut "$nom" depuis la BDD. // Récupère l'attribut "$nom" depuis la BDD.
$select_table = (self::est_propriete_globale($nom)) ? "_pages" : $this->nom_module(); if (self::est_attribut_global($nom)) {
$select = "select $nom from " . BDD::table($select_table) . " where _uid_page = " . $this->uid() . ";"; $select_table = "_pages";
return new BDDCell($this->uid(), $nom, BDD::select_one($select)); $type = self::$attributs_globaux[$nom]['type'];
} else {
$select_table = $this->nom_module();
$type = $this->module['attributs'][$nom]['type'];
}
$select = "select $nom from " . BDD::table($select_table) . " where _uid_page = " . BDD::escape_int($this->uid()) . ";";
return new BDDCell($this->uid(), $nom, $type, BDD::select_one($select));
} }
public function __set($nom, $val) { public function __set($nom, $val) {
@ -391,8 +402,8 @@ class mPage {
public function set_prop_direct($nom, $val) { public function set_prop_direct($nom, $val) {
// Modifie l'attribut "$nom" dans la BDD. // Modifie l'attribut "$nom" dans la BDD.
$update_table = (self::est_propriete_globale($nom)) ? "_pages" : $this->nom_module(); $update_table = (self::est_attribut_global($nom)) ? "_pages" : $this->nom_module();
$update = "update " . BDD::table($update_table) . " set $nom = '" . mysql_real_escape_string(toString($val)) . "' where _uid_page = " . $this->uid(); $update = "update " . BDD::table($update_table) . " set $nom = '" . BDD::escape(toString($val)) . "' where _uid_page = " . $this->uid();
BDD::unbuf_query($update); BDD::unbuf_query($update);
if ($nom != "date_modification") { if ($nom != "date_modification") {
$this->date_modification = time(); $this->date_modification = time();

View File

@ -8,14 +8,6 @@ abstract class mGalerieBase extends mPage {
public static function info($module) { public static function info($module) {
$cvars = get_class_vars($module); $cvars = get_class_vars($module);
/* echo "<pre>";
var_dump($module);
var_dump($cvars);
echo "\n\n\n";
$cvars = get_class_vars("mGalerieBase");
var_dump($cvars);
echo "</pre>";
exit;*/
ressources_statiques("i_icone_nouvelle_page c_style"); ressources_statiques("i_icone_nouvelle_page c_style");
ressources_dynamiques("h_page h_miniature h_mini_miniature"); ressources_dynamiques("h_page h_miniature h_mini_miniature");
type_liens("enfants", $cvars['type_enfants']); type_liens("enfants", $cvars['type_enfants']);