Output time in UTC format when sending payment requests to CyberPlusPayment. Also...
[platal.git] / modules / xnetgrp.php
index e6099e5..933d6d2 100644 (file)
@@ -38,6 +38,7 @@ class XnetGrpModule extends PLModule
             '%grp/annuaire/csv'    => $this->make_hook('csv',                   AUTH_PASSWD, 'groupmember:groupannu'),
             '%grp/directory/sync'  => $this->make_hook('directory_sync',        AUTH_PASSWD, 'groupadmin'),
             '%grp/directory/unact' => $this->make_hook('non_active',            AUTH_PASSWD, 'groupadmin'),
+            '%grp/directory/awact' => $this->make_hook('awaiting_active',       AUTH_PASSWD, 'groupadmin'),
             '%grp/trombi'          => $this->make_hook('trombi',                AUTH_PASSWD, 'groupannu'),
             '%grp/geoloc'          => $this->make_hook('geoloc',                AUTH_PASSWD, 'groupannu'),
             '%grp/subscribe'       => $this->make_hook('subscribe',             AUTH_PASSWD, 'groups'),
@@ -51,6 +52,7 @@ class XnetGrpModule extends PLModule
             '%grp/member/new/ajax' => $this->make_hook('admin_member_new_ajax', AUTH_PASSWD, 'groups', NO_AUTH),
             '%grp/member/del'      => $this->make_hook('admin_member_del',      AUTH_PASSWD, 'groupadmin'),
             '%grp/member/suggest'  => $this->make_hook('admin_member_suggest',  AUTH_PASSWD, 'groupadmin'),
+            '%grp/member/reg'      => $this->make_hook('admin_member_reg',      AUTH_PASSWD, 'groupadmin'),
 
             '%grp/rss'             => $this->make_token_hook('rss',             AUTH_PUBLIC),
             '%grp/announce/new'    => $this->make_hook('edit_announce',         AUTH_PASSWD, 'groupadmin'),
@@ -192,6 +194,24 @@ class XnetGrpModule extends PLModule
             } else {
                 $site = "";
             }
+
+            $notify_all = (Post::v('notify_all') ? true : false);
+            if (!$notify_all) {
+                $to_notify = array();
+                $uf = New UserFilter(New UFC_Group($globals->asso('id'), true));
+                $uids = $uf->getIds();
+                foreach ($uids as $uid) {
+                    if (Post::b('to_notify_' . $uid)) {
+                        $to_notify[] = $uid;
+                    }
+                }
+                if (count($to_notify) == 0) {
+                    $notify_all = true;
+                    $page->trigWarning("Aucun animateur n'ayant été selectionné pour recevoir les demandes d'inscriptions, tous le seront.");
+                }
+            }
+            $flags->addFlag('notify_all', $notify_all);
+
             if (S::admin()) {
                 $page->assign('super', true);
 
@@ -300,8 +320,25 @@ class XnetGrpModule extends PLModule
                 }
             }
 
+            XDB::execute("UPDATE  group_members
+                             SET  flags = ''
+                           WHERE  asso_id = {?}",
+                         $globals->asso('id'));
+            if (!$notify_all) {
+                XDB::execute("UPDATE  group_members
+                                 SET  flags = 'notify'
+                               WHERE  asso_id = {?} AND uid IN {?}",
+                             $globals->asso('id'), $to_notify);
+            }
+
             pl_redirect('../' . Post::v('diminutif', $globals->asso('diminutif')) . '/edit');
         }
+
+        $uf = New UserFilter(New UFC_Group($globals->asso('id'), true, UFC_Group::NOTIFIED));
+        $page->assign('notified', $uf->getUsers());
+        $uf = New UserFilter(New UFC_Group($globals->asso('id'), true, UFC_Group::UNNOTIFIED));
+        $page->assign('unnotified', $uf->getUsers());
+
         $page->assign('error', $error);
         $page->assign('cat', $globals->asso('cat'));
         $page->assign('dom', $globals->asso('dom'));
@@ -309,6 +346,7 @@ class XnetGrpModule extends PLModule
         $page->assign('inscriptible', $globals->asso('inscriptible'));
         $page->assign('pub', $globals->asso('pub'));
         $page->assign('notif_unsub', $globals->asso('notif_unsub'));
+        $page->assign('notify_all', $globals->asso('notify_all'));
     }
 
     function handler_mail($page)
