Merge branch 'platal-0.9.17'
authorVincent Zanotti <vincent.zanotti@polytechnique.org>
Mon, 30 Jun 2008 00:35:55 +0000 (02:35 +0200)
committerVincent Zanotti <vincent.zanotti@polytechnique.org>
Mon, 30 Jun 2008 00:35:55 +0000 (02:35 +0200)
Signed-off-by: Vincent Zanotti <vincent.zanotti@polytechnique.org>
27 files changed:
ChangeLog
classes/xnetpage.php
include/user.func.inc.php
modules/lists.php
modules/lists/lists.inc.php
modules/profile.php
modules/xnetgrp.php
templates/lists/admin.tpl
templates/lists/create.tpl
templates/lists/members.tpl
templates/profile/admin_trombino.tpl
templates/profile/base.tpl
templates/profile/nomusage.tpl
templates/profile/orange.tpl
templates/profile/trombino.tpl
templates/xnetevents/admin.tpl
templates/xnetgrp/announce-admin.tpl
templates/xnetgrp/announce-edit.tpl
templates/xnetgrp/annuaire.tpl
templates/xnetgrp/asso.tpl
templates/xnetgrp/inscrire.tpl
templates/xnetgrp/mail.tpl
templates/xnetgrp/membres-add.tpl
templates/xnetgrp/membres-del.tpl
templates/xnetgrp/membres-edit.tpl
templates/xnetgrp/subscribe-valid.tpl [new file with mode: 0644]
upgrade/0.9.17/03_xnetgrp.sql

index 82f1998..ee9b857 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -25,11 +25,13 @@ Bug/Wish:
         - #844: Uses INT in MySQL to store user ids                        -VZA
 
     * Lists:
+        - #756: Can build the list of members from a file                  -FRU
         - #761: Fix user comment in moderation mail sent by mailman        -FRU
         - #810: Fix encoding of admin pages                                -FRU
         - #813: Fix display of the sample mail refusal message             -JAC
         - #817: Automation of the management of associations' ML           -JAC
         - #839: Fix warning when adding an external address                -FRU
+        - #849: Don't list registrated user in unregistrated list          -FRU
         - Larger click target to toggle emails in the validation interface -ALK
 
     * Profile:
@@ -49,6 +51,7 @@ Bug/Wish:
         - #806: Unsubscribe from MLs when leaving the group                -FRU
         - #807: Notify groupes managers of unsubscriptions                 -FRU
         - #814: Group managers can change the visibility of the group      -FRU
+        - #823: Store the subscription requests                            -FRU
         - #824: Fix redirection when changing status of the user           -FRU
         - #846: Don't export users without a forlife in the vcard          -FRU
         - #847: Can export the directory as .csv file                      -FRU
index 1fce8e4..293fa9c 100644 (file)
@@ -114,13 +114,13 @@ class XnetPage extends PlPage
             }
             if (S::has_perms()) {
                 $sub['gérer les groupes'] = array('href' => 'admin', 'style' => 'color: gray;');
-                $sub['clear cache'] = array('href' => 'purge_cache', 'style' => 'color: gray;');
+                $sub['clear cache'] = array('href' => 'purge_cache?token=' . S::v('xsrf_token'), 'style' => 'color: gray;');
             }
             $menu['Administrer'] = $sub;
         } elseif (S::has_perms()) {
             $sub = array();
             $sub['gérer les groupes'] = 'admin';
-            $sub['clear cache'] = 'purge_cache';
+            $sub['clear cache'] = 'purge_cache?token=' . S::v('xsrf_token');
             $menu['Administrer'] = $sub;
         }
 
index 1f8a698..21bcbb5 100644 (file)
@@ -197,15 +197,27 @@ function get_users_forlife_list($members, $strict = false, $callback = '_default
         if (strlen(trim($members)) == 0) {
             return null;
         }
-        $members = explode(' ', $members);
+        $members = split("[; ,\r\n\|]+", $members);
     }
     if ($members) {
         $list = array();
         foreach ($members as $i => $alias) {
+            $alias = trim($alias);
+            if (empty($alias)) {
+                continue;
+            }
             if (($login = get_user_forlife($alias, $callback)) !== false) {
                 $list[$i] = $login;
-            } else if(!$strict) {
+            } else if (!$strict) {
                 $list[$i] = $alias;
+            } else {
+                global $globals;
+                if (strpos($alias, '@') !== false) {
+                    list($user, $dom) = explode('@', $alias);
+                    if ($dom != $globals->mail->domain && $dom != $globals->mail->domain2) {
+                        $list[$i] = $alias;
+                    }
+                }
             }
         }
         return $list;
@@ -246,7 +258,7 @@ function get_not_registered_user($login, $iterator = false)
     }
     $sql = "SELECT  user_id, nom, prenom, promo
               FROM  auth_user_md5
-             WHERE  $where
+             WHERE  $where AND perms = 'pending'
           ORDER BY  promo, nom, prenom";
     if ($iterator) {
         return XDB::iterator($sql, $nom, $prenom, $promo);
index dac625d..c7aed33 100644 (file)
@@ -184,21 +184,32 @@ class ListsModule extends PLModule
         }
 
         // click on validate button 'add_member_sub'
