source: spip-zone/_core_/branches/spip-3.0/plugins/textwheel/inc/lien.php @ 104360

Last change on this file since 104360 was 104360, checked in by spip.franck@…, 3 years ago

code.spip est maintenant en https, donc j'ajoute le "s" à http

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