Start porting carnet to UserFilter.
authorFlorent Bruneau <florent.bruneau@polytechnique.org>
Sun, 8 Feb 2009 23:06:45 +0000 (00:06 +0100)
committerFlorent Bruneau <florent.bruneau@polytechnique.org>
Mon, 9 Feb 2009 22:01:54 +0000 (23:01 +0100)
Signed-off-by: Florent Bruneau <florent.bruneau@polytechnique.org>
classes/userfilter.php
classes/xorgsession.php
include/notifs.inc.php
modules/carnet.php
modules/profile/page.inc.php
templates/carnet/notifs.tpl
upgrade/account/01_profiles.sql
upgrade/account/03_carnet.sql
upgrade/account/99_insertion.sql

index 0f592c9..8ba722b 100644 (file)
@@ -397,9 +397,9 @@ class UFC_EmailList implements UserFilterCondition
     }
 }
 
-class UFC_Contact implements UserFilterCondition
+abstract class UFC_UserRelated implements UserFilterCondition
 {
-    private $uid;
+    protected $uid;
     public function __construct($uid = null)
     {
         if (is_null($uid)) {
@@ -412,7 +412,10 @@ class UFC_Contact implements UserFilterCondition
             Platal::page()->kill("Invalid contact type");
         }
     }
+}
 
+class UFC_Contact extends UFC_UserRelated
+{
     public function buildCondition(UserFilter &$uf)
     {
         $sub = $uf->addContactFilter($this->uid);
@@ -420,6 +423,43 @@ class UFC_Contact implements UserFilterCondition
     }
 }
 
+class UFC_WatchRegistration extends UFC_UserRelated
+{
+    public function buildCondition(UserFilter &$uf)
+    {
+        $sub = $uf->addWatchRegistrationFilter($this->uid);
+        return 'wn' . $sub . '.uid IS NOT NULL';
+    }
+}
+
+class UFC_WatchPromo extends UFC_UserRelated
+{
+    private $grade;
+    public function __construct($uid = null, $grade = UserFilter::GRADE_ING)
+    {
+        parent::__construct($uid);
+        $this->grade = $grade;
+    }
+
+    public function buildCondition(UserFilter &$uf)
+    {
+        $sube = $uf->addEducationFilter(true, $this->grade);
+        $subw = $uf->addWatchPromoFilter($this->uid);
+        $field = 'pe' . $sube . '.' . UserFilter::promoYear($this->grade);
+        return $field . ' IS NOT NULL AND ' . $field . ' = wp' . $subw . '.promo';
+    }
+}
+
+class UFC_WatchContacts extends UFC_Contact
+{
+    public function buildCondition(UserFilter &$uf)
+    {
+        $sub = $uf->addWatchFilter($this->uid);
+        return 'FIND_IN_SET(\'contacts\' w' . $sub . '.flags) AND ' . parent::buildCondition($uf);
+    }
+}
+
+
 /******************
  * ORDERS
  ******************/
@@ -1003,6 +1043,61 @@ class UserFilter
         }
         return $joins;
     }
+
+
+    /** CARNET
+     */
+    private $wn = array();
+    public function addWatchRegistrationFilter($uid = null)
+    {
+        return $this->register_optional($this->wn, is_null($uid) ? null : 'user_' . $uid);
+    }
+
+    private $wp = array();
+    public function addWatchPromoFilter($uid = null)
+    {
+        return $this->register_optional($this->wp, is_null($uid) ? null : 'user_' . $uid);
+    }
+
+    private $w = array();
+    public function addWatchFilter($uid = null)
+    {
+        return $this->register_optional($this->w, is_null($uid) ? null : 'user_' . $uid);
+    }
+
+    private function watchJoins()
+    {
+        $joins = array();
+        foreach ($this->w as $sub=>$key) {
+            if (is_null($key)) {
+                $joins['w' . $sub] = array('left', 'watch');
+            } else {
+                $joins['w' . $sub] = array('left', 'watch', XDB::format('$ME.uid = {?}', substr($key, 5)));
+            }
+        }
+        foreach ($this->wn as $sub=>$key) {
+            if (is_null($key)) {
+                $joins['wn' . $sub] = array('left', 'watch_nonins', '$ME.ni_id = $UID');
+            } else {
+                $joins['wn' . $sub] = array('left', 'watch_nonins', XDB::format('$ME.uid = {?} AND $ME.ni_id = $UID', substr($key, 5)));
+            }
+        }
+        foreach ($this->wn as $sub=>$key) {
+            if (is_null($key)) {
+                $joins['wn' . $sub] = array('left', 'watch_nonins', '$ME.ni_id = $UID');
+            } else {
+                $joins['wn' . $sub] = array('left', 'watch_nonins', XDB::format('$ME.uid = {?} AND $ME.ni_id = $UID', substr($key, 5)));
+            }
+        }
+        foreach ($this->wp as $sub=>$key) {
+            if (is_null($key)) {
+                $joins['wp' . $sub] = array('left', 'watch_promo');
+            } else {
+                $joins['wp' . $sub] = array('left', 'watch_promo', XDB::format('$ME.uid = {?}', substr($key, 5)));
+            }
+        }
+        return $joins;
+    }
 }
 
 
