--- /dev/null
+<?php
+/**
+ * Plugin Spip 2.0 Reloaded
+ * Ce que vous ne trouverez pas dans Spip 2.0
+ * (c) 2008 Cedric Morin
+ * Licence GPL
+ *
+ */
+
+if (!defined("_ECRIRE_INC_VERSION")) return;
+
+
+global $array_server;
+
+// fonction pour la premiere connexion a un serveur array
+function req_array_dist($host, $port, $login, $pass, $db='', $prefixe='', $ldap='') {
+ $GLOBALS['array_rappel_nom_base'] = false;
+# spip_log("Connexion vers $host, base $db, prefixe $prefixe "
+# . ($ok ? "operationnelle sur $link" : 'impossible'));
+
+ return array(
+ 'db' => $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++<intval($arg))
+ each($array_results[$hash]['res']);
+ return true;
+ }
+ if (isset($array_results[$hash]['iter'])) {
+ $array_results[$hash]['iter']['i'] = intval($arg);
+ return true;
+ }
+ return false;
+ }
+ elseif($store=='count'){
+ if (isset($array_results[$hash]['res']))
+ return count($array_results[$hash]['res']);
+ if (isset($array_results[$hash]['iter']))
+ return floor(($array_results[$hash]['iter']['fin']-$array_results[$hash]['iter']['debut'])/$array_results[$hash]['iter']['pas'])+1;
+ return false;
+ }
+ elseif($store=='free')
+ unset($array_results[$hash]);
+ else {
+ $hash = count($array_results)?max(array_keys($array_results))+1:1; // pas de 0 svp
+ // un tableau direct
+ if (is_array($store)){
+ $array_results[$hash]['res'] = $store;
+ reset($array_results[$hash]['res']);
+ }
+ elseif(is_string($store) AND strpos($store,':')!==FALSE){
+ $iter = explode(':',$store);
+ if (count($iter)==2 OR count($iter)==3)
+ $array_results[$hash]['iter']=array('debut'=>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.", '<multi>') = 0 , ".
+ " TRIM(".$objet."), ".
+ " CONCAT( ".
+ " LEFT(".$objet.", INSTR(".$objet.", '<multi>')-1), ".
+ " IF( ".
+ " INSTR(TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '<multi>')))),'[".$lang."]') = 0, ".
+ " IF( ".
+ " TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '<multi>')))) REGEXP '^\\[[a-z\_]{2,}\\]', ".
+ " INSERT( ".
+ " TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '<multi>')))), ".
+ " 1, ".
+ " INSTR(TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '<multi>')))), ']'), ".
+ " '' ".
+ " ), ".
+ " TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '<multi>')))) ".
+ " ), ".
+ " 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) . "'");
+}
+
+?>