9fc5d4804f281e93aaa85362630b2f8e146ed5e1
[ptitvelo/web/www.git] / www / ecrire / inc / lien.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2014 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
8 * *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
12
13 if (!defined('_ECRIRE_INC_VERSION')) return;
14
15 include_spip('base/abstract_sql');
16
17 //
18 // Production de la balise A+href a partir des raccourcis [xxx->url] etc.
19 // Note : complique car c'est ici qu'on applique typo(),
20 // et en plus on veut pouvoir les passer en pipeline
21 //
22
23 function inc_lien_dist($lien, $texte='', $class='', $title='', $hlang='', $rel='', $connect='', $env=array()) {
24
25 return $lien;
26 }
27
28 // Regexp des raccourcis, aussi utilisee pour la fusion de sauvegarde Spip
29 // Laisser passer des paires de crochets pour la balise multi
30 // mais refuser plus d'imbrications ou de mauvaises imbrications
31 // sinon les crochets ne peuvent plus servir qu'a ce type de raccourci
32 define('_RACCOURCI_LIEN', "/\[([^][]*?([[]\w*[]][^][]*)*)->(>?)([^]]*)\]/msS");
33
34 // http://doc.spip.org/@expanser_liens
35 function expanser_liens($t, $connect='', $env=array()){
36
37 $t = pipeline('pre_liens', $t);
38
39 // on passe a traiter_modeles la liste des liens reperes pour lui permettre
40 // de remettre le texte d'origine dans les parametres du modele
41 $t = traiter_modeles($t, false, false, $connect);
42 return $t;
43 }
44
45 // Meme analyse mais pour eliminer les liens
46 // et ne laisser que leur titre, a expliciter si ce n'est fait
47 // http://doc.spip.org/@nettoyer_raccourcis_typo
48 function nettoyer_raccourcis_typo($texte, $connect='')
49 {
50
51
52 return $texte;
53 }
54
55
56
57 // Repere dans la partie texte d'un raccourci [texte->...]
58 // la langue et la bulle eventuelles
59 // http://doc.spip.org/@traiter_raccourci_lien_atts
60 function traiter_raccourci_lien_atts($texte) {
61 $bulle='';
62 $hlang='';
63 return array(trim($texte), $bulle, $hlang);
64 }
65
66
67 define('_RACCOURCI_CHAPO', '/^(\W*)(\W*)(\w*\d+([?#].*)?)$/');
68 /**
69 * Fonction pour les champs virtuels de redirection qui peut etre:
70 * 3. une URL std
71 *
72 * renvoie l'url reelle de redirection si le $url=true,
73 * l'url brute contenue dans le chapo sinon
74 *
75 * http://doc.spip.org/@chapo_redirige
76 *
77 * @param string $virtuel
78 * @param bool $url
79 * @return string
80 */
81 function virtuel_redirige($virtuel, $url=false){
82 return $virtuel;
83 }
84
85
86 // Cherche un lien du type [->raccourci 123]
87 // associe a une fonction generer_url_raccourci() definie explicitement
88 // ou implicitement par le jeu de type_urls courant.
89 //
90 // Valeur retournee selon le parametre $pour:
91 // 'tout' : tableau d'index url,class,titre,lang (vise <a href="U" class='C' hreflang='L'>T</a>)
92 // 'titre': seulement T ci-dessus (i.e. le TITRE ci-dessus ou dans table SQL)
93 // 'url': seulement U (i.e. generer_url_RACCOURCI)
94
95 // http://doc.spip.org/@calculer_url
96 function calculer_url ($ref, $texte='', $pour='url', $connect='', $echappe_typo = true) {
97 $r = traiter_lien_implicite($ref, $texte, $pour, $connect, $echappe_typo);
98 return $r ? $r : traiter_lien_explicite($ref, $texte, $pour, $connect, $echappe_typo);
99 }
100
101 define('_EXTRAIRE_LIEN', ',^\s*(?:' . _PROTOCOLES_STD . '):?/?/?\s*$,iS');
102
103 // http://doc.spip.org/@traiter_lien_explicite
104 function traiter_lien_explicite ($ref, $texte='', $pour='url', $connect='', $echappe_typo = true)
105 {
106 if (preg_match(_EXTRAIRE_LIEN, $ref))
107 return ($pour != 'tout') ? '' : array('','','','');
108
109 $lien = entites_html(trim($ref));
110
111 // Liens explicites
112 if (!$texte) {
113 $texte = str_replace('"', '', $lien);
114 // evite l'affichage de trops longues urls.
115 $lien_court = charger_fonction('lien_court', 'inc');
116 $texte = $lien_court($texte);
117 if ($echappe_typo){
118 $texte = "<html>".quote_amp($texte)."</html>";
119 }
120 }
121
122 // petites corrections d'URL
123 if (preg_match('/^www\.[^@]+$/S',$lien))
124 $lien = "http://".$lien;
125 else if (strpos($lien, "@") && email_valide($lien)) {
126 if (!$texte) $texte = $lien;
127 $lien = "mailto:".$lien;
128 }
129
130 if ($pour == 'url') return $lien;
131
132 if ($pour == 'titre') return $texte;
133
134 return array('url' => $lien, 'titre' => $texte);
135 }
136
137 function liens_implicite_glose_dist($texte,$id,$type,$args,$ancre,$connect=''){
138 if (function_exists($f = 'glossaire_' . $ancre))
139 $url = $f($texte, $id);
140 else
141 $url = glossaire_std($texte);
142 return $url;
143 }
144
145 // http://doc.spip.org/@traiter_lien_implicite
146 function traiter_lien_implicite ($ref, $texte='', $pour='url', $connect='')
147 {
148 if (!($match = typer_raccourci($ref))) return false;
149 @list($type,,$id,,$args,,$ancre) = $match;
150 # attention dans le cas des sites le lien doit pointer non pas sur
151 # la page locale du site, mais directement sur le site lui-meme
152 if ($f = charger_fonction("implicite_$type","liens",true))
153 $url = $f($texte,$id,$type,$args,$ancre,$connect);
154 if (!$url)
155 $url = generer_url_entite($id,$type,$args,$ancre,$connect ? $connect : NULL);
156 if (!$url) return false;
157 if (is_array($url)) {
158 @list($type,$id) = $url;
159 $url = generer_url_entite($id,$type,$args,$ancre,$connect ? $connect : NULL);
160 }
161 if ($pour === 'url') return $url;
162 $r = traiter_raccourci_titre($id, $type, $connect);
163 if ($r) $r['class'] = ($type == 'site')?'spip_out':'spip_in';
164 if ($texte = trim($texte)) $r['titre'] = $texte;
165 if (!@$r['titre']) $r['titre'] = _T($type) . " $id";
166 if ($pour=='titre') return $r['titre'];
167 $r['url'] = $url;
168
169 // dans le cas d'un lien vers un doc, ajouter le type='mime/type'
170 if ($type == 'document'
171 AND $mime = sql_getfetsel('mime_type', 'spip_types_documents',
172 "extension IN (".sql_get_select("extension","spip_documents","id_document=".sql_quote($id)).")",
173 '','','','',$connect)
174 )
175 $r['mime'] = $mime;
176
177 return $r;
178 }
179
180 // analyse des raccourcis issus de [TITRE->RACCOURCInnn] et connexes
181
182 define('_RACCOURCI_URL', '/^\s*(\w*?)\s*(\d+)(\?(.*?))?(#([^\s]*))?\s*$/S');
183
184 // http://doc.spip.org/@typer_raccourci
185 function typer_raccourci ($lien) {
186 if (!preg_match(_RACCOURCI_URL, $lien, $match)) return array();
187 $f = $match[1];
188 // valeur par defaut et alias historiques
189 if (!$f) $f = 'article';
190 else if ($f == 'art') $f = 'article';
191 else if ($f == 'br') $f = 'breve';
192 else if ($f == 'rub') $f = 'rubrique';
193 else if ($f == 'aut') $f = 'auteur';
194 else if ($f == 'doc' OR $f == 'im' OR $f == 'img' OR $f == 'image' OR $f == 'emb')
195 $f = 'document';
196 else if (preg_match('/^br..?ve$/S', $f)) $f = 'breve'; # accents :(
197 $match[0] = $f;
198 return $match;
199 }
200
201 // Retourne le champ textuel associe a une cle primaire, et sa langue
202 function traiter_raccourci_titre($id, $type, $connect=NULL)
203 {
204 $trouver_table = charger_fonction('trouver_table', 'base');
205 $desc = $trouver_table(table_objet($type));
206 if (!($desc AND $s = $desc['titre'])) return array();
207 $_id = $desc['key']['PRIMARY KEY'];
208 $r = sql_fetsel($s, $desc['table'], "$_id=$id", '','','','',$connect);
209 if (!$r) return array();
210 $r['titre'] = supprimer_numero($r['titre']);
211 if (!$r['titre']) $r['titre'] = $r['surnom'];
212 if (!isset($r['lang'])) $r['lang'] = '';
213 return $r;
214 }
215
216 // traite les modeles (dans la fonction typo), en remplacant
217 // le raccourci <modeleN|parametres> par la page calculee a
218 // partir du squelette modeles/modele.html
219 // Le nom du modele doit faire au moins trois caracteres (evite <h2>)
220 // Si $doublons==true, on repere les documents sans calculer les modeles
221 // mais on renvoie les params (pour l'indexation par le moteur de recherche)
222 // http://doc.spip.org/@traiter_modeles
223
224 define('_RACCOURCI_MODELE',
225 '(<([a-z_-]{3,})' # <modele
226 .'\s*([0-9]*)\s*' # id
227 .'([|](?:<[^<>]*>|[^>])*?)?' # |arguments (y compris des tags <...>)
228 .'\s*/?'.'>)' # fin du modele >
229 .'\s*(<\/a>)?' # eventuel </a>
230 );
231
232 define('_RACCOURCI_MODELE_DEBUT', '@^' . _RACCOURCI_MODELE .'@isS');
233
234 // http://doc.spip.org/@traiter_modeles
235 function traiter_modeles($texte, $doublons=false, $echap='', $connect='', $liens = null, $env = array()) {
236 // preserver la compatibilite : true = recherche des documents
237 if ($doublons===true)
238 $doublons = array('documents'=>array('doc','emb','img'));
239 // detecter les modeles (rapide)
240 if (strpos($texte,"<")!==false AND
241 preg_match_all('/<[a-z_-]{3,}\s*[0-9|]+/iS', $texte, $matches, PREG_SET_ORDER)) {
242 include_spip('public/assembler');
243 $wrap_embed_html = charger_fonction("wrap_embed_html","inc",true);
244 foreach ($matches as $match) {
245 // Recuperer l'appel complet (y compris un eventuel lien)
246
247 $a = strpos($texte,$match[0]);
248 preg_match(_RACCOURCI_MODELE_DEBUT,
249 substr($texte, $a), $regs);
250 $regs[]=""; // s'assurer qu'il y a toujours un 5e arg, eventuellement vide
251 list(,$mod, $type, $id, $params, $fin) = $regs;
252 if ($fin AND
253 preg_match('/<a\s[^<>]*>\s*$/i',
254 substr($texte, 0, $a), $r)) {
255 $lien = array(
256 'href' => extraire_attribut($r[0],'href'),
257 'class' => extraire_attribut($r[0],'class'),
258 'mime' => extraire_attribut($r[0],'type')
259 );
260 $n = strlen($r[0]);
261 $a -= $n;
262 $cherche = $n + strlen($regs[0]);
263 } else {
264 $lien = false;
265 $cherche = strlen($mod);
266 }
267
268 // calculer le modele
269 # hack indexation
270 if ($doublons)
271 $texte .= preg_replace(',[|][^|=]*,s',' ',$params);
272 # version normale
273 else {
274 // si un tableau de liens a ete passe, reinjecter le contenu d'origine
275 // dans les parametres, plutot que les liens echappes
276 if (!is_null($liens))
277 $params = str_replace($liens[0], $liens[1], $params);
278 $modele = inclure_modele($type, $id, $params, $lien, $connect, $env);
279 // en cas d'echec,
280 // si l'objet demande a une url,
281 // creer un petit encadre vers elle
282 if ($modele === false) {
283 if (!$lien)
284 $lien = traiter_lien_implicite("$type$id", '', 'tout', $connect);
285 if ($lien)
286 $modele = '<a href="'
287 .$lien['url']
288 .'" class="spip_modele'
289 . '">'
290 .sinon($lien['titre'], _T('ecrire:info_sans_titre'))
291 ."</a>";
292 else {
293 $modele = "";
294 if (test_espace_prive()) {
295 $modele = entites_html(substr($texte,$a,$cherche));
296 if (!is_null($liens))
297 $modele = "<pre>".str_replace($liens[0], $liens[1], $modele)."</pre>";
298 }
299 }
300 }
301 // le remplacer dans le texte
302 if ($modele !== false) {
303 $modele = protege_js_modeles($modele);
304 if ($wrap_embed_html){
305 $modele = $wrap_embed_html($mod,$modele);
306 }
307 $rempl = code_echappement($modele, $echap);
308 $texte = substr($texte, 0, $a)
309 . $rempl
310 . substr($texte, $a+$cherche);
311 }
312 }
313
314 // hack pour tout l'espace prive
315 if (((!_DIR_RESTREINT) OR ($doublons)) AND ($id)){
316 foreach($doublons?$doublons:array('documents'=>array('doc','emb','img')) as $quoi=>$modeles)
317 if (in_array($type,$modeles))
318 $GLOBALS["doublons_{$quoi}_inclus"][] = $id;
319 }
320 }
321 }
322
323 return $texte;
324 }
325
326 //
327 // Raccourcis ancre [#ancre<-]
328 //
329 // http://doc.spip.org/@traiter_raccourci_ancre
330 function traiter_raccourci_ancre($letexte)
331 {
332 return $letexte;
333 }
334
335 // http://doc.spip.org/@traiter_raccourci_glossaire
336 function traiter_raccourci_glossaire($texte)
337 {
338 return $texte;
339 }
340
341 // http://doc.spip.org/@glossaire_std
342 function glossaire_std($terme)
343 {
344 return $terme;
345 }
346
347 ?>