1 | <?php |
---|
2 | |
---|
3 | /***************************************************************************\ |
---|
4 | * SPIP, Systeme de publication pour l'internet * |
---|
5 | * * |
---|
6 | * Copyright (c) 2001-2011 * |
---|
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='') { |
---|
24 | static $u=null; |
---|
25 | if (!$u) $u=url_de_base(); |
---|
26 | $typo = false; |
---|
27 | |
---|
28 | // Si une langue est demandee sur un raccourci d'article, chercher |
---|
29 | // la traduction ; |
---|
30 | // - [{en}->art2] => traduction anglaise de l'article 2, sinon art 2 |
---|
31 | // - [{}->art2] => traduction en langue courante de l'art 2, sinon art 2 |
---|
32 | // s'applique a tout objet traduit |
---|
33 | if ($hlang |
---|
34 | AND $match = typer_raccourci($lien)) { |
---|
35 | @list($type,,$id,,$args,,$ancre) = $match; |
---|
36 | $table_objet_sql = table_objet_sql($type); |
---|
37 | $id_table_objet = id_table_objet($type); |
---|
38 | if ($row=sql_fetsel('*', $table_objet_sql, "$id_table_objet=".intval($id)) |
---|
39 | AND isset($row['id_trad']) |
---|
40 | AND isset($row['lang']) |
---|
41 | AND $id_dest = sql_getfetsel($id_table_objet, $table_objet_sql,"id_trad=".intval($row['id_trad'])." AND lang=" . sql_quote($hlang)) |
---|
42 | AND objet_test_si_publie($type,$id_dest) |
---|
43 | ) |
---|
44 | $lien = "$type$id_dest"; |
---|
45 | else |
---|
46 | $hlang = ''; |
---|
47 | } |
---|
48 | |
---|
49 | $mode = ($texte AND $class) ? 'url' : 'tout'; |
---|
50 | $lien = calculer_url($lien, $texte, $mode, $connect); |
---|
51 | if ($mode === 'tout') { |
---|
52 | $texte = $lien['titre']; |
---|
53 | if (!$class AND isset($lien['class'])) $class = $lien['class']; |
---|
54 | $lang = isset($lien['lang']) ?$lien['lang'] : ''; |
---|
55 | $mime = isset($lien['mime']) ? " type='".$lien['mime']."'" : ""; |
---|
56 | $lien = $lien['url']; |
---|
57 | } |
---|
58 | |
---|
59 | $lien = trim($lien); |
---|
60 | if (strncmp($lien,"#",1) == 0) # ancres pures (internes a la page) |
---|
61 | $class = 'spip_ancre'; |
---|
62 | elseif (strncasecmp($lien,'mailto:',7)==0) # pseudo URL de mail |
---|
63 | $class = "spip_mail"; |
---|
64 | elseif (strncmp($texte,'<html>',6)==0) # cf traiter_lien_explicite |
---|
65 | $class = "spip_url spip_out"; |
---|
66 | elseif (!$class) $class = "spip_out"; # si pas spip_in|spip_glossaire |
---|
67 | |
---|
68 | // Si l'objet n'est pas de la langue courante, on ajoute hreflang |
---|
69 | if (!$hlang AND $lang!==$GLOBALS['spip_lang']) |
---|
70 | $hlang = $lang; |
---|
71 | |
---|
72 | $lang = ($hlang ? " hreflang='$hlang'" : ''); |
---|
73 | |
---|
74 | if ($title) $title = ' title="'.attribut_html($title).'"'; |
---|
75 | |
---|
76 | // rel=external pour les liens externes |
---|
77 | if ((strncmp($lien,'http://',7)==0 OR strncmp($lien,'https://',8)==0) |
---|
78 | AND strncmp("$lien/", $u ,strlen($u))!=0) |
---|
79 | $rel = trim("$rel external"); |
---|
80 | if ($rel) $rel = " rel='$rel'"; |
---|
81 | |
---|
82 | if (traiter_modeles($texte, false, $echapper ? 'TYPO' : '', $connect)==$texte){ |
---|
83 | $texte = typo($texte, true, $connect); |
---|
84 | $lien = "<a href=\"".str_replace('"', '"', $lien)."\" class='$class'$lang$title$rel$mime>$texte</a>"; |
---|
85 | return $lien; |
---|
86 | } |
---|
87 | # ceci s'execute heureusement avant les tableaux et leur "|". |
---|
88 | # Attention, le texte initial est deja echappe mais pas forcement |
---|
89 | # celui retourne par calculer_url. |
---|
90 | # Penser au cas [<imgXX|right>->URL], qui exige typo('<a>...</a>') |
---|
91 | $lien = "<a href=\"".str_replace('"', '"', $lien)."\" class='$class'$lang$title$rel$mime>$texte</a>"; |
---|
92 | return typo($lien, true, $connect); |
---|
93 | } |
---|
94 | |
---|
95 | // Regexp des raccourcis, aussi utilisee pour la fusion de sauvegarde Spip |
---|
96 | // Laisser passer des paires de crochets pour la balise multi |
---|
97 | // mais refuser plus d'imbrications ou de mauvaises imbrications |
---|
98 | // sinon les crochets ne peuvent plus servir qu'a ce type de raccourci |
---|
99 | define('_RACCOURCI_LIEN', "/\[([^][]*?([[]\w*[]][^][]*)*)->(>?)([^]]*)\]/msS"); |
---|
100 | |
---|
101 | // http://doc.spip.org/@expanser_liens |
---|
102 | function expanser_liens($t, $connect='') |
---|
103 | { |
---|
104 | |
---|
105 | $t = pipeline('pre_liens', $t); |
---|
106 | |
---|
107 | expanser_un_lien($connect,'init'); |
---|
108 | |
---|
109 | if (strpos($t, '->') !== false) |
---|
110 | $t = preg_replace_callback (_RACCOURCI_LIEN, 'expanser_un_lien',$t); |
---|
111 | |
---|
112 | // on passe a traiter_modeles la liste des liens reperes pour lui permettre |
---|
113 | // de remettre le texte d'origine dans les parametres du modele |
---|
114 | $t = traiter_modeles($t, false, false, $connect, expanser_un_lien('','sources')); |
---|
115 | |
---|
116 | $t = corriger_typo($t); |
---|
117 | |
---|
118 | $t = expanser_un_lien($t,'reinsert'); |
---|
119 | |
---|
120 | return $t; |
---|
121 | } |
---|
122 | |
---|
123 | |
---|
124 | function expanser_un_lien($reg, $quoi='echappe'){ |
---|
125 | static $pile = array(); |
---|
126 | static $inserts; |
---|
127 | static $sources; |
---|
128 | static $regs; |
---|
129 | static $k = 0; |
---|
130 | static $lien; |
---|
131 | static $connect=''; |
---|
132 | |
---|
133 | switch ($quoi){ |
---|
134 | case 'init': |
---|
135 | if (!$lien) $lien = charger_fonction('lien', 'inc'); |
---|
136 | array_push($pile,array($inserts,$sources,$regs,$connect,$k)); |
---|
137 | $inserts = $sources = $regs = array(); |
---|
138 | $connect = $reg; // stocker le $connect pour les appels a inc_lien_dist |
---|
139 | $k=0; |
---|
140 | return; |
---|
141 | break; |
---|
142 | case 'echappe': |
---|
143 | $inserts[$k] = '@@SPIP_ECHAPPE_LIEN_' . $k . '@@'; |
---|
144 | $sources[$k] = $reg[0]; |
---|
145 | |
---|
146 | #$titre=$reg[1]; |
---|
147 | list($titre, $bulle, $hlang) = traiter_raccourci_lien_atts($reg[1]); |
---|
148 | $r = end($reg); |
---|
149 | // la mise en lien automatique est passee par la a tort ! |
---|
150 | // corrigeons pour eviter d'avoir un <a...> dans un href... |
---|
151 | if (strncmp($r,'<a',2)==0){ |
---|
152 | $href = extraire_attribut($r, 'href'); |
---|
153 | // remplacons dans la source qui peut etre reinjectee dans les arguments |
---|
154 | // d'un modele |
---|
155 | $sources[$k] = str_replace($r,$href,$sources[$k]); |
---|
156 | // et prenons le href comme la vraie url a linker |
---|
157 | $r = $href; |
---|
158 | } |
---|
159 | $regs[$k] = $lien($r, $titre, '', $bulle, $hlang, '', $connect); |
---|
160 | return $inserts[$k++]; |
---|
161 | break; |
---|
162 | case 'reinsert': |
---|
163 | if (count($inserts)) |
---|
164 | $reg = str_replace($inserts, $regs, $reg); |
---|
165 | list($inserts,$sources,$regs,$connect,$k) = array_pop($pile); |
---|
166 | return $reg; |
---|
167 | break; |
---|
168 | case 'sources': |
---|
169 | return array($inserts, $sources); |
---|
170 | break; |
---|
171 | } |
---|
172 | } |
---|
173 | |
---|
174 | // Meme analyse mais pour eliminer les liens |
---|
175 | // et ne laisser que leur titre, a expliciter si ce n'est fait |
---|
176 | // http://doc.spip.org/@nettoyer_raccourcis_typo |
---|
177 | function nettoyer_raccourcis_typo($texte, $connect='') |
---|
178 | { |
---|
179 | $texte = pipeline('nettoyer_raccourcis_typo',$texte); |
---|
180 | |
---|
181 | if (preg_match_all(_RACCOURCI_LIEN, $texte, $regs, PREG_SET_ORDER)) |
---|
182 | foreach ($regs as $reg) { |
---|
183 | list ($titre,,)= traiter_raccourci_lien_atts($reg[1]); |
---|
184 | if (!$titre) { |
---|
185 | $match = typer_raccourci($reg[count($reg)-1]); |
---|
186 | @list($type,,$id,,,,) = $match; |
---|
187 | if ($type) { |
---|
188 | $url = generer_url_entite($id,$type,'','',true); |
---|
189 | if (is_array($url)) list($type, $id) = $url; |
---|
190 | $titre = traiter_raccourci_titre($id, $type, $connect); |
---|
191 | } |
---|
192 | $titre = $titre ? $titre['titre'] : $match[0]; |
---|
193 | } |
---|
194 | $titre = corriger_typo(supprimer_tags($titre)); |
---|
195 | $texte = str_replace($reg[0], $titre, $texte); |
---|
196 | } |
---|
197 | |
---|
198 | // supprimer les notes |
---|
199 | $texte = preg_replace(",[[][[]([^]]|[]][^]])*[]][]],UimsS","",$texte); |
---|
200 | |
---|
201 | // supprimer les codes typos |
---|
202 | $texte = str_replace(array('}','{'), '', $texte); |
---|
203 | |
---|
204 | // supprimer les tableaux |
---|
205 | $texte = preg_replace(",(^|\r)\|.*\|\r,s", "\r", $texte); |
---|
206 | |
---|
207 | return $texte; |
---|
208 | } |
---|
209 | |
---|
210 | |
---|
211 | |
---|
212 | // Repere dans la partie texte d'un raccourci [texte->...] |
---|
213 | // la langue et la bulle eventuelles |
---|
214 | |
---|
215 | define('_RACCOURCI_ATTRIBUTS', '/^(.*?)([|]([^<>]*?))?([{]([a-z_]*)[}])?$/'); |
---|
216 | |
---|
217 | // http://doc.spip.org/@traiter_raccourci_lien_atts |
---|
218 | function traiter_raccourci_lien_atts($texte) { |
---|
219 | |
---|
220 | $bulle = $hlang = ''; |
---|
221 | // title et hreflang donnes par le raccourci ? |
---|
222 | if (strpbrk($texte, "|{") !== false AND |
---|
223 | preg_match(_RACCOURCI_ATTRIBUTS, $texte, $m)) { |
---|
224 | |
---|
225 | $n =count($m); |
---|
226 | // |infobulle ? |
---|
227 | if ($n > 2) { |
---|
228 | $bulle = $m[3]; |
---|
229 | // {hreflang} ? |
---|
230 | if ($n > 4) { |
---|
231 | // si c'est un code de langue connu, on met un hreflang |
---|
232 | if (traduire_nom_langue($m[5]) <> $m[5]) { |
---|
233 | $hlang = $m[5]; |
---|
234 | } elseif (!$m[5]) { |
---|
235 | $hlang = test_espace_prive() ? |
---|
236 | $GLOBALS['lang_objet'] : $GLOBALS['spip_lang']; |
---|
237 | // sinon c'est un italique |
---|
238 | } else { |
---|
239 | $m[1] .= $m[4]; |
---|
240 | } |
---|
241 | |
---|
242 | // S'il n'y a pas de hreflang sous la forme {}, ce qui suit le | |
---|
243 | // est peut-etre une langue |
---|
244 | } else if (preg_match('/^[a-z_]+$/', $m[3])) { |
---|
245 | // si c'est un code de langue connu, on met un hreflang |
---|
246 | // mais on laisse le title (c'est arbitraire tout ca...) |
---|
247 | if (traduire_nom_langue($m[3]) <> $m[3]) { |
---|
248 | $hlang = $m[3]; |
---|
249 | } |
---|
250 | } |
---|
251 | } |
---|
252 | $texte = $m[1]; |
---|
253 | } |
---|
254 | |
---|
255 | return array(trim($texte), $bulle, $hlang); |
---|
256 | } |
---|
257 | |
---|
258 | define('_EXTRAIRE_DOMAINE', '/^(?:[^\W_]((?:[^\W_]|-){0,61}[^\W_,])?\.)+[a-z]{2,6}\b/Si'); |
---|
259 | |
---|
260 | // callback pour la fonction traiter_raccourci_liens() |
---|
261 | // http://doc.spip.org/@autoliens_callback |
---|
262 | function traiter_autoliens($r) { |
---|
263 | if (count($r)<2) return reset($r); |
---|
264 | list($tout, $l) = $r; |
---|
265 | if (!$l) return $tout; |
---|
266 | // reperer le protocole |
---|
267 | if (preg_match(',^(https?):/*,S', $l, $m)) { |
---|
268 | $l = substr($l, strlen($m[0])); |
---|
269 | $protocol = $m[1]; |
---|
270 | } else $protocol = 'http'; |
---|
271 | // valider le nom de domaine |
---|
272 | if (!preg_match(_EXTRAIRE_DOMAINE, $l)) return $tout; |
---|
273 | // supprimer les ponctuations a la fin d'une URL |
---|
274 | preg_match('/^(.*?)([,.;?]?)$/', $l, $k); |
---|
275 | $url = $protocol.'://'.$k[1]; |
---|
276 | $lien = charger_fonction('lien', 'inc'); |
---|
277 | $r = $lien($url,'','','','','nofollow') . $k[2]; |
---|
278 | |
---|
279 | // ajouter la class auto |
---|
280 | $r = inserer_attribut($r, 'class', trim(extraire_attribut($r,'class').' auto')); |
---|
281 | |
---|
282 | // si l'original ne contenait pas le 'http:' on le supprime du clic |
---|
283 | return $m ? $r : str_replace('>http://', '>', $r); |
---|
284 | } |
---|
285 | |
---|
286 | define('_EXTRAIRE_LIENS', ',' . '\[[^\[\]]*(?:<-|->).*?\]' . '|<a\b.*?</a\b' . '|<\w.*?>' . '|((?:https?:/|www\.)[^"\'\s\[\]\}\)<>]*)' .',imsS'); |
---|
287 | |
---|
288 | // Les URLs brutes sont converties en <a href='url'>url</a> |
---|
289 | // http://doc.spip.org/@traiter_raccourci_liens |
---|
290 | function traiter_raccourci_liens($t) { |
---|
291 | return preg_replace_callback(_EXTRAIRE_LIENS, 'traiter_autoliens', $t); |
---|
292 | } |
---|
293 | |
---|
294 | |
---|
295 | define('_RACCOURCI_CHAPO', '/^(\W*)(\W*)(\w*\d+([?#].*)?)$/'); |
---|
296 | /** |
---|
297 | * Fonction pour les champs virtuels de redirection qui peut etre: |
---|
298 | * 1. un raccourci Spip habituel (premier If) [texte->TYPEnnn] |
---|
299 | * 2. un ultra raccourci TYPEnnn voire nnn (article) (deuxieme If) |
---|
300 | * 3. une URL std |
---|
301 | * |
---|
302 | * renvoie l'url reelle de redirection si le $url=true, |
---|
303 | * l'url brute contenue dans le chapo sinon |
---|
304 | * |
---|
305 | * http://doc.spip.org/@chapo_redirige |
---|
306 | * |
---|
307 | * @param string $virtuel |
---|
308 | * @param bool $url |
---|
309 | * @return string |
---|
310 | */ |
---|
311 | function virtuel_redirige($virtuel, $url=false){ |
---|
312 | if (!strlen($virtuel)) return ''; |
---|
313 | if (!preg_match(_RACCOURCI_LIEN, $virtuel, $m)) |
---|
314 | if (!preg_match(_RACCOURCI_CHAPO, $virtuel, $m)) |
---|
315 | return $virtuel; |
---|
316 | |
---|
317 | return !$url ? $m[3] : traiter_lien_implicite($m[3]); |
---|
318 | } |
---|
319 | |
---|
320 | |
---|
321 | // Cherche un lien du type [->raccourci 123] |
---|
322 | // associe a une fonction generer_url_raccourci() definie explicitement |
---|
323 | // ou implicitement par le jeu de type_urls courant. |
---|
324 | // |
---|
325 | // Valeur retournee selon le parametre $pour: |
---|
326 | // 'tout' : tableau d'index url,class,titre,lang (vise <a href="U" class='C' hreflang='L'>T</a>) |
---|
327 | // 'titre': seulement T ci-dessus (i.e. le TITRE ci-dessus ou dans table SQL) |
---|
328 | // 'url': seulement U (i.e. generer_url_RACCOURCI) |
---|
329 | |
---|
330 | // http://doc.spip.org/@calculer_url |
---|
331 | function calculer_url ($ref, $texte='', $pour='url', $connect='') { |
---|
332 | $r = traiter_lien_implicite($ref, $texte, $pour, $connect); |
---|
333 | return $r ? $r : traiter_lien_explicite($ref, $texte, $pour, $connect); |
---|
334 | } |
---|
335 | |
---|
336 | define('_EXTRAIRE_LIEN', ",^\s*(http:?/?/?|mailto:?)\s*$,iS"); |
---|
337 | |
---|
338 | // http://doc.spip.org/@traiter_lien_explicite |
---|
339 | function traiter_lien_explicite ($ref, $texte='', $pour='url', $connect='') |
---|
340 | { |
---|
341 | if (preg_match(_EXTRAIRE_LIEN, $ref)) |
---|
342 | return ($pour != 'tout') ? '' : array('','','',''); |
---|
343 | |
---|
344 | $lien = entites_html(trim($ref)); |
---|
345 | |
---|
346 | // Liens explicites |
---|
347 | if (!$texte) { |
---|
348 | $texte = str_replace('"', '', $lien); |
---|
349 | // evite l'affichage de trops longues urls. |
---|
350 | $lien_court = charger_fonction('lien_court', 'inc'); |
---|
351 | $texte = $lien_court($texte); |
---|
352 | $texte = "<html>".quote_amp($texte)."</html>"; |
---|
353 | } |
---|
354 | |
---|
355 | // petites corrections d'URL |
---|
356 | if (preg_match('/^www\.[^@]+$/S',$lien)) |
---|
357 | $lien = "http://".$lien; |
---|
358 | else if (strpos($lien, "@") && email_valide($lien)) { |
---|
359 | if (!$texte) $texte = $lien; |
---|
360 | $lien = "mailto:".$lien; |
---|
361 | } |
---|
362 | |
---|
363 | if ($pour == 'url') return $lien; |
---|
364 | |
---|
365 | if ($pour == 'titre') return $texte; |
---|
366 | |
---|
367 | return array('url' => $lien, 'titre' => $texte); |
---|
368 | } |
---|
369 | |
---|
370 | function liens_implicite_glose_dist($texte,$id,$type,$args,$ancre,$connect=''){ |
---|
371 | if (function_exists($f = 'glossaire_' . $ancre)) |
---|
372 | $url = $f($texte, $id); |
---|
373 | else |
---|
374 | $url = glossaire_std($texte); |
---|
375 | return $url; |
---|
376 | } |
---|
377 | |
---|
378 | /** |
---|
379 | * Transformer un lien raccourci art23 en son URL |
---|
380 | * Par defaut la fonction produit une url prive si on est dans le prive |
---|
381 | * ou publique si on est dans le public. |
---|
382 | * La globale lien_implicite_cible_public permet de forcer un cas ou l'autre : |
---|
383 | * $GLOBALS['lien_implicite_cible_public'] = true; |
---|
384 | * => tous les liens raccourcis pointent vers le public |
---|
385 | * $GLOBALS['lien_implicite_cible_public'] = false; |
---|
386 | * => tous les liens raccourcis pointent vers le prive |
---|
387 | * unset($GLOBALS['lien_implicite_cible_public']); |
---|
388 | * => retablit le comportement automatique |
---|
389 | * |
---|
390 | * http://doc.spip.org/@traiter_lien_implicite |
---|
391 | * |
---|
392 | * @param string $ref |
---|
393 | * @param string $texte |
---|
394 | * @param string $pour |
---|
395 | * @param string $connect |
---|
396 | * @return array|bool|string |
---|
397 | */ |
---|
398 | function traiter_lien_implicite ($ref, $texte='', $pour='url', $connect='') |
---|
399 | { |
---|
400 | $cible = ($connect ? $connect : (isset($GLOBALS['lien_implicite_cible_public'])?$GLOBALS['lien_implicite_cible_public']:null)); |
---|
401 | if (!($match = typer_raccourci($ref))) return false; |
---|
402 | @list($type,,$id,,$args,,$ancre) = $match; |
---|
403 | # attention dans le cas des sites le lien doit pointer non pas sur |
---|
404 | # la page locale du site, mais directement sur le site lui-meme |
---|
405 | if ($f = charger_fonction("implicite_$type","liens",true)) |
---|
406 | $url = $f($texte,$id,$type,$args,$ancre,$connect); |
---|
407 | if (!$url) |
---|
408 | $url = generer_url_entite($id,$type,$args,$ancre,$cible); |
---|
409 | if (!$url) return false; |
---|
410 | if (is_array($url)) { |
---|
411 | @list($type,$id) = $url; |
---|
412 | $url = generer_url_entite($id,$type,$args,$ancre,$cible); |
---|
413 | } |
---|
414 | if ($pour === 'url') return $url; |
---|
415 | $r = traiter_raccourci_titre($id, $type, $connect); |
---|
416 | if ($r) $r['class'] = ($type == 'site')?'spip_out':'spip_in'; |
---|
417 | if ($texte = trim($texte)) $r['titre'] = $texte; |
---|
418 | if (!@$r['titre']) $r['titre'] = _T($type) . " $id"; |
---|
419 | if ($pour=='titre') return $r['titre']; |
---|
420 | $r['url'] = $url; |
---|
421 | |
---|
422 | // dans le cas d'un lien vers un doc, ajouter le type='mime/type' |
---|
423 | if ($type == 'document' |
---|
424 | AND $mime = sql_getfetsel('mime_type', 'spip_types_documents', |
---|
425 | "extension IN (SELECT extension FROM spip_documents where id_document =".intval($id).")", |
---|
426 | '','','','',$connect) |
---|
427 | ) |
---|
428 | $r['mime'] = $mime; |
---|
429 | |
---|
430 | return $r; |
---|
431 | } |
---|
432 | |
---|
433 | // analyse des raccourcis issus de [TITRE->RACCOURCInnn] et connexes |
---|
434 | |
---|
435 | define('_RACCOURCI_URL', '/^\s*(\w*?)\s*(\d+)(\?(.*?))?(#([^\s]*))?\s*$/S'); |
---|
436 | |
---|
437 | // http://doc.spip.org/@typer_raccourci |
---|
438 | function typer_raccourci ($lien) { |
---|
439 | if (!preg_match(_RACCOURCI_URL, $lien, $match)) return array(); |
---|
440 | $f = $match[1]; |
---|
441 | // valeur par defaut et alias historiques |
---|
442 | if (!$f) $f = 'article'; |
---|
443 | else if ($f == 'art') $f = 'article'; |
---|
444 | else if ($f == 'br') $f = 'breve'; |
---|
445 | else if ($f == 'rub') $f = 'rubrique'; |
---|
446 | else if ($f == 'aut') $f = 'auteur'; |
---|
447 | else if ($f == 'doc' OR $f == 'im' OR $f == 'img' OR $f == 'image' OR $f == 'emb') |
---|
448 | $f = 'document'; |
---|
449 | else if (preg_match('/^br..?ve$/S', $f)) $f = 'breve'; # accents :( |
---|
450 | $match[0] = $f; |
---|
451 | return $match; |
---|
452 | } |
---|
453 | |
---|
454 | // Retourne le champ textuel associe a une cle primaire, et sa langue |
---|
455 | function traiter_raccourci_titre($id, $type, $connect=NULL) |
---|
456 | { |
---|
457 | $trouver_table = charger_fonction('trouver_table', 'base'); |
---|
458 | $desc = $trouver_table(table_objet($type)); |
---|
459 | if (!($desc AND $s = $desc['titre'])) return array(); |
---|
460 | $_id = $desc['key']['PRIMARY KEY']; |
---|
461 | $r = sql_fetsel($s, $desc['table'], "$_id=$id", '','','','',$connect); |
---|
462 | if (!$r) return array(); |
---|
463 | $r['titre'] = supprimer_numero($r['titre']); |
---|
464 | if (!$r['titre']) $r['titre'] = $r['surnom']; |
---|
465 | if (!isset($r['lang'])) $r['lang'] = ''; |
---|
466 | return $r; |
---|
467 | } |
---|
468 | |
---|
469 | // traite les modeles (dans la fonction typo), en remplacant |
---|
470 | // le raccourci <modeleN|parametres> par la page calculee a |
---|
471 | // partir du squelette modeles/modele.html |
---|
472 | // Le nom du modele doit faire au moins trois caracteres (evite <h2>) |
---|
473 | // Si $doublons==true, on repere les documents sans calculer les modeles |
---|
474 | // mais on renvoie les params (pour l'indexation par le moteur de recherche) |
---|
475 | // http://doc.spip.org/@traiter_modeles |
---|
476 | |
---|
477 | define('_RACCOURCI_MODELE', |
---|
478 | '(<([a-z_-]{3,})' # <modele |
---|
479 | .'\s*([0-9]*)\s*' # id |
---|
480 | .'([|](?:<[^<>]*>|[^>])*?)?' # |arguments (y compris des tags <...>) |
---|
481 | .'\s*/?'.'>)' # fin du modele > |
---|
482 | .'\s*(<\/a>)?' # eventuel </a> |
---|
483 | ); |
---|
484 | |
---|
485 | define('_RACCOURCI_MODELE_DEBUT', '@^' . _RACCOURCI_MODELE .'@isS'); |
---|
486 | |
---|
487 | // http://doc.spip.org/@traiter_modeles |
---|
488 | function traiter_modeles($texte, $doublons=false, $echap='', $connect='', $liens = null) { |
---|
489 | // preserver la compatibilite : true = recherche des documents |
---|
490 | if ($doublons===true) |
---|
491 | $doublons = array('documents'=>array('doc','emb','img')); |
---|
492 | // detecter les modeles (rapide) |
---|
493 | if (strpos($texte,"<")!==false AND |
---|
494 | preg_match_all('/<[a-z_-]{3,}\s*[0-9|]+/iS', $texte, $matches, PREG_SET_ORDER)) { |
---|
495 | include_spip('public/assembler'); |
---|
496 | foreach ($matches as $match) { |
---|
497 | // Recuperer l'appel complet (y compris un eventuel lien) |
---|
498 | |
---|
499 | $a = strpos($texte,$match[0]); |
---|
500 | preg_match(_RACCOURCI_MODELE_DEBUT, |
---|
501 | substr($texte, $a), $regs); |
---|
502 | $regs[]=""; // s'assurer qu'il y a toujours un 5e arg, eventuellement vide |
---|
503 | list(,$mod, $type, $id, $params, $fin) = $regs; |
---|
504 | if ($fin AND |
---|
505 | preg_match('/<a\s[^<>]*>\s*$/i', |
---|
506 | substr($texte, 0, $a), $r)) { |
---|
507 | $lien = array( |
---|
508 | 'href' => extraire_attribut($r[0],'href'), |
---|
509 | 'class' => extraire_attribut($r[0],'class'), |
---|
510 | 'mime' => extraire_attribut($r[0],'type') |
---|
511 | ); |
---|
512 | $n = strlen($r[0]); |
---|
513 | $a -= $n; |
---|
514 | $cherche = $n + strlen($regs[0]); |
---|
515 | } else { |
---|
516 | $lien = false; |
---|
517 | $cherche = strlen($mod); |
---|
518 | } |
---|
519 | |
---|
520 | // calculer le modele |
---|
521 | # hack indexation |
---|
522 | if ($doublons) |
---|
523 | $texte .= preg_replace(',[|][^|=]*,s',' ',$params); |
---|
524 | # version normale |
---|
525 | else { |
---|
526 | // si un tableau de liens a ete passe, reinjecter le contenu d'origine |
---|
527 | // dans les parametres, plutot que les liens echappes |
---|
528 | if (!is_null($liens)) |
---|
529 | $params = str_replace($liens[0], $liens[1], $params); |
---|
530 | $modele = inclure_modele($type, $id, $params, $lien, $connect); |
---|
531 | // en cas d'echec, |
---|
532 | // si l'objet demande a une url, |
---|
533 | // creer un petit encadre vers elle |
---|
534 | if ($modele === false) { |
---|
535 | if (!$lien) |
---|
536 | $lien = traiter_lien_implicite("$type$id", '', 'tout', $connect); |
---|
537 | if ($lien) |
---|
538 | $modele = '<a href="' |
---|
539 | .$lien['url'] |
---|
540 | .'" class="spip_modele' |
---|
541 | . '">' |
---|
542 | .sinon($lien['titre'], _T('ecrire:info_sans_titre')) |
---|
543 | ."</a>"; |
---|
544 | else { |
---|
545 | $modele = ""; |
---|
546 | if (test_espace_prive()) { |
---|
547 | $modele = entites_html(substr($texte,$a,$cherche)); |
---|
548 | if (!is_null($liens)) |
---|
549 | $modele = "<pre>".str_replace($liens[0], $liens[1], $modele)."</pre>"; |
---|
550 | } |
---|
551 | } |
---|
552 | } |
---|
553 | // le remplacer dans le texte |
---|
554 | if ($modele !== false) { |
---|
555 | $modele = protege_js_modeles($modele); |
---|
556 | $rempl = code_echappement($modele, $echap); |
---|
557 | $texte = substr($texte, 0, $a) |
---|
558 | . $rempl |
---|
559 | . substr($texte, $a+$cherche); |
---|
560 | } |
---|
561 | } |
---|
562 | |
---|
563 | // hack pour tout l'espace prive |
---|
564 | if (((!_DIR_RESTREINT) OR ($doublons)) AND ($id)){ |
---|
565 | foreach($doublons?$doublons:array('documents'=>array('doc','emb','img')) as $quoi=>$modeles) |
---|
566 | if (in_array($type,$modeles)) |
---|
567 | $GLOBALS["doublons_{$quoi}_inclus"][] = $id; |
---|
568 | } |
---|
569 | } |
---|
570 | } |
---|
571 | |
---|
572 | return $texte; |
---|
573 | } |
---|
574 | |
---|
575 | // |
---|
576 | // Raccourcis ancre [#ancre<-] |
---|
577 | // |
---|
578 | |
---|
579 | define('_RACCOURCI_ANCRE', "/\[#?([^][]*)<-\]/S"); |
---|
580 | |
---|
581 | // http://doc.spip.org/@traiter_raccourci_ancre |
---|
582 | function traiter_raccourci_ancre($letexte) |
---|
583 | { |
---|
584 | if (preg_match_all(_RACCOURCI_ANCRE, $letexte, $m, PREG_SET_ORDER)) |
---|
585 | foreach ($m as $regs) |
---|
586 | $letexte = str_replace($regs[0], |
---|
587 | '<a name="'.entites_html($regs[1]).'"></a>', $letexte); |
---|
588 | return $letexte; |
---|
589 | } |
---|
590 | |
---|
591 | // |
---|
592 | // Raccourcis automatiques [?SPIP] vers un glossaire |
---|
593 | // Wikipedia par defaut, avec ses contraintes techniques |
---|
594 | // cf. http://fr.wikipedia.org/wiki/Wikip%C3%A9dia:Conventions_sur_les_titres |
---|
595 | |
---|
596 | define('_RACCOURCI_GLOSSAIRE', "/\[\?+\s*([^][<>]+)\]/S"); |
---|
597 | define('_RACCOURCI_GLOSES', '/^([^|#{]*\w[^|#{]*)([^#]*)(#([^|{}]*))?(.*)$/S'); |
---|
598 | |
---|
599 | // http://doc.spip.org/@traiter_raccourci_glossaire |
---|
600 | function traiter_raccourci_glossaire($texte) |
---|
601 | { |
---|
602 | if (!preg_match_all(_RACCOURCI_GLOSSAIRE, |
---|
603 | $texte, $matches, PREG_SET_ORDER)) |
---|
604 | return $texte; |
---|
605 | |
---|
606 | include_spip('inc/charsets'); |
---|
607 | $lien = charger_fonction('lien', 'inc'); |
---|
608 | |
---|
609 | foreach ($matches as $regs) { |
---|
610 | // Eviter les cas particulier genre "[?!?]" |
---|
611 | // et isoler le lexeme a gloser de ses accessoires |
---|
612 | // (#:url du glossaire, | bulle d'aide, {} hreflang) |
---|
613 | // Transformation en pseudo-raccourci pour passer dans inc_lien |
---|
614 | if (preg_match(_RACCOURCI_GLOSES, $regs[1], $r)) { |
---|
615 | preg_match('/^(.*?)(\d*)$/', $r[4], $m); |
---|
616 | $_n = intval($m[2]); |
---|
617 | $gloss = $m[1] ? ('#' . $m[1]) : ''; |
---|
618 | $t = $r[1] . $r[2] . $r[5]; |
---|
619 | list($t, $bulle, $hlang) = traiter_raccourci_lien_atts($t); |
---|
620 | $t = unicode2charset(charset2unicode($t), 'utf-8'); |
---|
621 | $ref = $lien("glose$_n$gloss", $t, 'spip_glossaire', $bulle, $hlang); |
---|
622 | $texte = str_replace($regs[0], $ref, $texte); |
---|
623 | } |
---|
624 | } |
---|
625 | return $texte; |
---|
626 | } |
---|
627 | |
---|
628 | // http://doc.spip.org/@glossaire_std |
---|
629 | function glossaire_std($terme) |
---|
630 | { |
---|
631 | global $url_glossaire_externe; |
---|
632 | static $pcre = NULL; |
---|
633 | |
---|
634 | if ($pcre === NULL) { |
---|
635 | $pcre = isset($GLOBALS['meta']['pcre_u']) |
---|
636 | ? $GLOBALS['meta']['pcre_u'] |
---|
637 | : ''; |
---|
638 | if (strpos($url_glossaire_externe, "%s") === false) |
---|
639 | $url_glossaire_externe .= '%s'; |
---|
640 | } |
---|
641 | |
---|
642 | $glosateur = str_replace("@lang@", |
---|
643 | $GLOBALS['spip_lang'], |
---|
644 | $GLOBALS['url_glossaire_externe']); |
---|
645 | |
---|
646 | $terme = rawurlencode(preg_replace(',\s+,'.$pcre, '_', $terme)); |
---|
647 | |
---|
648 | return str_replace("%s", $terme, $glosateur); |
---|
649 | } |
---|
650 | |
---|
651 | ?> |
---|