From 707b09ed529876ad1d1a1966c819571f209546c7 Mon Sep 17 00:00:00 2001
From: Fil <fil@rezo.net>
Date: Wed, 20 Apr 2005 19:35:02 +0000
Subject: [PATCH] podcasting et documents distants, commit initial

---
 .gitattributes                 |   1 +
 dist/backend.html              |  27 ++--
 ecrire/articles.php3           |   6 +-
 ecrire/img_pack/attachment.gif | Bin 0 -> 976 bytes
 ecrire/inc_auxbase.php3        |   2 +
 ecrire/inc_documents.php3      |  62 ++++++---
 ecrire/inc_filtres.php3        |  73 +++++++---
 ecrire/inc_getdocument.php3    | 238 +++++++++++++++++++++++++++------
 ecrire/inc_logos.php3          |  40 ------
 ecrire/inc_sites.php3          | 123 +++++++++++++++--
 ecrire/inc_texte.php3          |   8 +-
 ecrire/inc_urls.php3           |  16 ++-
 inc-boucles.php3               |   6 +-
 inc-compilo-api.php3           |   6 +
 inc-criteres.php3              |   8 +-
 spip_image.php3                |  16 ++-
 16 files changed, 472 insertions(+), 160 deletions(-)
 create mode 100644 ecrire/img_pack/attachment.gif

diff --git a/.gitattributes b/.gitattributes
index 9657dc1467..78cb595a48 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -82,6 +82,7 @@ ecrire/img_pack/annonce.gif -text
 ecrire/img_pack/article-24.gif -text
 ecrire/img_pack/asuivre-24.gif -text
 ecrire/img_pack/asuivre-48.png -text
+ecrire/img_pack/attachment.gif -text
 ecrire/img_pack/auteur-24.gif -text
 ecrire/img_pack/barre-blanc.gif -text
 ecrire/img_pack/barre-d.gif -text
diff --git a/dist/backend.html b/dist/backend.html
index bf7923d4a4..39cd2f2fab 100644
--- a/dist/backend.html
+++ b/dist/backend.html
@@ -12,36 +12,35 @@
 
 	<image>
 		<title>[(#NOM_SITE_SPIP|texte_backend)]</title>
-		<url>#URL_SITE_SPIP[/(#LOGO_SITE_SPIP||extraire_attribut{src})]</url>
+		<url>[(#LOGO_SITE_SPIP||extraire_attribut{src}|url_absolue|texte_backend)]</url>
 		<link>#URL_SITE_SPIP/</link>
 		<description></description>
 	</image>
 
-	<BOUCLE_10recents(ARTICLES){lang ?}{branche ?}{par date}{inverse}{0,10}{unique}>
+	<BOUCLE_un_article(ARTICLES){id_article}>
 		<item>
 		<title>[(#TITRE|texte_backend)]</title>
 		<link>#URL_SITE_SPIP/#URL_ARTICLE</link>
 		<date>#DATE</date>
-		<description>[&lt;img src="#URL_SITE_SPIP/(#LOGO_ARTICLE||extraire_attribut{src})" align="left" hspace="4" vspace="4"&gt; ][(#INTRODUCTION|texte_backend)]</description>
+		<description>[(#LOGO_ARTICLE|right||liens_absolus|texte_backend)][(#TEXTE|liens_absolus|texte_backend)]</description>
 		<author><BOUCLE_auteurs(AUTEURS){id_article}{", "}>[(#NOM|texte_backend)]</BOUCLE_auteurs></author>
 		<dc:date>[(#DATE|date_iso)]</dc:date>
 		<dc:format>text/html</dc:format>
 		<dc:language>#LANG</dc:language>
 		<dc:creator><BOUCLE_auteursb(AUTEURS){id_article}{", "}>[(#NOM|texte_backend)]</BOUCLE_auteursb></dc:creator>
+		<BOUCLE_podcast(DOCUMENTS){id_article}{doublons}{extension==(mp3|zip)}>[
+			<enclosure url="(#URL_DOCUMENT|url_absolue|unique)" length="[(#TAILLE)]" type="#MIME_TYPE" />]
+		</BOUCLE_podcast>
+
 		</item>
+	</BOUCLE_un_article>
+
+
+	<BOUCLE_10recents(ARTICLES){lang ?}{branche ?}{par date}{inverse}{0,10}{unique}>
+		<BOUCLE_a(BOUCLE_un_article)></BOUCLE_a>
 	</BOUCLE_10recents>
 	<BOUCLE_tres_recents(ARTICLES){lang ?}{branche ?}{par date}{inverse}{age<3}{unique}>
-		<item>
-		<title>[(#TITRE|texte_backend)]</title>
-		<link>#URL_SITE_SPIP/#URL_ARTICLE</link>
-		<date>#DATE</date>
-		<description>[&lt;img src="#URL_SITE_SPIP/(#LOGO_ARTICLE||extraire_attribut{src})" align="left" hspace="4" vspace="4"&gt; ][(#INTRODUCTION|texte_backend)]</description>
-		<author><BOUCLE_auteurs_t(AUTEURS){id_article}{","}>[(#NOM|texte_backend)]</BOUCLE_auteurs_t></author>
-		<dc:date>[(#DATE|date_iso)]</dc:date>
-		<dc:format>text/html</dc:format>
-		<dc:language>#LANG</dc:language>
-		<dc:creator><BOUCLE_auteurs_tb(AUTEURS){id_article}{", "}>[(#NOM|texte_backend)]</BOUCLE_auteurs_tb></dc:creator>
-		</item>
+		<BOUCLE_b(BOUCLE_un_article)></BOUCLE_b>
 	</BOUCLE_tres_recents>
 
 </channel>
diff --git a/ecrire/articles.php3 b/ecrire/articles.php3
index c750392f68..d8895dc267 100644
--- a/ecrire/articles.php3
+++ b/ecrire/articles.php3
@@ -1422,7 +1422,7 @@ if ((lire_meta('multi_articles') == 'oui')
 
 			echo "<form action='$lien' method='post' style='margin:0px; padding:0px;'>";
 			echo _T('trad_lier');
-			echo "<div align='$spip_lang_right'><input type='text' class='fondl' name='lier_trad' size='5'> <INPUT TYPE='submit' NAME='Modifier' VALUE='"._T('bouton_modifier')."' CLASS='fondl'></div>";
+			echo "<div align='$spip_lang_right'><input type='text' class='fondl' name='lier_trad' size='5'> <INPUT TYPE='submit' NAME='Valider' VALUE='"._T('bouton_valider')."' CLASS='fondl'></div>";
 			echo "</form>";
 			echo "</td>\n";
 			echo "<td background='' width='10'> &nbsp; </td>";
@@ -1502,9 +1502,9 @@ if ($connect_statut == '0minirezo' AND acces_rubrique($rubrique_article)) {
 
 	echo " &nbsp; ". http_img_pack("puce-".puce_statut($statut_article).'.gif', "", "border='0' NAME='statut'") . "  &nbsp; ";
 
-	// echo "<noscript><INPUT TYPE='submit' NAME='Modifier' VALUE='"._T('bouton_modifier')."' CLASS='fondo'></noscript>";
+	// echo "<noscript><INPUT TYPE='submit' NAME='Valider' VALUE='"._T('bouton_valider')."' CLASS='fondo'></noscript>";
 	echo "<span class='visible_au_chargement' id='valider_statut'>";
-	echo "<INPUT TYPE='submit' NAME='Modifier' VALUE='"._T('bouton_modifier')."' CLASS='fondo'>";
+	echo "<INPUT TYPE='submit' NAME='Valider' VALUE='"._T('bouton_valider')."' CLASS='fondo'>";
 	echo "</span>";
 	echo aide ("artstatut");
 	echo "</CENTER>";
diff --git a/ecrire/img_pack/attachment.gif b/ecrire/img_pack/attachment.gif
new file mode 100644
index 0000000000000000000000000000000000000000..72fbb17ad4752785010f771b2fa7d95aad96d00c
GIT binary patch
literal 976
zcmV;>126nXNk%w1VGjTg0OtSz000010RaL60s{jB1Ox;H1qB8M1_uWR2nYxX2?+`c
z3JVJh3=9kn4Gj(s4i66x5D*X%5fKs+5)%^>6ciK{6%`g178e&67#J8C85tTH8XFrM
z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7
zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?
zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy
zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj
zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T
za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD
zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}
zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(
zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p
zxVX5vxw*Q!y1To(yu7@<y}iD^zQ4b}z`(%4!NJ19!o$PE#KgqK#l^<P#>dCU$jHda
z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1<F+1c9K
z+S}XP+}zyV-QC{a-rwKf;Nall;o;)q;^X7v<mBY#<>lt)=I7_<=;-L_>FMg~>g((4
z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg=
z{r&#_{{R2~A^8LW3IP59EC2ui01p5U000QB0R0IZC~)7bFGbuaBS<ivn<j@wxhb-c
zAv`i<Rz=(w=!-=+WI9PXlSJ6AA_Vc-;j$=6Cx2B;Eh0luk(8FE{H<!Ts>rT^qmnFY
zlF6U2BALk8*(dO1pelj<Z4;`f$vA=Ink*Vc1|B>vc1-ychz}$_fAGqZndS1Iz*$AM
y4eTRj7gV<bzXZbDQdyrfX9ptvhi_34VN%mETom(66T}P&_9<dVZsdUh0RTHqAJKOJ

literal 0
HcmV?d00001

diff --git a/ecrire/inc_auxbase.php3 b/ecrire/inc_auxbase.php3
index 8f52a54cca..8ec9e684d7 100644
--- a/ecrire/inc_auxbase.php3
+++ b/ecrire/inc_auxbase.php3
@@ -369,6 +369,8 @@ $tables_auxiliaires  =
 				       'key' => &$spip_documents_rubriques_key),
 	'spip_documents_breves' => array('field' => &$spip_documents_breves,
 				    'key' => &$spip_documents_breves_key),
+	'spip_documents_syndic' => array('field' => &$spip_documents_syndic,
+				    'key' => &$spip_documents_syndic_key),
 	'spip_mots_articles' => array('field' => &$spip_mots_articles,
 				 'key' => &$spip_mots_articles_key),
 	'spip_mots_breves' => array('field' => &$spip_mots_breves,
diff --git a/ecrire/inc_documents.php3 b/ecrire/inc_documents.php3
index f3c9f1bc7b..42f17df436 100644
--- a/ecrire/inc_documents.php3
+++ b/ecrire/inc_documents.php3
@@ -52,12 +52,20 @@ function vignette_par_defaut($type_extension, $size=true) {
 }
 
 
-function document_et_vignette($url, $document) {
-	eregi('\.([a-z0-9]+)$', $document, $regs);
+function document_et_vignette($url, $id_type) {
+	if ($id_type) {
+		list($extension) = spip_fetch_array(spip_query("SELECT id_type FROM
+		spip_types_documents WHERE id_type=$id_type"));
+	}
+
 	list($fichier, $largeur, $hauteur) =
-		vignette_par_defaut($regs[1]);
-	$doc = "<a href='$url'><img src='$fichier' style='border-width: 0px' /></a>";
-	return $doc;
+		vignette_par_defaut($extension);
+
+	if (!$taille)
+		return "<a href='$url'><img src='$fichier' style='border-width: 0px' /></a>";
+	else
+		return "<a href='$url'><img src='$fichier' style='border-width: 0px'  height='$taille' width='$taille' /></a>";
+
 }
 
 //
@@ -417,8 +425,10 @@ function texte_vignette_document($largeur_vignette, $hauteur_vignette, $fichier_
 function afficher_formulaire_taille($document, $type_inclus='AUTO') {
 
 	// (on ne le propose pas pour les images qu'on sait
-	// lire, id_type<=3)
-	if ($document['id_type'] <= 3)
+	// lire, id_type<=3), sauf bug, ou document distant
+	if ($document['id_type'] <= 3
+	AND $document['hauteur']*$document['largeur']>0
+	AND $document['distant']!='oui')
 		return '';
 
 	// Si on n'a pas le type_inclus, on va le chercher dans spip_types_documents
@@ -428,7 +438,7 @@ function afficher_formulaire_taille($document, $type_inclus='AUTO') {
 	AND $type = @spip_fetch_array($r))
 			$type_inclus = $type['inclus'];
 
-	if (($type_inclus == "embed"
+	if (($type_inclus == "embed"  #meme pour le MP3 : "l x h pixels"? 
 	OR $type_inclus == "image")) {
 		echo "<br /><b>"._T('entree_dimensions')."</b><br />\n";
 		echo "<input type='text' name='largeur_document' class='fondl' style='font-size:9px;' value=\"".$document['largeur']."\" size='5'>";
@@ -442,7 +452,7 @@ function afficher_formulaire_taille($document, $type_inclus='AUTO') {
 //
 
 function afficher_upload($link, $redirect='', $intitule, $inclus = '', $envoi_multiple = true, $forcer_document = false) {
-	global $clean_link, $connect_statut, $connect_toutes_rubriques, $options;
+	global $clean_link, $connect_statut, $connect_toutes_rubriques, $options, $spip_lang_right;
 	static $num_form = 0; $num_form ++;
 
 
@@ -458,7 +468,7 @@ function afficher_upload($link, $redirect='', $intitule, $inclus = '', $envoi_mu
 
 	// bouton permettant de telecharger 10 images ou docs a la fois
 	$envoi_multiple &= ($options == "avancees");
-	if ($envoi_multiple)
+	if ($envoi_multiple OR $forcer_document)
 		echo bouton_block_invisible("ftp$num_form");
 
 	if (tester_upload()) {
@@ -485,9 +495,10 @@ function afficher_upload($link, $redirect='', $intitule, $inclus = '', $envoi_mu
 
 	echo "</div>\n";
 
+	echo debut_block_invisible("ftp$num_form");
+
 	if ($connect_statut == '0minirezo' AND $connect_toutes_rubriques
 	AND $envoi_multiple) {
-		echo debut_block_invisible("ftp$num_form");
 		$texte_upload = texte_upload_manuel(_DIR_TRANSFERT, $inclus);
 		if ($texte_upload) {
 			echo "<p><div style='color: #505050;'>";
@@ -505,8 +516,20 @@ function afficher_upload($link, $redirect='', $intitule, $inclus = '', $envoi_mu
 			echo _T('info_installer_ftp').aide("ins_upload");
 			echo "</div>";
 		}
-		echo fin_block();
 	}
+
+	// Lien document distant, jamais en mode image
+	if ($forcer_document) {
+		echo "<p /><div style='border: 1px #303030 solid; padding: 4px; color: #505050;'>";
+		echo "<img src='"._DIR_IMG_PACK.'attachment.gif',
+			"' style='float: $spip_lang_right;' alt=\"\" />\n";
+		echo "\n"._L('R&eacute;f&eacute;rencer un document sur l\'internet')."&nbsp;:<br />";
+		echo "\n<input name='image_url' size='32' class='fondl' value='http://' />";
+		echo "\n  <div align='".$GLOBALS['spip_lang_right']."'><input name='ok_url' type='Submit' value='"._T('bouton_choisir')."' class='fondo'></div>";
+		echo "</div>\n";
+	}
+
+	echo fin_block();
 	echo "</form>\n";
 }
 
@@ -551,10 +574,17 @@ function afficher_portfolio (
 		if ($case == 0) {
 			echo "<tr style='border-top: 1px solid black;'>";
 		}
+		
 		$style = "border-$spip_lang_left: 1px solid $couleur; border-bottom: 1px solid $couleur;";
 		if ($case == $bord_droit) $style .= " border-$spip_lang_right: 1px solid $couleur;";
 		echo "<td width='33%' style='text-align: $spip_lang_left; $style' valign='top'>";
 
+			// Signaler les documents distants par une icone de site
+			if ($document['distant'] == 'oui') {
+				echo "<img src='"._DIR_IMG_PACK.'attachment.gif'."' style='float: $spip_lang_right;' alt=\"".entites_html($document['fichier'])."\" title=\"" .
+entites_html($document['fichier'])."\" />\n";
+			}
+
 			// bloc vignette + rotation
 			echo "<div style='text-align:center;'>";
 			
@@ -574,7 +604,8 @@ function afficher_portfolio (
 
 			// bloc rotation de l'image
 			if ($flag_modif
-			AND strstr(lire_meta('formats_graphiques'), $document['extension'])) {
+			AND strstr(lire_meta('formats_graphiques'), $document['extension'])
+			AND $document['distant']!='oui') {
 				echo "<div class='verdana1' style='float: $spip_lang_right; text-align: $spip_lang_right;'>";
 				$process = lire_meta('image_process');
 				if ($process == 'imagick' OR $process == 'gd2'
@@ -634,7 +665,7 @@ function afficher_portfolio (
 				echo texte_vignette_document($largeur_vignette, $hauteur_vignette, $fichier_vignette, $url);
 			}
 			else {
-				echo document_et_vignette($url, $fichier); 
+				echo document_et_vignette($url, $document['id_type']); 
 			}
 
 			echo "</div>"; // fin du bloc vignette + rotation
@@ -801,7 +832,8 @@ function bloc_gerer_vignette($document, $image_url, $redirect_url, $album) {
 	else {
 		// lien "creation automatique"
 		if (strstr(lire_meta('formats_graphiques'), $document['extension'])
-		AND lire_meta('creer_preview') == 'oui') {
+		AND lire_meta('creer_preview') == 'oui'
+		AND $document['distant'] != 'oui') {
 			$link = new Link($image_url);
 			$link->addvar('creer_vignette', 'oui');
 			$link->addVar('redirect',
diff --git a/ecrire/inc_filtres.php3 b/ecrire/inc_filtres.php3
index 61cb9e8d05..1d534bfcc8 100644
--- a/ecrire/inc_filtres.php3
+++ b/ecrire/inc_filtres.php3
@@ -254,6 +254,8 @@ function attribut_html($texte) {
 
 // Vider les url nulles comme 'http://' ou 'mailto:'
 function vider_url($url) {
+	# un message pour abs_url
+	$GLOBALS['mode_abs_url'] = 'url';
 
 	$url = trim($url);
 	if (eregi("^(http:?/?/?|mailto:?)$", $url))
@@ -855,10 +857,10 @@ function http_script($script, $src='', $noscript='') {
 function tester_config($ignore, $quoi) {
 	switch ($quoi) {
 		case 'mode_inscription':
-			if (lire_meta("accepter_inscriptions") == "oui")       
+			if (lire_meta("accepter_inscriptions") == "oui")
 				return 'redac';
-			else if (lire_meta("accepter_visiteurs") == "oui" 
-			OR lire_meta('forums_publics') == 'abo')               
+			else if (lire_meta("accepter_visiteurs") == "oui"
+			OR lire_meta('forums_publics') == 'abo')
 				return 'forum';
 			else
 				return '';
@@ -883,24 +885,52 @@ function calendrier($date='', $type='mois', $echelle='', $partie_cal='', $script
      http_calendrier_init($date, $type, $echelle, $partie_cal, $script);
 }
 
-// un filtre pour transformer les URLs relatives en URLs absolues ;
-// ne s'applique qu'aux #URL_XXXX
-function url_absolue($url) {
-	$url = trim($url);
 
-	if (preg_match(',^[a-z0-9]+://,i', $url))
-		return $url;
+//
+// Filtres d'URLs
+//
+
+// Nettoyer une URL contenant des ../
+//
+// echo resolve_url('/.././/truc/chose/machin/./.././.././hopla/..');
+// inspire (de loin) par PEAR:NetURL:resolvePath
+//
+function resolve_path($url) {
+	while (preg_match(',/\.?/,', $url, $regs)		# supprime // et /./
+	OR preg_match(',/[^/]*/\.\./,', $url, $regs)	# supprime /toto/../
+	OR preg_match(',^/\.\./,', $url, $regs))		# supprime les /../ du haut
+		$url = str_replace($regs[0], '/', $url);
 
-	$site = lire_meta('adresse_site');
-	if ($url[0] == '/') {
-		if (preg_match(',^([a-z0-9]+://)(.*?/)?,i', $site.'/', $regs))
-			$host = $regs[1].$regs[2];
-		else
-			$host = $site.'/';
-		return $host.substr($url,1);
+	return $url;
+}
+
+// 
+// Suivre un lien depuis une adresse donnee -> nouvelle adresse
+//
+// echo suivre_lien('http://rezo.net/sous/dir/../ect/ory/fi.html..s#toto',
+// 'a/../../titi.coco.html/tata#titi');
+function suivre_lien($url, $lien) {
+	# lien absolu ? ok
+	if (preg_match(',^([a-z0-9]+://|mailto:),i', $lien))
+		return $lien;
+
+	# lien relatif, il faut verifier l'url de base
+	if (preg_match(',^(.*?://[^/]+)(/.*?/?)?[^/]*$,', $url, $regs)) {
+		$debut = $regs[1];
+		$dir = $regs[2];
 	}
+	if (substr($lien,0,1) == '/')
+		return $debut . resolve_path($lien);
+	else
+		return $debut . resolve_path($dir.$lien);
+}
 
-	return $site.'/'.$url;
+// un filtre pour transformer les URLs relatives en URLs absolues ;
+// ne s'applique qu'aux #URL_XXXX
+function url_absolue($url) {
+	if (strlen($url = trim($url)) == 0)
+		return '';
+	return suivre_lien(lire_meta('adresse_site').'/', $url);
 }
 
 // un filtre pour transformer les URLs relatives en URLs absolues ;
@@ -917,5 +947,14 @@ function liens_absolus($texte) {
 	return $texte;
 }
 
+//
+// Ce filtre public va traiter les URL ou les <a href>
+//
+function abs_url($texte) {
+	if ($GLOBALS['mode_abs_url'] == 'url')
+		return url_absolue($url);
+	else
+		return liens_absolus($texte);
+}
 
 ?>
diff --git a/ecrire/inc_getdocument.php3 b/ecrire/inc_getdocument.php3
index 3044dcb001..857098fe46 100644
--- a/ecrire/inc_getdocument.php3
+++ b/ecrire/inc_getdocument.php3
@@ -210,55 +210,157 @@ function afficher_compactes($image_name /* not used */, $fichiers, $link) {
 	install_fin_html();
 }
 
+// Si on doit conserver une copie locale des fichiers distants, autant que ca
+// soit a un endroit canonique -- si ca peut etre bijectif c'est encore mieux,
+// mais la tout de suite je ne trouve pas l'idee, etant donne les limitations
+// des filessystems
+function fichier_copie_locale($source, $extension) {
+	$dir = _DIR_IMG. creer_repertoire(_DIR_IMG, 'distant'); # IMG/distant/
+	$dir2 = $dir . creer_repertoire($dir, $extension); 		# IMG/distant/pdf/
+	return $dir2 . substr(basename($source).'-'.md5($source),0,12).
+		substr(md5($source),0,4).'.'.$extension;
+}
+
+// Recuperer les infos d'un document distant, sans trop le telecharger
+function recuperer_infos_distantes($source, $max=0) {
+	include_ecrire('inc_sites.php3');
+
+	$a = array();
+
+	// On va directement charger le debut des images et des fichiers html,
+	// de maniere a attrapper le maximum d'infos (titre, taille, etc). Si
+	// ca echoue l'utilisateur devra les entrer...
+	if ($headers = recuperer_page($source, false, true, $max)) {
+		list($headers, $a['body']) = split("\n\n", $headers, 2);
+		if (preg_match(",\nContent-Type: *([^[:space:];]*),i",
+			"\n$headers", $regs)
+		AND $mime_type = addslashes(trim($regs[1]))
+		AND $s = spip_query("SELECT id_type,extension FROM spip_types_documents
+			WHERE mime_type='$mime_type'")
+		AND $t = spip_fetch_array($s)) {
+			spip_log("mime-type $mime_type ok");
+			$a['id_type'] = $t['id_type'];
+			$a['extension'] = $t['extension'];
+		} else {
+			spip_log("mime-type $mime_type inconnu");
+			return false;
+		}
+
+		if (preg_match(",\nContent-Length: *([^[:space:]]*),i",
+			"\n$headers", $regs))
+			$a['taille'] = intval($regs[1]);
+	}
+
+	// Si on n'a pas reussi avec une requete HEAD, ou si au contraire on a
+	// il s'agit d'une image pas trop grosse ou d'un fichier html, on va aller
+	// recharger le document en GET et recuperer des donnees supplementaires...
+	if (preg_match(',^image/(jpeg|gif|png|swf),', $mime_type)) {
+		if ($max == 0
+		AND $taille < 1024*1024
+		AND ereg(",".$a['extension'].",",
+		','.lire_meta('formats_graphiques').',')){
+			$a = recuperer_infos_distantes($source, 1024*1024);
+		}
+		else if ($a['body']) {
+			$a['fichier'] = fichier_copie_locale($source, $a['extension']);
+			ecrire_fichier($a['fichier'], $a['body']);
+			$size_image = @getimagesize($a['fichier']);
+			$a['largeur'] = intval($size_image[0]);
+			$a['hauteur'] = intval($size_image[1]);
+			$a['type_image'] = true;
+		}
+	}
+	
+	if ($mime_type == 'text/html') {
+		$page = recuperer_page($source, true, false, 1024*1024);
+		if(preg_match(',<title>(.*?)</title>,ims', $page, $regs))
+			$a['titre'] = corriger_caracteres(trim($regs[1]));
+			if (!$a['taille']) $a['taille'] = strlen($page); # a peu pres
+	}
+
+	return $a;
+}
+
 
 //
 // Ajouter un document (au format $_FILES)
 //
 function ajouter_un_document ($source, $nom_envoye, $type_lien, $id_lien, $mode, $id_document, &$documents_actifs) {
 
-	// type de document inconnu ?
-	if (!ereg("\.([^.]+)$", $nom_envoye, $match)) {
-		spip_log("nom envoye incorrect ($nom_envoye)");
-		return;
-	}
-
-	// tester le type de document :
-	// - interdit a l'upload ?
-	// - quel numero dans spip_types_documents ?  =-(
-	// - est-ce "inclus" comme une image ?
-	$ext = corriger_extension(addslashes(strtolower($match[1])));
-
-	if (!$row = spip_fetch_array(spip_query(
-	"SELECT * FROM spip_types_documents
-	WHERE extension='$ext' AND upload='oui'"))) {
-		spip_log("Extension $ext interdite a l'upload");
-		return;
+	// Documents distants : pas trop de verifications bloquantes, mais un test
+	// via une requete HEAD pour savoir si la ressource existe (non 404), si le
+	// content-type est connu, et si possible recuperer la taille, voire plus.
+	if ($mode == 'distant') {
+		if ($a = recuperer_infos_distantes($source)) {
+			# fichier local pour creer la vignette (!!),
+			# on retablira la valeur de l'url a la fin
+			$fichier = $a['fichier'];
+
+			$id_type = $a['id_type'];
+			$taille = $a['taille'];
+			$titre = $a['titre'];
+			$largeur = $a['largeur'];
+			$hauteur = $a['hauteur'];
+			$ext = $a['extension'];
+			$type_image = $a['type_image'];
+
+			$distant = 'oui';
+			$mode = 'document';
+		}
+		else {
+			spip_log("Echec du lien vers le document $source, abandon");
+			return;
+		}
 	}
-	$id_type = $row['id_type'];	# numero du type dans spip_types_documents :(
-	$type_inclus_image = ($row['inclus'] == 'image');
 
-	// Recopier le fichier a son emplacement definitif
-	$definitif = copier_document($ext, $nom_envoye, $source);
-	if (!$definitif) {
-		spip_log("Impossible de copier_document($ext, $nom_envoye, $source)");
-		return;
-	}
+	else {
+	
+		$distant = 'non';
 
-	// Quelques infos sur le fichier
-	if (!@file_exists($definitif)
-	OR !$taille = @filesize($definitif))
-		return;
+		// type de document inconnu ?
+		if (!ereg("\.([^.]+)$", $nom_envoye, $match)) {
+			spip_log("nom envoye incorrect ($nom_envoye)");
+			return;
+		}
 
-	// Si c'est une image, recuperer sa taille et son type (detecte aussi swf)
-	$size_image = @getimagesize($definitif);
-	$largeur = intval($size_image[0]);
-	$hauteur = intval($size_image[1]);
-	$type_image = decoder_type_image($size_image[2]);
+		// tester le type de document :
+		// - interdit a l'upload ?
+		// - quel numero dans spip_types_documents ?  =-(
+		// - est-ce "inclus" comme une image ?
+		$ext = corriger_extension(addslashes(strtolower($match[1])));
+
+		if (!$row = spip_fetch_array(spip_query(
+		"SELECT * FROM spip_types_documents
+		WHERE extension='$ext' AND upload='oui'"))) {
+			spip_log("Extension $ext interdite a l'upload");
+			return;
+		}
+		$id_type = $row['id_type'];	# numero du type dans spip_types_documents:(
+		$type_inclus_image = ($row['inclus'] == 'image');
+
+		// Recopier le fichier a son emplacement definitif
+		$fichier = copier_document($ext, $nom_envoye, $source);
+		if (!$fichier) {
+			spip_log("Impossible de copier_document($ext, $nom_envoye, $source)");
+			return;
+		}
 
-	// Si on veut uploader une vignette, il faut qu'elle ait ete bien lue
-	if ($mode == 'vignette' AND !($largeur * $hauteur)) {
-		@unlink($definitif);
-		return;
+		// Quelques infos sur le fichier
+		if (!@file_exists($fichier)
+		OR !$taille = @filesize($fichier))
+			return;
+
+		// Si c'est une image, recuperer sa taille et son type (detecte aussi swf)
+		$size_image = @getimagesize($fichier);
+		$largeur = intval($size_image[0]);
+		$hauteur = intval($size_image[1]);
+		$type_image = decoder_type_image($size_image[2]);
+
+		// Si on veut uploader une vignette, il faut qu'elle ait ete bien lue
+		if ($mode == 'vignette' AND !($largeur * $hauteur)) {
+			@unlink($fichier);
+			return;
+		}
 	}
 
 	// regler l'ancre du retour
@@ -288,7 +390,8 @@ function ajouter_un_document ($source, $nom_envoye, $type_lien, $id_lien, $mode,
 	if (!$id_document) {
 		// Inserer le nouveau doc et recuperer son id_
 		$id_document = spip_abstract_insert("spip_documents",
-		"(id_type, titre, date)", "($id_type, '', NOW())");
+		"(id_type, titre, date, distant)",
+		"($id_type, '".texte_script($titre)."', NOW(), '$distant')");
 
 		if ($id_lien
 		AND preg_match('/^[a-z0-9_]+$/i', $type_lien) # securite
@@ -304,14 +407,14 @@ function ajouter_un_document ($source, $nom_envoye, $type_lien, $id_lien, $mode,
 				$mode = 'vignette';
 			else
 				$mode = 'document';
-			$update = "mode='$mode', ";
+		$update = "mode='$mode', ";
 	}
 
 	// Mise a jour des donnees
 	spip_query("UPDATE spip_documents
 		SET $update
 		taille='$taille', largeur='$largeur', hauteur='$hauteur',
-		fichier='$definitif'
+		fichier='$fichier'
 		WHERE id_document=$id_document");
 
 	if ($id_document_lie) {
@@ -325,10 +428,15 @@ function ajouter_un_document ($source, $nom_envoye, $type_lien, $id_lien, $mode,
 		$documents_actifs[] = $id_document; 
 
 	// Creer la vignette des images
-	if ($mode == 'document'
-	AND ereg(",$ext,", ','.lire_meta('formats_graphiques').',')
+	if (ereg(",$ext,", ','.lire_meta('formats_graphiques').',')
+	AND $mode == 'document'
 	AND $type_image)
-		creer_fichier_vignette($definitif);
+		creer_fichier_vignette($fichier);
+
+	// Pour les fichiers distants remettre l'URL de base
+	if ($distant == 'oui')
+		spip_query("UPDATE spip_documents SET fichier='".addslashes($source)."'
+		WHERE id_document = $id_document");
 
 	return true;
 }
@@ -593,6 +701,48 @@ function creer_fichier_vignette($vignette, $test_cache_only=false) {
 	}
 }
 
+// Insertion d'une vignette dans la base
+function inserer_vignette_base($image, $vignette) {
+
+	$taille = @filesize($vignette);
+	
+	$size = @getimagesize($vignette);
+	$largeur = $size[0];
+	$hauteur = $size[1];
+	$type = $size[2];
+
+	if ($type == "2") $format = 1;			# spip_types_documents
+	else if ($type == "3") $format = 2;
+	else if ($type == "1") $format = 3;
+	else return;
+
+	$vignette = str_replace('../', '', $vignette);
+
+	spip_log("creation vignette($image) -> $vignette");
+
+	if ($t = spip_query("SELECT id_document FROM spip_documents
+	WHERE fichier='".addslashes($image)."'")) {
+		if ($row = spip_fetch_array($t)) {
+			$id_document = $row['id_document'];
+			$id_vignette = spip_abstract_insert("spip_documents", 
+				"(mode)",
+				"('vignette')");
+			spip_query("UPDATE spip_documents
+				SET id_vignette=$id_vignette WHERE id_document=$id_document");
+			spip_query("UPDATE spip_documents SET
+				id_type = '$format',
+				largeur = '$largeur',
+				hauteur = '$hauteur',
+				taille = '$taille',
+				fichier = '$vignette',
+				date = NOW()
+				WHERE id_document = $id_vignette");
+			spip_log("(document=$id_document, vignette=$id_vignette)");
+		}
+	}
+}
+
+
 // Effacer un doc (et sa vignette)
 function supprime_document_et_vignette($doc_supp) {
 
diff --git a/ecrire/inc_logos.php3 b/ecrire/inc_logos.php3
index 45c67c54a7..cfc78c1473 100644
--- a/ecrire/inc_logos.php3
+++ b/ecrire/inc_logos.php3
@@ -396,46 +396,6 @@ function creer_vignette($image, $maxWidth, $maxHeight, $format, $destdir, $destf
 }
 
 
-function inserer_vignette_base($image, $vignette) {
-
-	$taille = @filesize($vignette);
-	
-	$size = @getimagesize($vignette);
-	$largeur = $size[0];
-	$hauteur = $size[1];
-	$type = $size[2];
-
-	if ($type == "2") $format = 1;			# spip_types_documents
-	else if ($type == "3") $format = 2;
-	else if ($type == "1") $format = 3;
-	else return;
-
-	$vignette = str_replace('../', '', $vignette);
-
-	spip_log("creation vignette($image) -> $vignette");
-
-	if ($t = spip_query("SELECT id_document FROM spip_documents
-	WHERE fichier='".addslashes($image)."'")) {
-		if ($row = spip_fetch_array($t)) {
-			$id_document = $row['id_document'];
-			$id_vignette = spip_abstract_insert("spip_documents", 
-				"(mode)",
-				"('vignette')");
-			spip_query("UPDATE spip_documents
-				SET id_vignette=$id_vignette WHERE id_document=$id_document");
-			spip_query("UPDATE spip_documents SET
-				id_type = '$format',
-				largeur = '$largeur',
-				hauteur = '$hauteur',
-				taille = '$taille',
-				fichier = '$vignette',
-				date = NOW()
-				WHERE id_document = $id_vignette");
-			spip_log("(document=$id_document, vignette=$id_vignette)");
-		}
-	}
-}
-
 
 //
 // Retourner taille d'une image
diff --git a/ecrire/inc_sites.php3 b/ecrire/inc_sites.php3
index 5c58b3e235..fe06290d94 100644
--- a/ecrire/inc_sites.php3
+++ b/ecrire/inc_sites.php3
@@ -68,7 +68,10 @@ function no_password_proxy_url($http_proxy) {
 // Recupere une page sur le net
 // et au besoin l'encode dans le charset local
 //
-function recuperer_page($url, $munge_charset=false) {
+// options : get_headers si on veut recuperer les entetes
+// taille_max : arreter le contenu au-dela (0 = seulement les entetes)
+// Par defaut taille_max = 1Mo.
+function recuperer_page($url, $munge_charset=false, $get_headers=false, $taille_max = 1048576) {
 	$http_proxy = lire_meta("http_proxy");
 	if (!eregi("^http://", $http_proxy))
 		$http_proxy = '';
@@ -99,11 +102,16 @@ function recuperer_page($url, $munge_charset=false) {
 		} else
 			$f = @fsockopen($scheme_fsock.$host, $port);
 
+		if ($taille_max == 0)
+			$get = 'HEAD';
+		else
+			$get = 'GET';
+
 		if ($f) {
 			if ($http_proxy)
-				fputs($f, "GET $scheme://$host" . (($port != 80) ? ":$port" : "") . $path . ($query ? "?$query" : "") . " HTTP/1.0\r\n");
+				fputs($f, "$get $scheme://$host" . (($port != 80) ? ":$port" : "") . $path . ($query ? "?$query" : "") . " HTTP/1.0\r\n");
 			else
-				fputs($f, "GET $path" . ($query ? "?$query" : "") . " HTTP/1.0\r\n");
+				fputs($f, "$get $path" . ($query ? "?$query" : "") . " HTTP/1.0\r\n");
 
 			fputs($f, "Host: $host\r\n");
 			fputs($f, "User-Agent: SPIP-".$GLOBALS['spip_version_affichee']." (http://www.spip.net/)\r\n");
@@ -117,14 +125,18 @@ function recuperer_page($url, $munge_charset=false) {
 			if ($referer = lire_meta("adresse_site"))
 				fputs($f, "Referer: $referer/\r\n");
 
-			// Fin des entetes
+			// Fin des entetes envoyees par SPIP
 			fputs($f,"\r\n");
 
+			// Reponse du serveur distant
 			$s = trim(fgets($f, 16384));
 			if (ereg('^HTTP/[0-9]+\.[0-9]+ ([0-9]+)', $s, $r)) {
 				$status = $r[1];
 			}
 			else return;
+
+			// Entetes HTTP de la page
+			$headers = '';
 			while ($s = trim(fgets($f, 16384))) {
 				$headers .= $s."\n";
 				if (eregi('^Location: (.*)', $s, $r)) {
@@ -145,11 +157,12 @@ function recuperer_page($url, $munge_charset=false) {
 		}
 	}
 
+	// Contenu de la page
 	if (!$f) {
 		spip_log("ECHEC chargement $url$via_proxy");
 		$result = '';
 	} else {
-		while (!feof($f))
+		while (!feof($f) AND strlen($result)<$taille_max)
 			$result .= fread($f, 16384);
 		fclose($f);
 	}
@@ -160,7 +173,7 @@ function recuperer_page($url, $munge_charset=false) {
 		$result = transcoder_page ($result, $headers);
 	}
 
-	return $result;
+	return ($get_headers ? $headers."\n" : '').$result;
 }
 
 
@@ -253,6 +266,65 @@ function analyser_site($url) {
 	return $result;
 }
 
+// Inserer les references aux fichiers joints
+function traiter_les_enclosures_rss($enclosures,$id_syndic,$lelien) {
+
+	list($id_syndic_article) = spip_fetch_array(spip_query(
+	"SELECT id_syndic_article FROM spip_syndic_articles
+	WHERE id_syndic=$id_syndic AND url='$lelien'"));
+
+	// deja vu ?
+	if (spip_num_rows(spip_query("SELECT id_document FROM spip_documents_syndic
+	WHERE id_syndic_article=$id_syndic_article")) > 0)
+		return;
+
+	foreach ($enclosures as $enclosure) {
+		$enclosure = $enclosure[0];
+		// url et type sont obligatoires
+		if (preg_match(',[[:space:]]url=[\'"]?(https?://[^\'"]*),i',
+		$enclosure, $enc_regs_url)
+		AND preg_match(',[[:space:]]type=[\'"]?([^\'"]*),i',
+		$enclosure, $enc_regs_type)) {
+
+			$url = urldecode($enc_regs_url[1]);
+			$type = $enc_regs_type[1];
+
+			// Verifier que le content-type nous convient
+			list($id_type) = spip_fetch_array(spip_query("SELECT id_type
+			FROM spip_types_documents WHERE mime_type='$type'"));
+			if (!$id_type) {die ("pas de id_type pour $type");}#continue;
+
+			// length : optionnel (non bloquant)
+			if (preg_match(',[[:space:]]length=[\'"]?([^\'"]*),i',
+			$enclosure, $enc_regs_length)) {
+				$taille = intval($enc_regs_length[1]);
+			} else {
+				$taille = 0;
+			}
+
+			// Inserer l'enclosure dans la table spip_documents
+			if ($t = spip_fetch_array(spip_query("SELECT id_document FROM
+			spip_documents WHERE fichier='$url' AND distant='oui'")))
+				$id_document = $t['id_document'];
+			else {
+				spip_query("INSERT INTO spip_documents
+				(id_type, titre, fichier, date, distant, taille, mode)
+				VALUES ($id_type,'','$url',NOW(),'oui',$taille, 'document')");
+				$id_document = spip_insert_id();
+			}
+
+			// lier avec l'article syndique
+			spip_query("INSERT INTO spip_documents_syndic
+			(id_document, id_syndic, id_syndic_article)
+			VALUES ($id_document, $id_syndic, $id_syndic_article)");
+
+			$n++;
+		}
+	}
+
+	return $n; #nombre d'enclosures integrees
+}
+
 
 function syndic_a_jour($now_id_syndic, $statut = 'off') {
 	include_ecrire("inc_texte.php3");
@@ -370,6 +442,7 @@ function syndic_a_jour($now_id_syndic, $statut = 'off') {
 			foreach ($items as $item) {
 
 				$data = array();
+				unset($error);
 
 				// URL (obligatoire)
 				if (ereg($syndic_regexp['link1'],$item,$match)) {
@@ -380,16 +453,19 @@ function syndic_a_jour($now_id_syndic, $statut = 'off') {
 				// guid n'est un URL que si marque de <guid permalink="true">
 				else if (eregi("<guid.*>[[:space:]]*(https?:[^<]*)</guid>",$item,$match))
 					$data['url'] = addslashes(filtrer_entites($match[1]));
-				else continue;
+				else $error = 'url';
+				# note http://static.userland.com/gems/backend/gratefulDead.xml
+				# n'a que des enclosures, sans url ni titre... tant pis...
 
-				// Titre (obligatoire)
+				// Titre (semi-obligatoire)
 				if
 (preg_match(",<title>(.*?)</title>,ims",$item,$match))
 					$data['titre'] = $match[1];
 				else if (($syndic_version==0.3) AND (strlen($letitre)==0))
-					if (ereg('title[[:space:]]*=[[:space:]]*[\'"]([^"|^\']+)[\'"]',$link_match,$mat))
+					if (ereg('title[[:space:]]*=[[:space:]]*[\'"]([^"\']+)[\'"]',$link_match,$mat))
 						$data['titre']=$mat[1]; 
-				else continue;
+				if (!$data['titre'] = trim($data['titre']))
+					$data['titre'] = _T('ecrire:info_sans_titre');
 
 				// Date
 				$la_date = "";
@@ -440,6 +516,7 @@ function syndic_a_jour($now_id_syndic, $statut = 'off') {
 
 				// Creer le lien s'il est nouveau - cle=(id_syndic,url)
 				$le_lien = addslashes($data['url']);
+				if (!$error)
 				if (spip_num_rows(spip_query(
 					"SELECT * FROM spip_syndic_articles
 					WHERE url='".addslashes($data['url'])."'
@@ -453,6 +530,7 @@ function syndic_a_jour($now_id_syndic, $statut = 'off') {
 				}
 
 				// Mise a jour du contenu (titre,auteurs,description)
+				if (!$error)
 				spip_query ("UPDATE spip_syndic_articles SET
 				titre='".addslashes($data['titre'])."',
 				lesauteurs='".addslashes($data['lesauteurs'])."',
@@ -460,6 +538,7 @@ function syndic_a_jour($now_id_syndic, $statut = 'off') {
 				WHERE id_syndic='$now_id_syndic' AND url='$le_lien'");
 
 				// Honorer le <lastbuilddate> en forcant la date
+				if (!$error)
 				if (preg_match(',<(lastbuilddate|modified)>([^<>]+)</\1>,i',
 				$item, $regs)
 				AND $lastbuilddate = strtotime(trim($regs[2]))
@@ -469,8 +548,15 @@ function syndic_a_jour($now_id_syndic, $statut = 'off') {
 					SET date = FROM_UNIXTIME($lastbuilddate)
 					WHERE id_syndic='$now_id_syndic' AND url='$le_lien'");
 				}
-				
+
+				// Attraper les URLs des pieces jointes <enclosure>
+				if (!$error)
+				if (preg_match_all(',<enclosure[[:space:]][^<>]+>,i', $item,
+				$enclosures, PREG_SET_ORDER)) {
+					traiter_les_enclosures_rss($enclosures,$now_id_syndic,$le_lien);
+				}
 			}
+
 			spip_query("UPDATE spip_syndic SET syndication='oui' WHERE id_syndic='$now_id_syndic'");
 		}
 		else $erreur = _T('avis_echec_syndication_01');
@@ -639,7 +725,7 @@ function afficher_syndic_articles($titre_table, $requete, $afficher_site = false
 	global $flag_editable;
 
 	static $n_liste_sites;
-	global $spip_lang_rtl;
+	global $spip_lang_rtl, $spip_lang_right;
 
 	$adresse_page = substr($REQUEST_URI, strpos($REQUEST_URI, "/ecrire")+8, strlen($REQUEST_URI));
 	$adresse_page = ereg_replace("\&?debut\_liste\_sites\[$n_liste_sites\]\=[0-9]+","",$adresse_page);
@@ -680,7 +766,7 @@ function afficher_syndic_articles($titre_table, $requete, $afficher_site = false
 			$titre=typo($row["titre"]);
 			$url=$row["url"];
 			$date=$row["date"];
-			$lesauteurs=propre($row["lesauteurs"]);
+			$lesauteurs=typo($row["lesauteurs"]);
 			$statut=$row["statut"];
 			$descriptif=propre($row["descriptif"]);
 
@@ -708,6 +794,17 @@ function afficher_syndic_articles($titre_table, $requete, $afficher_site = false
 
 			$s = "<a href='$url'>$titre</a>";
 			if (strlen($lesauteurs) > 0) $s .= " ($lesauteurs)";
+
+			// S'il y a des fichiers joints (enclosures), on les affiche ici
+			if (spip_num_rows($q = spip_query("SELECT docs.* FROM spip_documents AS docs, spip_documents_syndic AS lien WHERE lien.id_syndic_article = $id_syndic_article AND lien.id_document = docs.id_document"))) {
+				include_ecrire('inc_documents.php3');
+				while ($t = spip_fetch_array($q)) {
+					$s .= '&nbsp;<a href="' . $t['fichier'] . '">'
+					. http_img_pack('attachment.gif', 'height="15" width="15"
+					border="0" title="'.entites_html($t['fichier']).'"').'</a>';
+				}
+			}
+
 			if (strlen($descriptif) > 0) $s .= "<div class='arial1'>$descriptif</div>";
 			$vals[] = $s;
 
diff --git a/ecrire/inc_texte.php3 b/ecrire/inc_texte.php3
index 62c90f9bea..aaec73955e 100644
--- a/ecrire/inc_texte.php3
+++ b/ecrire/inc_texte.php3
@@ -503,7 +503,13 @@ function typo_generale($letexte) {
 	$letexte = strtr($letexte, $illegal, $protege);
 
 	// Appeler la fonction de post-traitement
-	return spip_apres_typo ($letexte);
+	$letexte = spip_apres_typo ($letexte);
+
+	# un message pour abs_url - on est passe en mode texte
+	$GLOBALS['mode_abs_url'] = 'texte';
+
+	// et retour
+	return $letexte;
 }
 
 function typo($letexte) {
diff --git a/ecrire/inc_urls.php3 b/ecrire/inc_urls.php3
index cb1f458f6c..d3df38caf9 100644
--- a/ecrire/inc_urls.php3
+++ b/ecrire/inc_urls.php3
@@ -62,11 +62,17 @@ function generer_url_auteur($id_auteur) {
 function generer_url_document($id_document) {
 	if (intval($id_document) <= 0)
 		return '';
-	if ((lire_meta("creer_htaccess")) == 'oui')
-		return "../spip_acces_doc.php3?id_document=$id_document";
-	if ($row = @spip_fetch_array(spip_query("SELECT fichier FROM spip_documents WHERE id_document = $id_document")))
-		return '../' . ($row['fichier']);
-	return '';
+	if ($row = @spip_fetch_array(spip_query("SELECT fichier,distant
+	FROM spip_documents WHERE id_document = $id_document"))) {
+		if ($row['distant'] == 'oui') {
+			$url = $row['fichier'];
+		} else {
+			$url = '../' . ($row['fichier']);
+			if ((lire_meta("creer_htaccess")) == 'oui')
+				$url = "../spip_acces_doc.php3?id_document=$id_document";
+		}
+	}
+	return $url;
 }
 
 ?>
diff --git a/inc-boucles.php3 b/inc-boucles.php3
index bb6f59beee..ff8d231102 100644
--- a/inc-boucles.php3
+++ b/inc-boucles.php3
@@ -135,8 +135,10 @@ function boucle_DOCUMENTS_dist($id_boucle, &$boucles) {
 	$boucle->from[] =  "spip_documents AS $id_table";
 	$boucle->from[] =  "spip_types_documents AS types_documents";
 	$boucle->where[] = "$id_table.id_type=types_documents.id_type";
-	$boucle->where[] = "$id_table.taille > 0";
-	return calculer_boucle($id_boucle, $boucles); 
+	// on ne veut pas des fichiers de taille nulle,
+	// sauf s'ils sont distants (taille inconnue)
+	$boucle->where[] = "($id_table.taille > 0 OR $id_table.distant='oui')";
+	return calculer_boucle($id_boucle, $boucles);
 }
 
 
diff --git a/inc-compilo-api.php3 b/inc-compilo-api.php3
index a1d598aa3d..0d9a807694 100644
--- a/inc-compilo-api.php3
+++ b/inc-compilo-api.php3
@@ -148,6 +148,8 @@ $exceptions_des_tables['documents']['type_document']=array('types_documents'
 , 'titre');
 $exceptions_des_tables['documents']['extension_document']=array('types_docum
 ents', 'extension');
+$exceptions_des_tables['documents']['mime_type']=array('types_documents'
+, 'mime_type');
 
 # ne sert plus ? verifier balise_URL_ARTICLE
 $exceptions_des_tables['syndic_articles']['url_article']='url';
@@ -187,6 +189,8 @@ $tables_relations['breves']['id_document']='documents_breves';
 $tables_relations['documents']['id_article']='documents_articles';
 $tables_relations['documents']['id_rubrique']='documents_rubriques';
 $tables_relations['documents']['id_breve']='documents_breves';
+$tables_relations['documents']['id_syndic']='documents_syndic';
+$tables_relations['documents']['id_syndic_article']='documents_syndic';
 
 $tables_relations['forums']['id_mot']='mots_forum';
 
@@ -202,5 +206,7 @@ $tables_relations['rubriques']['id_mot']='mots_rubriques';
 $tables_relations['rubriques']['id_document']='documents_rubriques';
 
 $tables_relations['syndication']['id_mot']='mots_syndic';
+$tables_relations['syndication']['id_document']='documents_syndic';
+$tables_relations['syndic_articles']['id_document']='documents_syndic';
 
 ?>
diff --git a/inc-criteres.php3 b/inc-criteres.php3
index b5c8b57edb..1bf93ba81d 100644
--- a/inc-criteres.php3
+++ b/inc-criteres.php3
@@ -401,8 +401,9 @@ function calculer_critere_DEFAUT($idb, &$boucles, $param, $not) {
 
 			}
 
-			if ($s = calculer_critere_externe($boucle, $id_field,$col, $type))
+			if ($s = calculer_critere_externe($boucle, $id_field,$col, $type)) {
 				$col_table = $s;
+			}
 
 			// Cas particulier pour les raccourcis 'type_mot' et 'titre_mot'
 			else if ($type != 'mots'
@@ -442,7 +443,7 @@ function calculer_critere_DEFAUT($idb, &$boucles, $param, $not) {
 			// Cas particulier : lier les articles syndiques
 			// au site correspondant
 			else if ($type == 'syndic_articles' AND
-			!ereg("^(id_syndic_article|titre|url|date|descriptif|lesauteurs)$",$col))
+			!ereg("^(id_syndic_article|titre|url|date|descriptif|lesauteurs|id_document)$",$col))
 				$col_table = 'syndic';
 
 			// Cas particulier : id_enfant => utiliser la colonne id_objet
@@ -562,12 +563,11 @@ function calculer_critere_externe(&$boucle, $id_field, $col, $type)
 	if ($col_table =  $tables_relations[$type][$col]) {
 		$externe = "$id_field=$col_table." . $boucle->primary;
 		if (!$boucle->where || (!in_array($externe, $boucle->where))) {
-
 			$boucle->lien = true;
 			$boucle->from[] = "spip_$col_table AS $col_table";
 			$boucle->where[] = $externe;
 			$boucle->group = $id_field;
-		// postgres exige que le champ pour GROUP soit dans le SELECT
+			// postgres exige que le champ pour GROUP soit dans le SELECT
 			$boucle->select[] = $id_field;
 		}
 	}
diff --git a/spip_image.php3 b/spip_image.php3
index f07060ee92..a978d6605f 100644
--- a/spip_image.php3
+++ b/spip_image.php3
@@ -98,6 +98,15 @@ else if ($ajout_doc == 'oui') {
 				'tmp_name' => $upload)
 			);
 	}
+	
+	// Cas d'un document distant reference sur internet
+	else if (preg_match(',^https?://....+,i', $_POST['image_url'])) {
+		$_FILES = array(
+			array('name' => basename($_POST['image_url']),
+			'tmp_name' => $_POST['image_url'])
+		);
+		$mode = 'distant';
+	}
 
 	//
 	// Upload d'un ZIP
@@ -194,13 +203,16 @@ else if ($ajout_doc == 'oui') {
 		// afficher l'erreur 'fichier trop gros' ou autre
 		check_upload_error($file['error']);
 
-		spip_log ("ajout du document ".$file['name'].", $mode ($type $id_article)");
+		spip_log ("ajout du document ".$file['name'].", $mode ($type $id_article $id_document)");
 		ajouter_un_document (
 			$file['tmp_name'],	# le fichier sur le serveur (/var/tmp/xyz34)
 			$file['name'],		# son nom chez le client (portequoi.pdf)
 			$type,				# lie a un article, une breve ou une rubrique ?
 			$id_article,		# identifiant de l'article (ou rubrique) lie
-			$mode,				# 'vignette' => vignette personnalisee
+			$mode,				# 'vignette' => image en mode image
+								# ou vignette personnalisee liee a un document
+								# 'document' => doc ou image en mode document
+								# 'distant' => lien internet
 			$id_document,		# pour une vignette, l'id_document de maman
 			$documents_actifs	# tableau des id_document "actifs" (par ref)
 		);
-- 
GitLab