@@ -374,6 +412,7 @@ class XnetGrpModule extends PLModule
         $view = new UserSet(new UFC_Group($globals->asso('id'), $admins));
         $view->addMod('groupmember', 'Annuaire');
         $view->addMod('trombi', 'Trombinoscope');
+        $view->addMod('map', 'Planisphère');
         $view->apply('annuaire', $page, $action);
         $page->assign('only_admin', $admins);
         $page->changeTpl('xnetgrp/annuaire.tpl');
@@ -415,9 +454,15 @@ class XnetGrpModule extends PLModule
             $filename = $globals->asso('diminutif') . '.csv';
         }
         $users = $globals->asso()->getMembersFilter(null, new UFO_Name())->getUsers();
-        pl_cached_content_headers('text/x-csv', 1);
-        $page->changeTpl('xnetgrp/annuaire-csv.tpl', NO_SKIN);
-        $page->assign('users', $users);
+        pl_cached_content_headers('text/x-csv', 'iso-8859-1', 1);
+
+        echo utf8_decode("Nom;Prénom;Sexe;Promotion;Commentaire\n");
+        foreach ($users as $user) {
+            $line = $user->lastName() . ';' . $user->firstName() . ';' . ($user->isFemale() ? 'F' : 'M')
+                  . ';' . $user->promo() . ';' . strtr($user->group_comm, ';', ',');
+            echo utf8_decode($line) . "\n";
+        }
+        exit();
     }
 
     function handler_directory_sync($page)
@@ -471,20 +516,22 @@ class XnetGrpModule extends PLModule
                     continue;
                 }
 
+                require_once 'name.func.inc.php';
                 $parts = explode('.', $local_part);
                 if (count($parts) == 1) {
-                    $lastname = $display_name = $full_name = $directory_name = ucfirst($local_part);
+                    $lastname = $display_name = capitalize_name($mbox);
                     $firstname = '';
                 } else {
-                    $firstname = ucfirst($parts[0]);
-                    $lastname = ucwords(implode(' ', array_slice($parts, 1)));
-                    $display_name = $firstname;
-                    $full_name = $firstname . ' ' . $lastname;
-                    $directory_name = strtoupper($lastname) . ' ' . $firstname;
+                    $display_name = $firstname = capitalize_name($parts[0]);
+                    $lastname = capitalize_name(implode(' ', array_slice($parts, 1)));
                 }
-                XDB::execute('INSERT INTO  accounts (hruid, display_name, full_name, directory_name, firstname, lastname, email, type, state)
-                                   VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?}, \'xnet\', \'disabled\')',
-                             $hruid, $display_name, $full_name, $directory_name, $firstname, $lastname, $email);
+                $full_name = build_full_name($firstname, $lastname);
+                $directory_name = build_directory_name($firstname, $lastname);
+                $sort_name = build_sort_name($firstname, $lastname);
+                XDB::execute('INSERT INTO  accounts (hruid, display_name, full_name, directory_name, sort_name,
+                                                     firstname, lastname, email, type, state)
+                                   VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, \'xnet\', \'disabled\')',
+                             $hruid, $display_name, $full_name, $directory_name, $sort_name, $firstname, $lastname, $email);
                 $uid = XDB::insertId();
                 XDB::execute('INSERT INTO  group_members (asso_id, uid)
                                    VALUES  ({?}, {?})',
@@ -570,8 +617,7 @@ class XnetGrpModule extends PLModule
             $uids_to_enable = array_intersect(array_keys(Post::v('enable_accounts')), $uids);
 
             $user = S::user();
-            $group = Platal::globals()->asso('nom');
-            $request = new BulkAccountsReq($user, $uids_to_enable, $group);
+            $request = new BulkAccountsReq($user, $uids_to_enable, $globals->asso('nom'), $globals->asso('diminutif'));
             $request->submit();
             $page->trigSuccess('Un email va bientôt être envoyé aux personnes sélectionnées pour l\'activation de leur compte.');
 
@@ -586,6 +632,68 @@ class XnetGrpModule extends PLModule
         $page->assign('users', $users);
     }
 
