source: spip-zone/_core_/plugins/textwheel/inc/lien.php @ 49127

Last change on this file since 49127 was 49127, checked in by cedric@…, 10 years ago

variable non définie introduite dans r16331 + commentaire du code concerné

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