A first version of 'UserFilter' with implementation of promo filtering
authorFlorent Bruneau <florent.bruneau@polytechnique.org>
Sun, 1 Feb 2009 22:55:08 +0000 (23:55 +0100)
committerFlorent Bruneau <florent.bruneau@polytechnique.org>
Sun, 1 Feb 2009 22:55:08 +0000 (23:55 +0100)
against User objects.

Signed-off-by: Florent Bruneau <florent.bruneau@polytechnique.org>
classes/userfilter.php [new file with mode: 0644]
modules/events.php
modules/xnetgrp.php
templates/events/index.tpl
templates/xnetgrp/annuaire.tpl

diff --git a/classes/userfilter.php b/classes/userfilter.php
new file mode 100644 (file)
index 0000000..7f8259f
--- /dev/null
@@ -0,0 +1,195 @@
+<?php
+/***************************************************************************
+ *  Copyright (C) 2003-2009 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                *
+ ***************************************************************************/
+
+interface UserFilterCondition
+{
+    /** Check that the given user matches the rule.
+     */
+    public function check(PlUser &$user);
+}
+
+abstract class UFC_OneChild implements UserFilterCondition
+{
+    protected $child;
+
+    public function setChild(UserFilterCondition &$cond)
+    {
+        $this->child =& $cond;
+    }
+}
+
+abstract class UFC_NChildren implements UserFilterCondition
+{
+    protected $children = array();
+
+    public function addChild(UserFilterCondition &$cond)
+    {
+        $this->children[] =& $cond;
+    }
+}
+
+class UFC_True implements UserFilterCondition
+{
+    public function check(PlUser &$user)
+    {
+        return true;
+    }
+}
+
+class UFC_False implements UserFilterCondition
+{
+    public function check(PlUser &$user)
+    {
+        return false;
+    }
+}
+
+class UFC_Not extends UFC_OneChild
+{
+    public function check(PlUser &$user)
+    {
+        return !$this->child->child($user);
+    }
+}
+
+class UFC_And extends UFC_NChildren
+{
+    public function check(PlUser &$user)
+    {
+        foreach ($this->children as &$cond) {
+            if (!$cond->check($user)) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
+
+class UFC_Or extends UFC_NChildren
+{
+    public function check(PlUser &$user)
+    {
+        foreach ($this->children as &$cond) {
+            if ($cond->check($user)) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
+
+class UFC_Promo implements UserFilterCondition
+{
+    const GRADE_ING = 'Ing.';
+    const GRADE_PHD = 'PhD';
+    const GRADE_MST = 'M%';
+
+    private $grade;
+    private $promo;
+    private $comparison;
+
+    public function __construct($comparison, $grade, $promo)
+    {
+        $this->grade = $grade;
+        $this->comparison = $comparison;
+        $this->promo = $promo;
+    }
+
+    public function check(PlUser &$user)
+    {
+        if (!$user->hasProfile()) {
+            return false;
+        }
+        // XXX: Definition of promotion for phds and masters might change in near future.
+        if ($this->grade == self::GRADE_ING) {
+            $promo_year = 'entry_year';
+        } else {
+            $promo_year = 'grad_year';
+        }
+        $req = XDB::fetchOneCell('SELECT  COUNT(pe.id)
+                                    FROM  profile_education AS pe
+                              INNER JOIN  profile_education_degree_enum AS pede ON (pe.degreeid = pede.id AND pede.abbreviation LIKE {?})
+                              INNER JOIN  profile_education_enum AS pee ON (pe.eduid = pee.id AND pee.abbreviation = \'X\')
+                                   WHERE  pe.' . $promo_year . ' ' . $this->comparison . ' {?} AND pe.uid = {?}',
+                                 $this->grade, $this->promo, $user->profile()->id());
+        return intval($req) > 0;
+    }
+}
+
+class UserFilter
+{
+    private $root;
+
+    /** Check that the user match the given rule.
+     */
+    public function checkUser(PlUser &$user)
+    {
+        return $this->root->check($user);
+    }
+
+    /** Filter a list of user to extract the users matching the rule.
+     */
+    public function filter(array $users)
+    {
+        $output = array();
+        foreach ($users as &$user) {
+            if ($this->checkUser($user)) {
+                $output[] = $user;
+            }
+        }
+        return $output;
+    }
+
+    public function setCondition(UserFilterCondition &$cond)
+    {
+        $this->root =& $cond;
+    }
+
+
+    static public function getLegacy($promo_min, $promo_max)
+    {
+        $min = null;
+        if ($promo_min != 0) {
+            $min = new UFC_Promo('>=', UFC_Promo::GRADE_ING, intval($promo_min));
+        }
+        $max = null;
+        if ($promo_max != 0) {
+            $max = new UFC_Promo('<=', UFC_Promo::GRADE_ING, intval($promo_max));
+        }
+        $uf = new UserFilter();
+        if (is_null($max) && is_null($min)) {
+            $uf->setCondition(new UFC_True());
+        } else if (is_null($max)) {
+            $uf->setCondition($min);
+        } else if (is_null($min)) {
+            $uf->setCondition($max);
+        } else {
+            $cond = new UFC_And();
+            $cond->addChild($min);
+            $cond->addChild($max);
+            $uf->setCondition($cond);
+        }
+        return $uf;
+    }
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
index 9809e39..063ffc4 100644 (file)
@@ -157,26 +157,34 @@ class EventsModule extends PLModule
             pl_redirect('events#newsid'.$eid);
         }
 
+        function next_event(PlIterator &$it)
+        {
+            $user = S::user();
+            while ($body = $it->next()) {
+                $uf = UserFilter::getLegacy($body['promo_min'], $body['promo_max']);
+                if ($uf->checkUser($user)) {
+                    return $body;
+                }
+            }
+            return null;
+        }
+
         // Fetch the events to display, along with their metadata.
         $array = array();
-        $it = XDB::iterator("SELECT  e.id, e.titre, e.texte, e.post_id, a.user_id, a.nom, a.prenom, d.promo AS promo_display ,a.hruid,
+        $it = XDB::iterator("SELECT  e.id, e.titre, e.texte, e.post_id, e.user_id,
                                      p.x, p.y, p.attach IS NOT NULL AS img, FIND_IN_SET('wiki', e.flags) AS wiki,
                                      FIND_IN_SET('important', e.flags) AS important,
                                      e.creation_date > DATE_SUB(CURDATE(), INTERVAL 2 DAY) AS news,
                                      e.peremption < DATE_ADD(CURDATE(), INTERVAL 2 DAY) AS end,
-                                     ev.user_id IS NULL AS nonlu
+                                     ev.user_id IS NULL AS nonlu, e.promo_min, e.promo_max
                                FROM  evenements       AS e
                           LEFT JOIN  evenements_photo AS p  ON (e.id = p.eid)
-                         INNER JOIN  auth_user_md5    AS a  ON (e.user_id = a.user_id)
-                         INNER JOIN  profile_display  AS d  ON (d.pid = a.user_id)
                           LEFT JOIN  evenements_vus   AS ev ON (e.id = ev.evt_id AND ev.user_id = {?})
                               WHERE  FIND_IN_SET('valide', e.flags) AND peremption >= NOW()
-                                     AND (e.promo_min = 0 || e.promo_min <= {?})
-                                     AND (e.promo_max = 0 || e.promo_max >= {?})
                            ORDER BY  important DESC, news DESC, end DESC, e.peremption, e.creation_date DESC",
-                            S::i('uid'), S::i('promo'), S::i('promo'));
+                            S::i('uid'));
         $cats = array('important', 'news', 'end', 'body');
-        $body  = $it->next();
+        $body  = next_event($it);
         foreach ($cats as $cat) {
             $data = array();
             if (!$body) {
@@ -188,12 +196,13 @@ class EventsModule extends PLModule
                 } else {
                     break;
                 }
-                $body = $it->next();
+                $body = next_event($it);
             } while ($body);
             if (!empty($data)) {
                 $array[$cat] = $data;
             }
         }
+
         $page->assign_by_ref('events', $array);
     }
 
index 52e6092..74c79b8 100644 (file)
@@ -138,13 +138,9 @@ class XnetGrpModule extends PLModule
     {
         global $globals;
 
-        $res = XDB::query("SELECT logo, logo_mime
-                             FROM groupex.asso WHERE id = {?}",
-                          $globals->asso('id'));
-        list($logo, $logo_mime) = $res->fetchOneRow();
-
+        $logo = $globals->asso('logo');
         if (!empty($logo)) {
-            header("Content-type: $mime");
+            header('Content-type: ' . $globals->asso('logo_mime'));
             header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
             header('Last-Modified:' . gmdate('D, d M Y H:i:s') . ' GMT');
             header('Cache-Control: no-cache, must-revalidate');
@@ -339,7 +335,7 @@ class XnetGrpModule extends PLModule
             $users = $globals->asso()->getMembers($sort, NB_PER_PAGE, $ofs * NB_PER_PAGE);
             $count = $globals->asso()->getMemberCount();
         }
-        $page->assign('pages', ($count + NB_PER_PAGE - 1) / NB_PER_PAGE);
+        $page->assign('pages', floor(($count + NB_PER_PAGE - 1) / NB_PER_PAGE));
         $page->assign('current', $ofs);
         $page->assign('order', $sort);
         $page->assign('users', $users);
index e629466..3e9bc0e 100644 (file)
@@ -242,10 +242,7 @@ Bienvenue {$smarty.session.display_name}{if $birthday}
             <img alt="Sommaire" title="Remonter tout en haut" src="images/up.png"/>
           </a>
         </div>
-        Annonce proposée par
-        <a href="profile/{$ev.hruid}" class="popup2">
-          {$ev.prenom} {$ev.nom} {$ev.promo_display}
-        </a>
+        Annonce proposée par {profile user=$ev.user_id sex=false promo=true}
       </td>
     </tr>
   </table>
index ee05e60..4755dc5 100644 (file)
@@ -128,9 +128,9 @@ Le groupe {$asso->nom} compte {$nb_tot} membres&nbsp;:
   {/foreach}
 </table>
 
-{if $pages ge 1}
+{if $pages gt 1}
 <p class="descr" style="text-align: center">
-{section name="links" loop=$pages min=1}
+{section name="links" loop=$pages}
 {if $smarty.section.links.index eq $current}
 <span class="erreur">{$smarty.section.links.iteration}</span>
 {else}