/** * Mettre a jour les sessions existantes pour un auteur * Quand on modifie une fiche auteur on appelle cette fonction qui va * mettre a jour les fichiers de session de l'auteur en question. * (auteurs identifies seulement) * * Ne concerne que les sessions des auteurs loges (id_auteur connu) * * @param array $auteur * @param array $supprimer_cles * Liste des clés à supprimer des tableaux de sessions */ function actualiser_sessions($auteur, $supprimer_cles = array()) { $id_auteur = isset($auteur['id_auteur']) ? intval($auteur['id_auteur']) : 0; $id_auteur_courant = isset($GLOBALS['visiteur_session']['id_auteur']) ? intval($GLOBALS['visiteur_session']['id_auteur']) : 0; // si l'auteur est celui de la session courante, verifier/creer la session si besoin $fichier_session_courante = ""; if ($id_auteur == $id_auteur_courant) { ajouter_session($auteur); if ($id_auteur) { $fichier_session_courante = fichier_session('alea_ephemere'); } } // si session anonyme on ne fait rien d'autre ici : les sessions anonymes sont non partagees if (!$id_auteur) { return; } // memoriser l'auteur courant (celui qui modifie la fiche) $sauve = $GLOBALS['visiteur_session']; // .. mettre a jour les sessions de l'auteur cible // attention au $ final pour ne pas risquer d'embarquer un .php.jeton temporaire // cree par une ecriture concurente d'une session (fichier atomique temporaire) $sessions = preg_files(_DIR_SESSIONS, '/' . $id_auteur . '_.*\\.php$'); // 1ere passe : lire et fusionner les sessions foreach ($sessions as $session) { $GLOBALS['visiteur_session'] = array(); // a pu etre supprime entre le preg initial et le moment ou l'on arrive la (concurrence) if ($session !== $fichier_session_courante and @file_exists($session)) { include $session; # $GLOBALS['visiteur_session'] est alors l'auteur cible $auteur = array_merge($GLOBALS['visiteur_session'], $auteur); } } // supprimer les eventuelles cles dont on ne veut plus foreach ($supprimer_cles as $cle) { unset($auteur[$cle]); } $auteur_session = preparer_ecriture_session($auteur); // seconde passe : ecrire les sessions qui ne sont pas a jour foreach ($sessions as $session) { $GLOBALS['visiteur_session'] = array(); // a pu etre supprime entre le preg initial et le moment ou l'on arrive la (concurrence) if (@file_exists($session)) { include $session; # $GLOBALS['visiteur_session'] est alors l'auteur cible // est-ce que cette session est a mettre a jour ? if ($auteur_session != $GLOBALS['visiteur_session']) { ecrire_fichier_session($session, $auteur); } } } if ($id_auteur == $id_auteur_courant) { $GLOBALS['visiteur_session'] = $auteur; $GLOBALS['auteur_session'] =& $GLOBALS['visiteur_session']; } else { // restaurer l'auteur courant $GLOBALS['visiteur_session'] = $sauve; } }
/** * Ajouter une donnee dans la session SPIP * http://doc.spip.org/@session_set * * @param string $nom * @param null $val * @return void */ function session_set($nom, $val = null) { if (is_null($val)) { // rien a faire if (!isset($GLOBALS['visiteur_session'][$nom])) { return; } unset($GLOBALS['visiteur_session'][$nom]); } else { // On ajoute la valeur dans la globale $GLOBALS['visiteur_session'][$nom] = $val; } ajouter_session($GLOBALS['visiteur_session']); actualiser_sessions($GLOBALS['visiteur_session']); }
function verifier_session($change=false) { // si pas de cookie, c'est fichu if (!isset($_COOKIE['spip_session'])) return false; // Tester avec alea courant $fichier_session = fichier_session('alea_ephemere', true); if ($fichier_session AND @file_exists($fichier_session)) { include($fichier_session); } else { // Sinon, tester avec alea precedent $fichier_session = fichier_session('alea_ephemere_ancien', true); if (!$fichier_session OR !@file_exists($fichier_session)) return false; // Renouveler la session avec l'alea courant include($fichier_session); spip_unlink($fichier_session); ajouter_session($GLOBALS['visiteur_session']); } // Compatibilite ascendante : auteur_session est visiteur_session si // c'est un auteur SPIP authentifie (tandis qu'un visiteur_session peut // n'etre qu'identifie, sans aucune authentification). if ($GLOBALS['visiteur_session']['id_auteur']) $GLOBALS['auteur_session'] = &$GLOBALS['visiteur_session']; // Si l'adresse IP change, inc/presentation mettra une balise image // avec un URL de rappel demandant a changer le nom de la session. // Seul celui qui a l'IP d'origine est rejoue // ainsi un eventuel voleur de cookie ne pourrait pas deconnecter // sa victime, mais se ferait deconnecter par elle. if (hash_env() != $GLOBALS['visiteur_session']['hash_env']) { if (!$GLOBALS['visiteur_session']['ip_change']) { $GLOBALS['rejoue_session'] = rejouer_session(); $GLOBALS['visiteur_session']['ip_change'] = true; ajouter_session($GLOBALS['visiteur_session']); } else if ($change) { spip_log("session non rejouee, vol de cookie ?"); } } else if ($change) { spip_log("rejoue session $fichier_session ".$_COOKIE['spip_session']); spip_unlink($fichier_session); $GLOBALS['visiteur_session']['ip_change'] = false; unset($_COOKIE['spip_session']); ajouter_session($GLOBALS['visiteur_session']); } return is_numeric($GLOBALS['visiteur_session']['id_auteur'])?$GLOBALS['visiteur_session']['id_auteur']:null; }
/** * Ajouter une donnee dans la session SPIP * http://doc.spip.org/@session_set * * @param string $nom * @param null $val * @return void */ function session_set($nom, $val = null) { // On ajoute la valeur dans la globale $GLOBALS['visiteur_session'][$nom] = $val; ajouter_session($GLOBALS['visiteur_session']); actualiser_sessions($GLOBALS['visiteur_session']); }