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