2 /***************************************************************************
3 * Copyright (C) 2003-2009 Polytechnique.org *
4 * http://opensource.polytechnique.org/ *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
20 ***************************************************************************/
22 class RegisterModule
extends PLModule
27 'register' => $this->make_hook('register', AUTH_PUBLIC
),
28 'register/end' => $this->make_hook('end', AUTH_PUBLIC
),
32 function handler_register(&$page, $hash = null
)
35 $sub_state = S
::v('sub_state', Array());
36 if (!isset($sub_state['step'])) {
37 $sub_state['step'] = 0;
39 if (!isset($sub_state['backs'])) {
40 $sub_state['backs'] = array();
42 if (Get
::has('back') && Get
::i('back') < $sub_state['step']) {
43 $sub_state['step'] = max(0,Get
::i('back'));
45 unset($state['backs']);
46 $sub_state['backs'][] = $state;
47 if (count($sub_state['backs']) == 3) {
48 $alert .= "Tentative d'inscription très hésitante - ";
54 "SELECT m.uid, u.promo, u.nom, u.prenom, u.matricule, u.naissance_ini, FIND_IN_SET('watch', u.flags)
55 FROM register_marketing AS m
56 INNER JOIN auth_user_md5 AS u ON u.user_id = m.uid
57 WHERE m.hash={?}", $hash);
58 if (list($uid, $promo, $nom, $prenom, $ourmat, $naiss, $watch) = $res->fetchOneRow()) {
59 $sub_state['uid'] = $uid;
60 $sub_state['hash'] = $hash;
61 $sub_state['promo'] = $promo;
62 $sub_state['nom'] = $nom;
63 $sub_state['prenom'] = $prenom;
64 $sub_state['ourmat'] = $ourmat;
65 $sub_state['watch'] = $watch;
66 $sub_state['naissance_ini'] = $naiss;
69 "REPLACE INTO register_mstats (uid,sender,success)
70 SELECT m.uid, m.sender, 0
71 FROM register_marketing AS m
72 WHERE m.hash", $sub_state['hash']);
76 switch ($sub_state['step']) {
78 $wp = new PlWikiPage('Reference.Charte');
80 if (Post
::has('step1')) {
81 $sub_state['step'] = 1;
82 if (isset($sub_state['hash'])) {
83 $sub_state['step'] = 3;
84 $this->load('register.inc.php');
85 create_aliases($sub_state);
91 if (Post
::has('promo')) {
92 $promo = Post
::i('promo');
93 $res = XDB
::query("SELECT COUNT(*)
95 WHERE perms='pending' AND deces = '0000-00-00'
98 if (!$res->fetchOneCell()) {
99 $err = "La promotion saisie est incorrecte ou tous les camarades de cette promotion sont inscrits !";
101 $sub_state['step'] = 2;
102 $sub_state['promo'] = $promo;
103 if ($promo >= 1996 && $promo<2000) {
104 $sub_state['mat'] = ($promo %
100)*10 . '???';
105 } elseif($promo >= 2000) {
106 $sub_state['mat'] = 100 +
($promo %
100) . '???';
114 $this->load('register.inc.php');
115 $sub_state['prenom'] = Post
::v('prenom');
116 $sub_state['nom'] = Post
::v('nom');
117 $sub_state['mat'] = Post
::v('mat');
118 $err = check_new_user($sub_state);
120 if ($err !== true
) { break; }
121 $err = create_aliases($sub_state);
124 $sub_state['step'] = 3;
131 $this->load('register.inc.php');
133 // Validate the email address format and domain.
134 require_once 'emails.inc.php';
135 if (!isvalid_email(Post
::v('email'))) {
136 $err[] = "Le champ 'Email' n'est pas valide.";
137 } elseif (!isvalid_email_redirection(Post
::v('email'))) {
138 $err[] = $sub_state['forlife']." doit renvoyer vers un email existant ".
139 "valide, en particulier, il ne peut pas être renvoyé vers lui-même.";
142 // Validate the birthday format and range.
143 $birth = trim(Env
::v('naissance'));
144 if (!preg_match('@^[0-3]?\d/[01]?\d/(19|20)?\d{2}$@', $birth)) {
145 $err[] = "La 'Date de naissance' n'est pas correcte.";
147 $birth = explode('/', $birth, 3);
148 for ($i = 0; $i < 3; $i++
)
149 $birth[$i] = intval($birth[$i]);
150 if ($birth[2] < 100) $birth[2] +
= 1900;
152 $promo = (int)$sub_state['promo'];
153 if ($year > $promo - 15 ||
$year < $promo - 30) {
154 $err[] = "La 'Date de naissance' n'est pas correcte.";
155 $alert = "Date de naissance incorrecte à l'inscription - ";
156 $sub_state['wrong_naissance'] = $birth;
160 // Validate the password.
161 if (!Post
::v('response2', false
)) {
162 $err[] = "Le mot de passe n'est pas valide.";
165 // Check if the given email is known as dangerous.
166 $res = XDB
::query("SELECT w.state, w.description
167 FROM emails_watch AS w
168 WHERE w.email = {?} AND w.state != 'safe'",
170 $email_banned = false
;
171 if ($res->numRows()) {
172 list($state, $description) = $res->fetchOneRow();
173 $alert .= "Email surveillé proposé à l'inscription - ";
174 $sub_state['email_desc'] = $description;
175 if ($state == 'dangerous') {
176 $email_banned = true
;
179 if ($sub_state['watch']) {
180 $alert .= "Inscription d'un utilisateur surveillé - ";
183 if (($ip_banned = check_ip('unsafe'))) {
188 $err = join('<br />', $err);
190 $sub_state['naissance'] = sprintf("%04d-%02d-%02d",
191 intval($birth[2]), intval($birth[1]), intval($birth[0]));
192 $sub_state['email'] = Post
::v('email');
193 $sub_state['password'] = Post
::v('response2');
195 // Update the current alert if the birthdate is incorrect,
196 // or if the IP address of the user has been banned.
197 if ($sub_state['naissance_ini'] != '0000-00-00' && $sub_state['naissance'] != $sub_state['naissance_ini']) {
198 $alert .= "Date de naissance incorrecte à l'inscription - ";
201 $alert .= "Tentative d'inscription depuis une IP surveillée";
204 // Prevent banned user from actually registering; save the current state for others.
205 if ($email_banned ||
$ip_banned) {
207 $err = "Une erreur s'est produite lors de l'inscription."
208 . " Merci de contacter <a href='mailto:register@{$globals->mail->domain}>"
209 . " register@{$globals->mail->domain}</a>"
210 . " pour nous faire part de cette erreur";
212 $sub_state['step'] = 4;
213 if (count($sub_state['backs']) >= 3) {
214 $alert .= "Fin d'une inscription hésitante";
216 finish_ins($sub_state);
223 $_SESSION['sub_state'] = $sub_state;
224 if (!empty($alert)) {
225 send_warning_mail($alert);
228 $page->changeTpl('register/step'.intval($sub_state['step']).'.tpl');
229 $page->addJsLink('motdepasse.js');
231 $page->trigError($err);
235 function handler_end(&$page, $hash = null
)
238 $_SESSION['sub_state'] = array('step' => 5);
240 // Reject registration requests from unsafe IP addresses (and remove the
241 // registration information from the database, to prevent IP changes).
242 if (check_ip('unsafe')) {
243 send_warning_mail('Une IP surveillée a tenté de finaliser son inscription');
244 XDB
::execute("DELETE FROM register_pending
245 WHERE hash = {?} AND hash != 'INSCRIT'", $hash);
249 require_once('user.func.inc.php');
251 // Retrieve the pre-registration information using the url-provided
252 // authentication token.
255 "SELECT r.uid, r.forlife, r.bestalias, r.mailorg2,
256 r.password, r.email, r.naissance, u.nom, u.prenom,
257 u.promo, FIND_IN_SET('femme', u.flags), u.naissance_ini
258 FROM register_pending AS r
259 INNER JOIN auth_user_md5 AS u ON r.uid = u.user_id
260 WHERE hash = {?} AND hash != 'INSCRIT'", $hash);
262 if (!$hash ||
$res->numRows() == 0) {
263 $page->kill("<p>Cette adresse n'existe pas, ou plus, sur le serveur.</p>
264 <p>Causes probables :</p>
266 <li>Vérifie que tu visites l'adresse du dernier
267 email reçu s'il y en a eu plusieurs.</li>
268 <li>Tu as peut-être mal copié l'adresse reçue par
269 email, vérifie-la à la main.</li>
270 <li>Tu as peut-être attendu trop longtemps pour
271 confirmer. Les pré-inscriptions sont annulées
272 tous les 30 jours.</li>
273 <li>Tu es en fait déjà inscrit.</li>
277 list($uid, $forlife, $bestalias, $mailorg2, $password, $email,
278 $naissance, $nom, $prenom, $promo, $femme, $naiss_ini) = $res->fetchOneRow();
280 // Prepare the template for display.
281 $page->changeTpl('register/end.tpl');
282 $page->addJsLink('do_challenge_response_logged.js');
283 $page->assign('forlife', $forlife);
284 $page->assign('prenom', $prenom);
285 $page->assign('femme', $femme);
287 // Check if the user did enter a valid password; if not (or if none is found),
288 // get her an information page.
289 if (Env
::has('response')) {
290 require_once 'secure_hash.inc.php';
291 $expected_response = hash_encrypt("$forlife:$password:" . S
::v('challenge'));
292 if (Env
::v('response') != $expected_response) {
293 $page->trigError("Mot de passe invalide.");
294 S
::logger($uid)->log('auth_fail', 'bad password (register/end)');
302 // Create the user account.
304 XDB
::execute("UPDATE auth_user_md5
305 SET password = {?}, perms = 'user',
306 date = NOW(), naissance = {?}, date_ins = NOW()
307 WHERE user_id = {?}", $password, $naissance, $uid);
308 XDB
::execute("REPLACE INTO auth_user_quick (user_id) VALUES ({?})", $uid);
309 XDB
::execute("INSERT INTO aliases (id, alias, type)
310 VALUES ({?}, {?}, 'a_vie')", $uid, $forlife);
311 XDB
::execute("INSERT INTO aliases (id, alias, type, flags)
312 VALUES ({?}, {?}, 'alias', 'bestalias')", $uid, $bestalias);
314 XDB
::execute("INSERT INTO aliases (id, alias, type)
315 VALUES ({?}, {?}, 'alias')", $uid, $mailorg2);
318 // Add the registration email address as first and only redirection.
319 require_once('emails.inc.php');
320 $user = User
::getSilent($uid);
321 $redirect = new Redirect($user);
322 $redirect->add_email($email);
324 // Log the registration in the user session.
325 S
::logger($uid)->log('inscription', $email);
326 XDB
::execute("UPDATE register_pending
328 WHERE uid = {?}", $uid);
330 // Congratulate our newly registered user by email.
331 $mymail = new PlMailer('register/inscription.reussie.tpl');
332 $mymail->assign('forlife', $forlife);
333 $mymail->assign('prenom', $prenom);
336 // Index the user, to allow her to appear in searches.
337 require_once('user.func.inc.php');
340 // Notify other users which were watching for her arrival.
341 require_once 'notifs.inc.php';
342 register_watch_op($uid, WATCH_INSCR
);
343 inscription_notifs_base($uid);
345 // Forcibly register the new user on default forums.
346 $promo_forum = 'xorg.promo.x' . $promo;
347 $registered_forums = array('xorg.general', 'xorg.pa.divers', 'xorg.pa.logements', $promo_forum);
348 foreach ($registered_forums as $forum) {
349 XDB
::execute("INSERT INTO forums.abos (fid,uid)
355 // Notify the newsgroup admin of the promotion forum needs be created.
356 if (XDB
::affectedRows() == 0 && $forum == $promo_forum) {
357 $res = XDB
::query("SELECT SUM(perms IN ('admin','user') AND deces = 0), COUNT(*)
359 WHERE promo = {?}", $promo);
360 list($promo_registered_count, $promo_count) = $res->fetchOneRow();
361 if ($promo_registered_count > 0.2 * $promo_count) {
362 $mymail = new PlMailer('admin/forums-promo.mail.tpl');
363 $mymail->assign('promo', $promo);
369 // Update the global registration count stats.
370 $globals->updateNbIns();
372 // Try to start a session (so the user don't have to log in); we will use
373 // the password available in Post:: to authenticate the user.
374 Platal
::session()->start(AUTH_MDP
);
377 // Update collateral data sources, and inform watchers by email.
380 // Email the referrer(s) of this new user.
382 "SELECT sa.alias, IF(s.nom_usage,s.nom_usage,s.nom) AS nom,
383 s.prenom, FIND_IN_SET('femme', s.flags) AS femme,
384 GROUP_CONCAT(m.email SEPARATOR ', ') AS mails, MAX(m.last) AS dateDernier
385 FROM register_marketing AS m
386 INNER JOIN auth_user_md5 AS s ON (m.sender = s.user_id)
387 INNER JOIN aliases AS sa ON (sa.id = m.sender
388 AND FIND_IN_SET('bestalias', sa.flags))
391 ORDER BY dateDernier DESC", $uid);
392 XDB
::execute("UPDATE register_mstats
394 WHERE uid = {?}", $uid);
397 while (list($salias, $snom, $sprenom, $sfemme, $mails, $dateDernier) = $res->next()) {
398 $market[] = " - par $snom $sprenom sur $mails (le plus récemment le $dateDernier)";
399 $mymail = new PlMailer();
400 $mymail->setSubject("$prenom $nom s'est inscrit à Polytechnique.org !");
401 $mymail->setFrom('"Marketing Polytechnique.org" <register@' . $globals->mail
->domain
. '>');
402 $mymail->addTo("\"$sprenom $snom\" <$salias@{$globals->mail->domain}>");
403 $msg = ($sfemme?
'Chère':'Cher')." $sprenom,\n\n"
404 . "Nous t'écrivons pour t'informer que $prenom $nom (X$promo), "
405 . "que tu avais incité".($femme?
'e':'')." à s'inscrire à Polytechnique.org, "
406 . "vient à l'instant de terminer son inscription.\n\n"
407 . "Merci de ta participation active à la reconnaissance de ce site !!!\n\n"
408 . "Bien cordialement,\n"
410 . "L'équipe Polytechnique.org";
411 $mymail->setTxtBody(wordwrap($msg, 72));
415 // Email the plat/al administrators about the registration.
416 if ($globals->register
->notif
) {
417 $mymail = new PlMailer();
418 $mymail->setSubject("Inscription de $prenom $nom (X$promo)");
419 $mymail->setFrom('"Webmaster Polytechnique.org" <web@' . $globals->mail
->domain
. '>');
420 $mymail->addTo($globals->register
->notif
);
421 $mymail->addHeader('Reply-To', $globals->register
->notif
);
422 $msg = "$prenom $nom (X$promo) a terminé son inscription avec les données suivantes :\n"
424 . " - prenom : $prenom\n"
425 . " - promo : $promo\n"
426 . " - naissance : $naissance (date connue : $naiss_ini)\n"
427 . " - forlife : $forlife\n"
428 . " - email : $email\n"
429 . " - sexe : $femme\n"
430 . " - ip : " . S
::logger()->ip
. " (" . S
::logger()->host
. ")\n"
431 . (S
::logger()->proxy_ip ?
" - proxy : " . S
::logger()->proxy_ip
. " (" . S
::logger()->proxy_host
. ")\n" : "")
433 if (count($market) > 0) {
434 $msg .= "Les marketings suivants avaient été effectués :\n"
435 . implode("\n", $market);
437 $msg .= "$prenom $nom n'a jamais reçu d'email de marketing.";
439 $mymail->setTxtBody($msg);
443 // Remove old pending marketing requests for the new user.
444 Marketing
::clear($uid);
446 pl_redirect('profile/edit');
450 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: