Adds multiple contacts, and markets those unregistered (Closes #709).
authorStéphane Jacob <sj@m4x.org>
Mon, 26 Sep 2011 15:47:28 +0000 (17:47 +0200)
committerStéphane Jacob <sj@m4x.org>
Mon, 26 Sep 2011 15:47:28 +0000 (17:47 +0200)
Signed-off-by: Stéphane Jacob <sj@m4x.org>
ChangeLog
modules/carnet.php
templates/carnet/batch.tpl [new file with mode: 0644]
templates/carnet/index.tpl

index 38da5fd..b70261a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,7 @@ New:
 Bug/Wish:
 
     * Carnet:
+        - #709: Adds multiple contacts, and markets those unregistered     -JAC
         - #808: Enables watch of groups                                    -JAC
         - #1528: Do not display birthday of deceased users in emails       -FUL
 
index 283ecc9..38de2b1 100644 (file)
@@ -34,6 +34,7 @@ class CarnetModule extends PLModule
             'carnet/contacts/ical'         => $this->make_token_hook('ical',         AUTH_COOKIE, 'directory_private'),
             'carnet/contacts/csv'          => $this->make_token_hook('csv',          AUTH_COOKIE, 'directory_private'),
             'carnet/contacts/csv/birthday' => $this->make_token_hook('csv_birthday', AUTH_COOKIE, 'directory_private'),
+            'carnet/batch'                 => $this->make_hook('batch',              AUTH_COOKIE, 'directory_private'),
 
             'carnet/rss'                   => $this->make_token_hook('rss',          AUTH_COOKIE, 'directory_private'),
         );
@@ -201,8 +202,13 @@ class CarnetModule extends PLModule
     {
         XDB::execute('INSERT IGNORE INTO  watch_nonins (uid, ni_id)
                                   VALUES  ({?}, {?})', S::i('uid'), $user->id());
-        S::user()->invalidWatchCache();
-        Platal::session()->updateNbNotifs();
+        if (XDB::affectedRows() > 0) {
+            S::user()->invalidWatchCache();
+            Platal::session()->updateNbNotifs();
+            $page->trigSuccess('Contact ajouté&nbsp;: ' . $user->fullName(true));
+        } else {
+            $page->trigWarning('Contact déjà dans la liste&nbsp;: ' . $user->fullName(true));
+        }
     }
 
     public function delNonRegistered(PlPage $page, PlUser $user)
@@ -214,6 +220,33 @@ class CarnetModule extends PLModule
         Platal::session()->updateNbNotifs();
     }
 