+    private function again($uid)
+    {
+        $data = XDB::fetchOneAssoc('SELECT  hash, group_name, sender_name, email
+                                      FROM  register_pending_xnet
+                                     WHERE  uid = {?}',
+                                   $uid);
+        XDB::execute('UPDATE  register_pending_xnet
+                         SET  last_date = NOW()
+                       WHERE  uid = {?}',
+                     $uid);
+
+        $mailer = new PlMailer('xnet/account.mail.tpl');
+        $mailer->addCc('validation+xnet_account@polytechnique.org');
+        $mailer->setTo($data['email']);
+        $mailer->assign('hash', $data['hash']);
+        $mailer->assign('email', $data['email']);
+        $mailer->assign('group', $data['group_name']);
+        $mailer->assign('sender_name', $data['sender_name']);
+        $mailer->assign('again', true);
+        $mailer->assign('baseurl', Platal::globals()->xnet->xorg_baseurl);
+        $mailer->send();
+    }
+
+    function handler_awaiting_active($page)
+    {
+        global $globals;
+        $page->changeTpl('xnetgrp/awaiting_active.tpl');
+
+        XDB::execute('DELETE FROM  register_pending_xnet
+                            WHERE  DATE_SUB(NOW(), INTERVAL 1 MONTH) > date');
+
+        $uids = XDB::fetchColumn('SELECT  g.uid
+                                    FROM  group_members         AS g
+                              INNER JOIN  accounts              AS a ON (a.uid = g.uid)
+                              INNER JOIN  register_pending_xnet AS p ON (p.uid = g.uid)
+                                   WHERE  a.uid = g.uid AND g.asso_id = {?} AND a.type = \'xnet\' AND a.state = \'pending\'',
+                                 $globals->asso('id'));
+
+        if (Post::has('again')) {
+            S::assert_xsrf_token();
+
+            $uids_to_again = array_intersect(array_keys(Post::v('again')), $uids);
+            foreach ($uids_to_again as $uid) {
+                $this->again($uid);
+            }
+            $page->trigSuccess('Relances effectuées avec succès.');
+        }
+
+        $registration_date = XDB::fetchAllAssoc('uid', 'SELECT  uid, date
+                                                          FROM  register_pending_xnet
+                                                         WHERE  uid IN {?}', $uids);
+        $last_date = XDB::fetchAllAssoc('uid', 'SELECT  uid, last_date
+                                                  FROM  register_pending_xnet
+                                                 WHERE  uid IN {?}', $uids);
+
+        $users = User::getBulkUsersWithUIDs($uids);
+        $page->assign('users', $users);
+        $page->assign('registration_date', $registration_date);
+        $page->assign('last_date', $last_date);
+
+    }
+
     private function removeSubscriptionRequest($uid)
     {
         global $globals;
@@ -700,8 +808,7 @@ class XnetGrpModule extends PLModule
             XDB::execute('DELETE FROM  group_former_members
                                 WHERE  uid = {?} AND asso_id = {?}',
                          S::i('uid'), $globals->asso('id'));
-            $uf = New UserFilter(New UFC_Group($globals->asso('id'), true));
-            $admins = $uf->iterUsers();
+            $admins = $globals->asso()->iterToNotify();
             $admin = $admins->next();
             $to = $admin->bestEmail();
             while ($admin = $admins->next()) {
@@ -838,6 +945,7 @@ class XnetGrpModule extends PLModule
         global $globals;
 
         $page->changeTpl('xnetgrp/membres-add.tpl');
+        $page->addJsLink('xnet_members.js');
 
         if (is_null($email)) {
             return;
@@ -850,20 +958,10 @@ class XnetGrpModule extends PLModule
         // + (the data) => %2B (in the url) => + (first decoding) => ' ' (second decoding)
         // Since there can be no spaces in emails, we can fix this with :
         $email = str_replace(' ', '+', $email);
+        $is_valid_email = isvalid_email($email);
 
-        // Finds or creates account: first cases are for users with an account.
-        if (!User::isForeignEmailAddress($email)) {
-            // Standard account
-            $user = User::getSilent($email);
-        } else if (!isvalid_email($email)) {
-            // email might not be a regular email but an alias or a hruid
-            $user = User::getSilent($email);
-            if (!$user) {
-                // need a valid email address
-                $page->trigError('«&nbsp;<strong>' . $email . '</strong>&nbsp;» n\'est pas une adresse email valide.');
-                return;
-            }
-        } else if (Env::v('x') && Env::i('userid')) {
+        // X not registered to main site.
+        if (Env::v('x') && Env::i('userid') && $is_valid_email) {
             $user = User::getSilentWithUID(Env::i('userid'));
             if (!$user) {
                 $page->trigError('Utilisateur invalide.');
@@ -876,21 +974,31 @@ class XnetGrpModule extends PLModule
                 XDB::query('UPDATE  accounts
                                SET  email = {?}
                              WHERE  uid = {?} AND email IS NULL',
-                           Post::t('email'), $user->id());
+                           $email, $user->id());
                 // Add email for marketing if required.
-                if (Env::v('market')) {
+                if (Env::v('marketing')) {
                     $market = Marketing::get($user->uid, $email);
                     if (!$market) {
                         $market = new Marketing($user->uid, $email, 'group', $globals->asso('nom'),
-                                                Env::v('market_from'), S::v('uid'));
+                                                Env::v('marketing_from'), S::v('uid'));
                         $market->add();
                     }
                 }
+            } elseif (Env::v('broken')) {
+                // Add email for broken if required.
+                $valid = new BrokenReq(S::user(), $user, $email, 'Groupe : ' . $globals->asso('nom'));
+                $valid->submit();
             }
         } else {
-            // Check if the email is a redirection.
             $user = User::getSilent($email);
 
+            // Wrong email and no user: failure.
+            if (is_null($user) && (!$is_valid_email || !User::isForeignEmailAddress($email))) {
+                $page->trigError('«&nbsp;<strong>' . $email . '</strong>&nbsp;» n\'est pas une adresse email valide.');
+                return;
+            }
+
+            // Deals with xnet accounts.
             if (is_null($user) || $user->type == 'xnet') {
                 // User is of type xnet. There are 3 possible cases:
                 //  * the email is not known yet: we create a new account and
@@ -908,20 +1016,22 @@ class XnetGrpModule extends PLModule
 
                 // If the user has no account yet, creates new account: build names from email address.
                 if (empty($user)) {
+                    require_once 'name.func.inc.php';
                     $parts = explode('.', $mbox);
                     if (count($parts) == 1) {
-                        $lastname = $display_name = $full_name = $directory_name = ucfirst($mbox);
+                        $lastname = $display_name = capitalize_name($mbox);
                         $firstname = '';
                     } else {
-                        $firstname = ucfirst($parts[0]);
-                        $lastname = ucwords(implode(' ', array_slice($parts, 1)));
-                        $display_name = $firstname;
-                        $full_name = "$firstname $lastname";
-                        $directory_name = strtoupper($lastname) . " " . $firstname;
+                        $display_name = $firstname = capitalize_name($parts[0]);
+                        $lastname = capitalize_name(implode(' ', array_slice($parts, 1)));
                     }
-                    XDB::execute('INSERT INTO  accounts (hruid, display_name, full_name, directory_name, firstname, lastname, email, type, state)
-                                       VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?}, \'xnet\', \'disabled\')',
-                                 $hruid, $display_name, $full_name, $directory_name, $firstname, $lastname, $email);
+                    $full_name = build_full_name($firstname, $lastname);
+                    $directory_name = build_directory_name($firstname, $lastname);
+                    $sort_name = build_sort_name($firstname, $lastname);
+                    XDB::execute('INSERT INTO  accounts (hruid, display_name, full_name, directory_name, sort_name,
+                                                         firstname, lastname, email, type, state)
+                                       VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, \'xnet\', \'disabled\')',
+                                 $hruid, $display_name, $full_name, $directory_name, $sort_name, $firstname, $lastname, $email);
                     $user = User::getSilent($hruid);
                 }
 
@@ -986,12 +1096,13 @@ class XnetGrpModule extends PLModule
 
         if (Post::has('suggest')) {
             if (Post::t('suggest') == 'yes') {
+                global $globals;
+
                 $user = S::user();
-                $group = Platal::globals()->asso('nom');
-                $request = new AccountReq($user, $hruid, $email, $group);
+                $request = new AccountReq($user, $hruid, $email, $globals->asso('nom'), $globals->asso('diminutif'));
                 $request->submit();
                 $page->trigSuccessRedirect('Un email va bien être envoyé à ' . $email . ' pour l\'activation de son compte.',
-                                           $group . '/member/' . $hruid);
+                                           $globals->asso('diminutif') . '/member/' . $hruid);
             } else {
                 pl_redirect('member/' . $hruid);
             }
@@ -1000,20 +1111,34 @@ class XnetGrpModule extends PLModule
         $page->assign('hruid', $hruid);
     }
 
+    function handler_admin_member_reg($page, $uid)
+    {
+        pl_content_headers('text/plain');
+
+        $user = User::getSilentWithUID($uid);
+        if ($user && $user->state != 'pending' && $user->hasProfile()) {
+            echo true;
+        }
+        echo false;
+        exit();
+    }
+
     function handler_admin_member_new_ajax($page)
     {
         pl_content_headers("text/html");
         $page->changeTpl('xnetgrp/membres-new-search.tpl', NO_SKIN);
         $users = array();
+        $same_email = false;
         if (Env::has('login')) {
             $user = User::getSilent(Env::t('login'));
             if ($user && $user->state != 'pending') {
-                $users = array($user);
+                $users = array($user->id() => $user);
+                $same_email = true;
             }
         }
         if (empty($users)) {
             list($lastname, $firstname) = str_replace(array('-', ' ', "'"), '%', array(Env::t('nom'), Env::t('prenom')));
-            $cond = new PFC_And(new PFC_Not(new UFC_Registered()));
+            $cond = new PFC_And();
             if (!empty($lastname)) {
                 $cond->addChild(new UFC_NameTokens($lastname, array(), false, false, Profile::LASTNAME));
             }
@@ -1030,7 +1155,9 @@ class XnetGrpModule extends PLModule
                 $users = array();
             }
         }
+
         $page->assign('users', $users);
+        $page->assign('same_email', $same_email);
     }
 
     function unsubscribe(PlUser $user, $remember = false)
@@ -1040,7 +1167,7 @@ class XnetGrpModule extends PLModule
 
         if ($globals->asso('notif_unsub')) {
             $mailer = new PlMailer('xnetgrp/unsubscription-notif.mail.tpl');
-            $admins = $globals->asso()->iterAdmins();
+            $admins = $globals->asso()->iterToNotify();
             while ($admin = $admins->next()) {
                 $mailer->addTo($admin);
             }
@@ -1153,7 +1280,7 @@ class XnetGrpModule extends PLModule
         }
     }
 
-    private function changeLogin(PlPage $page, PlUser $user, $login)
+    private function changeLogin(PlPage $page, PlUser $user, $login, $req_broken = false, $req_marketing = false, $marketing_from = 'user')
     {
         // Search the user's uid.
         $xuser = User::getSilent($login);
@@ -1173,6 +1300,19 @@ class XnetGrpModule extends PLModule
             return false;
         }
 
+        // Market or suggest new redirection if required.
+        $email = $user->bestEmail();
+        if ($req_broken) {
+            $valid = new BrokenReq(S::user(), $xuser, $email, 'Groupe : ' . Platal::globals()->asso('nom'));
+            $valid->submit();
+        } elseif ($req_marketing) {
+            $market = Marketing::get($xuser->uid, $email);
+            if (!$market) {
+                $market = new Marketing($xuser->uid, $email, 'group', Platal::globals()->asso('nom'), $marketing_from, S::i('uid'));
+                $market->add();
+            }
+        }
+
         if ($user->mergeIn($xuser)) {
             return $xuser->login();
         }
@@ -1193,16 +1333,18 @@ class XnetGrpModule extends PLModule
         }
 
         $page->changeTpl('xnetgrp/membres-edit.tpl');
+        $page->addJsLink('xnet_members.js');
 
         $mmlist = new MMList(S::user(), $globals->asso('mail_domain'));
 
         if (Post::has('change')) {
-            require_once 'emails.inc.php';
             S::assert_xsrf_token();
+            require_once 'emails.inc.php';
+            require_once 'name.func.inc.php';
 
             // Convert user status to X
-            if (!Post::blank('login_X')) {
-                $forlife = $this->changeLogin($page, $user, Post::t('login_X'));
+            if (!Post::blank('x')) {
+                $forlife = $this->changeLogin($page, $user, Post::i('userid'), Post::b('broken'), Post::b('marketing'), Post::v('marketing_from'));
                 if ($forlife) {
                     pl_redirect('member/' . $forlife);
                 }
@@ -1210,31 +1352,38 @@ class XnetGrpModule extends PLModule
 
             // Update user info
             if ($user->type == 'virtual' || ($user->type == 'xnet' && !$user->perms)) {
-                $lastname = Post::s('lastname');
+                $lastname = capitalize_name(Post::t('lastname'));
                 if (Post::s('type') != 'virtual') {
-                    $firstname = Post::s('firstname');
-                    $full_name = $firstname . ' ' . $lastname;
-                    $directory_name = mb_strtoupper($lastname) . ' ' . $firstname;
+                    $firstname = capitalize_name(Post::t('firstname'));
                 } else {
                     $firstname = '';
-                    $full_name = $lastname;
-                    $directory_name = mb_strtoupper($lastname);
                 }
+                $full_name = build_full_name($firstname, $lastname);
+                $directory_name = build_directory_name($firstname, $lastname);
+                $sort_name = build_sort_name($firstname, $lastname);
                 XDB::query('UPDATE  accounts
-                               SET  full_name = {?}, directory_name = {?}, display_name = {?},
-                                    firstname = {?}, lastname = {?}, sex = {?}, email = {?}, type = {?}
+                               SET  full_name = {?}, directory_name = {?}, sort_name = {?}, display_name = {?},
+                                    firstname = {?}, lastname = {?}, sex = {?}, type = {?}
                              WHERE  uid = {?}',
-                           $full_name, $directory_name, Post::t('display_name'), $firstname, $lastname,
-                           (Post::t('sex') == 'male') ? 'male' : 'female', Post::t('email'),
+                           $full_name, $directory_name, $sort_name, Post::t('display_name'), $firstname, $lastname,
+                           (Post::t('sex') == 'male') ? 'male' : 'female',
                            (Post::t('type') == 'xnet') ? 'xnet' : 'virtual', $user->id());
-            } else if (!$user->perms && Post::has('email') && require_email_update($user, Post::t('email'))) {
+            }
+
+            // Updates email.
+            $new_email = strtolower(Post::t('email'));
+            if (($user->type == 'virtual' || ($user->type == 'xnet' && !$user->perms))
+                && require_email_update($user, $new_email)) {
                 XDB::query('UPDATE  accounts
                                SET  email = {?}
                              WHERE  uid = {?}',
-                           Post::t('email'), $user->id());
-                $listClient = new MMList(S::user());
-                $listClient->change_user_email($user->forlifeEmail(), Post::t('email'));
-                update_alias_user($user->forlifeEmail(), Post::t('email'));
+                           $new_email, $user->id());
+                if ($user->forlifeEmail()) {
+                    $listClient = new MMList(S::user());
+                    $listClient->change_user_email($user->forlifeEmail(), $new_email);
+                    update_alias_user($user->forlifeEmail(), $new_email);
+                }
+                $user = User::getWithUID($user->id());
             }
             if (XDB::affectedRows()) {
                 $page->trigSuccess('Données de l\'utilisateur mises à jour.');
@@ -1242,25 +1391,12 @@ class XnetGrpModule extends PLModule
 
             if (($user->type == 'xnet' && !$user->perms)) {
                 if (Post::b('suggest')) {
-                    $request = new AccountReq(S::user(), $user->hruid, Post::t('email'), $globals->asso('nom'));
+                    $request = new AccountReq(S::user(), $user->hruid, Post::t('email'), $globals->asso('nom'), $globals->asso('diminutif'));
                     $request->submit();
                     $page->trigSuccess('Le compte va bientôt être activé.');
                 }
                 if (Post::b('again')) {
-                    $data = XDB::fetchOneAssoc('SELECT  hash, group_name, sender_name, email
-                                                  FROM  register_pending_xnet
-                                                 WHERE  uid = {?}',
-                                               $user->id());
-
-                    $mailer = new PlMailer('xnet/account.mail.tpl');
-                    $mailer->addCc('validation+xnet_account@polytechnique.org');
-                    $mailer->setTo($data['email']);
-                    $mailer->assign('hash', $data['hash']);
-                    $mailer->assign('email', $data['email']);
-                    $mailer->assign('group', $data['group_name']);
-                    $mailer->assign('sender_name', $data['sender_name']);
-                    $mailer->assign('again', true);
-                    $mailer->send();
+                    $this->again($user->id());
                     $page->trigSuccess('Relance effectuée avec succès.');
                 }
             }