3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
6 * Copyright (c) 2001-2017 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
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 \***************************************************************************/
14 * Gestion de l'inscription d'un auteur
16 * @package SPIP\Core\Inscription
18 if (!defined('_ECRIRE_INC_VERSION')) {
24 * Inscrire un nouvel auteur sur la base de son nom et son email
26 * L'email est utilisé pour repérer si il existe déjà ou non
27 * => identifiant par défaut
29 * @param string $statut
30 * @param string $mail_complet
32 * @param array $options
33 * - login : login precalcule
34 * - id : id_rubrique fournit en second arg de #FORMULAIRE_INSCRIPTION
35 * - from : email de l'envoyeur pour l'envoi du mail d'inscription
36 * - force_nouveau : forcer le statut nouveau sur l'auteur inscrit, meme si il existait deja en base
37 * - modele_mail : squelette de mail a utiliser
38 * @return array|string
40 function action_inscrire_auteur_dist($statut, $mail_complet, $nom, $options = array()) {
41 if (!is_array($options)) {
42 $options = array('id' => $options);
45 if (function_exists('test_inscription')) {
46 $f = 'test_inscription';
48 $f = 'test_inscription_dist';
50 $desc = $f($statut, $mail_complet, $nom, $options);
53 if (!is_array($desc)) {
57 include_spip('base/abstract_sql');
58 $res = sql_select("statut, id_auteur, login, email", "spip_auteurs", "email=" . sql_quote($desc['email']));
61 return _T('titre_probleme_technique');
64 $row = sql_fetch($res);
67 if (isset($options['force_nouveau']) and $options['force_nouveau'] == true) {
68 $desc['id_auteur'] = $row['id_auteur'];
69 $desc = inscription_nouveau($desc);
73 } else // s'il n'existe pas deja, creer les identifiants
75 $desc = inscription_nouveau($desc);
79 if (!is_array($desc)) {
84 // generer le mot de passe (ou le refaire si compte inutilise)
85 $desc['pass'] = creer_pass_pour_auteur($desc['id_auteur']);
87 // attribuer un jeton pour confirmation par clic sur un lien
88 $desc['jeton'] = auteur_attribuer_jeton($desc['id_auteur']);
90 // charger de suite cette fonction, pour ses utilitaires
91 $envoyer_inscription = charger_fonction("envoyer_inscription", "");
92 list($sujet, $msg, $from, $head) = $envoyer_inscription($desc, $nom, $statut, $options);
94 $notifications = charger_fonction('notifications', 'inc');
95 notifications_envoyer_mails($mail_complet, $msg, $sujet, $from, $head);
98 $notifications('inscription', $desc['id_auteur'],
99 array('nom' => $desc['nom'], 'email' => $desc['email'])
107 * Contrôler que le nom (qui sert à calculer le login) est plausible
108 * et que l'adresse courriel est valide.
110 * On les normalise au passage (trim etc).
112 * On peut redéfinir cette fonction pour filtrer les adresses mail et les noms,
113 * et donner des infos supplémentaires
115 * @param string $statut
116 * @param string $mail
118 * @param array $options
119 * @return array|string
120 * - array : si ok, tableau avec au minimum email, nom, mode (redac / forum)
121 * - string : si ko, chaîne de langue servant d'argument au filtre `_T` expliquant le refus
124 function test_inscription_dist($statut, $mail, $nom, $options) {
125 include_spip('inc/filtres');
126 if (!$r = email_valide($mail)) {
127 return 'info_email_invalide';
129 $nom = trim(corriger_caracteres($nom));
130 $res = array('email' => $r, 'nom' => $nom, 'prefs' => $statut);
131 if (isset($options['login'])) {
132 $login = trim(corriger_caracteres($options['login']));
133 if ((strlen($login) >= _LOGIN_TROP_COURT
) and (strlen($nom) <= 64)) {
134 $res['login'] = $login;
137 if (!isset($res['login']) and ((strlen($nom) < _LOGIN_TROP_COURT
) or (strlen($nom) > 64))) {
138 return 'ecrire:info_login_trop_court';
146 * On enregistre le demandeur comme 'nouveau', en memorisant le statut final
147 * provisoirement dans le champ prefs, afin de ne pas visualiser les inactifs
148 * A sa premiere connexion il obtiendra son statut final.
151 * @return mixed|string
153 function inscription_nouveau($desc) {
154 if (!isset($desc['login']) or !strlen($desc['login'])) {
155 $desc['login'] = test_login($desc['nom'], $desc['email']);
158 $desc['statut'] = 'nouveau';
159 include_spip('action/editer_auteur');
160 if (isset($desc['id_auteur'])) {
161 $id_auteur = $desc['id_auteur'];
163 $id_auteur = auteur_inserer();
167 return _T('titre_probleme_technique');
170 $desc['lang'] = $GLOBALS['spip_lang'];
172 include_spip('inc/autoriser');
173 // lever l'autorisation pour pouvoir modifier le statut
174 autoriser_exception('modifier', 'auteur', $id_auteur);
175 auteur_modifier($id_auteur, $desc);
176 autoriser_exception('modifier', 'auteur', $id_auteur, false);
178 $desc['id_auteur'] = $id_auteur;
185 * http://code.spip.net/@test_login
188 * @param string $mail
191 function test_login($nom, $mail) {
192 include_spip('inc/charsets');
193 $nom = strtolower(translitteration($nom));
194 $login_base = preg_replace("/[^\w\d_]/", "_", $nom);
196 // il faut eviter que le login soit vraiment trop court
197 if (strlen($login_base) < 3) {
198 $mail = strtolower(translitteration(preg_replace('/@.*/', '', $mail)));
199 $login_base = preg_replace("/[^\w\d]/", "_", $mail);
201 if (strlen($login_base) < 3) {
202 $login_base = 'user';
205 $login = $login_base;
207 for ($i = 1; ; $i++
) {
208 if (!sql_countsel('spip_auteurs', "login='$login'")) {
211 $login = $login_base . $i;
219 * Construction du mail envoyant les identifiants
221 * Fonction redefinissable qui doit retourner un tableau
222 * dont les elements seront les arguments de inc_envoyer_mail
226 * @param string $mode
227 * @param array $options
230 function envoyer_inscription_dist($desc, $nom, $mode, $options = array()) {
232 $contexte = array_merge($desc, $options);
233 $contexte['nom'] = $nom;
234 $contexte['mode'] = $mode;
235 $contexte['url_confirm'] = generer_url_action('confirmer_inscription', '', true, true);
236 $contexte['url_confirm'] = parametre_url($contexte['url_confirm'], 'email', $desc['email']);
237 $contexte['url_confirm'] = parametre_url($contexte['url_confirm'], 'jeton', $desc['jeton']);
239 $modele_mail = 'modeles/mail_inscription';
240 if (isset($options['modele_mail']) and $options['modele_mail']){
241 $modele_mail = $options['modele_mail'];
243 $message = recuperer_fond($modele_mail, $contexte);
244 $from = (isset($options['from']) ?
$options['from'] : null);
247 return array("", $message, $from, $head);
252 * Creer un mot de passe initial aleatoire
254 * @param int $id_auteur
257 function creer_pass_pour_auteur($id_auteur) {
258 include_spip('inc/acces');
259 $pass = creer_pass_aleatoire(8, $id_auteur);
260 include_spip('action/editer_auteur');
261 auteur_instituer($id_auteur, array('pass' => $pass));
267 * Determine le statut d'inscription :
268 * si $statut_tmp fourni, verifie qu'il est autorise
269 * sinon determine le meilleur statut possible et le renvoie
271 * @param string $statut_tmp
275 function tester_statut_inscription($statut_tmp, $id) {
276 include_spip('inc/autoriser');
278 return autoriser('inscrireauteur', $statut_tmp, $id) ?
$statut_tmp : '';
280 autoriser('inscrireauteur', $statut_tmp = "1comite", $id)
281 or autoriser('inscrireauteur', $statut_tmp = "6forum", $id)
291 * Un nouvel inscrit prend son statut definitif a la 1ere connexion.
292 * Le statut a ete memorise dans prefs (cf test_inscription_dist).
293 * On le verifie, car la config a peut-etre change depuis,
294 * et pour compatibilite avec les anciennes versions qui n'utilisaient pas "prefs".
296 * @param array $auteur
299 function confirmer_statut_inscription($auteur) {
301 if ($auteur['statut'] != 'nouveau') {
305 $s = $auteur['prefs'];
306 // securite, au cas ou prefs aurait ete corrompu (ou deja ecrase par un tableau serialize)
307 if (!preg_match(',^\w+$,', $s)) {
310 include_spip('inc/autoriser');
311 if (!autoriser('inscrireauteur', $s)) {
315 include_spip('inc/autoriser');
316 // accorder l'autorisation de modif du statut auteur
317 autoriser_exception('modifier', 'auteur', $auteur['id_auteur']);
318 include_spip('action/editer_auteur');
320 auteur_modifier($auteur['id_auteur'], array('statut' => $s));
321 unset($_COOKIE['spip_session']); // forcer la maj de la session
322 // lever l'autorisation de modif du statut auteur
323 autoriser_exception('modifier', 'auteur', $auteur['id_auteur'], false);
325 // mettre a jour le statut
326 $auteur['statut'] = $s;
333 * Attribuer un jeton temporaire pour un auteur
334 * en assurant l'unicite du jeton
336 * @param int $id_auteur
339 function auteur_attribuer_jeton($id_auteur) {
340 include_spip('inc/acces');
341 // s'assurer de l'unicite du jeton pour le couple (email,cookie)
343 $jeton = creer_uniqid();
344 sql_updateq("spip_auteurs", array("cookie_oubli" => $jeton), "id_auteur=" . intval($id_auteur));
345 } while (sql_countsel("spip_auteurs", "cookie_oubli=" . sql_quote($jeton)) > 1);
351 * Retrouver l'auteur par son jeton
353 * @param string $jeton
356 function auteur_verifier_jeton($jeton) {
357 // refuser un jeton corrompu
358 if (preg_match(',[^0-9a-f.],i', $jeton)) {
362 // on peut tomber sur un jeton compose uniquement de chiffres, il faut forcer le $type pour sql_quote pour eviter de planter
363 $desc = sql_fetsel('*', 'spip_auteurs', "cookie_oubli=" . sql_quote($jeton, $serveur, 'string'));
369 * Effacer le jeton d'un auteur apres utilisation
371 * @param int $id_auteur
374 function auteur_effacer_jeton($id_auteur) {
375 return sql_updateq("spip_auteurs", array("cookie_oubli" => ''), "id_auteur=" . intval($id_auteur));