function recuperer_parametres_url(&$fond, $url) { global $contexte; // traiter les injections du type domaine.org/spip.php/cestnimportequoi/ou/encore/plus/rubrique23 if ($GLOBALS['profondeur_url'] > 0 and $fond == 'sommaire') { $fond = '404'; } /* * Le bloc qui suit sert a faciliter les transitions depuis * 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 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'] : ''); include_spip('inc/urls'); $objets = urls_liste_objets(); if ($url_propre and preg_match(",^({$objets}|type_urls|404)\$,", $fond)) { if ($GLOBALS['profondeur_url'] <= 0) { $urls_anciennes = charger_fonction('propres', 'urls'); } else { $urls_anciennes = charger_fonction('arbo', 'urls'); } $p = $urls_anciennes($url_propre, $fond, $contexte); $contexte = $p[0]; } else { if ($GLOBALS['profondeur_url'] <= 0 and preg_match(',[?/&](' . $objets . ')[=]?([0-9]+),', $url, $r)) { $fond = $r[1]; $contexte[id_table_objet($r[1])] = $r[2]; } } /* Fin compatibilite urls-page */ return; }
function nettoyer_url_page($url, $contexte=array()) { $url_objets = urls_liste_objets(); $raccourci_url_page_html = ',^(?:[^?]*/)?('. $url_objets . ')([0-9]+)(?:\.html)?([?&].*)?$,'; $raccourci_url_page_id = ',^(?:[^?]*/)?('. $url_objets .')\.php3?[?]id_\1=([0-9]+)([?&].*)?$,'; $raccourci_url_page_spip = ',^(?:[^?]*/)?(?:spip[.]php)?[?]('. $url_objets .')([0-9]+)(&.*)?$,'; if (preg_match($raccourci_url_page_html, $url, $regs) OR preg_match($raccourci_url_page_id, $url, $regs) OR preg_match($raccourci_url_page_spip, $url, $regs)) { $type = preg_replace(',s$,', '', table_objet($regs[1])); if ($type == 'syndic') $type = 'site'; $_id = id_table_objet($regs[1]); $contexte[$_id] = $regs[2]; $suite = $regs[3]; return array($contexte, $type, null, $type, $suite); } return array(); }
function declarer_url_propre($type, $id_objet) { $trouver_table = charger_fonction('trouver_table', 'base'); $desc = $trouver_table(table_objet($type)); $table = $desc['table']; $champ_titre = $desc['titre'] ? $desc['titre'] : 'titre'; $col_id = @$desc['key']["PRIMARY KEY"]; if (!$col_id) { return false; } // Quand $type ne reference pas une table $id_objet = intval($id_objet); // Recuperer une URL propre correspondant a l'objet. // mais urls a 1 segment uniquement (pas d'urls /) // de preference avec id_parent=0, puis perma, puis par date desc $row = sql_fetsel("U.url, U.date, U.id_parent, U.perma, {$champ_titre}", "{$table} AS O LEFT JOIN spip_urls AS U ON (U.type='{$type}' AND U.id_objet=O.{$col_id})", "O.{$col_id}={$id_objet} AND (U.segments IS NULL OR U.segments=1)", '', 'U.id_parent=0 DESC, U.perma DESC, U.date DESC', 1); // en SQLite le left join retourne du vide si il y a une url mais qui ne correspond pas pour la condition sur le segment // on verifie donc que l'objet existe bien avant de sortir ou de creer une url pour cet objet if (!$row) { $row = sql_fetsel("'' as url, '' as date, 0 as id_parent, 0 as perma, {$champ_titre}", "{$table} AS O", "O.{$col_id}={$id_objet}"); } if (!$row) { return ""; } # Quand $id_objet n'est pas un numero connu $url_propre = $row['url']; // si url_propre connue mais avec id_parent non nul, essayer de reinserer tel quel avec id_parent=0 if ($url_propre and $row['id_parent']) { include_spip('action/editer_url'); $set = array('url' => $url_propre, 'type' => $type, 'id_objet' => $id_objet, 'perma' => $row['perma']); // si on arrive pas a reinserer tel quel, on annule url_propre pour forcer un recalcul d'url if (!url_insert($set, false, _url_propres_sep_id)) { $url_propre = ""; } else { $url_propre = $row['url'] = $set['url']; } } // Se contenter de cette URL si elle existe ; // sauf si on invoque par "voir en ligne" avec droit de modifier l'url // l'autorisation est verifiee apres avoir calcule la nouvelle url propre // car si elle ne change pas, cela ne sert a rien de verifier les autorisations // qui requetent en base $modifier_url = (defined('_VAR_URLS') and _VAR_URLS and !$row['perma']); if ($url_propre and !$modifier_url) { return $url_propre; } // Sinon, creer une URL $url = pipeline('propres_creer_chaine_url', array('data' => $url_propre, 'objet' => array_merge($row, array('type' => $type, 'id_objet' => $id_objet)))); // Eviter de tamponner les URLs a l'ancienne (cas d'un article // intitule "auteur2") include_spip('inc/urls'); $objets = urls_liste_objets(); if (preg_match(',^(' . $objets . ')[0-9]+$,', $url, $r) and $r[1] != $type) { $url = $url . _url_propres_sep_id . $id_objet; } // Pas de changement d'url if ($url == $url_propre) { return $url_propre; } // verifier l'autorisation, maintenant qu'on est sur qu'on va agir if ($modifier_url) { include_spip('inc/autoriser'); $modifier_url = autoriser('modifierurl', $type, $id_objet); } // Verifier si l'utilisateur veut effectivement changer l'URL if ($modifier_url and CONFIRMER_MODIFIER_URL and $url_propre and $url != preg_replace('/' . preg_quote(_url_propres_sep_id, '/') . '.*/', '', $url_propre)) { $confirmer = true; } else { $confirmer = false; } if ($confirmer and !_request('ok')) { die("vous changez d'url ? {$url_propre} -> {$url}"); } $set = array('url' => $url, 'type' => $type, 'id_objet' => $id_objet); include_spip('action/editer_url'); if (!url_insert($set, $confirmer, _url_propres_sep_id)) { return $url_propre; } //serveur out ? retourner au mieux return $set['url']; }
/** * Nettoyer une URL, en repérant notamment les raccourcis d'objets * * Repère les entités comme `?article13`, `?rubrique21` ... * les traduisant pour compléter le contexte fourni en entrée * * @param string $url * @param array $contexte * @return array */ function nettoyer_url_page($url, $contexte = array()) { $url_objets = urls_liste_objets(); $raccourci_url_page_html = ',^(?:[^?]*/)?(' . $url_objets . ')([0-9]+)(?:\\.html)?([?&].*)?$,'; $raccourci_url_page_id = ',^(?:[^?]*/)?(' . $url_objets . ')\\.php3?[?]id_\\1=([0-9]+)([?&].*)?$,'; $raccourci_url_page_spip = ',^(?:[^?]*/)?(?:spip[.]php)?[?](' . $url_objets . ')([0-9]+)=?(&.*)?$,'; if (preg_match($raccourci_url_page_html, $url, $regs) or preg_match($raccourci_url_page_id, $url, $regs) or preg_match($raccourci_url_page_spip, $url, $regs)) { $regs = array_pad($regs, 4, null); $type = objet_type($regs[1]); $_id = id_table_objet($type); $contexte[$_id] = $regs[2]; $suite = $regs[3]; return array($contexte, $type, null, $type, $suite); } return array(); }
/** * Retrouver/Calculer l'ensemble des segments d'url d'un objet * * http://doc.spip.org/@declarer_url_arbo * * @param string $type * @param int $id_objet * @return string */ function declarer_url_arbo($type, $id_objet) { static $urls = array(); // utiliser un cache memoire pour aller plus vite if (!is_null($C = Cache())) { return $C; } // Se contenter de cette URL si elle existe ; // sauf si on invoque par "voir en ligne" avec droit de modifier l'url // l'autorisation est verifiee apres avoir calcule la nouvelle url propre // car si elle ne change pas, cela ne sert a rien de verifier les autorisations // qui requetent en base $modifier_url = (defined('_VAR_URLS') and _VAR_URLS); if (!isset($urls[$type][$id_objet]) or $modifier_url) { $r = renseigner_url_arbo($type, $id_objet); // Quand $type ne reference pas une table if ($r === false) { return false; } if (!is_null($r)) { $urls[$type][$id_objet] = $r; } } if (!isset($urls[$type][$id_objet])) { return ""; } # objet inexistant $url_propre = $urls[$type][$id_objet]['url']; // si on a trouve l'url // et que le parent est bon // et (permanente ou pas de demande de modif) if (!is_null($url_propre) and $urls[$type][$id_objet]['id_parent'] == $urls[$type][$id_objet]['parent'] and ($urls[$type][$id_objet]['perma'] or !$modifier_url)) { return declarer_url_arbo_rec($url_propre, $type, isset($urls[$type][$id_objet]['parent']) ? $urls[$type][$id_objet]['parent'] : 0, isset($urls[$type][$id_objet]['type_parent']) ? $urls[$type][$id_objet]['type_parent'] : null); } // Si URL inconnue ou maj forcee sur une url non permanente, recreer une url $url = $url_propre; if (is_null($url_propre) or $modifier_url and !$urls[$type][$id_objet]['perma']) { $url = pipeline('arbo_creer_chaine_url', array('data' => $url_propre, 'objet' => array_merge($urls[$type][$id_objet], array('type' => $type, 'id_objet' => $id_objet)))); // Eviter de tamponner les URLs a l'ancienne (cas d'un article // intitule "auteur2") include_spip('inc/urls'); $objets = urls_liste_objets(); if (preg_match(',^(' . $objets . ')[0-9]*$,', $url, $r) and $r[1] != $type) { $url = $url . _url_arbo_sep_id . $id_objet; } } // Pas de changement d'url ni de parent if ($url == $url_propre and $urls[$type][$id_objet]['id_parent'] == $urls[$type][$id_objet]['parent']) { return declarer_url_arbo_rec($url_propre, $type, $urls[$type][$id_objet]['parent'], $urls[$type][$id_objet]['type_parent']); } // verifier l'autorisation, maintenant qu'on est sur qu'on va agir if ($modifier_url) { include_spip('inc/autoriser'); $modifier_url = autoriser('modifierurl', $type, $id_objet); } // Verifier si l'utilisateur veut effectivement changer l'URL if ($modifier_url and CONFIRMER_MODIFIER_URL and $url_propre and $url != preg_replace('/' . preg_quote(_url_propres_sep_id, '/') . '.*/', '', $url_propre)) { $confirmer = true; } else { $confirmer = false; } if ($confirmer and !_request('ok')) { die("vous changez d'url ? {$url_propre} -> {$url}"); } $set = array('url' => $url, 'type' => $type, 'id_objet' => $id_objet, 'id_parent' => $urls[$type][$id_objet]['parent'], 'perma' => intval($urls[$type][$id_objet]['perma'])); include_spip('action/editer_url'); if (url_insert($set, $confirmer, _url_arbo_sep_id)) { $urls[$type][$id_objet]['url'] = $set['url']; $urls[$type][$id_objet]['id_parent'] = $set['id_parent']; } else { // l'insertion a echoue, //serveur out ? retourner au mieux $urls[$type][$id_objet]['url'] = $url_propre; } return declarer_url_arbo_rec($urls[$type][$id_objet]['url'], $type, $urls[$type][$id_objet]['parent'], $urls[$type][$id_objet]['type_parent']); }
/** * Préparer le contexte d'environnement pour les boutons * * Permettra d'afficher le bouton 'Modifier ce...' s'il y a un * `$id_XXX` défini globalement par `spip_register_globals` * * @note * Attention à l'ordre dans la boucle: * on ne veut pas la rubrique si un autre bouton est possible * * @return array * Tableau de l'environnement calculé **/ function admin_objet() { include_spip('inc/urls'); $env = array(); $trouver_table = charger_fonction('trouver_table', 'base'); $objets = urls_liste_objets(false); $objets = array_diff($objets, array('rubrique')); $objets = array_reverse($objets); array_unshift($objets, 'rubrique'); foreach ($objets as $obj) { $type = $obj; if ($type == objet_type($type, false) and $_id_type = id_table_objet($type) and isset($GLOBALS['contexte'][$_id_type]) and $id = $GLOBALS['contexte'][$_id_type] and !is_array($id) and $id = intval($id)) { $id = sql_getfetsel($_id_type, table_objet_sql($type), "{$_id_type}=" . intval($id)); if ($id) { $env[$_id_type] = $id; $env['objet'] = $type; $env['id_objet'] = $id; $env['voir_' . $obj] = str_replace('&', '&', generer_url_entite($id, $obj, '', '', false)); if ($desc = $trouver_table(table_objet_sql($type)) and isset($desc['field']['id_rubrique']) and $type != 'rubrique') { unset($env['id_rubrique']); unset($env['voir_rubrique']); if (admin_preview($type, $id, $desc)) { $env['preview'] = parametre_url(self(), 'var_mode', 'preview', '&'); } } } } } return $env; }
function declarer_url_arbo($type, $id_objet) { static $urls=array(); // Se contenter de cette URL si elle existe ; // sauf si on invoque par "voir en ligne" avec droit de modifier l'url // l'autorisation est verifiee apres avoir calcule la nouvelle url propre // car si elle ne change pas, cela ne sert a rien de verifier les autorisations // qui requetent en base $modifier_url = $GLOBALS['var_urls']; if (!isset($urls[$type][$id_objet]) OR $modifier_url) { $trouver_table = charger_fonction('trouver_table', 'base'); $desc = $trouver_table(table_objet($type)); $champ_titre = $desc['titre']; $col_id = @$desc['key']["PRIMARY KEY"]; // $type doit designer une table, avec champ indiquant un titre if (!$col_id OR !$champ_titre) return false; $table = $desc['table']; $id_objet = intval($id_objet); // parent $champ_parent = url_arbo_parent($type); $sel_parent = ($champ_parent)?", O.".reset($champ_parent).' as parent':''; // Recuperer une URL propre correspondant a l'objet. $row = sql_fetsel("U.url, U.date, O.$champ_titre $sel_parent", "$table AS O LEFT JOIN spip_urls AS U ON (U.type='$type' AND U.id_objet=O.$col_id)", "O.$col_id=$id_objet", '', 'U.date DESC', 1); if ($row){ $urls[$type][$id_objet] = $row; $urls[$type][$id_objet]['type_parent'] = $champ_parent?end($champ_parent):''; } } if (!isset($urls[$type][$id_objet])) return ""; # objet inexistant $url_propre = $urls[$type][$id_objet]['url']; if (!is_null($url_propre) AND !$modifier_url) return declarer_url_arbo_rec($url_propre,$type, isset($urls[$type][$id_objet]['parent'])?$urls[$type][$id_objet]['parent']:null, isset($urls[$type][$id_objet]['type_parent'])?$urls[$type][$id_objet]['type_parent']:null); // Sinon, creer une URL $url = pipeline('arbo_creer_chaine_url', array( 'data' => $url_propre, // le vieux url_propre 'objet' => array_merge($urls[$type][$id_objet], array('type' => $type, 'id_objet' => $id_objet) ) ) ); // Eviter de tamponner les URLs a l'ancienne (cas d'un article // intitule "auteur2") include_spip('inc/urls'); $objets = urls_liste_objets(); if (preg_match(',^('.$objets.')[0-9]*$,', $url, $r) AND $r[1] != $type) $url = $url._url_arbo_sep_id.$id_objet; // Pas de changement d'url if ($url == $url_propre) return declarer_url_arbo_rec($url_propre,$type,$urls[$type][$id_objet]['parent'],$urls[$type][$id_objet]['type_parent']); // verifier l'autorisation, maintenant qu'on est sur qu'on va agir if ($modifier_url) { include_spip('inc/autoriser'); $modifier_url = autoriser('modifierurl', $type, $id_objet); } // Verifier si l'utilisateur veut effectivement changer l'URL if ($modifier_url AND CONFIRMER_MODIFIER_URL AND $url_propre AND $url != preg_replace('/,.*/', '', $url_propre)) $confirmer = true; else $confirmer = false; if ($confirmer AND !_request('ok')) { die ("vous changez d'url ? $url_propre -> $url"); } $set = array('url' => $url, 'type' => $type, 'id_objet' => $id_objet); include_spip('action/editer_url'); if (url_insert($set,$confirmer,_url_arbo_sep_id)){ $urls[$type][$id_objet]['url'] = $set['url']; } else { // l'insertion a echoue, //serveur out ? retourner au mieux $urls[$type][$id_objet]['url']=$url_propre; } return declarer_url_arbo_rec($urls[$type][$id_objet]['url'],$type,$urls[$type][$id_objet]['parent'],$urls[$type][$id_objet]['type_parent']); }
/** * Calcul de la rubrique associée à la requête * (sélection de squelette spécifique par id_rubrique & lang) * * Êttention, on repète cela à chaque inclusion, * on optimise donc pour ne faire la recherche qu'une fois * par contexte semblable du point de vue des id_xx * * @staticvar array $liste_objets * @param array $contexte * @return array */ function quete_rubrique_fond($contexte) { static $liste_objets = null; static $quete = array(); if (is_null($liste_objets)) { $liste_objets = array(); include_spip('inc/urls'); include_spip('public/quete'); $l = urls_liste_objets(false); // placer la rubrique en tete des objets $l = array_diff($l, array('rubrique')); array_unshift($l, 'rubrique'); foreach ($l as $objet) { $id = id_table_objet($objet); if (!isset($liste_objets[$id])) { $liste_objets[$id] = objet_type($objet, false); } } } $c = array_intersect_key($contexte, $liste_objets); if (!count($c)) { return false; } $c = array_map('intval', $c); $s = serialize($c); if (isset($quete[$s])) { return $quete[$s]; } if (isset($c['id_rubrique']) and $r = $c['id_rubrique']) { unset($c['id_rubrique']); $c = array('id_rubrique' => $r) + $c; } foreach ($c as $_id => $id) { if ($id and $row = quete_parent_lang(table_objet_sql($liste_objets[$_id]), $id)) { $lang = isset($row['lang']) ? $row['lang'] : ''; if ($_id == 'id_rubrique' or isset($row['id_rubrique']) and $id = $row['id_rubrique']) { return $quete[$s] = array($id, $lang); } } } return $quete[$s] = false; }