+        require_once('user.func.inc.php');
         if (Post::has('add_member_sub') && Post::has('add_member')) {
-            require_once('user.func.inc.php');
             $forlifes = get_users_forlife_list(Post::v('add_member'), true);
             if (!is_null($forlifes)) {
                 $members = array_merge($members, $forlifes);
             }
         }
+        if (Post::has('add_member_sub') && isset($_FILES['add_member_file']) && $_FILES['add_member_file']['tmp_name']) {
+            $upload =& PlUpload::get($_FILES['add_member_file'], S::v('forlife'), 'list.addmember', true);
+            if (!$upload) {
+                $page->trigError('Une erreur s\'est produite lors du téléchargement du fichier');
+            } else {
+                $forlifes = get_users_forlife_list($upload->getContents(), true);
+                if (!is_null($forlifes)) {
+                    $members = array_merge($members, $forlifes);
+                }
+            }
+        }
 
         ksort($owners);        
         $owners = array_unique($owners);
         ksort($members);
         $members = array_unique($members);
 
-        $page->assign('owners', join(' ', $owners));
-        $page->assign('members', join(' ', $members));
+        $page->assign('owners', join("\n", $owners));
+        $page->assign('members', join("\n", $members));
 
         if (!Post::has('submit')) {
             return;
@@ -599,6 +610,23 @@ class ListsModule extends PLModule
             }
         }
 