index fd54234..ae4d524 100644 (file)
@@ -321,9 +321,6 @@ class XorgSession extends PlSession
 
     public function updateNbNotifs()
     {
-        require_once 'notifs.inc.php';
-        $n = select_notifs(false, S::i('uid'), S::v('watch_last'), false);
-        S::set('notifs', $n->numRows());
     }
 
     public function setAccessCookie($replace = false, $log = true) {
index 8f28f82..8efb108 100644 (file)
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
  ***************************************************************************/
 
-define('WATCH_FICHE', 1);
-define('WATCH_INSCR', 2);
-define('WATCH_DEATH', 3);
-define('WATCH_BIRTH', 4);
-
-// {{{ function inscription_notifs_base
-
-function inscription_notifs_base($uid)
-{
-    XDB::execute('REPLACE INTO  watch_sub (uid, cid)
-                        SELECT  {?}, id
-                          FROM  watch_cat', $uid);
-}
-
-// }}}
-// {{{ function register_watch_op
-
-function register_watch_op($uid, $cid, $date='', $info='')
-{
-    // XXX
-    // TODO: Find out whether uid is a user or a profile!!!
-    // XXX
-    if (empty($date)) {
-        $date = date('Y-m-d');
-    }
-    XDB::execute('REPLACE INTO  watch_ops (uid, cid, known, date, info)
-                        VALUES  ({?}, {?}, NOW(), {?}, {?})',
-                 $uid, $cid, $date, $info);
-    if($cid == WATCH_FICHE) {
-        if ($info) {
-            register_profile_update($uid, $info);
-        }
-        XDB::execute('UPDATE  profiles
-                         SET  last_change = NOW()
-                       WHERE  pid = {?}', $uid);
-    } elseif($cid == WATCH_INSCR) {
-        XDB::execute('REPLACE INTO  contacts (uid,contact)
-                            SELECT  uid, ni_id
-                              FROM  watch_nonins
-                             WHERE  ni_id = {?}', $uid);
-        XDB::execute('DELETE FROM watch_nonins
-                            WHERE ni_id = {?}', $uid);
-    }
-    Platal::session()->updateNbNotifs();
-}
-
-// }}}
-// {{{ function _select_notifs_base
-
-function _select_notifs_base($table, $mail, $where)
-{
-    $cases = Array(
-        'contacts'     => Array('wfield' => 'contact', 'ufield' => 'user_id', 'need_contact' => false,
-            'freq_sql' => '',
-            'contact_sql' => '1'
-        ),
-        'watch_promo'  => Array('wfield' => 'promo',   'ufield' => 'promo',   'need_contact' => true,
-            'freq_sql' => ' AND ( wc.type = "basic" OR wc.type="near" AND (u.promo <= v.promo_sortie-2 AND u.promo_sortie >= v.promo+2) )',
-            'contact_sql' => 'IF(c.contact IS NULL, 0, 1)'
-        ),
-        'watch_nonins' => Array('wfield' => 'ni_id',   'ufield' => 'user_id', 'need_contact' => true,
-            'freq_sql' => '',
-            'contact_sql' => 'IF(c.contact IS NULL, 0, 1)'
-        )
-    );
-
-    $our   = $cases[$table];
-    $sql = "
-        (
-            SELECT  u.promo, u.prenom, IF(u.nom_usage='',u.nom,u.nom_usage) AS nom,
-                    u.deces != 0 AS dcd, (u.flags = 'femme') AS sexe,
-                    a.alias AS bestalias,
-                    wo.*,
-                    {$our['contact_sql']} AS contact,
-                    (u.perms IN('admin','user')) AS inscrit";
-    if ($mail) {
-        $sql.=",
-            w.uid AS aid, v.prenom AS aprenom, IF(v.nom_usage='',v.nom,v.nom_usage) AS anom,
-            b.alias AS abestalias, (v.flags='femme') AS asexe, q.core_mail_fmt AS mail_fmt";
-    }
-
-    $sql .= "
-            FROM  $table          AS w
-      INNER JOIN  auth_user_md5   AS u  ON(u.{$our['ufield']} = w.{$our['wfield']})
-      INNER JOIN  auth_user_quick AS q  ON(q.user_id = w.uid)
-      INNER JOIN  auth_user_md5   AS v  ON(v.user_id = q.user_id)";
-    if ($mail) {
-        $sql .="
-      INNER JOIN  aliases         AS b  ON(b.id = q.user_id AND FIND_IN_SET('bestalias', b.flags))";
-    }
-    if ($our['need_contact']) {
-        $sql .="
-       LEFT JOIN  contacts        AS c  ON(c.uid = w.uid AND c.contact = u.user_id)";
-    }
-
-    $sql .="
-      INNER JOIN  watch_ops       AS wo ON(wo.uid = u.user_id AND ".($mail ? 'wo.known > q.watch_last' : '( wo.known > {?} OR wo.date=NOW() )').")
-      INNER JOIN  watch_sub       AS ws ON(ws.cid = wo.cid AND ws.uid = w.uid)
-      INNER JOIN  watch_cat       AS wc ON(wc.id = wo.cid{$our['freq_sql']})
-       LEFT JOIN  aliases         AS a  ON(a.id = u.user_id AND FIND_IN_SET('bestalias', a.flags))
-          WHERE  $where
-    )";
-
-    return $sql;
-}
-
-// }}}
-// {{{ function select_notifs
-
-function select_notifs($mail, $uid=null, $last=null, $iterator=true)
-{
-    $where = $mail ? 'q.watch_flags=3' : 'w.uid = {?}';
-    $sql   = _select_notifs_base('contacts',     $mail, $where.($mail?'':' AND (q.watch_flags=1 OR q.watch_flags=3)')) . " UNION DISTINCT ";
-    $sql  .= _select_notifs_base('watch_promo',  $mail, $where) .  " UNION DISTINCT ";
-    $sql  .= _select_notifs_base('watch_nonins', $mail, $where);
-
-    if ($iterator) {
-        return XDB::iterator($sql . ' ORDER BY cid, promo, date DESC, nom', $last, $uid, $last, $uid, $last, $uid);
-    } else {
-        return XDB::query($sql, $last, $uid, $last, $uid, $last, $uid);
-    }
-}
-
-// }}}
-// {{{
-
-global $prf_desc;
-$prf_desc = array('search_names' => 'L\'un de ses noms',
-                  'freetext' => 'Le texte libre',
-                  'mobile' => 'Son numéro de téléphone portable',
-                  'nationalite' => 'Sa nationalité',
-                  'nationalite2' => 'Sa seconde nationalité',
-                  'nationalite3' => 'Sa troisième nationalité',
-                  'nick' => 'Son surnom',
-                  'networking' => 'La liste de ses adresses de networking',
-                  'edus' => 'Ses formations',
-                  'addresses' => 'Ses adresses',
-                  'section' => 'Sa section sportive',
-                  'binets' => 'La liste de ses binets',
-                  'medals' => 'Ses décorations',
-                  'cv' => 'Son Curriculum Vitae',
-                  'corps' => 'Son Corps d\'État',
-                  'jobs' => 'Ses informations professionnelles',
-                  'photo' => 'Sa photographie');
-
-function get_profile_change_details($event, $limit) {
-    global $prf_desc;
-    $res = XDB::iterRow("SELECT  field
-                           FROM  watch_profile
-                          WHERE  uid = {?} AND ts > {?}
-                       ORDER BY  ts DESC",
-                         $event['uid'], $limit);
-    if ($res->total() > 0) {
-        $data = array();
-        while (list($field) = $res->next()) {
-            $data[] .= $prf_desc[$field];
-        }
-        return '<ul><li>' . implode('</li><li>', $data) . '</li></ul>';
-    }
-    return null;
-}
-
-// }}}
-// {{{ function register_profile_update
-
-function register_profile_update($uid, $field) {
-    XDB::execute("REPLACE INTO  watch_profile (uid, ts, field)
-                        VALUES  ({?}, NOW(), {?})",
-                 $uid, $field);
-}
-
-// {{{ class AllNotifs
-
-class AllNotifs
-{
-    public $_cats = Array();
-    public $_data = Array();
-
-    public function __construct()
-    {
-        $res = XDB::iterator("SELECT * FROM watch_cat");
-        while($tmp = $res->next()) {
-            $this->_cats[$tmp['id']] = $tmp;
-        }
-
-        // recupère tous les watchers, avec détails des watchers, a partir du
-        // watch_last de chacun, seulement ceux qui sont surveillés, ordonnés
-        $res = select_notifs(true);
-
-        while($tmp = $res->next()) {
-            $aid = $tmp['aid'];
-            if (empty($this->_data[$aid])) {
-                $this->_data[$aid] = Array("prenom" => $tmp['aprenom'], 'nom' => $tmp['anom'],
-                    'bestalias'=>$tmp['abestalias'], 'sexe' => $tmp['asexe'], 'mail_fmt' => $tmp['mail_fmt'],
-                    'dcd'=>$tmp['dcd']);
-            }
-            unset($tmp['aprenom'], $tmp['anom'], $tmp['abestalias'], $tmp['aid'], $tmp['asexe'], $tmp['mail_fmt'], $tmp['dcd']);
-            $this->_data[$aid]['data'][$tmp['cid']][] = $tmp;
-        }
-    }
-}
-
-// }}}
-// {{{ class Notifs
-
-class Notifs
-{
-    public $_uid;
-    public $_cats = Array();
-    public $_data = Array();
-
-    function __construct($uid, $up=false)
-    {
-        $this->_uid = $uid;
-
-        $res = XDB::iterator("SELECT * FROM watch_cat");
-        while($tmp = $res->next()) {
-            $this->_cats[$tmp['id']] = $tmp;
-        }
-
-        $lastweek = date('YmdHis', time() - 7*24*60*60);
-
-        // recupere les notifs du watcher $uid, sans detail sur le watcher,
-        // depuis la semaine dernière, meme ceux sans surveillance, ordonnés
-        $res = select_notifs(false, $uid, $lastweek);
-        while($tmp = $res->next()) {
-            if ($tmp['cid'] == WATCH_FICHE) {
-                $tmp['data'] = get_profile_change_details($tmp, $lastweek);
-            }
-            $this->_data[$tmp['cid']][$tmp['promo']][] = $tmp;
-        }
-
-        if($up) {
-            XDB::execute('UPDATE  watch
-                             SET  last = NOW()
-                           WHERE  uid = {?}', $uid);
-        }
-    }
-}
-
-// }}}
-// {{{ class Watch
-
-class Watch
+class WatchProfileUpdate
 {
-    public $_uid;
-    public $_promos;
-    public $_nonins;
-    public $_cats = Array();
-    public $_subs;
-    public $watch_contacts;
-    public $watch_mail;
-
-    public function __construct($uid)
-    {
-        $this->_uid = $uid;
-        $this->_promos = new PromoNotifs($uid);
-        $this->_nonins = new NoninsNotifs($uid);
-        $this->_subs = new WatchSub($uid);
-        $res = XDB::query('SELECT  FIND_IN_SET(\'contacts\', flags),
-                                   FIND_IN_SET(\'mail\', flags)
-                             FROM  watch
-                            WHERE  uid = {?}', $uid);
-        list($this->watch_contacts, $this->watch_mail) = $res->fetchOneRow();
+    const ID = 1;
 
-        $this->_cats = XDB::fetchAllAssoc('id', 'SELECT * FROM watch_cat');
-    }
-
-    public function saveFlags()
+    public static function register(Profile &$profile, $field)
     {
-        $flags = new PlFlagSet();
-        $flags->addFlag('contacts', $this->watch_contacts);
-        $flags->addFlag('mail',     $this->watch_mail);
-        XDB::execute('UPDATE  watch
-                         SET  flags = {?}
-                       WHERE  uid = {?}',
-                     $flags, $this->_uid);
+        XDB::execute('REPLACE INTO  watch_profile (uid, ts, field)
+                            VALUES  ({?}, NOW(), {?})',
+                     $profile->id(), $field);
     }
 
-    public function cats()
+    public static function getCondition(PlUser &$user)
     {
-        return $this->_cats;
-    }
-
-    public function subs($i)
-    {
-        return $this->_subs->_data[$i];
-    }
-
-    public function promos()
-    {
-        return $this->_promos->toRanges();
-    }
-
-    public function nonins()
-    {
-        return $this->_nonins->_data;
+        return new UFC_And(new UFC_ProfileUpdated('>=', $user->watch_last),
+                           new UFC_WatchContacts($user->id()));
     }
 }
 
-// }}}
-// {{{ class WatchSub
-
-class WatchSub
+class WatchRegistration
 {
-    public $_uid;
-    public $_data = Array();
-
-    public function __construct($uid)
-    {
-        $this->_uid = $uid;
-        $res = XDB::iterRow('SELECT cid FROM watch_sub WHERE uid={?}', $uid);
-        while(list($c) = $res->next()) {
-            $this->_data[$c] = $c;
-        }
-    }
+    const ID = 2;
 
-    public function update($ind)
+    public static function getCondition(PlUser &$user)
     {
-        $this->_data = Array();
-        XDB::execute('DELETE FROM watch_sub WHERE uid={?}', $this->_uid);
-        foreach (Env::v($ind) as $key=>$val) {
-            XDB::query('INSERT INTO watch_sub SELECT {?},id FROM watch_cat WHERE id={?}', $this->_uid, $key);
-            if(XDB::affectedRows()) {
-                $this->_data[$key] = $key;
-            }
-        }
+        return new UFC_And(new UFC_Registered(false, '>=', $user->watch_last),
+                           new UFC_WatchRegistration($user->id()));
     }
 }
 
-// }}}
-// {{{ class PromoNotifs
-
-class PromoNotifs
+class WatchDeath
 {
-    public $_uid;
-    public $_data = Array();
-
-    public function __construct($uid)
-    {
-        $this->_uid = $uid;
-        $res = XDB::iterRow('SELECT promo FROM watch_promo WHERE uid={?} ORDER BY promo', $uid);
-        while (list($p) = $res->next()) {
-            $this->_data[intval($p)] = intval($p);
-        }
-    }
-
-    public function add($p)
-    {
-        $promo = intval($p);
-        XDB::execute('REPLACE INTO watch_promo (uid,promo) VALUES({?},{?})', $this->_uid, $promo);
-        $this->_data[$promo] = $promo;
-        asort($this->_data);
-    }
-
-    public function del($p)
-    {
-        $promo = intval($p);
-        XDB::execute('DELETE FROM watch_promo WHERE uid={?} AND promo={?}', $this->_uid, $promo);
-        unset($this->_data[$promo]);
-    }
-
-    public function addRange($_p1,$_p2)
-    {
-        $p1 = intval($_p1);
-        $p2 = intval($_p2);
-        $values = Array();
-        for($i = min($p1,$p2); $i<=max($p1,$p2); $i++) {
-            $values[] = "('{$this->_uid}',$i)";
-            $this->_data[$i] = $i;
-        }
-        XDB::execute('REPLACE INTO watch_promo (uid,promo) VALUES '.join(',',$values));
-        asort($this->_data);
-    }
-
-    public function delRange($_p1,$_p2)
-    {
-        $p1 = intval($_p1);
-        $p2 = intval($_p2);
-        $where = Array();
-        for($i = min($p1,$p2); $i<=max($p1,$p2); $i++) {
-            $where[] = "promo=$i";
-            unset($this->_data[$i]);
-        }
-        XDB::execute('DELETE FROM watch_promo WHERE uid={?} AND ('.join(' OR ',$where).')', $this->_uid);
-    }
+    const ID = 3;
 
-    public function toRanges()
+    public static function getCondition(PlUser &$user)
     {
-        $ranges = Array();
-        $I = Array();
-        foreach($this->_data as $promo) {
-            if(!isset($I[0])) {
-                $I = Array($promo,$promo);
-            }
-            elseif($I[1]+1 == $promo) {
-                $I[1] ++;
-            }
-            else {
-                $ranges[] = $I;
-                $I = Array($promo,$promo);
-            }
-        }
-        if(isset($I[0])) $ranges[] = $I;
-        return $ranges;
+        return new UFC_And(new UFC_Dead('>=', $user->watch_last, true),
+                           new UFC_Or(new UFC_WatchPromo($user->id()),
+                                      new UFC_WatchContacts($user->id())));
     }
 }
 
-// }}}
-// {{{ class NoninsNotifs
-
-class NoninsNotifs
+class WatchBirthday
 {
-    public $_uid;
-    public $_data = Array();
-
-    public function __construct($uid)
-    {
-        $this->_uid = $uid;
-        $res = XDB::iterator("SELECT  u.prenom,IF(u.nom_usage='',u.nom,u.nom_usage) AS nom, u.promo, u.user_id
-                                FROM  watch_nonins  AS w
-                          INNER JOIN  auth_user_md5 AS u ON (u.user_id = w.ni_id)
-                               WHERE  w.uid = {?}
-                            ORDER BY  promo,nom", $uid);
-        while($tmp = $res->next()) {
-            $this->_data[$tmp['user_id']] = $tmp;
-        }
-    }
-
-    public function del($p)
-    {
-        unset($this->_data["$p"]);
-        XDB::execute('DELETE FROM  watch_nonins WHERE uid={?} AND ni_id={?}', $this->_uid, $p);
-    }
+    const ID = 4;
 
-    public function add($p)
+    public static function getCondition(PlUser &$user)
     {
-        XDB::execute('INSERT IGNORE INTO  watch_nonins (uid,ni_id) VALUES({?},{?})', $this->_uid, $p);
-        $res = XDB::query('SELECT  prenom, IF(nom_usage="",nom,nom_usage) AS nom,promo,user_id
-                             FROM  auth_user_md5
-                            WHERE  user_id={?}', $p);
-        $this->_data["$p"] = $res->fetchOneAssoc();
+        return new UFC_And(new UFC_Birthday(),
+                           new UFC_Or(new UFC_WatchPromo($user->id()),
+                                      new UFC_WatchContacts($user->id())));
     }
 }
 
-// }}}
-
-// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
 ?>
index 42b954e..7cd9320 100644 (file)
@@ -73,89 +73,176 @@ class CarnetModule extends PLModule
         $this->_add_rss_link($page);
     }
 
-    function _handler_notifs_promos(&$page, &$watch, $action, $arg)
+    private function getSinglePromotion(PlPage &$page, $promo)
     {
-        if(preg_match('!^ *(\d{4}) *$!', $arg, $matches)) {
-            $p = intval($matches[1]);
-            if($p<1900 || $p>2100) {
-                $page->trigError("la promo entrée est invalide");
-            } else {
-                if ($action == 'add_promo') {
-                    $watch->_promos->add($p);
-                } else {
-                    $watch->_promos->del($p);
-                }
-            }
-        } elseif (preg_match('!^ *(\d{4}) *- *(\d{4}) *$!', $arg, $matches)) {
-            $p1 = intval($matches[1]);
-            $p2 = intval($matches[2]);
-            if($p1<1900 || $p1>2100) {
-                $page->trigError('la première promo de la plage entrée est invalide');
-            } elseif($p2<1900 || $p2>2100) {
-                $page->trigError('la seconde promo de la plage entrée est invalide');
+        if (!ctype_digit($promo) || $promo < 1920 || $promo > date('Y')) {
+            $page->trigError('Promotion invalide : ' . $promo);
+            return null;
+        }
+        return (int)$promo;
+    }
+
+    private function getPromo(PlPage &$page, $promo)
+    {
+        if (strpos($promo, '-') === false) {
+            $promo = $this->getSinglePromotion($page, $promo);
+            if (!$promo) {
+                return null;
             } else {
-                if ($action == 'add_promo') {
-                    $watch->_promos->addRange($p1, $p2);
-                } else {
-                    $watch->_promos->delRange($p1, $p2);
-                }
+                return array($promo);
             }
-        } else {
-            $page->trigError("La promo (ou la plage de promo) entrée est dans un format incorrect.");
         }
+
+        list($promo1, $promo2) = explode('-', $promo);
+        $promo1 = $this->getSinglePromotion($page, $promo1);
+        if (!$promo1) {
+            return null;
+        }
+        $promo2 = $this->getSinglePromotion($page, $promo2);
+        if (!$promo2) {
+            return null;
+        }
+        if ($promo1 > $promo2) {
+            $page->trigError("Intervale non valide : " . $promo);
+            return null;
+        }
+        $array = array();
+        for ($i = $promo1 ; $i <= $promo2 ; ++$i) {
+            $array[] = $i;
+        }
+        return $array;
     }
 
-    function handler_notifs(&$page, $action = null, $arg = null)
+    private function addPromo(PlPage &$page, $promo)
     {
-        $page->changeTpl('carnet/notifs.tpl');
+        $promos = $this->getPromo($page, $promo);
+        if (!$promos || count($promos) == 0) {
+            return;
+        }
+        $to_add = array();
+        foreach ($promos as $promo) {
+            $to_add[] = XDB::format('({?}, {?})', S::i('uid'), $promo);
+        }
+        XDB::execute('INSERT IGNORE INTO  watch_promo (uid, promo)
+                                  VALUES  ' . implode(', ', $to_add));
+    }
 
-        require_once 'notifs.inc.php';
+    private function delPromo(PlPage &$page, $promo)
+    {
+        $promos = $this->getPromo($page, $promo);
+        if (!$promos || count($promos) == 0) {
+            return;
+        }
+        $to_delete = array();
+        foreach ($promos as $promo) {
+            $to_delete[] = XDB::format('{?}', $promo);
+        }
+        XDB::execute('DELETE FROM  watch_promo
+                            WHERE  ' . XDB::format('uid = {?}', S::i('uid')) . '
+                                   AND promo IN (' . implode(', ', $to_delete) . ')');
+    }
+
+    public function addNonRegistered(PlPage &$page, PlUser &$user)
+    {
+        XDB::execute('INSERT IGNORE INTO  watch_nonins (uid, ni_id)
+                                  VALUES  ({?}, {?})', S::i('uid'), $user->id());
+    }
 
-        $watch = new Watch(S::v('uid'));
+    public function delNonRegistered(PlPage &$page, PlUser &$user)
+    {
+        XDB::execute('DELETE FROM  watch_nonins
+                            WHERE  uid = {?} AND ni_id = {?}',
+                    S::i('uid'), $user->id());
+    }
 
-        $res = XDB::query("SELECT promo_sortie
-                                       FROM auth_user_md5
-                                      WHERE user_id = {?}",
-                                    S::v('uid', -1));
-        $promo_sortie = $res->fetchOneCell();
-        $page->assign('promo_sortie', $promo_sortie);
+    public function handler_notifs(&$page, $action = null, $arg = null)
+    {
+        $page->changeTpl('carnet/notifs.tpl');
 
         if ($action) {
             S::assert_xsrf_token();
-        }
-        switch ($action) {
-          case 'add_promo':
-          case 'del_promo':
-            $this->_handler_notifs_promos($page, $watch, $action, $arg);
-            break;
-
-          case 'del_nonins':
-            $watch->_nonins->del($arg);
-            break;
-
-          case 'add_nonins':
-            $watch->_nonins->add($arg);
-            break;
+            switch ($action) {
+              case 'add_promo':
+                $this->addPromo($page, $arg);
+                break;
+
+              case 'del_promo':
+                $this->delPromo($page, $arg);
+                break;
+
+              case 'del_nonins':
+                $user = User::get($arg);
+                if ($user) {
+                    $this->delNonRegistered($page, $user);
+                }
+                break;
+
+              case 'add_nonins':
+                $user = User::get($arg);
+                if ($user) {
+                    $this->addNonRegistered($page, $user);
+                }
+                break;
+            }
         }
 
         if (Env::has('subs')) {
             S::assert_xsrf_token();
-            $watch->_subs->update('sub');
+            $flags = new PlFlagSet();
+            foreach (Env::v('sub') as $key=>$value) {
+                $flags->addFlag($key, $value);
+            }
+            XDB::execute('UPDATE  watch
+                             SET  actions = {?}
+                           WHERE  uid = {?}', $flags, S::i('uid'));
         }
 
         if (Env::has('flags_contacts')) {
             S::assert_xsrf_token();
-            $watch->watch_contacts = Env::b('contacts');
-            $watch->saveFlags();
+            XDB::execute('UPDATE  watch
+                             SET  ' . XDB::changeFlag('flags', 'contacts', Env::b('contacts')) . '
+                               WHERE  uid = {?}', S::i('uid'));
         }
 
         if (Env::has('flags_mail')) {
             S::assert_xsrf_token();
-            $watch->watch_mail = Env::b('mail');
-            $watch->saveFlags();
+            XDB::execute('UPDATE  watch
+                             SET  ' . XDB::changeFlag('flags', 'mail', Env::b('mail')) . '
+                               WHERE  uid = {?}', S::i('uid'));
         }
 
-        $page->assign_by_ref('watch', $watch);
+        $user = S::user();
+        $nonins = new UserFilter(new UFC_WatchRegistration($user));
+
+        $promo = XDB::fetchColumn('SELECT  promo
+                                     FROM  watch_promo
+                                    WHERE  uid = {?}
+                                 ORDER BY  promo', S::i('uid'));
+        $page->assign('promo_count', count($promo));
+        $ranges = array();
+        $range_start  = null;
+        $range_end    = null;
+        foreach ($promo as $p) {
+            if (is_null($range_start)) {
+                $range_start = $range_end = $p;
+            } else if ($p != $range_end + 1) {
+                $ranges[] = array($range_start, $range_end);
+                $range_start = $range_end = $p;
+            } else {
+                $range_end = $p;
+            }
+        }
+        $ranges[] = array($range_start, $range_end);
+        $page->assign('promo_ranges', $ranges);
+        $page->assign('nonins', $nonins->getUsers());
+
+        list($flags, $actions) = XDB::fetchOneRow('SELECT  flags, actions
+                                                     FROM  watch
+                                                    WHERE  uid = {?}', S::i('uid'));
+        $flags = new PlFlagSet($flags);
+        $actions = new PlFlagSet($actions);
+        $page->assign('flags', $flags);
+        $page->assign('actions', $actions);
     }
 
     function handler_contacts(&$page, $action = null, $subaction = null, $ssaction = null)
index cd9d38c..da36717 100644 (file)
@@ -347,17 +347,15 @@ abstract class ProfilePage implements PlWizardPage
                 $setting->save($this, $field, $this->values[$field]);
             }
             if ($this->changed[$field] && @$this->watched[$field]) {
-                register_profile_update($this->pid(), $field);
+                WatchProfileUpdate::register($this->profile, $field);
             }
         }
         $this->_saveData();
 
         // Update the last modification date
-        XDB::execute('REPLACE INTO  user_changes
-                               SET  user_id = {?}', $this->pid());
-        if (!S::suid()) {
-            register_watch_op($this->pid(), WATCH_FICHE);
-        }
+        XDB::execute('UPDATE  profiles
+                         SET  last_change = NOW()
+                       WHERE  pid = {?}', $this->pid());
         global $platal;
         S::logger()->log('profil', $platal->pl_self(2));
     }
index f5ef990..d19dbaf 100644 (file)
@@ -30,8 +30,10 @@ S'il n'y a rien à te signaler l'email ne t'est pas envoyé.</p>
   {xsrf_token_field}
   <fieldset>
     <legend>Email</legend>
-    <label><input type='checkbox' name='mail' onclick="this.form.submit();" {if $watch->watch_mail}checked="checked"{/if} />
-    Recevoir un email hebdomadaire des événements que je n'ai pas déjà vus sur le site.</label><br />
+    <label>
+      <input type='checkbox' name='mail' onclick="this.form.submit();" {if $flags->hasFlag('mail')}checked="checked"{/if} />
+      Recevoir un email hebdomadaire des événements que je n'ai pas déjà vus sur le site.
+    </label><br />
     <input type='hidden' name='flags_mail' value='valider' />
   </fieldset>
 </form>
@@ -40,10 +42,22 @@ S'il n'y a rien à te signaler l'email ne t'est pas envoyé.</p>
   {xsrf_token_field}
   <fieldset>
     <legend>Événements à surveiller</legend>
-    {foreach from=$watch->cats() item=s key=i}
-    <label><input type='checkbox' name='sub[{$i}]' {if $watch->subs($i)}checked="checked"{/if} />
-    {$s.short} {if $s.type eq near}<sup>o</sup>{elseif $s.type eq often}<sup>*</sup>{/if}</label><br />
-    {/foreach}
+    <label>
+      <input type="checkbox" name='sub[profile]' {if $actions->hasFlag('profile')}checked="checked"{/if} />
+      Mise à jour de fiche<sup>*</sup>
+    </label><br />
+    <label>
+      <input type="checkbox" name='sub[registration]' {if $actions->hasFlag('registration')}checked="checked"{/if} />
+      Nouveaux inscrits
+    </label><br />
+    <label>
+      <input type="checkbox" name='sub[death]' {if $actions->hasFlag('death')}checked="checked"{/if} />
+      Décès
+    </label><br />
+    <label>
+      <input type="checkbox" name='sub[birthday]' {if $actions->hasFlag('birthday')}checked="checked"{/if} />
+      Anniversaires<sup>o</sup>
+    </label><br />
     <span class='smaller'><sup>*</sup>: ne concerne pas les promos (événements très fréquents).</span><br />
     <span class='smaller'><sup>o</sup>: ne concerne que les promos entre {$smarty.session.promo-1} et {$promo_sortie-2} que tu surveilles.</span>
   </fieldset>
@@ -60,8 +74,10 @@ S'il n'y a rien à te signaler l'email ne t'est pas envoyé.</p>
   {xsrf_token_field}
   <fieldset>
     <legend>Contacts</legend>
-    <label><input type='checkbox' name='contacts' onclick="this.form.submit();" {if
-    $watch->watch_contacts}checked="checked"{/if} /> Surveiller mes contacts</label><br />
+    <label>
+      <input type='checkbox' name='contacts' onclick="this.form.submit();" {if $flags->hasFlag('contacts')}checked="checked"{/if} />
+      Surveiller mes contacts
+    </label><br />
     <input type='hidden' name='flags_contacts' value='valider' />
   </fieldset>
 </form>
@@ -86,14 +102,14 @@ Attention&nbsp;: pour les promos, tu n'es pas notifié des événements trop fr
     <input type='submit' name='del_promo' value='retirer'
       onclick="this.form.action += 'del_promo/' + this.form.promo.value;" />
     <br />
-    {if $watch->promos()|@count eq 0}
+    {if $promo_count eq 0}
     <p>Tu ne surveilles actuellement aucune promo.</p>
     {else}
-    <p>Tu surveilles les promos suivantes&nbsp;:</p>
+    <p>Tu surveilles {if $promo_count eq 1}la promotion suivante&nbsp;:{else}les promotions suivantes&nbsp;:{/if}</p>
     <ul>
-      {foreach from=$watch->promos() item=p}
-      <li>{if $p.0 eq $p.1}{$p.0}{else}{$p.0} à {$p.1}{/if}</li>
-      {/foreach}
+    {foreach from=$promo_ranges item=promos}
+      <li>{$promos[0]}{if $promos[0] neq $promos[1]} à {$promos[1]}{/if}</li>
+    {/foreach}
     </ul>
     {/if}
   </fieldset>
@@ -112,14 +128,15 @@ et cliquer sur les icones {icon name=add} pour les ajouter à cette liste.
 
 <fieldset>
   <legend>Non-inscrits</legend>
-    {if $watch->nonins()|@count eq 0}
+    {if $nonins|@count eq 0}
     Tu ne surveilles actuellement aucun non-inscrit.
-    {elseif $watch->nonins()|@count}
-    Tu surveilles {if $watch->nonins()|@count eq 1}le non-inscrit{else}les non-inscrits{/if}&nbsp;:
+    {else}
+    Tu surveilles {if $nonins|@count eq 1}le non-inscrit{else}les non-inscrits{/if}&nbsp;:
     <ul>
-    {foreach from=$watch->nonins() item=p}
+    {foreach from=$nonins item=p}
     <li>
-      {$p.prenom} {$p.nom} ({$p.promo}) <a href="carnet/notifs/del_nonins/{$p.user_id}?token={xsrf_token}">{icon name='cross' title='retirer'}</a>
+      {profile user=$p promo=true sex=true}
+      <a href="carnet/notifs/del_nonins/{$p->login()}?token={xsrf_token}">{icon name='cross' title='retirer'}</a>
     </li>
     {/foreach}
   </ul>
index 4ecb6b7..8248cd4 100644 (file)
@@ -12,6 +12,7 @@ create table profiles (
   birthdate date default null,
   birthdate_ref date default null,
   deathdate date default null,
+  deathdate_rec date default null,
 
   sex enum('female', 'male') not null default 'male',
   section tinyint(2) unsigned default null,
index 707fe01..8e635fa 100644 (file)
@@ -1,6 +1,7 @@
 create table watch (
   uid   int(6) not null,
   flags set('contacts', 'mail') not null default 'contacts',
+  actions set('profile', 'registration', 'death', 'birthday') not null default '',
   last  timestamp not null default '0000-00-00',
 
   primary key uid (uid),
index 73e0216..3af9373 100644 (file)
@@ -28,8 +28,17 @@ insert into accounts
 
 # Insert carnet-relative data
 insert into watch
-     select user_id as uid, watch_flags as flags, watch_last as last
-       from auth_user_quick;
+     select q.user_id as uid, q.watch_flags as flags,
+            CONCAT(IF(ws1.cid IS NULL, '', 'profile'), ',',
+                   IF(ws2.cid IS NULL, '', 'registration'), ',',
+                   IF(ws3.cid IS NULL, '', 'death'), ',',
+                   IF(ws4.cid IS NULL, '', 'birthday')) AS actions,
+            q.watch_last as last
+       from auth_user_quick as q
+  left join watch_sub as ws1 on (ws1.uid = q.user_id and ws1.cid = 1)
+  left join watch_sub as ws2 on (ws2.uid = q.user_id and ws2.cid = 2)
+  left join watch_sub as ws3 on (ws3.uid = q.user_id and ws3.cid = 3)
+  left join watch_sub as ws4 on (ws4.uid = q.user_id and ws4.cid = 4);
 
 # Insert carvas
 insert into carvas
@@ -42,6 +51,7 @@ insert into profiles
      select u.user_id AS pid, u.hruid AS hrpid, u.matricule AS xorg_id,
             u.matricule_ax AS ax_id, u.naissance AS birthdate, u.naissance_ini AS birthdate_ref,
             IF(u.deces = 0, NULL, u.deces) AS deathdate,
+            IF(u.deces = 0, NULL, u.deces) AS deathdate_rec,
             IF(FIND_IN_SET('femme', flags), 'female', 'male') AS sex,
             IF(u.section = 0, NULL, u.section) AS section,
             IF(LENGTH(u.cv) > 0, u.cv, NULL) AS cv,