| [ Index ] |
|
Code source de SPIP 1.9.2c |
1 <?php 2 3 /***************************************************************************\ 4 * SPIP, Systeme de publication pour l'internet * 5 * * 6 * Copyright (c) 2001-2007 * 7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * 8 * * 9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * 10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * 11 \***************************************************************************/ 12 13 if (!defined("_ECRIRE_INC_VERSION")) return; 14 15 //constantes spip pour spip_fetch_array() 16 define('SPIP_BOTH', MYSQL_BOTH); 17 define('SPIP_ASSOC', MYSQL_ASSOC); 18 define('SPIP_NUM', MYSQL_NUM); 19 20 // 21 // Appel de requetes SQL 22 // 23 24 // fonction pour la premiere connexion 25 26 // http://doc.spip.org/@base_db_mysql_dist 27 function base_db_mysql_dist() 28 { 29 // fichier d'init present ? 30 if (!_FILE_CONNECT) { 31 if ($GLOBALS['exec'] != 'install') // est-ce l'installation ? 32 return false; // non, faut faire sans 33 else return 'spip_query_db'; // oui; valeur d'office 34 } 35 36 include_once(_FILE_CONNECT); 37 if (!$GLOBALS['db_ok']) return false; 38 39 // Version courante = 0.3 40 // 41 // les versions 0.1 et 0.2 fonctionnent toujours, meme si : 42 // - la version 0.1 est moins performante que la 0.2 43 // - la 0.2 fait un include_ecrire('inc_db_mysql.php3') 44 // En tout cas on ne force pas la mise a niveau 45 if ($GLOBALS['spip_connect_version'] >= 0.1) 46 return 'spip_query_db'; 47 48 // La version 0.0 (non numerotee) doit etre refaite par un admin 49 50 if (!_DIR_RESTREINT) return false; 51 52 include_spip('inc/headers'); 53 redirige_par_entete(generer_url_ecrire('upgrade', 'reinstall=oui', true)); 54 } 55 56 // http://doc.spip.org/@spip_query_db 57 function spip_query_db($query) { 58 59 $query = traite_query($query); 60 61 $start = (isset($_GET['var_profile']) 62 AND isset($GLOBALS['auteur_session']['statut']) 63 AND ($GLOBALS['auteur_session']['statut'] == '0minirezo') 64 ) ? microtime() : 0; 65 66 return spip_mysql_trace($query, 67 $start, 68 (($GLOBALS['mysql_rappel_connexion'] AND $GLOBALS['spip_mysql_link']) ? 69 mysql_query($query, $GLOBALS['spip_mysql_link']) : 70 mysql_query($query))); 71 } 72 73 // http://doc.spip.org/@spip_mysql_trace 74 function spip_mysql_trace($query, $start, $result) 75 { 76 $s = mysql_errno(); 77 78 if ($start) spip_mysql_timing($start, microtime(), $query, $result); 79 80 if ($s) { 81 $s .= ' '.mysql_error(); 82 if ($GLOBALS['mysql_debug'] 83 AND (isset($GLOBALS['auteur_session']['statut'])) 84 AND ($GLOBALS['auteur_session']['statut'] == '0minirezo')) { 85 include_spip('public/debug'); 86 echo _T('info_erreur_requete'), 87 " ", 88 htmlentities($query), 89 "<br />« ", 90 htmlentities($result = $s), 91 " »<p>"; 92 } 93 spip_log($GLOBALS['REQUEST_METHOD'].' '.$GLOBALS['REQUEST_URI'], 'mysql'); 94 spip_log("$result - $query", 'mysql'); 95 spip_log($s, 'mysql'); 96 } 97 return $result; 98 } 99 100 // http://doc.spip.org/@spip_mysql_timing 101 function spip_mysql_timing($m1, $m2, $query, $result) 102 { 103 static $tt = 0; 104 list($usec, $sec) = explode(" ", $m1); 105 list($usec2, $sec2) = explode(" ", $m2); 106 $dt = $sec2 + $usec2 - $sec - $usec; 107 $tt += $dt; 108 echo "<small>", htmlentities($query), " -> <span style='color: blue'>", sprintf("%3f", $dt),"</span> (", $tt, ")</small> $result<p>\n"; 109 } 110 111 // fonction appelant la precedente specifiquement pour l'espace public 112 // c'est une instance de spip_abstract_select, voir ses specs dans abstract.php 113 // traite_query pourrait y est fait d'avance, à moindre cout. 114 // Les \n et \t sont utiles au debusqueur. 115 116 // La parametre sous_requete n'est plus utilise 117 118 // http://doc.spip.org/@spip_mysql_select 119 function spip_mysql_select($select, $from, $where, 120 $groupby, $orderby, $limit, 121 $sousrequete, $having, 122 $table, $id, $server) { 123 124 $query = (!is_array($select) ? $select : join(", ", $select)) . 125 (!$from ? '' : 126 ("\nFROM " . 127 (!is_array($from) ? $from : spip_select_as($from)))) 128 . (!$where ? '' : ("\nWHERE " . (!is_array($where) ? $where : (join("\n\tAND ", array_map('calculer_where', $where)))))) 129 . ($groupby ? "\nGROUP BY $groupby" : '') 130 . (!$having ? '' : "\nHAVING " . (!is_array($having) ? $having : (join("\n\tAND ", array_map('calculer_where', $having))))) 131 . ($orderby ? ("\nORDER BY " . join(", ", $orderby)) : '') 132 . ($limit ? "\nLIMIT $limit" : ''); 133 134 // Erreur ? C'est du debug de squelette, ou une erreur du serveur 135 136 if (isset($GLOBALS['var_mode']) AND $GLOBALS['var_mode'] == 'debug') { 137 include_spip('public/debug'); 138 boucle_debug_resultat($id, 'requete', "SELECT " . $query); 139 } 140 141 if (!($res = @spip_query("SELECT ". $query, $server))) { 142 include_spip('public/debug'); 143 erreur_requete_boucle($query, $id, $table, 144 spip_sql_errno(), 145 spip_sql_error()); 146 } 147 return $res; 148 } 149 150 // http://doc.spip.org/@calculer_where 151 function calculer_where($v) 152 { 153 if (!is_array($v)) 154 return $v ; 155 156 $op = array_shift($v); 157 if (!($n=count($v))) 158 return $op; 159 else { 160 $arg = calculer_where(array_shift($v)); 161 if ($n==1) { 162 return "$op($arg)"; 163 } else { 164 $arg2 = calculer_where(array_shift($v)); 165 if ($n==2) { 166 return "($arg $op $arg2)"; 167 } else return "($arg $op ($arg2) : $v[0])"; 168 } 169 } 170 } 171 172 // http://doc.spip.org/@spip_select_as 173 function spip_select_as($args) 174 { 175 $argsas = ""; 176 foreach($args as $k => $v) { 177 $argsas .= ', ' . $v . (is_numeric($k) ? '' : " AS `$k`"); 178 } 179 return substr($argsas,2); 180 } 181 182 // 183 // Passage d'une requete standardisee 184 // Quand tous les appels SQL seront abstraits on pourra l'ameliorer 185 186 // http://doc.spip.org/@traite_query 187 function traite_query($query) { 188 if ($GLOBALS['table_prefix']) $table_pref = $GLOBALS['table_prefix']."_"; 189 else $table_pref = ""; 190 191 if ($GLOBALS['mysql_rappel_nom_base'] AND $db = $GLOBALS['spip_mysql_db']) 192 $db = '`'.$db.'`.'; 193 194 // changer les noms des tables ($table_prefix) 195 if (preg_match('/\s(SET|VALUES|WHERE)\s/i', $query, $regs)) { 196 $suite = strstr($query, $regs[0]); 197 $query = substr($query, 0, -strlen($suite)); 198 } else $suite =''; 199 return preg_replace('/([,\s])spip_/', '\1'.$db.$table_pref, $query) . $suite; 200 } 201 202 // 203 // Fonction appelee uniquement par le fichier FILE_CONNECT cree a l'installation, 204 // et comportant les identifants de connexion SQL 205 // db_ok est globale, pour test par base_db_mysql_dist ci-dessus 206 // Ce serait plus propre de reduire FILE_CONNECT a un fichier de donnees 207 // et d'appeler cette fonction a partir de base_db_mysql_dist. 208 209 // http://doc.spip.org/@spip_connect_db 210 function spip_connect_db($host, $port, $login, $pass, $db) { 211 global $spip_mysql_link, $spip_mysql_db; // pour connexions multiples 212 213 // gerer le fichier tmp/mysql_out 214 ## TODO : ajouter md5(parametres de connexion) 215 if (@file_exists(_DIR_TMP.'mysql_out') 216 AND (time() - @filemtime(_DIR_TMP.'mysql_out') < 30) 217 AND !defined('_ECRIRE_INSTALL')) 218 return $GLOBALS['db_ok'] = false; 219 220 if ($port > 0) $host = "$host:$port"; 221 $spip_mysql_link = @mysql_connect($host, $login, $pass); 222 $spip_mysql_db = $db; 223 $ok = @mysql_select_db($db); 224 225 if (defined('_MYSQL_SQL_MODE_TEXT_NOT_NULL')) 226 mysql_query("set sql_mode=''"); 227 228 $GLOBALS['db_ok'] = $ok 229 AND !!@spip_num_rows(@spip_query_db('SELECT COUNT(*) FROM spip_meta')); 230 231 // En cas d'erreur marquer le fichier mysql_out 232 if (!$GLOBALS['db_ok'] 233 AND !defined('_ECRIRE_INSTALL')) { 234 @touch(_DIR_TMP.'mysql_out'); 235 $err = 'Echec connexion MySQL '.spip_sql_errno().' '.spip_sql_error(); 236 spip_log($err); 237 spip_log($err, 'mysql'); 238 } else $GLOBALS['db_ok'] = 'spip_query_db'; 239 return $GLOBALS['db_ok']; 240 } 241 242 // Fonction de creation d'une table SQL nommee $nom 243 // a partir de 2 tableaux PHP : 244 // champs: champ => type 245 // cles: type-de-cle => champ(s) 246 // si $autoinc, c'est une auto-increment (i.e. serial) sur la Primary Key 247 // Le nom des caches doit etre inferieur a 64 caracteres 248 249 // http://doc.spip.org/@spip_mysql_create 250 function spip_mysql_create($nom, $champs, $cles, $autoinc=false, $temporary=false) { 251 $query = ''; $keys = ''; $s = ''; $p=''; 252 253 // certains plugins declarent les tables (permet leur inclusion dans le dump) 254 // sans les renseigner (laisse le compilo recuperer la description) 255 if (!is_array($champs) || !is_array($cles)) 256 return; 257 258 foreach($cles as $k => $v) { 259 $keys .= "$s\n\t\t$k ($v)"; 260 if ($k == "PRIMARY KEY") 261 $p = $v; 262 $s = ","; 263 } 264 $s = ''; 265 266 foreach($champs as $k => $v) { 267 $query .= "$s\n\t\t$k $v" . 268 (($autoinc && ($p == $k)) ? " auto_increment" : ''); 269 $s = ","; 270 } 271 $temporary = $temporary ? 'TEMPORARY':''; 272 spip_query_db("CREATE $temporary TABLE IF NOT EXISTS $nom ($query" . ($keys ? ",$keys" : '') . ")\n"); 273 } 274 275 // http://doc.spip.org/@spip_mysql_showtable 276 function spip_mysql_showtable($nom_table) 277 { 278 $a = spip_query("SHOW TABLES LIKE '$nom_table'"); 279 if (!$a) return ""; 280 if (!spip_fetch_array($a)) return ""; 281 list(,$a) = spip_fetch_array(spip_query("SHOW CREATE TABLE $nom_table"),SPIP_NUM); 282 if (!preg_match("/^[^(),]*\((([^()]*\([^()]*\)[^()]*)*)\)[^()]*$/", $a, $r)) 283 return ""; 284 else { 285 $dec = $r[1]; 286 if (preg_match("/^(.*?),([^,]*KEY.*)$/s", $dec, $r)) { 287 $namedkeys = $r[2]; 288 $dec = $r[1]; 289 } 290 else 291 $namedkeys = ""; 292 293 $fields = array(); 294 foreach(preg_split("/,\s*`/",$dec) as $v) { 295 preg_match("/^\s*`?([^`]*)`\s*(.*)/",$v,$r); 296 $fields[strtolower($r[1])] = $r[2]; 297 } 298 $keys = array(); 299 300 foreach(preg_split('/\)\s*,?/',$namedkeys) as $v) { 301 if (preg_match("/^\s*([^(]*)\((.*)$/",$v,$r)) { 302 $k = str_replace("`", '', trim($r[1])); 303 $t = strtolower(str_replace("`", '', $r[2])); 304 if ($k && !isset($keys[$k])) $keys[$k] = $t; else $keys[] = $t; 305 } 306 } 307 return array('field' => $fields, 'key' => $keys); 308 } 309 } 310 311 // 312 // Recuperation des resultats 313 // 314 315 // interface de abstract_sql. 316 317 // http://doc.spip.org/@spip_mysql_fetch 318 function spip_mysql_fetch($r, $t=SPIP_ASSOC) { 319 if ($r) return mysql_fetch_array($r, $t); 320 } 321 322 // http://doc.spip.org/@spip_fetch_array 323 function spip_fetch_array($r, $t=SPIP_ASSOC) { 324 if ($r) return mysql_fetch_array($r, $t); 325 } 326 327 // http://doc.spip.org/@spip_sql_error 328 function spip_sql_error() { 329 return mysql_error(); 330 } 331 332 // http://doc.spip.org/@spip_sql_errno 333 function spip_sql_errno() { 334 return mysql_errno(); 335 } 336 337 // Interface de abstract_sql 338 // http://doc.spip.org/@spip_mysql_count 339 function spip_mysql_count($r) { 340 if ($r) return mysql_num_rows($r); 341 } 342 343 // http://doc.spip.org/@spip_num_rows 344 function spip_num_rows($r) { 345 if ($r) return mysql_num_rows($r); 346 } 347 348 // Interface de abstract_sql (on est sur de l'argument, c'est le compilateur) 349 350 // http://doc.spip.org/@spip_mysql_free 351 function spip_mysql_free($r) { 352 return mysql_free_result($r); 353 } 354 355 // Vieux nom a laisser tomber 356 // http://doc.spip.org/@spip_free_result 357 function spip_free_result($r) { 358 if ($r) return mysql_free_result($r); 359 } 360 361 // http://doc.spip.org/@spip_mysql_insert 362 function spip_mysql_insert($table, $champs, $valeurs) { 363 spip_query("INSERT INTO $table $champs VALUES $valeurs"); 364 return mysql_insert_id(); 365 } 366 367 // http://doc.spip.org/@spip_insert_id 368 function spip_insert_id() { 369 return mysql_insert_id(); 370 } 371 372 // 373 // Poser un verrou local a un SPIP donne 374 // 375 // http://doc.spip.org/@spip_get_lock 376 function spip_get_lock($nom, $timeout = 0) { 377 global $spip_mysql_db, $table_prefix; 378 if ($table_prefix) $nom = "$table_prefix:$nom"; 379 if ($spip_mysql_db) $nom = "$spip_mysql_db:$nom"; 380 381 // Changer de nom toutes les heures en cas de blocage MySQL (ca arrive) 382 define('_LOCK_TIME', intval(time()/3600-316982)); 383 $nom .= _LOCK_TIME; 384 385 $q = spip_query("SELECT GET_LOCK(" . _q($nom) . ", $timeout)"); 386 list($lock_ok) = spip_fetch_array($q,SPIP_NUM); 387 388 if (!$lock_ok) spip_log("pas de lock sql pour $nom"); 389 return $lock_ok; 390 } 391 392 // http://doc.spip.org/@spip_release_lock 393 function spip_release_lock($nom) { 394 global $spip_mysql_db, $table_prefix; 395 if ($table_prefix) $nom = "$table_prefix:$nom"; 396 if ($spip_mysql_db) $nom = "$spip_mysql_db:$nom"; 397 398 $nom .= _LOCK_TIME; 399 400 spip_query("SELECT RELEASE_LOCK(" . _q($nom) . ")"); 401 } 402 403 // http://doc.spip.org/@spip_mysql_version 404 function spip_mysql_version() { 405 $row = spip_fetch_array(spip_query("SELECT version() AS n")); 406 return ($row['n']); 407 } 408 409 // http://doc.spip.org/@creer_objet_multi 410 function creer_objet_multi ($objet, $lang) { 411 $retour = "(TRIM(IF(INSTR(".$objet.", '<multi>') = 0 , ". 412 " TRIM(".$objet."), ". 413 " CONCAT( ". 414 " LEFT(".$objet.", INSTR(".$objet.", '<multi>')-1), ". 415 " IF( ". 416 " INSTR(TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '<multi>')))),'[".$lang."]') = 0, ". 417 " IF( ". 418 " TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '<multi>')))) REGEXP '^\\[[a-z\_]{2,}\\]', ". 419 " INSERT( ". 420 " TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '<multi>')))), ". 421 " 1, ". 422 " INSTR(TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '<multi>')))), ']'), ". 423 " '' ". 424 " ), ". 425 " TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '<multi>')))) ". 426 " ), ". 427 " TRIM(RIGHT(".$objet.", ( LENGTH(".$objet.") - (INSTR(".$objet.", '[".$lang."]')+ LENGTH('[".$lang."]')-1) ) )) ". 428 " ) ". 429 " ) ". 430 "))) AS multi "; 431 432 return $retour; 433 } 434 435 436 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Wed Nov 21 10:20:27 2007 | par Balluche grâce à PHPXref 0.7 |
|