diff --git a/ecrire/inc/utils.php b/ecrire/inc/utils.php index ff3c7de7b7add62e29ebec4b4184f7e6c7eb2ef5..c4ecc08bc953bb8ea06b9b0b49886bb114fcd2a5 100644 --- a/ecrire/inc/utils.php +++ b/ecrire/inc/utils.php @@ -746,9 +746,10 @@ function autoriser_sans_cookie($nom) // $entite = surnom de la table SQL (donne acces au nom de cle primaire) // $args = query_string a placer apres cle=$id&.... // $ancre = ancre a mettre a la fin de l'URL a produire -// $prive = vrai s'il faut produire l'URL d'edition, celle de lecture sinon +// $public = produire l'URL publique ou privee (par defaut: selon espace) // $type = fichier dans le repertoire ecrire/urls determinant l'apparence - +// @return string : url codee +// @return string : fonction de decodage // http://doc.spip.org/@generer_url_entite function generer_url_entite($id='', $entite='', $args='', $ancre='', $public=NULL, $type=NULL) { @@ -775,11 +776,12 @@ function generer_url_entite($id='', $entite='', $args='', $ancre='', $public=NUL ? $GLOBALS['meta']['type_urls'] : $GLOBALS['type_urls']; // pour SPIP <2 } + $f = charger_fonction($type, 'urls', true); // si $entite='', on veut la fonction de passage URL ==> id if (!$entite) return $f; // sinon on veut effectuer le passage id ==> URL - $res = !$f ? '' : $f($id, $entite, $args, $ancre); + $res = !$f ? '' : $f(intval($id), $entite, $args, $ancre); } } if ($res) return $res; diff --git a/ecrire/public/assembler.php b/ecrire/public/assembler.php index d3a144630eb59e30e923a9a82f9ea0b5c572df97..bee18cf69a82c84232b7f4c7128cd15878d8a17b 100644 --- a/ecrire/public/assembler.php +++ b/ecrire/public/assembler.php @@ -75,18 +75,35 @@ function assembler($fond, $connect='') { $contexte = $page['contexte']; } // ATTENTION, gestion des URLs transformee par le htaccess + // $renommer = 'urls_propres_dist'; + // renvoie array($contexte, $fond, $url_redirect) + // Compat ascendante si le retour est null: // 1. $contexte est global car cette fonction le modifie. // 2. $fond est passe par reference, pour la meme raison - // Bref, les URL dites propres ont une implementation sale. - // Interdit de nettoyer, faut assumer l'histoire. // et calculer la page else { $renommer = generer_url_entite(); - if ($renommer) - $renommer(nettoyer_uri(), $fond); + if ($renommer) { + $url = nettoyer_uri(); + $a = $renommer($url, $fond); + if (is_array($a)) { + list($ncontexte, $nfond, $url_redirect) = $a; + if (isset($url_redirect) + AND $url !== $url_redirect) { + spip_log("Redirige $url vers $url_redirect"); + include_spip('inc/headers'); + http_status(301); + redirige_par_entete($url_redirect); + } + if (isset($nfond)) + $fond = $nfond; + if (isset($ncontexte)) + $contexte = $ncontexte; + } + } elseif (function_exists('recuperer_parametres_url')) // compatibilite <= 1.9.2 - recuperer_parametres_url($fond, nettoyer_uri()); + recuperer_parametres_url($fond, nettoyer_uri()); $parametrer = charger_fonction('parametrer', 'public'); $page = $parametrer($fond, $GLOBALS['contexte'], $chemin_cache, $connect); diff --git a/ecrire/urls/arbo.php b/ecrire/urls/arbo.php index e4135fa3c25b11221918023db232963073deb41a..4a35a5462be3bdd5c22ea0547460523d0e9422b6 100644 --- a/ecrire/urls/arbo.php +++ b/ecrire/urls/arbo.php @@ -403,10 +403,9 @@ function _generer_url_arbo($type, $id, $args='', $ancre='') { } +// @return array([contexte],[fond],[url_redirect]) : url decodee // http://doc.spip.org/@urls_arbo_dist -function urls_arbo_dist($i, &$entite, $args='', $ancre='') { - global $contexte; - +function urls_arbo_dist($i, $entite, $args='', $ancre='') { if (is_numeric($i)) return _generer_url_arbo($entite, $i, $args, $ancre); @@ -415,41 +414,33 @@ function urls_arbo_dist($i, &$entite, $args='', $ancre='') { $entite = 'type_urls'; } + $contexte = $GLOBALS['contexte']; // recuperer aussi les &debut_xx $url = $i; $id_objet = $type = 0; + $url_redirect = null; // Migration depuis anciennes URLs ? - if ( - // traiter les injections du type domaine.org/spip.php/cestnimportequoi/ou/encore/plus/rubrique23 - $GLOBALS['profondeur_url']<=0 - AND $_SERVER['REQUEST_METHOD'] != 'POST') { + // traiter les injections domain.tld/spip.php/n/importe/quoi/rubrique23 + if ($GLOBALS['profondeur_url']<=0 + AND $_SERVER['REQUEST_METHOD'] != 'POST') { + // Decoder l'url html, page ou standard if (preg_match( - ',(^|/)(article|breve|rubrique|mot|auteur|site)(\.php3?|[0-9]+(\.html)?)' - .'([?&].*)?$,', $url, $regs) - ) { - $type = $regs[2]; - $id_table_objet = id_table_objet($type); - $id_objet = intval(_request($id_table_objet)); - } - - /* Compatibilite urls-page */ - else if (preg_match( - ',[?/&](article|breve|rubrique|mot|auteur|site)[=]?([0-9]+),', + ',(^|id_|[?])(article|breve|rubrique|mot|auteur|site|syndic)=?(\d+),iS', $url, $regs)) { - $type = $regs[1]; - $id_objet = $regs[2]; + $type = preg_replace(',s$,', '', table_objet($regs[2])); + $_id = id_table_objet($regs[2]); + $id_objet = $regs[3]; } } if ($id_objet) { $url_propre = generer_url_entite($id_objet, $type, $args, $ancre); + $contexte = array($_id => $id_objet); if (strlen($url_propre) AND !strstr($url,$url_propre)) { - include_spip('inc/headers'); - http_status(301); - // recuperer les arguments supplementaires (&debut_xxx=...) $reste = preg_replace('/^&/','?', preg_replace("/[?&]$id_table_objet=$id_objet/",'',$regs[5])); - redirige_par_entete("$url_propre$reste"); + $url_redirect = "$url_propre$reste"; + return array($contexte, $type, $url_redirect); } } /* Fin compatibilite anciennes urls */ @@ -501,28 +492,21 @@ function urls_arbo_dist($i, &$entite, $args='', $ancre='') { // Compatibilite avec les anciens marqueurs d'URL propres // Tester l'entree telle quelle (avec 'url_libre' des sites ont pu avoir des entrees avec marqueurs dans la table spip_urls) if (is_null($type) - OR !$row=sql_fetsel('id_objet, type, date', 'spip_urls',array('url='.sql_quote("$typesyn/$url_propre")))) { - if (!is_null($type)) + OR !$row=sql_fetsel('id_objet, type, date', 'spip_urls',array('url='.sql_quote("$typesyn/$url_propre")))) { + if (!is_null($type)) array_push($url_arbo,$type); $row = sql_fetsel('id_objet, type, date', 'spip_urls',array('url='.sql_quote($url_propre))); } if ($row) { $type = $row['type']; - - // Redirection 301 si l'url est vieux - /*if ($recent = sql_fetsel('url, date', 'spip_urls', - 'type='.sql_quote($row['type']).' AND id_objet='.sql_quote($row['id_objet']) - .' AND date>'.sql_quote($row['date']), '', 'date DESC', 1)) { - spip_log('Redirige '.$url_propre.' vers '.$recent['url']); - include_spip('inc/headers'); - redirige_par_entete($recent['url']); - }*/ - $col_id = id_table_objet($type); + $contexte[$col_id] = $row['id_objet']; + $entite = $row['type']; + if (!isset($contexte[$col_id])) // n'affecter que la premiere fois un parent de type id_rubrique $contexte[$col_id] = $row['id_objet']; - if (!$entite - OR !in_array($type,$types_parents)) + if (!$entite + OR !in_array($type,$types_parents)) $entite = $type; if ($p = url_arbo_parent($type)) @@ -532,18 +516,16 @@ function urls_arbo_dist($i, &$entite, $args='', $ancre='') { // un segment est inconnu if ($entite=='type_urls') { // on genere une 404 comme il faut si on ne sait pas ou aller - include_spip('inc/headers'); - http_status('404'); - $entite = '404'; + return array(array(),'404'); } - return; + return; // ? } } // gerer le retour depuis des urls propres if ($entite=='type_urls' AND $GLOBALS['profondeur_url']<=0){ $urls_anciennes = charger_fonction('propres','urls'); - $urls_anciennes($url_propre,$entite); + return $urls_anciennes($url_propre,$entite); } } if ($entite=='type_urls') { @@ -555,6 +537,8 @@ function urls_arbo_dist($i, &$entite, $args='', $ancre='') { } } define('_SET_HTML_BASE',1); + + return array($contexte, $entite); } ?> diff --git a/ecrire/urls/html.php b/ecrire/urls/html.php index 64239a9d2a6fdfadfabce7b0854c08e96e45f1f6..3a3bc28edf56e11cc507cb34c1cac051ba9b8714 100644 --- a/ecrire/urls/html.php +++ b/ecrire/urls/html.php @@ -51,18 +51,28 @@ function _generer_url_html($type, $id, $args='', $ancre='') { // retrouver les parametres d'une URL dite "html" // http://doc.spip.org/@urls_html_dist -function urls_html_dist($i, &$entite, $args='', $ancre='') { - global $contexte; +function urls_html_dist($i, $entite, $args='', $ancre='') { + $contexte = $GLOBALS['contexte']; // recuperer aussi les &debut_xx if (is_numeric($i)) return _generer_url_html($entite, $i, $args, $ancre); // traiter les injections du type domaine.org/spip.php/cestnimportequoi/ou/encore/plus/rubrique23 if ($GLOBALS['profondeur_url']>0 AND $entite=='sommaire'){ - $entite = '404'; + return array(array(),'404'); } $url = $i; + // Decoder l'url html, page ou standard + if (preg_match( + ',(^|id_|[?])(article|breve|rubrique|mot|auteur|site|syndic)=?(\d+),iS', + $url, $regs)) { + $type = preg_replace(',s$,', '', table_objet($regs[2])); + $_id = id_table_objet($regs[2]); + $contexte[$_id] = $id = $regs[3]; + return array($contexte, $type); + } + /* * Le bloc qui suit sert a faciliter les transitions depuis * le mode 'urls-propres' vers les modes 'urls-standard' et 'url-html' @@ -71,17 +81,20 @@ function urls_html_dist($i, &$entite, $args='', $ancre='') { */ // Si on est revenu en mode html, mais c'est une ancienne url_propre // on ne redirige pas, on assume le nouveau contexte (si possible) - $url_propre = isset($_SERVER['REDIRECT_url_propre']) ? - $_SERVER['REDIRECT_url_propre'] : - (isset($_ENV['url_propre']) ? - $_ENV['url_propre'] : - ''); - if ($url_propre AND preg_match(',^(article|breve|rubrique|mot|auteur|site|type_urls|404)$,', $entite)) { + $url_propre = isset($url) + ? $url + : (isset($_SERVER['REDIRECT_url_propre']) + ? $_SERVER['REDIRECT_url_propre'] + : (isset($_ENV['url_propre']) + ? $_ENV['url_propre'] + : '' + )); + if ($url_propre) { if ($GLOBALS['profondeur_url']<=0) $urls_anciennes = charger_fonction('propres','urls'); else $urls_anciennes = charger_fonction('arbo','urls'); - $urls_anciennes($url_propre,$entite); + return $urls_anciennes($url_propre,$entite); } /* Fin du bloc compatibilite url-propres */ } diff --git a/ecrire/urls/page.php b/ecrire/urls/page.php index 9c46b2ca44edfc441fc4b67c8bdc844fb95206b6..0575f2a873f3ef291edea34344ae57eb349dd0a6 100644 --- a/ecrire/urls/page.php +++ b/ecrire/urls/page.php @@ -47,69 +47,51 @@ function _generer_url_page($type,$id, $args='', $ancre='') { // http://doc.spip.org/@urls_page_dist function urls_page_dist($i, &$entite, $args='', $ancre='') { - global $contexte; + $contexte = $GLOBALS['contexte']; // recuperer aussi les &debut_xx if (is_numeric($i)) return _generer_url_page($entite, $i, $args, $ancre); - $url = $i; // traiter les injections du type domaine.org/spip.php/cestnimportequoi/ou/encore/plus/rubrique23 if ($GLOBALS['profondeur_url']>0 AND $entite=='sommaire'){ - $entite = '404'; + return array(array(),'404'); } + $url = $i; - // Ce bloc gere les urls page et la compatibilite avec les "urls standard" - if ($entite=='sommaire'){ - if (preg_match( - ',^[^?]*[?/](article|rubrique|breve|mot|site|auteur)(?:\.php3?)?.*?([0-9]+),', - $url, $regs)) { - $entite = $regs[1]; - if ($regs[1] == 'site') { - if (!isset($contexte['id_syndic'])) - $contexte['id_syndic'] = $regs[2]; - } else { - if (!isset($contexte['id_'.$entite])) - $contexte['id_'.$entite] = $regs[2]; - } - - return; - } - /* Compatibilite urls-page avec formulaire en get !!! */ - else if (preg_match( - ',[?/&](article|breve|rubrique|mot|auteur|site)[=]?([0-9]+),', - $url, $regs)) { - $entite = $regs[1]; - if ($regs[1] == 'site') { - if (!isset($contexte['id_syndic'])) - $contexte['id_syndic'] = $regs[2]; - } else { - if (!isset($contexte['id_'.$entite])) - $contexte['id_'.$entite] = $regs[2]; - } - return; - } - /* Fin compatibilite urls-page */ + // Decoder l'url html, page ou standard + if (preg_match( + ',(^|id_|[?])(article|breve|rubrique|mot|auteur|site|syndic)=?(\d+),iS', + $url, $regs)) { + $type = preg_replace(',s$,', '', table_objet($regs[2])); + $_id = id_table_objet($regs[2]); + $contexte[$_id] = $id = $regs[3]; + return array($contexte, $type); } - /* * Le bloc qui suit sert a faciliter les transitions depuis - * le mode 'urls-propres' vers les modes 'urls-standard/page' et 'url-html' + * le mode 'urls-propres' vers les modes 'urls-standard' et 'url-html' * Il est inutile de le recopier si vous personnalisez vos URLs * et votre .htaccess */ - // Si on est revenu en mode page, mais c'est une ancienne url_propre + // Si on est revenu en mode html, mais c'est une ancienne url_propre // on ne redirige pas, on assume le nouveau contexte (si possible) - if ( - (isset($_SERVER['REDIRECT_url_propre']) AND $url_propre = $_SERVER['REDIRECT_url_propre']) - OR (isset($_ENV['url_propre']) AND $url_propre = $_ENV['url_propre']) - AND preg_match(',^(article|breve|rubrique|mot|auteur|site|type_urls|404)$,', $entite)) { + $url_propre = isset($url) + ? $url + : (isset($_SERVER['REDIRECT_url_propre']) + ? $_SERVER['REDIRECT_url_propre'] + : (isset($_ENV['url_propre']) + ? $_ENV['url_propre'] + : '' + )); + if ($url_propre) { if ($GLOBALS['profondeur_url']<=0) $urls_anciennes = charger_fonction('propres','urls'); else $urls_anciennes = charger_fonction('arbo','urls'); - $urls_anciennes($url_propre,$entite); + return $urls_anciennes($url_propre,$entite); } /* Fin du bloc compatibilite url-propres */ } + ?> diff --git a/ecrire/urls/propres.php b/ecrire/urls/propres.php index 0f9880ce95780dd3bbfd7fea2a954ac0f9d842e2..d17da1c758e5fcc36f999222933d2fb0224f0c57 100644 --- a/ecrire/urls/propres.php +++ b/ecrire/urls/propres.php @@ -321,48 +321,55 @@ function _generer_url_propre($type, $id, $args='', $ancre='') { // retrouve le fond et les parametres d'une URL propre // ou produit une URL propre si on donne un parametre +// @return array([contexte],[fond],[url_redirect]) : url decodee // http://doc.spip.org/@urls_propres_dist -function urls_propres_dist($i, &$entite, $args='', $ancre='') { - global $contexte; +function urls_propres_dist($i, $entite, $args='', $ancre='') { if (is_numeric($i)) return _generer_url_propre($entite, $i, $args, $ancre); $url = $i; $id_objet = $type = 0; + $url_redirect = null; + $contexte = $GLOBALS['contexte']; // recuperer aussi les &debut_xx // Migration depuis anciennes URLs ? - if ( - // traiter les injections du type domaine.org/spip.php/cestnimportequoi/ou/encore/plus/rubrique23 - $GLOBALS['profondeur_url']<=0 - AND $_SERVER['REQUEST_METHOD'] != 'POST') { + // traiter les injections domain.tld/spip.php/n/importe/quoi/rubrique23 + if ($GLOBALS['profondeur_url']<=0 + AND $_SERVER['REQUEST_METHOD'] != 'POST') { + // Decoder l'url html, page ou standard if (preg_match( - ',(^|/)(article|breve|rubrique|mot|auteur|site)(\.php3?|[0-9]+(\.html)?)' - .'([?&].*)?$,', $url, $regs) - ) { - $type = $regs[2]; - $id_table_objet = id_table_objet($type); - $id_objet = intval(_request($id_table_objet)); - } - - /* Compatibilite urls-page */ - else if (preg_match( - ',[?/&](article|breve|rubrique|mot|auteur|site)[=]?([0-9]+),', + ',(^|id_|[?])(article|breve|rubrique|mot|auteur|site|syndic)=?(\d+),iS', $url, $regs)) { - $type = $regs[1]; - $id_objet = $regs[2]; + $type = preg_replace(',s$,', '', table_objet($regs[2])); + $_id = id_table_objet($regs[2]); + $id_objet = $regs[3]; } } if ($id_objet) { $url_propre = generer_url_entite($id_objet, $type, $args, $ancre); + $contexte = array($_id => $id_objet); + if (strlen($url_propre) + AND !strstr($url,$url_propre)) { + $reste = preg_replace('/^&/','?', + preg_replace("/[?&]$id_table_objet=$id_objet/",'',$regs[5])); + $url_redirect = "$url_propre$reste"; + return array($contexte, $type, $url_redirect); + } + } + /* Fin compatibilite anciennes urls */ + + if ($id_objet) { + $url_propre = generer_url_entite($id_objet, $type, $args, $ancre); + $contexte = array($id_table_objet => $id_objet); if (strlen($url_propre) AND !strstr($url,$url_propre)) { include_spip('inc/headers'); - http_status(301); // recuperer les arguments supplementaires (&debut_xxx=...) $reste = preg_replace('/^&/','?', preg_replace("/[?&]$id_table_objet=$id_objet/",'',$regs[5])); - redirige_par_entete("$url_propre$reste"); + $url_redirect = "$url_propre$reste"; + return array($contexte, $type, $url_redirect); } } /* Fin compatibilite anciennes urls */ @@ -394,8 +401,7 @@ function urls_propres_dist($i, &$entite, $args='', $ancre='') { // mais si url arbo ne trouve pas, on veut une 404 par securite if ($GLOBALS['profondeur_url']>0){ $urls_anciennes = charger_fonction('arbo','urls'); - $urls_anciennes($url_propre,$entite); - return; + return $urls_anciennes($url_propre,$entite); } include_spip('base/abstract_sql'); // chercher dans la table des URLS @@ -414,8 +420,11 @@ function urls_propres_dist($i, &$entite, $args='', $ancre='') { if ($row) { $type = $row['type']; + $col_id = id_table_objet($type); + $contexte[$col_id] = $row['id_objet']; + $entite = $row['type']; - // Redirection 301 si l'url est vieux + // Si l'url est vieux, donner le nouveau if ($recent = sql_fetsel('url, date', 'spip_urls', 'type='.sql_quote($row['type']).' AND id_objet='.sql_quote($row['id_objet']) .' AND date>'.sql_quote($row['date']), '', 'date DESC', 1)) { @@ -426,15 +435,8 @@ function urls_propres_dist($i, &$entite, $args='', $ancre='') { $marqueur2 = $marqueur[$type.'2']; // fin '-+' } else $marqueur1 = $marqueur2 = ''; - $recent = $marqueur1 . $recent['url'] . $marqueur2; - spip_log('Redirige '.$url_propre.' vers '.$recent); - include_spip('inc/headers'); - redirige_par_entete($recent); + $url_redirect = $marqueur1 . $recent['url'] . $marqueur2; } - - $col_id = id_table_objet($type); - $contexte[$col_id] = $row['id_objet']; - $entite = $row['type']; } if ($entite=='type_urls') { @@ -445,5 +447,8 @@ function urls_propres_dist($i, &$entite, $args='', $ancre='') { $contexte['erreur'] = ''; // qu'afficher ici ? l'url n'existe pas... on ne sait plus dire de quel type d'objet il s'agit } } + + return array($contexte, $entite, $url_redirect); } + ?>