source: spip-zone/_core_/plugins/urls_etendues/urls/arbo.php @ 93629

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

Indentation et regles de codage selon http://www.spip.net/fr_article3497.html#regles_codage

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