$db, 'prefixe' => 'spip', 'link' => false, 'ldap' => '', ); } function array_get_var($table){ if (is_string($table) AND $t = unserialize($table)) $table = $t; if(is_string($table) AND strpos($table,':')!==FALSE){ $iter = explode(':',$table); if (count($iter)==2 AND is_numeric($iter[0]) AND is_numeric($iter[1])) $var = range($iter[0],$iter[1]); if (count($iter)==3 AND is_numeric($iter[0]) AND is_numeric($iter[1]) AND is_numeric($iter[2])) $var = range($iter[0],$iter[2],$iter[1]); return $var; // pas de copie necessaire } // $table doit toujours etre un array if (!is_array($table)) return null; // faisons une copie, sans le sous tableau recursif GLOBALS eventuel $var = array(); foreach($table as $k=>$v) if ($k !== 'GLOBALS') $var[$k] = $v; return $var; } function array_where_sql2php($where){ $where = preg_replace(",(^|\()([\w.]+)\s*REGEXP\s*(.+)($|\)),Uims","\\1preg_match('/'.str_replace('/','\/',\\3).'/Uims',\\2)\\4",$where); // == -> preg_match $where = preg_replace(",([\w.]+)\s*=,Uims","\\1==",$where); // = -> == $where = preg_replace(";^FIELD\(([^,]+),(.*)$;Uims","in_array(\\1,array(\\2)",$where); // IN -> FIELD -> in_array() $where = preg_replace(";(^|\(|\(\()([\w.]+)\s*IN\s*(.+)($|\)|\)\));Uims","in_array(\\2,array\\3",$where); // IN -> in_array() return $where; } function array_where_teste($cle,$valeur,$table,$where){ if (is_array($valeur)) $valeur = serialize($valeur); $where = preg_replace(array( ",(\W)$table\.cle(\W),i", ",(\W)cle(\W),i", ",(\W)$table\.valeur(\W),i", ",(\W)valeur(\W),i", ',NOT\(,i' ), array( "\\1'".addslashes($cle)."'\\2", "\\1'".addslashes($cle)."'\\2", "\\1'".addslashes($valeur)."'\\2", "\\1'".addslashes($valeur)."'\\2", "\\1!(" ),$where); return eval("if ($where) return true; else return false;"); } function calculer_array_where($v) { if (!is_array($v)) return array_where_sql2php($v) ; $op = array_shift($v); if (!($n=count($v))) return $op; else { $arg = calculer_array_where(array_shift($v)); if ($n==1) { return "$op($arg)"; } else { $arg2 = calculer_array_where(array_shift($v)); if ($n==2) { return array_where_sql2php("($arg $op $arg2)"); } else return "($arg $op ($arg2) : $v[0])"; } } } function array_query_filter($cle,$valeur,$table,$where){ static $wherec = array(); $hash = md5(serialize($where)); if (!isset($wherec[$hash])){ if (is_array($where)) $wherec[$hash] = implode("AND ",array_map('calculer_array_where',$where)); else $wherec[$hash] = calculer_array_where($where); } return array_where_teste($cle,$valeur,$table,$wherec[$hash]); } function array_results($hash,$store='get',$arg=null){ static $array_results = array(); if($store=='get'){ if (isset($array_results[$hash]['res'])){ return each($array_results[$hash]['res']); } if (isset($array_results[$hash]['iter'])) { $pas = $array_results[$hash]['iter']['pas']; $valeur = $array_results[$hash]['iter']['debut']+$array_results[$hash]['iter']['i']*$pas; if (($valeur>$array_results[$hash]['iter']['fin'] AND $pas>0) OR ($valeur<$array_results[$hash]['iter']['fin'] AND $pas<0)) return false; return array(++$array_results[$hash]['iter']['i'],$valeur); } return false; } elseif($store=='seek'){ if (isset($array_results[$hash]['res'])){ // pas de seek sur les tableaux, on emule avec reset+n each reset($array_results[$hash]['res']); $i=0; while ($i++reset($iter),'fin'=>end($iter),'pas'=>count($iter)==2?1:$iter[1],'i'=>0); } return $hash; } } // emulations array function array_query($query){ // pas de jointure, que des requetes simples // trouver le tableau de base, fourni en condition having // c'est un hack ... $table = null; if (!is_array($query['having'])) return -1; // on arrive pas ici par une boucle ! foreach($query['having'] as $k=>$w){ if (reset($w)=='tableau') $table = end($w); } // recuperer le pseudo nom de la table pour la condition where if (is_array($query['from'])) if (count($query['from'])!==1) return false; else $query['from'] = reset($query['from']); $res = array_get_var($table); // recuperer la table if (!$res OR !is_array($res)) $res = array(); // filtrons les resultats if ($query['where']){ foreach($res as $k=>$v){ if (!array_query_filter($k,$v,$query['from'],$query['where'])) unset($res[$k]); } } if ($query['orderby']){ // on ne prend que le premier critere $sort = is_array($query['orderby'])?reset($query['orderby']):$query['orderby']; $sort = str_replace($query['from'].".","",$sort); $sort = explode(',',$sort); $sort = reset($sort); // (POUR){par cle} if (preg_match(',^cle,',$sort)){ if (preg_match(',DESC$,i',$sort)) krsort($res); else ksort($res); } // (POUR){par valeur} else if (preg_match(',^valeur,',$sort)){ if (preg_match(',DESC$,i',$sort)) arsort($res); else asort($res); } // (POUR) {par XXX} : on considere que la valeur est un array, // et on trie nos array sur leur valeur XXX ; si ce sont des objets // on les caste en array else { preg_match(',^(.*)( DESC)?$,Ui', $sort, $tri); $sens = $tri[2] ? '<' : '>'; uasort($res, create_function('$a, $b', 'return ((is_string($a["'.$tri[1].'"]) AND is_string($b["'.$tri[1].'"]))? (strcasecmp($a["'.$tri[1].'"],$b["'.$tri[1].'"])'.$sens.'0) :((array)$a["'.$tri[1].'"] '.$sens.' (array) $b["'.$tri[1].'"])) ? 1 : -1;' ) ); } } if ($query['limit']){ $limit = explode(',',$query['limit']); $res = array_slice($res,$limit[0],$limit[1],true); } // regarder si il y a un count dans select foreach($query['select'] as $s){ if (preg_match(',^count\(,i',$s)) { $res = array(0=>count($res)); continue; } } // ici calculer un vrai res si la variable existe if (count($res)) { $hash = array_results(false,$res); return $hash; } return -1; // pas de resultats mais pas false non plus } // ----- $GLOBALS['spip_array_functions_1'] = array( 'count' => 'spip_array_count', 'countsel' => 'spip_array_countsel', 'errno' => 'spip_array_errno', 'error' => 'spip_array_error', 'explain' => 'spip_array_explain', 'fetch' => 'spip_array_fetch', 'seek' => 'spip_array_seek', 'free' => 'spip_array_free', 'hex' => 'spip_array_hex', 'in' => 'spip_array_in', 'listdbs' => 'spip_array_listdbs', 'multi' => 'spip_array_multi', 'optimize' => 'spip_array_optimize', 'query' => 'spip_array_query', 'quote' => 'spip_array_quote', 'select' => 'spip_array_select', 'selectdb' => 'spip_array_selectdb', 'set_charset' => 'spip_array_set_charset', 'get_charset' => 'spip_array_get_charset', 'showbase' => 'spip_array_showbase', 'showtable' => 'spip_array_showtable', ); function spip_array_set_charset($charset, $serveur=''){ #spip_log("changement de charset sql : "."SET NAMES "._q($charset)); return true; } function spip_array_get_charset($charset=array(), $serveur=''){ return false; } // Fonction de requete generale, munie d'une trace a la demande function spip_array_query($query, $serveur='') { $connexion = $GLOBALS['connexions'][$serveur ? $serveur : 0]; $prefixe = $connexion['prefixe']; $link = $connexion['link']; $db = $connexion['db']; $t = !isset($_GET['var_profile']) ? 0 : trace_query_start(); $r = array_query($query,$db); if ($e = spip_array_errno()) // Log de l'erreur eventuelle $e .= spip_array_error($query); // et du fautif return $t ? trace_query_end(var_export($query,true), $t, $r, $e) : $r; } // fonction instance de sql_select, voir ses specs dans abstract.php // Les \n et \t sont utiles au debusqueur. function spip_array_select($select, $from, $where='', $groupby='', $orderby='', $limit='', $having='', $serveur='',$requeter=true) { $from = (!is_array($from) ? $from : spip_array_select_as($from)); // pas de prefixage par nom de table dans array, une seule table a la fois ! $clean_prefix = trim($from)."."; $query = array( 'select'=>$select, 'from'=>$from, 'where'=>$where, 'groupby'=>$groupby, 'orderby'=>$orderby, 'limit'=>$limit); $querydump = var_export($query,1); $query['having'] = $having; // Erreur ? C'est du debug de squelette, ou une erreur du serveur if (isset($GLOBALS['var_mode']) AND $GLOBALS['var_mode'] == 'debug' AND function_exists('boucle_debug_requete')) { include_spip('public/debug'); boucle_debug_requete($querydump); } $res = spip_array_query($query, $serveur); if (!$res AND function_exists('boucle_debug_requete')) { include_spip('public/debug'); erreur_requete_boucle($querydump, spip_array_errno(), spip_array_error($query) ); } // renvoyer la requete inerte si demandee if ($requeter === false) return $querydump; return $res ? $res : $querydump; } // 0+x avec un champ x commencant par des chiffres est converti par array // en le nombre qui commence x. // Pas portable malheureusement, on laisse pour le moment. function spip_array_order($orderby) { return (is_array($orderby)) ? join(", ", $orderby) : $orderby; } function spip_array_select_as($args) { $argsas = ""; foreach($args as $k => $v) { if (strpos($v, 'JOIN') === false) $argsas .= ', '; $argsas .= $v;// PAS de AS en array : . (is_numeric($k) ? '' : " AS `$k`"); } return substr($argsas,2); } function spip_array_selectdb($db) { return true; } // Retourne les bases accessibles // Attention on n'a pas toujours les droits function spip_array_listdbs($serveur='') { return false; } function spip_array_showbase($match, $serveur='') { $res = array('pour'=>array('table'=>'pour'),'condition'=>array('table'=>'condition')); $match = str_replace('_','.',$match); $match = str_replace('%','.*',$match); $match = str_replace('\.*','%',$match); $match = str_replace('\.','_',$match); $match = ",^$match$,i"; foreach(array_keys($res) as $k) if (!preg_match($match,$k)) unset($res[$k]); $hash = array_results(false,$res); return $hash; } // pas fe SHOW en array, on renvoie une declaration type si la variable existe function spip_array_showtable($nom_table, $serveur='') { if (in_array(strtolower($nom_table),array('pour'))) return array('field'=>array('cle'=>'text','valeur'=>'text'),'key'=>array('PRIMARY KEY'=>'cle')); if (in_array(strtolower($nom_table),array('condition'))) return array('field'=>array('valeur'=>'text'),'key'=>array()); return false; } // // Recuperation des resultats // function spip_array_fetch($r, $t='', $serveur='') { if ($r AND $each = array_results($r)) { list($cle,$valeur) = $each; return array('valeur'=>$valeur,'cle'=>$cle); } return false; } function spip_array_seek($r, $row_number, $serveur='',$requeter=true) { return array_results($r,'seek',$row_number); } function spip_array_error($query='') { spip_log("Erreur - $query", 'array'); return false; } // A transposer dans les portages function spip_array_errno() { return false; } function spip_array_explain($query, $serveur='',$requeter=true){ return $query; } // Interface de abstract_sql function spip_array_count($r, $serveur='') { return array_results($r,'count'); } function spip_array_countsel($from = array(), $where = array(), $groupby = '', $limit = '', $sousrequete = '', $having = array(), $serveur='',$requeter=true) { $r = spip_array_select("*", $from, $where,'', '', $limit, $having, $serveur, $requeter); if (!$requeter) return $r; if (!$r) return 0; list($c) = spip_array_count($r,$serveur); spip_array_free($r,$serveur); return $c; } function spip_array_free($r, $serveur='') { array_results($r,'free'); return true; } function spip_array_multi ($objet, $lang) { $retour = "(TRIM(IF(INSTR(".$objet.", '') = 0 , ". " TRIM(".$objet."), ". " CONCAT( ". " LEFT(".$objet.", INSTR(".$objet.", '')-1), ". " IF( ". " INSTR(TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '')))),'[".$lang."]') = 0, ". " IF( ". " TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '')))) REGEXP '^\\[[a-z\_]{2,}\\]', ". " INSERT( ". " TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '')))), ". " 1, ". " INSTR(TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '')))), ']'), ". " '' ". " ), ". " TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '')))) ". " ), ". " TRIM(RIGHT(".$objet.", ( LENGTH(".$objet.") - (INSTR(".$objet.", '[".$lang."]')+ LENGTH('[".$lang."]')-1) ) )) ". " ) ". " ) ". "))) AS multi "; return $retour; } function spip_array_hex($v) { return "0x" . $v; } function spip_array_quote($v) { return _q($v); } // pour compatibilite function spip_array_in($val, $valeurs, $not='', $serveur='') { return calcul_array_in($val, $valeurs, $not); } // // IN (...) est limite a 255 elements, d'ou cette fonction assistante // function calcul_array_in($val, $valeurs, $not='') { if (is_array($valeurs)) $valeurs = join(',', array_map('_q', $valeurs)); if (!strlen(trim($valeurs))) return ($not ? "0=0" : '0=1'); $n = $i = 0; $in_sql =""; while ($n = strpos($valeurs, ',', $n+1)) { if ((++$i) >= 255) { $in_sql .= "($val $not IN (" . substr($valeurs, 0, $n) . "))\n" . ($not ? "AND\t" : "OR\t"); $valeurs = substr($valeurs, $n+1); $i = $n = 0; } } $in_sql .= "($val $not IN ($valeurs))"; return "($in_sql)"; } function spip_array_cite($v, $type) { if (sql_test_date($type) AND preg_match('/^\w+\(/', $v) OR (sql_test_int($type) AND (is_numeric($v) OR (ctype_xdigit(substr($v,2)) AND $v[0]=='0' AND $v[1]=='x')))) return $v; else return ("'" . addslashes($v) . "'"); } ?>