Port marketing.
authorFlorent Bruneau <florent.bruneau@polytechnique.org>
Thu, 5 Feb 2009 21:57:01 +0000 (22:57 +0100)
committerFlorent Bruneau <florent.bruneau@polytechnique.org>
Thu, 5 Feb 2009 21:57:01 +0000 (22:57 +0100)
Signed-off-by: Florent Bruneau <florent.bruneau@polytechnique.org>
classes/user.php
classes/userfilter.php
include/googleapps.inc.php
include/marketing.inc.php
modules/marketing.php
templates/marketing/promo.tpl
templates/marketing/relance.tpl
templates/marketing/this_week.tpl
templates/marketing/volontaire.tpl

index 17cbd72..0f50a8a 100644 (file)
@@ -355,6 +355,38 @@ class User extends PlUser
         return $this->login() . '@' . $globals->mail->domain2;
     }
 
+
+    /** Get marketing informations
+     */
+    private function fetchMarketingData()
+    {
+        if (isset($this->last_known_email)) {
+            return;
+        }
+        $infos = XDB::fetchOneAssoc('SELECT  IF (MAX(m.last) > p.relance, MAX(m.last), p.relance) AS last_relance,
+                                             p.email AS last_known_email
+                                       FROM  register_pending AS p
+                                  LEFT JOIN  register_marketing AS m ON (p.uid = m.uid)
+                                      WHERE  p.uid = {?}
+                                   GROUP BY  p.uid', $this->id());
+        if (!$infos) {
+            $infos = array('last_relance' => null, 'last_known_email' => null);
+        }
+        $this->fillFromArray($infos);
+    }
+
+    public function lastMarketingRelance()
+    {
+        $this->fetchMarketingData();
+        return $this->last_relance;
+    }
+
+    public function lastKnownEmail()
+    {
+        $this->fetchMarketingData();
+        return $this->last_known_email;
+    }
+
     // Return permission flags for a given permission level.
     public static function makePerms($perms, $is_admin)
     {
@@ -395,6 +427,9 @@ class User extends PlUser
     // Fetch a set of users from a list of UIDs
     public static function getBulkUsersWithUIDs(array $uids)
     {
+        if (count($uids) == 0) {
+            return array();
+        }
         $fields = self::loadMainFieldsFromUIDs($uids);
         $table = array();
         while (($list = $fields->next())) {
index ad9672e..18ae09a 100644 (file)
@@ -173,14 +173,21 @@ class UFC_Promo implements UserFilterCondition
         $this->grade = $grade;
         $this->comparison = $comparison;
         $this->promo = $promo;
-        UserFilter::assertGrade($this->grade);
+        if ($this->grade != UserFilter::DISPLAY) {
+            UserFilter::assertGrade($this->grade);
+        }
     }
 
     public function buildCondition(UserFilter &$uf)
     {
-        $sub = $uf->addEducationFilter(true, $this->grade);
-        $field = 'pe' . $sub . '.' . UserFilter::promoYear($this->grade);
-        return $field . ' IS NOT NULL AND ' . $field . ' ' . $this->comparison . ' ' . XDB::format('{?}', $this->promo);
+        if ($this->grade == UserFilter::DISPLAY) {
+            $sub = $uf->addDisplayFilter();
+            return XDB::format('pd' . $sub . '.promo = {?}', $this->promo);
+        } else {
+            $sub = $uf->addEducationFilter(true, $this->grade);
+            $field = 'pe' . $sub . '.' . UserFilter::promoYear($this->grade);
+            return $field . ' IS NOT NULL AND ' . $field . ' ' . $this->comparison . ' ' . XDB::format('{?}', $this->promo);
+        }
     }
 }
 
@@ -239,37 +246,49 @@ class UFC_Name implements UserFilterCondition
 
 class UFC_Dead implements UserFilterCondition
 {
-    private $dead;
-    public function __construct($dead)
+    private $comparison;
+    private $date;
+
+    public function __construct($comparison = null, $date = null)
     {
-        $this->dead = $dead;
+        $this->comparison = $comparison;
+        $this->date = $date;
     }
 
     public function buildCondition(UserFilter &$uf)
     {
-        if ($this->dead) {
-            return 'p.deathdate IS NOT NULL';
-        } else {
-            return 'p.deathdate IS NULL';
+        $str = 'p.deathdate IS NOT NULL';
+        if (!is_null($this->comparison)) {
+            $str .= ' AND p.deathdate ' . $this->comparison . ' ' . XDB::format('{?}', date('Y-m-d', $this->date));
         }
+        return $str;
     }
 }
 
 class UFC_Registered implements UserFilterCondition
 {
     private $active;
-    public function __construct($active = false)
+    private $comparison;
+    private $date;
+
+    public function __construct($active = false, $comparison = null, $date = null)
     {
         $this->only_active = $active;
+        $this->comparison = $comparison;
+        $this->date = $date;
     }
 
     public function buildCondition(UserFilter &$uf)
     {
         if ($this->active) {
-            return 'a.uid IS NOT NULL AND a.state = \'active\'';
+            $date = 'a.uid IS NOT NULL AND a.state = \'active\'';
         } else {
-            return 'a.uid IS NOT NULL AND a.state != \'pending\'';
+            $date = 'a.uid IS NOT NULL AND a.state != \'pending\'';
+        }
+        if (!is_null($this->comparison)) {
+            $date .= ' AND a.registration_date ' . $this->comparison . ' ' . XDB::format('{?}', date('Y-m-d', $this->date));
         }
+        return $date;
     }
 }
 
@@ -391,6 +410,19 @@ class UFO_Name extends UserFilterOrder
     }
 }
 
+class UFO_Registration extends UserFilterOrder
+{
+    public function __construct($desc = false)
+    {
+        $this->desc = $desc;
+    }
+
+    protected function getSortTokens(UserFilter &$uf)
+    {
+        return 'a.registration_date';
+    }
+}
+
 /***********************************
   *********************************
           USER FILTER CLASS
@@ -555,7 +587,13 @@ class UserFilter
 
     public function getTotalCount()
     {
-        return $this->lastcount;
+        if (is_null($this->lastcount)) {
+            return (int)XDB::fetchOneCell('SELECT  COUNT(*)
+                                          ' . $this->query . '
+                                         GROUP BY  a.uid');
+        } else {
+            return $this->lastcount;
+        }
     }
 
     public function setCondition(UserFilterCondition &$cond)
@@ -588,6 +626,7 @@ class UserFilter
 
     /** DISPLAY
      */
+    const DISPLAY = 'display';
     private $pd = false;
     public function addDisplayFilter()
     {
@@ -683,7 +722,7 @@ class UserFilter
     const GRADE_MST = 'M%';
     static public function isGrade($grade)
     {
-        return $grade == self::GRADE_ING || self::$grade == GRADE_PHD || self::$grade == GRADE_MST;
+        return $grade == self::GRADE_ING || $grade == self::GRADE_PHD || $grade == self::GRADE_MST;
     }
 
     static public function assertGrade($grade)
index 4302593..3c111e3 100644 (file)
@@ -360,7 +360,8 @@ class GoogleAppsAccount
     }
 
     // Creates a new Google Apps account with the @p local parameters.
-    public function create($password_sync, $password, $redirect_mails) {
+    public function create($password_sync, $password, $redirect_mails)
+    {
         if ($this->g_status != NULL) {
             return;
         }
index 13d4c3c..b197977 100644 (file)
@@ -185,23 +185,27 @@ class Marketing
         }
     }
 
-    static public function relance($uid, $nbx = -1)
+    static public function getAliveUsersCount()
+    {
+        return new UserFilter(new UFC_Not(new UFC_Dead()))->getTotalCount();
+    }
+
+    static public function relance(PlUser &$user, $nbx = -1)
     {
         global $globals;
 
         if ($nbx < 0) {
-            $res = XDB::query("SELECT COUNT(*) FROM auth_user_md5 WHERE deces=0");
-            $nbx = $res->fetchOneCell();
+            $nbx = self::getAliveUsersCount();
         }
 
-        $res = XDB::query("SELECT  r.date, u.promo, u.nom, u.prenom, r.email, r.bestalias
-                             FROM  register_pending AS r
-                       INNER JOIN  auth_user_md5    AS u ON u.user_id = r.uid
-                            WHERE  hash != 'INSCRIT' AND uid = {?} AND
-                                   (TO_DAYS(relance) IS NULL OR TO_DAYS(relance) < TO_DAYS(NOW()))",
-                          $uid);
-        if (!list($date, $promo, $nom, $prenom, $email, $alias) = $res->fetchOneRow()) {
+        $res = XDB:i:fetchOneCell('SELECT  r.date, r.email, r.bestalias
+                                     FROM  register_pending
+                                    WHERE  r.hash = \'INSCRIT\' AND uid = {?}',
+                                   $user->id());
+        if (!$res) {
             return false;
+        } else {
+            list($date, $email, $alias) = $res;
         }
 
         $hash     = rand_url_id(12);
@@ -221,8 +225,8 @@ class Marketing
         $mymail->send();
         XDB::execute('UPDATE  register_pending
                          SET  hash={?}, password={?}, relance=NOW()
-                       WHERE  uid={?}', $hash, $pass_encrypted, $uid);
-        return "$prenom $nom ($promo)";
+                       WHERE  uid={?}', $hash, $pass_encrypted, $user->id());
+        return $user->fullName();
     }
 }
 
@@ -275,8 +279,7 @@ class AnnuaireMarketing implements MarketingEngine
         $page->assign('intro', $this->getIntro());
         $page->assign('u', $user);
         $page->assign('sign', $this->getSignature());
-        $res = XDB::query("SELECT COUNT(*) FROM auth_user_md5 WHERE perms IN ('user', 'admin') AND deces = 0");
-        $page->assign('num_users', $res->fetchOneCell());
+        $page->assign('num_users', self::getAliveUsersCount());
     }
 
     public function getText(array $user)
index 45a3fd9..10c8791 100644 (file)
@@ -41,39 +41,7 @@ class MarketingModule extends PLModule
         $page->changeTpl('marketing/index.tpl');
 
         $page->setTitle('Marketing');
-
-        // Quelques statistiques
-
-        $res   = XDB::query(
-                  "SELECT COUNT(*) AS vivants,
-                          COUNT(NULLIF(perms='admin' OR perms='user', 0)) AS inscrits,
-                          100*COUNT(NULLIF(perms='admin' OR perms='user', 0))/COUNT(*) AS ins_rate,
-                          COUNT(NULLIF(promo >= 1972, 0)) AS vivants72,
-                          COUNT(NULLIF(promo >= 1972 AND (perms='admin' OR perms='user'), 0)) AS inscrits72,
-                          100 * COUNT(NULLIF(promo >= 1972 AND (perms='admin' OR perms='user'), 0)) /
-                              COUNT(NULLIF(promo >= 1972, 0)) AS ins72_rate,
-                          COUNT(NULLIF(FIND_IN_SET('femme', flags), 0)) AS vivantes,
-                          COUNT(NULLIF(FIND_IN_SET('femme', flags) AND (perms='admin' OR perms='user'), 0)) AS inscrites,
-                          100 * COUNT(NULLIF(FIND_IN_SET('femme', flags) AND (perms='admin' OR perms='user'), 0)) /
-                              COUNT(NULLIF(FIND_IN_SET('femme', flags), 0)) AS inse_rate
-                     FROM auth_user_md5
-                    WHERE deces = 0");
-        $stats = $res->fetchOneAssoc();
-        $page->assign('stats', $stats);
-
-        $res   = XDB::query("SELECT count(*) FROM auth_user_md5 WHERE date_ins > ".
-                                      date('Ymd000000', strtotime('1 week ago')));
-        $page->assign('nbInsSem', $res->fetchOneCell());
-
-        $res = XDB::query("SELECT count(*) FROM register_pending WHERE hash != 'INSCRIT'");
-        $page->assign('nbInsEnCours', $res->fetchOneCell());
-
-        $res = XDB::query("SELECT count(*) FROM register_marketing");
-        $page->assign('nbInsMarket', $res->fetchOneCell());
-
-        $res = XDB::query("SELECT count(*) FROM register_mstats
-                                      WHERE TO_DAYS(NOW()) - TO_DAYS(success) <= 7");
-        $page->assign('nbInsMarkOK', $res->fetchOneCell());
+        $page->trigWarning("Les statistiques sont momentanéement désactivées");
     }
 
     function handler_private(&$page, $hruid = null,
@@ -88,16 +56,15 @@ class MarketingModule extends PLModule
         }
 
         // Retrieves marketed user details.
-        $res = XDB::query(
-            "SELECT  matricule
-               FROM  auth_user_md5
-              WHERE  user_id = {?} AND perms = 'pending'", $user->id());
-        if (!($matricule = $res->fetchOneCell())) {
-            $page->kill("Cet utilisateur est déjà inscrit au site.");
+        if ($user->state != 'pending') {
+            $page->kill('Cet utilisateur est déjà inscrit');
+        }
+        if (!$user->hasProfile()) {
+            $page->kill('Cet utilisateur n\'est pas concerné par le marketing');
         }
+        $matricule = $user->profile()->xorg_id;
 
         require_once('user.func.inc.php');
-        $matricule = $res->fetchOneCell();
         $matricule_X = get_X_mat($matricule);
 
         $page->assign('full_name', $user->fullName());
@@ -241,15 +208,11 @@ class MarketingModule extends PLModule
         }
         $page->assign('promo', $promo);
 
-        $sql = "SELECT  u.user_id, u.nom, u.prenom, u.last_known_email, u.matricule_ax,
-                        IF(MAX(m.last) > p.relance, MAX(m.last), p.relance) AS dern_rel, p.email
-                  FROM  auth_user_md5      AS u
-             LEFT JOIN  register_pending   AS p ON p.uid = u.user_id
-             LEFT JOIN  register_marketing AS m ON m.uid = u.user_id
-                 WHERE  u.promo = {?} AND u.deces = 0 AND u.perms='pending'
-              GROUP BY  u.user_id
-              ORDER BY  nom, prenom";
-        $page->assign('nonins', XDB::iterator($sql, $promo));
+        $uf = new UserFilter(new UFC_And(new UFC_Promo('=', UserFilter::DISPLAY, $promo),
+                                            new UFC_Not(new UFC_Registered())),
+                                array(new UFO_Name(UserFilter::LASTNAME), new UFO_Name(UserFilter::FIRSTNAME)));
+        $users = $uf->getUsers();
+        $page->assign('nonins', $users);
     }
 
     function handler_public(&$page, $hruid = null)
@@ -258,16 +221,12 @@ class MarketingModule extends PLModule
 
         // Retrieves the user info, and checks the user is not yet registered.
         $user = User::getSilent($hruid);
-        if (!$user) {
+        if (!$user || !$user->hasProfile()) {
             return PL_NOT_FOUND;
         }
 
-        $res = XDB::query(
-            "SELECT  COUNT(*)
-               FROM  auth_user_md5
-              WHERE  user_id = {?} AND perms = 'pending'", $user->id());
-        if (!$res->fetchOneCell()) {
-            $page->kill("Cet utilisateur est déjà inscrit au site.");
+        if ($user->state != 'pending') {
+            $page->kill('Cet utilisateur est déjà inscrit');
         }
 
         // Displays the page, and handles the eventual user actions.
@@ -301,14 +260,10 @@ class MarketingModule extends PLModule
     {
         $page->changeTpl('marketing/this_week.tpl');
 
-        $sort = $sorting == 'per_promo' ? 'promo' : 'date_ins';
+        $sort = $sorting == 'per_promo' ? new UFO_Promo() : new UFO_Registration();
 
-        $sql = "SELECT  a.alias AS forlife, u.date_ins, u.promo, u.nom, u.prenom
-                  FROM  auth_user_md5  AS u
-            INNER JOIN  aliases        AS a ON (u.user_id = a.id AND a.type='a_vie')
-                 WHERE  u.date_ins > ".date("Ymd000000", strtotime ('1 week ago'))."
-              ORDER BY  u.$sort DESC";
-        $page->assign('ins', XDB::iterator($sql));
+        $uf = new UserFilter(new UFC_Registered(false, '>', strtotime('1 week ago')), $sort);
+        $page->assign('users', $uf->getUsers());
     }
 
     function handler_volontaire(&$page, $promo = null)
@@ -316,22 +271,21 @@ class MarketingModule extends PLModule
         $page->changeTpl('marketing/volontaire.tpl');
 
         $res = XDB::query(
-                "SELECT
-               DISTINCT  a.promo
+                'SELECT DISTINCT  pd.promo
                    FROM  register_marketing AS m
-             INNER JOIN  auth_user_md5      AS a  ON a.user_id = m.uid
-               ORDER BY  a.promo");
+             INNER JOIN  account_profiles AS ap ON (m.uid = ap.uid AND FIND_IN_SET(\'owner\', ap.perms))
+             INNER JOIN  profile_display AS pd ON (pd.pid = ap.pid)
+               ORDER BY  pd.promo');
         $page->assign('promos', $res->fetchColumn());
 
 
         if (!is_null($promo)) {
-            $sql = "SELECT  a.nom, a.prenom, a.user_id,
-                            m.email, sa.alias AS forlife
-                      FROM  register_marketing AS m
-                INNER JOIN  auth_user_md5      AS a  ON a.user_id = m.uid AND a.promo = {?}
-                INNER JOIN  aliases            AS sa ON (m.sender = sa.id AND sa.type='a_vie')
-                  ORDER BY  a.nom";
-            $page->assign('addr', XDB::iterator($sql, $promo));
+            $it = XDB::iterator('SELECT  m.uid, m.email
+                                   FROM  register_marketing AS m
+                             INNER JOIN  account_profiles AS ap ON (m.uid = ap.uid AND FIND_IN_SET(\'owner\', ap.perms))
+                             INNER JOIN  profile_display AS pd ON (pd.pid = ap.pid)
+                                  WHERE  pd.promo = {?}', $promo);
+            $page->assign('addr', $it);
         }
     }
 
@@ -340,24 +294,22 @@ class MarketingModule extends PLModule
         $page->changeTpl('marketing/relance.tpl');
 
         if (Post::has('relancer')) {
-            $res   = XDB::query("SELECT COUNT(*) FROM auth_user_md5 WHERE deces=0");
-            $nbdix = $res->fetchOneCell();
+            $nbdix = Marketing::getAliveUsersCount();
 
             $sent  = Array();
-            foreach (array_keys($_POST['relance']) as $uid) {
-                if ($tmp = Marketing::relance($uid, $nbdix)) {
+            $users = User::getBulkUsersWithUIDs($_POST['relance']);
+            foreach ($users as $user) {
+                if ($tmp = Marketing::relance($user, $nbdix)) {
                     $sent[] = $tmp . ' a été relancé.';
                 }
             }
             $page->assign('sent', $sent);
         }
 
-        $sql = "SELECT  r.date, r.relance, r.uid, u.promo, u.nom, u.prenom
-                  FROM  register_pending AS r
-            INNER JOIN  auth_user_md5    AS u ON r. uid = u.user_id
-                 WHERE  hash!='INSCRIT'
-              ORDER BY  date DESC";
-        $page->assign('relance', XDB::iterator($sql));
+        $page->assign('relance', XDB::iterator('SELECT  r.date, r.relance, r.uid
+                                                  FROM  register_pending AS r
+                                                 WHERE  hash != \'INSCRIT\'
+                                              ORDER BY  date DESC'));
     }
 }
 
index 44b4775..a78da79 100644 (file)
 
 <form action="marketing/promo/" method="post" onsubmit="this.action += this.promo.value">
   <div class="center">
-    <a href="marketing/promo/{$promo-10}" title="-10"><img src="images/icons/resultset_first.gif" alt="[&lt;&lt;]" /></a>
-    <a href="marketing/promo/{$promo-1}" title="-1"><img src="images/icons/resultset_previous.gif" alt="[&lt;]" /></a>
-
-    &nbsp;
-    Promo&nbsp;:<input type="text" name="promo" value="{$promo}" size="4" maxlength="4" /><input type="submit" value="GO" />
-    &nbsp;
-
-    <a href="marketing/promo/{$promo+1}" title="+1"><img src="images/icons/resultset_next.gif" alt="[&gt;]" /></a>
-    <a href="marketing/promo/{$promo+10}" title="+10"><img src="images/icons/resultset_last.gif" alt="[&gt;&gt;]" /></a>
+    Promo&nbsp;:<input type="text" name="promo" value="{$promo}" size="5" maxlength="5" /><input type="submit" value="GO" />
   </div>
 </form>
 
       <th>Statut</th>
       <th>&nbsp;</th>
     </tr>
-    {iterate from=$nonins item=it}
+    {foreach from=$nonins item=it}
     <tr class="{cycle values="pair,impair"}">
-      <td>{$it.nom} {$it.prenom}</td>
-      <td>{if $it.last_known_email}{mailto address=$it.last_known_email}{/if}</td>
+      <td>{profile user=$it}</td>
+      <td>{if $it->lastKnownEmail()}{mailto address=$it->lastKnownEmail()}{/if}</td>
       <td class="center">
-        {if $it.dern_rel && $it.dern_rel != '0000-00-00'}
-        Relance le&nbsp;: {$it.dern_rel}
+        {if $it->lastMarketingRelance() && $it->lastMarketingRelance() != '0000-00-00'}
+        Relance le&nbsp;: {$it->lastMarketingRelance()}
         {elseif $it.email}
-        En cours&nbsp;: {$it.email}
+        En cours&nbsp;: {$it->lastKnownEmail()}
         {else}
         -
         {/if}
       </td>
       <td class="center">
-        <a href="marketing/private/{$it.user_id}">{icon name=wrench title="Marketing"}</a>
-        <a href="http://www.polytechniciens.com/?page=AX_FICHE_ANCIEN&amp;anc_id={$it.matricule_ax}">{*
-          *}{icon name=user_gray title="fiche AX"}</a>
+        <a href="marketing/private/{$it->id()}">{icon name=wrench title="Marketing"}</a>
+        <a href="profile/ax/{$it->login()}">{icon name=user_gray title="fiche AX"}</a>
       </td>
     </tr>
-    {/iterate}
+    {/foreach}
   </table>
 </form>
 
 <p>
-{$nonins->total()} Polytechniciens de la promo {$promo} ne sont pas inscrits !
+{$nonins|@count} Polytechniciens de la promo {$promo} ne sont pas inscrits !
 </p>
 
 
index d3639c4..05db7e3 100644 (file)
@@ -32,7 +32,6 @@
   <table class="bicol" summary="liste des inscriptions non confirmées">
     <tr>
       <th>Date</th>
-      <th>Promo</th> 
       <th>Nom</th>
       <th>Dernière relance</th>
       <th>&nbsp;</th>
@@ -40,8 +39,7 @@
     {iterate from=$relance item=it}
     <tr class="{cycle values="pair,impair"}">
       <td class="center">{$it.date}</td>
-      <td class="center">{$it.promo}</td>
-      <td>{$it.nom} {$it.prenom}</td>
+      <td>{profile user=$it.uid promo=true}</td>
       <td class="center">
         {if $it.relance eq "0000-00-00"}Jamais{else}{$it.relance}{/if}
       </td>
index deddacb..b08b4de 100644 (file)
@@ -24,7 +24,7 @@
 <h1>Inscrits des 7 derniers jours</h1>
 
 <p>
-{$ins->total()} Polytechniciens se sont inscrits ces 7 derniers jours !
+{$users|@count} Polytechniciens se sont inscrits ces 7 derniers jours !
 </p>
 
 <div class="right">
     <th>Promo</th>
     <th>Nom</th>
   </tr>
-{iterate item=in from=$ins}
+{foreach item=user from=$users}
   <tr class="{cycle values="impair,pair"}">
-    <td class="center">{$in.date_ins|date_format:"%x %X"}</td>
+    <td class="center">{$user->registration_date|date_format:"%x %X"}</td>
     <td class="center">
-      <a href="marketing/promo/{$in.promo}">{$in.promo}</a>
+      <a href="marketing/promo/{$user->promo()}">{$user->promo()}</a>
     </td>
     <td>
-      <a href="profile/{$in.forlife}" class="popup2">
-        {$in.nom} {$in.prenom}</a>
+      {profile user=$user}
     </td>
   </tr>
-{/iterate}
+{/foreach}
 </table>
 
 <div class="right">
index cac08f1..6cf86c2 100644 (file)
@@ -46,7 +46,7 @@ Choix de la promo&nbsp;:
   </tr>
   {iterate from=$addr item=it}
   <tr class="{cycle values="pair,impair"}">
-    <td><a href="marketing/private/{$it.user_id}">{$it.nom} {$it.prenom}</a></td>
+    <td><a href="marketing/private/{$it.uid}">{profile user=$it.uid link=false promo=true}</a></td>
     <td>{$it.email}</td>
     <td>{$it.forlife}</td>
   </tr>