[SPIP] ~v3.0.20-->v3.0.25
[lhc/web/clavette_www.git] / www / ecrire / inc / urls.php
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
13 if (!defined('_ECRIRE_INC_VERSION')) return;
14 include_spip('base/objets');
15
16 /**
17 * Decoder une url en utilisant les fonctions inverse
18 * gestion des URLs transformee par le htaccess
19 * $renommer = 'urls_propres_dist';
20 * renvoie array($contexte, $type, $url_redirect, $nfond)
21 * $nfond n'est retourne que si l'url est definie apres le ?
22 * et risque d'etre effacee par un form en get
23 * elle est utilisee par form_hidden exclusivement
24 * Compat ascendante si le retour est null en gerant une sauvegarde/restauration
25 * des globales modifiees par les anciennes fonctions
26 *
27 * @param string $url
28 * url a decoder
29 * @param string $fond
30 * fond initial par defaut
31 * @param array $contexte
32 * contexte initial a prendre en compte
33 * @param bool $assembler
34 * true si l'url correspond a l'url principale de la page qu'on est en train d'assembler
35 * dans ce cas la fonction redirigera automatiquement si besoin
36 * et utilisera les eventuelles globales $_SERVER['REDIRECT_url_propre'] et $_ENV['url_propre']
37 * provenant du htaccess
38 * @return array
39 * ($fond,$contexte,$url_redirect)
40 * si l'url n'est pas valide, $fond restera a la valeur initiale passee
41 * il suffit d'appeler la fonction sans $fond et de verifier qu'a son retour celui-ci
42 * est non vide pour verifier une url
43 *
44 */
45 function urls_decoder_url($url, $fond='', $contexte=array(), $assembler=false){
46 static $current_base = null;
47 // les anciennes fonctions modifient directement les globales
48 // on les sauve avant l'appel, et on les retablit apres !
49 $save = array(@$GLOBALS['fond'],@$GLOBALS['contexte'],@$_SERVER['REDIRECT_url_propre'],@$_ENV['url_propre'],$GLOBALS['profondeur_url']);
50 if (is_null($current_base)){
51 include_spip('inc/filtres_mini');
52 // le decodage des urls se fait toujours par rapport au site public
53 $current_base = url_absolue(_DIR_RACINE?_DIR_RACINE:'./');
54 }
55 if (strncmp($url,$current_base,strlen($current_base))==0)
56 $url = substr($url,strlen($current_base));
57
58 // si on est pas en train d'assembler la page principale,
59 // vider les globales url propres qui ne doivent pas etre utilisees en cas
60 // d'inversion url => objet
61 if (!$assembler) {
62 unset($_SERVER['REDIRECT_url_propre']);
63 unset($_ENV['url_propre']);
64 include_spip('inc/filtres_mini');
65 if (strpos($url,"://")===false){
66 $GLOBALS['profondeur_url'] = substr_count(ltrim(resolve_path("/$url"),'/'),'/');
67 }
68 else {
69 $GLOBALS['profondeur_url'] = max(0,substr_count($url,"/")-substr_count($current_base,"/"));
70 }
71 }
72
73
74 $url_redirect = "";
75 $renommer = generer_url_entite('','','','',true);
76 if (!$renommer AND !function_exists('recuperer_parametres_url'))
77 $renommer = charger_fonction('page','urls'); // fallback pour decoder l'url
78 if ($renommer) {
79 $a = $renommer($url, $fond, $contexte);
80 if (is_array($a)) {
81 list($ncontexte, $type, $url_redirect, $nfond) = array_pad($a, 4, null);
82 if ($url_redirect == $url)
83 $url_redirect = ""; // securite pour eviter une redirection infinie
84 if ($assembler AND strlen($url_redirect)) {
85 spip_log("Redirige $url vers $url_redirect");
86 include_spip('inc/headers');
87 redirige_par_entete($url_redirect, '', 301);
88 }
89 if (isset($nfond))
90 $fond = $nfond;
91 else if ($fond == ''
92 OR $fond == 'type_urls' /* compat avec htaccess 2.0.0 */
93 )
94 $fond = $type;
95 if (isset($ncontexte))
96 $contexte = $ncontexte;
97 if (defined('_DEFINIR_CONTEXTE_TYPE') AND _DEFINIR_CONTEXTE_TYPE)
98 $contexte['type'] = $type;
99 if (defined('_DEFINIR_CONTEXTE_TYPE_PAGE') AND _DEFINIR_CONTEXTE_TYPE_PAGE)
100 $contexte['type-page'] = $type;
101 }
102 }
103 // compatibilite <= 1.9.2
104 elseif (function_exists('recuperer_parametres_url')) {
105 $GLOBALS['fond'] = $fond;
106 $GLOBALS['contexte'] = $contexte;
107 recuperer_parametres_url($fond, nettoyer_uri());
108 // fond est en principe modifiee directement
109 $contexte = $GLOBALS['contexte'];
110 }
111
112 // retablir les globales
113 list($GLOBALS['fond'],$GLOBALS['contexte'],$_SERVER['REDIRECT_url_propre'],$_ENV['url_propre'],$GLOBALS['profondeur_url']) = $save;
114
115 // vider les globales url propres qui ne doivent plus etre utilisees en cas
116 // d'inversion url => objet
117 // maintenir pour compat ?
118 #if ($assembler) {
119 # unset($_SERVER['REDIRECT_url_propre']);
120 # unset($_ENV['url_propre']);
121 #}
122
123 return array($fond,$contexte,$url_redirect);
124 }
125
126
127 /**
128 * Lister les objets pris en compte dans les urls
129 * c'est a dire suceptibles d'avoir une url propre
130 *
131 * @param bool $preg
132 * permet de definir si la fonction retourne une chaine avec | comme separateur
133 * pour utiliser en preg, ou un array()
134 * @return string/array
135 */
136 function urls_liste_objets($preg = true){
137 static $url_objets = null;
138 if (is_null($url_objets)){
139 $url_objets = array();
140 // recuperer les tables_objets_sql declarees
141 $tables_objets = lister_tables_objets_sql();
142 foreach($tables_objets as $t=>$infos){
143 if ($infos['page']) {
144 $url_objets[] = $infos['type'];
145 $url_objets = array_merge($url_objets,$infos['type_surnoms']);
146 }
147 }
148 $url_objets = pipeline('declarer_url_objets',$url_objets);
149 }
150 if (!$preg) return $url_objets;
151 return implode('|',array_map('preg_quote',$url_objets));
152 }
153
154 /**
155 * Nettoyer une url, en reperant notamment les raccourcis d'entites
156 * comme ?article13, ?rubrique21 ...
157 * et en les traduisant pour completer le contexte fourni en entree
158 *
159 * @param string $url
160 * @param array $contexte
161 * @return array
162 */
163 function nettoyer_url_page($url, $contexte=array())
164 {
165 $url_objets = urls_liste_objets();
166 $raccourci_url_page_html = ',^(?:[^?]*/)?('. $url_objets . ')([0-9]+)(?:\.html)?([?&].*)?$,';
167 $raccourci_url_page_id = ',^(?:[^?]*/)?('. $url_objets .')\.php3?[?]id_\1=([0-9]+)([?&].*)?$,';
168 $raccourci_url_page_spip = ',^(?:[^?]*/)?(?:spip[.]php)?[?]('. $url_objets .')([0-9]+)=?(&.*)?$,';
169
170 if (preg_match($raccourci_url_page_html, $url, $regs)
171 OR preg_match($raccourci_url_page_id, $url, $regs)
172 OR preg_match($raccourci_url_page_spip, $url, $regs)) {
173 $type = objet_type($regs[1]);
174 $_id = id_table_objet($type);
175 $contexte[$_id] = $regs[2];
176 $suite = $regs[3];
177 return array($contexte, $type, null, $type, $suite);
178 }
179 return array();
180 }
181
182 /**
183 * Generer l'url d'un objet dans l'espace prive,
184 * fonction de son etat publie ou non
185 * calcule a partir de la declaration de statut
186 *
187 * @param int $id
188 * @param string $args
189 * @param string $ancre
190 * @param string $statut
191 * @param string $connect
192 * @return string
193 *
194 */
195 function generer_url_ecrire_objet($objet,$id, $args='', $ancre='', $public=null, $connect=''){
196 static $furls = array();
197 if (!isset($furls[$objet])){
198 if (function_exists($f = 'generer_url_ecrire_' . $objet)
199 // ou definie par un plugin
200 OR $f = charger_fonction($f,'urls',true))
201 $furls[$objet] = $f;
202 else
203 $furls[$objet] = '';
204 }
205 if ($furls[$objet])
206 return $furls[$objet]($id, $args, $ancre, $public, $connect);
207 // si pas de flag public fourni
208 // le calculer en fonction de la declaration de statut
209 if (is_null($public) AND !$connect)
210 $public = objet_test_si_publie($objet, $id, $connect);
211 if ($public OR $connect){
212 return generer_url_entite_absolue($id, $objet, $args, $ancre, $connect);
213 }
214 $a = id_table_objet($objet) . "=" . intval($id);
215 if (!function_exists('objet_info'))
216 include_spip('inc/filtres');
217 return generer_url_ecrire(objet_info($objet,'url_voir'), $a . ($args ? "&$args" : '')). ($ancre ? "#$ancre" : '');
218 }
219
220 ?>