Fixes the code used to synchronize passwords back to Google Apps;
[platal.git] / modules / xnetgrp.php
index 7ad6236..4fccb1b 100644 (file)
@@ -51,6 +51,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 +193,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 +319,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 +345,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 +411,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 +453,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 +515,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 +616,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.');
 
@@ -700,8 +745,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 +882,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 +895,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,52 +911,69 @@ 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 {
-            // User is of type xnet. There are 3 possible cases:
-            //  * the email is not known yet: we create a new account and
-            //      propose to send an email to the user so he can activate
-            //      his account,
-            //  * the email is known but the user was not contacted in order to
-            //      activate yet: we propose to send an email to the user so he
-            //      can activate his account,
-            //  * the email is known and the user was already contacted or has
-            //      an active account: nothing to be done.
-            list($mbox, $domain) = explode('@', strtolower($email));
-            $hruid = User::makeHrid($mbox, $domain, 'ext');
-            // User might already have an account (in another group for example).
-            $user = User::getSilent($hruid);
-
-            // If the user has no account yet, creates new account: build names from email address.
-            if (empty($user)) {
-                $parts = explode('.', $mbox);
-                if (count($parts) == 1) {
-                    $lastname = $display_name = $full_name = $directory_name = ucfirst($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;
-                }
-                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);
-                $user = User::getSilent($hruid);
+            $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;
             }
 
-            $suggest_account_activation = $this->suggest($user);
+            // 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
+                //      propose to send an email to the user so he can activate
+                //      his account,
+                //  * the email is known but the user was not contacted in order to
+                //      activate yet: we propose to send an email to the user so he
+                //      can activate his account,
+                //  * the email is known and the user was already contacted or has
+                //      an active account: nothing to be done.
+                list($mbox, $domain) = explode('@', strtolower($email));
+                $hruid = User::makeHrid($mbox, $domain, 'ext');
+                // User might already have an account (in another group for example).
+                $user = User::getSilent($hruid);
+
+                // 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 = capitalize_name($mbox);
+                        $firstname = '';
+                    } else {
+                        $display_name = $firstname = capitalize_name($parts[0]);
+                        $lastname = capitalize_name(implode(' ', array_slice($parts, 1)));
+                    }
+                    $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);
+                }
+
+                $suggest_account_activation = $this->suggest($user);
+            }
         }
 
         if ($user) {
@@ -981,12 +1033,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);
             }
@@ -995,20 +1048,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));
             }
@@ -1025,7 +1092,9 @@ class XnetGrpModule extends PLModule
                 $users = array();
             }
         }
+
         $page->assign('users', $users);
+        $page->assign('same_email', $same_email);
     }
 
     function unsubscribe(PlUser $user, $remember = false)
@@ -1035,7 +1104,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);
             }
@@ -1148,7 +1217,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);
@@ -1168,6 +1237,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();
         }
@@ -1188,52 +1270,57 @@ 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);
                 }
             }
 
             // Update user info
-            $email_changed = (!$user->profile() && strtolower($user->forlifeEmail()) != strtolower(Post::v('email')));
-            $from_email = $user->forlifeEmail();
             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) {
+            }
+
+            // 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());
-            }
-            if (require_email_update($user, Post::t('email'))) {
-                $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.');
@@ -1241,7 +1328,7 @@ 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é.');
                 }
@@ -1259,6 +1346,7 @@ class XnetGrpModule extends PLModule
                     $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();
                     $page->trigSuccess('Relance effectuée avec succès.');
                 }
@@ -1294,10 +1382,6 @@ class XnetGrpModule extends PLModule
             foreach (Env::v('ml1', array()) as $ml => $state) {
                 $ask = empty($_REQUEST['ml2'][$ml]) ? 0 : 2;
                 if ($ask == $state) {
-                    if ($state && $email_changed) {
-                        $mmlist->replace_email($ml, $from_email, $user->forlifeEmail());
-                        $page->trigSuccess("L'abonnement de {$user->fullName()} à $ml@ a été mis à jour.");
-                    }
                     continue;
                 }
                 if ($state == '1') {
@@ -1308,11 +1392,7 @@ class XnetGrpModule extends PLModule
                     $mmlist->mass_subscribe($ml, Array($user->forlifeEmail()));
                     $page->trigSuccess("{$user->fullName()} a été abonné à $ml@.");
                 } else {
-                    if ($email_changed) {
-                        $mmlist->mass_unsubscribe($ml, Array($from_email));
-                    } else {
-                        $mmlist->mass_unsubscribe($ml, Array($user->forlifeEmail()));
-                    }
+                    $mmlist->mass_unsubscribe($ml, Array($user->forlifeEmail()));
                     $page->trigSuccess("{$user->fullName()} a été désabonné de $ml@.");
                 }
             }
@@ -1322,12 +1402,10 @@ class XnetGrpModule extends PLModule
                 require_once 'emails.inc.php';
                 $ask = !empty($_REQUEST['ml4'][$ml]);
                 list($local_part, ) = explode('@', $ml);
-                if($state == $ask) {
-                    if ($state && $email_changed) {
-                        update_list_alias($user->id(), $from_email, $local_part, $globals->asso('mail_domain'));
-                        $page->trigSuccess("L'abonnement de {$user->fullName()} à $ml a été mis à jour.");
-                    }
-                } else if($ask) {
+                if ($ask == $state) {
+                    continue;
+                }
+                if ($ask) {
                     add_to_list_alias($user->id(), $local_part, $globals->asso('mail_domain'));
                     $page->trigSuccess("{$user->fullName()} a été abonné à $ml.");
                 } else {