Enables watch of groups (Closes #808).
authorStéphane Jacob <sj@m4x.org>
Sun, 25 Sep 2011 16:50:30 +0000 (18:50 +0200)
committerStéphane Jacob <sj@m4x.org>
Sun, 25 Sep 2011 18:19:38 +0000 (20:19 +0200)
Signed-off-by: Stéphane Jacob <sj@m4x.org>
ChangeLog
classes/user.php
classes/userfilter/conditions.inc.php
include/notifs.inc.php
modules/carnet.php
templates/carnet/notifs.tpl
upgrade/1.1.4/03_watch_group.sql [new file with mode: 0644]

index abc1611..5dbf04f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,7 @@ New:
 Bug/Wish:
 
     * Carnet:
+        - #808: Enables watch of groups                                    -JAC
         - #1528: Do not display birthday of deceased users in emails       -FUL
 
     * Core:
index eb3c855..3aea2fc 100644 (file)
@@ -568,6 +568,10 @@ class User extends PlUser
         $watch['watch_promos'] = XDB::fetchColumn('SELECT  promo
                                                      FROM  watch_promo
                                                     WHERE  uid = {?}', $this->id());
+        $watch['watch_groups'] = XDB::fetchColumn("SELECT  w.groupid
+                                                     FROM  watch_group AS w
+                                               INNER JOIN  groups      AS g ON (w.groupid = g.id AND NOT FIND_IN_SET('private', pub))
+                                                    WHERE  w.uid = {?}", $this->id());
         $watch['watch_users'] = XDB::fetchColumn('SELECT  ni_id
                                                     FROM  watch_nonins
                                                    WHERE  uid = {?}', $this->id());
@@ -598,6 +602,12 @@ class User extends PlUser
         return $this->watch_promos;
     }
 
+    public function watchGroups()
+    {
+        $this->fetchWatchData();
+        return $this->watch_groups;
+    }
+
     public function watchUsers()
     {
         $this->fetchWatchData();
@@ -616,6 +626,7 @@ class User extends PlUser
         unset($this->watch_users);
         unset($this->watch_last);
         unset($this->watch_promos);
+        unset($this->watch_groups);
     }
 
 
@@ -708,7 +719,7 @@ class User extends PlUser
     /**
      * Clears a user.
      *  *always deletes in: account_lost_passwords, register_marketing,
-     *      register_pending, register_subs, watch_nonins, watch, watch_promo
+     *      register_pending, register_subs, watch_nonins, watch, watch_promo, watch_group,
      *  *always keeps in: account_types, accounts, email_virtual, carvas,
      *      group_members, homonyms_list, newsletter_ins, register_mstats, email_source_account
      *  *deletes if $clearAll: account_auth_openid, announce_read, contacts,
@@ -728,7 +739,7 @@ class User extends PlUser
     {
         $tables = array('account_lost_passwords', 'register_marketing',
                         'register_pending', 'register_subs', 'watch_nonins',
-                        'watch', 'watch_promo');
+                        'watch', 'watch_promo', 'watch_group');
 
         foreach ($tables as $t) {
             XDB::execute('DELETE FROM  ' . $t . '
index cb8f5de..a66ef5a 100644 (file)
@@ -1582,6 +1582,27 @@ class UFC_WatchPromo extends UFC_UserRelated
     }
 }
 // }}}
+// {{{ class UFC_WatchGroup
+/** Filters users belonging to a group watched by selected user
+ * @param $user Selected user (the one watching group)
+ */
+class UFC_WatchGroup extends UFC_UserRelated
+{
+    public function buildCondition(PlFilter $uf)
+    {
+        $groups = $this->user->watchGroups();
+        if (count($groups) == 0) {
+            return PlFilterCondition::COND_FALSE;
+        }
+        $conditions = array();
+        foreach ($groups as $group) {
+            $sub = $uf->addGroupFilter($group);
+            $conditions[] = 'gpm' . $sub . '.perms IS NOT NULL';
+        }
+        return implode(' OR ', $conditions);
+    }
+}
+// }}}
 // {{{ class UFC_WatchContact
 /** Filters users watched by selected user
  */
index d79de44..088c4a1 100644 (file)
@@ -130,7 +130,8 @@ class WatchRegistration extends WatchOperation
     {
         return new PFC_And(new UFC_Registered(false, '>', $watch->date()),
                            new PFC_Or($watch->contactCondition(),
-                                      $watch->promoCondition()));
+                                      $watch->promoCondition(),
+                                      $watch->groupCondition()));
     }
 
     public function getOrder()
@@ -158,7 +159,8 @@ class WatchDeath extends WatchOperation
     {
         return new PFC_And(new UFC_Dead('>', $watch->date(), true),
                            new PFC_Or($watch->contactCondition(),
-                                      $watch->promoCondition()));
+                                      $watch->promoCondition(),
+                                      $watch->groupCondition()));
     }
 
     public function getOrder()
@@ -205,7 +207,8 @@ class WatchBirthday extends WatchOperation
             $cond = new PFC_Or($cond,
                                new PFC_And($watch->promoCondition(),
                                            new UFC_Promo('>=', $profile->mainGrade(), $profile->yearpromo() - 1),
-                                           new UFC_Promo('<=', $profile->mainGrade(), $profile->yearpromo() + 1)));
+                                           new UFC_Promo('<=', $profile->mainGrade(), $profile->yearpromo() + 1)),
+                               $watch->groupCondition());
         }
         return new PFC_And($select_date, $cond);
     }
@@ -248,6 +251,7 @@ class Watch
     private $date = null;
     private $contactCond = null;
     private $promoCond = null;
+    private $groupCond = null;
 
     private $filters = array();
 
@@ -288,6 +292,14 @@ class Watch
         return $this->promoCond;
     }
 
