From ed74d0d9c3362d1aa8e504585b27435ed3abbff0 Mon Sep 17 00:00:00 2001
From: Fil <fil@rezo.net>
Date: Sun, 29 Oct 2006 16:43:12 +0000
Subject: [PATCH] petit chambardement d'API pour les rubriques, breves et
 articles, avec l'idee d'unifier progressivement tout ca

---
 .gitattributes                      |   2 +
 dist/javascript/presentation.js     |  34 ++---
 ecrire/action/editer_article.php    | 147 ++++++++++---------
 ecrire/action/editer_breve.php      | 210 ++++++++++++++++++++++++++++
 ecrire/action/editer_rubrique.php   | 147 +++++++++++--------
 ecrire/action/instituer_article.php |  35 +----
 ecrire/action/instituer_breve.php   |  17 +--
 ecrire/exec/articles.php            |  26 ++--
 ecrire/exec/breves_edit.php         |  72 +++++-----
 ecrire/exec/breves_voir.php         | 141 ++++++-------------
 ecrire/exec/rubriques_edit.php      |  14 +-
 ecrire/inc/actions.php              |   1 +
 ecrire/inc/chercher_rubrique.php    |   1 +
 ecrire/inc/drapeau_edition.php      |  18 +++
 ecrire/inc/editer_article.php       |  10 +-
 ecrire/inc/extra.php                | 103 +++++++++-----
 ecrire/inc/mail.php                 |  97 +------------
 ecrire/inc/notifications.php        | 154 ++++++++++++++++++++
 ecrire/inc/presentation.php         |   3 -
 ecrire/inc/utils.php                |  31 +++-
 ecrire/inc_version.php              |   2 +-
 21 files changed, 773 insertions(+), 492 deletions(-)
 create mode 100644 ecrire/action/editer_breve.php
 create mode 100644 ecrire/inc/notifications.php

diff --git a/.gitattributes b/.gitattributes
index 5d26130dda..609b5fc932 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -307,6 +307,7 @@ ecrire/action/dater.php -text
 ecrire/action/documenter.php -text
 ecrire/action/editer_article.php -text
 ecrire/action/editer_auteurs.php -text
+ecrire/action/editer_breve.php -text
 ecrire/action/editer_forum.php -text
 ecrire/action/editer_mot.php -text
 ecrire/action/editer_rubrique.php -text
@@ -469,6 +470,7 @@ ecrire/inc/legender_auteur.php -text
 ecrire/inc/maintenance.php -text
 ecrire/inc/message_select.php -text
 ecrire/inc/minipres.php -text
+ecrire/inc/notifications.php -text
 ecrire/inc/petitionner.php -text
 ecrire/inc/plonger.php -text
 ecrire/inc/plugin.php -text
diff --git a/dist/javascript/presentation.js b/dist/javascript/presentation.js
index 3475d99f3c..0d9cec9c55 100644
--- a/dist/javascript/presentation.js
+++ b/dist/javascript/presentation.js
@@ -56,20 +56,25 @@ function decalerCouche(id_couche) {
 
 }
 
-var accepter_change_statut;
+var accepter_change_statut = false;
 
 function selec_statut(id, type, decal, puce, script) {
 
-	if (!accepter_change_statut) {
-		accepter_change_statut = confirm(confirm_changer_statut)
-	}
+	if (!accepter_change_statut)
+		accepter_change_statut = confirm(confirm_changer_statut);
 
 	if (accepter_change_statut) {
 		changestyle ('statutdecal'+type+id, 'marginLeft', decal+'px');
 		cacher ('statutdecal'+type+id);
 
-		findObj('imgstatut'+type+id).src = puce;
-		frames['iframe_action'].location.href = script;
+		$.get(script,
+			function (c) {
+				if (!c)
+					findObj('imgstatut'+type+id).src = puce;
+				else
+					alert(c); // eventuel message d'erreur (TODO)
+			}
+		);
 	}
 }
 
@@ -183,22 +188,7 @@ function puce_statut(selection){
 	}
 }
 