+        if (isset($_FILES['add_member_file']) && $_FILES['add_member_file']['tmp_name']) {
+            $upload =& PlUpload::get($_FILES['add_member_file'], S::v('forlife'), 'list.addmember', true);
+            if (!$upload) {
+                $page->trigError('Une erreur s\'est produite lors du téléchargement du fichier');
+            } else {
+                $members = get_users_forlife_list($upload->getContents(),
+                                                  false,
+                                                  array('ListsModule', 'no_login_callback'));
+                $arr = $this->client->mass_subscribe($liste, $members);
+                if (is_array($arr)) {
+                    foreach($arr as $addr) {
+                        $page->trigSuccess("{$addr[0]} inscrit.");
+                    }
+                }
+            }
+        }
+
         if (Env::has('del_member')) {
             if (strpos(Env::v('del_member'), '@') === false) {
                 $this->client->mass_unsubscribe(
index c3a5abf..2fcb84e 100644 (file)
@@ -53,7 +53,7 @@ function list_sort_owners(&$members, $tri_promo = true) {
                             LEFT JOIN auth_user_md5   AS u  ON(m2.origine = "X" AND m2.uid = u.user_id)
                                 WHERE m1.email={?}', $globals->asso('id'), $mem);
             if (list($uid, $prenom, $nom, $promo) = $res->fetchOneRow()) {
-                $key = $tri_promo ? ($promo != 'non-X' ? $promo : 0) : strtoupper($nom{0});
+                $key = $tri_promo ? ($promo != 'non-X' ? $promo : 0) : strtoupper(@$nom{0});
                 if ($tri_promo) {
                     $promo = null;
                 }
index 72a6ea0..63e3370 100644 (file)
@@ -134,6 +134,8 @@ class ProfileModule extends PLModule
                     .'/'.S::v('forlife').'.jpg';
 
         if (Env::has('upload')) {
+            S::assert_xsrf_token();
+
             $upload = new PlUpload(S::v('forlife'), 'photo');
             if (!$upload->upload($_FILES['userfile']) && !$upload->download(Env::v('photo'))) {
                 $page->trigError('Une erreur est survenue lors du téléchargement du fichier');
@@ -144,6 +146,8 @@ class ProfileModule extends PLModule
                 }
             }
         } elseif (Env::has('trombi')) {
+            S::assert_xsrf_token();
+
             $upload = new PlUpload(S::v('forlife'), 'photo');
             if ($upload->copyFrom($trombi_x)) {
                 $myphoto = new PhotoReq(S::v('uid'), $upload);
@@ -153,6 +157,8 @@ class ProfileModule extends PLModule
                 }
             }
         } elseif (Env::v('suppr')) {
+            S::assert_xsrf_token();
+
             XDB::execute('DELETE FROM  photo
                                 WHERE  uid = {?}',
                          S::v('uid'));
@@ -161,6 +167,8 @@ class ProfileModule extends PLModule
                          S::v('uid'));
             $globals->updateNbValid();
         } elseif (Env::v('cancel')) {
+            S::assert_xsrf_token();
+
             $sql = XDB::query('DELETE FROM  requests
                                      WHERE  user_id={?} AND type="photo"',
                               S::v('uid'));
@@ -460,6 +468,8 @@ class ProfileModule extends PLModule
 
         if (!Env::has('promo_sortie')) {
             return;
+        } else {
+            S::assert_xsrf_token();
         }
 
         $promo_sortie = Env::i('promo_sortie');
@@ -662,6 +672,8 @@ class ProfileModule extends PLModule
         $page->assign('usage_req', $nom_usage);
 
         if (Env::has('submit') && ($nom_usage != $usage_old)) {
+            S::assert_xsrf_token();
+
             // on vient de recevoir une requete, differente de l'ancien nom d'usage
             if ($nom_usage == $nom) {
                 $page->assign('same', true);
@@ -722,7 +734,6 @@ class ProfileModule extends PLModule
         list($forlife, $promo) = $q->fetchOneRow();
 
         switch ($action) {
-
             case "original":
                 header("Content-type: image/jpeg");
                readfile("/home/web/trombino/photos".$promo."/".$forlife.".jpg");
@@ -730,6 +741,8 @@ class ProfileModule extends PLModule
                break;
 
             case "new":
+                S::assert_xsrf_token();
+
                 $data = file_get_contents($_FILES['userfile']['tmp_name']);
                list($x, $y) = getimagesize($_FILES['userfile']['tmp_name']);
                $mimetype = substr($_FILES['userfile']['type'], 6);
@@ -740,6 +753,8 @@ class ProfileModule extends PLModule
                break;
 
             case "delete":
+                S::assert_xsrf_token();
+
                 XDB::execute('DELETE FROM photo WHERE uid = {?}', $uid);
                 break;
         }
index 3a6ea7e..6fb4e7c 100644 (file)
@@ -86,6 +86,7 @@ class XnetGrpModule extends PLModule
             '%grp/trombi'         => $this->make_hook('trombi',    AUTH_MDP, 'groupannu'),
             '%grp/geoloc'         => $this->make_hook('geoloc',    AUTH_MDP, 'groupannu'),
             '%grp/subscribe'      => $this->make_hook('subscribe', AUTH_MDP),
+            '%grp/subscribe/valid' => $this->make_hook('subscribe_valid', AUTH_MDP, 'groupadmin'),
             '%grp/unsubscribe'    => $this->make_hook('unsubscribe', AUTH_MDP, 'groupmember'),
 
             '%grp/change_rights'  => $this->make_hook('change_rights', AUTH_MDP),
@@ -165,6 +166,13 @@ class XnetGrpModule extends PLModule
                                           AND FIND_IN_SET('public', u.flags)",
                                   $globals->asso('id'));
         }
+        if (may_update()) {
+            $subs_valid = XDB::query("SELECT  uid
+                                        FROM  groupex.membres_sub_requests
+                                       WHERE  asso_id = {?}",
+                                     $globals->asso('id'));
+            $page->assign('requests', $subs_valid->numRows());
+        }
 
         if (!S::has('core_rss_hash')) {
             $page->setRssLink("Polytechnique.net :: {$globals->asso("nom")} :: News publiques",
@@ -304,6 +312,7 @@ class XnetGrpModule extends PLModule
         $page->addJsLink('ajax.js');
 
         if (Post::has('send')) {
+            S::assert_xsrf_token();
             $from  = Post::v('from');
             $sujet = Post::v('sujet');
             $body  = Post::v('body');
@@ -502,6 +511,38 @@ class XnetGrpModule extends PLModule
         $page->assign('ann', $ann);
     }
 
+    private function removeSubscriptionRequest($uid)
+    {
+        global $globals;
+        XDB::execute("DELETE FROM groupex.membres_sub_requests
+                            WHERE asso_id = {?} AND uid = {?}",
+                     $globals->asso('id'), $uid);
+    }
+
+    private function validSubscription($nom, $prenom, $sexe, $uid, $forlife)
+    {
+        global $globals;
+        $this->removeSubscriptionRequest($uid);
+        XDB::execute("INSERT INTO  groupex.membres (asso_id, uid)
+                           VALUES  ({?}, {?})",
+                     $globals->asso('id'), $uid);
+        $mailer = new PlMailer();
+        $mailer->addTo("$forlife@polytechnique.org");
+        $mailer->setFrom('"' . S::v('prenom') . ' ' . S::v('nom')
+                         . '" <' . S::v('forlife') . '@polytechnique.org>');
+        $mailer->setSubject('[' . $globals->asso('nom') . '] Demande d\'inscription');
+        $message = ($sexe ? 'Chère' : 'Cher') . " Camarade,\n"
+                 . "\n"
+                 . "  Suite à ta demande d'adhésion à " . $globals->asso('nom') . ",\n"
+                 . "j'ai le plaisir de t'annoncer que ton inscription a été validée !\n"
+                 . "\n"
+                 . "Bien cordialement,\n"
+                 . "-- \n"
+                 . S::s('prenom') . ' ' . S::s('nom') . '.';
+        $mailer->setTxtBody($message);
+        $mailer->send();
+    }
+
     function handler_subscribe(&$page, $u = null)
     {
         global $globals;
@@ -514,12 +555,13 @@ class XnetGrpModule extends PLModule
 
         if (!is_null($u) && may_update()) {
             $page->assign('u', $u);
-            $res = XDB::query("SELECT  u.nom, u.prenom, u.promo, u.user_id, FIND_IN_SET('femme', u.flags)
+            $res = XDB::query("SELECT  u.nom, u.prenom, u.promo, u.user_id, FIND_IN_SET('femme', u.flags), s.reason
                                  FROM  auth_user_md5 AS u
                            INNER JOIN  aliases AS al ON (al.id = u.user_id AND al.type != 'liste')
-                                WHERE  al.alias = {?}", $u);
+                            LEFT JOIN  groupex.membres_sub_requests AS s ON (u.user_id = s.uid AND s.asso_id = {?})
+                                WHERE  al.alias = {?}", $globals->asso('id'), $u);
 
-            if (list($nom, $prenom, $promo, $uid, $sexe) = $res->fetchOneRow()) {
+            if (list($nom, $prenom, $promo, $uid, $sexe, $reason) = $res->fetchOneRow()) {
                 $res = XDB::query("SELECT  COUNT(*)
                                      FROM  groupex.membres AS m
                                INNER JOIN  aliases  AS a ON (m.uid = a.id AND a.type != 'homonyme')
@@ -527,33 +569,18 @@ class XnetGrpModule extends PLModule
                                   $u, $globals->asso('id'));
                 $n   = $res->fetchOneCell();
                 if ($n) {
+                    $this->removeSubscriptionRequest($uid);
                     $page->kill("$prenom $nom est déjà membre du groupe !");
                     return;
-                }
-                elseif (Env::has('accept'))
-                {
-                    XDB::execute("INSERT INTO  groupex.membres (asso_id, uid)
-                                       VALUES  ({?}, {?})",
-                                            $globals->asso('id'), $uid);
-                    $mailer = new PlMailer();
-                    $mailer->addTo("$u@polytechnique.org");
-                    $mailer->setFrom('"'.S::v('prenom').' '.S::v('nom')
-                                     .'" <'.S::v('forlife').'@polytechnique.org>');
-                    $mailer->setSubject('['.$globals->asso('nom').'] Demande d\'inscription');
-                    $message = ($sexe ? 'Chère' : 'Cher') . " Camarade,\n"
-                             . "\n"
-                             . "  Suite à ta demande d'adhésion à ".$globals->asso('nom').",\n"
-                             . "j'ai le plaisir de t'annoncer que ton inscription a été validée !\n"
-                             . "\n"
-                             . "Bien cordialement,\n"
-                             . "-- \n"
-                             . "{$_SESSION["prenom"]} {$_SESSION["nom"]}.";
-                    $mailer->setTxtBody($message);
-                    $mailer->send();
+                } elseif (Env::has('accept')) {
+                    S::assert_xsrf_token();
+
+                    $this->validSubscription($nom, $prenom, $sexe, $uid, $u);
                     pl_redirect("member/$u");
-                }
-                elseif (Env::has('refuse'))
-                {
+                } elseif (Env::has('refuse')) {
+                    S::assert_xsrf_token();
+
+                    $this->removeSubscriptionRequest($uid);
                     $mailer = new PlMailer();
                     $mailer->addTo("$u@polytechnique.org");
                     $mailer->setFrom('"'.S::v('prenom').' '.S::v('nom')
@@ -568,6 +595,7 @@ class XnetGrpModule extends PLModule
                     $page->assign('nom', $nom);
                     $page->assign('promo', $promo);
                     $page->assign('uid', $uid);
+                    $page->assign('reason', $reason);
                 }
                 return;
             }
@@ -579,15 +607,29 @@ class XnetGrpModule extends PLModule
             return;
         }
 
+        $res = XDB::query("SELECT  uid
+                             FROM  groupex.membres_sub_requests
+                            WHERE  uid = {?} AND asso_id = {?}",
+                         S::i('uid'), $globals->asso('id'));
+        if ($res->numRows() != 0) {
+            $page->kill("Tu as déjà demandé ton inscription à ce groupe. Cette demande est actuellement en attente de validation.");
+            return;
+        }
+
         if (Post::has('inscrire')) {
+            S::assert_xsrf_token();
+
+            XDB::execute("INSERT INTO  groupex.membres_sub_requests (asso_id, uid, ts, reason)
+                               VALUES  ({?}, {?}, NOW(), {?})",
+                         $globals->asso('id'), S::i('uid'), Post::v('message'));
             $res = XDB::query('SELECT  IF(m.email IS NULL,
-                                                    CONCAT(al.alias,"@polytechnique.org"),
-                                                    m.email)
-                                           FROM  groupex.membres AS m
-                                     INNER JOIN  aliases         AS al ON (al.type = "a_vie"
-                                                                           AND al.id = m.uid)
-                                          WHERE  perms="admin" AND m.asso_id = {?}',
-                                         $globals->asso('id'));
+                                          CONCAT(al.alias,"@polytechnique.org"),
+                                           m.email)
+                                 FROM  groupex.membres AS m
+                           INNER JOIN  aliases         AS al ON (al.type = "a_vie"
+                                                                 AND al.id = m.uid)
+                                WHERE  perms="admin" AND m.asso_id = {?}',
+                             $globals->asso('id'));
             $emails = $res->fetchColumn();
             $to     = implode(',', $emails);
 
@@ -622,6 +664,45 @@ class XnetGrpModule extends PLModule
         }
     }
 
+    function handler_subscribe_valid(&$page)
+    {
+        global $globals;
+
+        if (Post::has('valid')) {
+            S::assert_xsrf_token();
+            $subs = Post::v('subs');
+            if (is_array($subs)) {
+                $users = array();
+                foreach ($subs as $forlife => $val) {
+                    if ($val == '1') {
+                        $res = XDB::query("SELECT  IF(u.nom_usage != '', u.nom_usage, u.nom) AS u,
+                                                   u.prenom, FIND_IN_SET('femme', u.flags) AS sexe,
+                                                   u.user_id
+                                             FROM  auth_user_md5 AS u
+                                       INNER JOIN  aliases AS a ON (a.id = u.user_id)
+                                            WHERE  a.alias = {?}", $forlife);
+                        if ($res->numRows() == 1) {
+                            list($nom, $prenom, $sexe, $uid) = $res->fetchOneRow();
+                            $this->validSubscription($nom, $prenom, $sexe, $uid, $forlife);
+                        }
+                    }
+                }
+            }
+        }
+
+        $it = XDB::iterator("SELECT  IF(u.nom_usage != '', u.nom_usage, u.nom) AS nom,
+                                     u.prenom, u.promo, a.alias AS forlife, s.ts AS date
+                               FROM  groupex.membres_sub_requests AS s
+                         INNER JOIN  auth_user_md5 AS u ON (s.uid = u.user_id)
+                         INNER JOIN  aliases AS a ON (a.id = s.uid AND a.type = 'a_vie')
+                              WHERE  asso_id = {?}
+                           ORDER BY  nom, prenom",
+                           $globals->asso('id'));
+
+        $page->changeTpl('xnetgrp/subscribe-valid.tpl');
+        $page->assign('valid', $it);
+    }
+
     function handler_change_rights(&$page)
     {
         if (Env::has('right') && (may_update() || S::has('suid'))) {
@@ -705,6 +786,8 @@ class XnetGrpModule extends PLModule
 
         if (is_null($email)) {
             return;
+        } else {
+            S::assert_xsrf_token();
         }
 
         if (strpos($email, '@') === false) {
@@ -747,6 +830,7 @@ class XnetGrpModule extends PLModule
                         XDB::execute('INSERT INTO groupex.membres (uid, asso_id, origine, email)
                                            VALUES ({?}, {?}, "X", {?})',
                                      $uid, $globals->asso('id'), $email);
+                        $this->removeSubscriptionRequest($uid);
                         pl_redirect("member/$email");
                     }
                     $page->trigError("Utilisateur invalide");
@@ -871,6 +955,8 @@ class XnetGrpModule extends PLModule
 
         if (!Post::has('confirm')) {
             return;
+        } else {
+            S::assert_xsrf_token();
         }
 
         if ($this->unsubscribe($user)) {
@@ -892,6 +978,8 @@ class XnetGrpModule extends PLModule
 
         if (!Post::has('confirm')) {
             return;
+        } else {
+            S::assert_xsrf_token();
         }
 
         if ($this->unsubscribe($user)) {
@@ -985,6 +1073,8 @@ class XnetGrpModule extends PLModule
                              $globals->asso('mail_domain'));
 
         if (Post::has('change')) {
+            S::assert_xsrf_token();
+
             // Convert user status to X
             if ($user['origine'] == 'ext' && trim(Post::v('login_X'))) {
                 $forlife = $this->changeLogin($page, $user, $mmlist, trim(Post::v('login_X')));
@@ -1169,6 +1259,8 @@ class XnetGrpModule extends PLModule
 
         if (Post::v('valid') == 'Visualiser' || Post::v('valid') == 'Enregistrer'
             || Post::v('valid') == 'Supprimer l\'image' || Post::v('valid') == 'Pas d\'image') {
+            S::assert_xsrf_token();
+
             if (!is_null($aid)) {
                 $art['id'] = $aid;
             }
@@ -1332,6 +1424,7 @@ class XnetGrpModule extends PLModule
         $page->changeTpl('xnetgrp/announce-admin.tpl');
 
         if (Env::has('del')) {
+            S::assert_xsrf_token();
             XDB::execute("DELETE  FROM groupex.announces
                            WHERE  id = {?} AND asso_id = {?}",
                          Env::i('del'), $globals->asso('id'));
index d0efb02..0adaf22 100644 (file)
@@ -112,7 +112,7 @@ mails de marketing. Une fois inscrits à Polytechnique.org, l'inscription à la
         {if $promo && strpos($x.l, '@') === false}
         <a href="profile/{$x.l}" class="popup2">{$x.n}</a>
         {elseif $x.x}
-        <a href="{$platal->ns}member/{$x.x}">{$x.n}</a>
+        <a href="{$platal->ns}member/{$x.x}">{if $x.n|trim}{$x.n}{else}{$x.l}{/if}</a>
         {elseif $x.n}
         {$x.n}
         {else}
@@ -124,11 +124,10 @@ mails de marketing. Une fois inscrits à Polytechnique.org, l'inscription à la
       </td>
     </tr>
     {/foreach}
-    <tr>
-      <td class='titre'>Ajouter ... </td>
+    <tr class="pair">
+      <td class='titre'>Ajouter</td>
       <td>
         <input type='text' size='30' name='add_owner' />
-        &nbsp;
         <input type='submit' value='ajouter' />
       </td>
     </tr>
@@ -140,7 +139,7 @@ mails de marketing. Une fois inscrits à Polytechnique.org, l'inscription à la
   {$np_m|default:"0"} membre{if $np_m > 1}s{/if} dans la liste
 </h1>
 
-<form method='post' action='{$smarty.server.REQUEST_URI}'>
+<form method='post' action='{$smarty.server.REQUEST_URI}' enctype="multipart/form-data">
   <table class='bicol' cellpadding='0' cellspacing='0'>
     {foreach from=$members item=xs key=promo}
     <tr>
@@ -150,7 +149,7 @@ mails de marketing. Une fois inscrits à Polytechnique.org, l'inscription à la
         {if $promo && strpos($x.l, '@') === false}
         <a href="profile/{$x.l}" class="popup2">{$x.n}</a>
         {elseif $x.x}
-        <a href="{$platal->ns}member/{$x.x}">{$x.n}</a>
+        <a href="{$platal->ns}member/{$x.x}">{if $x.n|trim}{$x.n}{else}{$x.l}{/if}</a>
         {elseif $x.n}
         {$x.n}
         {else}
@@ -163,15 +162,32 @@ mails de marketing. Une fois inscrits à Polytechnique.org, l'inscription à la
     </tr>
     {/foreach}
     <tr>
-      <td class='titre'>Ajouter ...</td>
+      <th colspan="2">Ajouter</th>
+    </tr>
+    <tr class="pair">
+      <td class="titre">Liste</td>
       <td>
         <input type='text' size='40' name='add_member' />
-        &nbsp;
+      </td>
+    </tr>
+    <tr class="pair">
+      <td class="titre">ou fichier(*)</td>
+      <td>
+        <input type="file" name="add_member_file" />*
+      </td>
+    </tr>
+    <tr class="pair">
+      <td colspan="2" class="center">
         <input type='submit' value='ajouter' />
       </td>
     </tr>
   </table>
 </form>
 
+<div class="smaller">
+ * Le fichier doit contenir une adresse e-mail par ligne. Les X doivent être identifiés par une adresse
+ @polytechnique.org, @m4x.org ou @melix.net/org.
+</div>
+
 
 {* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index 0f79963..d642394 100644 (file)
@@ -37,7 +37,7 @@ moins 4 polytechniciens inscrits sur le site, et de fournir les informations sui
 liste&nbsp;:
 </p>
 
-<form action='lists/create' method='post'>
+<form action='lists/create' method='post' enctype="multipart/form-data">
   <table class='bicol' cellspacing='0' cellpadding='2'>
     <tr>
       <th colspan='5'>Caractéristiques de la liste</th>
@@ -166,13 +166,17 @@ liste&nbsp;:
         <input type='hidden' name='members' value='{$members}' />
         {$members|nl2br|default:"<span class='erreur'>pas de membres</span>"}
         <br />
-        <input type='text' name='add_member' />
+        <input type='text' name='add_member' /><br />
+        <input type="file" name="add_member_file" /><br />
         <input type='submit' name='add_member_sub' value='Ajouter' />
       </td>
     </tr>
     <tr>
       <td colspan='5'>
-        <small>Tu peux entrer une liste de membres en entrant plusieurs adresses séparées par des espaces.</small>
+        <small>
+          Tu peux entrer une liste de membres en entrant plusieurs adresses séparées par des espaces, des virgules ou des point-virgules.
+          Tu peux aussi fournir un fichier avec une adresse email par ligne.
+        </small>
       </td>
     </tr>
   </table>
index b902968..135b6b8 100644 (file)
       {if $x.b}<a href="https://www.polytechnique.org/marketing/broken/{$x.l}">{icon name=error}</a>{/if}
       <a href="profile/{$x.l}" class="popup2">{$x.n}</a>
       {elseif $x.x}
-      <a href="{$platal->ns}member/{$x.x}">{$x.n}</a>
+      <a href="{$platal->ns}member/{$x.x}">{if $x.n|trim}{$x.n}{else}{$x.l}{/if}</a>
       {elseif $x.n}
       {$x.n}
       {else}
index c3c29c8..15180f4 100644 (file)
@@ -33,7 +33,7 @@ Photo actuelle de {$forlife}
 <br />
 
 <p>
-<a href="admin/trombino/{$uid}/delete">Supprimer cette photo</a>
+<a href="admin/trombino/{$uid}/delete?token={xsrf_token}">Supprimer cette photo</a>
 </p>
 
 <p>
@@ -41,6 +41,7 @@ Photo actuelle de {$forlife}
 </p>
 
 <form action="admin/trombino/{$uid}/new" method="post" enctype="multipart/form-data">
+  {xsrf_token_field}
   <div>
     <input name="userfile" type="file" size="20" maxlength="150" />
     <input type="submit" value="Envoyer" />
index dba4c05..bfd56f1 100644 (file)
@@ -21,6 +21,7 @@
 {**************************************************************************}
 
 <form action="{$wiz_baseurl}/{$lookup[$current]}" method="post" id="prof_annu">
+  {xsrf_token_field}
   <div>
     {icon name=information title="Voir ma fiche"} Tu peux consulter ta fiche telle que la
     voient <a class="popup2" href="profile/{$smarty.session.forlife}?view=public">n'importe quel internaute</a>,
index 9b813df..58f4f8f 100644 (file)
@@ -92,6 +92,7 @@ utiliser une adresse personnalisée, il faut se tourner vers
   return false;
 ">
 {/literal}
+    {xsrf_token_field}
     <table class="bicol" cellpadding="4" summary="Nom d'usage">
       <tr>
         <th>Nom d'usage</th>
index fac9b52..b057cc0 100644 (file)
@@ -41,6 +41,7 @@
 <br />
 
 <form action="profile/orange" method="post">
+  {xsrf_token_field}
   <table class="bicol" cellpadding="4" summary="Année de sortie">
     <tr>
       <th>Année de sortie</th>
index 3b23f6b..877b2fc 100644 (file)
@@ -24,6 +24,7 @@
 <h1>Trombinoscope</h1>
 
 <form enctype="multipart/form-data" action="photo/change" method="post">
+  {xsrf_token_field}
   {if ($session.promo ge 1995) || ($session.promo le 2002)}
   <p>
   Si tu n'as pas encore fourni de photo, c'est celle du trombinoscope de l'X qui est
index 5402e45..6056605 100644 (file)
@@ -178,7 +178,7 @@ Ils ont payé mais ont oublié de s'inscrire&nbsp;:
     {/if}
   </tr>
   {/foreach}
-  {if $is_admin && $evt.money}
+  {if $is_admin && $evt.money && $tout}
   <tr>
     {assign var=cols value=$moments|@count}
     <td colspan="{$cols+3}" class="right"><strong>Total</strong></td>
@@ -225,7 +225,9 @@ Ils ont payé mais ont oublié de s'inscrire&nbsp;:
 {if $is_admin}
 
 <p class="descr">
-[<a href="{$platal->ns}events/csv/{$evt.eid}/{$platal->argv[2]}/{$evt.intitule}{if $evt.titre}.{$evt.titre}{/if}.csv">Télécharger le fichier Excel</a>]
+  <a href="{$platal->ns}events/csv/{$evt.eid}/{$platal->argv[2]}/{$evt.intitule}{if $evt.titre}.{$evt.titre}{/if}.csv">
+    {icon name=page_excel title="Télécharger au format Excel"} Télécharger le fichier Excel
+  </a>
 </p>
 
 <hr />
index 1e4ee15..470b09d 100644 (file)
@@ -32,7 +32,7 @@
   <tr class="{if $art.perime}im{/if}pair">
     <td><a href="{$platal->ns}announce/edit/{$art.id}">{$art.titre}</a></td>
     <td>{$art.peremption|date_format}</td>
-    <td class="right"><a href="{$platal->ns}admin/announces?del={$art.id}">
+    <td class="right"><a href="{$platal->ns}admin/announces?del={$art.id}&amp;token={xsrf_token}">
         Supprimer l'annonce {icon name=cross}
       </a>
     </td>
index 6337ea4..413fd12 100644 (file)
@@ -42,6 +42,7 @@ function visibilityChange(box)
 {/if}
 
 <form method="post" action="{$platal->ns}announce/{if $new}new{else}edit/{$art.id}{/if}" enctype="multipart/form-data">
+{xsrf_token_field}
 <div>
   <table class="bicol">
     <tr>
index 552fb53..0d5ca00 100644 (file)
@@ -117,7 +117,7 @@ Le groupe {$asso.nom} compte {$nb_tot} membres&nbsp;:
     {if $m.comm}
     <td>{$m.comm}</td>
     {/if}
-    <td class="center" {if !$m.comm}colspan="2"{/if}>
+    <td class="right" {if !$m.comm}colspan="2"{/if}>
       {if $m.inscrit}
       <a href="https://www.polytechnique.org/vcard/{$m.email}.vcf">{icon name=vcard title="[vcard]"}</a>
       <a href="mailto:{$m.email}@polytechnique.org">{icon name=email title="mail"}</a>
index 4175ea8..537fac3 100644 (file)
     </td>
   </tr>
   {/if}
+
+  {if $is_admin && $requests}
+  <tr>
+    <td class="titre center" colspan="2">
+      <a href="{$platal->ns}subscribe/valid">{$requests} demande{if $requests gt 1}s{/if} d'inscription en attente</a>
+    </td>
+  </tr>
+  {/if}
 </table>
 
 <br />
index 6306877..edf1b49 100644 (file)
 {if $u && $is_admin && $show_form}
 
 <h2>
-  Demande de la part de&nbsp;: {$prenom} {$nom} (X{$promo})
-  <a href="https://www.polytechnique.org/profile/{$u}">Voir sa fiche</a>
+  Demande de la part de&nbsp;: <a href="profile/{$u}" class="popup2">{$prenom} {$nom} (X{$promo})</a>
 </h2>
+
+{if $reason}
+<fieldset>
+  <legend>Motif de la demande</legend>
+  {$reason|nl2br}
+</fieldset>
+{/if}
+
 <form action="{$platal->ns}subscribe/{$u}" method="post">
-  <input type="submit" value="Accepter" name="accept" />
-  <br />
-  ou bien
-  <br />
-  <input type="submit" value="Refuser avec le motif ci-dessous" name="refuse" />
-  <textarea cols="70" rows="8" name="motif"></textarea>
-  <br />
+  {xsrf_token_field}
+  <table class="bicol">
+    <tr>
+      <td>Raison (en cas de refus)&nbsp;:</td>
+    </tr>
+    <tr>
+      <td>
+        <textarea cols="70" rows="8" name="motif"></textarea>
+      </td>
+    </tr>
+    <tr>
+      <td class="center">
+        <input type="submit" value="Accepter" name="accept" />
+        <input type="submit" value="Refuser" name="refuse" />
+      </td>
+    </tr>
+  </table>
 </form>
 
+<div><a href="{$platal->ns}/subscribe/valid">Revenir à la liste des validations en attente</a></div>
+
 {elseif $smarty.post.inscrire}
 
 <p class="descr">
@@ -53,6 +72,7 @@ formulaire ci-dessous. Vérifie et corrige au besoin les différents champs, pui
 [&nbsp;M'inscrire&nbsp;!&nbsp;].
 </p>
 <form action="{$platal->ns}subscribe" method="post">
+  {xsrf_token_field}
   <p class="descr">
   <strong>OUI, je souhaite être inscrit au groupe {$asso.nom}.</strong>
   </p>
index 88d4a3e..3880d24 100644 (file)
@@ -43,6 +43,7 @@ masculin ou féminin, par son prénom, ou son nom.
 //]]></script>
  
 <form action="{$platal->ns}mail" method="post" enctype="multipart/form-data">
+  {xsrf_token_field}
   <table class='bicol'>
     <tr>
       <th colspan="2">Écrire un mail&nbsp;:</th>
index 7b674d2..40b4dda 100644 (file)
@@ -55,6 +55,7 @@ function searchX()
 <h1>{$asso.nom}&nbsp;: Ajout d'un membre</h1>
 
 <form method="post" action="{$platal->ns}member/new/">
+  {xsrf_token_field}
   <ul class='descr'>
     <li>
       Pour ajouter un X dans ton groupe, il suffit d'entrer ici une de ses
index ad51b2e..cec88a5 100644 (file)
@@ -40,6 +40,7 @@
 
 
 <form method="post" action="{$platal->pl_self()}">
+  {xsrf_token_field}
   <div class="center">
     <p class="descr">
     {if $self}
index 0dc6347..f30c160 100644 (file)
@@ -47,7 +47,7 @@
 </p>
 
 <h2>
-  Édition du profil de {$user.prenom} {$user.nom}
+  Édition du profil de {if "`$user.prenom` `$user.nom`"|trim}{$user.prenom} {$user.nom}{else}{$user.email}{/if}
   {if $user.origine eq 'X'}
   (X{$user.promo})
   <a href="https://www.polytechnique.org/profile/{$user.alias}">{icon name=user_suit title="fiche"}</a>
@@ -57,6 +57,7 @@
 </h2>
 
 <form method="post" action="{$platal->ns}member/{$platal->argv[1]}">
+  {xsrf_token_field}
   <table cellpadding="0" cellspacing="0" class='tinybicol'>
     <tr class="pair">
       <td class="titre">
diff --git a/templates/xnetgrp/subscribe-valid.tpl b/templates/xnetgrp/subscribe-valid.tpl
new file mode 100644 (file)
index 0000000..521bae3
--- /dev/null
@@ -0,0 +1,70 @@
+{**************************************************************************}
+{*                                                                        *}
+{*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+{*  http://opensource.polytechnique.org/                                  *}
+{*                                                                        *}
+{*  This program is free software; you can redistribute it and/or modify  *}
+{*  it under the terms of the GNU General Public License as published by  *}
+{*  the Free Software Foundation; either version 2 of the License, or     *}
+{*  (at your option) any later version.                                   *}
+{*                                                                        *}
+{*  This program is distributed in the hope that it will be useful,       *}
+{*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *}
+{*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *}
+{*  GNU General Public License for more details.                          *}
+{*                                                                        *}
+{*  You should have received a copy of the GNU General Public License     *}
+{*  along with this program; if not, write to the Free Software           *}
+{*  Foundation, Inc.,                                                     *}
+{*  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA               *}
+{*                                                                        *}
+{**************************************************************************}
+
+<h1>{$asso.nom}&nbsp;: Validation des inscriptions</h1>
+
+<script type="text/javascript">//<![CDATA[
+{literal}
+  var toggleState = false;
+  function toggleSelection()
+  {
+    toggleState = !toggleState;
+    var boxes = $(':checkbox.select_sub');
+    if (toggleState) {
+      boxes.attr("checked", "checked");
+    } else {
+      boxes.removeAttr("checked");
+    }
+    return true;
+  }
+{/literal}
+//]]></script>
+
+<form action="{$platal->ns}subscribe/valid" method="post">
+  <table class="tinybicol">
+    <tr>
+      <th><a href="javascript:toggleSelection()">{icon name="arrow_refresh" title="Inverser la sélection"}</a></th> 
+      <th>Prénom Nom</th>
+      <th>Date de demande</th>
+      <th></th>
+    </tr>
+    {iterate from=$valid item=user}
+    <tr>
+      <td><input type="checkbox" name="subs[{$user.forlife}]" value="1" class="select_sub" /></td>
+      <td><a href="profile/{$user.forlife}" class="popup2">{$user.prenom} {$user.nom} (X{$user.promo})</a></td>
+      <td>{$user.date|date_format}</td>
+      <td><a href="{$platal->ns}subscribe/{$user.forlife}">{icon name=magnifier title="Détails"}</a></td>
+    </tr>
+    {/iterate}
+  </table>
+
+  <div class="center">
+    {xsrf_token_field}
+    <input type="submit" name="valid" value="Accepter" />
+  </div>
+
+  <div>
+    Pour voir le détail sur une demande, clique sur le lien {icon name=magnifier title="Détails"}.<br />
+    Pour refuser une demande, tu dois aller consulter les détails et remplir la raison du refus.
+  </div>
+</form>
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index 7f25048..bf012cf 100644 (file)
@@ -2,6 +2,15 @@ use groupex;
 
 alter table asso change column flags flags set('wiki_desc', 'notif_unsub') not null;
 
+create table membres_sub_requests (
+  asso_id smallint(5) unsigned not null,
+  uid int(11) not null,
+  ts timestamp not null default NOW(),
+  reason text default null,
+
+  primary key sub (asso_id, uid)
+) charset=utf8;
+
 use x4dat;
 
 # vim:set syntax=mysql: