From ece300e2c76d5426f2c344967a817bdd94e3c393 Mon Sep 17 00:00:00 2001
From: "Committo,Ergo:sum" <esj@rezo.net>
Date: Wed, 1 Aug 2007 18:15:13 +0000
Subject: [PATCH] (#209): Introduction d'un jeu de fonctions permettant
 d'installer SPIP sur un serveur Postgres.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

ATTENTION: actuellement en PG seule l'installation fonctionne, il n'est pas possible de créer quoi que ce soit (article, auteur, etc). La version MySQL quant à elle reste opérationnelle bien entendu.

exec/accueil : standardisation SQL
inc/auth : standardisation SQL
inc/agenda: standardisation SQL
inc/boutons: standardisation SQL
inc/meta: remplacement de REPLACE (!)
base/db_pg: clone de db_mysql, à compléter.
---
 .gitattributes          |   1 +
 ecrire/base/db_pg.php   | 314 ++++++++++++++++++++++++++++++++++++++++
 ecrire/exec/accueil.php |   8 +-
 ecrire/inc/agenda.php   |   8 +-
 ecrire/inc/auth.php     |   8 +-
 ecrire/inc/boutons.php  |   2 +-
 ecrire/inc/meta.php     |  12 +-
 7 files changed, 337 insertions(+), 16 deletions(-)
 create mode 100644 ecrire/base/db_pg.php

diff --git a/.gitattributes b/.gitattributes
index 401fd8887e..b990601168 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -400,6 +400,7 @@ ecrire/balise/index.php -text
 ecrire/base/admin_repair.php -text
 ecrire/base/convert_sql_utf8.php -text
 ecrire/base/convert_utf8.php -text
+ecrire/base/db_pg.php -text
 ecrire/base/delete_all.php -text
 ecrire/base/import_all.php -text
 ecrire/base/index.php -text
diff --git a/ecrire/base/db_pg.php b/ecrire/base/db_pg.php
new file mode 100644
index 0000000000..7622210758
--- /dev/null
+++ b/ecrire/base/db_pg.php
@@ -0,0 +1,314 @@
+<?php
+
+/***************************************************************************\
+ *  SPIP, Systeme de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright (c) 2001-2007                                                *
+ *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
+ *                                                                         *
+ *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
+ *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
+\***************************************************************************/
+
+
+if (!defined("_ECRIRE_INC_VERSION")) return;
+
+//constantes spip pour spip_fetch_array()
+define('SPIP_BOTH', PGSQL_BOTH);
+define('SPIP_ASSOC', PGSQL_ASSOC);
+define('SPIP_NUM', PGSQL_NUM);
+
+// Se connecte et retourne le nom de la fonction a connexion persistante
+
+function base_db_pg_dist($addr, $port, $login, $pass, $db='') {
+	global $spip_pg_link;
+
+	@list($host, $p) = split(';', $addr);
+	if ($p >0) $port = " port=$p" ; else $port = '';
+	if ($db) $db= " dbname=$db";
+	$spip_pg_link = pg_connect("host=$host$port$db  user=$login password=$pass");
+	if ($spip_pg_link) return 'spip_pg_query';
+
+	spip_log("pas d'acces vers $host:$port sur $db pour $login");
+	return false;
+}
+
+// Fonction de requete generale. 
+// Passe la main pour les idiosyncrasies MySQL a traduire
+
+function spip_pg_query($query)
+{
+	global $spip_pg_link, $table_prefix;
+
+	if (strpos($query, 'REPLACE') ===0)
+		return spip_pg_replace($query);
+	// changer les noms des tables ($table_prefix)
+	if (preg_match('/\s(SET|VALUES|WHERE)\s/i', $query, $regs)) {
+		$suite = strstr($query, $regs[0]);
+		$query = substr($query, 0, -strlen($suite));
+	} else $suite ='';
+	$query = preg_replace('/([,\s])spip_/', '\1'.$table_prefix.'_', $query) . $suite;
+
+	$r = pg_query($spip_pg_link, $query);
+
+	return $r;
+}
+
+
+function spip_pg_replace($query) {
+  spip_log("REPLACE a implementer en postgres");
+}
+
+
+//  Qu'une seule base pour le moment
+
+function spip_pg_selectdb($db) {
+	return pg_dbname();
+}
+
+// Qu'une seule base pour le moment
+
+function spip_pg_listdbs() {
+	return array();
+}
+
+function spip_pg_select($select, $from, $where,
+                           $groupby, $orderby, $limit,
+                           $sousrequete, $having,
+                           $table, $id, $serveur){
+	global $spip_pg_link;
+	if (eregi("^([0-9]+), *([0-9]+)$", $limit,$match))
+	      {
+		$offset = $match[1];
+		$count = $match[2];
+	      }
+
+	$q =  (!is_array($select) ? $select : join(", ", $select)) .
+	  (!$from ? '' :
+			("\nFROM " .
+			(!is_array($from) ? $from : spip_pg_select_as($from))))
+	  . (!$where ? '' : ("\nWHERE " . (!is_array($where) ? $where : (join("\n\tAND ", array_map('calculer_pg_where', $where))))))
+	  . ($groupby ? "\nGROUP BY $groupby" : '')
+	  . (!$having ? '' : "\nHAVING " . (!is_array($having) ? $having : (join("\n\tAND ", array_map('calculer_where', $having)))))
+	  . ($orderby ? ("\nORDER BY " . join(", ", $orderby)) : '')
+	  . (!$limit ? '' : (" LIMIT $count" . (!$offset ? '' : " OFFSET $offset")));
+		$q = " SELECT ". $q;
+
+	// Erreur ? C'est du debug, ou une erreur du serveur
+	// il faudrait mettre ici le déclenchement du message SQL
+	// actuellement dans erreur_requete_boucle
+
+	if ($GLOBALS['var_mode'] == 'debug') {
+		boucle_debug_resultat($id, '', $q);
+	}
+
+	if (!($res = spip_pg_query($q))) {
+		include_spip('inc/debug_sql.php');
+		erreur_requete_boucle($q, $id, $table,
+				      spip_pg_errno(),
+				      spip_pg_error());
+	}
+#	spip_log("selectabs $q" . pg_numrows($res));
+	return $res;
+}
+
+
+function calculer_pg_where($v)
+{
+	if (!is_array($v))
+	  return $v ;
+
+	$op = array_shift($v);
+	if (!($n=count($v)))
+		return $op;
+	else {
+		$arg = calculer_pg_where(array_shift($v));
+		if ($n==1) {
+			  return "$op($arg)";
+		} else {
+			$arg2 = calculer_pg_where(array_shift($v));
+			if ($n==2) {
+				return "($arg $op $arg2)";
+			} else return "($arg $op ($arg2) : $v[0])";
+		}
+	}
+}
+
+function spip_pg_select_as($args)
+{
+	$argsas = "";
+	foreach($args as $k => $v) {
+	  $argsas .= ', ' . $v . ((is_numeric($k) OR $v==$k) ? '' : " AS $k");
+	}
+	return substr($argsas,2);
+}
+
+function spip_pg_fetch($res, $extra='') {
+	  static $n = array();
+	  if ($extra) spip_log("fetch argument 2: $extra a revoir");
+	  if ($res) $res = pg_fetch_array($res, $n[$res]++, PGSQL_ASSOC);
+	  return $res;
+}
+ 
+// http://doc.spip.org/@spip_fetch_array
+function spip_fetch_array($r, $extra='') {
+	  if ($extra) spip_log("fetch argument 2: $extra a revoir");
+	  if ($r) return pg_fetch_array($r);
+}
+
+function spip_pg_count($res, $serveur='') {
+		return !$res ? 0 : pg_numrows($res);
+}
+  
+function spip_pg_free($res, $serveur='') {
+  // rien à faire en postgres
+}
+
+function spip_pg_insert($table, $champs, $valeurs, $ignore='') {
+	global $tables_principales;
+	global $spip_pg_link, $table_prefix;
+	include_spip('base/serial.php');
+	if (isset($tables_principales[$table]['key']["PRIMARY KEY"]))
+		$ret = " RETURNING "
+		. $tables_principales[$table]['key']["PRIMARY KEY"];
+	else $ret = '';
+	if ($GLOBALS['table_prefix'])
+		$table = preg_replace('/^spip/',
+				    $GLOBALS['table_prefix'],
+				    $table);
+	$r = pg_query($spip_pg_link, "INSERT INTO $table $champs VALUES $valeurs $ret");
+	if (!$r) return 0;
+	if (!$ret) return -1;
+	$r = pg_fetch_array($r, 0, PGSQL_NUM);
+
+	return $r[0];
+}
+
+function spip_pg_update($table, $exp, $where='') {
+	global $spip_pg_link, $table_prefix;
+	if ($GLOBALS['table_prefix'])
+		$table = preg_replace('/^spip/',
+				    $GLOBALS['table_prefix'],
+				    $table);
+	pg_query($spip_pg_link, "UPDATE $table SET $exp" . ($where ? " WHERE $where" : ''));
+}
+
+
+function spip_pg_error() {
+	return pg_last_error();
+}
+
+function spip_pg_errno() {
+	return pg_last_error() ? 1 : 0;
+}
+
+function spip_pg_showtable($nom_table)
+{
+	spip_log("spip_pg_showtable('$nom_table') a definir");
+}
+
+function calcul_pg_in($val, $valeurs, $not='') {
+//
+// IN (...) souvent limite a 255  elements, d'ou cette fonction assistante
+//
+	if (!$valeurs) return '0=0';
+	$s = split(',', $valeurs, 255);
+	if (count($s) < 255) {
+		return ("($val $not IN ($valeurs))");
+	} else {
+		$valeurs = array_pop($s);
+		return ("($val $not IN (" . join(',',$s) . "))\n" .
+			($not ? "AND\t" : "OR\t") .
+			calcul_pgsql_in($val, $valeurs, $not));
+    }
+}
+
+// Fonction de creation d'une table SQL nommee $nom
+// a partir de 2 tableaux PHP :
+// champs: champ => type
+// cles: type-de-cle => champ(s)
+// si $autoinc, c'est une auto-increment (i.e. serial) sur la Primary Key
+// Le nom des caches doit etre inferieur a 64 caracteres
+function spip_pg_create($nom, $champs, $cles, $autoinc=false, $temporary=false) {
+	global $spip_pg_link;
+	if ($GLOBALS['table_prefix'])
+		$nom = preg_replace('/^spip/',
+				    $GLOBALS['table_prefix'],
+				    $nom);
+	$query = $prim = $s = $p='';
+	$keys = array();
+
+	// certains plugins declarent les tables  (permet leur inclusion dans le dump)
+	// sans les renseigner (laisse le compilo recuperer la description)
+	if (!is_array($champs) || !is_array($cles)) 
+		return;
+
+	foreach($cles as $k => $v) {
+		if (strpos($k, "KEY ") === 0) {
+		  $n = str_replace('`','',$k);	
+		  $v = str_replace('`','"',$v);	
+		  $i = $nom . preg_replace("/KEY +/", '_',$n);
+		  if ($k != $n) $i = "\"$i\"";
+		  $keys[] = "CREATE INDEX $i ON $nom ($v);";
+		} else $prim .= "$s\n\t\t" . str_replace('`','"',$k) ." ($v)";
+		if ($k == "PRIMARY KEY")
+			$p = $v;
+		$s = ",";
+	}
+	$s = '';
+	
+	$character_set = "";
+	if (@$GLOBALS['meta']['charset_sql_base'])
+		$character_set .= " CHARACTER SET ".$GLOBALS['meta']['charset_sql_base'];
+	if (@$GLOBALS['meta']['charset_collation_sql_base'])
+		$character_set .= " COLLATE ".$GLOBALS['meta']['charset_collation_sql_base'];
+
+	foreach($champs as $k => $v) {
+		$k = str_replace('`','"',$k);
+		if (preg_match(',([a-z]*\s*(\(\s*[0-9]*\s*\))?(\s*binary)?),i',$v,$defs)){
+			if (preg_match(',(char|text),i',$defs[1]) AND !preg_match(',binary,i',$defs[1]) ){
+				$v = $defs[1] . $character_set . ' ' . substr($v,strlen($defs[1]));
+			}
+		}
+
+		$query .= "$s\n\t\t$k "
+			. (($autoinc && ($p == $k) && preg_match(',\b(big)?int\b,i', $v))
+				? " bigserial"
+			   : mysql2pg_type($v)
+			);
+		$s = ",";
+	}
+	$temporary = $temporary ? 'TEMPORARY':'';
+
+	// controler si la table existe deja serait pas mal
+
+	$q = "CREATE $temporary TABLE $nom ($query" . ($prim ? ",$prim" : '') . ")".
+	($character_set?" DEFAULT $character_set":"")
+	."\n";
+
+	pg_query($spip_pg_link, $q);
+	foreach($keys as $index)  {pg_query($spip_pg_link, $index);}
+}
+
+// Palanquee d'idiosyncrasies MySQL dans les creations de table
+// A completer par les autres, mais essayer de reduire en amont.
+
+function mysql2pg_type($v)
+{
+  return     preg_replace('/bigint\s*[(]\d+[)]/i', 'bigint', 
+	preg_replace("/longtext/i", 'text',
+		str_replace("mediumtext", 'text',
+		preg_replace("/tinytext/i", 'text',
+	  	str_replace("longblob", 'text',
+	  	str_replace("datetime", 'timestamp',
+		str_replace("0000-00-00",'1970-01-01',
+		   preg_replace("/unsigned/i", '', 	
+		   preg_replace("/double/i", 'double precision', 	
+		   preg_replace("/tinyint/i", 'int', 	
+		     str_replace("VARCHAR(255) BINARY", 'bytea', 
+				 preg_replace("/ENUM *[(][^)]*[)]/", "varchar(255)",
+					      $v 
+				 ))))))))))));
+}
+
+?>
diff --git a/ecrire/exec/accueil.php b/ecrire/exec/accueil.php
index 4c351dbd5f..3928879a59 100644
--- a/ecrire/exec/accueil.php
+++ b/ecrire/exec/accueil.php
@@ -295,7 +295,7 @@ function etat_base_accueil()
 
 	$res .= propre($GLOBALS['meta']["descriptif_site"]);
 
-	$q = spip_query("SELECT COUNT(*) AS cnt, statut FROM spip_articles GROUP BY statut HAVING cnt <>0");
+	$q = spip_query("SELECT COUNT(*) AS cnt, statut FROM spip_articles GROUP BY statut HAVING COUNT(*)<>0");
   
 	$cpt = array();
 	$cpt2 = array();
@@ -320,7 +320,7 @@ function etat_base_accueil()
 		$res .= "</ul>";
 	}
 
-	$q = spip_query("SELECT COUNT(*) AS cnt, statut FROM spip_breves GROUP BY statut HAVING cnt <>0");
+	$q = spip_query("SELECT COUNT(*) AS cnt, statut FROM spip_breves GROUP BY statut HAVING COUNT(*)<>0");
 
 	$cpt = array();
 	$cpt2 = array();
@@ -345,7 +345,7 @@ function etat_base_accueil()
 		$res .= "</ul>";
 	}
 
-	$q = spip_query("SELECT COUNT(*) AS cnt, statut FROM spip_forum WHERE statut IN ('publie', 'prop') GROUP BY statut HAVING cnt <>0");
+	$q = spip_query("SELECT COUNT(*) AS cnt, statut FROM spip_forum WHERE statut IN ('publie', 'prop') GROUP BY statut HAVING COUNT(*)<>0");
 
 	$cpt = array();
 	$cpt2 = array();
@@ -387,7 +387,7 @@ function accueil_liste_participants()
 {
 	global $spip_lang_left;
 
-	$q = spip_query("SELECT COUNT(*) AS cnt, statut FROM spip_auteurs GROUP BY statut HAVING cnt <>0 AND statut IN (".  _q($GLOBALS['liste_des_statuts']) . ")");
+	$q = spip_query("SELECT COUNT(*) AS cnt, statut FROM spip_auteurs GROUP BY statut HAVING COUNT(*)<>0 AND statut IN (".  _q($GLOBALS['liste_des_statuts']) . ")");
 
 	$cpt = array();
 	while($row=spip_fetch_array($q)) $cpt[$row['statut']] = $row['cnt']; 
diff --git a/ecrire/inc/agenda.php b/ecrire/inc/agenda.php
index cdc450917d..ced445bcfd 100644
--- a/ecrire/inc/agenda.php
+++ b/ecrire/inc/agenda.php
@@ -1435,7 +1435,7 @@ function sql_calendrier_interval_rv($avant, $apres) {
 	global $connect_id_auteur;
 	$evenements= array();
 	if (!$connect_id_auteur) return $evenements;
-	$result=spip_query("SELECT messages.id_message, messages.titre, messages.texte, messages.date_heure, messages.date_fin, messages.type FROM spip_messages AS messages, spip_auteurs_messages AS lien WHERE	((lien.id_auteur='$connect_id_auteur' AND	lien.id_message=messages.id_message) OR messages.type='affich') AND	messages.rv='oui'  AND	((messages.date_fin >= $avant OR messages.date_heure >= $avant) AND messages.date_heure <= $apres) AND	messages.statut='publie' GROUP BY messages.id_message ORDER BY messages.date_heure");
+	$result=spip_query("SELECT messages.id_message, messages.titre, messages.texte, messages.date_heure, messages.date_fin, messages.type FROM spip_messages AS messages, spip_auteurs_messages AS lien WHERE	((lien.id_auteur=$connect_id_auteur AND	lien.id_message=messages.id_message) OR messages.type='affich') AND	messages.rv='oui'  AND	((messages.date_fin >= $avant OR messages.date_heure >= $avant) AND messages.date_heure <= $apres) AND	messages.statut='publie' GROUP BY messages.id_message ORDER BY messages.date_heure");
 	while($row=spip_fetch_array($result)){
 		$date_heure=$row["date_heure"];
 		$date_fin=$row["date_fin"];
@@ -1453,7 +1453,7 @@ function sql_calendrier_interval_rv($avant, $apres) {
 		    else {
 		      $cat = 'calendrier-couleur9';
 		      $auteurs = array();
-		      $result_aut=spip_query("SELECT nom FROM spip_auteurs AS auteurs, spip_auteurs_messages AS lien WHERE	(lien.id_message='$id_message'  AND	(auteurs.id_auteur!='$connect_id_auteur'  AND	lien.id_auteur=auteurs.id_auteur))");
+		      $result_aut=spip_query("SELECT nom FROM spip_auteurs AS auteurs, spip_auteurs_messages AS lien WHERE	(lien.id_message=$id_message  AND	(auteurs.id_auteur!=$connect_id_auteur  AND	lien.id_auteur=auteurs.id_auteur))");
 			while($row_auteur=spip_fetch_array($result_aut)){
 				$auteurs[] = $row_auteur['nom'];
 			}
@@ -1546,7 +1546,7 @@ function sql_calendrier_taches_rv () {
 	$r = array();
 	if (!$connect_id_auteur) return $r;
 
-	$result = spip_query("SELECT messages.texte AS DESCRIPTION, messages.id_message AS UID, messages.date_heure AS DTSTART, messages.date_fin AS DTEND, messages.titre AS SUMMARY, messages.type AS CATEGORY, messages.rv AS LOCATION FROM spip_messages AS messages, spip_auteurs_messages AS lien  WHERE ((lien.id_auteur='$connect_id_auteur' AND lien.id_message=messages.id_message) OR messages.type='affich') AND messages.rv='oui' AND ( (messages.date_heure > DATE_SUB(NOW(), INTERVAL 1 DAY) AND messages.date_heure < DATE_ADD(NOW(), INTERVAL 1 MONTH))	OR (messages.date_heure < NOW() AND messages.date_fin > NOW() )) AND messages.statut='publie' GROUP BY messages.id_message ORDER BY messages.date_heure");
+	$result = spip_query("SELECT messages.texte AS DESCRIPTION, messages.id_message AS UID, messages.date_heure AS DTSTART, messages.date_fin AS DTEND, messages.titre AS SUMMARY, messages.type AS CATEGORY, messages.rv AS LOCATION FROM spip_messages AS messages, spip_auteurs_messages AS lien  WHERE ((lien.id_auteur=$connect_id_auteur AND lien.id_message=messages.id_message) OR messages.type='affich') AND messages.rv='oui' AND ( (messages.date_heure > DATE_SUB(NOW(), INTERVAL 1 DAY) AND messages.date_heure < DATE_ADD(NOW(), INTERVAL 1 MONTH))	OR (messages.date_heure < NOW() AND messages.date_fin > NOW() )) AND messages.statut='publie' GROUP BY messages.id_message ORDER BY messages.date_heure");
 	while ($row = spip_fetch_array($result,SPIP_ASSOC)) {
 		$row['URL'] = tache_redirige($row);
 		$r[] = $row;
@@ -1566,7 +1566,7 @@ function sql_calendrier_agenda ($annee, $mois) {
 	$annee = annee($date);
 
 	// rendez-vous personnels dans le mois
-	$result_messages=spip_query("SELECT messages.titre AS SUMMARY, messages.texte AS DESCRIPTION, messages.id_message AS UID, messages.date_heure FROM spip_messages AS messages, spip_auteurs_messages AS lien WHERE ((lien.id_auteur='$connect_id_auteur' AND lien.id_message=messages.id_message) OR messages.type='affich') AND messages.rv='oui' AND messages.date_heure >='$annee-$mois-1' AND date_heure < DATE_ADD('$annee-$mois-1', INTERVAL 1 MONTH) AND messages.statut='publie'");
+	$result_messages=spip_query("SELECT messages.titre AS SUMMARY, messages.texte AS DESCRIPTION, messages.id_message AS UID, messages.date_heure FROM spip_messages AS messages, spip_auteurs_messages AS lien WHERE ((lien.id_auteur=$connect_id_auteur AND lien.id_message=messages.id_message) OR messages.type='affich') AND messages.rv='oui' AND messages.date_heure >='$annee-$mois-1' AND date_heure < DATE_ADD('$annee-$mois-1', INTERVAL 1 MONTH) AND messages.statut='publie'");
 	while($row=spip_fetch_array($result_messages, SPIP_ASSOC)){
 		$rv[journum($row['date_heure'])] = $row;
 	}
diff --git a/ecrire/inc/auth.php b/ecrire/inc/auth.php
index 7f2ea39f4c..e8874bed19 100644
--- a/ecrire/inc/auth.php
+++ b/ecrire/inc/auth.php
@@ -124,7 +124,7 @@ function inc_auth_dist() {
 
 	// Trouver les autres infos dans la table auteurs.
 	// le champ 'quand' est utilise par l'agenda
-	$result = @spip_query("SELECT *, UNIX_TIMESTAMP(en_ligne) AS quand FROM spip_auteurs WHERE $where AND statut!='5poubelle'");
+	$result = spip_query("SELECT *, en_ligne AS quand FROM spip_auteurs WHERE $where AND statut!='5poubelle'");
 	if (!$row = spip_fetch_array($result)) {
 		// il n'est PLUS connu. c'est SQL qui est desyncrho
 		auth_areconnecter($connect_login);
@@ -189,9 +189,11 @@ function inc_auth_dist() {
 	// Pour les redacteurs, inc_version a fait l'initialisation minimale
 
 	// Indiquer la connexion. A la minute pres ca suffit.
-	$connect_quand = $row['quand'];
+	if (!is_numeric($connect_quand = $row['quand']))
+		$connect_quand = strtotime($connect_quand);
+
 	if ((time() - $connect_quand)  >= 60) {
-		@spip_query("UPDATE spip_auteurs SET en_ligne=NOW() WHERE id_auteur='$connect_id_auteur'");
+		spip_query("UPDATE spip_auteurs SET en_ligne=NOW() WHERE id_auteur=$connect_id_auteur");
 	}
 
 	return ''; // i.e. pas de pb.
diff --git a/ecrire/inc/boutons.php b/ecrire/inc/boutons.php
index 63cb99bc08..bad5457a88 100644
--- a/ecrire/inc/boutons.php
+++ b/ecrire/inc/boutons.php
@@ -100,7 +100,7 @@ function definir_barre_boutons() {
 
 	$sousmenu=array();
 
-	$nombre_articles = spip_num_rows(spip_query("SELECT art.id_article FROM spip_articles AS art, spip_auteurs_articles AS lien WHERE lien.id_auteur = '".$GLOBALS['connect_id_auteur']."' AND art.id_article = lien.id_article LIMIT 1"));
+	$nombre_articles = spip_num_rows(spip_query("SELECT art.id_article FROM spip_articles AS art, spip_auteurs_articles AS lien WHERE lien.id_auteur =".$GLOBALS['connect_id_auteur']." AND art.id_article = lien.id_article LIMIT 1"));
 	if ($nombre_articles > 0) {
 		$sousmenu['articles_page']=
 		  new Bouton('article-24.gif', 'icone_tous_articles');
diff --git a/ecrire/inc/meta.php b/ecrire/inc/meta.php
index 478c1884a1..9f1e55102e 100644
--- a/ecrire/inc/meta.php
+++ b/ecrire/inc/meta.php
@@ -33,11 +33,15 @@ function ecrire_meta($nom, $valeur, $importable = NULL) {
 	if (strlen($nom)){
 		$GLOBALS['meta'][$nom] = $valeur; 
 		if (!_FILE_CONNECT && !@file_exists(_FILE_CONNECT_INS .'.php')) return;
+		$r = spip_query("SELECT impt FROM spip_meta WHERE nom=" . _q($nom));
+		$r = spip_fetch_array($r);
 		// conserver la valeur de impt si existante
-		if ($importable === NULL)
-			spip_query("REPLACE spip_meta (nom, valeur) VALUES ("._q($nom).", " . _q($valeur) . ")");
-		else
-			spip_query("REPLACE spip_meta (nom, valeur, impt) VALUES ("._q($nom).", " . _q($valeur) . ","._q($importable).")");
+		if ($r) {
+		  $r = ($importable === NULL) ? ''
+		    : ", impt=" .  _q($importable);
+			spip_query("UPDATE spip_meta SET valeur=" . _q($valeur) ."$r WHERE nom=" . _q($nom) );
+		} else
+			spip_query("INSERT INTO spip_meta (nom,valeur,impt) VALUES (" .  _q($nom) . "," . _q($valeur) ."," .  _q($importable) . ')');
 	}
 }
 
-- 
GitLab