-// lorsqu'on touche a un formulaire, desactiver les autres
-// (a voir : onchange=... fonctionne sous FF, mais pas Safari)
-function disable_other_forms(me) {
-	var items = document.getElementsByTagName('form');
-	for (var j = 0; j < items.length; j++) {
-		if (items[j] != me) {
-			var fields = items[j].getElementsByTagName('input');
-			for (var k = 0; k < fields.length; k++) {
-				fields[k].disabled=true;
-			}
-		}
-	}
-}
-
-// Pour ne pas fermer le formulaire de recherche pendant qu'on l'edite	
-
+// Pour ne pas fermer le formulaire de recherche pendant qu'on l'edite
 function recherche_desesperement()
 {
 	if (findObj('bandeaurecherche') && findObj('bandeaurecherche').style.visibility == 'visible') 
diff --git a/ecrire/action/editer_article.php b/ecrire/action/editer_article.php
index 7659c016da..3984dea1ad 100644
--- a/ecrire/action/editer_article.php
+++ b/ecrire/action/editer_article.php
@@ -36,7 +36,7 @@ function action_editer_article_dist() {
 	} 
 
 	// Enregistre l'envoi dans la BD
-	$err = articles_set($id_article, $arg=='oui');
+	$err = articles_set($id_article);
 
 	$redirect = parametre_url(urldecode(_request('redirect')),
 		'id_article', $id_article, '&') . ($err ? '&trad_err=1' : '');
@@ -91,13 +91,11 @@ function insert_article($id_rubrique) {
 }
 
 // http://doc.spip.org/@articles_set
-function articles_set($id_article, $new) {
-	include_spip('inc/filtres');
-	include_spip('inc/rubriques');
+function articles_set($id_article) {
 
 	// si editer_article='oui', on modifie le contenu
 	if (_request('editer_article') == 'oui') {
-		revisions_articles($id_article, $new);
+		revisions_articles($id_article);
 	}
 
 	// Un lien de trad a prendre en compte
@@ -108,63 +106,73 @@ function articles_set($id_article, $new) {
 }
 
 // Enregistre une revision d'article
-// $new indique si c'est un INSERT
 // $c est un contenu (par defaut on prend le contenu via _request())
 // http://doc.spip.org/@revisions_articles
-function revisions_articles ($id_article, $new, $c = false) {
+function revisions_articles ($id_article, $c=false) {
 	global $flag_revisions;
+	include_spip('inc/filtres');
+	include_spip('inc/rubriques');
 
-	$s = spip_query("SELECT statut FROM spip_articles WHERE id_article=$id_article");
-	$row = spip_fetch_array($s);
-	$statut = $row['statut'];
-	$nouveau_statut = false;
+	// Ces champs seront pris nom pour nom (_POST[x] => spip_articles.x)
+	$champs_normaux = array('surtitre', 'titre', 'soustitre', 'descriptif',
+		'nom_site', 'url_site', 'chapo', 'texte', 'ps');
 
-	// unifier $texte en cas de texte trop long
-	trop_longs_articles();
+	// unifier $texte en cas de texte trop long (sur methode POST seulement)
+	if (!is_array($c)) trop_longs_articles();
 
 	// ne pas accepter de titre vide
-	if ($c!==false)
-		if ($c['titre'] === '')
-			$c['titre'] = _T('ecrire:info_sans_titre');
-	else
-	if (_request('titre') === '')
-		set_request('titre', _T('ecrire:info_sans_titre'));
-
-	foreach (array(
-	'surtitre', 'titre', 'soustitre', 'descriptif',
-	'nom_site', 'url_site', 'chapo', 'texte', 'ps') as $champ) {
-		$val = is_array($c) ? $c[$champ] : _request($champ);
+	if (_request('titre', $c) === '')
+		$c = set_request('titre', _T('ecrire:info_sans_titre'), $c);
+
+	$champs = array();
+	foreach ($champs_normaux as $champ) {
+		$val = _request($champ, $c);
 		if ($val !== NULL)
 			$champs[$champ] = corriger_caracteres($val);
 	}
 
+	// Changer le statut de l'article ?
+	include_spip('inc/auth');
+	auth_rubrique($GLOBALS['auteur_session']['id_auteur'], $GLOBALS['auteur_session']['statut']);
+	$s = spip_query("SELECT statut, id_rubrique FROM spip_articles WHERE id_article=$id_article");
+	$row = spip_fetch_array($s);
+	$id_rubrique = $row['id_rubrique'];
+	$statut = $row['statut'];
+
+	if (_request('statut', $c)
+	AND _request('statut', $c) != $statut) {
+		if (acces_rubrique($id_rubrique))
+			$statut = $champs['statut'] = _request('statut', $c);
+		// else erreur ?
+	}
+
 	// Verifier que la rubrique demandee existe et est differente
 	// de la rubrique actuelle
-	$id_parent = is_array($c) ? $c['id_parent'] : _request('id_parent');
-	if ($id_rubrique = intval($id_parent)
-	    AND (spip_fetch_array(spip_query("SELECT id_rubrique FROM spip_rubriques WHERE id_rubrique=$id_rubrique")))
-	    AND (spip_fetch_array(spip_query("SELECT id_rubrique FROM spip_articles WHERE id_article=$id_article AND id_rubrique!=$id_rubrique")))) {
-		$champs['id_rubrique'] = $id_rubrique;
+	if ($id_parent = _request('id_parent', $c)
+	AND $id_parent != $id_rubrique
+	AND (spip_fetch_array(spip_query("SELECT id_rubrique FROM spip_rubriques WHERE id_rubrique=$id_parent")))) {
+		$champs['id_rubrique'] = $id_parent;
 
-		// si l'article est publie 
+		// si l'article etait publie
 		// et que le demandeur n'est pas admin de la rubrique
 		// repasser l'article en statut 'propose'.
 		if ($statut == 'publie') {
 			if ($GLOBALS['auteur_session']['statut'] != '0minirezo')
-				$nouveau_statut = $statut = 'prop';
+				$champs['statut'] = 'prop';
 			else {
 				include_spip('inc/auth');
 				$r = auth_rubrique($GLOBALS['auteur_session']['id_auteur'], $GLOBALS['auteur_session']['statut']);
 				if (is_array($r) AND !$r[$id_rubrique])
-		  			$nouveau_statut = $statut = 'prop';
+					$champs['statut'] = 'prop';
 			}
 		}
 	}
-	// recuperer les extras (incompatible avec $c pour l'instant)
-	if ($GLOBALS['champs_extra']
-	AND !is_array($c)) {
+
+	// recuperer les extras
+	if ($GLOBALS['champs_extra']) {
 		include_spip('inc/extra');
-		$champs['extra'] = extra_recup_saisie("articles", _request('id_secteur'));
+		if ($extra = extra_update('articles', $id_article, $c))
+			$champs['extra'] = $extra;
 	}
 
 	// Envoyer aux plugins
@@ -178,38 +186,50 @@ function revisions_articles ($id_article, $new, $c = false) {
 		)
 	);
 
-	// Stockage des versions : creer une premier version si non-existante
-	if (($GLOBALS['meta']["articles_versions"]=='oui') && $flag_revisions) {
+	// Stockage des versions : creer une premiere version si non-existante
+	if  ($flag_revisions
+	AND $GLOBALS['meta']["articles_versions"]=='oui') {
 		include_spip('inc/revisions');
-		if  (!$new) {
-			$query = spip_query("SELECT id_article FROM spip_versions WHERE id_article=$id_article LIMIT 1");
-			if (!spip_num_rows($query)) {
-				$select = join(", ", array_keys($champs));
-				$query = spip_query("SELECT $select FROM spip_articles WHERE id_article=$id_article");
-				$champs_originaux = spip_fetch_array($query);
-				$id_version = ajouter_version($id_article, $champs_originaux, _T('version_initiale'), 0);
-
-				// Remettre une date un peu ancienne pour la version initiale 
-				if ($id_version == 1) // test inutile ?
-				spip_query("UPDATE spip_versions SET date=DATE_SUB(NOW(), INTERVAL 2 HOUR) WHERE id_article=$id_article AND id_version=1");
+		$query = spip_query("SELECT id_article FROM spip_versions WHERE id_article=$id_article LIMIT 1");
+		if (!spip_num_rows($query)) {
+			$select = join(", ", array_keys($champs_normaux));
+			$query = spip_query("SELECT $select FROM spip_articles WHERE id_article=$id_article");
+			$champs_originaux = spip_fetch_array($query);
+
+			// Si le titre est vide, c'est qu'on vient de creer l'article
+			if ($champs_originaux['titre'] != '') {
+				$id_version = ajouter_version($id_article, $champs_originaux,
+					_T('version_initiale'), 0);
+				// Remettre une date un peu ancienne pour la version initiale
+				spip_query("UPDATE spip_versions SET date=DATE_SUB(NOW(), INTERVAL 2 HOUR) WHERE id_article=$id_article AND id_version=$id_version");
 			}
 		}
 	}
 
-	$update = '';
+	if (!count($champs)) return;
+
+	$update = array();
 	foreach ($champs as $champ => $val)
-		$update .= $champ . '=' . _q($val).', ';
+		$update[] = $champ . '=' . _q($val);
 
-	spip_query("UPDATE spip_articles SET $update date_modif=NOW() WHERE id_article=$id_article");
+	// Si on ne modifie que le statut, ne pas faire tout le tralala
+	// de la gestion de revisions
+	$statut_seulement = (count($champs) == 1 AND isset($champs['statut']));
+	if (!$statut_seulement)
+		$update[] = 'date_modif=NOW()';
+
+	spip_query("UPDATE spip_articles SET ".join(', ',$update)." WHERE id_article=$id_article");
 
 	// Stockage des versions
-	if (($GLOBALS['meta']["articles_versions"]=='oui') && $flag_revisions) {
+	if (!$statut_seulement
+	AND $GLOBALS['meta']["articles_versions"]=='oui'
+	AND $flag_revisions)
 		ajouter_version($id_article, $champs, '', $GLOBALS['auteur_session']['id_auteur']);
-	}
 
 	// marquer le fait que l'article est travaille par toto a telle date
 	// une alerte sera donnee aux autres redacteurs sur exec=articles
-	if ($GLOBALS['meta']['articles_modif'] != 'non') {
+	if (!$statut_seulement
+	AND $GLOBALS['meta']['articles_modif'] != 'non') {
 		include_spip('inc/drapeau_edition');
 		if ($id_article)
 			signale_edition ($id_article, $GLOBALS['auteur_session'], 'article');
@@ -231,8 +251,6 @@ function revisions_articles ($id_article, $new, $c = false) {
 			if ($langue_new != $langue_old)
 				spip_query("UPDATE spip_articles SET lang = '$langue_new' WHERE id_article = $id_article");
 		}
-		if ($nouveau_statut)
-			spip_query("UPDATE spip_articles SET statut = '$statut' WHERE id_article = $id_article");
 	}
 
 
@@ -240,24 +258,24 @@ function revisions_articles ($id_article, $new, $c = false) {
 	// Post-modifications
 	//
 
-	// Invalider les caches
-	if ($statut == 'publie') {
+	// Invalider les caches si l'article est publie, ou si on le depublie
+	if ($statut == 'publie'
+	OR ($statut_ancien=='publie' AND $champ['statut'])) {
 		include_spip('inc/invalideur');
 		suivre_invalideur("id='id_article/$id_article'");
 	}
 
-	// Demander une reindexation de l'article
+	// Demander une reindexation de l'article s'il est publie
 	if ($statut == 'publie') {
 		include_spip('inc/indexation');
 		marquer_indexer('spip_articles', $id_article);
 	}
 
 	// Recalculer les rubriques (statuts et dates) si l'on deplace
-	// un article publie
-	if ($statut == 'publie'
-	AND isset($champ['id_rubrique'])) {
+	// un article publie, ou si on le depublie
+	if (($statut == 'publie' AND isset($champ['id_rubrique']))
+	OR ($statut_ancien=='publie' AND $champ['statut']))
 		calculer_rubriques();
-	}
 }
 
 
@@ -307,4 +325,5 @@ function article_referent ($id_article, $lier_trad) {
 	return false; # pas d'erreur
 }
 
+
 ?>
diff --git a/ecrire/action/editer_breve.php b/ecrire/action/editer_breve.php
new file mode 100644
index 0000000000..567939a9bf
--- /dev/null
+++ b/ecrire/action/editer_breve.php
@@ -0,0 +1,210 @@
+<?php
+
+/***************************************************************************\
+ *  SPIP, Systeme de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright (c) 2001-2006                                                *
+ *  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;
+
+include_spip('inc/actions');
+
+// http://doc.spip.org/@action_editer_breve_dist
+function action_editer_breve_dist() {
+
+	$var_f = charger_fonction('controler_action_auteur', 'inc');
+	$var_f();
+
+	$arg = _request('arg');
+
+	// Envoi depuis les boutons "publier/supprimer cette breve"
+	if (preg_match(',^(\d+)\Wstatut\W(\w+)$,', $arg, $r)) {
+		$id_breve = $r[1];
+		set_request('statut', $r[2]);
+		revisions_breves($id_breve);
+	}
+	// Envoi depuis le formulaire d'edition d'une breve existante
+	else if ($id_breve = intval($arg)) {
+		revisions_breves($id_breve);
+	}
+	// Envoi depuis le formulaire de creation d'une breve
+	else if ($arg == 'oui') {
+		$id_breve = insert_breve(_request('id_parent'));
+		revisions_breves($id_breve);
+	}
+	// Erreur
+	else {
+		redirige_par_entete('./');
+	}
+
+	// Rediriger le navigateur
+	$redirect = parametre_url(urldecode(_request('redirect')),
+		'id_breve', $id_breve, '&');
+	redirige_par_entete($redirect);
+}
+
+// http://doc.spip.org/@insert_breve
+function insert_breve($id_rubrique) {
+
+	include_spip('base/abstract_sql');
+	include_spip('inc/rubriques');
+
+	// Si id_rubrique vaut 0 ou n'est pas definie, creer la breve
+	// dans la premiere rubrique racine
+	if (!$id_rubrique = intval($id_rubrique)) {
+		$row = spip_fetch_array(spip_query("SELECT id_rubrique FROM spip_rubriques WHERE id_parent=0 ORDER by 0+titre,titre LIMIT 1"));
+		$id_rubrique = $row['id_rubrique'];
+	}
+
+	// La langue a la creation : c'est la langue de la rubrique
+	$row = spip_fetch_array(spip_query("SELECT lang, id_secteur FROM spip_rubriques WHERE id_rubrique=$id_rubrique"));
+	$choisie = 'non';
+	$lang = $row['lang'];
+	$id_rubrique = $row['id_secteur']; // garantir la racine
+
+	$id_breve = spip_abstract_insert("spip_breves",
+		"(id_rubrique, statut, date_heure, lang, langue_choisie)",
+		"($id_rubrique, 'prop', NOW(), '$lang', '$choisie')");
+	return $id_breve;
+}
+
+
+// Enregistre une revision de breve
+// $new indique si c'est un INSERT
+// $c est un contenu (par defaut on prend le contenu via _request())
+// http://doc.spip.org/@revisions_breves
+function revisions_breves ($id_breve, $c=false) {
+	include_spip('inc/filtres');
+	include_spip('inc/rubriques');
+
+	// Ces champs seront pris nom pour nom (_POST[x] => spip_breves.x)
+	$champs_normaux = array('titre', 'texte', 'lien_titre', 'lien_url');
+
+	// ne pas accepter de titre vide
+	if (_request('titre', $c) === '')
+		$c = set_request('titre', _T('ecrire:info_sans_titre'), $c);
+
+	$champs = array();
+	foreach ($champs_normaux as $champ) {
+		$val = _request($champ, $c);
+		if ($val !== NULL)
+			$champs[$champ] = corriger_caracteres($val);
+	}
+
+	// Changer le statut de la breve ?
+	include_spip('inc/auth');
+	auth_rubrique($GLOBALS['auteur_session']['id_auteur'], $GLOBALS['auteur_session']['statut']);
+
+	$s = spip_query("SELECT statut, id_rubrique FROM spip_breves WHERE id_breve=$id_breve");
+	$row = spip_fetch_array($s);
+	$id_rubrique = $row['id_rubrique'];
+	$statut = $row['statut'];
+
+	if (_request('statut', $c)
+	AND _request('statut', $c) != $statut
+	AND acces_rubrique($id_rubrique)) {
+		$statut = $champs['statut'] = _request('statut', $c);
+	}
+
+	// Changer de rubrique ?
+	// Verifier que la rubrique demandee est a la racine et differente
+	// de la rubrique actuelle
+	if ($id_parent = intval(_request('id_parent', $c))
+	AND $id_parent != $id_rubrique
+	AND (spip_fetch_array(spip_query("SELECT id_rubrique FROM spip_rubriques WHERE id_parent=0 AND id_rubrique=$id_parent")))) {
+		$champs['id_rubrique'] = $id_parent;
+
+		// si la breve est publiee
+		// et que le demandeur n'est pas admin de la rubrique
+		// repasser la breve en statut 'prop'.
+		if ($statut == 'publie') {
+			if ($GLOBALS['auteur_session']['statut'] != '0minirezo')
+				$champs['statut'] = $statut = 'prop';
+			else {
+				if (!acces_rubrique($id_parent))
+					$champs['statut'] = $statut = 'prop';
+			}
+		}
+	}
+
+	// recuperer les extras
+	if ($GLOBALS['champs_extra']) {
+		include_spip('inc/extra');
+		if ($extra = extra_update('breves', $id_breve, $c))
+			$champs['extra'] = $extra;
+	}
+
+	// Envoyer aux plugins
+	$champs = pipeline('pre_enregistre_contenu',
+		array(
+			'args' => array(
+				'table' => 'spip_breves',
+				'id_objet' => $id_breve
+			),
+			'data' => $champs
+		)
+	);
+
+	$update = array();
+	foreach ($champs as $champ => $val)
+		$update[] = $champ . '=' . _q($val);
+
+	if (!count($update)) return;
+
+	spip_query("UPDATE spip_breves SET ".join(', ',$update)." WHERE id_breve=$id_breve");
+
+	// marquer le fait que la breve est travaillee par toto a telle date
+	// une alerte sera donnee aux autres redacteurs sur exec=breves_voir
+	if ($GLOBALS['meta']['articles_modif'] != 'non') {
+		include_spip('inc/drapeau_edition');
+		signale_edition ($id_breve, $GLOBALS['auteur_session'], 'breve');
+	}
+
+	// Si on deplace la breve
+	// - propager les secteurs
+	// - changer sa langue (si heritee)
+	if (isset($champs['id_rubrique'])) {
+		propager_les_secteurs();
+
+		$row = spip_fetch_array(spip_query("SELECT lang, langue_choisie FROM spip_breves WHERE id_breve=$id_breve"));
+		$langue_old = $row['lang'];
+		$langue_choisie_old = $row['langue_choisie'];
+
+		if ($langue_choisie_old != "oui") {
+			$row = spip_fetch_array(spip_query("SELECT lang FROM spip_rubriques WHERE id_rubrique=$id_rubrique"));
+			$langue_new = $row['lang'];
+			if ($langue_new != $langue_old)
+				spip_query("UPDATE spip_breves SET lang = '$langue_new' WHERE id_breve = $id_breve");
+		}
+	}
+
+	//
+	// Post-modifications
+	//
+
+	// Invalider les caches
+	if ($statut == 'publie') {
+		include_spip('inc/invalideur');
+		suivre_invalideur("id='id_breve/$id_breve'");
+	}
+
+	// Demander une reindexation de la breve
+	if ($statut == 'publie') {
+		include_spip('inc/indexation');
+		marquer_indexer('spip_breves', $id_breve);
+	}
+
+	// Recalculer les rubriques (statuts et dates) si l'on deplace
+	// une breve publiee
+	if ($statut == 'publie'
+	AND isset($champ['id_rubrique'])) {
+		calculer_rubriques();
+	}
+}
+
+?>
diff --git a/ecrire/action/editer_rubrique.php b/ecrire/action/editer_rubrique.php
index f6e1b385ca..aa5af106ca 100644
--- a/ecrire/action/editer_rubrique.php
+++ b/ecrire/action/editer_rubrique.php
@@ -23,77 +23,81 @@ function action_editer_rubrique_dist() {
 
 	$arg = _request('arg');
 
-	if (!preg_match(";^(\d+),(\w*),(\d+)$;", $arg, $r)) {
-		 spip_log("action_editer_rubrique_dist $arg pas compris");
-	} else action_editer_rubrique_post($r);
-}
+	if (!$id_rubrique = intval($arg)) {
+		if ($arg != 'oui') redirige_par_entete('./');
+		$id_rubrique = insert_rubrique(_request('id_parent'));
+	}
 
-// http://doc.spip.org/@action_editer_rubrique_post
-function action_editer_rubrique_post($r)
-{
+	revisions_rubriques($id_rubrique);
 
-	list($x, $old_parent, $new, $id_rubrique) = $r;
-	$id_parent = intval(_request('id_parent'));
-	if ($new == 'oui')
-		$id_rubrique = enregistre_creer_naviguer($id_parent);
+	$redirect = parametre_url(
+		urldecode(_request('redirect')),
+		'id_rubrique', $id_rubrique, '&');
+	redirige_par_entete($redirect);
+}
 
-	enregistre_modifier_naviguer($id_rubrique,
-				$id_parent,
-				_request('titre'),
-				_request('texte'),
-				_request('descriptif'),
-				$old_parent);
 
-	calculer_rubriques();
-	calculer_langues_rubriques();
+// http://doc.spip.org/@insert_rubrique
+function insert_rubrique($id_parent) {
+	include_spip('base/abstract_sql');
+	return spip_abstract_insert("spip_rubriques",
+		"(titre, id_parent)",
+		"('"._T('item_nouvelle_rubrique')."', ".intval($id_parent).")"
+	);
+}
 
-	// invalider les caches marques de cette rubrique
-	include_spip('inc/invalideur');
-	suivre_invalideur("id='id_rubrique/$id_rubrique'");
+// Enregistrer certaines modifications d'une rubrique
+// $c est un tableau qu'on peut proposer en lieu et place de _request()
+// http://doc.spip.org/@revisions_rubriques
+function revisions_rubriques($id_rubrique, $c=false) {
+	include_spip('inc/filtres');
 
-        $redirect = parametre_url(urldecode(_request('redirect')),
-				  'id_rubrique', $id_rubrique, '&');
-        redirige_par_entete($redirect);
-}
+	// Ces champs seront pris nom pour nom (_POST[x] => spip_articles.x)
+	$champs_normaux = array('titre', 'texte', 'descriptif');
 
+	// ne pas accepter de titre vide
+	if (_request('titre', $c) === '')
+		$c = set_request('titre', _T('ecrire:info_sans_titre'), $c);
 
-// http://doc.spip.org/@enregistre_creer_naviguer
-function enregistre_creer_naviguer($id_parent)
-{
-	include_spip('base/abstract_sql');
-	return spip_abstract_insert("spip_rubriques", 
-			"(titre, id_parent)",
-			"('"._T('item_nouvelle_rubrique')."', '$id_parent')");
-}
+	$champs = array();
+	foreach ($champs_normaux as $champ) {
+		$val = _request($champ, $c);
+		if ($val !== NULL)
+			$champs[$champ] = corriger_caracteres($val);
+	}
 
-// http://doc.spip.org/@enregistre_modifier_naviguer
-function enregistre_modifier_naviguer($id_rubrique, $id_parent, $titre, $texte, $descriptif, $old_parent=0)
-{
+	// traitement de la rubrique parente
 	// interdiction de deplacer vers ou a partir d'une rubrique
 	// qu'on n'administre pas.
+	if ($id_parent = _request('id_parent', $c)) {
+		$s = spip_fetch_array(spip_query("SELECT * FROM spip_rubriques WHERE id_rubrique=".intval($id_rubrique)));
+		$old_parent = $s['id_parent'];
 
-	$parent = '';
-	if ($id_parent != $old_parent)	  {
-		include_spip('inc/auth');
-		$r = auth_rubrique($GLOBALS['auteur_session']['id_auteur'], $GLOBALS['auteur_session']['statut']);
-
-		if (is_int($r)
-		OR (is_array($r)
-			AND $r[$id_parent]
-			AND (!$old_parent OR $r[$old_parent])))
-			$parent = "id_parent=" . intval($id_parent) . ", ";
-		else {
-			spip_log("deplacement de $id_rubrique vers $id_parent refuse a " . $GLOBALS['auteur_session']['id_auteur'] . ' '.  $GLOBALS['auteur_session']['statut']);
-			$id_parent = '';
+		$parent = '';
+		if ($id_parent != $old_parent) {
+			include_spip('inc/auth');
+			$r = auth_rubrique($GLOBALS['auteur_session']['id_auteur'], $GLOBALS['auteur_session']['statut']);
+
+			if (is_int($r)
+			OR (is_array($r)
+				AND $r[$id_parent]
+				AND (!$old_parent OR $r[$old_parent])))
+				$parent = "id_parent=" . intval($id_parent) . ", ";
+			else {
+				spip_log("deplacement de $id_rubrique vers $id_parent refuse a " . $GLOBALS['auteur_session']['id_auteur'] . ' '.  $GLOBALS['auteur_session']['statut']);
+				$parent = '';
+			}
 		}
 	}
+	else
+		$parent = '';
 
 	// si c'est une rubrique-secteur contenant des breves, ne deplacer
 	// que si $confirme_deplace == 'oui', et changer l'id_rubrique des
 	// breves en question
-	if (_request('confirme_deplace') == 'oui'
-	AND $parent) {
-		$id_secteur = spip_fetch_array(spip_query("SELECT id_secteur FROM spip_rubriques WHERE id_rubrique=$id_parent"));
+	if ($parent
+	AND _request('confirme_deplace', $c) == 'oui') {
+		$id_secteur = spip_fetch_array(spip_query("SELECT id_secteur FROM spip_rubriques WHERE id_rubrique=".intval($id_parent)));
 		if ($id_secteur= $id_secteur['id_secteur'])
 			spip_query("UPDATE spip_breves	SET id_rubrique=$id_secteur	WHERE id_rubrique=$id_rubrique");
 	} else
@@ -101,20 +105,47 @@ function enregistre_modifier_naviguer($id_rubrique, $id_parent, $titre, $texte,
 
 	if ($id_parent == $id_rubrique) $parent = ''; // au fou
 
+	// recuperer les extras
 	if ($GLOBALS['champs_extra']) {
 		include_spip('inc/extra');
-		$extra = extra_recup_saisie("rubriques");
+		if ($extra = extra_update('rubriques', $id_rubrique, $c))
+			$champs['extra'] = $extra;
 	}
-	else $extra = '';
 
-	spip_query("UPDATE spip_rubriques SET " . $parent . "titre=" . _q($titre) . ", descriptif=" . _q($descriptif) . ", texte=" . _q($texte) . (!$extra ? '' :  ", extra = " . _q($extra) . "") . " WHERE id_rubrique=$id_rubrique");
+	// Envoyer aux plugins
+	$champs = pipeline('pre_enregistre_contenu',
+		array(
+			'args' => array(
+				'table' => 'spip_rubriques',
+				'id_objet' => $id_rubrique
+			),
+			'data' => $champs
+		)
+	);
+
+	$update = array();
+	foreach ($champs as $champ => $val)
+		$update[] = $champ . '=' . _q($val);
+
+	if (!count($update)) return;
+
+	spip_query("UPDATE spip_rubriques SET ".join(', ', $update)." WHERE id_rubrique=$id_rubrique");
 
 
 	if ($GLOBALS['meta']['activer_moteur'] == 'oui') {
-			include_spip("inc/indexation");
-			marquer_indexer('spip_rubriques', $id_rubrique);
+		include_spip("inc/indexation");
+		marquer_indexer('spip_rubriques', $id_rubrique);
 	}
+
 	propager_les_secteurs();
+
+	calculer_rubriques();
+	calculer_langues_rubriques();
+
+	// invalider les caches marques de cette rubrique
+	include_spip('inc/invalideur');
+	suivre_invalideur("id='id_rubrique/$id_rubrique'");
+
 }
 
 ?>
diff --git a/ecrire/action/instituer_article.php b/ecrire/action/instituer_article.php
index 046a25479e..5da4bdefbc 100644
--- a/ecrire/action/instituer_article.php
+++ b/ecrire/action/instituer_article.php
@@ -26,40 +26,11 @@ function action_instituer_article_dist() {
 	if (!$statut) return; // impossible mais sait-on jamais
 
 	$id_article = intval($id_article);
-	$result = spip_query("SELECT statut FROM spip_articles WHERE id_article=$id_article");
 
-	if ($row = spip_fetch_array($result)) {
-		$statut_ancien = $row['statut'];
-		}
+	include_spip('action/editer_article');
 
-	if ($statut != $statut_ancien) {
-		spip_query("UPDATE spip_articles SET statut='$statut',	date=NOW() WHERE id_article=$id_article");
+	revisions_articles($id_article, array('statut' => $statut));
 
-		include_spip('inc/rubriques');
-		calculer_rubriques();
-
-		if ($statut == 'publie') {
-			if ($GLOBALS['meta']['activer_moteur'] == 'oui') {
-			include_spip("inc/indexation");
-			marquer_indexer('spip_articles', $id_article);
-			}
-			include_spip('inc/lang');
-			include_spip('inc/texte');
-			include_spip('inc/mail');
-			envoyer_mail_publication($id_article);
-		}
-
-		if ($statut_ancien == 'publie') {
-			include_spip('inc/invalideur');
-			suivre_invalideur("id='id_article/$id_article'");
-		}
-
-		if ($statut == "prop" AND $statut_ancien != 'publie') {
-			include_spip('inc/lang');
-			include_spip('inc/texte');
-			include_spip('inc/mail');
-			envoyer_mail_proposition($id_article);
-		}
-	}
 }
+
 ?>
diff --git a/ecrire/action/instituer_breve.php b/ecrire/action/instituer_breve.php
index 2c0b3da40b..567da061f2 100644
--- a/ecrire/action/instituer_breve.php
+++ b/ecrire/action/instituer_breve.php
@@ -12,6 +12,9 @@
 
 if (!defined("_ECRIRE_INC_VERSION")) return;
 
+
+// ON PEUT SUPPRIMER CE FICHIER
+
 // http://doc.spip.org/@action_instituer_breve_dist
 function action_instituer_breve_dist() {
 
@@ -24,17 +27,9 @@ function action_instituer_breve_dist() {
 	list($id_breve, $statut) = preg_split('/\W/', $arg);
 
 	$id_breve = intval($id_breve);
-	$result = spip_query("SELECT statut FROM spip_breves WHERE id_breve=$id_breve");
-
-	if ($row = spip_fetch_array($result)) {
-		$statut_ancien = $row['statut'];
-		}
 
-	if ($statut != $statut_ancien) {
-		spip_query("UPDATE spip_breves SET date_heure=NOW(), statut='$statut' WHERE id_breve=$id_breve");
-
-		include_spip('inc/rubriques');
-		calculer_rubriques();
-	}
+	include_spip('action/editer_breve');
+	revisions_breves($id_breve, false, array('statut' => $statut));
 }
+
 ?>
diff --git a/ecrire/exec/articles.php b/ecrire/exec/articles.php
index 408c36fff5..62a77399d0 100644
--- a/ecrire/exec/articles.php
+++ b/ecrire/exec/articles.php
@@ -81,24 +81,13 @@ function articles_affiche($id_article, $row, $cherche_auteur, $ids, $cherche_mot
 	$flag_editable = ($statut_rubrique OR ($flag_auteur AND ($statut_article == 'prepa' OR $statut_article == 'prop' OR $statut_article == 'poubelle')));
 
 	// Est-ce que quelqu'un a deja ouvert l'article en edition ?
-	$modif = array();
-	if ($GLOBALS['meta']['articles_modif'] != 'non') {
+	if ($flag_editable
+	AND $GLOBALS['meta']['articles_modif'] != 'non') {
 		include_spip('inc/drapeau_edition');
-		$modif = qui_edite($id_article, 'article');
-		unset($modif[$connect_id_auteur]);
-
-		if ($modif) {
-			$quand = 0;
-			foreach($modif as $duo) {
-				$auteurs[] = typo(extraire_multi(key($duo)));
-				$quand = max($quand, current($duo));
-			}
-		// format lie a la chaine de langue 'avis_article_modifie'
-		  	$modif = array(
-				'nom_auteur_modif' => join(' | ', $auteurs),
-				'date_diff' => floor((time()-$quand) / 60));
-		}
-	}
+		$modif = mention_qui_edite($id_article, 'article');
+	} else
+		$modif = array();
+
 
  // chargement prealable des fonctions produisant des formulaires
 
@@ -113,7 +102,8 @@ function articles_affiche($id_article, $row, $cherche_auteur, $ids, $cherche_mot
 
 	if ($flag_editable)
 		$instituer_article = charger_fonction('instituer_article', 'inc');
-	else $instituer_article ='';
+	else
+		$instituer_article ='';
 
 	$res = debut_gauche('accueil',true)
 
diff --git a/ecrire/exec/breves_edit.php b/ecrire/exec/breves_edit.php
index 17d82dd05a..32c3ab5372 100644
--- a/ecrire/exec/breves_edit.php
+++ b/ecrire/exec/breves_edit.php
@@ -103,19 +103,16 @@ if ($new != "oui") {
 
 if ($connect_statut=="0minirezo" OR $statut=="prop" OR $new == "oui") {
 	if ($id_breve) $lien = "id_breve=$id_breve";
-	echo generer_url_post_ecrire('breves_voir',$lien, 'formulaire');
-
-	if ($new == "oui") echo "<INPUT TYPE='Hidden' NAME='new' VALUE=\"oui\">";
 
 	$titre = entites_html($titre);
 	$lien_titre = entites_html($lien_titre);
 
-	echo _T('entree_titre_obligatoire');
-	echo "<INPUT TYPE='text' CLASS='formo' NAME='titre' VALUE=\"$titre\" SIZE='40' $onfocus>";
+	$form = _T('entree_titre_obligatoire')
+	. "<INPUT TYPE='text' CLASS='formo' NAME='titre' VALUE=\"$titre\" SIZE='40' $onfocus>"
 
 
 	/// Dans la rubrique....
-	echo "<INPUT TYPE='Hidden' NAME='id_rubrique_old' VALUE=\"$id_rubrique\"><p />";
+	. "<INPUT TYPE='Hidden' NAME='id_rubrique_old' VALUE=\"$id_rubrique\"><p />";
 
 	if ($id_rubrique == 0) $logo_parent = "racine-site-24.gif";
 	else {
@@ -129,7 +126,7 @@ if ($connect_statut=="0minirezo" OR $statut=="prop" OR $new == "oui") {
 	}
 
 
-	debut_cadre_couleur("$logo_parent", false, "",_T('entree_interieur_rubrique').aide ("brevesrub"));
+	$form .= debut_cadre_couleur("$logo_parent", true, "",_T('entree_interieur_rubrique').aide ("brevesrub"));
 
 	// appel du script a la racine, faut choisir 
 	// on prend le dernier secteur cree
@@ -144,55 +141,60 @@ if ($connect_statut=="0minirezo" OR $statut=="prop" OR $new == "oui") {
 
 	// selecteur de rubrique (en general pas d'ajax car toujours racine)
 	$selecteur_rubrique = charger_fonction('chercher_rubrique', 'inc');
-	echo $selecteur_rubrique($id_rubrique, 'breve', ($statut == 'publie'));
+	$form .= $selecteur_rubrique($id_rubrique, 'breve', ($statut == 'publie'));
 
-	fin_cadre_couleur();
+	$form .= fin_cadre_couleur(true);
 	
 	if ($spip_ecran == "large") $rows = 28;
 	else $rows = 15;
 	
-	echo "<p /><B>"._T('entree_texte_breve')."</B><BR>";
-	echo afficher_barre('document.formulaire.texte');
-	echo "<TEXTAREA NAME='texte' ".$GLOBALS['browser_caret']." ROWS='$rows' CLASS='formo' COLS='40' wrap=soft>";
-	echo entites_html($texte);
-	echo "</TEXTAREA><P>\n";
+	$form .= "<p /><B>"._T('entree_texte_breve')."</B><BR>"
+	. afficher_barre('document.formulaire.texte')
+	. "<TEXTAREA NAME='texte' ".$GLOBALS['browser_caret']." ROWS='$rows' CLASS='formo' COLS='40' wrap='soft'>"
+	. entites_html($texte)
+	. "</TEXTAREA><P>\n"
 
 
-	echo _T('entree_liens_sites').aide ("breveslien")."<BR>";
-	echo _T('info_titre')."<BR>";
-	echo "<INPUT TYPE='text' CLASS='forml' NAME='lien_titre' VALUE=\"$lien_titre\" SIZE='40'><BR>";
+	. _T('entree_liens_sites').aide ("breveslien")."<BR>"
+	. _T('info_titre')."<BR>"
+	. "<INPUT TYPE='text' CLASS='forml' NAME='lien_titre' VALUE=\"$lien_titre\" SIZE='40'><BR>"
 
-	echo _T('info_url')."<BR>";
-	echo "<INPUT TYPE='text' CLASS='forml' NAME='lien_url' VALUE=\"$lien_url\" SIZE='40'><P>";
+	. _T('info_url')."<BR>"
+	. "<INPUT TYPE='text' CLASS='forml' NAME='lien_url' VALUE=\"$lien_url\" SIZE='40'><P>";
 
 	if ($champs_extra) {
 		include_spip('inc/extra');
-		echo extra_saisie($extra, 'breves', $id_rubrique);
+		$form .= extra_saisie($extra, 'breves', $id_rubrique);
 	}
 
 	if ($connect_statut=="0minirezo" AND acces_rubrique($id_rubrique)) {
-		debut_cadre_relief();
-		echo "<B>"._T('entree_breve_publiee')."</B>\n";
+		$form .= debut_cadre_relief('', true)
+		. "<B>"._T('entree_breve_publiee')."</B>\n"
 
-		echo "<SELECT NAME='statut' SIZE=1 CLASS='fondl'>\n";
-		
-		echo "<OPTION".mySel("prop",$statut)." style='background-color: white'>"._T('item_breve_proposee')."\n";		
-		echo "<OPTION".mySel("refuse",$statut). http_style_background('rayures-sup.gif'). ">"._T('item_breve_refusee')."\n";		
-		echo "<OPTION".mySel("publie",$statut)." style='background-color: #B4E8C5'>"._T('item_breve_validee')."\n";		
+		. "<SELECT NAME='statut' SIZE=1 CLASS='fondl'>\n"
+		. "<OPTION".mySel("prop",$statut)." style='background-color: white'>"._T('item_breve_proposee')."\n"
+		. "<OPTION".mySel("refuse",$statut). http_style_background('rayures-sup.gif'). ">"._T('item_breve_refusee')."\n"
+		. "<OPTION".mySel("publie",$statut)." style='background-color: #B4E8C5'>"._T('item_breve_validee')."\n"
 
-		echo "</SELECT>".aide ("brevesstatut")."<P>\n";
-		fin_cadre_relief();
-	}
-	else {
-		echo "<INPUT TYPE='Hidden' NAME='statut' VALUE=\"$statut\">";
+		. "</SELECT>".aide ("brevesstatut")."<P>\n"
+		. fin_cadre_relief(true);
 	}
-	echo "<P ALIGN='right'><INPUT TYPE='submit' NAME='Valider' VALUE='"._T('bouton_enregistrer')."' CLASS='fondo'  >";
-	echo "</FORM>";
+	$form .= "<P ALIGN='right'><INPUT TYPE='submit' NAME='Valider' VALUE='"._T('bouton_enregistrer')."' CLASS='fondo'>";
+
+	echo generer_action_auteur('editer_breve',
+		$new ? $new : $id_breve,
+		$redirect = generer_url_ecrire('breves_voir'),
+		$form,
+		" method='post' name='formulaire'"
+	);
+
 }
-else echo "<H2>"._T('info_page_interdite')."</H2>";
+else
+	echo "<H2>"._T('info_page_interdite')."</H2>";
 
 fin_cadre_formulaire();
 echo fin_page();
+
 }
 
 ?>
diff --git a/ecrire/exec/breves_voir.php b/ecrire/exec/breves_voir.php
index dbd3c965c7..6749b3b27a 100644
--- a/ecrire/exec/breves_voir.php
+++ b/ecrire/exec/breves_voir.php
@@ -41,9 +41,23 @@ function afficher_breves_voir($id_breve, $changer_lang, $cherche_mot, $select_gr
 	}
 
 	$flag_editable = (($connect_statut == '0minirezo' AND acces_rubrique($id_rubrique)) OR $statut == 'prop');
-	
-	pipeline('exec_init',array('args'=>array('exec'=>'breves_voir','id_breve'=>$id_breve),'data'=>''));
-	
+
+	// Est-ce que quelqu'un a deja ouvert la breve en edition ?
+	if ($flag_editable
+	AND $GLOBALS['meta']['articles_modif'] != 'non') {
+		include_spip('inc/drapeau_edition');
+		$modif = mention_qui_edite($id_breve, 'breve');
+	} else
+		$modif = array();
+
+
+	pipeline('exec_init',
+		array(
+			'args'=>array('exec'=>'breves_voir','id_breve'=>$id_breve),
+			'data'=>''
+		)
+	);
+
 	debut_page("&laquo; $titre_breve &raquo;", "naviguer", "breves", "", $id_rubrique);
 	
 	debut_grand_cadre();
@@ -78,9 +92,21 @@ function afficher_breves_voir($id_breve, $changer_lang, $cherche_mot, $select_gr
 	echo bloc_des_raccourcis(icone_horizontale(_T('icone_nouvelle_breve'), generer_url_ecrire("breves_edit","new=oui&id_rubrique=$id_rubrique"), "breve-24.gif","creer.gif", false));
 
 	
-	echo pipeline('affiche_gauche',array('args'=>array('exec'=>'breves_voir','id_breve'=>$id_breve),'data'=>''));
+	echo pipeline('affiche_gauche',
+		array(
+		'args'=>array('exec'=>'breves_voir','id_breve'=>$id_breve),
+		'data'=>''
+		)
+	);
+
 	creer_colonne_droite();
-	echo pipeline('affiche_droite',array('args'=>array('exec'=>'breves_voir','id_breve'=>$id_breve),'data'=>''));
+
+	echo pipeline('affiche_droite',
+		array(
+		'args'=>array('exec'=>'breves_voir','id_breve'=>$id_breve),
+		'data'=>''
+		)
+	);
 
 	echo meme_rubrique($id_rubrique, $id_breve, 'breve', 'date_heure');
 
@@ -89,9 +115,7 @@ function afficher_breves_voir($id_breve, $changer_lang, $cherche_mot, $select_gr
 	debut_cadre_relief("breve-24.gif");
 	echo "<TABLE WIDTH=100% CELLPADDING=0 CELLSPACING=0 BORDER=0>";
 	echo "<TR><td class='serif'>";
-	
-	
-	
+
 	echo "\n<table cellpadding=0 cellspacing=0 border=0 width='100%'>";
 	echo "<tr width='100%'><td width='100%' valign='top'>";
 	gros_titre($titre);
@@ -100,7 +124,14 @@ function afficher_breves_voir($id_breve, $changer_lang, $cherche_mot, $select_gr
 	if ($flag_editable) {
 		echo "<td>", http_img_pack("rien.gif", ' ', "width='5'") ."</td>\n";
 		echo "<td  align='right'>";
-		icone(_T('icone_modifier_breve'), generer_url_ecrire("breves_edit","id_breve=$id_breve&retour=nav"), "breve-24.gif", "edit.gif");
+		icone(
+			// TODO -- _L("Fil a travaille sur cette breve il y a x minutes")
+			!$modif ? _T('icone_modifier_breve')
+				: _T('texte_travail_article', $modif),
+			generer_url_ecrire("breves_edit","id_breve=$id_breve&retour=nav"),
+			!$modif ? "breve-24.gif" : "warning-24.gif",
+			!$modif ? "edit.gif" : ''
+		);
 		echo "</td>";
 	}
 	echo "</tr></table>\n";
@@ -192,13 +223,13 @@ function afficher_breves_voir($id_breve, $changer_lang, $cherche_mot, $select_gr
 		echo "<table>";
 		echo "<td  align='right'>";
 		icone(_T('icone_publier_breve'), 
-		      redirige_action_auteur('instituer_breve',"$id_breve-publie","breves_voir","id_breve=$id_breve"), "breve-24.gif", "racine-24.gif");
+		      redirige_action_auteur('editer_breve',"$id_breve-statut-publie","breves_voir","id_breve=$id_breve"), "breve-24.gif", "racine-24.gif");
 		echo "</td>";
 		
 		echo "<td>", http_img_pack("rien.gif", ' ', "width='5'") ."</td>\n";
 		echo "<td  align='right'>";
 		icone(_T('icone_refuser_breve'), 
-		      redirige_action_auteur('instituer_breve', "$id_breve-refuse", "breves_voir","id_breve=$id_breve"), "breve-24.gif", "supprimer.gif");
+		      redirige_action_auteur('editer_breve', "$id_breve-statut-refuse", "breves_voir","id_breve=$id_breve"), "breve-24.gif", "supprimer.gif");
 		echo "</td>";
 		echo "</table>";	
 		
@@ -233,87 +264,13 @@ function exec_breves_voir_dist()
 	global $connect_statut;
 
 	$id_breve = intval(_request('id_breve'));
-	$id_rubrique_old = 0;
 
-	if (($id_breve == 0) AND (_request('new') == "oui")) {
-		$id_rubrique_old = $id_rubrique = intval(_request('id_parent'));
-		$row = spip_fetch_array(spip_query("SELECT lang FROM spip_rubriques WHERE id_rubrique=$id_rubrique"));
-		$langue_new = $row ? $row["lang"] : "";
-		if (!$langue_new) $langue_new = $GLOBALS['meta']['langue_site'];
-		
-		$id_breve = spip_abstract_insert("spip_breves",
-			"(titre, date_heure, id_rubrique, statut, lang, langue_choisie)", 
-			"('"._T('item_nouvelle_breve')."', NOW(), '$id_rubrique', 'refuse', '$langue_new', 'non')");
-	}
+	if ($row = spip_fetch_array(spip_query("SELECT id_rubrique FROM spip_breves WHERE id_breve=$id_breve")))
+		$id_rubrique = $row['id_rubrique'];
 	else
-		if ($row = spip_fetch_array(spip_query("SELECT id_rubrique FROM spip_breves WHERE id_breve=$id_breve")))
-			$id_rubrique_old = $row['id_rubrique'];
-
-
- $calculer_rubriques = false;
-
-	if (($connect_statut=="0minirezo" OR _request('statut')=="prop" OR _request('new') == "oui") AND
-     strval(_request('titre'))) {
-	
-		foreach (array(
-		 'titre', 'texte', 'lien_titre', 'lien_url',
-		 'statut', 'id_parent'=>'id_rubrique') as $req=>$champ) {
-			if (($val = _request(is_numeric($req)?$champ:$req)) !== NULL)
-				$champs[$champ] = corriger_caracteres($val);
-		}
-		// recuperer les extras
-		if ($GLOBALS['champs_extra']) {
-			include_spip('inc/extra');
-			$champs['extra'] = extra_recup_saisie("breves");
-		}
-		$id_rubrique = $champs['id_rubrique'];
-	
-		// Envoyer aux plugins
-		$champs = pipeline('pre_enregistre_contenu',
-			array(
-				'args' => array(
-					'table' => 'spip_breves',
-					'id_objet' => $id_breve
-				),
-				'data' => $champs
-			)
-		);
-		
-		$update = '';
-		foreach ($champs as $champ => $val)
-			$update .= $champ . '=' . _q($val).', ';
-		$update = substr($update,0,strlen($update)-2);
-	
-		spip_query("UPDATE spip_breves SET $update WHERE id_breve=$id_breve");
-	
-		// invalider et reindexer
-		include_spip('inc/invalideur');
-		suivre_invalideur("id='id_breve/$id_breve'");
-	
-		if ($GLOBALS['meta']['activer_moteur'] == 'oui') {
-			include_spip("inc/indexation");
-			marquer_indexer('spip_breves', $id_breve);
-		}
-		$calculer_rubriques = true;
-		
-		
-		// Changer la langue heritee
-		if ($id_rubrique != $id_rubrique_old) {
-			$row = spip_fetch_array(spip_query("SELECT lang, langue_choisie FROM spip_breves WHERE id_breve=$id_breve"));
-			$langue_old = $row['lang'];
-			$langue_choisie_old = $row['langue_choisie'];
-			
-			if ($langue_choisie_old != "oui") {
-				$row = spip_fetch_array(spip_query("SELECT lang FROM spip_rubriques WHERE id_rubrique=$id_rubrique"));
-				$langue_new = $row['lang'];
-		
-				if ($langue_new != $langue_old) {
-					spip_query("UPDATE spip_breves SET lang = '$langue_new' WHERE id_breve = $id_breve");
-				}
-			}
-		}
-	}
+		die ('breve inexistante');
 
+	// TODO: passer ce qui reste de l'update dans action/editer_breve.php
 	if (_request('jour') AND $connect_statut == '0minirezo') {
 		$annee = _request('annee');
 		$mois = _request('mois');
@@ -321,14 +278,8 @@ function exec_breves_voir_dist()
 		if ($annee == "0000") $mois = "00";
 		if ($mois == "00") $jour = "00";
 		spip_query("UPDATE spip_breves SET date_heure='$annee-$mois-$jour' WHERE id_breve=$id_breve");
-		$calculer_rubriques = true;
 	}
 
-	if ($calculer_rubriques) calculer_rubriques();
-
-	if (_request('new') == 'oui')
-		redirige_par_entete(
-			generer_url_ecrire('breves_voir', 'id_breve='.$id_breve, '&'));
 	afficher_breves_voir($id_breve, _request('changer_lang'), _request('cherche_mot'), _request('select_groupe'));
 }
 ?>
diff --git a/ecrire/exec/rubriques_edit.php b/ecrire/exec/rubriques_edit.php
index 2106f5a0ac..d2947e8a14 100644
--- a/ecrire/exec/rubriques_edit.php
+++ b/ecrire/exec/rubriques_edit.php
@@ -133,12 +133,10 @@ function exec_rubriques_edit_dist()
 	if ($options == "avancees" OR $descriptif) {
 		$form .= "<b>"._T('texte_descriptif_rapide')."</b><br />"
 		. _T('entree_contenu_rubrique')."<br />"
-		. "<textarea name='descriptif' class='forml' rows='4' cols='40' wrap=soft>"
+		. "<textarea name='descriptif' class='forml' rows='4' cols='40' wrap='soft'>"
 		. entites_html($descriptif)
 		. "</textarea><p>\n";
-	} else {
-		$form .= "<input type='hidden' name='descriptif' value=\"".entites_html($descriptif)."\" />";
-}
+	}
 
 	$form .= "<B>"._T('info_texte_explicatif')."</B>"
 	. aide ("raccourcis")
@@ -151,15 +149,13 @@ function exec_rubriques_edit_dist()
 		$form .= extra_saisie($extra, 'rubriques', $id_secteur);
 	}
 
-	$form .= "<input type='hidden' name='new' value='"
-	.  (($new == "oui") ? 'oui' : 'non')
-	.  "' />"
-	. "\n<p align='right'><input type='submit' value='"
+	$form .= "\n<p align='right'><input type='submit' value='"
 	. _T('bouton_enregistrer')
 	. "' class='fondo' />\n</p>";
 
 	$retour = generer_url_ecrire("naviguer");
-	$arg = intval($id_parent) . ",$new," . intval($id_rubrique);
+
+	if (!$arg = intval($id_rubrique)) $arg='oui';
 
 	echo generer_action_auteur("editer_rubrique", $arg, $retour, $form, " method='post'");
 
diff --git a/ecrire/inc/actions.php b/ecrire/inc/actions.php
index 69a7e8bd68..618da3f911 100644
--- a/ecrire/inc/actions.php
+++ b/ecrire/inc/actions.php
@@ -301,4 +301,5 @@ function ask_php_auth($pb, $raison, $retour, $url='', $re='', $lien='') {
 	exit;
 }
 
+
 ?>
diff --git a/ecrire/inc/chercher_rubrique.php b/ecrire/inc/chercher_rubrique.php
index 173fe20282..e14fedd8d8 100644
--- a/ecrire/inc/chercher_rubrique.php
+++ b/ecrire/inc/chercher_rubrique.php
@@ -31,6 +31,7 @@ function inc_chercher_rubrique_dist ($id_rubrique, $type, $restreint, $idem=0) {
 	// - soit parce que le cookie ajax n'est pas la
 	// - soit parce qu'il y a peu de rubriques
 	if ($_COOKIE['spip_accepte_ajax'] < 1
+	OR $type == 'breve'
 	OR spip_num_rows(
 	spip_query("SELECT id_rubrique FROM spip_rubriques LIMIT ".intval(_SPIP_SELECT_RUBRIQUES+1))) < _SPIP_SELECT_RUBRIQUES)
 		return selecteur_rubrique_html($id_rubrique, $type, $restreint, $idem);
diff --git a/ecrire/inc/drapeau_edition.php b/ecrire/inc/drapeau_edition.php
index 86ff306c7f..1ca6718401 100644
--- a/ecrire/inc/drapeau_edition.php
+++ b/ecrire/inc/drapeau_edition.php
@@ -90,6 +90,24 @@ function qui_edite ($id, $type='article') {
 	return $edition[$type][$id];
 }
 
+function mention_qui_edite ($id, $type='article') {
+	$modif = qui_edite($id, $type);
+	unset($modif[$GLOBALS['auteur_session']['id_auteur']]);
+
+	if ($modif) {
+		$quand = 0;
+		foreach ($modif as $duo) {
+			$auteurs[] = typo(extraire_multi(key($duo)));
+			$quand = max($quand, current($duo));
+		}
+		// format lie a la chaine de langue 'avis_article_modifie'
+		return array(
+			'nom_auteur_modif' => join(' | ', $auteurs),
+			'date_diff' => ceil((time()-$quand) / 60)
+		);
+	}
+}
+
 // Quels sont les articles en cours d'edition par X ?
 // http://doc.spip.org/@liste_drapeau_edition
 function liste_drapeau_edition ($id_auteur, $type = 'article') {
diff --git a/ecrire/inc/editer_article.php b/ecrire/inc/editer_article.php
index 51788265d6..733a7eb40b 100644
--- a/ecrire/inc/editer_article.php
+++ b/ecrire/inc/editer_article.php
@@ -47,8 +47,8 @@ function inc_editer_article($row, $lier_trad, $new, $champs_article) {
 	$id_secteur = $row['id_secteur'];
 	$date = $row['date'];
 	$extra = $row['extra'];
-	$onfocus = $row['onfocus'];
 	$statut = $row['statut'];
+	$onfocus = $row['onfocus']; // effacer le titre lorsque nouvel article
 	
 	if ($id_rubrique == 0) $logo = "racine-site-24.gif";
 	elseif ($id_secteur == $id_rubrique) $logo = "secteur-24.gif";
@@ -82,11 +82,7 @@ function inc_editer_article($row, $lier_trad, $new, $champs_article) {
 			  aide ("arttitre") .
 			  "<br />\n<input type='text' name='surtitre' class='forml' value=\"" .
 			  $surtitre .
-			  "\" size='40'" .
-// Pour faire fonctionner le onchange sur Safari il faudrait modifier
-// chaque input. Conclusion : c'est la mauvaise methode.
-// ' onchange="disable_other_forms(this.parentNode);"'.
-			  " /><p>")) .
+			  "\" size='40' /><p>")) .
 		_T('texte_titre_obligatoire') .
 		aide ("arttitre") .
 		"\n<br /><input type='text' name='titre' style='font-weight: bold; font-size: 13px;' class='formo' value=\"" .
@@ -163,7 +159,7 @@ function inc_editer_article($row, $lier_trad, $new, $champs_article) {
 	 	_T('texte_modifier_article') .
 		gros_titre($gros_titre,'',false) . 
 		"</td></tr></table><hr />\n<p>" .
-	  generer_action_auteur("editer_article", $new ? $new : $id_article, $redirect, $form, " method='post' name='formulaire' onchange='disable_other_forms(this);'");
+	  generer_action_auteur("editer_article", $new ? $new : $id_article, $redirect, $form, " method='post' name='formulaire'");
 
 }
 
diff --git a/ecrire/inc/extra.php b/ecrire/inc/extra.php
index 02bf4dbe40..4fcc71fe60 100644
--- a/ecrire/inc/extra.php
+++ b/ecrire/inc/extra.php
@@ -142,12 +142,14 @@ function extra_form($extra, $type, $ensemble='') {
 
 		switch($form) {
 
+			// complique car la valeur n'esst pas envoyee ar le nav si unchecked
 			case "case":
 			case "checkbox":
 				$affiche = ereg_replace("<br />$", "&nbsp;", $affiche);
-				$affiche .= "<INPUT TYPE='checkbox' NAME='suppl_$champ'";
+				$affiche .= "<input type='hidden' name='suppl_$champ' value='1' /><input type='checkbox' name='suppl_{$champ}_check'";
 				if ($extra[$champ] == 'true')
-					$affiche .= " CHECKED ";
+					$affiche .= " checked";
+					$affiche .= " />";
 				break;
 
 			case "list":
@@ -165,18 +167,18 @@ function extra_form($extra, $type, $ensemble='') {
 				if($valeurs == explode(",",""))
 					$valeurs = $choix ;
 
-				$affiche .= "<SELECT NAME='suppl_$champ' ";
-				$affiche .= "CLASS='forml'>\n";
+				$affiche .= "<select name='suppl_$champ' ";
+				$affiche .= "class='forml'>\n";
 				$i = 0 ;
 				while (list(, $choix_) = each($choix)) {
 					$val = $valeurs[$i] ;
-					$affiche .= "<OPTION VALUE=\"$val\"";
+					$affiche .= "<option value=\"$val\"";
 					if ($val == entites_html($extra[$champ]))
-						$affiche .= " SELECTED";
-					$affiche .= ">$choix_</OPTION>\n";
+						$affiche .= " selected";
+					$affiche .= ">$choix_</option>\n";
 					$i++;
 				}
-				$affiche .= "</SELECT>";
+				$affiche .= "</select>";
 				break;
 
 			case "radio":
@@ -191,16 +193,16 @@ function extra_form($extra, $type, $ensemble='') {
 
 				$i=0;
 				while (list(, $choix_) = each($choix)) {
-					$affiche .= "<INPUT TYPE='radio' NAME='suppl_$champ' ";
+					$affiche .= "<input type='radio' name='suppl_$champ' ";
 					$val = $valeurs[$i] ;
-					if (entites_html($extra["$champ"])== $val)
-						$affiche .= " CHECKED";
+					if (entites_html($extra[$champ])== $val)
+						$affiche .= " checked";
 
 					// premiere valeur par defaut
-					if (!$extra["$champ"] AND $i == 0)
-						$affiche .= " CHECKED";
+					if (!$extra[$champ] AND $i == 0)
+						$affiche .= " checked";
 
-					$affiche .= " VALUE='$val'>$choix_</INPUT>\n";
+					$affiche .= " value='$val'>$choix_</input>\n";
 					$i++;
 				}
 				break;
@@ -211,20 +213,22 @@ function extra_form($extra, $type, $ensemble='') {
 				$choix = explode(",",$choix);
 				if (!is_array($choix)) {
 					$affiche .= "Pas de choix d&eacute;finis.\n";
-					break; }
+					break;
+				}
+				$affiche .= "<input type='hidden' name='suppl_{$champ}' value='1' />";
 				for ($i=0; $i < count($choix); $i++) {
-					$affiche .= "<INPUT TYPE='checkbox' NAME='suppl_$champ$i'";
-					if (entites_html($extra["$champ"][$i])=="on")
-						$affiche .= " CHECKED";
+					$affiche .= "<input type='checkbox' name='suppl_$champ$i'";
+					if (entites_html($extra[$champ][$i])=="on")
+						$affiche .= " checked";
 					$affiche .= ">\n";
 					$affiche .= $choix[$i];
-					$affiche .= "</INPUT>\n";
+					$affiche .= "</input>\n";
 				}
 				break;
 
 			case "bloc":
 			case "block":
-				$affiche .= "<TEXTAREA NAME='suppl_$champ' CLASS='forml' ROWS='5' COLS='40'>".entites_html($extra[$champ])."</TEXTAREA>\n";
+				$affiche .= "<textarea name='suppl_$champ' class='forml' rows='5' cols='40'>".entites_html($extra[$champ])."</textarea>\n";
 				break;
 
 			case "masque":
@@ -234,12 +238,12 @@ function extra_form($extra, $type, $ensemble='') {
 			case "ligne":
 			case "line":
 			default:
-				$affiche .= "<INPUT TYPE='text' NAME='suppl_$champ' CLASS='forml'\n";
-				$affiche .= " VALUE=\"".entites_html($extra[$champ])."\" SIZE='40'>\n";
+				$affiche .= "<input type='text' name='suppl_$champ' class='forml'\n";
+				$affiche .= " value=\"".entites_html($extra[$champ])."\" size='40'>\n";
 				break;
 		}
 
-		$affiche .= "<p>\n";
+		$affiche .= "<p />\n";
 	}
 
 	return $affiche;
@@ -247,43 +251,47 @@ function extra_form($extra, $type, $ensemble='') {
 
 // recupere les valeurs postees pour reconstituer l'extra
 // http://doc.spip.org/@extra_recup_saisie
-function extra_recup_saisie($type) {
+function extra_recup_saisie($type, $c=false) {
 	$champs = $GLOBALS['champs_extra'][$type];
 	if (is_array($champs)) {
 		$extra = Array();
-		while(list($champ,)=each($champs)) {
-			list($style, $filtre, , $choix,) = explode("|", $GLOBALS['champs_extra'][$type][$champ]);
+		foreach($champs as $champ => $config)
+		if (($val = _request("suppl_$champ",$c)) !== NULL) {
+			list($style, $filtre, , $choix,) = explode("|", $config);
 			list(, $filtre) = explode(",", $filtre);
 			switch ($style) {
 			case "multiple":
 				$choix =  explode(",", $choix);
-				$extra["$champ"] = array();
+				$multiple = array();
 				for ($i=0; $i < count($choix); $i++) {
+					$val2 = _request("suppl_$champ$i",$c);
 					if ($filtre && function_exists($filtre))
-						 $extra["$champ"][$i] =
-						 	$filtre($GLOBALS["suppl_$champ$i"]);
+						 $multiple[$i] = $filtre($val2);
 					else
-						$extra["$champ"][$i] = $GLOBALS["suppl_$champ$i"];
+						$multiple[$i] = $val2;
 				}
+				$extra[$champ] = $multiple;
 				break;
 
 			case 'case':
 			case 'checkbox':
-				if ($GLOBALS["suppl_$champ"] == 'on')
-					$GLOBALS["suppl_$champ"] = 'true';
+				if (_request("suppl_{$champ}_check") == 'on')
+					$val = 'true';
 				else
-					$GLOBALS["suppl_$champ"] = 'false';
+					$val = 'false';
+				// pas de break; on continue
 
 			default:
 				if ($filtre && function_exists($filtre))
-				$extra["$champ"]=$filtre($GLOBALS["suppl_$champ"]);
-				else $extra["$champ"]=$GLOBALS["suppl_$champ"];
+					$extra[$champ] = $filtre($val);
+				else
+					$extra[$champ] = $val;
 				break;
 			}
 		}
 		return serialize($extra);
 	} else
-		return '';
+		return false;
 }
 
 // Retourne la liste des filtres a appliquer pour un champ extra particulier
@@ -363,4 +371,27 @@ function extra_affichage($extra, $type) {
 			. fin_cadre_enfonce(true);
 }
 
+// s'il y a mise a jour des extras, mixer les champs modifies
+// avec les champs existants (car la mise a jour peut etre partielle)
+function extra_update($type, $id, $c = false) {
+	$extra = @unserialize(extra_recup_saisie($type, $c));
+
+	// pas de mise a jour, ou erreur
+	if (!is_array($extra) OR !count($extra))
+		return false;
+
+	// passer de 'articles' a 'article' :-(
+	$t = preg_replace(',s$,', '', $type);
+
+	$orig = spip_query("SELECT extra FROM spip_".table_objet($t)." WHERE ".id_table_objet($t)."=".intval($id));
+	$orig = spip_fetch_array($orig);
+
+	if (isset($orig['extra'])
+	AND is_array($orig = @unserialize($orig['extra']))) {
+		$extra = array_merge($orig, $extra);
+	}
+
+	return serialize($extra);
+}
+
 ?>
diff --git a/ecrire/inc/mail.php b/ecrire/inc/mail.php
index 76005adafb..48e666b744 100644
--- a/ecrire/inc/mail.php
+++ b/ecrire/inc/mail.php
@@ -18,105 +18,10 @@ function envoyer_mail($email, $sujet, $texte, $from = "", $headers = "") {
 	return $f($email,$sujet,$texte,$from,$headers);
 }
 
-// http://doc.spip.org/@extrait_article
-function extrait_article($row) {
-	include_spip('inc/texte');
-	
-	$id_article = $row['id_article'];
-	$titre = nettoyer_titre_email($row['titre']);
-	$chapo = $row['chapo'];
-	$texte = $row['texte'];
-	$date = $row['date'];
-	$statut = $row['statut'];
-
-	$les_auteurs = "";
-	$result_auteurs = spip_query("SELECT nom FROM spip_auteurs AS auteurs, spip_auteurs_articles AS lien WHERE lien.id_article=$id_article AND auteurs.id_auteur=lien.id_auteur");
-
-	while ($row = spip_fetch_array($result_auteurs)) {
-		if ($les_auteurs) $les_auteurs .= ', ';
-		$les_auteurs .= trim(supprimer_tags(typo($row['nom'])));
-	}
-
-	$extrait = "** $titre **\n";
-	if ($les_auteurs) $extrait .= _T('info_les_auteurs_1', array('les_auteurs' => $les_auteurs));
-	if ($statut == 'publie') $extrait .= " "._T('date_fmt_nomjour_date', array('nomjour'=>nom_jour($date), 'date'=>affdate($date)));
-	$extrait .= "\n\n".textebrut(propre(couper_intro("$chapo<p>$texte", 700)))."\n\n";
-	if ($statut == 'publie') 
-		$extrait .= "-> ".
-		  generer_url_action("redirect", "id_article=$id_article", true) .
-		  "\n\n";
-	return $extrait;
-}
 
 // http://doc.spip.org/@nettoyer_titre_email
 function nettoyer_titre_email($titre) {
-	return ereg_replace("\n", ' ', supprimer_tags(extraire_multi($titre)));
-}
-
-// http://doc.spip.org/@envoyer_mail_publication
-function envoyer_mail_publication($id_article) {
-	$adresse_suivi = $GLOBALS['meta']["adresse_suivi"];
-	$nom_site_spip = nettoyer_titre_email($GLOBALS['meta']["nom_site"]);
-	$suivi_edito = $GLOBALS['meta']["suivi_edito"];
-
-	if ($suivi_edito == "oui") {
-		$result = spip_query("SELECT * FROM spip_articles WHERE id_article = $id_article");
-
-		if ($row = spip_fetch_array($result)) {
-
-			// selectionne langue
-			$lang_utilisateur = $GLOBALS['spip_lang'];
-			changer_langue($row['lang']);
-
-			$titre = nettoyer_titre_email($row['titre']);
-
-			$sujet = _T('info_publie_1', array('nom_site_spip' => $nom_site_spip, 'titre' => $titre));
-			$courr = _T('info_publie_2')."\n\n";
-
-			$nom = $GLOBALS['auteur_session']['nom'];
-			$nom = trim(supprimer_tags(typo($nom)));
-			$courr .= _T('info_publie_01', array('titre' => $titre, 'connect_nom' => $nom))."\n\n\n";
-			$courr = $courr . extrait_article($row);
-			envoyer_mail($adresse_suivi, $sujet, $courr);
-
-			// reinstalle la langue utilisateur (au cas ou)
-			changer_langue($lang_utilisateur);
-		}
-	}
-}
-
-// http://doc.spip.org/@envoyer_mail_proposition
-function envoyer_mail_proposition($id_article) {
-	$adresse_suivi = $GLOBALS['meta']["adresse_suivi"];
-	$nom_site_spip = nettoyer_titre_email($GLOBALS['meta']["nom_site"]);
-	$suivi_edito = $GLOBALS['meta']["suivi_edito"];
-
-	if ($suivi_edito == "oui") {
-		$row = spip_fetch_array(spip_query("SELECT * FROM spip_articles WHERE id_article = $id_article"));
-		if ($row) {
-
-			$lang_utilisateur = $GLOBALS['spip_lang'];
-			changer_langue($row['lang']);
-
-			$titre = nettoyer_titre_email($row['titre']);
-
-			$sujet = _T('info_propose_1', array('nom_site_spip' => $nom_site_spip, 'titre' => $titre));
-			envoyer_mail($adresse_suivi,
-				     $sujet,
-				     _T('info_propose_2')
-				     ."\n\n" 
-				     . _T('info_propose_3', array('titre' => $titre))
-				     ."\n" 
-				     . _T('info_propose_4')
-				     ."\n" 
-				     . _T('info_propose_5')
-				     ."\n" 
-				     . generer_url_ecrire("articles", "id_article=$id_article", true)
-				     . "\n\n\n" 
-				     . extrait_article($row));
-			changer_langue($lang_utilisateur);
-		}
-	}
+	return str_replace("\n", ' ', supprimer_tags(extraire_multi($titre)));
 }
 
 
diff --git a/ecrire/inc/notifications.php b/ecrire/inc/notifications.php
new file mode 100644
index 0000000000..14ff9b270c
--- /dev/null
+++ b/ecrire/inc/notifications.php
@@ -0,0 +1,154 @@
+<?php
+
+/***************************************************************************\
+ *  SPIP, Systeme de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright (c) 2001-2006                                                *
+ *  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;
+
+
+// Fonctione appelee par divers pipelines
+function notifications($pipeline, $x) {
+
+	// En cas de changement de statut d'article vers 'publie' ou 'prop',
+	// envoyer un mail
+	if ($pipeline == 'pre_enregistre_contenu'
+	AND $x['args']['table'] == 'spip_articles'
+	AND (
+		$x['data']['statut'] == 'publie'
+		OR $x['data']['statut'] == 'prop')
+	) {
+
+		$statut = $x['data']['statut'];
+		$id_article = intval($x['args']['id_objet']);
+		$result = spip_query("SELECT statut FROM spip_articles WHERE id_article=$id_article");
+		if ($row = spip_fetch_array($result))
+			$statut_ancien = $row['statut'];
+		else
+			return $x;
+
+		// ne devrait jamais se produire
+		if ($statut == $statut_ancien)
+			return $x;
+
+		include_spip('inc/lang');
+		include_spip('inc/texte');
+		include_spip('inc/mail');
+
+		if ($statut == 'publie')
+			envoyer_mail_publication($id_article);
+
+		if ($statut == 'prop' AND $statut_ancien != 'publie')
+			envoyer_mail_proposition($id_article);
+	}
+
+	return $x;
+}
+
+
+// http://doc.spip.org/@extrait_article
+function extrait_article($row) {
+	include_spip('inc/texte');
+	
+	$id_article = $row['id_article'];
+	$titre = nettoyer_titre_email($row['titre']);
+	$chapo = $row['chapo'];
+	$texte = $row['texte'];
+	$date = $row['date'];
+	$statut = $row['statut'];
+
+	$les_auteurs = "";
+	$result_auteurs = spip_query("SELECT nom FROM spip_auteurs AS auteurs, spip_auteurs_articles AS lien WHERE lien.id_article=$id_article AND auteurs.id_auteur=lien.id_auteur");
+
+	while ($row = spip_fetch_array($result_auteurs)) {
+		if ($les_auteurs) $les_auteurs .= ', ';
+		$les_auteurs .= trim(supprimer_tags(typo($row['nom'])));
+	}
+
+	$extrait = "** $titre **\n";
+	if ($les_auteurs) $extrait .= _T('info_les_auteurs_1', array('les_auteurs' => $les_auteurs));
+	if ($statut == 'publie') $extrait .= " "._T('date_fmt_nomjour_date', array('nomjour'=>nom_jour($date), 'date'=>affdate($date)));
+	$extrait .= "\n\n".textebrut(propre(couper_intro("$chapo<p>$texte", 700)))."\n\n";
+	if ($statut == 'publie') 
+		$extrait .= "-> "
+			. generer_url_action("redirect", "id_article=$id_article", true)
+			. "\n\n";
+	return $extrait;
+}
+
+
+// http://doc.spip.org/@envoyer_mail_publication
+function envoyer_mail_publication($id_article) {
+	$adresse_suivi = $GLOBALS['meta']["adresse_suivi"];
+	$nom_site_spip = nettoyer_titre_email($GLOBALS['meta']["nom_site"]);
+	$suivi_edito = $GLOBALS['meta']["suivi_edito"];
+
+	if ($suivi_edito == "oui") {
+		$result = spip_query("SELECT * FROM spip_articles WHERE id_article = $id_article");
+
+		if ($row = spip_fetch_array($result)) {
+
+			// selectionne langue
+			$lang_utilisateur = $GLOBALS['spip_lang'];
+			changer_langue($row['lang']);
+
+			$titre = nettoyer_titre_email($row['titre']);
+
+			$sujet = _T('info_publie_1', array('nom_site_spip' => $nom_site_spip, 'titre' => $titre));
+			$courr = _T('info_publie_2')."\n\n";
+
+			$nom = $GLOBALS['auteur_session']['nom'];
+			$nom = trim(supprimer_tags(typo($nom)));
+			$courr .= _T('info_publie_01', array('titre' => $titre, 'connect_nom' => $nom))."\n\n\n";
+			$courr = $courr . extrait_article($row);
+			envoyer_mail($adresse_suivi, $sujet, $courr);
+
+			// reinstalle la langue utilisateur (au cas ou)
+			changer_langue($lang_utilisateur);
+		}
+	}
+}
+
+// http://doc.spip.org/@envoyer_mail_proposition
+function envoyer_mail_proposition($id_article) {
+	$adresse_suivi = $GLOBALS['meta']["adresse_suivi"];
+	$nom_site_spip = nettoyer_titre_email($GLOBALS['meta']["nom_site"]);
+	$suivi_edito = $GLOBALS['meta']["suivi_edito"];
+
+	if ($suivi_edito == "oui") {
+		$row = spip_fetch_array(spip_query("SELECT * FROM spip_articles WHERE id_article = $id_article"));
+		if ($row) {
+
+			$lang_utilisateur = $GLOBALS['spip_lang'];
+			changer_langue($row['lang']);
+
+			$titre = nettoyer_titre_email($row['titre']);
+
+			$sujet = _T('info_propose_1', array('nom_site_spip' => $nom_site_spip, 'titre' => $titre));
+			envoyer_mail($adresse_suivi,
+				$sujet,
+				_T('info_propose_2')
+				."\n\n" 
+				. _T('info_propose_3', array('titre' => $titre))
+				."\n" 
+				. _T('info_propose_4')
+				."\n" 
+				. _T('info_propose_5')
+				."\n" 
+				. generer_url_ecrire("articles", "id_article=$id_article", true)
+				. "\n\n\n" 
+				. extrait_article($row)
+			);
+			changer_langue($lang_utilisateur);
+		}
+	}
+}
+
+
+?>
diff --git a/ecrire/inc/presentation.php b/ecrire/inc/presentation.php
index 310cb7a9af..dfbb364480 100644
--- a/ecrire/inc/presentation.php
+++ b/ecrire/inc/presentation.php
@@ -1908,9 +1908,6 @@ function init_body($rubrique='accueil', $sous_rubrique='accueil', $load='', $id_
 		return;
 	}
 
-	// iframe permettant de passer les changements de statut rapides
-	echo "<iframe id='iframe_action' name='iframe_action' width='1' height='1' style='position: absolute; visibility: hidden;'></iframe>";
-
 	// Lien oo
 	echo "<div class='invisible_au_chargement' style='position: absolute; height: 0px; visibility: hidden;'><a href='oo'>"._T("access_mode_texte")."</a></div>";
 	
diff --git a/ecrire/inc/utils.php b/ecrire/inc/utils.php
index 30ab41fd74..6e816f4ae3 100644
--- a/ecrire/inc/utils.php
+++ b/ecrire/inc/utils.php
@@ -227,9 +227,13 @@ function _q($arg_sql) {
 }
 
 // Renvoie le _GET ou le _POST emis par l'utilisateur
-//
+// ou pioche dans $c si c'est un array()
 // http://doc.spip.org/@_request
-function _request($var) {
+function _request($var, $c=false) {
+
+	if (is_array($c))
+		return isset($c[$var]) ? $c[$var] : NULL;
+
 	if (isset($_GET[$var])) $a = $_GET[$var];
 	elseif (isset($_POST[$var])) $a = $_POST[$var];
 	else return NULL;
@@ -250,14 +254,24 @@ function _request($var) {
 
 	return $a;
 }
+
 // Methode set de la fonction _request()
-//
+// Attention au cas ou l'on fait set_request('truc', NULL);
 // http://doc.spip.org/@set_request
-function set_request($var, $val = NULL) {
-	unset($_GET[$var]); // au cas ou l'on fait set_request('truc', NULL);
+function set_request($var, $val = NULL, $c=false) {
+	if (is_array($c)) {
+		unset($c[$var]);
+		if ($val !== NULL)
+			$c[$var] = $val;
+		return $c;
+	}
+
+	unset($_GET[$var]);
 	unset($_POST[$var]);
 	if ($val !== NULL)
 		$_GET[$var] = $val;
+	
+	return false; # n'affecte pas $c
 }
 
 //
@@ -1192,4 +1206,11 @@ function lang_dselect ($rien='') {
 	}
 }
 
+// pipeline appelant la fonction de notification
+// avant chaque modification du contenu
+function notif_pre_enregistre_contenu($x) {
+	include_spip('inc/notifications');
+	return notifications('pre_enregistre_contenu', $x);
+}
+
 ?>
diff --git a/ecrire/inc_version.php b/ecrire/inc_version.php
index 761ef2f838..ca379e6a7d 100644
--- a/ecrire/inc_version.php
+++ b/ecrire/inc_version.php
@@ -234,7 +234,7 @@ $spip_pipeline = array(
 	'insert_head' => '|f_jQuery',
 	'nettoyer_raccourcis_typo' => '',
 	'pre_indexation' => '',
-	'pre_enregistre_contenu' => '',
+	'pre_enregistre_contenu' => '|notif_pre_enregistre_contenu',
 	'pre_propre' => '|extraire_multi',
 	'pre_syndication' => '',
 	'pre_typo' => '|extraire_multi',
-- 
GitLab