+    public function addRegistered(PlPage $page, Profile $profile)
+    {
+        XDB::execute('INSERT IGNORE INTO  contacts (uid, contact)
+                                  VALUES  ({?}, {?})',
+                     S::i('uid'), $profile->id());
+        if (XDB::affectedRows() > 0) {
+            S::user()->invalidWatchCache();
+            Platal::session()->updateNbNotifs();
+            $page->trigSuccess('Contact ajouté&nbsp;: ' . $profile->fullName(true));
+        } else {
+            $page->trigWarning('Contact déjà dans la liste&nbsp;: ' . $profile->fullName(true));
+        }
+    }
+
+    public function delRegistered(PlPage $page, Profile $profile)
+    {
+        XDB::execute('DELETE FROM  contacts
+                            WHERE  uid = {?} AND contact = {?}',
+                     S::i('uid'), $profile->id());
+        if (XDB::affectedRows() > 0) {
+            S::user()->invalidWatchCache();
+            Platal::session()->updateNbNotifs();
+            $page->trigSuccess("Contact retiré&nbsp;!");
+        }
+
+    }
+
     public function handler_notifs($page, $action = null, $arg = null)
     {
         $page->changeTpl('carnet/notifs.tpl');
@@ -331,9 +364,6 @@ class CarnetModule extends PLModule
         $page->setTitle('Mes contacts');
         $this->_add_rss_link($page);
 
-        $uid  = S::i('uid');
-        $user = S::user();
-
         // For XSRF protection, checks both the normal xsrf token, and the special RSS token.
         // It allows direct linking to contact adding in the RSS feed.
         if (Env::v('action') && Env::v('token') !== S::user()->token) {
@@ -342,26 +372,13 @@ class CarnetModule extends PLModule
         switch (Env::v('action')) {
             case 'retirer':
                 if (($contact = Profile::get(Env::v('user')))) {
-                    if (XDB::execute("DELETE FROM  contacts
-                                            WHERE  uid = {?} AND contact = {?}",
-                                     $uid, $contact->id())) {
-                        Platal::session()->updateNbNotifs();
-                        $page->trigSuccess("Contact retiré&nbsp;!");
-                    }
+                    $this->delRegistered($page, $contact);
                 }
                 break;
 
             case 'ajouter':
                 if (($contact = Profile::get(Env::v('user')))) {
-                    XDB::execute('INSERT IGNORE INTO  contacts (uid, contact)
-                                              VALUES  ({?}, {?})',
-                                 $uid, $contact->id());
-                    if (XDB::affectedRows() > 0) {
-                        Platal::session()->updateNbNotifs();
-                        $page->trigSuccess('Contact ajouté&nbsp;!');
-                    } else {
-                        $page->trigWarning('Contact déjà dans la liste&nbsp;!');
-                    }
+                    $this->addRegistered($page, $contact);
                 }
                 break;
         }
@@ -488,6 +505,85 @@ class CarnetModule extends PLModule
         require_once 'carnet/outlook.inc.php';
         Outlook::output_profiles($pf->getProfiles(), 'fr');
     }
+
+    function handler_batch($page)
+    {
+        $page->changeTpl('carnet/batch.tpl');
+        $errors = false;
+        $incomplete = array();
+
+        if (Post::has('add')) {
+            S::assert_xsrf_token();
+            require_once 'userset.inc.php';
+            require_once 'emails.inc.php';
+            require_once 'marketing.inc.php';
+
+            $list = explode("\n", Post::v('list'));
+            $origin = Post::v('origin');
+
+            foreach ($list as $item) {
+                if ($item = trim($item)) {
+                    $elements = preg_split("/\s/", $item);
+                    $email = array_pop($elements);
+                    if (!isvalid_email($email)) {
+                        $page->trigError('Email invalide&nbsp;: ' . $email);
+                        $incomplete[] = $item;
+                        $errors = true;
+                        continue;
+                    }
+
+                    $user = User::getSilent($email);
+                    if (is_null($user)) {
+                        $details = implode(' ', $elements);
+                        $promo = trim(array_pop($elements));
+                        $cond = new PFC_And();
+                        if (preg_match('/^[MDX]\d{4}$/', $promo)) {
+                            $cond->addChild(new UFC_Promo('=', UserFilter::DISPLAY, $promo));
+                        } else {
+                            $cond->addChild(new UFC_NameTokens($promo));
+                        }
+                        foreach ($elements as $element) {
+                            $cond->addChild(new UFC_NameTokens($element));
+                        }
+                        $uf = new UserFilter($cond);
+                        $count = $uf->getTotalCount();
+                        if ($count == 0) {
+                            $page->trigError('Les informations : « ' . $item . ' » ne correspondent à aucun camarade.');
+                            $incomplete[] = $item;
+                            $errors = true;
+                            continue;
+                        } elseif ($count > 1) {
+                            $page->trigError('Les informations : « ' . $item . ' » sont ambigues et correspondent à plusieurs camarades.');
+                            $incomplete[] = $item;
+                            $errors = true;
+                            continue;
+                        } else {
+                            $user = $uf->getUser();
+                        }
+                    }
+
+                    if ($user->state == 'active') {
+                        $this->addRegistered($page, $user->profile());
+                    } else {
+                        if (!User::isForeignEmailAddress($email)) {
+                            $page->trigError('Email pas encore attribué&nbsp;: ' . $email);
+                            $incomplete[] = $item;
+                            $errors = true;
+                        } else {
+                            $this->addNonRegistered($page, $user);
+                            if (!Marketing::get($user->id(), $email, true)) {
+                                check_email($email, "Une adresse surveillée est proposée au marketing par " . S::user()->login());
+                                $market = new Marketing($user->id(), $email, 'default', null, $origin, S::v('uid'), null);
+                                $market->add();
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        $page->assign('errors', $errors);
+        $page->assign('incomplete', $incomplete);
+    }
 }
 
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
diff --git a/templates/carnet/batch.tpl b/templates/carnet/batch.tpl
new file mode 100644 (file)
index 0000000..220441e
--- /dev/null
@@ -0,0 +1,48 @@
+{**************************************************************************}
+{*                                                                        *}
+{*  Copyright (C) 2003-2011 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>Marketing</h1>
+
+<p>
+  La liste des camarades à ajouter doit comporter un camarade par ligne, sous la forme&nbsp;:
+  <em>Prénom Nom Promo Email</em>, où tous les champs, sauf l'email, sont facultatifs. La promotion éventuelle doit être
+  indiquée sous la forme <em>X2004</em>.
+</p>
+{if $errors}
+<p class="erreur">
+  Les lignes incomplètes ou erronées ont été remises dans le cadre ci-dessous pour que tu puisses les corriger et/ou les complèter.
+</p>
+{/if}
+
+<form method="post" action="{$platal->ns}carnet/batch" enctype="multipart/form-data">
+  {xsrf_token_field}
+  <div>
+  <textarea name="list" cols="60" rows="30">{if $errors}{foreach from=$incomplete item=line}{$line}
+{/foreach}{/if}</textarea><br />
+  Marketer les camarades non inscrits à Polytechnique.org&nbsp;:<br />
+  <label>en ton nom<input type="radio" name="origin" value="user" checked="checked" /></label>&nbsp;-&nbsp;
+  <label><input type="radio" name="origin" value="staff" />au nom de l'équipe Polytechnique.org </label><br />
+  <input type="submit" name="add" value="Ajouter" />
+  </div>
+</form>
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index bccf4bd..d26b025 100644 (file)
       </div>
     </td>
   </tr>
+  <tr class="impair">
+    <td colspan="2">
+      <h3><a href="carnet/batch">Ajouter plusieurs camarades à ses contacts</a></h3>
+      <div class="explication">
+        De cette façon, tu peux aussi suggérer d'un seul coup plusieurs camarades dont tu connais les adresses email de s'inscrire à Polytechnique.org.
+        Ceux déjà isncrits seront directement ajoutés à tes contacts.
+      </div>
+    </td>
+  </tr>
 </table>
 
 <br />