source: spip-zone/_core_/branches/spip-3.0/plugins/urls_etendues/urls/arbo.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: 22.8 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; // securiser
14
15# donner un exemple d'url pour le formulaire de choix
16define('URLS_ARBO_EXEMPLE', '/article/titre');
17# specifier le form de config utilise pour ces urls
18define('URLS_ARBO_CONFIG', 'arbo');
19
20// TODO: une interface permettant de verifier qu'on veut effectivment modifier
21// une adresse existante
22defined('CONFIRMER_MODIFIER_URL') || define('CONFIRMER_MODIFIER_URL', false);
23
24/**
25 * - Comment utiliser ce jeu d'URLs ?
26 * Recopiez le fichier "htaccess.txt" du repertoire de base du site SPIP sous
27 * le sous le nom ".htaccess" (attention a ne pas ecraser d'autres reglages
28 * que vous pourriez avoir mis dans ce fichier) ; si votre site est en
29 * "sous-repertoire", vous devrez aussi editer la ligne "RewriteBase" ce fichier.
30 * Les URLs definies seront alors redirigees vers les fichiers de SPIP.
31 *
32 * Choisissez "arbo" dans les pages de configuration d'URL
33 *
34 * SPIP calculera alors ses liens sous la forme "Mon-titre-d-article".
35 * Variantes :
36 *
37 * Terminaison :
38 * les terminaisons ne *sont pas* stockees en base, elles servent juste
39 * a rendre les url jolies ou conformes a un usage
40 * pour avoir des url terminant par html
41 * define ('_terminaison_urls_arbo', '.html');
42 *
43 * pour preciser des terminaisons particulieres pour certains types
44 * $GLOBALS['url_arbo_terminaisons']=array(
45 * 'rubrique' => '/',
46 * 'mot' => '',
47 * 'groupe' => '/',
48 * 'defaut' => '.html');
49 *
50 * pour avoir des url numeriques (id) du type 12/5/4/article/23
51 * define ('_URLS_ARBO_MIN',255);
52 *
53 *
54 * pour conserver la casse des titres dans les url
55 * define ('_url_arbo_minuscules',0);
56 *
57 * pour choisir le caractere de separation titre-id en cas de doublon
58 * (ne pas utiliser '/')
59 * define ('_url_arbo_sep_id','-');
60 *
61 * pour modifier la hierarchie apparente dans la constitution des urls
62 * ex pour que les mots soient classes par groupes
63 * $GLOBALS['url_arbo_parents']=array(
64 *                        'article'=>array('id_rubrique','rubrique'),
65 *                        'rubrique'=>array('id_parent','rubrique'),
66 *                        'breve'=>array('id_rubrique','rubrique'),
67 *                        'site'=>array('id_rubrique','rubrique'),
68 *                              'mot'=>array('id_groupe','groupes_mot'));
69 *
70 * pour personaliser les types
71 * $GLOBALS['url_arbo_types']=array(
72 * 'rubrique'=>'', // pas de type pour les rubriques
73 * 'article'=>'a',
74 * 'mot'=>'tags'
75 * );
76 *
77 */
78
79
80$config_urls_arbo = isset($GLOBALS['meta']['urls_arbo'])?unserialize($GLOBALS['meta']['urls_arbo']):array();
81if (!defined('_debut_urls_arbo')) define('_debut_urls_arbo', '');
82if (!defined('_terminaison_urls_arbo')) define('_terminaison_urls_arbo', '');
83// pour choisir le caractere de separation titre-id en cas de doublon
84// (ne pas utiliser '/')
85if (!defined('_url_arbo_sep_id')) define('_url_arbo_sep_id',isset($config_urls_arbo['url_arbo_sep_id'])?$config_urls_arbo['url_arbo_sep_id']:'-');
86// option pour tout passer en minuscules
87if (!defined('_url_arbo_minuscules')) define('_url_arbo_minuscules',isset($config_urls_arbo['url_arbo_minuscules'])?$config_urls_arbo['url_arbo_minuscules']:1);
88if (!defined('_URLS_ARBO_MAX')) define('_URLS_ARBO_MAX', isset($config_urls_arbo['URLS_ARBO_MAX'])?$config_urls_arbo['URLS_ARBO_MAX']:80);
89if (!defined('_URLS_ARBO_MIN')) define('_URLS_ARBO_MIN', isset($config_urls_arbo['URLS_ARBO_MIN'])?$config_urls_arbo['URLS_ARBO_MIN']:3);
90
91if (!defined('_url_sep_id')) define('_url_sep_id',_url_arbo_sep_id);
92
93// Ces chaines servaient de marqueurs a l'epoque ou les URL propres devaient
94// indiquer la table ou les chercher (articles, auteurs etc),
95// et elles etaient retirees par les preg_match dans la fonction ci-dessous.
96// Elles sont a present definies a "" pour avoir des URL plus jolies
97// mais les preg_match restent necessaires pour gerer les anciens signets.
98
99#define('_MARQUEUR_URL', serialize(array('rubrique1' => '-', 'rubrique2' => '-', 'breve1' => '+', 'breve2' => '+', 'site1' => '@', 'site2' => '@', 'auteur1' => '_', 'auteur2' => '_', 'mot1' => '+-', 'mot2' => '-+')));
100if (!defined('_MARQUEUR_URL')) define('_MARQUEUR_URL', false);
101
102/**
103 * Definir les parentees utilisees pour construire des urls arborescentes
104 *
105 * @param string $type
106 * @return string
107 */
108function url_arbo_parent($type){
109        static $parents = null;
110        if (is_null($parents)){
111                $parents = array(
112                          'article'=>array('id_rubrique','rubrique'),
113                          'rubrique'=>array('id_parent','rubrique'),
114                          'breve'=>array('id_rubrique','rubrique'),
115                          'site'=>array('id_rubrique','rubrique'));
116                if (isset($GLOBALS['url_arbo_parents']) AND !isset($_REQUEST['url_arbo_parents'])){
117                        $parents = array_merge($parents,$GLOBALS['url_arbo_parents']);
118                }                         
119        }
120        return (isset($parents[$type])?$parents[$type]:'');
121}
122
123/**
124 * Definir les terminaisons des urls :
125 * / pour une rubrique
126 * .html pour une page etc..
127 *
128 * @param string $type
129 * @return string
130 */
131function url_arbo_terminaison($type){
132        static $terminaison_types = null;
133        if ($terminaison_types==null){
134                $terminaison_types = array('rubrique' => '/','mot' => '','defaut' => defined('_terminaison_urls_arbo')?_terminaison_urls_arbo:'.html');
135                if (isset($GLOBALS['url_arbo_terminaisons']))
136                        $terminaison_types = array_merge($terminaison_types,$GLOBALS['url_arbo_terminaisons']);
137        }
138        // si c'est un appel avec type='' c'est pour avoir la liste des terminaisons
139        if (!$type)
140                return array_unique(array_values($terminaison_types));
141        if (isset($terminaison_types[$type]))
142                return $terminaison_types[$type];
143        elseif (isset($terminaison_types['defaut']))
144                return $terminaison_types['defaut'];
145        return "";
146}
147
148/**
149 * Definir le prefixe qui designe le type et qu'on utilise pour chaque objet
150 * ex : "article"/truc
151 * par defaut les rubriques ne sont pas typees, mais le reste oui
152 *
153 * @param string $type
154 * @return array|string
155 */
156function url_arbo_type($type){
157        static $synonymes_types = null;
158        if (!$synonymes_types){
159                $synonymes_types = array('rubrique'=>'');
160                if (isset($GLOBALS['url_arbo_types']) AND is_array($GLOBALS['url_arbo_types']))
161                        $synonymes_types = array_merge($synonymes_types,$GLOBALS['url_arbo_types']);
162        }
163        // si c'est un appel avec type='' c'est pour avoir la liste inversee des synonymes
164        if (!$type)
165                return array_flip($synonymes_types);
166        return 
167            ($t=(isset($synonymes_types[$type])?$synonymes_types[$type]:$type))  // le type ou son synonyme
168          . ($t?'/':''); // le / eventuel pour separer, si le synonyme n'est pas vide
169}
170
171/**
172 * Pipeline pour creation d'une adresse : il recoit l'url propose par le
173 * precedent, un tableau indiquant le titre de l'objet, son type, son id,
174 * et doit donner en retour une chaine d'url, sans se soucier de la
175 * duplication eventuelle, qui sera geree apres
176 * https://code.spip.net/@creer_chaine_url
177 *
178 * @param array $x
179 * @return array
180 */
181function urls_arbo_creer_chaine_url($x) {
182        // NB: ici url_old ne sert pas, mais un plugin qui ajouterait une date
183        // pourrait l'utiliser pour juste ajouter la
184        $url_old = $x['data'];
185        $objet = $x['objet'];
186        include_spip('inc/filtres');
187
188        include_spip('action/editer_url');
189        if (!$url = url_nettoyer($objet['titre'],_URLS_ARBO_MAX,_URLS_ARBO_MIN,'-',_url_arbo_minuscules?'strtolower':''))
190                $url = $objet['id_objet'];
191       
192        $x['data'] =
193                  url_arbo_type($objet['type']) // le type ou son synonyme
194          . $url; // le titre
195
196        return $x;
197}
198
199/**
200 * Boucler sur le parent pour construire l'url complete a partir des segments
201 * https://code.spip.net/@declarer_url_arbo_rec
202 *
203 * @param string $url
204 * @param string $type
205 * @param string $parent
206 * @param string $type_parent
207 * @return string
208 */
209function declarer_url_arbo_rec($url,$type,$parent,$type_parent){
210        if (is_null($parent)){
211                return $url;
212        }
213        // Si pas de parent ou si son URL est vide, on ne renvoit que l'URL de l'objet en court
214        if ($parent==0 or !($url_parent = declarer_url_arbo($type_parent?$type_parent:'rubrique',$parent))){
215                return rtrim($url,'/');
216        }
217        // Sinon on renvoit l'URL de l'objet concaténée avec celle du parent
218        else {
219                return rtrim($url_parent,'/') . '/' . rtrim($url,'/');
220        }
221}
222
223/**
224 * Renseigner les infos les plus recentes de l'url d'un objet
225 * et de quoi la (re)construire si besoin
226 * @param string $type
227 * @param int $id_objet
228 * @return bool|null|array
229 */
230function renseigner_url_arbo($type,$id_objet){
231        $urls = array();
232        $trouver_table = charger_fonction('trouver_table', 'base');
233        $desc = $trouver_table(table_objet($type));
234        $table = $desc['table'];
235        $col_id =  @$desc['key']["PRIMARY KEY"];
236        if (!$col_id) return false; // Quand $type ne reference pas une table
237        $id_objet = intval($id_objet);
238
239        $champ_titre = $desc['titre'] ? $desc['titre'] : 'titre';
240       
241        // parent
242        $champ_parent = url_arbo_parent($type);
243        $sel_parent = ', 0 as parent';
244        $order_by_parent = "";
245        if ($champ_parent){
246                $sel_parent = ", O.".reset($champ_parent).' as parent';
247                // trouver l'url qui matche le parent en premier
248                $order_by_parent = "O.".reset($champ_parent)."=U.id_parent DESC, ";
249        }
250        //  Recuperer une URL propre correspondant a l'objet.
251        $row = sql_fetsel("U.url, U.date, U.id_parent, U.perma, $champ_titre $sel_parent",
252                                                                                "$table AS O LEFT JOIN spip_urls AS U ON (U.type='$type' AND U.id_objet=O.$col_id)",
253                                                                                "O.$col_id=$id_objet",
254                                                                                '',
255                                                                                $order_by_parent.'U.perma DESC, U.date DESC', 1);
256        if ($row){
257                $urls[$type][$id_objet] = $row;
258                $urls[$type][$id_objet]['type_parent'] = $champ_parent?end($champ_parent):'';
259        }
260        return isset($urls[$type][$id_objet])?$urls[$type][$id_objet]:null;
261}
262
263/**
264 * Retrouver/Calculer l'ensemble des segments d'url d'un objet
265 *
266 * https://code.spip.net/@declarer_url_arbo
267 *
268 * @param string $type
269 * @param int $id_objet
270 * @return string
271 */
272function declarer_url_arbo($type, $id_objet) {
273        static $urls=array();
274
275        // Se contenter de cette URL si elle existe ;
276        // sauf si on invoque par "voir en ligne" avec droit de modifier l'url
277
278        // l'autorisation est verifiee apres avoir calcule la nouvelle url propre
279        // car si elle ne change pas, cela ne sert a rien de verifier les autorisations
280        // qui requetent en base
281        $modifier_url = (defined('_VAR_URLS') AND _VAR_URLS);
282       
283        if (!isset($urls[$type][$id_objet]) OR $modifier_url) {
284                $r = renseigner_url_arbo($type,$id_objet);
285                // Quand $type ne reference pas une table
286                if ($r===false)
287                        return false;
288
289                if (!is_null($r))
290                        $urls[$type][$id_objet] = $r;
291        }
292
293        if (!isset($urls[$type][$id_objet])) return ""; # objet inexistant
294
295        $url_propre = $urls[$type][$id_objet]['url'];
296
297        // si on a trouve l'url
298        // et que le parent est bon
299        // et (permanente ou pas de demande de modif)
300        if (!is_null($url_propre)
301          AND $urls[$type][$id_objet]['id_parent'] == $urls[$type][$id_objet]['parent']
302          AND ($urls[$type][$id_objet]['perma'] OR !$modifier_url))
303                return declarer_url_arbo_rec($url_propre,$type,
304                  isset($urls[$type][$id_objet]['parent'])?$urls[$type][$id_objet]['parent']:0,
305                  isset($urls[$type][$id_objet]['type_parent'])?$urls[$type][$id_objet]['type_parent']:null);
306
307        // Si URL inconnue ou maj forcee sur une url non permanente, recreer une url
308        $url = $url_propre;
309        if (is_null($url_propre) OR ($modifier_url AND !$urls[$type][$id_objet]['perma'])) {
310                $url = pipeline('arbo_creer_chaine_url',
311                        array(
312                                'data' => $url_propre,  // le vieux url_propre
313                                'objet' => array_merge($urls[$type][$id_objet],
314                                        array('type' => $type, 'id_objet' => $id_objet)
315                                )
316                        )
317                );
318
319                // Eviter de tamponner les URLs a l'ancienne (cas d'un article
320                // intitule "auteur2")
321                include_spip('inc/urls');
322                $objets = urls_liste_objets();
323                if (preg_match(',^('.$objets.')[0-9]*$,', $url, $r)
324                AND $r[1] != $type)
325                        $url = $url._url_arbo_sep_id.$id_objet;
326        }
327
328
329        // Pas de changement d'url ni de parent
330        if ($url == $url_propre
331          AND $urls[$type][$id_objet]['id_parent'] == $urls[$type][$id_objet]['parent'])
332                return declarer_url_arbo_rec($url_propre,$type,$urls[$type][$id_objet]['parent'],$urls[$type][$id_objet]['type_parent']);
333
334        // verifier l'autorisation, maintenant qu'on est sur qu'on va agir
335        if ($modifier_url) {
336                include_spip('inc/autoriser');
337                $modifier_url = autoriser('modifierurl', $type, $id_objet);
338        }
339        // Verifier si l'utilisateur veut effectivement changer l'URL
340        if ($modifier_url
341                AND CONFIRMER_MODIFIER_URL
342                AND $url_propre
343                // on essaye pas de regenerer une url en -xxx (suffixe id anti collision)
344                AND $url != preg_replace('/'.preg_quote(_url_propres_sep_id,'/').'.*/', '', $url_propre))
345                $confirmer = true;
346        else
347                $confirmer = false;
348
349        if ($confirmer AND !_request('ok')) {
350                die ("vous changez d'url ? $url_propre -&gt; $url");
351        }
352
353        $set = array('url' => $url, 'type' => $type, 'id_objet' => $id_objet, 'id_parent'=>$urls[$type][$id_objet]['parent'],'perma'=>intval($urls[$type][$id_objet]['perma']));
354        include_spip('action/editer_url');
355        if (url_insert($set,$confirmer,_url_arbo_sep_id)){
356                $urls[$type][$id_objet]['url'] = $set['url'];
357                $urls[$type][$id_objet]['id_parent'] = $set['id_parent'];
358        }
359        else {
360                // l'insertion a echoue,
361                //serveur out ? retourner au mieux
362                $urls[$type][$id_objet]['url']=$url_propre;
363        }
364
365        return declarer_url_arbo_rec($urls[$type][$id_objet]['url'],$type,$urls[$type][$id_objet]['parent'],$urls[$type][$id_objet]['type_parent']);
366}
367
368/**
369 * Generer l'url arbo complete constituee des segments + debut + fin
370 *
371 * https://code.spip.net/@_generer_url_arbo
372 *
373 * @param string $type
374 * @param int $id
375 * @param string $args
376 * @param string $ancre
377 * @return string
378 */
379function _generer_url_arbo($type, $id, $args='', $ancre='') {
380
381        if ($generer_url_externe = charger_fonction("generer_url_$type",'urls',true)) {
382                $url = $generer_url_externe($id, $args, $ancre);
383                if (NULL != $url) return $url;
384        }
385
386        // Mode propre
387        $propre = declarer_url_arbo($type, $id);
388
389        if ($propre === false) return ''; // objet inconnu. raccourci ?
390
391        if ($propre) {
392                $url = _debut_urls_arbo
393                        . rtrim($propre,'/')
394                        . url_arbo_terminaison($type);
395        } else {
396
397                // objet connu mais sans possibilite d'URL lisible, revenir au defaut
398                include_spip('base/connect_sql');
399                $id_type = id_table_objet($type);
400                $url = get_spip_script('./')."?"._SPIP_PAGE."=$type&$id_type=$id";
401        }
402
403        // Ajouter les args
404        if ($args)
405                $url .= ((strpos($url, '?')===false) ? '?' : '&') . $args;
406
407        // Ajouter l'ancre
408        if ($ancre)
409                $url .= "#$ancre";
410
411        return _DIR_RACINE . $url;
412}
413
414
415/**
416 * API : retourner l'url d'un objet si i est numerique
417 * ou decoder cette url si c'est une chaine
418 * array([contexte],[type],[url_redirect],[fond]) : url decodee
419 *
420 * https://code.spip.net/@urls_arbo_dist
421 *
422 * @param string|int $i
423 * @param string $entite
424 * @param string|array $args
425 * @param string $ancre
426 * @return array|string
427 */
428function urls_arbo_dist($i, $entite, $args='', $ancre='') {
429        if (is_numeric($i))
430                return _generer_url_arbo($entite, $i, $args, $ancre);
431
432        // traiter les injections du type domaine.org/spip.php/cestnimportequoi/ou/encore/plus/rubrique23
433        if ($GLOBALS['profondeur_url']>0 AND $entite=='sommaire'){
434                $entite = 'type_urls';
435        }
436
437        // recuperer les &debut_xx;
438        if (is_array($args))
439                $contexte = $args;
440        else
441                parse_str($args,$contexte);
442
443        $url = $i;
444        $id_objet = $type = 0;
445        $url_redirect = null;
446
447        // Migration depuis anciennes URLs ?
448        // traiter les injections domain.tld/spip.php/n/importe/quoi/rubrique23
449        if ($GLOBALS['profondeur_url']<=0
450        AND $_SERVER['REQUEST_METHOD'] != 'POST') {
451                include_spip('inc/urls');
452                $r = nettoyer_url_page($i, $contexte);
453                if ($r) {
454                        list($contexte, $type,,, $suite) = $r;
455                        $_id = id_table_objet($type);
456                        $id_objet = $contexte[$_id];
457                        $url_propre = generer_url_entite($id_objet, $type);
458                        if (strlen($url_propre)
459                        AND !strstr($url,$url_propre)) {
460                                list(,$hash) = explode('#', $url_propre);
461                                $args = array();
462                                foreach(array_filter(explode('&', $suite)) as $fragment) {
463                                        if ($fragment != "$_id=$id_objet")
464                                                $args[] = $fragment;
465                                }
466                                $url_redirect = generer_url_entite($id_objet, $type, join('&',array_filter($args)), $hash);
467
468                                return array($contexte, $type, $url_redirect, $type);
469                        }
470                }
471        }
472        /* Fin compatibilite anciennes urls */
473
474        // Chercher les valeurs d'environnement qui indiquent l'url-propre
475        if (isset($_SERVER['REDIRECT_url_propre']))
476                $url_propre = $_SERVER['REDIRECT_url_propre'];
477        elseif (isset($_ENV['url_propre']))
478                $url_propre = $_ENV['url_propre'];
479        else {
480                // ne prendre que le segment d'url qui correspond, en fonction de la profondeur calculee
481                $url = ltrim($url,'/');
482                $url = explode('/',$url);
483                while (count($url)>$GLOBALS['profondeur_url']+1)
484                        array_shift($url);
485                $url = implode('/',$url);
486                $url_propre = preg_replace(',[?].*,', '', $url);
487        }
488
489        // Mode Query-String ?
490        if (!$url_propre
491        AND preg_match(',[?]([^=/?&]+)(&.*)?$,', $url, $r)) {
492                $url_propre = $r[1];
493        }
494
495        if (!$url_propre
496          OR $url_propre==_DIR_RESTREINT_ABS
497          OR $url_propre==_SPIP_SCRIPT) return; // qu'est-ce qu'il veut ???
498
499
500        include_spip('base/abstract_sql'); // chercher dans la table des URLS
501
502        // Revenir en utf-8 si encodage type %D8%A7 (farsi)
503        $url_propre = rawurldecode($url_propre);
504
505        // Compatibilite avec .htm/.html et autres terminaisons
506        $t = array_diff(array_unique(array_merge(array('.html','.htm','/'),url_arbo_terminaison(''))),array(''));
507        if (count($t))
508                $url_propre = preg_replace('{('
509                  .implode('|',array_map('preg_quote',$t)).')$}i', '', $url_propre);
510
511        if (strlen($url_propre) AND !preg_match(',^[^/]*[.]php,',$url_propre)){
512                $parents_vus = array();
513               
514                // recuperer tous les objets de larbo xxx/article/yyy/mot/zzzz
515                // on parcourt les segments de gauche a droite
516                // pour pouvoir contextualiser un segment par son parent
517                $url_arbo = explode('/',$url_propre);
518                $url_arbo_new = array();
519                $dernier_parent_vu = false;
520                $objet_segments = 0;
521                while (count($url_arbo)>0){
522                        $type=null;
523                        if (count($url_arbo)>1)
524                                $type = array_shift($url_arbo);
525                        $url_segment = array_shift($url_arbo);
526                        // Rechercher le segment de candidat
527                        // si on est dans un contexte de parent, donne par le segment precedent,
528                        // prefixer le segment recherche avec ce contexte
529                        $cp = "0"; // par defaut : parent racine, id=0
530                        if ($dernier_parent_vu)
531                                $cp = $parents_vus[$dernier_parent_vu];
532                        // d'abord recherche avec prefixe parent, en une requete car aucun risque de colision
533                        $row=sql_fetsel('id_objet, type, url',
534                                                                                        'spip_urls',
535                                                                                        is_null($type)
536                                                                                                ? "url=".sql_quote($url_segment, '', 'TEXT')
537                                                                                                : sql_in('url',array("$type/$url_segment",$type)),
538                                                                                        '',
539                                                                                        // en priorite celui qui a le bon parent et les deux segments
540                                                                                        // puis le bon parent avec 1 segment
541                                                                                        // puis un parent indefini (le 0 de preference) et les deux segments
542                                                                                        // puis un parent indefini (le 0 de preference) et 1 segment
543                                                                                        (intval($cp)?"id_parent=".intval($cp)." DESC, ":"id_parent>=0 DESC, ")."segments DESC, id_parent"
544                        );
545                        if ($row){
546                                if (!is_null($type) AND $row['url']==$type){
547                                        array_unshift($url_arbo,$url_segment);
548                                        $url_segment = $type;
549                                        $type = null;
550                                }
551                                $type = $row['type'];
552                                $col_id = id_table_objet($type);
553                               
554                                // le plus a droite l'emporte pour des objets presents plusieurs fois dans l'url (ie rubrique)
555                                $contexte[$col_id] = $row['id_objet'];
556
557                                $type_parent = '';
558                                if ($p = url_arbo_parent($type))
559                                        $type_parent=end($p);
560                                // l'entite la plus a droite l'emporte, si le type de son parent a ete vu
561                                // sinon c'est un segment contextuel supplementaire a ignorer
562                                // ex : rub1/article/art1/mot1 : il faut ignorer le mot1, la vrai url est celle de l'article
563                                if (!$entite
564                                  OR $dernier_parent_vu == $type_parent){
565                                        if ($objet_segments==0)
566                                                $entite = $type;
567                                }
568                                // sinon on change d'objet concerne
569                                else{
570                                        $objet_segments++;
571                                }
572
573                                $url_arbo_new[$objet_segments]['id_objet'] = $row['id_objet'];
574                                $url_arbo_new[$objet_segments]['objet'] = $type;
575                                $url_arbo_new[$objet_segments]['segment'][] = $row['url'];
576
577                                // on note le dernier parent vu de chaque type
578                                $parents_vus[$dernier_parent_vu = $type] = $row['id_objet'];
579                        }
580                        else {
581                                // un segment est inconnu
582                                if ($entite=='' OR $entite=='type_urls') {
583                                        // on genere une 404 comme il faut si on ne sait pas ou aller
584                                        return array(array(),'404');
585                                }
586                                // ici on a bien reconnu un segment en amont, mais le segment en cours est inconnu
587                                // on pourrait renvoyer sur le dernier segment identifie
588                                // mais de fait l'url entiere est inconnu : 404 aussi
589                                // mais conserver le contexte qui peut contenir un fond d'ou venait peut etre $entite (reecriture urls)
590                                return array($contexte,'404');
591                        }
592                }
593
594                if (count($url_arbo_new)){
595                        $caller = debug_backtrace();
596                        $caller = $caller[1]['function'];
597                        // si on est appele par un autre module d'url c'est du decodage d'une ancienne URL
598                        // ne pas regenerer des segments arbo, mais rediriger vers la nouvelle URL
599                        // dans la nouvelle forme
600                        if (strncmp($caller,"urls_",5)==0 AND $caller!=="urls_decoder_url"){
601                                // en absolue, car assembler ne gere pas ce cas particulier
602                                include_spip('inc/filtres_mini');
603                                $col_id = id_table_objet($entite);
604                                $url_new = generer_url_entite($contexte[$col_id],$entite);
605                                // securite contre redirection infinie
606                                if ($url_new!==$url_propre
607                                        AND rtrim($url_new,"/")!==rtrim($url_propre,"/"))
608                                        $url_redirect = url_absolue($url_new);
609                        }
610                        else {
611                                foreach($url_arbo_new as $k=>$o)
612                                        if ($s = declarer_url_arbo($o['objet'],$o['id_objet']))
613                                                $url_arbo_new[$k] = $s;
614                                        else
615                                                $url_arbo_new[$k] = implode('/',$o['segment']);
616                                $url_arbo_new = ltrim(implode('/',$url_arbo_new),'/');
617
618                                if ($url_arbo_new!==$url_propre){
619                                        $url_redirect = $url_arbo_new;
620                                        // en absolue, car assembler ne gere pas ce cas particulier
621                                        include_spip('inc/filtres_mini');
622                                        $url_redirect = url_absolue($url_redirect);
623                                }
624                        }
625                }
626
627                // gerer le retour depuis des urls propres
628                if (($entite=='' OR $entite=='type_urls')
629                AND $GLOBALS['profondeur_url']<=0){
630                        $urls_anciennes = charger_fonction('propres','urls');
631                        return $urls_anciennes($url_propre, $entite, $contexte);
632                }
633        }
634        if ($entite=='' OR $entite=='type_urls' /* compat .htaccess 2.0 */) {
635                if ($type)
636                        $entite = objet_type ($type);
637                else {
638                        // Si ca ressemble a une URL d'objet, ce n'est pas la home
639                        // et on provoque un 404
640                        if (preg_match(',^[^\.]+(\.html)?$,', $url)) {
641                                $entite = '404';
642                                $contexte['erreur'] = ''; // qu'afficher ici ?  l'url n'existe pas... on ne sait plus dire de quel type d'objet il s'agit
643                        }
644                }
645        }
646        if (!defined('_SET_HTML_BASE')){
647                define('_SET_HTML_BASE',1);
648        }
649
650        return array($contexte, $entite, $url_redirect, null);
651}
652
653?>
Note: See TracBrowser for help on using the repository browser.