+    public function groupCondition()
+    {
+        if (!$this->groupCond) {
+            $this->groupCond = new UFC_WatchGroup($this->user);
+        }
+        return $this->groupCond;
+    }
+
     private function fetchEventWatch($class)
     {
         if (!isset(self::$events[$class])) {
index d60d34d..283ecc9 100644 (file)
@@ -152,6 +152,51 @@ class CarnetModule extends PLModule
         Platal::session()->updateNbNotifs();
     }
 
+    private function getGroup(PlPage $page, $group)
+    {
+        $groupid = XDB::fetchOneCell("SELECT  id
+                                        FROM  groups
+                                       WHERE  (nom = {?} OR diminutif = {?}) AND NOT FIND_IN_SET('private', pub)",
+                                     $group, $group);
+        if (is_null($groupid)) {
+            $search = XDB::formatWildcards(XDB::WILDCARD_CONTAINS, $group);
+            $res = XDB::query('SELECT  id
+                                 FROM  groups
+                                WHERE  (nom ' . $search . ' OR diminutif ' . $search . ") AND NOT FIND_IN_SET('private', pub)",
+                              $search, $search);
+            if ($res->numRows() == 1) {
+                $groupid = $res->fetchOneCell();
+            }
+        }
+        return $groupid;
+    }
+
+    private function addGroup(PlPage $page, $group)
+    {
+        $groupid = $this->getGroup($page, $group);
+        if (is_null($groupid)) {
+            return;
+        }
+        XDB::execute('INSERT IGNORE INTO  watch_group (uid, groupid)
+                                  VALUES  ({?}, {?})',
+                     S::i('uid'), $groupid);
+        S::user()->invalidWatchCache();
+        Platal::session()->updateNbNotifs();
+    }
+
+    private function delGroup(PlPage $page, $group)
+    {
+        $groupid = $this->getGroup($page, $group);
+        if (is_null($groupid)) {
+            return;
+        }
+        XDB::execute('DELETE FROM  watch_group
+                            WHERE  uid = {?} AND groupid = {?}',
+                     S::i('uid'), $groupid);
+        S::user()->invalidWatchCache();
+        Platal::session()->updateNbNotifs();
+    }
+
     public function addNonRegistered(PlPage $page, PlUser $user)
     {
         XDB::execute('INSERT IGNORE INTO  watch_nonins (uid, ni_id)
@@ -184,6 +229,14 @@ class CarnetModule extends PLModule
                 $this->delPromo($page, $arg);
                 break;
 
+              case 'add_group':
+                $this->addGroup($page, $arg);
+                break;
+
+              case 'del_group':
+                $this->delGroup($page, $arg);
+                break;
+
               case 'del_nonins':
                 $user = User::get($arg);
                 if ($user) {
@@ -256,6 +309,14 @@ class CarnetModule extends PLModule
         $page->assign('promo_ranges', $ranges);
         $page->assign('nonins', $nonins->getUsers());
 
+        $groups = XDB::fetchColumn('SELECT  g.nom
+                                      FROM  watch_group AS w
+                                INNER JOIN  groups      AS g ON (g.id = w.groupid)
+                                     WHERE  w.uid = {?}
+                                  ORDER BY  g.nom',
+                                   S::i('uid'));
+        $page->assign('groups', $groups);
+        $page->assign('groups_count', count($groups));
         list($flags, $actions) = XDB::fetchOneRow('SELECT  flags, actions
                                                      FROM  watch
                                                     WHERE  uid = {?}', S::i('uid'));
index 9d13880..86e19b9 100644 (file)
@@ -116,6 +116,36 @@ Attention&nbsp;: pour les promos, tu n'es pas notifié des événements trop fr
   </fieldset>
 </form>
 
+<h2>Surveiller des groupes X</h2>
+
+<p>
+Attention&nbsp;: comme pour les promos, pour les groupes X, tu n'es pas notifié des événements trop fréquents (par exemple les changements de fiche).
+</p>
+
+<form action="carnet/notifs/" method="post">
+  {xsrf_token_field}
+  <fieldset>
+    <legend>{icon name="group"} Ajouter un groupe X</legend>
+    Tu peux surveiller des groupes X (mettre le nom ou le diminutif du groupe).<br />
+    <input type='text' name='group' />
+    <input type='submit' name='add_group' value='ajouter'
+      onclick="this.form.action += 'add_group/' + this.form.group.value;" />
+    <input type='submit' name='del_group' value='retirer'
+      onclick="this.form.action += 'del_group/' + this.form.group.value;" />
+    <br />
+    {if $groups_count eq 0}
+    <p>Tu ne surveilles actuellement aucun groupe X.</p>
+    {else}
+    <p>Tu surveilles {if $groups_count eq 1}le groupe suivant&nbsp;:{else}les groupes suivants&nbsp;:{/if}</p>
+    <ul>
+    {foreach from=$groups item=group}
+      <li>{$group}</li>
+    {/foreach}
+    </ul>
+    {/if}
+  </fieldset>
+</form>
+
 <h2>Surveiller des non inscrits</h2>
 
 <p>
diff --git a/upgrade/1.1.4/03_watch_group.sql b/upgrade/1.1.4/03_watch_group.sql
new file mode 100644 (file)
index 0000000..a873863
--- /dev/null
@@ -0,0 +1,9 @@
+CREATE TABLE watch_group (
+  uid int(11) unsigned NOT NULL DEFAULT '0',
+  groupid smallint(5) unsigned NOT NULL DEFAULT '0',
+  PRIMARY KEY (uid, groupid),
+  CONSTRAINT FOREIGN KEY (uid) REFERENCES accounts (uid) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT FOREIGN KEY (groupid) REFERENCES groups (id) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- vim:set syntax=mysql: