Merge commit 'origin/fusionax' into account
authorStéphane Jacob <sj@m4x.org>
Tue, 21 Jul 2009 13:49:45 +0000 (15:49 +0200)
committerStéphane Jacob <sj@m4x.org>
Tue, 21 Jul 2009 13:49:45 +0000 (15:49 +0200)
161 files changed:
Makefile
bin/cron/notifs.birthday.php
classes/group.php [new file with mode: 0644]
classes/platalglobals.php.in
classes/platallogger.php
classes/profile.php [new file with mode: 0644]
classes/user.php
classes/userfilter.php [new file with mode: 0644]
classes/xnetpage.php
classes/xnetsession.php
classes/xorgsession.php
configs/platal.ini
htdocs/css/base.css
htdocs/css/keynote.css
htdocs/javascript/.gitignore
htdocs/webredirect.php
include/banana/forum.inc.php
include/banana/hooks.inc.php
include/banana/ml.inc.php
include/common.inc.php
include/education.func.inc.php
include/emails.combobox.inc.php
include/emails.inc.php
include/googleapps.inc.php
include/marketing.inc.php
include/massmailer.inc.php
include/notifs.inc.php
include/secure_hash.inc.php [deleted file]
include/synchro_ax.inc.php [deleted file]
include/user.func.inc.php
include/userset.inc.php
include/validations.inc.php
include/validations/aliases.inc.php
include/validations/homonymes.inc.php
include/validations/listes.inc.php
include/validations/marketing.inc.php
include/vcard.inc.php
include/wiki/farmconfig.php
modules/admin.php
modules/admin/homonyms.inc.php [moved from include/homonymes.inc.php with 63% similarity]
modules/auth.php
modules/auth/auth.inc.php
modules/axletter.php
modules/axletter/axletter.inc.php
modules/carnet.php
modules/carnet/feed.inc.php
modules/email.php
modules/events.php
modules/events/feed.inc.php
modules/forums.php
modules/fusionax.php
modules/gadgets.php
modules/googleapps.php
modules/lists.php
modules/lists/lists.inc.php
modules/marketing.php
modules/newsletter.php
modules/payment.php
modules/payment/money/cyberpaiement.inc.php
modules/payment/money/paypal.inc.php
modules/platal.php
modules/profile.php
modules/profile/addresses.inc.php
modules/profile/decos.inc.php
modules/profile/general.inc.php
modules/profile/groups.inc.php
modules/profile/jobs.inc.php
modules/profile/mentor.inc.php
modules/profile/page.inc.php
modules/profile/skills.inc.php
modules/register.php
modules/register/register.inc.php
modules/search.php
modules/stats.php
modules/survey/survey.inc.php
modules/xnetevents.php
modules/xnetevents/xnetevents.inc.php
modules/xnetgrp.php
modules/xnetgrp/feed.inc.php
modules/xnetgrp/mail.inc.php
modules/xnetlists.php
plugins/function.profile.php [moved from include/rss.inc.php with 60% similarity]
plugins/insert.getName.php [deleted file]
templates/admin/accounts.tpl
templates/admin/dead_but_active.tpl
templates/admin/deces_promo.tpl
templates/admin/homonymes.tpl
templates/admin/utilisateurs.tpl
templates/admin/wiki.tpl
templates/axletter/admin.tpl
templates/axletter/letter.mail.tpl
templates/carnet/index.tpl
templates/carnet/mescontacts.tpl
templates/carnet/notifs.tpl
templates/carnet/panel.tpl
templates/carnet/rss.tpl
templates/core/password_prompt.tpl
templates/emails/alias.tpl
templates/emails/broken-web.mail.tpl [new file with mode: 0644]
templates/emails/broken.tpl
templates/emails/send.tpl
templates/events/admin.tpl
templates/events/index.tpl
templates/events/rss.tpl
templates/gadgets/ig-events.tpl
templates/include/minifiche.tpl
templates/include/plview.minifiche.tpl
templates/marketing/promo.tpl
templates/marketing/relance.tpl
templates/marketing/this_week.tpl
templates/marketing/volontaire.tpl
templates/newsletter/nl.mail.tpl
templates/payment/xnet.tpl
templates/platal/changeLog.tpl
templates/platal/filrss.tpl
templates/platal/preferences.tpl
templates/platal/webredirect.tpl
templates/profile/general.tpl
templates/skin/common.bandeau.tpl
templates/skin/common.header.tpl
templates/stats/profile.tpl
templates/xnet/skin.tpl
templates/xnetevents/admin.tpl
templates/xnetevents/calendar.tpl
templates/xnetevents/csv.tpl
templates/xnetevents/edit.tpl
templates/xnetevents/index.tpl
templates/xnetevents/subscribe.tpl
templates/xnetgrp/announce-admin.tpl
templates/xnetgrp/announce-edit.tpl
templates/xnetgrp/announce-rss.tpl
templates/xnetgrp/annuaire-csv.tpl
templates/xnetgrp/annuaire.tpl
templates/xnetgrp/asso.tpl
templates/xnetgrp/edit.tpl
templates/xnetgrp/form.announce.tpl
templates/xnetgrp/forum.tpl
templates/xnetgrp/inscrire.tpl
templates/xnetgrp/mail.tpl
templates/xnetgrp/membres-add.tpl
templates/xnetgrp/membres-del.tpl
templates/xnetgrp/membres-edit.tpl
templates/xnetgrp/membres-new-search.tpl
templates/xnetgrp/subscribe-valid.tpl
templates/xnetgrp/unsubscription-notif.mail.tpl
templates/xnetlists/alias-admin.tpl
templates/xnetlists/alias-create.tpl
templates/xnetlists/create.tpl
templates/xnetlists/index.tpl
templates/xnetlists/sync.tpl
upgrade/account/00_account.sql [new file with mode: 0644]
upgrade/account/01_profiles.sql [new file with mode: 0644]
upgrade/account/02_forums.sql [new file with mode: 0644]
upgrade/account/03_carnet.sql [new file with mode: 0644]
upgrade/account/04_carva.sql [new file with mode: 0644]
upgrade/account/05_emails.sql [new file with mode: 0644]
upgrade/account/99_insertion.sql [new file with mode: 0644]
upgrade/account/README [new file with mode: 0644]
upgrade/account/birthday.php [new symlink]
upgrade/account/connect.db.inc.php [new symlink]
upgrade/account/upgrade.sh [new file with mode: 0644]

index ba24d7e..446aedd 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -28,6 +28,9 @@ all: build
 
 build: core conf banana wiki openid medals jquery
 
+check:
+       @!(find . -name '*.php' -exec php -l {} ";" | grep -v 'No syntax errors detected')
+
 q:
        @echo -e "Code statistics\n"
        @sloccount $(filter-out wiki/ spool/, $(wildcard */)) 2> /dev/null | egrep '^[a-z]*:'
@@ -161,10 +164,13 @@ $(MEDAL_THUMBNAILS): $(subst /medals/thumb/,/medals/,$(@F))
 JQUERY_PLUGINS=color
 JQUERY_PLUGINS_PATHES=$(addprefix htdocs/javascript/jquery.,$(addsuffix .js,$(JQUERY_PLUGINS)))
 
+JQUERY_UI=core tabs
+JQUERY_UI_PATHES=$(addprefix htdocs/javascript/ui.,$(addsuffix .js,$(JQUERY_UI)))
+
 # TODO: jquery.autocomplete.js should rather be downloaded from an official source. The issue
 # is that the version we use is not available anymore on the Internet, and the latest version
 # we could use is not backward compatible with our current code.
-jquery: htdocs/javascript/jquery.js $(JQUERY_PLUGINS_PATHES)
+jquery: htdocs/javascript/jquery.js $(JQUERY_PLUGINS_PATHES) $(JQUERY_UI_PATHES)
 
 htdocs/javascript/jquery.js: DOWNLOAD_SRC = http://jquery.com/src/jquery-latest.min.js
 htdocs/javascript/jquery.js:
@@ -174,7 +180,11 @@ $(JQUERY_PLUGINS_PATHES): DOWNLOAD_SRC = http://plugins.jquery.com/files/$(@F).t
 $(JQUERY_PLUGINS_PATHES):
        @$(download)
 
+$(JQUERY_UI_PATHES): DOWNLOAD_SRC = http://ui.jquery.com/latest/ui/$(@F)
+$(JQUERY_UI_PATHES):
+       @$(download)
+
 ################################################################################
 
-.PHONY: build dist clean core wiki build-wiki banana htdocs/images/banana htdocs/css/banana.css include/banana/banana.inc.php http*
+.PHONY: build dist clean core wiki build-wiki banana htdocs/images/banana htdocs/css/banana.css include/banana/banana.inc.php http* check
 
index 46c2ae0..96516b8 100755 (executable)
 
 require('./connect.db.inc.php');
 
-$date  = date('Y-m-d', time() + 7 * 24*60*60);
-$stamp = date('Ymd000000');
-$like  = date('%-m-d', time() + 7 * 24*60*60);
-
-XDB::execute("DELETE FROM  watch_ops
-                    WHERE  cid = 4 AND date < CURDATE()");
-
-XDB::execute("INSERT INTO  watch_ops (uid, cid, known, date)
-                   SELECT  user_id, 4, $stamp, '$date'
-                     FROM  auth_user_md5
-                    WHERE  naissance LIKE '$like' AND deces=0");
-
+$it = 0;
+do {
+    XDB::execute('UPDATE  profiles
+                     SET  next_birthday = DATE_ADD(next_birthday, INTERVAL 1 YEAR)
+                   WHERE  (next_birthday != 0 AND next_birthday IS NOT NULL AND next_birthday < CURDATE())
+                           AND deathdate IS NULL');
+    ++$it;
+    $affected = XDB::affectedRows();
+    echo "Iteration $it => $affected changes\n";
+} while ($affected > 0);
 
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
 ?>
diff --git a/classes/group.php b/classes/group.php
new file mode 100644 (file)
index 0000000..c75191b
--- /dev/null
@@ -0,0 +1,98 @@
+<?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                *
+ ***************************************************************************/
+
+class Group
+{
+    public $id;
+    public $shortname;
+    private $data = array();
+
+    private function __construct(array $data)
+    {
+        foreach ($data as $key=>$value) {
+            $this->data[$key] = $value;
+        }
+        $this->id = intval($this->data['id']);
+        $this->shortname = $this->data['diminutif'];
+    }
+
+    public function __get($name)
+    {
+        if (property_exists($this, $name)) {
+            return $this->$name;
+        }
+
+        if (isset($this->data[$name])) {
+            return $this->data[$name];
+        }
+
+        return null;
+    }
+
+    public function __isset($name)
+    {
+        return property_exists($this, $name) || isset($this->data[$name]);
+    }
+
+    private function getUF($admin = false, $extra_cond = null, $sort = null)
+    {
+        $cond = new UFC_Group($this->id, $admin);
+        if (!is_null($extra_cond)) {
+            $cond = new UFC_And($cond, $extra_cond);
+        }
+        return new UserFilter($cond, $sort);
+    }
+
+    public function getMembers($extra_cond = null, $sort = null)
+    {
+        return $this->getUF(false, $extra_cond, $sort);
+    }
+
+    public function getAdmins($extra_cond = null, $sort = null)
+    {
+        return $this->getUF(true, $extra_cond, $sort);
+    }
+
+    static public function get($id)
+    {
+        if (!$id) {
+            return null;
+        }
+        if (ctype_digit($id)) {
+            $where = XDB::format('id = {?}', $id);
+        } else {
+            $where = XDB::format('diminutif = {?}', $id);
+        }
+        $res = XDB::query('SELECT  a.*, d.nom AS domnom,
+                                   FIND_IN_SET(\'wiki_desc\', a.flags) AS wiki_desc,
+                                   FIND_IN_SET(\'notif_unsub\', a.flags) AS notif_unsub
+                             FROM  groupex.asso AS a
+                        LEFT JOIN  groupex.dom  AS d ON d.id = a.dom
+                            WHERE  ' . $where);
+        if ($res->numRows() != 1) {
+            return null;
+        }
+        return new Group($res->fetchOneAssoc());
+    }
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
index 94803e8..5d8493e 100644 (file)
@@ -49,47 +49,32 @@ class PlatalGlobals extends PlGlobals
         $this->bootstrap(array('NbValid'), array($this, 'updateNbValid'));
     }
 
-    public function asso($key=null)
+    public function asso($key = null)
     {
         static $aid = null;
 
-        if (is_null($aid)) {
+        if (isset($GLOBALS['IS_XNET_SITE']) && is_null($aid)) {
             $gp = Get::v('n');
             if ($p = strpos($gp, '/')) {
                 $gp = substr($gp, 0, $p);
             }
 
-            if ($gp) {
-                $res = XDB::query("SELECT  a.*, d.nom AS domnom,
-                                           FIND_IN_SET('wiki_desc', a.flags) AS wiki_desc,
-                                           FIND_IN_SET('notif_unsub', a.flags) AS notif_unsub,
-                                           FIND_IN_SET('has_ml', a.flags) AS has_ml
-                                     FROM  groupex.asso AS a
-                                LEFT JOIN  groupex.dom  AS d ON d.id = a.dom
-                                    WHERE  diminutif = {?}",
-                                  $gp);
-                if (!($aid = $res->fetchOneAssoc())) {
-                    $aid = array();
-                }
-            } else {
-                $aid = array();
-            }
+            $aid = Group::get($gp);
         }
         if (empty($key)) {
             return $aid;
-        } elseif ( isset($aid[$key]) ) {
-            return $aid[$key];
+        } elseif (isset($aid->$key) ) {
+            return $aid->$key;
         } else {
             return null;
         }
     }
 
-
     public function updateNbIns()
     {
         $res = XDB::query("SELECT  COUNT(*)
-                             FROM  auth_user_md5
-                            WHERE  perms IN ('admin','user') AND deces=0");
+                             FROM  accounts
+                            WHERE  state = 'active'");
         $cnt = $res->fetchOneCell();
         $this->changeDynamicConfig(array('NbIns' => $cnt));
     }
index 7ebdab0..447ff9e 100644 (file)
@@ -45,11 +45,8 @@ class PlatalLogger extends PlLogger
         $this->session = $this->writeSession($uid, $suid);
 
         // retrieve available actions
-        $res = XDB::iterRow("SELECT id, text FROM logger.actions");
-
-        while (list($action_id, $action_text) = $res->next()) {
-            $this->actions[$action_text] = $action_id;
-        }
+        $this->actions = XDB::fetchAllAssoc('text', 'SELECT  id, text
+                                                       FROM  logger.actions');
     }
 
     /** Creates a new session entry in database and return its ID.
@@ -74,8 +71,8 @@ class PlatalLogger extends PlLogger
             $proxy = 'proxy';
         }
 
-        XDB::execute("INSERT INTO logger.sessions
-                         SET uid={?}, host={?}, ip={?}, forward_ip={?}, forward_host={?}, browser={?}, suid={?}, flags={?}",
+        XDB::execute("INSERT INTO  logger.sessions
+                              SET  uid={?}, host={?}, ip={?}, forward_ip={?}, forward_host={?}, browser={?}, suid={?}, flags={?}",
                      $uid, $host, ip_to_uint($ip), ip_to_uint($forward_ip), $forward_host, $browser, $suid, $proxy);
         if ($forward_ip) {
             $this->proxy_ip = $ip;
@@ -109,8 +106,8 @@ class PlatalLogger extends PlLogger
     public function log($action, $data = null)
     {
         if (isset($this->actions[$action])) {
-            XDB::execute("INSERT INTO logger.events
-                             SET session={?}, action={?}, data={?}",
+            XDB::execute("INSERT INTO  logger.events
+                                  SET  session={?}, action={?}, data={?}",
                          $this->session, $this->actions[$action], $data);
         } else {
             trigger_error("PlLogger: unknown action, $action", E_USER_WARNING);
diff --git a/classes/profile.php b/classes/profile.php
new file mode 100644 (file)
index 0000000..6e68dc9
--- /dev/null
@@ -0,0 +1,454 @@
+<?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                *
+ ***************************************************************************/
+
+class Profile
+{
+    static private $v_values = array('public'  => array('public'),
+                                     'ax'      => array('ax', 'public'),
+                                     'private' => array('private', 'ax', 'public'));
+    const VISIBILITY_PUBLIC  = 'public';
+    const VISIBILITY_AX      = 'ax';
+    const VISIBILITY_PRIVATE = 'private';
+
+    const ADDRESS_MAIN       = 0x000001;
+    const ADDRESS_PERSO      = 0x000002;
+    const ADDRESS_PRO        = 0x000004;
+    const ADDRESS_ALL        = 0x000006;
+    const ADDRESS_POSTAL     = 0x000008;
+
+    const EDUCATION_MAIN     = 0x000010;
+    const EDUCATION_EXTRA    = 0x000020;
+    const EDUCATION_ALL      = 0x000040;
+    const EDUCATION_FINISHED = 0x000080;
+    const EDUCATION_CURRENT  = 0x000100;
+
+    const JOBS_MAIN          = 0x001000;
+    const JOBS_ALL           = 0x002000;
+    const JOBS_FINISHED      = 0x004000;
+    const JOBS_CURRENT       = 0x008000;
+
+    const NETWORKING_ALL     = 0x000000;
+    const NETWORKING_WEB     = 0x010000;
+    const NETWORKING_IM      = 0x020000;
+    const NETWORKING_SOCIAL  = 0x040000;
+
+    private $pid;
+    private $hrpid;
+    private $data = array();
+
+    private $visibility = null;
+
+    private function __construct(array $data)
+    {
+        $this->data = $data;
+        $this->pid = $this->data['pid'];
+        $this->hrpid = $this->data['hrpid'];
+        if (!S::logged()) {
+            $this->setVisibilityLevel(self::VISIBILITY_PUBLIC);
+        }
+    }
+
+    public function id()
+    {
+        return $this->pid;
+    }
+
+    public function hrid()
+    {
+        return $this->hrpid;
+    }
+
+    public function promo()
+    {
+        return $this->promo;
+    }
+
+    /** Print a name with the given formatting:
+     * %s = • for women
+     * %f = firstname
+     * %l = lastname
+     * %F = fullname
+     * %S = shortname
+     * %p = promo
+     */
+    public function name($format)
+    {
+        return str_replace(array('%s', '%f', '%l', '%F', '%S', '%p'),
+                           array($this->isFemale() ? '•' : '',
+                                 $this->first_name, $this->last_name,
+                                 $this->full_name, $this->short_name,
+                                 $this->promo), $format);
+    }
+
+    public function fullName($with_promo = false)
+    {
+        if ($with_promo) {
+            return $this->full_name . ' (' . $this->promo . ')';
+        }
+        return $this->full_name;
+    }
+
+    public function shortName($with_promo = false)
+    {
+        if ($with_promo) {
+            return $this->short_name . ' (' . $this->promo . ')';
+        }
+        return $this->short_name;
+    }
+
+    public function firstName()
+    {
+        return $this->firstname;
+    }
+
+    public function lastName()
+    {
+        return $this->lastname;
+    }
+
+    public function isFemale()
+    {
+        return $this->sex == PlUser::GENDER_FEMALE;
+    }
+
+    public function data()
+    {
+        $this->first_name;
+        return $this->data;
+    }
+
+    public function __get($name)
+    {
+        if (property_exists($this, $name)) {
+            return $this->$name;
+        }
+
+        if (isset($this->data[$name])) {
+            return $this->data[$name];
+        }
+
+        return null;
+    }
+
+    public function __isset($name)
+    {
+        return property_exists($this, $name) || isset($this->data[$name]);
+    }
+
+    public function setVisibilityLevel($visibility)
+    {
+        if ($visibility != self::VISIBILITY_PRIVATE 
+         && $visibility != self::VISIBILITY_AX 
+         && $visibility != self::VISIBILITY_PUBLIC) {
+            Platal::page()->kill("Visibility invalide: " . $visibility);
+        }
+        $this->visibility = self::$v_values[$visibility];
+        if ($this->mobile && !in_array($this->modbile_pub, $this->visibility)) {
+            unset($this->data['mobile']);
+        }
+    }
+
+
+    /* Addresses
+     */
+    public function getAddresses($flags, $limit = null)
+    {
+        $where = XDB::format('pa.pid = {?}', $this->id());
+        if ($flags & self::ADDRESS_MAIN) {
+            $where .= ' AND FIND_IN_SET(\'current\', pa.flags)';
+        }
+        if ($flags & self::ADDRESS_POSTAL) {
+            $where .= ' AND FIND_IN_SET(\'mail\', pa.flags)';
+        }
+        if ($this->visibility) {
+            $where .= ' AND pa.pub IN ' . XDB::formatArray($this->visibility);
+        }
+        $type = array();
+        if ($flags & self::ADDRESS_PRO) {
+            $type[] = 'job';
+        }
+        if ($flags & self::ADDRESS_PERSO) {
+            $type[] = 'home';
+        }
+        if (count($type) > 0) {
+            $where .= ' AND pa.type IN ' . XDB::formatArray($type);
+        }
+        $limit = is_null($limit) ? '' : XDB::format('LIMIT {?}', (int)$limit);
+        return XDB::iterator('SELECT  pa.text, pa.postalCode, pa.type, pa.latitude, pa.longitude,
+                                      gl.name AS locality, gas.name AS subAdministrativeArea,
+                                      ga.name AS administrativeArea, gc.countryFR AS country,
+                                      FIND_IN_SET(\'current\', pa.flags) AS current,
+                                      FIND_IN_SET(\'temporary\', pa.flags) AS temporary,
+                                      FIND_IN_SET(\'secondary\', pa.flags) AS secondary,
+                                      FIND_IN_SET(\'mail\', pa.flags) AS mail, pa.type
+                                FROM  profile_addresses AS pa
+                           LEFT JOIN  geoloc_localities AS gl ON (gl.id = pa.localityId)
+                           LEFT JOIN  geoloc_administrativeareas AS ga ON (ga.id = pa.administrativeAreaId)
+                           LEFT JOIN  geoloc_administrativeareas AS gas ON (gas.id = pa.subAdministrativeAreaId)
+                           LEFT JOIN  geoloc_countries AS gc ON (gc.iso_3166_1_a2 = pa.countryId)
+                               WHERE  ' . $where . '
+                            ORDER BY  pa.id
+                                      ' . $limit);
+    }
+
+    public function getMainAddress()
+    {
+        $it = $this->getAddresses(self::ADDRESS_PERSO | self::ADDRESS_MAIN);
+        if ($it->total() == 0) {
+            return null;
+        } else {
+            return $it->next();
+        }
+    }
+
+
+    /* Educations
+     */
+    public function getEducations($flags, $limit = null)
+    {
+        $where = XDB::format('pe.uid = {?}', $this->id());
+        if ($flags & self::EDUCATION_MAIN) {
+            $where .= ' AND FIND_IN_SET(\'primary\', pe.flags)';
+        } else if ($flags & self::EDUCATION_EXTRA) {
+            $where .= ' AND NOT FIND_IN_SET(\'primary\', pe.flags)';
+        } else if ($flags & self::EDUCATION_FINISHED) {
+            $where .= ' AND pe.grad_year <= YEAR(CURDATE())';
+        } else if ($flags & self::EDUCATION_CURRENT) {
+            $where .= ' AND pe.grad_year > YEAR(CURDATE())';
+        }
+        $limit = is_null($limit) ? '' : XDB::format('LIMIT {?}', (int)$limit);
+        return XDB::iterator('SELECT  pe.entry_year, pe.grad_year, pe.program,
+                                      pee.name AS school, pee.abbreviation AS school_short, pee.url AS school_url, gc.countryFR AS country,
+                                      pede.degree, pede.abbreviation AS degree_short, pede.level AS degree_level, pefe.field,
+                                      FIND_IN_SET(\'primary\', pe.flags) AS prim
+                                FROM  profile_education AS pe
+                          INNER JOIN  profile_education_enum AS pee ON (pe.eduid = pee.id)
+                           LEFT JOIN  geoloc_countries AS gc ON (gc.iso_3166_1_a2 = pee.country)
+                          INNER JOIN  profile_education_degree_enum AS pede ON (pe.degreeid = pede.id)
+                           LEFT JOIN  profile_education_field_enum AS pefe ON (pe.fieldid = pefe.id)
+                               WHERE  ' . $where . '
+                            ORDER BY  NOT FIND_IN_SET(\'primary\', pe.flags), pe.entry_year, pe.id
+                                      ' . $limit);
+    }
+
+    public function getExtraEducations($limit = null)
+    {
+        return $this->getEducations(self::EDUCATION_EXTRA, $limit);
+    }
+
+
+    /** Networking
+     */
+
+    public function getNetworking($flags, $limit = null)
+    {
+        $where = XDB::format('pn.uid = {?}', $this->id());
+        if ($flags & self::NETWORKING_WEB) {
+            $where .= ' AND pn.network_type = 0'; // XXX hardcoded reference to web site index
+        }
+        if ($this->visibility) {
+            $where .= ' AND pn.pub IN ' . XDB::formatArray($this->visibility);
+        }
+        $limit = is_null($limit) ? '' : XDB::format('LIMIT {?}', (int)$limit);
+        return XDB::iterator('SELECT  pne.name, pne.icon,
+                                      IF (LENGTH(pne.link) > 0, REPLACE(pne.link, \'%s\', pn.address),
+                                                                pn.address) AS address
+                                FROM  profile_networking AS pn
+                          INNER JOIN  profile_networking_enum AS pne ON (pn.network_type = pne.network_type)
+                               WHERE  ' . $where . '
+                            ORDER BY  pn.network_type, pn.nwid
+                                      ' . $limit);
+    }
+
+    public function getWebSite()
+    {
+        $site = $this->getNetworking(self::NETWORKING_WEB, 1);
+        if ($site->total() != 1) {
+            return null;
+        }
+        $site = $site->next();
+        return $site['address'];
+    }
+
+
+    /** Jobs
+     */
+
+    public function getJobs($flags, $limit = null)
+    {
+        $where = XDB::format('pj.uid = {?}', $this->id());
+        $cond  = 'TRUE';
+        if ($this->visibility) {
+            $where .= ' AND pj.pub IN ' . XDB::formatArray($this->visibility);
+            $cond  =  'pj.email_pub IN ' . XDB::formatArray($this->visibility);
+        }
+        $limit = is_null($limit) ? '' : XDB::format('LIMIT {?}', (int)$limit);
+        return XDB::iterator('SELECT  pje.name, pje.acronym, pje.url, pje.email, pje.NAF_code,
+                                      pj.description, pj.url AS user_site,
+                                      IF (' . $cond . ', pj.email, NULL) AS user_email,
+                                      pjfe.name AS function, pjse.name AS sector,
+                                      pjsse.name AS subsector, pjssse.name AS subsubsector
+                                FROM  profile_job AS pj
+                          INNER JOIN  profile_job_enum AS pje ON (pje.id = pj.jobid)
+                           LEFT JOIN  profile_job_function_enum AS pjfe ON (pjfe.id = pj.functionid)
+                           LEFT JOIN  profile_job_sector_enum AS pjse ON (pjse.id = pj.sectorid)
+                           LEFT JOIN  profile_job_subsector_enum AS pjsse ON (pjsse.id = pj.subsectorid)
+                           LEFT JOIN  profile_job_subsubsector_enum AS pjssse ON (pjssse.id = pj.subsubsectorid)
+                               WHERE  ' . $where . '
+                            ORDER BY  pj.id
+                                      ' . $limit);
+    }
+
+    public function getMailJob()
+    {
+        $job = $this->getJobs(self::JOBS_MAIN, 1);
+        if ($job->total() != 1) {
+            return null;
+        }
+        return $job->next();
+    }
+
+
+    public function owner()
+    {
+        return User::getSilent($this);
+    }
+
+    private static function fetchProfileData(array $pids)
+    {
+        if (count($pids) == 0) {
+            return array();
+        }
+        return XDB::fetchAllAssoc('SELECT  p.*, p.sex = \'female\' AS sex, pe.entry_year, pe.grad_year,
+                                           pn_f.name AS firstname, pn_l.name AS lastname, pn_n.name AS nickname,
+                                           IF(pn_uf.name IS NULL, pn_f.name, pn_uf.name) AS firstname_usual,
+                                           IF(pn_ul.name IS NULL, pn_l.name, pn_ul.name) AS lastname_usual,
+                                           pd.promo AS promo, pd.short_name, pd.directory_name AS full_name,
+                                           pp.display_tel AS mobile, pp.pub AS mobile_pub
+                                     FROM  profiles AS p
+                               INNER JOIN  profile_display AS pd ON (pd.pid = p.pid)
+                               INNER JOIN  profile_education AS pe ON (pe.uid = p.pid AND FIND_IN_SET(\'primary\', pe.flags))
+                               INNER JOIN  profile_name AS pn_f ON (pn_f.pid = p.pid
+                                                                    AND pn_f.typeid = ' . self::getNameTypeId('lastname', true) . ')
+                               INNER JOIN  profile_name AS pn_l ON (pn_l.pid = p.pid
+                                                                    AND pn_l.typeid = ' . self::getNameTypeId('firstname', true) . ')
+                                LEFT JOIN  profile_name AS pn_uf ON (pn_uf.pid = p.pid
+                                                                     AND pn_uf.typeid = ' . self::getNameTypeId('lastname_ordinary', true) . ')
+                                LEFT JOIN  profile_name AS pn_ul ON (pn_ul.pid = p.pid
+                                                                     AND pn_ul.typeid = ' . self::getNameTypeId('firstname_ordinary', true) . ')
+                                LEFT JOIN  profile_name AS pn_n ON (pn_n.pid = p.pid 
+                                                                    AND pn_n.typeid = ' . self::getNameTypeId('nickname', true) . ')
+                                LEFT JOIN  profile_phones AS pp ON (pp.uid = p.pid AND pp.link_type = \'user\' AND tel_type = \'mobile\')
+                                    WHERE  p.pid IN ' . XDB::formatArray($pids) . '
+                                 GROUP BY  p.pid');
+    }
+
+    public static function getPID($login)
+    {
+        if ($login instanceof PlUser) {
+            return XDB::fetchOneCell('SELECT  pid
+                                        FROM  account_profiles
+                                       WHERE  uid = {?} AND FIND_IN_SET(\'owner\', perms)',
+                                     $login->id());
+        } else if (ctype_digit($login)) {
+            return XDB::fetchOneCell('SELECT  pid
+                                        FROM  profiles
+                                       WHERE  pid = {?}', $login);
+        } else {
+            return XDB::fetchOneCell('SELECT  pid
+                                        FROM  profiles
+                                       WHERE  hrpid = {?}', $login);
+        }
+    }
+
+
+    /** Return the profile associated with the given login.
+     */
+    public static function get($login)
+    {
+        $pid = self::getPID($login);
+        if (!is_null($pid)) {
+            $data = self::fetchProfileData(array($pid));
+            return new Profile(array_pop($data));
+        } else {
+            /* Let say we can identify a profile using the identifiers of its owner.
+             */
+            if (!($login instanceof PlUser)) {
+                $user = User::getSilent($login);
+                if ($user && $user->hasProfile()) {
+                    return $user->profile();
+                }
+            }
+            return null;
+        }
+    }
+
+    /** Return profiles for the list of pids.
+     */
+    public static function getBulkProfilesWithPIDs(array $pids)
+    {
+        if (count($pids) == 0) {
+            return array();
+        }
+        $data = self::fetchProfileData($pids);
+        $inv = array_flip($pids);
+        $profiles = array();
+        foreach ($data AS $p) {
+            $p = new Profile($p);
+            $key = $inv[$p->id()];
+            $profiles[$key] = $p;
+        }
+        return $profiles;
+    }
+
+    /** Return profiles for uids.
+     */
+    public static function getBulkProfilesWithUIDS(array $uids)
+    {
+        if (count($uids) == 0) {
+            return array();
+        }
+        $table = XDB::fetchAllAssoc('uid', 'SELECT  ap.uid, ap.pid
+                                              FROM  account_profiles AS ap
+                                             WHERE  FIND_IN_SET(\'owner\', ap.perms)
+                                                    AND ap.uid IN ' . XDB::formatArray($uids));
+        return self::getBulkProfilesWithPIDs($table);
+    }
+
+    public static function getNameTypeId($type, $for_sql = false)
+    {
+        if (!S::has('name_types')) {
+            $table = XDB::fetchAllAssoc('type', 'SELECT  id, type
+                                                   FROM  profile_name_enum');
+            S::set('name_types', $table);
+        } else {
+            $table = S::v('name_types');
+        }
+        if ($for_sql) {
+            return XDB::escape($table[$type]);
+        } else {
+            return $table[$type];
+        }
+    }
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
index edd030a..71b21c9 100644 (file)
@@ -21,6 +21,9 @@
 
 class User extends PlUser
 {
+    private $_profile_fetched = false;
+    private $_profile = null;
+
     // Additional fields (non core)
     protected $promo = null;
 
@@ -33,9 +36,28 @@ class User extends PlUser
             throw new UserNotFoundException();
         }
 
+        if ($login instanceof User) {
+            $machin->id();
+        }
+
+        if ($login instanceof Profile) {
+            $this->_profile = $login;
+            $this->_profile_fetched = true;
+            $res = XDB::query('SELECT  ap.uid
+                                 FROM  account_profiles AS ap
+                                WHERE  ap.pid = {?} AND FIND_IN_SET(\'owner\', perms)',
+                              $login->id());
+            if ($res->numRows()) {
+                return $res->fetchOneCell();
+            }
+            throw new UserNotFoundException();
+        }
+
         // If $data is an integer, fetches directly the result.
         if (is_numeric($login)) {
-            $res = XDB::query("SELECT user_id FROM auth_user_md5 WHERE user_id = {?}", $login);
+            $res = XDB::query('SELECT  a.uid
+                                 FROM  accounts AS a
+                                WHERE  a.uid = {?}', $login);
             if ($res->numRows()) {
                 return $res->fetchOneCell();
             }
@@ -44,7 +66,9 @@ class User extends PlUser
         }
 
         // Checks whether $login is a valid hruid or not.
-        $res = XDB::query("SELECT user_id FROM auth_user_md5 WHERE hruid = {?}", $login);
+        $res = XDB::query('SELECT  a.uid
+                             FROM  accounts AS a
+                            WHERE  a.hruid = {?}', $login);
         if ($res->numRows()) {
             return $res->fetchOneCell();
         }
@@ -59,23 +83,24 @@ class User extends PlUser
         // Checks if $login is a valid alias on the main domains.
         list($mbox, $fqdn) = explode('@', $login);
         if ($fqdn == $globals->mail->domain || $fqdn == $globals->mail->domain2) {
-            $res = XDB::query("SELECT  u.user_id
-                                 FROM  auth_user_md5 AS u
-                           INNER JOIN  aliases AS a ON (a.id = u.user_id AND a.type IN ('alias', 'a_vie'))
-                                WHERE  a.alias = {?}", $mbox);
+            $res = XDB::query('SELECT  a.uid
+                                 FROM  accounts AS a
+                           INNER JOIN  aliases AS al ON (al.id = a.uid AND al.type IN (\'alias\', \'a_vie\'))
+                                WHERE  al.alias = {?}', $mbox);
             if ($res->numRows()) {
                 return $res->fetchOneCell();
             }
 
+            /** TODO: implements this by inspecting the profile.
             if (preg_match('/^(.*)\.([0-9]{4})$/u', $mbox, $matches)) {
-                $res = XDB::query("SELECT  u.user_id
-                                     FROM  auth_user_md5 AS u
-                               INNER JOIN  aliases AS a ON (a.id = u.user_id AND a.type IN ('alias', 'a_vie'))
-                                    WHERE  a.alias = {?} AND u.promo = {?}", $matches[1], $matches[2]);
+                $res = XDB::query('SELECT  a.uid
+                                     FROM  accounts AS a
+                               INNER JOIN  aliases AS al ON (al.id = a.uid AND al.type IN ('alias', 'a_vie'))
+                                    WHERE  al.alias = {?} AND a.promo = {?}', $matches[1], $matches[2]);
                 if ($res->numRows() == 1) {
                     return $res->fetchOneCell();
                 }
-            }
+            }*/
 
             throw new UserNotFoundException();
         }
@@ -89,10 +114,10 @@ class User extends PlUser
             if ($redir = $res->fetchOneCell()) {
                 // We now have a valid alias, which has to be translated to an hruid.
                 list($alias, $alias_fqdn) = explode('@', $redir);
-                $res = XDB::query("SELECT  u.user_id
-                                     FROM  auth_user_md5 AS u
-                                LEFT JOIN  aliases AS a ON (a.id = u.user_id AND a.type IN ('alias', 'a_vie'))
-                                    WHERE  a.alias = {?}", $alias);
+                $res = XDB::query("SELECT  a.uid
+                                     FROM  accounts AS a
+                                LEFT JOIN  aliases AS al ON (al.id = a.uid AND al.type IN ('alias', 'a_vie'))
+                                    WHERE  al.alias = {?}", $alias);
                 if ($res->numRows()) {
                     return $res->fetchOneCell();
                 }
@@ -101,10 +126,18 @@ class User extends PlUser
             throw new UserNotFoundException();
         }
 
+        // Looks for an account with the given email.
+        $res = XDB::query('SELECT  a.uid
+                             FROM  accounts AS a
+                            WHERE  a.email = {?}', $login);
+        if ($res->numRows() == 1) {
+            return $res->fetchOneCell();
+        }
+
         // Otherwise, we do suppose $login is an email redirection.
-        $res = XDB::query("SELECT  u.user_id
-                             FROM  auth_user_md5 AS u
-                        LEFT JOIN  emails AS e ON (e.uid = u.user_id)
+        $res = XDB::query("SELECT  a.uid
+                             FROM  accounts AS a
+                        LEFT JOIN  emails AS e ON (e.uid = a.uid)
                             WHERE  e.email = {?}", $login);
         if ($res->numRows() == 1) {
             return $res->fetchOneCell();
@@ -113,32 +146,54 @@ class User extends PlUser
         throw new UserNotFoundException($res->fetchColumn(1));
     }
 
+    protected static function loadMainFieldsFromUIDs(array $uids)
+    {
+        global $globals;
+        $joins = '';
+        $fields = array();
+        if ($globals->asso('id')) {
+            $joins .= XDB::format("LEFT JOIN groupex.membres AS gpm ON (gpm.uid = a.uid AND gpm.asso_id = {?})\n", $globals->asso('id'));
+            $fields[] = 'gpm.perms AS group_perms';
+            $fields[] = 'gpm.comm AS group_comm';
+        }
+        if (count($fields) > 0) {
+            $fields = ', ' . implode(', ', $fields);
+        } else {
+            $fields = '';
+        }
+        $uids = array_map(array('XDB', 'escape'), $uids);
+        return XDB::iterator('SELECT  a.uid, a.hruid, a.registration_date,
+                                      CONCAT(af.alias, \'@' . $globals->mail->domain . '\') AS forlife,
+                                      CONCAT(ab.alias, \'@' . $globals->mail->domain . '\') AS bestalias,
+                                      a.full_name, a.display_name, a.sex = \'female\' AS gender,
+                                      IF(a.state = \'active\', at.perms, \'\') AS perms,
+                                      a.email_format, a.is_admin, a.state, a.type, a.skin,
+                                      FIND_IN_SET(\'watch\', a.flags) AS watch, a.comment,
+                                      a.weak_password IS NOT NULL AS weak_access,
+                                      a.token IS NOT NULL AS token_access,
+                                      (e.email IS NULL AND NOT FIND_IN_SET(\'googleapps\', eo.storage)) AND a.state != \'pending\' AS lost
+                                      ' . $fields . '
+                                FROM  accounts AS a
+                          INNER JOIN  account_types AS at ON (at.type = a.type)
+                           LEFT JOIN  aliases AS af ON (af.id = a.uid AND af.type = \'a_vie\')
+                           LEFT JOIN  aliases AS ab ON (ab.id = a.uid AND FIND_IN_SET(\'bestalias\', ab.flags))
+                           LEFT JOIN  emails AS e ON (e.uid = a.uid AND e.flags = \'active\')
+                           LEFT JOIN  email_options AS eo ON (eo.uid = a.uid)
+                                   ' . $joins . '
+                               WHERE  a.uid IN (' . implode(', ', $uids) . ')
+                            GROUP BY  a.uid');
+    }
+
     // Implementation of the data loader.
     protected function loadMainFields()
     {
         if ($this->hruid !== null && $this->forlife !== null
             && $this->bestalias !== null && $this->display_name !== null
-            && $this->full_name !== null && $this->promo !== null && $this->perms !== null
+            && $this->full_name !== null && $this->perms !== null
             && $this->gender !== null && $this->email_format !== null) {
             return;
         }
-
-        global $globals;
-        $res = XDB::query("SELECT  u.hruid, d.promo,
-                                   CONCAT(af.alias, '@{$globals->mail->domain}') AS forlife,
-                                   CONCAT(ab.alias, '@{$globals->mail->domain}') AS bestalias,
-                                   CONCAT(u.prenom, ' ', IF(u.nom_usage <> '', u.nom_usage, u.nom)) AS full_name,
-                                   IF(u.prenom != '', u.prenom, u.nom) AS display_name,
-                                   FIND_IN_SET('femme', u.flags) AS gender,
-                                   q.core_mail_fmt AS email_format,
-                                   u.perms
-                             FROM  auth_user_md5 AS u
-                       INNER JOIN  profile_display AS d ON (d.pid = u.user_id)
-                        LEFT JOIN  auth_user_quick AS q ON (q.user_id = u.user_id)
-                        LEFT JOIN  aliases AS af ON (af.id = u.user_id AND af.type = 'a_vie')
-                        LEFT JOIN  aliases AS ab ON (ab.id = u.user_id AND FIND_IN_SET('bestalias', ab.flags))
-                            WHERE  u.user_id = {?}", $this->user_id);
-        $this->fillFromArray($res->fetchOneAssoc());
+        $this->fillFromArray(self::loadMainFieldsFromUIDs(array($this->user_id))->next());
     }
 
     // Specialization of the fillFromArray method, to implement hacks to enable
@@ -173,9 +228,6 @@ class User extends PlUser
         if (isset($values['mail_fmt'])) {
             $values['email_format'] = $values['mail_fmt'];
         }
-        if (isset($values['email_format'])) {
-            $values['email_format'] = ($values['email_format'] ? self::FORMAT_HTML : self::FORMAT_TEXT);
-        }
 
         parent::fillFromArray($values);
     }
@@ -191,26 +243,240 @@ class User extends PlUser
         if ($this->perms === null) {
              $this->loadMainFields();
         }
-        $this->perm_flags = self::makePerms($this->perms);
+        $this->perm_flags = self::makePerms($this->perms, $this->is_admin);
     }
 
-    // Return the password of the user
+    // We do not want to store the password in the object.
+    // So, fetch it 'on demand'
     public function password()
     {
-        return XDB::fetchOneCell('SELECT  u.password
-                                    FROM  auth_user_md5 AS u
-                                   WHERE  u.user_id = {?}', $this->id());
+        return XDB::fetchOneCell('SELECT  a.password
+                                    FROM  accounts AS a
+                                   WHERE  a.uid = {?}', $this->id());
     }
 
-    // Return permission flags for a given permission level.
-    public static function makePerms($perms)
+    /** Overload PlUser::promo(): there no promo defined for a user in the current
+     * schema. The promo is a field from the profile.
+     */
+    public function promo()
+    {
+        if (!$this->hasProfile()) {
+            return '';
+        }
+        return $this->profile()->promo();
+    }
+
+    public function firstName()
+    {
+        if (!$this->hasProfile()) {
+            return $this->displayName();
+        }
+        return $this->profile()->firstName();
+    }
+
+    public function lastName()
+    {
+        if (!$this->hasProfile()) {
+            return '';
+        }
+        return $this->profile()->lastName();
+    }
+
+    /** Return the main profile attached with this account if any.
+     */
+    public function profile()
+    {
+        if (!$this->_profile_fetched) {
+            $this->_profile_fetched = true;
+            $this->_profile = Profile::get($this);
+        }
+        return $this->_profile;
+    }
+
+    /** Return true if the user has an associated profile.
+     */
+    public function hasProfile()
+    {
+        return !is_null($this->profile());
+    }
+
+    /** Check if the user can edit to given profile.
+     */
+    public function canEdit(Profile $profile)
+    {
+        // XXX: Check permissions (e.g. secretary permission)
+        //      and flags from the profile
+        return XDB::fetchOneCell('SELECT  pid
+                                    FROM  account_profiles
+                                   WHERE  uid = {?} AND pid = {?}',
+                                 $this->id(), $profile->id());
+    }
+
+    /** Get the email alias of the user.
+     */
+    public function emailAlias()
+    {
+        global $globals;
+        $data = $this->emailAliases($globals->mail->alias_dom);
+        if (count($data) > 0) {
+            return array_pop($data);
+        }
+        return null;
+    }
+
+    /** Get all the aliases the user belongs to.
+     */
+    public function emailAliases($domain = null, $type = 'user',  $sub_state = false)
+    {
+        $join = XDB::format('(vr.redirect = {?} OR vr.redirect = {?}) ',
+                             $this->forlifeEmail(), $this->m4xForlifeEmail());
+        $where = '';
+        if (!is_null($domain)) {
+            $where = XDB::format('WHERE v.alias LIKE CONCAT("%@", {?})', $domain);
+        }
+        if (!is_null($type)) {
+            if (empty($where)) {
+                $where = XDB::format('WHERE v.type = {?}', $type);
+            } else {
+                $where .= XDB::format(' AND v.type = {?}', $type);
+            }
+        }
+        if ($sub_state) {
+            return XDB::fetchAllAssoc('alias', 'SELECT  v.alias, vr.redirect IS NOT NULL AS sub
+                                                  FROM  virtual AS v
+                                             LEFT JOIN  virtual_redirect AS vr ON (v.vid = vr.vid AND ' . $join . ')
+                                                 ' . $where);
+        } else {
+            return XDB::fetchColumn('SELECT  v.alias
+                                       FROM  virtual AS v
+                                 INNER JOIN  virtual_redirect AS vr ON (v.vid = vr.vid AND ' . $join . ')
+                                     ' . $where);
+        }
+    }
+
+    /** Get the alternative forlife email
+     * TODO: remove this uber-ugly hack. The issue is that you need to remove
+     * all @m4x.org addresses in virtual_redirect first.
+     * XXX: This is juste to make code more readable, to be remove as soon as possible
+     */
+    public function m4xForlifeEmail()
+    {
+        global $globals;
+        trigger_error('USING M4X FORLIFE', E_USER_NOTICE);
+        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;
+    }
+
+
+    /** Get watch informations
+     */
+    private function fetchWatchData()
     {
-        $flags = new PlFlagSet();
-        if (is_null($flags) || $perms == 'disabled' || $perms == 'ext') {
-            return $flags;
+        if (isset($this->watch_actions)) {
+            return;
         }
+        $watch = XDB::fetchOneAssoc('SELECT  flags AS watch_flags, actions AS watch_actions,
+                                             UNIX_TIMESTAMP(last) AS watch_last
+                                       FROM  watch
+                                      WHERE  uid = {?}', $this->id());
+        $watch['watch_flags'] = new PlFlagSet($watch['watch_flags']);
+        $watch['watch_actions'] = new PlFlagSet($watch['watch_actions']);
+        $watch['watch_promos'] = XDB::fetchColumn('SELECT  promo
+                                                     FROM  watch_promo
+                                                    WHERE  uid = {?}', $this->id());
+        $watch['watch_users'] = XDB::fetchColumn('SELECT  ni_id
+                                                    FROM  watch_nonins
+                                                   WHERE  uid = {?}', $this->id());
+        $this->fillFromArray($watch);
+    }
+
+    public function watch($type)
+    {
+        $this->fetchWatchData();
+        return $this->watch_actions->hasFlag($type);
+    }
+
+    public function watchContacts()
+    {
+        $this->fetchWatchData();
+        return $this->watch_flags->hasFlag('contacts');
+    }
+
+    public function watchEmail()
+    {
+        $this->fetchWatchData();
+        return $this->watch_flags->hasFlag('mail');
+    }
+
+    public function watchPromos()
+    {
+        $this->fetchWatchData();
+        return $this->watch_promos;
+    }
+
+    public function watchUsers()
+    {
+        $this->fetchWatchData();
+        return $this->watch_users;
+    }
+
+    public function watchLast()
+    {
+        $this->fetchWatchData();
+        return $this->watch_last;
+    }
+
+
+    // Contacts
+    private $contacts = null;
+    public function isContact(PlUser &$user)
+    {
+        if (is_null($this->contacts)) {
+            $this->contacts = XDB::fetchAllAssoc('contact', 'SELECT  *
+                                                               FROM  contacts
+                                                              WHERE  uid = {?}',
+                                                 $this->id());
+        }
+        return isset($this->contacts[$user->id()]);
+    }
+
+    // Return permission flags for a given permission level.
+    public static function makePerms($perms, $is_admin)
+    {
+        $flags = new PlFlagSet($perms);
         $flags->addFlag(PERMS_USER);
-        if ($perms == 'admin') {
+        if ($is_admin) {
             $flags->addFlag(PERMS_ADMIN);
         }
         return $flags;
@@ -241,6 +507,82 @@ class User extends PlUser
                $dom != $globals->mail->alias_dom &&
                $dom != $globals->mail->alias_dom2;
     }
+
+    public static function isVirtualEmailAddress($email)
+    {
+        global $globals;
+        if (strpos($email, '@') === false) {
+            return false;
+        }
+
+        list($user, $dom) = explode('@', $email);
+        return $dom == $globals->mail->alias_dom
+            || $dom == $globals->mail->alias_dom2;
+    }
+
+    // Fetch a set of users from a list of UIDs
+    public static function getBulkUsersWithUIDs(array $data, $orig = null, $dest = null, $fetchProfile = true)
+    {
+        // Fetch the list of uids
+        if (is_null($orig)) {
+            $uids = $data;
+        } else {
+            if (is_null($dest)) {
+                $dest = $orig;
+            }
+            $uids = array();
+            foreach ($data as $key=>$entry) {
+                if (isset($entry[$orig])) {
+                    $uids[] = $entry[$orig];
+                }
+            }
+        }
+
+        // Fetch users
+        if (count($uids) == 0) {
+            return $data;
+        }
+        $fields = self::loadMainFieldsFromUIDs($uids);
+        $table = array();
+        if ($fetchProfile) {
+            $profiles = Profile::getBulkProfilesWithUIDS($uids);
+        }
+        while (($list = $fields->next())) {
+            $uid  = $list['uid'];
+            $user = User::getSilentWithValues(null, $list);
+            if ($fetchProfile) {
+                if (isset($profiles[$uid])) {
+                    $user->_profile = $profiles[$uid];
+                }
+                $user->_profile_fetched = true;
+            }
+            $table[$list['uid']] = $user;
+        }
+
+        // Build the result with respect to input order.
+        if (is_null($orig)) {
+            $users = array();
+            foreach ($uids as $key=>$uid) {
+                $users[$key] = $table[$uid];
+            }
+            return $users;
+        } else {
+            foreach ($data as $key=>$entry) {
+                if (isset($entry[$orig])) {
+                    $entry[$dest] = $table[$entry[$orig]];
+                    $data[$key] = $entry;
+                }
+            }
+            return $data;
+        }
+    }
+
+    public static function getBulkUsersFromDB($fetchProfile = true)
+    {
+        $args = func_get_args();
+        $uids = call_user_func_array(array('XDB', 'fetchColumn'), $args);
+        return self::getBulkUsersWithUIDs($uids, null, null, $fetchProfile);
+    }
 }
 
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
diff --git a/classes/userfilter.php b/classes/userfilter.php
new file mode 100644 (file)
index 0000000..ebe69f4
--- /dev/null
@@ -0,0 +1,1190 @@
+<?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                *
+ ***************************************************************************/
+
+
+/******************
+ * CONDITIONS
+ ******************/
+
+interface UserFilterCondition
+{
+    const COND_TRUE  = 'TRUE';
+    const COND_FALSE = 'FALSE';
+
+    /** Check that the given user matches the rule.
+     */
+    public function buildCondition(UserFilter &$uf);
+}
+
+abstract class UFC_OneChild implements UserFilterCondition
+{
+    protected $child;
+
+    public function __construct($child = null)
+    {
+        if (!is_null($child) && ($child instanceof UserFilterCondition)) {
+            $this->setChild($child);
+        }
+    }
+
+    public function setChild(UserFilterCondition &$cond)
+    {
+        $this->child =& $cond;
+    }
+}
+
+abstract class UFC_NChildren implements UserFilterCondition
+{
+    protected $children = array();
+
+    public function __construct()
+    {
+        $children = func_get_args();
+        foreach ($children as &$child) {
+            if (!is_null($child) && ($child instanceof UserFilterCondition)) {
+                $this->addChild($child);
+            }
+        }
+    }
+
+    public function addChild(UserFilterCondition &$cond)
+    {
+        $this->children[] =& $cond;
+    }
+
+    protected function catConds(array $cond, $op, $fallback)
+    {
+        if (count($cond) == 0) {
+            return $fallback;
+        } else if (count($cond) == 1) {
+            return $cond[0];
+        } else {
+            return '(' . implode(') ' . $op . ' (', $cond) . ')';
+        }
+    }
+}
+
+class UFC_True implements UserFilterCondition
+{
+    public function buildCondition(UserFilter &$uf)
+    {
+        return self::COND_TRUE;
+    }
+}
+
+class UFC_False implements UserFilterCondition
+{
+    public function buildCondition(UserFilter &$uf)
+    {
+        return self::COND_FALSE;
+    }
+}
+
+class UFC_Not extends UFC_OneChild
+{
+    public function buildCondition(UserFilter &$uf)
+    {
+        $val = $this->child->buildCondition($uf);
+        if ($val == self::COND_TRUE) {
+            return self::COND_FALSE;
+        } else if ($val == self::COND_FALSE) {
+            return self::COND_TRUE;
+        } else {
+            return 'NOT (' . $val . ')';
+        }
+    }
+}
+
+class UFC_And extends UFC_NChildren
+{
+    public function buildCondition(UserFilter &$uf)
+    {
+        if (empty($this->children)) {
+            return self::COND_FALSE;
+        } else {
+            $true = self::COND_FALSE;
+            $conds = array();
+            foreach ($this->children as &$child) {
+                $val = $child->buildCondition($uf);
+                if ($val == self::COND_TRUE) {
+                    $true = self::COND_TRUE;
+                } else if ($val == self::COND_FALSE) {
+                    return self::COND_FALSE;
+                } else {
+                    $conds[] = $val;
+                }
+            }
+            return $this->catConds($conds, 'AND', $true);
+        }
+    }
+}
+
+class UFC_Or extends UFC_NChildren
+{
+    public function buildCondition(UserFilter &$uf)
+    {
+        if (empty($this->children)) {
+            return self::COND_TRUE;
+        } else {
+            $true = self::COND_TRUE;
+            $conds = array();
+            foreach ($this->children as &$child) {
+                $val = $child->buildCondition($uf);
+                if ($val == self::COND_TRUE) {
+                    return self::COND_TRUE;
+                } else if ($val == self::COND_FALSE) {
+                    $true = self::COND_FALSE;
+                } else {
+                    $conds[] = $val;
+                }
+            }
+            return $this->catConds($conds, 'OR', $true);
+        }
+    }
+}
+
+class UFC_Profile implements UserFilterCondition
+{
+    public function buildCondition(UserFilter &$uf)
+    {
+        return '$PID IS NOT NULL';
+    }
+}
+
+class UFC_Promo implements UserFilterCondition
+{
+
+    private $grade;
+    private $promo;
+    private $comparison;
+
+    public function __construct($comparison, $grade, $promo)
+    {
+        $this->grade = $grade;
+        $this->comparison = $comparison;
+        $this->promo = $promo;
+        if ($this->grade != UserFilter::DISPLAY) {
+            UserFilter::assertGrade($this->grade);
+        }
+    }
+
+    public function buildCondition(UserFilter &$uf)
+    {
+        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);
+        }
+    }
+}
+
+class UFC_Name implements UserFilterCondition
+{
+    const PREFIX   = 1;
+    const SUFFIX   = 2;
+    const PARTICLE = 7;
+    const VARIANTS = 8;
+    const CONTAINS = 3;
+
+    private $type;
+    private $text;
+    private $mode;
+
+    public function __construct($type, $text, $mode)
+    {
+        $this->type = $type;
+        $this->text = $text;
+        $this->mode = $mode;
+    }
+
+    private function buildNameQuery($type, $variant, $where, UserFilter &$uf)
+    {
+        $sub = $uf->addNameFilter($type, $variant);
+        return str_replace('$ME', 'pn' . $sub, $where);
+    }
+
+    public function buildCondition(UserFilter &$uf)
+    {
+        $left = '$ME.name';
+        $op   = ' LIKE ';
+        if (($this->mode & self::PARTICLE) == self::PARTICLE) {
+            $left = 'CONCAT($ME.particle, \' \', $ME.name)';
+        }
+        if (($this->mode & self::CONTAINS) == 0) {
+            $right = XDB::format('{?}', $this->text);
+            $op    = ' = ';
+        } else if (($this->mode & self::CONTAINS) == self::PREFIX) {
+            $right = XDB::format('CONCAT({?}, \'%\')', $this->text);
+        } else if (($this->mode & self::CONTAINS) == self::SUFFIX) {
+            $right = XDB::format('CONCAT(\'%\', {?})', $this->text);
+        } else {
+            $right = XDB::format('CONCAT(\'%\', {?}, \'%\')', $this->text);
+        }
+        $cond = $left . $op . $right;
+        $conds = array($this->buildNameQuery($this->type, null, $cond, $uf));
+        if (($this->mode & self::VARIANTS) != 0 && isset(UserFilter::$name_variants[$this->type])) {
+            foreach (UserFilter::$name_variants[$this->type] as $var) {
+                $conds[] = $this->buildNameQuery($this->type, $var, $cond, $uf);
+            }
+        }
+        return implode(' OR ', $conds);
+    }
+}
+
+class UFC_Dead implements UserFilterCondition
+{
+    private $comparison;
+    private $date;
+
+    public function __construct($comparison = null, $date = null)
+    {
+        $this->comparison = $comparison;
+        $this->date = $date;
+    }
+
+    public function buildCondition(UserFilter &$uf)
+    {
+        $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;
+    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) {
+            $date = 'a.uid IS NOT NULL AND a.state = \'active\'';
+        } else {
+            $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;
+    }
+}
+
+class UFC_ProfileUpdated implements UserFilterCondition
+{
+    private $comparison;
+    private $date;
+
+    public function __construct($comparison = null, $date = null)
+    {
+        $this->comparison = $comparison;
+        $this->date = $date;
+    }
+
+    public function buildCondition(UserFilter &$uf)
+    {
+        return 'p.last_change ' . $this->comparison . XDB::format(' {?}', date('Y-m-d H:i:s', $this->date));
+    }
+}
+
+class UFC_Birthday implements UserFilterCondition
+{
+    private $comparison;
+    private $date;
+
+    public function __construct($comparison = null, $date = null)
+    {
+        $this->comparison = $comparison;
+        $this->date = $date;
+    }
+
+    public function buildCondition(UserFilter &$uf)
+    {
+        return 'p.next_birthday ' . $this->comparison . XDB::format(' {?}', date('Y-m-d', $this->date));
+    }
+}
+
+class UFC_Sex implements UserFilterCondition
+{
+    private $sex;
+    public function __construct($sex)
+    {
+        $this->sex = $sex;
+    }
+
+    public function buildCondition(UserFilter &$uf)
+    {
+        if ($this->sex != User::GENDER_MALE && $this->sex != User::GENDER_FEMALE) {
+            return self::COND_FALSE;
+        } else {
+            return XDB::format('p.sex = {?}', $this->sex == User::GENDER_FEMALE ? 'female' : 'male');
+        }
+    }
+}
+
+class UFC_Group implements UserFilterCondition
+{
+    private $group;
+    private $admin;
+    public function __construct($group, $admin = false)
+    {
+        $this->group = $group;
+        $this->admin = $admin;
+    }
+
+    public function buildCondition(UserFilter &$uf)
+    {
+        $sub = $uf->addGroupFilter($this->group);
+        $where = 'gpm' . $sub . '.perms IS NOT NULL';
+        if ($this->admin) {
+            $where .= ' AND gpm' . $sub . '.perms = \'admin\'';
+        }
+        return $where;
+    }
+}
+
+class UFC_Email implements UserFilterCondition
+{
+    private $email;
+    public function __construct($email)
+    {
+        $this->email = $email;
+    }
+
+    public function buildCondition(UserFilter &$uf)
+    {
+        if (User::isForeignEmailAddress($this->email)) {
+            $sub = $uf->addEmailRedirectFilter($this->email);
+            return XDB::format('e' . $sub . '.email IS NOT NULL OR a.email = {?}', $this->email);
+        } else if (User::isVirtualEmailAddress($this->email)) {
+            $sub = $uf->addVirtualEmailFilter($this->email);
+            return 'vr' . $sub . '.redirect IS NOT NULL';
+        } else {
+            @list($user, $domain) = explode('@', $this->email);
+            $sub = $uf->addAliasFilter($user);
+            return 'al' . $sub . '.alias IS NOT NULL';
+        }
+    }
+}
+
+class UFC_EmailList implements UserFilterCondition
+{
+    private $emails;
+    public function __construct($emails)
+    {
+        $this->emails = $emails;
+    }
+
+    public function buildCondition(UserFilter &$uf)
+    {
+        $email   = null;
+        $virtual = null;
+        $alias   = null;
+        $cond = array();
+
+        if (count($this->emails) == 0) {
+            return UserFilterCondition::COND_TRUE;
+        }
+
+        foreach ($this->emails as $entry) {
+            if (User::isForeignEmailAddress($entry)) {
+                if (is_null($email)) {
+                    $email = $uf->addEmailRedirectFilter();
+                }
+                $cond[] = XDB::format('e' . $email . '.email = {?} OR a.email = {?}', $entry, $entry);
+            } else if (User::isVirtualEmailAddress($entry)) {
+                if (is_null($virtual)) {
+                    $virtual = $uf->addVirtualEmailFilter();
+                }
+                $cond[] = XDB::format('vr' . $virtual . '.redirect IS NOT NULL AND v' . $virtual . '.alias = {?}', $entry);
+            } else {
+                if (is_null($alias)) {
+                    $alias = $uf->addAliasFilter();
+                }
+                @list($user, $domain) = explode('@', $entry);
+                $cond[] = XDB::format('al' . $alias . '.alias = {?}', $user);
+            }
+        }
+        return '(' . implode(') OR (', $cond) . ')';
+    }
+}
+
+abstract class UFC_UserRelated implements UserFilterCondition
+{
+    protected $user;
+    public function __construct(PlUser &$user)
+    {
+        $this->user =& $user;
+    }
+}
+
+class UFC_Contact extends UFC_UserRelated
+{
+    public function buildCondition(UserFilter &$uf)
+    {
+        $sub = $uf->addContactFilter($this->user->id());
+        return 'c' . $sub . '.contact IS NOT NULL';
+    }
+}
+
+class UFC_WatchRegistration extends UFC_UserRelated
+{
+    public function buildCondition(UserFilter &$uf)
+    {
+        if (!$this->user->watch('registration')) {
+            return UserFilterCondition::COND_FALSE;
+        }
+        $uids = $this->user->watchUsers();
+        if (count($uids) == 0) {
+            return UserFilterCondition::COND_FALSE;
+        } else {
+            return '$UID IN ' . XDB::formatArray($uids);
+        }
+    }
+}
+
+class UFC_WatchPromo extends UFC_UserRelated
+{
+    private $grade;
+    public function __construct(PlUser &$user, $grade = UserFilter::GRADE_ING)
+    {
+        parent::__construct($user);
+        $this->grade = $grade;
+    }
+
+    public function buildCondition(UserFilter &$uf)
+    {
+        $promos = $this->user->watchPromos();
+        if (count($promos) == 0) {
+            return UserFilterCondition::COND_FALSE;
+        } else {
+            $sube = $uf->addEducationFilter(true, $this->grade);
+            $field = 'pe' . $sube . '.' . UserFilter::promoYear($this->grade);
+            return $field . ' IN ' . XDB::formatArray($promos);
+        }
+    }
+}
+
+class UFC_WatchContact extends UFC_Contact
+{
+    public function buildCondition(UserFilter &$uf)
+    {
+        if (!$this->user->watchContacts()) {
+            return UserFilterCondition::COND_FALSE;
+        }
+        return parent::buildCondition($uf);
+    }
+}
+
+
+/******************
+ * ORDERS
+ ******************/
+
+abstract class UserFilterOrder
+{
+    protected $desc = false;
+    public function __construct($desc = false)
+    {
+        $this->desc = $desc;
+    }
+
+    public function buildSort(UserFilter &$uf)
+    {
+        $sel = $this->getSortTokens($uf);
+        if (!is_array($sel)) {
+            $sel = array($sel);
+        }
+        if ($this->desc) {
+            foreach ($sel as $k=>$s) {
+                $sel[$k] = $s . ' DESC';
+            }
+        }
+        return $sel;
+    }
+
+    abstract protected function getSortTokens(UserFilter &$uf);
+}
+
+class UFO_Promo extends UserFilterOrder
+{
+    private $grade;
+
+    public function __construct($grade = null, $desc = false)
+    {
+        parent::__construct($desc);
+        $this->grade = $grade;
+    }
+
+    protected function getSortTokens(UserFilter &$uf)
+    {
+        if (UserFilter::isGrade($this->grade)) {
+            $sub = $uf->addEducationFilter($this->grade);
+            return 'pe' . $sub . '.' . UserFilter::promoYear($this->grade);
+        } else {
+            $sub = $uf->addDisplayFilter();
+            return 'pd' . $sub . '.promo';
+        }
+    }
+}
+
+class UFO_Name extends UserFilterOrder
+{
+    private $type;
+    private $variant;
+    private $particle;
+
+    public function __construct($type, $variant = null, $particle = false, $desc = false)
+    {
+        parent::__construct($desc);
+        $this->type = $type;
+        $this->variant = $variant;
+        $this->particle = $particle;
+    }
+
+    protected function getSortTokens(UserFilter &$uf)
+    {
+        if (UserFilter::isDisplayName($this->type)) {
+            $sub = $uf->addDisplayFilter();
+            return 'pd' . $sub . '.' . $this->type;
+        } else {
+            $sub = $uf->addNameFilter($this->type, $this->variant);
+            if ($this->particle) {
+                return 'CONCAT(pn' . $sub . '.particle, \' \', pn' . $sub . '.name)';
+            } else {
+                return 'pn' . $sub . '.name';
+            }
+        }
+    }
+}
+
+class UFO_Registration extends UserFilterOrder
+{
+    protected function getSortTokens(UserFilter &$uf)
+    {
+        return 'a.registration_date';
+    }
+}
+
+class UFO_Birthday extends UserFilterOrder
+{
+    protected function getSortTokens(UserFilter &$uf)
+    {
+        return 'p.next_birthday';
+    }
+}
+
+class UFO_ProfileUpdate extends UserFilterOrder
+{
+    protected function getSortTokens(UserFilter &$uf)
+    {
+        return 'p.last_change';
+    }
+}
+
+class UFO_Death extends UserFilterOrder
+{
+    protected function getSortTokens(UserFilter &$uf)
+    {
+        return 'p.deathdate';
+    }
+}
+
+
+/***********************************
+  *********************************
+          USER FILTER CLASS
+  *********************************
+ ***********************************/
+
+class UserFilter
+{
+    static private $joinMethods = array();
+
+    private $root;
+    private $sort = array();
+    private $query = null;
+    private $orderby = null;
+
+    private $lastcount = null;
+
+    public function __construct($cond = null, $sort = null)
+    {
+        if (empty(self::$joinMethods)) {
+            $class = new ReflectionClass('UserFilter');
+            foreach ($class->getMethods() as $method) {
+                $name = $method->getName();
+                if (substr($name, -5) == 'Joins' && $name != 'buildJoins') {
+                    self::$joinMethods[] = $name;
+                }
+            }
+        }
+        if (!is_null($cond)) {
+            if ($cond instanceof UserFilterCondition) {
+                $this->setCondition($cond);
+            }
+        }
+        if (!is_null($sort)) {
+            if ($sort instanceof UserFilterOrder) {
+                $this->addSort($sort);
+            } else if (is_array($sort)) {
+                foreach ($sort as $s) {
+                    $this->addSort($s);
+                }
+            }
+        }
+    }
+
+    private function buildQuery()
+    {
+        if (is_null($this->orderby)) {
+            $orders = array();
+            foreach ($this->sort as $sort) {
+                $orders = array_merge($orders, $sort->buildSort($this));
+            }
+            if (count($orders) == 0) {
+                $this->orderby = '';
+            } else {
+                $this->orderby = 'ORDER BY  ' . implode(', ', $orders);
+            }
+        }
+        if (is_null($this->query)) {
+            $where = $this->root->buildCondition($this);
+            $joins = $this->buildJoins();
+            $this->query = 'FROM  accounts AS a
+                       LEFT JOIN  account_profiles AS ap ON (ap.uid = a.uid AND FIND_IN_SET(\'owner\', ap.perms))
+                       LEFT JOIN  profiles AS p ON (p.pid = ap.pid)
+                               ' . $joins . '
+                           WHERE  (' . $where . ')';
+        }
+    }
+
+    private function formatJoin(array $joins)
+    {
+        $str = '';
+        foreach ($joins as $key => $infos) {
+            $mode  = $infos[0];
+            $table = $infos[1];
+            if ($mode == 'inner') {
+                $str .= 'INNER JOIN ';
+            } else if ($mode == 'left') {
+                $str .= 'LEFT JOIN ';
+            } else {
+                Platal::page()->kill("Join mode error");
+            }
+            $str .= $table . ' AS ' . $key;
+            if (isset($infos[2])) {
+                $str .= ' ON (' . str_replace(array('$ME', '$PID', '$UID'), array($key, 'p.pid', 'a.uid'), $infos[2]) . ')';
+            }
+            $str .= "\n";
+        }
+        return $str;
+    }
+
+    private function buildJoins()
+    {
+        $joins = array();
+        foreach (self::$joinMethods as $method) {
+            $joins = array_merge($joins, $this->$method());
+        }
+        return $this->formatJoin($joins);
+    }
+
+    private function getUIDList($uids = null, $count = null, $offset = null)
+    {
+        $this->buildQuery();
+        $limit = '';
+        if (!is_null($count)) {
+            if (!is_null($offset)) {
+                $limit = XDB::format('LIMIT {?}, {?}', (int)$offset, (int)$count);
+            } else {
+                $limit = XDB::format('LIMIT {?}', (int)$count);
+            }
+        }
+        $cond = '';
+        if (!is_null($uids)) {
+            $cond = ' AND a.uid IN ' . XDB::formatArray($uids);
+        }
+        $fetched = XDB::fetchColumn('SELECT SQL_CALC_FOUND_ROWS  a.uid
+                                    ' . $this->query . $cond . '
+                                   GROUP BY  a.uid
+                                    ' . $this->orderby . '
+                                    ' . $limit);
+        $this->lastcount = (int)XDB::fetchOneCell('SELECT FOUND_ROWS()');
+        return $fetched;
+    }
+
+    /** Check that the user match the given rule.
+     */
+    public function checkUser(PlUser &$user)
+    {
+        $this->buildQuery();
+        $count = (int)XDB::fetchOneCell('SELECT  COUNT(*)
+                                        ' . $this->query . XDB::format(' AND a.uid = {?}', $user->id()));
+        return $count == 1;
+    }
+
+    /** Filter a list of user to extract the users matching the rule.
+     */
+    public function filter(array $users, $count = null, $offset = null)
+    {
+        $this->buildQuery();
+        $table = array();
+        $uids  = array();
+        foreach ($users as $user) {
+            if ($user instanceof PlUser) {
+                $uid = $user->id();
+            } else {
+                $uid = $user;
+            }
+            $uids[] = $uid;
+            $table[$uid] = $user;
+        }
+        $fetched = $this->getUIDList($uids, $count, $offset);
+        $output = array();
+        foreach ($fetched as $uid) {
+            $output[] = $table[$uid];
+        }
+        return $output;
+    }
+
+    public function getUIDs($count = null, $offset = null)
+    {
+        return $this->getUIDList(null, $count, $offset);
+    }
+
+    public function getUsers($count = null, $offset = null)
+    {
+        return User::getBulkUsersWithUIDs($this->getUIDs($count, $offset));
+    }
+
+    public function getTotalCount()
+    {
+        if (is_null($this->lastcount)) {
+            $this->buildQuery();
+            return (int)XDB::fetchOneCell('SELECT  COUNT(DISTINCT a.uid)
+                                          ' . $this->query);
+        } else {
+            return $this->lastcount;
+        }
+    }
+
+    public function setCondition(UserFilterCondition &$cond)
+    {
+        $this->root =& $cond;
+        $this->query = null;
+    }
+
+    public function addSort(UserFilterOrder &$sort)
+    {
+        $this->sort[] = $sort;
+        $this->orderby = null;
+    }
+
+    static public function getLegacy($promo_min, $promo_max)
+    {
+        if ($promo_min != 0) {
+            $min = new UFC_Promo('>=', self::GRADE_ING, intval($promo_min));
+        } else {
+            $min = new UFC_True();
+        }
+        if ($promo_max != 0) {
+            $max = new UFC_Promo('<=', self::GRADE_ING, intval($promo_max));
+        } else {
+            $max = new UFC_True();
+        }
+        return new UserFilter(new UFC_And($min, $max));
+    }
+
+    static public function sortByName()
+    {
+        return array(new UFO_Name(self::LASTNAME), new UFO_Name(self::FIRSTNAME));
+    }
+
+    static public function sortByPromo()
+    {
+        return array(new UFO_Promo(), new UFO_Name(self::LASTNAME), new UFO_Name(self::FIRSTNAME));
+    }
+
+    static private function getDBSuffix($string)
+    {
+        return preg_replace('/[^a-z0-9]/i', '', $string);
+    }
+
+
+    private $option = 0;
+    private function register_optional(array &$table, $val)
+    {
+        if (is_null($val)) {
+            $sub   = $this->option++;
+            $index = null;
+        } else {
+            $sub   = self::getDBSuffix($val);
+            $index = $val;
+        }
+        $sub = '_' . $sub;
+        $table[$sub] = $index;
+        return $sub;
+    }
+
+    /** DISPLAY
+     */
+    const DISPLAY = 'display';
+    private $pd = false;
+    public function addDisplayFilter()
+    {
+        $this->pd = true;
+        return '';
+    }
+
+    private function displayJoins()
+    {
+        if ($this->pd) {
+            return array('pd' => array('left', 'profile_display', '$ME.pid = $PID'));
+        } else {
+            return array();
+        }
+    }
+
+    /** NAMES
+     */
+    /* name tokens */
+    const LASTNAME  = 'lastname';
+    const FIRSTNAME = 'firstname';
+    const NICKNAME  = 'nickname';
+    const PSEUDONYM = 'pseudonym';
+    const NAME      = 'name';
+    /* name variants */
+    const VN_MARITAL  = 'marital';
+    const VN_ORDINARY = 'ordinary';
+    const VN_OTHER    = 'other';
+    const VN_INI      = 'ini';
+    /* display names */
+    const DN_FULL      = 'directory_name';
+    const DN_DISPLAY   = 'yourself';
+    const DN_YOURSELF  = 'yourself';
+    const DN_DIRECTORY = 'directory_name';
+    const DN_PRIVATE   = 'private_name';
+    const DN_PUBLIC    = 'public_name';
+    const DN_SHORT     = 'short_name';
+    const DN_SORT      = 'sort_name';
+
+    static public $name_variants = array(
+        self::LASTNAME => array(self::VN_MARITAL, self::VN_ORDINARY),
+        self::FIRSTNAME => array(self::VN_ORDINARY, self::VN_INI, self::VN_OTHER)
+    );
+
+    static public function assertName($name)
+    {
+        if (!Profile::getNameTypeId($name)) {
+            Platal::page()->kill('Invalid name type');
+        }
+    }
+
+    static public function isDisplayName($name)
+    {
+        return $name == self::DN_FULL || $name == self::DN_DISPLAY
+            || $name == self::DN_YOURSELF || $name == self::DN_DIRECTORY
+            || $name == self::DN_PRIVATE || $name == self::DN_PUBLIC
+            || $name == self::DN_SHORT || $name == self::DN_SORT;
+    }
+
+    private $pn  = array();
+    public function addNameFilter($type, $variant = null)
+    {
+        if (!is_null($variant)) {
+            $ft  = $type . '_' . $variant;
+        } else {
+            $ft = $type;
+        }
+        $sub = '_' . $ft;
+        self::assertName($ft);
+
+        if (!is_null($variant) && $variant == 'other') {
+            $sub .= $this->option++;
+        }
+        $this->pn[$sub] = Profile::getNameTypeId($ft);
+        return $sub;
+    }
+
+    private function nameJoins()
+    {
+        $joins = array();
+        foreach ($this->pn as $sub => $type) {
+            $joins['pn' . $sub] = array('left', 'profile_name', '$ME.pid = $PID AND $ME.typeid = ' . $type);
+        }
+        return $joins;
+    }
+
+
+    /** EDUCATION
+     */
+    const GRADE_ING = 'Ing.';
+    const GRADE_PHD = 'PhD';
+    const GRADE_MST = 'M%';
+    static public function isGrade($grade)
+    {
+        return $grade == self::GRADE_ING || $grade == self::GRADE_PHD || $grade == self::GRADE_MST;
+    }
+
+    static public function assertGrade($grade)
+    {
+        if (!self::isGrade($grade)) {
+            Platal::page()->killError("Diplôme non valide");
+        }
+    }
+
+    static public function promoYear($grade)
+    {
+        // XXX: Definition of promotion for phds and masters might change in near future.
+        return ($grade == UserFilter::GRADE_ING) ? 'entry_year' : 'grad_year';
+    }
+
+    private $pepe     = array();
+    private $with_pee = false;
+    public function addEducationFilter($x = false, $grade = null)
+    {
+        if (!$x) {
+            $index = $this->option;
+            $sub   = $this->option++;
+        } else {
+            self::assertGrade($grade);
+            $index = $grade;
+            $sub   = $grade[0];
+            $this->with_pee = true;
+        }
+        $sub = '_' . $sub;
+        $this->pepe[$index] = $sub;
+        return $sub;
+    }
+
+    private function educationJoins()
+    {
+        $joins = array();
+        if ($this->with_pee) {
+            $joins['pee'] = array('inner', 'profile_education_enum', 'pee.abbreviation = \'X\'');
+        }
+        foreach ($this->pepe as $grade => $sub) {
+            if ($this->isGrade($grade)) {
+                $joins['pe' . $sub] = array('left', 'profile_education', '$ME.eduid = pee.id AND $ME.uid = $PID');
+                $joins['pede' . $sub] = array('inner', 'profile_education_degree_enum', '$ME.id = pe' . $sub . '.degreeid AND $ME.abbreviation LIKE ' .
+                                                  XDB::format('{?}', $grade));
+            } else {
+                $joins['pe' . $sub] = array('left', 'profile_education', '$ME.uid = $PID');
+                $joins['pee' . $sub] = array('inner', 'profile_education_enum', '$ME.id = pe' . $sub . '.eduid');
+                $joins['pede' . $sub] = array('inner', 'profile_education_degree_enum', '$ME.id = pe' . $sub . '.degreeid');
+            }
+        }
+        return $joins;
+    }
+
+
+    /** GROUPS
+     */
+    private $gpm = array();
+    public function addGroupFilter($group = null)
+    {
+        if (!is_null($group)) {
+            if (ctype_digit($group)) {
+                $index = $sub = $group;
+            } else {
+                $index = $group;
+                $sub   = self::getDBSuffix($group);
+            }
+        } else {
+            $sub = 'group_' . $this->option++;
+            $index = null;
+        }
+        $sub = '_' . $sub;
+        $this->gpm[$sub] = $index;
+        return $sub;
+    }
+
+    private function groupJoins()
+    {
+        $joins = array();
+        foreach ($this->gpm as $sub => $key) {
+            if (is_null($key)) {
+                $joins['gpa' . $sub] = array('inner', 'groupex.asso');
+                $joins['gpm' . $sub] = array('left', 'groupex.membres', '$ME.uid = $UID AND $ME.asso_id = gpa' . $sub . '.id');
+            } else if (ctype_digit($key)) {
+                $joins['gpm' . $sub] = array('left', 'groupex.membres', '$ME.uid = $UID AND $ME.asso_id = ' . $key);
+            } else {
+                $joins['gpa' . $sub] = array('inner', 'groupex.asso', XDB::format('$ME.diminutif = {?}', $key));
+                $joins['gpm' . $sub] = array('left', 'groupex.membres', '$ME.uid = $UID AND $ME.asso_id = gpa' . $sub . '.id');
+            }
+        }
+        return $joins;
+    }
+
+    /** EMAILS
+     */
+    private $e = array();
+    public function addEmailRedirectFilter($email = null)
+    {
+        return $this->register_optional($this->e, $email);
+    }
+
+    private $ve = array();
+    public function addVirtualEmailFilter($email = null)
+    {
+        $this->addAliasFilter(self::ALIAS_FORLIFE);
+        return $this->register_optional($this->ve, $email);
+    }
+
+    const ALIAS_BEST    = 'bestalias';
+    const ALIAS_FORLIFE = 'forlife';
+    private $al = array();
+    public function addAliasFilter($alias = null)
+    {
+        return $this->register_optional($this->al, $alias);
+    }
+
+    private function emailJoins()
+    {
+        global $globals;
+        $joins = array();
+        foreach ($this->e as $sub=>$key) {
+            if (is_null($key)) {
+                $joins['e' . $sub] = array('left', 'emails', '$ME.uid = $UID AND $ME.flags != \'filter\'');
+            } else {
+                $joins['e' . $sub] = array('left', 'emails', XDB::format('$ME.uid = $UID AND $ME.flags != \'filter\' AND $ME.email = {?}', $key));
+            }
+        }
+        foreach ($this->al as $sub=>$key) {
+            if (is_null($key)) {
+                $joins['al' . $sub] = array('left', 'aliases', '$ME.id = $UID AND $ME.type IN (\'alias\', \'a_vie\')');
+            } else if ($key == self::ALIAS_BEST) {
+                $joins['al' . $sub] = array('left', 'aliases', '$ME.id = $UID AND $ME.type IN (\'alias\', \'a_vie\') AND  FIND_IN_SET(\'bestalias\', $ME.flags)');
+            } else if ($key == self::ALIAS_FORLIFE) {
+                $joins['al' . $sub] = array('left', 'aliases', '$ME.id = $UID AND $ME.type = \'a_vie\'');
+            } else {
+                $joins['al' . $sub] = array('left', 'aliases', XDB::format('$ME.id = $UID AND $ME.type IN (\'alias\', \'a_vie\') AND $ME.alias = {?}', $key));
+            }
+        }
+        foreach ($this->ve as $sub=>$key) {
+            if (is_null($key)) {
+                $joins['v' . $sub] = array('left', 'virtual', '$ME.type = \'user\'');
+            } else {
+                $joins['v' . $sub] = array('left', 'virtual', XDB::format('$ME.type = \'user\' AND $ME.alias = {?}', $key));
+            }
+            $joins['vr' . $sub] = array('left', 'virtual_redirect', XDB::format('$ME.vid = v' . $sub . '.vid
+                                                                                 AND ($ME.redirect IN (CONCAT(al_forlife.alias, \'@\', {?}),
+                                                                                                       CONCAT(al_forlife.alias, \'@\', {?}),
+                                                                                                       a.email))',
+                                                                                $globals->mail->domain, $globals->mail->domain2));
+        }
+        return $joins;
+    }
+
+
+    /** CONTACTS
+     */
+    private $cts = array();
+    public function addContactFilter($uid = null)
+    {
+        return $this->register_optional($this->cts, is_null($uid) ? null : 'user_' . $uid);
+    }
+
+    private function contactJoins()
+    {
+        $joins = array();
+        foreach ($this->cts as $sub=>$key) {
+            if (is_null($key)) {
+                $joins['c' . $sub] = array('left', 'contacts', '$ME.contact = $UID');
+            } else {
+                $joins['c' . $sub] = array('left', 'contacts', XDB::format('$ME.uid = {?} AND $ME.contact = $UID', substr($key, 5)));
+            }
+        }
+        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;
+    }
+}
+
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
index bd3e1eb..9ccdf37 100644 (file)
@@ -138,11 +138,10 @@ function list_all_my_groups($params)
     if (!S::logged()) {
         return;
     }
-    $res = XDB::iterRow(
-            "SELECT  a.nom, a.diminutif
-               FROM  groupex.asso    AS a
-         INNER JOIN  groupex.membres AS m ON m.asso_id = a.id
-              WHERE  m.uid={?}", S::v('uid'));
+    $res = XDB::iterRow('SELECT  a.nom, a.diminutif
+                           FROM  groupex.asso    AS a
+                     INNER JOIN  groupex.membres AS m ON m.asso_id = a.id
+                          WHERE  m.uid = {?}', S::i('uid'));
     $links = '<a href="exit">déconnexion</a>';
     $html = '<div>Mes groupes (' . $links . ') :</div>';
     while (list($nom, $mini) = $res->next()) {
index e69e6eb..cb125d5 100644 (file)
@@ -76,7 +76,7 @@ class XnetSession extends XorgSession
     protected function doAuth($level)
     {
         if (S::identified()) { // ok, c'est bon, on n'a rien à faire
-            return S::i('uid');
+            return User::getSilentWithValues(null, array('user_id' => S::i('uid')));
         }
         if (!Get::has('auth')) {
             return null;
@@ -87,25 +87,25 @@ class XnetSession extends XorgSession
         }
         Get::kill('auth');
         S::set('auth', AUTH_MDP);
-        return Get::i('uid');
+        return User::getSilentWithValues(null, array('user_id' => Get::i('uid')));
     }
 
     protected function startSessionAs($user, $level)
     {
-        if ($level == -1) {
+        if ($level == AUTH_SUID) {
             S::set('auth', AUTH_MDP);
         }
-        $res  = XDB::query("SELECT  u.user_id AS uid, u.hruid, prenom, nom, perms, promo, password, FIND_IN_SET('femme', u.flags) AS femme,
-                                    q.core_mail_fmt AS mail_fmt, q.core_rss_hash
-                              FROM  auth_user_md5   AS u
-                        INNER JOIN  auth_user_quick AS q  USING(user_id)
-                             WHERE  u.user_id = {?} AND u.perms IN('admin', 'user')
-                             LIMIT  1", $user);
+        $res  = XDB::query("SELECT  a.uid, a.hruid, a.display_name, a.full_name,
+                                    a.sex = 'female' AS femme,
+                                    a.email_format, a.token,
+                                    at.perms, a.is_admin
+                              FROM  accounts AS a
+                        INNER JOIN  account_types AS at ON (at.type = a.type)
+                             WHERE  a.uid = {?} AND a.state = 'active'
+                             LIMIT  1", $user->id());
         $sess = $res->fetchOneAssoc();
-        $perms = $sess['perms'];
-        unset($sess['perms']);
         $_SESSION = array_merge($_SESSION, $sess);
-        S::set('perms', User::makePerms($perms));
+        $this->makePerms(S::s('perms'), S::b('is_admin'));
         S::kill('challenge');
         S::kill('loginX');
         S::kill('may_update');
@@ -122,7 +122,8 @@ class XnetSession extends XorgSession
 
     public function doSelfSuid()
     {
-        if (!$this->startSUID(S::i('uid'))) {
+        $user =& S::user();
+        if (!$this->startSUID($user)) {
             return false;
         }
         S::set('perms', User::makePerms('user'));
@@ -131,14 +132,13 @@ class XnetSession extends XorgSession
 
     public function stopSUID()
     {
-        $suid = S::v('suid');
+        $perms = S::suid('perms');
         if (!parent::stopSUID()) {
             return false;
         }
-        S::kill('suid');
         S::kill('may_update');
         S::kill('is_member');
-        S::set('perms', $suid['perms']);
+        S::set('perms', $perms);
         return true;
     }
 }
@@ -162,7 +162,7 @@ function may_update($force = false, $lose = false)
         return false;
     } elseif ($lose) {
         $may_update[$asso_id] = false;
-    } elseif (S::admin() || (S::has('suid') && $force)) {
+    } elseif (S::admin() || (S::suid() && $force)) {
         $may_update[$asso_id] = true;
     } elseif (!isset($may_update[$asso_id]) || $force) {
         $res = XDB::query("SELECT  perms
@@ -194,7 +194,7 @@ function is_member($force = false, $lose = false)
         return false;
     } elseif ($lose) {
         $is_member[$asso_id] = false;
-    } elseif (S::has('suid') && $force) {
+    } elseif (S::suid() && $force) {
         $is_member[$asso_id] = true;
     } elseif (!isset($is_member[$asso_id]) || $force) {
         $res = XDB::query("SELECT  COUNT(*)
index 0e55c97..d61c69d 100644 (file)
 
 class XorgSession extends PlSession
 {
+    const INVALID_USER = -2;
+    const NO_COOKIE = -1;
+    const COOKIE_SUCCESS = 0;
+    const INVALID_COOKIE = 1;
+
     public function __construct()
     {
         parent::__construct();
@@ -29,10 +34,15 @@ class XorgSession extends PlSession
     public function startAvailableAuth()
     {
         if (!S::logged()) {
-            $cookie = $this->tryCookie();
-            if ($cookie == 0) {
-                return $this->start(AUTH_COOKIE);
-            } else if ($cookie == 1 || $cookie == -2) {
+            switch ($this->tryCookie()) {
+              case self::COOKIE_SUCCESS:
+                if (!$this->start(AUTH_COOKIE)) {
+                    return false;
+                }
+                break;
+
+              case self::INVALID_USER:
+              case self::INVALID_COOKIE:
                 return false;
             }
         }
@@ -48,59 +58,35 @@ class XorgSession extends PlSession
     {
         S::kill('auth_by_cookie');
         if (Cookie::v('access') == '' || !Cookie::has('uid')) {
-            return -1;
+            return self::NO_COOKIE;
         }
 
-        $res = XDB::query('SELECT  user_id, password
-                             FROM  auth_user_md5
-                            WHERE  user_id = {?} AND perms IN(\'admin\', \'user\')',
+        $res = XDB::query('SELECT  uid, password
+                             FROM  accounts
+                            WHERE  uid = {?} AND state = \'active\'',
                          Cookie::i('uid'));
         if ($res->numRows() != 0) {
             list($uid, $password) = $res->fetchOneRow();
-            require_once 'secure_hash.inc.php';
-            $expected_value = hash_encrypt($password);
-            if ($expected_value == Cookie::v('access')) {
+            if (sha1($password) == Cookie::v('access')) {
                 S::set('auth_by_cookie', $uid);
-                return 0;
+                return self::COOKIE_SUCCESS;
             } else {
-                return 1;
+                return self::INVALID_COOKIE;
             }
         }
-        return -2;
+        return self::INVALID_USER;
     }
 
     private function checkPassword($uname, $login, $response, $login_type)
     {
-        $res = XDB::query('SELECT  u.user_id, u.password
-                             FROM  auth_user_md5 AS u
-                       INNER JOIN  aliases       AS a ON (a.id = u.user_id AND type != \'homonyme\')
-                             WHERE  a.' . $login_type . ' = {?} AND u.perms IN(\'admin\', \'user\')',
+        $res = XDB::query('SELECT  a.uid, a.password
+                             FROM  accounts AS a
+                       INNER JOIN  aliases  AS l ON (l.id = a.uid AND l.type != \'homonyme\')
+                            WHERE  l.' . $login_type . ' = {?} AND a.state = \'active\'',
                           $login);
         if (list($uid, $password) = $res->fetchOneRow()) {
-            require_once 'secure_hash.inc.php';
-            $expected_response = hash_encrypt("$uname:$password:" . S::v('challenge'));
-            if ($response != $expected_response && Env::has('xorpass')
-                && !preg_match('/^0*$/', Env::v('xorpass'))) {
-                $new_password = hash_xor(Env::v('xorpass'), $password);
-                $expected_response = hash_encrypt("$uname:$new_password:" . S::v('challenge'));
-                if ($response == $expected_response) {
-                    XDB::execute('UPDATE  auth_user_md5
-                                     SET  password = {?}
-                                   WHERE  user_id = {?}',
-                                 $new_password, $uid);
-
-                    // Update the GoogleApps password as well, if required.
-                    global $globals;
-                    if ($globals->mailstorage->googleapps_domain) {
-                        require_once 'googleapps.inc.php';
-                        $user = User::getSilent($uid);
-                        $account = new GoogleAppsAccount($user);
-                        if ($account->active() && $account->sync_password) {
-                            $account->set_password($new_password);
-                        }
-                    }
-                }
-            }
+            $expected_response = sha1("$uname:$password:" . S::v('challenge'));
+            /* XXX: Deprecates len(password) > 10 conversion */
             if ($response != $expected_response) {
                 if (!S::logged()) {
                     Platal::page()->trigError('Mot de passe ou nom d\'utilisateur invalide');
@@ -132,7 +118,7 @@ class XorgSession extends PlSession
             if (!S::logged()) {
                 S::set('auth', AUTH_COOKIE);
             }
-            return S::i('auth_by_cookie');
+            return User::getSilentWithValues(null, array('user_id' => S::i('auth_by_cookie')));
         }
 
 
@@ -144,9 +130,8 @@ class XorgSession extends PlSession
 
         /** We come from an authentication form.
          */
-        if (S::has('suid')) {
-            $suid  = S::v('suid');
-            $login = $uname = $suid['uid'];
+        if (S::suid()) {
+            $login = $uname = S::suid('uid');
             $redirect = false;
         } else {
             $uname = Env::v('username');
@@ -169,9 +154,8 @@ class XorgSession extends PlSession
         }
 
         $uid = $this->checkPassword($uname, $login, Post::v('response'), (!$redirect && is_numeric($uname)) ? 'id' : 'alias');
-        if (!is_null($uid) && S::has('suid')) {
-            $suid = S::v('suid');
-            if ($suid['uid'] == $uid) {
+        if (!is_null($uid) && S::suid()) {
+            if (S::suid('uid') == $uid) {
                 $uid = S::i('uid');
             } else {
                 $uid = null;
@@ -179,7 +163,7 @@ class XorgSession extends PlSession
         }
         if (!is_null($uid)) {
             S::set('auth', AUTH_MDP);
-            if (!S::has('suid')) {
+            if (!S::suid()) {
                 if (Post::has('domain')) {
                     if (($domain = Post::v('domain', 'login')) == 'alias') {
                         Cookie::set('domain', 'alias', 300);
@@ -191,12 +175,13 @@ class XorgSession extends PlSession
             S::kill('challenge');
             S::logger($uid)->log('auth_ok');
         }
-        return $uid;
+        return User::getSilentWithValues(null, array('user_id' => $uid));
     }
 
-    protected function startSessionAs($uid, $level)
+    protected function startSessionAs($user, $level)
     {
-        if ((!is_null(S::v('user')) && S::i('user') != $uid) || (S::has('uid') && S::i('uid') != $uid)) {
+        if ((!is_null(S::v('user')) && S::v('user')->id() != $user->id())
+            || (S::has('uid') && S::i('uid') != $user->id())) {
             return false;
         } else if (S::has('uid')) {
             return true;
@@ -206,17 +191,24 @@ class XorgSession extends PlSession
         }
 
         // Retrieves main user properties.
-        $res  = XDB::query("SELECT  u.user_id AS uid, u.hruid, prenom, prenom_ini, nom, nom_ini, nom_usage, perms, promo, promo_sortie,
-                                    matricule, password, FIND_IN_SET('femme', u.flags) AS femme,
-                                    q.core_mail_fmt AS mail_fmt, UNIX_TIMESTAMP(q.banana_last) AS banana_last, q.watch_last, q.core_rss_hash,
-                                    FIND_IN_SET('watch', u.flags) AS watch_account, q.last_version, g.g_account_name IS NOT NULL AS googleapps,
-                                    UNIX_TIMESTAMP(s.start) AS lastlogin, s.host
-                              FROM  auth_user_md5   AS u
-                        INNER JOIN  auth_user_quick AS q  USING(user_id)
-                         LEFT JOIN  gapps_accounts  AS g  ON (u.user_id = g.l_userid AND g.g_status = 'active')
-                         LEFT JOIN  logger.last_sessions AS ls ON (ls.uid = u.user_id)
+        /** TODO: Move needed informations to account tables */
+        /** TODO: Currently suppressed data are matricule, promo */
+        /** TODO: Use the User object to fetch all this */
+        $res  = XDB::query("SELECT  a.uid, a.hruid, a.display_name, a.full_name,
+                                    a.sex = 'female' AS femme, a.email_format,
+                                    a.token, FIND_IN_SET('watch', a.flags) AS watch_account,
+                                    UNIX_TIMESTAMP(fp.last_seen) AS banana_last, UNIX_TIMESTAMP(w.last) AS watch_last,
+                                    a.last_version, g.g_account_name IS NOT NULL AS googleapps,
+                                    UNIX_TIMESTAMP(s.start) AS lastlogin, s.host,
+                                    a.is_admin, at.perms
+                              FROM  accounts        AS a
+                        INNER JOIN  account_types   AS at ON(a.type = at.type)
+                        INNER JOIN  watch           AS w  ON(w.uid = a.uid)
+                         LEFT JOIN  forum_profiles  AS fp ON(fp.uid = a.uid)
+                         LEFT JOIN  gapps_accounts  AS g  ON(a.uid = g.l_userid AND g.g_status = 'active')
+                         LEFT JOIN  logger.last_sessions AS ls ON (ls.uid = a.uid)
                          LEFT JOIN  logger.sessions AS s  ON(s.id = ls.id)
-                             WHERE  u.user_id = {?} AND u.perms IN('admin', 'user')", $uid);
+                             WHERE  a.uid = {?} AND u.perms IN('admin', 'user')", $user->id());
         if ($res->numRows() != 1) {
             return false;
         }
@@ -229,24 +221,21 @@ class XorgSession extends PlSession
         $_SESSION = array_merge($_SESSION, $sess);
 
         // Starts the session's logger, and sets up the permanent cookie.
-        if (S::has('suid')) {
-            $suid = S::v('suid');
-            $logger = S::logger($uid);
-            $logger->log("suid_start", S::v('hruid') . " by " . $suid['hruid']);
+        if (S::suid()) {
+            S::logger()->log("suid_start", S::v('hruid') . ' by ' . S::suid('hruid'));
         } else {
-            $logger = S::logger($uid);
-            $logger->saveLastSession();
-            Cookie::set('uid', $uid, 300);
+            S::logger()->saveLastSession();
+            Cookie::set('uid', $user->id(), 300);
 
-            if (S::i('auth_by_cookie') == $uid || Post::v('remember', 'false') == 'true') {
-                $this->setAccessCookie(false, S::i('auth_by_cookie') != $uid);
+            if (S::i('auth_by_cookie') == $user->id() || Post::v('remember', 'false') == 'true') {
+                $this->setAccessCookie(false, S::i('auth_by_cookie') != $user->id());
             } else {
                 $this->killAccessCookie();
             }
         }
 
         // Finalizes the session setup.
-        S::set('perms', User::makePerms($perms));
+        $this->makePerms($perms, S::b('is_admin'));
         $this->securityChecks();
         $this->setSkin();
         $this->updateNbNotifs();
@@ -281,40 +270,29 @@ class XorgSession extends PlSession
 
     public function tokenAuth($login, $token)
     {
-        $res = XDB::query('SELECT  u.hruid
-                             FROM  aliases         AS a
-                       INNER JOIN  auth_user_md5   AS u ON (a.id = u.user_id AND u.perms IN ("admin", "user"))
-                       INNER JOIN  auth_user_quick AS q ON (a.id = q.user_id AND q.core_rss_hash = {?})
-                            WHERE  a.alias = {?} AND a.type != "homonyme"', $token, $login);
+        $res = XDB::query('SELECT  a.uid AS user_id, a.hruid
+                             FROM  aliases  AS l
+                       INNER JOIN  accounts AS a ON (l.id = a.uid AND a.state = \'active\')
+                            WHERE  a.token = {?} AND l.alias = {?} AND l.type != \'homonyme\'',
+                           $token, $login);
         if ($res->numRows() == 1) {
-            $data = $res->fetchOneAssoc();
-            return new User($data['hruid'], $data);
+            return new User(null, $res->fetchOneAssoc());
         }
         return null;
     }
 
     protected function makePerms($perm, $is_admin)
     {
-        $flags = new PlFlagSet();
-        if ($perm == 'disabled' || $perm == 'ext') {
-            S::set('perms', $flags);
-            return;
-        }
-        $flags->addFlag(PERMS_USER);
-        if ($perm == 'admin') {
-            $flags->addFlag(PERMS_ADMIN);
-        }
-        S::set('perms', $flags);
+        S::set('perms', User::makePerms($perm, $is_admin));
     }
 
     public function setSkin()
     {
-        if (S::logged() && (!S::has('skin') || S::has('suid'))) {
-            $uid = S::v('uid');
-            $res = XDB::query("SELECT  skin_tpl
-                                 FROM  auth_user_quick AS a
-                           INNER JOIN  skins           AS s ON a.skin = s.id
-                                WHERE  user_id = {?} AND skin_tpl != ''", $uid);
+        if (S::logged() && (!S::has('skin') || S::suid())) {
+            $res = XDB::query('SELECT  skin_tpl
+                                 FROM  accounts AS a
+                           INNER JOIN  skins    AS s on (a.skin = s.id)
+                                WHERE  a.uid = {?} AND skin_tpl != \'\'', S::i('uid'));
             S::set('skin', $res->fetchOneCell());
         }
     }
@@ -333,16 +311,16 @@ 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());
+        $user = S::user();
+        $n = Watch::getCount($user);
+        S::set('notifs', $n);
     }
 
     public function setAccessCookie($replace = false, $log = true) {
-        if (S::has('suid') || ($replace && !Cookie::blank('access'))) {
+        if (S::suid() || ($replace && !Cookie::blank('access'))) {
             return;
         }
-        require_once('secure_hash.inc.php');
-        Cookie::set('access', hash_encrypt(S::v('password')), 300, true);
+        Cookie::set('access', sha1(S::user()->password()), 300, true);
         if ($log) {
             S::logger()->log('cookie_on');
         }
index f263a75..dbdf3c0 100644 (file)
@@ -17,7 +17,6 @@ password = "***"
 web_user = "***"
 web_pass = "***"
 
-table_prefix = "banana_"
 spool_root   = "/var/spool/banana"
 mbox_helper  = "/usr/bin/banana-mbox-helper"
 
index d2ee6db..3719eb5 100644 (file)
@@ -67,4 +67,6 @@
     display: none;
 }
 
+.ui-tabs-hide { display: none; }
+
 /* vim: set et ts=4 sts=4 sw=4: */
index 743a8a1..4c44469 100644 (file)
@@ -360,46 +360,59 @@ div.long td.rt { width: 85%; }
         [ onglets des profils ]
 *******************************************************************************/
 
-.wizard {
+.wizard, .ui-tabs-nav {
+    margin: 0;
+    padding: 0;
     margin-left: -16px;
+    clear: both;
 }
 
-.wizard .wiz_header {
+.wizard .wiz_header, .ui-tabs-nav {
     height: 32px;
     width: 100%;
     background: url('../images/skins/wiz_background.png') top right repeat-x;
     margin-bottom: 1em;
+    text-align: left;
 }
 
-.wizard .wiz_header .wiz_tab {
+.wizard .wiz_header .wiz_tab, .ui-tabs-nav li {
     background: url('../images/skins/wiz_normal.png') #aaa top left repeat-x;
     height: 100%;
     text-align: center;
     font-size: 75%;
     border-right: 1px solid #888;
+    float: left;
+    vertical-align: middle;
 }
 
-.wizard .wiz_header .wiz_tab:hover {
+.ui-tabs-nav li {
+    margin: 0;
+    padding: 0;
+    list-style-type: none;
+}
+
+.wizard .wiz_header .wiz_tab:hover, .ui-tabs-nav li:hover {
     background: url('../images/skins/wiz_hover.png') #777 top left repeat-x;
     color: #fff;
 }
 
-.wizard .wiz_header .active, .wizard .wiz_header .active:hover {
+.wizard .wiz_header .active, .wizard .wiz_header .active:hover, li.ui-tabs-selected {
     background: url('../images/skins/wiz_active.png') #444 top left repeat-x;
     color: #fff;
 }
 
-.wizard .wiz_header a {
+.wizard .wiz_header a, .ui-tabs-nav a {
     color: #000;
     text-decoration: none;
 }
 
-.wizard .wiz_header a.active {
+.wizard .wiz_header a.active, .ui-tabs-selected a {
     color: #fff;
 }
 
-.wizard .wiz_content {
+.wizard .wiz_content, .ui-tabs-panel {
     margin-left: 16px;
+    clear: both;
 }
 
 .flags .texte {
index 7fa306b..da77c0b 100644 (file)
@@ -1,3 +1,4 @@
 # jQuery and its plugins are downloaded by the Makefile
 /jquery.*js
+/ui.*js
 !/jquery.autocomplete.js
index 3b96319..1093469 100644 (file)
 
 require_once 'xorg.inc.php';
 
-new Xorg('core');
+$platal = new Xorg('core');
 
 global $globals;
-list($username, $path) = preg_split('/\//', $_SERVER["REQUEST_URI"], 2, PREG_SPLIT_NO_EMPTY);
-$res = XDB::query(
-        "SELECT  redirecturl
-           FROM  auth_user_quick AS a
-     INNER JOIN  aliases         AS al ON (al.id = a.user_id AND (al.type='a_vie' OR al.type='alias'))
-          WHERE  al.alias = {?}
-       GROUP BY  redirecturl", $username);
+$path = ltrim($platal->pl_self(), '/');
+@list($username, $path) = explode('/', $path, 2);
 
-if ($url = $res->fetchOneCell()) {
-    $url = preg_replace('@/+$@', '', $url);
-    if ($path) {
-        http_redirect("http://$url/$path");
-    } else {
-        http_redirect("http://$url");
+if ($username && !is_null($user = User::getSilent($username))) {
+    $url = XDB::fetchOneCell('SELECT  url
+                                FROM  carvas
+                               WHERE  uid = {?}', $user->id());
+    if ($url) {
+        $url = preg_replace('@/+$@', '', $url);
+        if ($path) {
+            http_redirect("http://$url/$path");
+        } else {
+            http_redirect("http://$url");
+        }
     }
 }
 
-header("HTTP/1.0 404 Not Found");
-
+header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
 ?>
 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
 <html>
index 7ccabd7..393d39a 100644 (file)
@@ -46,15 +46,42 @@ class ForumsBanana extends Banana
         }
         Banana::$debug_nntp = ($globals->debug & DEBUG_BT);
         Banana::$debug_smarty = ($globals->debug & DEBUG_SMARTY);
-        if (!S::v('core_rss_hash')) {
-            Banana::$feed_active = false;
-        }
+        Banana::$feed_active = S::hasAuthToken();
+
         parent::__construct($params, 'NNTP', 'PlatalBananaPage');
         if (@$params['action'] == 'profile') {
             Banana::$action = 'profile';
         }
     }
 
+    private function fetchProfile()
+    {
+        // Get user profile from SQL
+        $req = XDB::query("SELECT  name, mail, sig,
+                                   FIND_IN_SET('threads',flags) AS threads,
+                                   FIND_IN_SET('automaj',flags) AS maj,
+                                   FIND_IN_SET('xface', flags) AS xface,
+                                   tree_unread, tree_read
+                             FROM  forum_profiles
+                            WHERE  uid = {?}", $this->user->id());
+        if ($req->numRows()) {
+            $infos = $req->fetchOneAssoc();
+        } else {
+            $infos = array();
+        }
+        if (empty($infos['name'])) {
+            $infos = array('name' => $this->user->fullName(),
+                           'mail' => $this->user->forlifeEmail(),
+                           'sig'  => $this->user->displayName(),
+                           'threads' => false,
+                           'maj'  => true,
+                           'xface' => false,
+                           'tree_unread' => 'o',
+                           'tree_read' => 'dg' );
+        }
+        return $infos;
+    }
+
     public function run()
     {
         global $platal, $globals;
@@ -63,50 +90,40 @@ class ForumsBanana extends Banana
         $time = null;
         if (!is_null($this->params) && isset($this->params['updateall'])) {
             $time = intval($this->params['updateall']);
-            $_SESSION['banana_last']     = $time;
+            S::set('banana_last', $time);
         }
 
-        // Get user profile from SQL
-        $req = XDB::query("SELECT  nom, mail, sig,
-                                   FIND_IN_SET('threads',flags), FIND_IN_SET('automaj',flags),
-                                   tree_unread, tree_read
-                             FROM  {$globals->banana->table_prefix}profils
-                            WHERE  uid={?}", S::i('uid'));
-        if (!(list($nom, $mail, $sig, $disp, $maj, $unread, $read) = $req->fetchOneRow())) {
-            $nom  = S::v('prenom')." ".S::v('nom');
-            $mail = $this->user->forlifeEmail();
-            $sig  = $nom." (".S::v('promo').")";
-            $disp = 0;
-            $maj  = 1;
-            $unread = 'o';
-            $read   = 'dg';
-        }
-        if ($maj) {
+        $infos = $this->fetchProfile();
+        if ($infos['maj']) {
             $time = time();
         }
 
         // Build user profile
-        $req = XDB::query("
-                 SELECT  nom
-                   FROM  {$globals->banana->table_prefix}abos
-              LEFT JOIN  {$globals->banana->table_prefix}list ON list.fid=abos.fid
-                  WHERE  uid={?}", S::i('uid'));
-        Banana::$profile['headers']['From']         = "$nom <$mail>";
+        $req = XDB::query("SELECT  name
+                             FROM  forum_subs AS fs
+                        LEFT JOIN  forums AS f ON (f.fid = fs.fid)
+                            WHERE  uid={?}", $this->user->id());
+        Banana::$profile['headers']['From']         = $infos['name'] . ' <' . $infos['mail'] . '>';
         Banana::$profile['headers']['Organization'] = make_Organization();
-        Banana::$profile['signature']               = $sig;
-        Banana::$profile['display']                 = $disp;
-        Banana::$profile['autoup']                  = $maj;
+        Banana::$profile['signature']               = $infos['sig'];
+        Banana::$profile['display']                 = $infos['threads'];
+        Banana::$profile['autoup']                  = $infos['maj'];
         Banana::$profile['lastnews']                = S::v('banana_last');
         Banana::$profile['subscribe']               = $req->fetchColumn();
-        Banana::$tree_unread = $unread;
-        Banana::$tree_read = $read;
+        Banana::$tree_unread = $infos['tree_unread'];
+        Banana::$tree_read = $infos['tree_read'];
 
         // Update the "unread limit"
         if (!is_null($time)) {
-            XDB::execute("UPDATE  auth_user_quick
-                             SET  banana_last = FROM_UNIXTIME({?})
-                           WHERE  user_id={?}",
-                         $time, S::i('uid'));
+            XDB::execute('UPDATE  forum_profiles
+                             SET  last_seen = FROM_UNIXTIME({?})
+                           WHERE  uid = {?}',
+                         $time, $this->user->id());
+            if (XDB::affectedRows() == 0) {
+                XDB::execute('INSERT INTO  forum_profiles (uid, last_seen)
+                                   VALUES  ({?}, FROM_UNIXTIME({?}))',
+                             $this->user->id(), $time);
+            }
         }
 
         if (!empty($GLOBALS['IS_XNET_SITE'])) {
@@ -136,11 +153,7 @@ class ForumsBanana extends Banana
     public function post($dest, $reply, $subject, $body)
     {
         global $globals;
-        $res = XDB::query('SELECT  nom, prenom, promo
-                             FROM  auth_user_md5 AS u
-                            WHERE  u.user_id = {?}', $this->user->id());
-        list($nom, $prenom, $promo) = $res->fetchOneRow();
-        Banana::$profile['headers']['From']         = "$prenom $nom ($promo) <{$this->user->bestEmail()}>";
+        Banana::$profile['headers']['From']         = $this->user->fullName() .  ' <' . $this->user->bestEmail() . '>';
         Banana::$profile['headers']['Organization'] = make_Organization();
         return parent::post($dest, $reply, $subject, $body);
     }
@@ -148,28 +161,27 @@ class ForumsBanana extends Banana
     protected function action_saveSubs($groups)
     {
         global $globals;
-        $uid = S::v('uid');
+        $uid = $this->user->id();
 
         Banana::$profile['subscribe'] = array();
-        XDB::execute("DELETE FROM {$globals->banana->table_prefix}abos WHERE uid={?}", $uid);
+        XDB::execute('DELETE FROM  forum_subs
+                            WHERE  uid = {?}', $this->user->id());
         if (!count($groups)) {
             return true;
         }
 
-        $req  = XDB::iterRow("SELECT fid,nom FROM {$globals->banana->table_prefix}list");
-        $fids = array();
-        while (list($fid,$fnom) = $req->next()) {
-            $fids[$fnom] = $fid;
-        }
-
+        $fids = XDB::fetchAllAssoc('name', 'SELECT  fid, name
+                                              FROM  forums');
         $diff = array_diff($groups, array_keys($fids));
         foreach ($diff as $g) {
-            XDB::execute("INSERT INTO {$globals->banana->table_prefix}list (nom) VALUES ({?})", $g);
+            XDB::execute('INSERT INTO  forums (name)
+                               VALUES  ({?})', $g);
             $fids[$g] = XDB::insertId();
         }
 
         foreach ($groups as $g) {
-            XDB::execute("INSERT INTO {$globals->banana->table_prefix}abos (fid,uid) VALUES ({?},{?})",
+            XDB::execute('INSERT INTO  forum_subs (fid, uid)
+                               VALUES  ({?}, {?})',
                          $fids[$g], $uid);
             Banana::$profile['subscribe'][] = $g;
         }
@@ -178,7 +190,7 @@ class ForumsBanana extends Banana
     protected function action_updateProfile()
     {
         global $globals;
-        $page = Platal::page();
+        $page =& Platal::page();
 
         $colors = glob(dirname(__FILE__) . '/../../htdocs/images/banana/m2*.gif');
         foreach ($colors as $key=>$path) {
@@ -189,7 +201,7 @@ class ForumsBanana extends Banana
 
         if (Post::has('action') && Post::v('action') == 'Enregistrer') {
             S::assert_xsrf_token();
-            $flags = new FlagSet();
+            $flags = new PlFlagSet();
             if (Post::b('bananadisplay')) {
                 $flags->addFlag('threads');
             }
@@ -203,44 +215,33 @@ class ForumsBanana extends Banana
             $read = Post::s('read');
             if (!in_array($unread, $colors) || !in_array($read, $colors)) {
                 $page->trigError('Le choix de type pour l\'arborescence est invalide');
-            } elseif (XDB::execute("REPLACE INTO  forums.profils (uid, sig, mail, nom, flags, tree_unread, tree_read)
-                                           VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?})",
-                                    S::v('uid'), Post::v('bananasig'),
-                                    Post::v('bananamail'), Post::v('banananame'),
-                                    $flags, $unread, $read)) {
-                $page->trigSuccess("Ton profil a été enregistré avec succès.");
             } else {
-                $page->trigError("Une erreur s'est produite lors de l'enregistrement de ton profil");
+                $last_seen = XDB::query('SELECT  last_seen
+                                           FROM  forum_profiles
+                                          WHERE  uid = {?}', $this->user->id());
+                if ($last_seen->numRows() > 0) {
+                    $last_seen = $last_seen->fetchOneCell();
+                } else {
+                    $last_seen = '0000-00-00';
+                }
+                XDB::execute('REPLACE INTO  forum_profiles (uid, sig, mail, name, flags, tree_unread, tree_read, last_seen)
+                                    VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})',
+                             $this->user->id(), Post::v('bananasig'),
+                             Post::v('bananamail'), Post::v('banananame'),
+                             $flags, $unread, $read, $last_seen);
+                $page->trigSuccess('Ton profil a été mis à jour');
             }
         }
 
-        $req = XDB::query("
-            SELECT  nom, mail, sig,
-                    FIND_IN_SET('threads', flags),
-                    FIND_IN_SET('automaj', flags),
-                    FIND_IN_SET('xface', flags),
-                    tree_unread,
-                    tree_read
-              FROM  forums.profils
-             WHERE  uid = {?}", S::v('uid'));
-        if (!(list($nom, $mail, $sig, $disp, $maj, $xface, $unread, $read) = $req->fetchOneRow())) {
-            $nom   = S::v('prenom').' '.S::v('nom');
-            $mail  = S::user()->forlifeEmail();
-            $sig   = $nom.' ('.S::v('promo').')';
-            $disp  = 0;
-            $maj   = 0;
-            $xface = 0;
-            $unread = 'o';
-            $read  = 'dg';
-        }
-        $page->assign('nom' ,  $nom);
-        $page->assign('mail',  $mail);
-        $page->assign('sig',   $sig);
-        $page->assign('disp',  $disp);
-        $page->assign('maj',   $maj);
-        $page->assign('xface', $xface);
-        $page->assign('unread', $unread);
-        $page->assign('read', $read);
+        $infos = $this->fetchProfile();
+        $page->assign('nom' ,  $infos['name']);
+        $page->assign('mail',  $infos['mail']);
+        $page->assign('sig',   $infos['sig']);
+        $page->assign('disp',  $infos['threads']);
+        $page->assign('maj',   $infos['maj']);
+        $page->assign('xface', $infos['xface']);
+        $page->assign('unread', $infos['tree_unread']);
+        $page->assign('read', $infos['tree_read']);
         return null;
     }
 }
index f5f608a..9e37484 100644 (file)
@@ -76,7 +76,7 @@ function hook_platalRSS($group)
     } else {
         $group = '';
     }
-    return '/rss/' . $group . S::v('hruid') . '/' . S::v('core_rss_hash') . '/rss.xml';
+    return '/rss/' . $group . S::v('hruid') . '/' . S::s('token') . '/rss.xml';
 }
 
 function hook_platalMessageLink($params)
@@ -177,20 +177,25 @@ function hook_hasXFace($headers)
 
 function hook_getXFace($headers)
 {
-    $login = @$headers['x-org-id'];
-    if (!$login) {
-        @list($login, ) = explode('@', $headers['x-org-mail']);
+    $login = null;
+    foreach (array('x-org-id', 'x-org-mail') as $key) {
+        if (isset($headers[$key])) {
+            $login = $headers[$key];
+            break;
+        }
     }
-    if (!$login) {
+    if (is_null($login)) {
+        // No login, fallback to default handler
         return false;
     }
     if (isset($headers['x-face'])) {
-        $res = XDB::query("SELECT  p.uid
-                             FROM  forums.profils AS p
-                       INNER JOIN  aliases AS a ON (p.uid = a.id)
-                            WHERE  FIND_IN_SET('xface', p.flags) AND a.alias = {?}",
-                          $login);
+        $user = User::getSilent($login);
+        $res = XDB::query('SELECT  pf.uid
+                             FROM  forum_profiles AS pf
+                            WHERE  pf.uid = {?} AND FIND_IN_SET(\'xface\', pf.flags)',
+                          $user->id());
         if ($res->numRows()) {
+            // User wants his xface to be showed, fallback to default handler
             return false;
         }
     }
@@ -324,7 +329,8 @@ class BananaHandler
 
 function run_banana(&$page, $class, array $args)
 {
-    $banana = new $class(S::user(), $args);
+    $user =& S::user();
+    $banana = new $class($user, $args);
     $page->assign('banana', $banana->run());
     $page->addCssInline($banana->css());
     $page->addCssLink('banana.css');
index 1bf497a..2ec904b 100644 (file)
@@ -63,9 +63,7 @@ class MLBanana extends Banana
             Banana::$msgshow_mimeparts[] = 'source';
         }
         array_push(Banana::$msgparse_headers, 'x-org-id', 'x-org-mail');
-        if (!S::v('core_rss_hash')) {
-            Banana::$feed_active = false;
-        }
+        Banana::$feed_active = S::hasAuthToken();
 
         MLBanana::$listname = $params['listname'];
         MLBanana::$domain   = $params['domain'];
@@ -83,9 +81,9 @@ class MLBanana extends Banana
         Banana::$msgedit_headers['X-Org-Mail'] = $this->user->forlifeEmail();
 
         // Tree color
-        $req = XDB::query("SELECT  tree_unread, tree_read
-                             FROM  {$globals->banana->table_prefix}profils
-                            WHERE  uid={?}", S::i('uid'));
+        $req = XDB::query('SELECT  tree_unread, tree_read
+                             FROM  forum_profiles
+                            WHERE  uid= {?}', $this->user->id());
         if (!(list($unread, $read) = $req->fetchOneRow())) {
             $unread = 'o';
             $read = 'dg';
index f524ec8..54802e7 100644 (file)
@@ -23,7 +23,10 @@ function __autoload($cls)
 {
     if (!pl_autoload($cls)) {
         $cls = strtolower($cls);
-        if (substr($cls, -3, 3) == 'req') {
+        if (substr($cls, 0, 4) == 'ufc_' || substr($cls, 0, 4) == 'ufo_') {
+            __autoload('userfilter');
+            return;
+        } else if (substr($cls, -3, 3) == 'req') {
             @include 'validations.inc.php';
             return;
         } else if (substr($cls, 0, 6) == 'banana') {
index 9d2e2b7..dd63591 100644 (file)
@@ -156,8 +156,16 @@ function education_fmt($name, $url, $degree, $grad_year, $field, $program, $sexe
 
 function _education_fmt($params, &$smarty)
 {
-    extract($params);
-    return education_fmt($name, $url, $degree, $grad_year, $field, $program, $sexe, $long);
+    $params  = new PlDict($params);
+    $edu     = $params->v('edu');
+    if (!$params->has('sex')) {
+        $profile = $params->v('profile');
+        $sex = $profile->isFemale();
+    } else {
+        $sex = $params->b('sex');
+    }
+    return education_fmt($edu['school_short'], $edu['school_url'], $edu['degree_short'], $edu['grad_year'],
+                         $edu['field'], $edu['program'], $sex, $params->b('long'));
 }
 Platal::page()->register_function('education_fmt', '_education_fmt');
 
index 2de4a2e..546063b 100644 (file)
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
  ***************************************************************************/
 
-function fill_email_combobox(PlPage& $page)
+function fill_email_combobox(PlPage& $page, $user = null, $profile = null)
 {
     global $globals;
 
-    $user = S::user();
+    if (is_null($user) && is_null($profile)) {
+        $user = S::user();
+        $profile = $user->profile();
+    }
     $email_type = "directory";
 
-    $res = XDB::query(
-            "SELECT  email_directory
-               FROM  profile_directory
-              WHERE  uid = {?}", $user->id());
-    $email_directory = $res->fetchOneCell();
-    if ($email_directory) {
-        $page->assign('email_directory', $email_directory);
-        list($alias, $domain) = explode('@', $email_directory);
-    } else {
-        $page->assign('email_directory', '');
-        $email_type = NULL;
-        $alias = $domain = '';
+    if ($profile) {
+        $res = XDB::query(
+                "SELECT  email_directory
+                   FROM  profile_directory
+                  WHERE  uid = {?}", $profile->id());
+        $email_directory = $res->fetchOneCell();
+        if ($email_directory) {
+            $page->assign('email_directory', $email_directory);
+            list($alias, $domain) = explode('@', $email_directory);
+        } else {
+            $page->assign('email_directory', '');
+            $email_type = NULL;
+            $alias = $domain = '';
+        }
     }
 
-    $res = XDB::query(
-            "SELECT  alias
-               FROM  virtual
-         INNER JOIN  virtual_redirect USING(vid)
-              WHERE  (redirect = {?} OR redirect = {?})
-                     AND alias LIKE '%@{$globals->mail->alias_dom}'",
-            $user->forlifeEmail(),
-            // TODO: remove this über-ugly hack. The issue is that you need
-            // to remove all @m4x.org addresses in virtual_redirect first.
-            $user->login() . '@' . $globals->mail->domain2);
-    $melix = $res->fetchOneCell();
-    if ($melix) {
-        list($melix) = explode('@', $melix);
-        $page->assign('melix', $melix);
-        if (($domain == $globals->mail->alias_dom) || ($domain == $globals->mail->alias_dom2)) {
-            $email_type = "melix";
+    if ($user) {
+        $melix = $user->emailAlias();
+        if ($melix) {
+            list($melix) = explode('@', $melix);
+            $page->assign('melix', $melix);
+            if (($domain == $globals->mail->alias_dom) || ($domain == $globals->mail->alias_dom2)) {
+                $email_type = "melix";
+            }
         }
-    }
 
-    $res = XDB::query(
-            "SELECT  alias
-               FROM  aliases
-              WHERE  id={?} AND (type='a_vie' OR type='alias')", $user->id());
-    $res = $res->fetchAllAssoc();
-    $page->assign('list_email_X', $res);
-    if (($domain == $globals->mail->domain) || ($domain == $globals->mail->domain2)) {
-        foreach ($res as $res_it) {
-            if ($alias == $res_it['alias']) {
-                $email_type = "X";
+        $res = XDB::query(
+                "SELECT  alias
+                   FROM  aliases
+                  WHERE  id={?} AND (type='a_vie' OR type='alias')", $user->id());
+        $res = $res->fetchAllAssoc();
+        $page->assign('list_email_X', $res);
+        if (($domain == $globals->mail->domain) || ($domain == $globals->mail->domain2)) {
+            foreach ($res as $res_it) {
+                if ($alias == $res_it['alias']) {
+                    $email_type = "X";
+                }
             }
         }
-    }
 
-    require_once 'emails.inc.php';
-    $redirect = new Redirect($user);
-    $redir    = array();
-    foreach ($redirect->emails as $redirect_it) {
-        if ($redirect_it instanceof EmailRedirection) {
-            $redir[] = $redirect_it->email;
-            if ($email_directory == $redirect_it->email) {
-                $email_type = "redir";
+        require_once 'emails.inc.php';
+        $redirect = new Redirect($user);
+        $redir    = array();
+        foreach ($redirect->emails as $redirect_it) {
+            if ($redirect_it instanceof EmailRedirection) {
+                $redir[] = $redirect_it->email;
+                if ($email_directory == $redirect_it->email) {
+                    $email_type = "redir";
+                }
             }
         }
-    }
-    $page->assign('list_email_redir', $redir);
+        $page->assign('list_email_redir', $redir);
 
-    $res = XDB::query(
-            "SELECT  email
-               FROM  profile_job
-              WHERE  uid = {?}", $user->id());
-    $res = $res->fetchAllAssoc();
-    $pro = array();
-    foreach ($res as $res_it) {
-        if ($res_it['email'] != '') {
-            $pro[] = $res_it['email'];
-            if ($email_directory == $res_it['email']) {
-                $email_type = "pro";
+        $res = XDB::query(
+                "SELECT  email
+                   FROM  profile_job
+                  WHERE  uid = {?}", $user->id());
+        $res = $res->fetchAllAssoc();
+        $pro = array();
+        foreach ($res as $res_it) {
+            if ($res_it['email'] != '') {
+                $pro[] = $res_it['email'];
+                if ($email_directory == $res_it['email']) {
+                    $email_type = "pro";
+                }
             }
         }
-    }
-    $page->assign('list_email_pro', $pro);
+        $page->assign('list_email_pro', $pro);
+        $page->assign('email_type', $email_type);
 
-    $page->assign('email_type', $email_type);
+    } else {
+        $page->assign('list_email_X', array());
+        $page->assign('list_email_redir', array());
+        $page->assign('list_email_pro', array());
+    }
 }
 
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
index d6e885f..084d25b 100644 (file)
@@ -380,18 +380,18 @@ class EmailStorage extends Email
     // Retrieves the current list of actives storages.
     private function get_storages()
     {
-        $res = XDB::query("SELECT  mail_storage
-                             FROM  auth_user_md5
-                            WHERE  user_id = {?}", $this->user->id());
-        return new PlFlagSet($res->fetchOneCell());
+        return new PlFlagSet(XDB::fetchOneCell('SELECT  storage
+                                                  FROM  email_options
+                                                 WHERE  uid = {?}',
+                                                $this->user->id()));
     }
 
     // Updates the list of active storages.
     private function set_storages($storages)
     {
-        XDB::execute("UPDATE  auth_user_md5
-                         SET  mail_storage = {?}
-                       WHERE  user_id = {?}", $storages, $this->user->id());
+        XDB::execute("UPDATE  email_options
+                         SET  storage = {?}
+                       WHERE  uid = {?}", $storages, $this->user->id());
     }
 
     // Returns the list of allowed storages for the @p user.
index accc779..d63af4d 100644 (file)
@@ -40,18 +40,12 @@ function post_queue_u_create($job) {
     }
 
     // Sends the 'account created' email to the user, with basic documentation.
-    $res = XDB::query(
-        "SELECT  FIND_IN_SET('femme', u.flags), prenom
-           FROM  auth_user_md5 AS u
-          WHERE  u.user_id = {?}", $user->id());
-    list($sexe, $prenom) = $res->fetchOneRow();
-
     $mailer = new PlMailer('googleapps/create.mail.tpl');
     $mailer->assign('account', $account);
     $mailer->assign('email', $user->bestEmail());
     $mailer->assign('googleapps_domain', $globals->mailstorage->googleapps_domain);
-    $mailer->assign('prenom', $prenom);
-    $mailer->assign('sexe', $sexe);
+    $mailer->assign('prenom', $user->displayName());
+    $mailer->assign('sexe', $user->isFemale());
     $mailer->send();
 }
 
@@ -79,17 +73,11 @@ function post_queue_u_update($job) {
             }
 
             // Sends an email to the account owner.
-            $res = XDB::query(
-                "SELECT  FIND_IN_SET('femme', u.flags), prenom
-                   FROM  auth_user_md5 AS u
-                  WHERE  u.user_id = {?}", $user->id());
-            list($sexe, $prenom) = $res->fetchOneRow();
-
             $mailer = new PlMailer('googleapps/unsuspend.mail.tpl');
             $mailer->assign('account', $account);
             $mailer->assign('email', $user->bestEmail());
-            $mailer->assign('prenom', $prenom);
-            $mailer->assign('sexe', $sexe);
+            $mailer->assign('prenom', $user->displayName());
+            $mailer->assign('sexe', $user->isFemale());
             $mailer->send();
         }
     }
@@ -369,17 +357,7 @@ class GoogleAppsAccount
 
         if (!$this->pending_update_suspension) {
             if ($this->sync_password) {
-                $res = XDB::query(
-                    "SELECT  password
-                       FROM  auth_user_md5
-                      WHERE  user_id = {?}", $this->user->id());
-                $password = ($res->numRows() > 0 ? $res->fetchOneCell() : false);
-            } else {
-                $password = false;
-            }
-
-            if ($password) {
-                $this->create_queue_job('u_update', array('suspended' => false, 'password' => $password));
+                $this->create_queue_job('u_update', array('suspended' => false, 'password' => $this->user->password()));
             } else {
                 $this->create_queue_job('u_update', array('suspended' => false));
             }
@@ -390,18 +368,22 @@ 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;
         }
 
         if (!$this->pending_create) {
             // Retrieves information on the new account.
-            $res = XDB::query(
-                "SELECT  nom, nom_usage, prenom
-                   FROM  auth_user_md5
-                  WHERE  user_id = {?}", $this->user->id());
-            list($nom, $nom_usage, $prenom) = $res->fetchOneRow();
+            // TODO: retreive first_name and last_name from the profile.
+            if (!$user->hasProfile()) {
+                $prenom = $user->displayName();
+                $nom    = $user->fullName();
+            } else {
+                $prenom = $user->profile()->firstName();
+                $nom    = $user->profile()->lastName();
+            }
 
             // Adds an 'unprovisioned' entry in the gapps_accounts table.
             XDB::execute(
@@ -417,8 +399,7 @@ class GoogleAppsAccount
                 $password_sync,
                 $redirect_mails,
                 $this->g_account_name,
-                $prenom,
-                ($nom_usage ? $nom_usage : $nom));
+                $prenom, $nom);
 
             // Adds the creation job in the GApps queue.
             $this->create_queue_job(
@@ -426,7 +407,7 @@ class GoogleAppsAccount
                 array(
                     'username' => $this->g_account_name,
                     'first_name' => $prenom,
-                    'last_name' => ($nom_usage ? $nom_usage : $nom),
+                    'last_name' => $nom,
                     'password' => $password,
                 ));
 
index 7a53989..be7dcbf 100644 (file)
@@ -185,29 +185,33 @@ class Marketing
         }
     }
 
-    static public function relance($uid, $nbx = -1)
+    static public function getAliveUsersCount()
+    {
+        $uf = new UserFilter(new UFC_Not(new UFC_Dead()));
+        return $uf->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::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;
         }
 
-        require_once('secure_hash.inc.php');
         $hash     = rand_url_id(12);
         $pass     = rand_pass();
-        $pass_encrypted = hash_encrypt($pass);
+        $pass_encrypted = sha1($pass);
         $fdate    = strftime('%d %B %Y', strtotime($date));
 
         $mymail = new PlMailer('marketing/relance.mail.tpl');
@@ -222,8 +226,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();
     }
 }
 
@@ -276,8 +280,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 3f7bcdd..decda36 100644 (file)
@@ -110,15 +110,15 @@ abstract class MassMailer
         return $mail ? $this->_title_mail : $this->_title;
     }
 
-    public function head($prenom = null, $nom = null, $sexe = null, $type = 'text')
+    public function head($user = null, $type = 'text')
     {
-        if (is_null($prenom)) {
+        if (is_null($user)) {
             return $this->_head;
         } else {
             $head = $this->_head;
-            $head = str_replace('<cher>',   $sexe ? 'Chère' : 'Cher', $head);
-            $head = str_replace('<prenom>', $prenom, $head);
-            $head = str_replace('<nom>',    $nom,    $head);
+            $head = str_replace('<cher>',   $user->isFemale() ? 'Chère' : 'Cher', $head);
+            $head = str_replace('<prenom>', $user->displayName(), $head);
+            $head = str_replace('<nom>', '', $head);
             return format_text($head, $type, 2, 64);
         }
     }
@@ -134,26 +134,22 @@ abstract class MassMailer
         }
     }
 
-    public function toText(&$page, $prenom, $nom, $sexe)
+    public function toText(&$page, $user)
     {
         $this->css($page);
         $page->assign('is_mail', false);
         $page->assign('mail_part', 'text');
-        $page->assign('prenom', $prenom);
-        $page->assign('nom', $nom);
-        $page->assign('sexe', $sexe);
+        $page->assign('user', $user);
         $this->assignData($page);
     }
 
-    public function toHtml(&$page, $prenom, $nom, $sexe)
+    public function toHtml(&$page, $user)
     {
         $this->css($page);
         $page->assign('prefix', $this->_prefix . '/' . $this->id());
         $page->assign('is_mail', false);
         $page->assign('mail_part', 'html');
-        $page->assign('prenom', $prenom);
-        $page->assign('nom', $nom);
-        $page->assign('sexe', $sexe);
+        $page->assign('user', $user);
         $this->assignData($page);
     }
 
@@ -164,71 +160,58 @@ abstract class MassMailer
         return $hash;
     }
 
-    public function sendTo($hruid, $email, $prenom, $nom, $sexe, $html, $hash = 0)
+    public function sendTo($user, $hash = null)
     {
-        // If $email is not a real email address, tries to compute it up from
-        // the hruid. Otherwise, we suppose that caller will have used a valid
-        // and canonical email address.
-        if (strpos($email, '@') === false) {
-            if (!($user = User::getSilent($email))) {
-                Platal::page()->trigError("'$email' is neither a valid email address nor a valid login; did not send the email.");
-            }
-            $email = $user->bestEmail();
+        if (is_null($hash)) {
+            $hash = XDB::fetchOneCell("SELECT  hash
+                                         FROM  {$this->_subscriptionTable}
+                                        WHERE  user_id = {?}", $user->id());
         }
-
-        if ($hruid && (is_null($hash) || $hash == 0)) {
-            $hash = $this->createHash(array($email, $prenom, $nom, $sexe, $html, rand(), "X.org rulez"));
-            XDB::query("UPDATE  {$this->_subscriptionTable} as ni
-                    INNER JOIN  auth_user_md5 AS u USING (user_id)
-                           SET  ni.hash = {?}
-                         WHERE  ni.user_id != 0 AND u.hruid = {?}",
-                       $hash, $hruid);
+        if (is_null($hash)) {
+            $hash = $this->createHash(array($user->displayName(), $user->fullName(),
+                                       $user->isFemale(), $user->isEmailFormatHtml(),
+                                       rand(), "X.org rulez"));
+            XDB::execute("UPDATE  {$this->_subscriptionTable} as ni
+                             SET  ni.hash = {?}
+                           WHERE  ni.user_id != {?}",
+                         $hash, $user->id());
         }
 
         $mailer = new PlMailer($this->_tpl);
         $this->assignData($mailer);
         $mailer->assign('is_mail', true);
-        $mailer->assign('prenom',  $prenom);
-        $mailer->assign('nom',     $nom);
-        $mailer->assign('sexe',    $sexe);
+        $mailer->assign('user', $user);
         $mailer->assign('prefix',  null);
         $mailer->assign('hash',    $hash);
-        $mailer->assign('email',   $email);
-        $mailer->assign('alias',   $hruid);
-        $mailer->addTo("\"$prenom $nom\" <$email>");
-        $mailer->send($html);
+        $mailer->addTo('"' . $user->fullName() . '" <' . $user->bestEmail() . '>');
+        $mailer->send($user->isEmailFormatHtml());
     }
 
     protected function getAllRecipients()
     {
         global $globals;
-        return  "SELECT  u.user_id, u.hruid, CONCAT(a.alias, '@{$globals->mail->domain}'),
-                         u.prenom, IF(u.nom_usage='', u.nom, u.nom_usage),
-                         FIND_IN_SET('femme', u.flags),
-                         q.core_mail_fmt AS pref, ni.hash AS hash
+        return  "SELECT  a.uid
                    FROM  {$this->_subscriptionTable}  AS ni
-             INNER JOIN  auth_user_md5   AS u  USING(user_id)
-             INNER JOIN  auth_user_quick AS q  ON(q.user_id = u.user_id)
-             INNER JOIN  aliases         AS a  ON(u.user_id=a.id AND FIND_IN_SET('bestalias',a.flags))
-              LEFT JOIN  emails          AS e  ON(e.uid=u.user_id AND e.flags='active')
+             INNER JOIN  accounts AS a ON (ni.user_id = a.uid)
+              LEFT JOIN  email_options AS eo ON (eo.uid = a.uid)
+              LEFT JOIN  emails   AS e ON (e.uid = a.uid AND e.flags='active')
                   WHERE  ni.last < {?} AND ({$this->subscriptionWhere()}) AND
-                         (e.email IS NOT NULL OR FIND_IN_SET('googleapps', u.mail_storage))
-               GROUP BY  u.user_id";
+                         (e.email IS NOT NULL OR FIND_IN_SET('googleapps', eo.storage))
+               GROUP BY  a.uid";
     }
 
     public function sendToAll()
     {
         $this->setSent();
-        $query = $this->getAllRecipients() . " LIMIT {?}";
+        $query = XDB::format($this->getAllRecipients(), $this->id()) . ' LIMIT 60';
         while (true) {
-            $res = XDB::iterRow($query, $this->_id, 60);
-            if (!$res->total()) {
+            $users = User::getBulkUsersWithUIDs(XDB::fetchColumn($query));
+            if (count($users) == 0) {
                 return;
             }
-            $sent = array();
-            while (list($uid, $hruid, $email, $prenom, $nom, $sexe, $fmt, $hash) = $res->next()) {
-                $sent[] = "(user_id='$uid'" . (!$uid ? " AND email='$email')": ')');
-                $this->sendTo($hruid, $email, $prenom, $nom, $sexe, $fmt=='html', $hash);
+            foreach ($users as $user) {
+                $sent[] = XDB::format('user_id = {?}', $user->id());
+                $this->sendTo($user, $hash);
             }
             XDB::execute("UPDATE  {$this->_subscriptionTable}
                              SET  last = {?}
index bae71b0..6601c1e 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)
+abstract class WatchOperation
 {
-    XDB::execute('REPLACE INTO  watch_sub (uid,cid) SELECT {?},id FROM watch_cat', $uid);
-}
+    protected $date;
 
-// }}}
-// {{{ function register_watch_op
-
-function register_watch_op($uid, $cid, $date='', $info='')
-{
-    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);
+    public function getTitle($count = 0)
+    {
+        if ($count == 1) {
+            return str_replace(array('$x', '$s'), '', $this->title);
+        } else {
+            return str_replace(array('$x', '$s'), array('x', 's'), $this->title);
         }
-        XDB::execute('UPDATE auth_user_md5 SET DATE=NOW() WHERE user_id={?}', $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)";
+    public function getCondition(PlUser &$user, $date)
+    {
+        $this->date = $date;
+        if (!$user->watch($this->flag)) {
+            return new UFC_False();
+        } else {
+            return $this->buildCondition($user);
+        }
     }
 
-    $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
+    abstract protected function buildCondition(PlUser &$user);
+    abstract public function getOrder();
+    abstract public function getDate(PlUser &$user);
 
-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);
+    public function publicationDate(PlUser &$user)
+    {
+        return $this->getDate($user);
     }
-}
 
-// }}}
-// {{{
-
-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>';
+    public function seen(PlUser &$user, $last)
+    {
+        return strtotime($this->getDate($user)) > $last;
     }
-    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);
+    public function getData(PlUser &$user)
+    {
+        return null;
+    }
 }
 
-// {{{ class AllNotifs
-
-class AllNotifs
+class WatchProfileUpdate extends WatchOperation
 {
-    public $_cats = Array();
-    public $_data = Array();
+    public $flag  = 'profile';
+    public $title = 'Mise$s à jour de fiche';
 
-    public function __construct()
+    public static function register(Profile &$profile, $field)
     {
-        $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;
-        }
+        XDB::execute('REPLACE INTO  watch_profile (uid, ts, field)
+                            VALUES  ({?}, NOW(), {?})',
+                     $profile->id(), $field);
     }
-}
-
-// }}}
-// {{{ class Notifs
-
-class Notifs
-{
-    public $_uid;
-    public $_cats = Array();
-    public $_data = Array();
 
-    function __construct($uid, $up=false)
+    protected function buildCondition(PlUser &$user)
     {
-        $this->_uid = $uid;
+        return new UFC_And(new UFC_ProfileUpdated('>', $this->date),
+                           new UFC_WatchContact($user));
+    }
 
-        $res = XDB::iterator("SELECT * FROM watch_cat");
-        while($tmp = $res->next()) {
-            $this->_cats[$tmp['id']] = $tmp;
-        }
+    public function getOrder()
+    {
+        return new UFO_ProfileUpdate();
+    }
 
-        $lastweek = date('YmdHis', time() - 7*24*60*60);
+    public function getDate(PlUser &$user)
+    {
+        return $user->profile()->last_change;
+    }
 
-        // 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);
+    static private $descriptions = 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');
+    public function getData(PlUser &$user)
+    {
+        $data = XDB::fetchColumn('SELECT  field
+                                    FROM  watch_profile
+                                   WHERE  uid = {?} AND ts > FROM_UNIXTIME({?}) AND field != \'\'
+                                ORDER BY  ts',
+                                 $user->id(), $this->date);
+        if (count($data) == 0) {
+            return null;
+        } else {
+            $text = array();
+            foreach ($data as $f) {
+                $text[] = self::$descriptions[$f];
             }
-            $this->_data[$tmp['cid']][$tmp['promo']][] = $tmp;
-        }
-
-        if($up) {
-            XDB::execute('UPDATE auth_user_quick SET watch_last=NOW() WHERE user_id={?}', $uid);
+            return $text;
         }
     }
 }
 
-// }}}
-// {{{ class Watch
-
-class Watch
+class WatchRegistration extends WatchOperation
 {
-    public $_uid;
-    public $_promos;
-    public $_nonins;
-    public $_cats = Array();
-    public $_subs;
-    public $watch_contacts;
-    public $watch_mail;
-
-    public function __construct($uid)
+    public $flag  = 'registration';
+    public $title = 'Inscription$s';
+
+    protected function buildCondition(PlUser &$user)
     {
-        $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',watch_flags),FIND_IN_SET('mail',watch_flags)
-                             FROM  auth_user_quick
-                            WHERE  user_id={?}", $uid);
-        list($this->watch_contacts,$this->watch_mail) = $res->fetchOneRow();
-
-        $res = XDB::iterator("SELECT * FROM watch_cat");
-        while($tmp = $res->next()) {
-            $this->_cats[$tmp['id']] = $tmp;
-        }
+        return new UFC_And(new UFC_Registered(false, '>', $this->date),
+                           new UFC_Or(new UFC_WatchContact($user),
+                                      new UFC_WatchPromo($user)));
     }
 
-    public function saveFlags()
+    public function getOrder()
     {
-        $flags = "";
-        if ($this->watch_contacts)
-            $flags = "contacts";
-        if ($this->watch_mail)
-            $flags .= ($flags ? ',' : '')."mail";
-        XDB::execute('UPDATE auth_user_quick SET watch_flags={?} WHERE user_id={?}',
-            $flags, $this->_uid);
+        return new UFO_Registration();
     }
 
-    public function cats()
+    public function getDate(PlUser &$user)
     {
-        return $this->_cats;
+        return $user->registration_date;
     }
+}
+
+class WatchDeath extends WatchOperation
+{
+    public $flag  = 'death';
+    public $title = 'Décès';
 
-    public function subs($i)
+    protected function buildCondition(PlUser &$user)
     {
-        return $this->_subs->_data[$i];
+        return new UFC_And(new UFC_Dead('>', $this->date, true),
+                           new UFC_Or(new UFC_WatchPromo($user),
+                                      new UFC_WatchContact($user)));
     }
 
-    public function promos()
+    public function getOrder()
     {
-        return $this->_promos->toRanges();
+        return new UFO_Death();
     }
 
-    public function nonins()
+    public function getDate(PlUser &$user)
     {
-        return $this->_nonins->_data;
+        return $user->profile()->deathdate;
     }
-}
-
-// }}}
-// {{{ class WatchSub
-
-class WatchSub
-{
-    public $_uid;
-    public $_data = Array();
 
-    public function __construct($uid)
+    public function publicationDate(PlUser &$user)
     {
-        $this->_uid = $uid;
-        $res = XDB::iterRow('SELECT cid FROM watch_sub WHERE uid={?}', $uid);
-        while(list($c) = $res->next()) {
-            $this->_data[$c] = $c;
-        }
+        return $user->profile()->deathdate_rec;
     }
 
-    public function update($ind)
+    public function seen(PlUser &$user, $last)
     {
-        $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 strtotime($user->profile()->deathdate_rec) > $last;
     }
 }
 
-// }}}
-// {{{ class PromoNotifs
-
-class PromoNotifs
+class WatchBirthday extends WatchOperation
 {
-    public $_uid;
-    public $_data = Array();
+    const WATCH_LIMIT = 604800; // 1 week
 
-    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 $flag  = 'birthday';
+    public $title = 'Anniversaire$s';
 
-    public function add($p)
+    protected function buildCondition(PlUser &$user)
     {
-        $promo = intval($p);
-        XDB::execute('REPLACE INTO watch_promo (uid,promo) VALUES({?},{?})', $this->_uid, $promo);
-        $this->_data[$promo] = $promo;
-        asort($this->_data);
+        return new UFC_And(new UFC_OR(new UFC_Birthday('=', time()),
+                                      new UFC_And(new UFC_Birthday('<=', time() + self::WATCH_LIMIT),
+                                                  new UFC_Birthday('>', $this->date + self::WATCH_LIMIT))),
+                           new UFC_Or(new UFC_WatchPromo($user),
+                                      new UFC_WatchContact($user)));
     }
 
-    public function del($p)
+    public function getOrder()
     {
-        $promo = intval($p);
-        XDB::execute('DELETE FROM watch_promo WHERE uid={?} AND promo={?}', $this->_uid, $promo);
-        unset($this->_data[$promo]);
+        return new UFO_Birthday();
     }
 
-    public function addRange($_p1,$_p2)
+    public function getDate(PlUser &$user)
     {
-        $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);
+        return $user->profile()->next_birthday;
     }
 
-    public function delRange($_p1,$_p2)
+    public function publicationDate(PlUser &$user)
     {
-        $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);
+        return date('Y-m-d', strtotime($user->profile()->next_birthday) - self::WATCH_LIMIT);
     }
 
-    public function toRanges()
+    public function seen(PlUser &$user, $last)
     {
-        $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;
+        $birthday = strtotime($user->profile()->next_birthday);
+        return $birthday >  $last + self::WATCH_LIMIT
+            || date('Ymd', $birthday) == date('Ymd');
     }
 }
 
-// }}}
-// {{{ class NoninsNotifs
-
-class NoninsNotifs
+class Watch
 {
-    public $_uid;
-    public $_data = Array();
+    private static  $classes = array('WatchRegistration',
+                                     'WatchProfileUpdate',
+                                     'WatchDeath',
+                                     'WatchBirthday');
 
-    public function __construct($uid)
+    private static function fetchCount(PlUser &$user, $date, $class)
     {
-        $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;
+        $obj = new $class();
+        $uf = new UserFilter($obj->getCondition($user, $date));
+        return $uf->getTotalCount();
+    }
+
+    public static function getCount(PlUser &$user, $date = null)
+    {
+        $count = 0;
+        if (is_null($date)) {
+            $date = $user->watchLast();
         }
+        foreach (self::$classes as $class) {
+            $count += self::fetchCount($user, $date, $class);
+        }
+        return $count;
     }
 
-    public function del($p)
+
+    private static function fetchEvents(PlUser &$user, $date, $class)
     {
-        unset($this->_data["$p"]);
-        XDB::execute('DELETE FROM  watch_nonins WHERE uid={?} AND ni_id={?}', $this->_uid, $p);
+        $obj = new $class();
+        $uf = new UserFilter($obj->getCondition($user, $date),
+                             array($obj->getOrder(), new UFO_Name(UserFilter::DN_SORT)));
+        $users = $uf->getUsers();
+        if (count($users) == 0) {
+            return null;
+        } else {
+            return array('operation' => $obj,
+                         'title'     => $obj->getTitle(count($users)),
+                         'users'     => $users);
+        }
     }
 
-    public function add($p)
+    public static function getEvents(PlUser &$user, $date = null)
     {
-        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();
+        if (is_null($date)) {
+            $date = $user->watchLast();
+        }
+        $events = array();
+        foreach (self::$classes as $class) {
+            $e = self::fetchEvents($user, $date, $class);
+            if (!is_null($e)) {
+                $events[] = $e;
+            }
+        }
+        return $events;
     }
 }
 
-// }}}
-
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
 ?>
diff --git a/include/secure_hash.inc.php b/include/secure_hash.inc.php
deleted file mode 100644 (file)
index ff0d3a2..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-<?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                *
- ***************************************************************************/
-
-function hash_encrypt($s) {
-    return sha1($s);
-}
-
-function hash_xor($a, $b) {
-    $c = "";
-    $i = strlen($a);
-    $j = strlen($b);
-    if ($i < $j) {
-        $d = $a; $a = $b; $b = $d;
-        $k = $i; $i = $j; $j = $k;
-    }
-    for ($k = 0; $k < $j; $k++)
-        $c .= dechex(hexdec($a{$k}) ^ hexdec($b{$k}));
-    for (; $k < $i; $k++)
-        $c .= $a{$k};
-    return $c;
-}
-// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
-?>
diff --git a/include/synchro_ax.inc.php b/include/synchro_ax.inc.php
deleted file mode 100644 (file)
index 798b4dd..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-<?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                *
- ***************************************************************************/
-
-require_once('user.func.inc.php');
-
-function is_ax_key_missing() {
-    global $globals;
-    return !isset($globals->webservice->private_key_ax) || !is_file($globals->webservice->private_key_ax);
-}
-
-function get_user_ax($matricule_ax, $raw=false)
-{
-    require_once('webservices/ax/client.inc');
-
-    $ancien = recupere_infos_ancien($matricule_ax);
-
-    $userax = Array();
-    $userax['matricule_ax'] = $matricule_ax;
-
-    $userax['nom'] = strtoupper($ancien->Nom_patr());
-    $userax['nom_usage'] = strtoupper($ancien->Nom_usuel());
-    if ($userax['nom_usage'] == $userax['nom']) $userax['nom_usage'] = '';
-    $userax['prenom'] = $ancien->Prenom();
-    $userax['sexe'] = ($ancien->Civilite() != 'M')?1:0;
-    $userax['promo'] = $ancien->Promo();
-/*    $userax['nationalite'] = $ancien->Nationalite();
-    if ($userax['nationalite'] == 'F') $userax['nationalite'] = 'Français'; */
-    //$userax['date'] = substr($ancien[12], 0, 10);
-    $userax['mobile'] = trim($ancien->Mobile(0));
-/*    if ($ancien->Corps() == 'D' || $ancien->Corps() == 'Z') {
-        $userax['corps'] = false;
-    } else {
-        $userax['corps'] = $ancien->Corps();
-        $userax['corps_grade'] = $ancien->Grade();
-    } */
-    $userax['adr_pro'] = array();
-
-    for ($i = 0; $i < $ancien->Num_Activite(); $i++) {
-        $jobax = array();
-        $jobax['entreprise'] = $ancien->Entreprise($i);
-        if (!$jobax['entreprise'])
-            $jobax['entreprise'] = $ancien->Adresse_act_adresse1($i);
-        $jobax['poste'] = $ancien->Fonction($i);
-        $jobax['adr1'] = $ancien->Adresse_act_adresse1($i);
-        $jobax['adr2'] = $ancien->Adresse_act_adresse2($i);
-        $jobax['adr3'] = $ancien->Adresse_act_adresse3($i);
-        $jobax['postcode']   = $ancien->Adresse_act_code_pst($i);
-        $jobax['city'] = $ancien->Adresse_act_ville($i);
-        $jobax['region'] = $ancien->Adresse_act_etat_region($i);
-        $jobax['countrytxt'] = ucwords(strtolower($ancien->Adresse_act_pays($i)));
-        $jobax['tel']  = $ancien->Adresse_act_tel($i);
-        $jobax['fax']  = $ancien->Adresse_act_fax($i);
-        $jobax['mobile'] = $ancien->Adresse_act_mobile($i);
-        $jobax['pub'] = 'ax';
-        $jobax['tel_pub'] = 'ax';
-        $jobax['adr_pub'] = 'ax';
-        $jobax['email_pub'] = 'ax';
-        $userax['adr_pro'][] = $jobax;
-    }
-
-    $userax['adr'] = array();
-    for($i=$ancien->Num_adresse() - 1; $i >= 0; $i--) {
-        $adrax = array();
-        $adrax['adr1'] = $ancien->Adresse1($i);
-        $adrax['adr2'] = $ancien->Adresse2($i);
-        $adrax['adr3'] = $ancien->Adresse3($i);
-        $adrax['postcode'] = $ancien->Code_pst($i);
-        $adrax['city'] = $ancien->Ville($i);
-        $adrax['region'] = $ancien->Etat_region($i);
-        $adrax['countrytxt'] = ucwords(strtolower($ancien->Pays($i)));
-        $adrax['pub'] = 'ax';
-        if ($ancien->Tel($i) || $ancien->Fax($i)) {
-            $adrax['tels'] = array();
-            if ($tel = $ancien->Tel($i))
-                $adrax['tels'][] = array('tel' => $tel, 'tel_type' => 'Tél.', 'tel_pub' => 'ax');
-            if ($tel = $ancien->Fax($i))
-                $adrax['tels'][] = array('tel' => $tel, 'tel_type' => 'Fax', 'tel_pub' => 'ax');
-        }
-        if ($ancien->Mobile($i)) $userax['mobile'] = $ancien->Mobile($i);
-        $userax['adr'][$i] = $adrax;
-    }
-
-/*    $userax['formation'] = array();
-    for($i=$ancien->Num_formation() - 1; $i >= 0; $i--)
-        $userax['formation'][$i] = $ancien->Formation($i);*/
-
-    return $userax;
-}
-
-function ax_synchronize($login, $uid) {
-    require_once('user.func.inc.php');
-    require_once 'profil.func.inc.php';
-    // get details from user, but looking only info that can be seen by ax
-    $user  = get_user_details($login, $uid, 'ax');
-    $userax= get_user_ax($user['matricule_ax']);
-    $diff = diff_user_details($userax, $user, 'ax');
-    set_user_details($user['user_id'], $diff);
-}
-// vim:set et sw=4 sts=4 sws=4 enc=utf-8:
-?>
index 3eb76f5..7e98747 100644 (file)
@@ -27,7 +27,7 @@
 function user_clear_all_subs($user_id, $really_del=true)
 {
     // keep datas in : aliases, adresses, tels, profile_education, binets_ins, contacts, groupesx_ins, homonymes, identification_ax, photo
-    // delete in     : auth_user_md5, auth_user_quick, competences_ins, emails, entreprises, langues_ins, mentor,
+    // delete in     : competences_ins, emails, entreprises, langues_ins, mentor,
     //                 mentor_pays, mentor_secteurs, newsletter_ins, perte_pass, requests, user_changes, virtual_redirect, watch_sub
     // + delete maillists
 
@@ -36,40 +36,41 @@ function user_clear_all_subs($user_id, $really_del=true)
     $user = User::getSilent($uid);
     list($alias) = explode('@', $user->forlifeEmail());
 
+    // TODO: clear profile.
     $tables_to_clear = array('uid' => array('competences_ins', 'profile_job', 'langues_ins', 'profile_mentor_country',
                                             'profile_mentor_sector', 'profile_mentor', 'perte_pass', 'watch_sub'),
                              'user_id' => array('requests', 'user_changes'));
 
     if ($really_del) {
         array_push($tables_to_clear['uid'], 'emails', 'groupex.membres', 'contacts', 'adresses', 'profile_phones',
-                                            'photo', 'perte_pass', 'langues_ins', 'forums.abos', 'forums.profils');
-        array_push($tables_to_clear['user_id'], 'newsletter_ins', 'auth_user_quick', 'binets_ins');
+                                            'photo', 'perte_pass', 'langues_ins', 'forum_subs', 'forum_profiles');
+        array_push($tables_to_clear['user_id'], 'newsletter_ins', 'binets_ins');
         $tables_to_clear['id'] = array('aliases');
         $tables_to_clear['contact'] = array('contacts');
-        XDB::execute("UPDATE auth_user_md5
-                         SET date_ins = 0, promo_sortie = 0, nom_usage = '',  password = '', perms = 'pending',
-                             nationalite = '', nationalite2 = '', nationalite3 = '', cv = '', section = 0,
-                             date = 0, smtppass = '', mail_storage = ''
-                       WHERE user_id = {?}", $uid);
+        XDB::execute("UPDATE accounts
+                         SET registration_date = 0, state = 'pending', password = NULL, weak_password = NULL, token = NULL, is_admin = 0
+                       WHERE uid = {?}", $uid);
         XDB::execute("DELETE virtual.* FROM virtual INNER JOIN virtual_redirect AS r USING(vid) WHERE redirect = {?}",
                      $alias.'@'.$globals->mail->domain);
         XDB::execute("DELETE virtual.* FROM virtual INNER JOIN virtual_redirect AS r USING(vid) WHERE redirect = {?}",
                      $alias.'@'.$globals->mail->domain2);
     } else {
-        XDB::execute("UPDATE auth_user_md5   SET password='',smtppass='' WHERE user_id={?}", $uid);
-        XDB::execute("UPDATE auth_user_quick SET watch_flags='' WHERE user_id={?}", $uid);
+        XDB::execute("UPDATE  accounts
+                         SET  password = NULL, weak_password = NULL, token = NULL
+                       WHERE  uid = {?}", $uid);
     }
 
     XDB::execute("DELETE FROM virtual_redirect WHERE redirect = {?}", $alias.'@'.$globals->mail->domain);
     XDB::execute("DELETE FROM virtual_redirect WHERE redirect = {?}", $alias.'@'.$globals->mail->domain2);
 
+    /* TODO: handle both account and profile
     foreach ($tables_to_clear as $key=>&$tables) {
         foreach ($tables as $table) {
             XDB::execute("DELETE FROM $table WHERE $key={?}", $uid);
         }
-    }
+    }*/
 
-    $mmlist = new MMList(S::v('uid'), S::v('password'));
+    $mmlist = new MMList($user);
     $mmlist->kill($alias, $really_del);
 
     // Deactivates, when available, the Google Apps account of the user.
@@ -83,607 +84,6 @@ function user_clear_all_subs($user_id, $really_del=true)
 }
 
 // }}}
-// {{{ function has_user_right()
-function has_user_right($pub, $view = 'private') {
-    if ($pub == $view) return true;
-    // all infos available for private
-    if ($view == 'private') return true;
-    // public infos available for all
-    if ($pub == 'public') return true;
-    // here we have view = ax or public, and pub = ax or private, and pub != view
-    return false;
-}
-// }}}
-// {{{ function get_not_registered_user()
-
-function get_not_registered_user($login, $iterator = false)
-{
-    global $globals;
-    @list($login, $domain) = explode('@', $login);
-    if ($domain && $domain != $globals->mail->domain && $domain != $globals->mail->domain2) {
-        return null;
-    }
-    @list($prenom, $nom, $promo) = explode('.', $login);
-    $where = 'REPLACE(REPLACE(REPLACE(nom, " ", ""), "-", ""), "\'", "")
-              LIKE CONCAT("%", REPLACE(REPLACE(REPLACE({?}, " ", ""), "-", ""), "\'", ""), "%")
-              AND  REPLACE(REPLACE(REPLACE(prenom, " ", ""), "-", ""), "\'", "")
-              LIKE CONCAT("%", REPLACE(REPLACE(REPLACE({?}, " ", ""), "-", ""), "\'", ""), "%")';
-    if ($promo) {
-        if (preg_match('/^[0-9]{2}$/', $promo)) {
-            $where .= 'AND MOD(promo, 100) = {?}';
-        } elseif (preg_match('/^[0-9]{4}$/', $promo)) {
-            $where .= 'AND promo = {?}';
-        }
-    }
-    $sql = "SELECT  user_id, nom, prenom, promo
-              FROM  auth_user_md5
-             WHERE  $where AND perms = 'pending'
-          ORDER BY  promo, nom, prenom";
-    if ($iterator) {
-        return XDB::iterator($sql, $nom, $prenom, $promo);
-    } else {
-        $res = XDB::query($sql, $nom, $prenom, $promo);
-        return $res->fetchAllAssoc();
-    }
-}
-
-// }}}
-// {{{ function get_user_details_pro()
-
-function get_user_details_pro($uid, $view = 'private')
-{
-    $sql  = "SELECT  en.name AS entreprise, s.name as secteur, f.fonction_fr as fonction,
-                     j.description AS poste, gp.pays AS countrytxt, gr.name AS region,
-                     j.id AS entrid, j.pub, j.email, j.email_pub, j.url AS w_web, en.url AS web,
-                     e.adr1, e.adr2, e.adr3, e.postcode, e.city, e.adr_pub
-               FROM  profile_job                   AS j
-          LEFT JOIN  entreprises                   AS e  ON (e.entrid = j.id AND e.uid = j.uid)
-          LEFT JOIN  profile_job_enum              AS en ON (j.jobid = en.id)
-          LEFT JOIN  profile_job_subsubsector_enum AS s  ON (j.subsubsectorid = s.id)
-          LEFT JOIN  fonctions_def                 AS f  ON (j.functionid = f.id)
-          LEFT JOIN  geoloc_pays                   AS gp ON (gp.a2 = e.country)
-          LEFT JOIN  geoloc_region                 AS gr ON (gr.a2 = e.country AND gr.region = e.region)
-              WHERE  j.uid = {?}
-           ORDER BY  j.id";
-    $res  = XDB::query($sql, $uid);
-    $all_pro = $res->fetchAllAssoc();
-    foreach ($all_pro as $i => $pro) {
-        if (!has_user_right($pro['pub'], $view))
-            unset($all_pro[$i]);
-        else {
-            if (!has_user_right($pro['adr_pub'], $view)) {
-                if ($pro['adr1'] == '' &&
-                    $pro['adr2'] == '' &&
-                    $pro['adr3'] == '' &&
-                    $pro['postcode'] == '' &&
-                    $pro['city'] == '' &&
-                    $pro['countrytxt'] == '' &&
-                    $pro['region'] == '') {
-                    $all_pro[$i]['adr_pub'] = $view;
-                } else {
-                    $all_pro[$i]['adr1'] = '';
-                    $all_pro[$i]['adr2'] = '';
-                    $all_pro[$i]['adr3'] = '';
-                    $all_pro[$i]['postcode'] = '';
-                    $all_pro[$i]['city'] = '';
-                    $all_pro[$i]['countrytxt'] = '';
-                    $all_pro[$i]['region'] = '';
-                }
-            }
-            $sql = "SELECT  pub AS tel_pub, tel_type, display_tel AS tel, comment
-                      FROM  profile_phones AS t
-                     WHERE  uid = {?} AND link_type = 'pro' AND link_id = {?}
-                  ORDER BY  link_id, tel_type DESC, tel_id";
-            $restel = XDB::iterator($sql, $uid, $pro['entrid']);
-            while ($nexttel = $restel->next()) {
-                if (has_user_right($nexttel['tel_pub'], $view)) {
-                    if (!isset($all_pro[$i]['tels'])) {
-                        $all_pro[$i]['tels'] = array($nexttel);
-                    } else {
-                        $all_pro[$i]['tels'][] = $nexttel;
-                    }
-                }
-            }
-            if (!has_user_right($pro['email_pub'], $view)) {
-                if ($pro['email'] == '')
-                    $all_pro[$i]['email_pub'] = $view;
-                else
-                    $all_pro[$i]['email'] = '';
-            }
-            if ($all_pro[$i]['adr1'] == '' &&
-                $all_pro[$i]['adr2'] == '' &&
-                $all_pro[$i]['adr3'] == '' &&
-                $all_pro[$i]['postcode'] == '' &&
-                $all_pro[$i]['city'] == '' &&
-                $all_pro[$i]['countrytxt'] == '' &&
-                $all_pro[$i]['region'] == '' &&
-                $all_pro[$i]['entreprise'] == '' &&
-                $all_pro[$i]['fonction'] == '' &&
-                $all_pro[$i]['secteur'] == '' &&
-                $all_pro[$i]['poste'] == '' &&
-                (!isset($all_pro[$i]['tels'])) &&
-                $all_pro[$i]['email'] == '')
-                unset($all_pro[$i]);
-        }
-    }
-    if (!count($all_pro)) return false;
-    return $all_pro;
-}
-
-// }}}
-// {{{ function get_user_details_adr()
-
-function get_user_details_adr($uid, $view = 'private') {
-    $sql  = "SELECT  a.adrid, a.adr1,a.adr2,a.adr3,a.postcode,a.city,
-                     gp.pays AS countrytxt,a.region, a.regiontxt,
-                     FIND_IN_SET('active', a.statut) AS active, a.adrid,
-                     FIND_IN_SET('res-secondaire', a.statut) AS secondaire,
-                     FIND_IN_SET('courrier', a.statut) AS courier,
-                     a.pub, gp.display, a.comment
-               FROM  adresses AS a
-          LEFT JOIN  geoloc_pays AS gp ON (gp.a2=a.country)
-              WHERE  uid= {?} AND NOT FIND_IN_SET('pro',a.statut)
-           ORDER BY  NOT FIND_IN_SET('active',a.statut), FIND_IN_SET('temporaire',a.statut), FIND_IN_SET('res-secondaire',a.statut)";
-    $res  = XDB::query($sql, $uid);
-    $all_adr = $res->fetchAllAssoc();
-    $adrid_index = array();
-    foreach ($all_adr as $i => $adr) {
-        if (!has_user_right($adr['pub'], $view))
-            unset($all_adr[$i]);
-        else
-            $adrid_index[$adr['adrid']] = $i;
-    }
-
-    $sql = "SELECT  link_id AS adrid, pub AS tel_pub, tel_type, display_tel AS tel, tel_id AS telid, comment
-              FROM  profile_phones AS t
-             WHERE  uid = {?} AND link_type = 'address'
-          ORDER BY  link_id, tel_type DESC, tel_id";
-    $restel = XDB::iterator($sql, $uid);
-    while ($nexttel = $restel->next()) {
-        if (has_user_right($nexttel['tel_pub'], $view)) {
-            $adrid = $nexttel['adrid'];
-            unset($nexttel['adrid']);
-            if (isset($adrid_index[$adrid])) {
-                if (!isset($all_adr[$adrid_index[$adrid]]['tels']))
-                    $all_adr[$adrid_index[$adrid]]['tels'] = array($nexttel);
-                else
-                    $all_adr[$adrid_index[$adrid]]['tels'][] = $nexttel;
-            }
-        }
-    }
-    return $all_adr;
-}
-
-// }}}
-// {{{ function get_user_details()
-
-function &get_user_details($login, $from_uid = '', $view = 'private')
-{
-    $reqsql = "SELECT  u.user_id, d.promo, u.prenom, u.nom, u.nom_usage, u.date, u.cv,
-                       u.perms IN ('admin','user','disabled') AS inscrit,  FIND_IN_SET('femme', u.flags) AS sexe, u.deces != 0 AS dcd, u.deces,
-                       q.profile_nick AS nickname, q.profile_from_ax, q.profile_freetext AS freetext,
-                       q.profile_freetext_pub AS freetext_pub,
-                       q.profile_medals_pub AS medals_pub, co.corps_pub AS corps_pub,
-                       IF(gp1.nat='',gp1.pays,gp1.nat) AS nationalite, gp1.a2 AS iso3166_1,
-                       IF(gp2.nat='',gp2.pays,gp2.nat) AS nationalite2, gp2.a2 AS iso3166_2,
-                       IF(gp3.nat='',gp3.pays,gp3.nat) AS nationalite3, gp3.a2 AS iso3166_3,
-                       a.alias AS forlife, a2.alias AS bestalias,
-                       c.uid IS NOT NULL AS is_contact,
-                       s.text AS section, p.x, p.y, p.pub AS photo_pub,
-                       u.matricule_ax,
-                       m.expertise != '' AS is_referent,
-                       (COUNT(e.email) > 0 OR FIND_IN_SET('googleapps', u.mail_storage) > 0) AS actif,
-                       d.public_name, d.private_name
-                 FROM  auth_user_md5         AS u
-           INNER JOIN  auth_user_quick       AS q   USING(user_id)
-           INNER JOIN  aliases               AS a   ON (u.user_id = a.id AND a.type = 'a_vie')
-           INNER JOIN  aliases               AS a2  ON (u.user_id = a2.id AND FIND_IN_SET('bestalias', a2.flags))
-            LEFT JOIN  contacts              AS c   ON (c.uid = {?} and c.contact = u.user_id)
-            LEFT JOIN  profile_corps         AS co  ON (co.uid = u.user_id)
-            LEFT JOIN  geoloc_pays           AS gp1 ON (gp1.a2 = u.nationalite)
-            LEFT JOIN  geoloc_pays           AS gp2 ON (gp2.a2 = u.nationalite2)
-            LEFT JOIN  geoloc_pays           AS gp3 ON (gp3.a2 = u.nationalite3)
-           INNER JOIN  sections              AS s   ON (s.id  = u.section)
-            LEFT JOIN  photo                 AS p   ON (p.uid = u.user_id)
-            LEFT JOIN  profile_mentor        AS m   ON (m.uid = u.user_id)
-            LEFT JOIN  emails                AS e   ON (e.uid = u.user_id AND e.flags='active')
-           INNER JOIN  profile_display       AS d   ON (d.pid = u.user_id)
-                WHERE  a.alias = {?}
-             GROUP BY  u.user_id";
-    $res  = XDB::query($reqsql, $from_uid, $login);
-    $user = $res->fetchOneAssoc();
-    $uid  = $user['user_id'];
-    // hide orange status, cv, nickname, section
-    if (!has_user_right('private', $view)) {
-        $user['cv'] = '';
-        $user['nickname'] = '';
-        $user['section'] = '';
-    }
-
-    // hide freetext
-    if (!has_user_right($user['freetext_pub'], $view)) {
-        if ($user['freetext'] == '')
-            $user['freetext_pub'] = $view;
-        else
-            $user['freetext'] = '';
-    }
-
-    $sql = "SELECT  pub AS tel_pub, tel_type, display_tel AS tel, comment
-              FROM  profile_phones AS t
-             WHERE  uid = {?} AND link_type = 'user'
-          ORDER BY  tel_type DESC, tel_id";
-    $restel = XDB::iterator($sql, $uid);
-    while ($nexttel = $restel->next()) {
-        if (has_user_right($nexttel['tel_pub'], $view)) {
-            if (!isset($user['tels'])) {
-                $user['tels'] = array($nexttel);
-            } else {
-                $user['tels'][] = $nexttel;
-            }
-        }
-    }
-
-    $user['adr_pro'] = get_user_details_pro($uid, $view);
-    $user['adr']     = get_user_details_adr($uid, $view);
-
-    if (has_user_right('private', $view)) {
-        $sql  = "SELECT  text
-                   FROM  binets_ins
-              LEFT JOIN  binets_def ON binets_ins.binet_id = binets_def.id
-                  WHERE  user_id = {?}";
-        $res  = XDB::query($sql, $uid);
-        $user['binets']      = $res->fetchColumn();
-        $user['binets_join'] = join(', ', $user['binets']);
-
-        $res  = XDB::iterRow("SELECT  a.diminutif, a.nom, a.site
-                                FROM  groupex.asso    AS a
-                           LEFT JOIN  groupex.membres AS m ON (m.asso_id = a.id)
-                               WHERE  m.uid = {?} AND (a.cat = 'GroupesX' OR a.cat = 'Institutions')
-                                      AND pub = 'public'", $uid);
-        $user['gpxs'] = Array();
-        $user['gpxs_name'] = Array();
-        while (list($gxd, $gxt, $gxu) = $res->next()) {
-            if (!$gxu) {
-                $gxu = 'http://www.polytechnique.net/' . $gxd;
-            }
-            $user['gpxs'][] = '<span title="' . pl_entities($gxt) . "\"><a href=\"$gxu\">$gxd</a></span>";
-            $user['gpxs_name'][] = $gxt;
-        }
-        $user['gpxs_join'] = join(', ', $user['gpxs']);
-    }
-
-    $res = XDB::iterRow("SELECT  en.name AS name, en.url AS url, d.degree AS degree,
-                                 ed.grad_year AS grad_year, f.field AS field, ed.program AS program
-                           FROM  profile_education AS ed
-                      LEFT JOIN  profile_education_enum        AS en ON (en.id = ed.eduid)
-                      LEFT JOIN  profile_education_degree_enum AS d  ON (d.id  = ed.degreeid)
-                      LEFT JOIN  profile_education_field_enum  AS f  ON (f.id  = ed.fieldid)
-                          WHERE  uid = {?} AND NOT FIND_IN_SET('primary', flags)
-                       ORDER BY  ed.grad_year", $uid);
-
-    if (list($name, $url, $degree, $grad_year, $field, $program) = $res->next()) {
-        require_once('education.func.inc.php');
-        $user['education'][] = education_fmt($name, $url, $degree, $grad_year, $field, $program, $user['sexe'], true);
-    }
-    while (list($name, $url, $degree, $grad_year, $field, $program) = $res->next()) {
-        $user['education'][] = education_fmt($name, $url, $degree, $grad_year, $field, $program, $user['sexe'], true);
-    }
-
-    if (has_user_right($user['corps_pub'], $view)) {
-        $res = XDB::query("SELECT  e1.name AS original, e2.name AS current, r.name AS rank
-                             FROM  profile_corps           AS c
-                        LEFT JOIN  profile_corps_enum      AS e1 ON (c.original_corpsid = e1.id)
-                        LEFT JOIN  profile_corps_enum      AS e2 ON (c.current_corpsid = e2.id)
-                        LEFT JOIN  profile_corps_rank_enum AS r  ON (c.rankid = r.id)
-                            WHERE  c.uid = {?} AND c.original_corpsid != 1", $uid);
-        if ($res = $res->fetchOneRow()) {
-            list($original, $current, $rank) = $res;
-            $user['corps'] = "Corps d'origine : " . $original . ", corps actuel : " . $current . ", grade : " . $rank;
-        }
-    }
-
-    if (has_user_right($user['medals_pub'], $view)) {
-        $res = XDB::iterator("SELECT  m.id, m.text AS medal, m.type, s.gid, g.text AS grade
-                                FROM  profile_medals_sub    AS s
-                          INNER JOIN  profile_medals        AS m ON ( s.mid = m.id )
-                           LEFT JOIN  profile_medals_grades AS g ON ( s.mid = g.mid AND s.gid = g.gid )
-                               WHERE  s.uid = {?}", $uid);
-        $user['medals'] = Array();
-        while ($tmp = $res->next()) {
-            $user['medals'][] = $tmp;
-        }
-    }
-
-    $user['networking'] = Array();
-    $res = XDB::iterator("SELECT  n.address, n.pub, m.network_type AS type, m.name, m.filter, m.link
-                            FROM  profile_networking AS n
-                      INNER JOIN  profile_networking_enum AS m ON (n.network_type = m.network_type)
-                           WHERE  n.uid = {?}", $uid);
-    while($network = $res->next())
-    {
-        if (has_user_right($network['pub'], $view)) {
-            $network['link'] = str_replace('%s', $network['address'], $network['link']);
-            $user['networking'][] = $network;
-        }
-    }
-
-    return $user;
-}
-// }}}
-// {{{ function add_user_address()
-function add_user_address($uid, $adrid, $adr) {
-    XDB::execute(
-        "INSERT INTO adresses (`uid`, `adrid`, `adr1`, `adr2`, `adr3`, `postcode`, `city`, `country`, `datemaj`, `pub`) (
-        SELECT u.user_id, {?}, {?}, {?}, {?}, {?}, {?}, gp.a2, NOW(), {?}
-            FROM auth_user_md5 AS u
-            LEFT JOIN geoloc_pays AS gp ON (gp.pays LIKE {?} OR gp.country LIKE {?} OR gp.a2 LIKE {?})
-            WHERE u.user_id = {?}
-            LIMIT 1)",
-        $adrid, $adr['adr1'], $adr['adr2'], $adr['adr3'], $adr['postcode'], $adr['city'], $adr['pub'], $adr['countrytxt'], $adr['countrytxt'], $adr['countrytxt'], $uid);
-    if (isset($adr['tels']) && is_array($adr['tels'])) {
-        $telid = 0;
-        foreach ($adr['tels'] as $tel) if ($tel['tel']) {
-            add_user_tel($uid, 'address', $adrid, $telid, $tel);
-            $telid ++;
-        }
-    }
-}
-// }}}
-// {{{ function update_user_address()
-function update_user_address($uid, $adrid, $adr) {
-    // update address
-    XDB::execute(
-        "UPDATE adresses AS a LEFT JOIN geoloc_pays AS gp ON (gp.pays = {?})
-        SET `adr1` = {?}, `adr2` = {?}, `adr3` = {?},
-        `postcode` = {?}, `city` = {?}, a.`country` = gp.a2, `datemaj` = NOW(), `pub` = {?}
-        WHERE adrid = {?} AND uid = {?}",
-        $adr['country_txt'],
-        $adr['adr1'], $adr['adr2'], $adr['adr3'],
-        $adr['postcode'], $adr['city'], $adr['pub'], $adrid, $uid);
-    if (isset($adr['tels']) && is_array($adr['tels'])) {
-        $res = XDB::query("SELECT tel_id FROM profile_phones WHERE uid = {?} AND link_type = 'address' AND link_id = {?} ORDER BY tel_id", $uid, $adrid);
-        $telids = $res->fetchColumn();
-        foreach ($adr['tels'] as $tel) {
-            if (isset($tel['telid']) && isset($tel['remove']) && $tel['remove']) {
-                remove_user_tel($uid, 'address', $adrid, $tel['telid']);
-                if (isset($telids[$tel['telid']])) unset($telids[$tel['telid']]);
-            } else if (isset($tel['telid'])) {
-                update_user_tel($uid, 'address', $adrid, $tel['telid'], $tel);
-            } else {
-                for ($telid = 0; isset($telids[$telid]) && ($telids[$telid] == $telid); $telid++);
-                add_user_tel($uid, 'address', $adrid, $telid, $tel);
-            }
-        }
-    }
-}
-// }}}
-// {{{ function remove_user_address()
-function remove_user_address($uid, $adrid) {
-    XDB::execute("DELETE FROM adresses WHERE adrid = {?} AND uid = {?}", $adrid, $uid);
-    XDB::execute("DELETE FROM profile_phones WHERE link_id = {?} AND uid = {?} AND link_type = 'address'", $adrid, $uid);
-}
-// }}}
-// {{{ function add_user_tel()
-function add_user_tel($uid, $link_type, $link_id, $telid, $tel) {
-    require('profil.func.inc.php');
-    $fmt_phone  = format_phone_number($tel['tel']);
-    $disp_phone = format_display_number($fmt_phone, $error);
-    XDB::execute("INSERT INTO profile_phones (uid, link_type, link_id, tel_id, tel_type, search_tel, display_tel, pub)
-                       VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})",
-                 $uid, $link_type, $link_id, $telid, $tel['tel_type'], $fmt_phone, $disp_phone, $tel['tel_pub']);
-}
-// }}}
-// {{{ function update_user_tel()
-function update_user_tel($uid, $link_type, $link_id, $telid, $tel) {
-    require('profil.func.inc.php');
-    $fmt_phone  = format_phone_number($tel['tel']);
-    $disp_phone = format_display_number($fmt_phone, $error);
-    XDB::execute("UPDATE profile_phones SET search_tel = {?}, display_tel = {?}, tel_type = {?}, pub = {?}
-                   WHERE link_type = {?} AND tel_id = {?} AND link_id = {?} AND uid = {?}",
-                 $fmt_phone, $disp_phone, $tel['tel_type'], $tel['tel_pub'],
-                 $link_type, $telid, $link_id, $uid);
-}
-// }}}
-// {{{ function remove_user_tel()
-function remove_user_tel($uid, $link_type, $link_id, $telid) {
-    XDB::execute("DELETE FROM profile_phones WHERE tel_id = {?} AND link_id = {?} AND uid = {?} AND link_type = {?}",
-                 $telid, $link_id, $uid, $link_type);
-}
-// }}}
-// {{{ function add_user_pro()
-function add_user_pro($uid, $entrid, $pro) {
-    XDB::execute(
-        "INSERT INTO entreprises (`uid`, `entrid`, `entreprise`, `poste`, `secteur`, `ss_secteur`, `fonction`,
-            `adr1`, `adr2`, `adr3`, `postcode`, `city`, `country`, `region`, `email`, `web`, `pub`, `adr_pub`, `email_pub`)
-        SELECT u.user_id, {?}, {?}, {?}, s.id, ss.id, f.id,
-        {?}, {?}, {?}, {?}, {?}, gp.a2, gr.region, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}
-        FROM auth_user_md5 AS u
-            LEFT JOIN  emploi_secteur AS s ON(s.label LIKE {?})
-            LEFT JOIN  emploi_ss_secteur AS ss ON(s.id = ss.secteur AND ss.label LIKE {?})
-            LEFT JOIN  fonctions_def AS f ON(f.fonction_fr LIKE {?} OR f.fonction_en LIKE {?})
-            LEFT JOIN  geoloc_pays AS gp ON (gp.country LIKE {?} OR gp.pays LIKE {?})
-            LEFT JOIN  geoloc_region AS gr ON (gr.a2 = gp.a2 AND gr.name LIKE {?})
-        WHERE u.user_id = {?}
-        LIMIT 1",
-        $entrid, $pro['entreprise'], $pro['poste'],
-        $pro['adr1'], $pro['adr2'], $pro['adr3'], $pro['postcode'], $pro['city'], $pro['email'], $pro['web'], $pro['pub'], $pro['adr_pub'], $pro['email_pub'],
-        $pro['secteur'], $pro['sous_secteur'], $pro['fonction'], $pro['fonction'],
-        $pro['countrytxt'], $pro['countrytxt'], $pro['region'],
-        $uid);
-    if (isset($pro['tels']) && is_array($pro['tels'])) {
-        $telid = 0;
-        foreach ($pro['tels'] as $tel) {
-            if ($pro['tel']) {
-                add_user_tel($uid, 'pro', $entrid, $telid, $tel);
-                $telid ++;
-            }
-        }
-    }
-}
-// }}}
-// {{{ function update_user_pro()
-function update_user_pro($uid, $entrid, $pro) {
-    $join = "";
-    $set = "";
-    $args_join = array();
-    $args_set = array();
-
-    $join .= "LEFT JOIN  emploi_secteur AS s ON(s.label LIKE {?})
-            LEFT JOIN  emploi_ss_secteur AS ss ON(s.id = ss.secteur AND ss.label LIKE {?})
-            LEFT JOIN  fonctions_def AS f ON(f.fonction_fr LIKE {?} OR f.fonction_en LIKE {?})";
-    $args_join[] = $pro['secteur'];
-    $args_join[] = $pro['sous_secteur'];
-    $args_join[] = $pro['fonction'];
-    $args_join[] = $pro['fonction'];
-    $set .= ", e.`entreprise` = {?}, e.`secteur` = s.id, e.`ss_secteur` = ss.id, e.`fonction` = f.id, e.`poste`= {?}, e.`web` = {?}, e.`pub` = {?}";
-    $args_set[] = $pro['entreprise'];
-    $args_set[] = $pro['poste'];
-    $args_set[] = $pro['web'];
-    $args_set[] = $pro['pub'];
-
-    if (isset($pro['adr1'])) {
-        $join .= "LEFT JOIN  geoloc_pays AS gp ON (gp.country LIKE {?} OR gp.pays LIKE {?})
-                LEFT JOIN  geoloc_region AS gr ON (gr.a2 = gp.a2 AND gr.name LIKE {?})";
-        $args_join[] = $pro['countrytxt'];
-        $args_join[] = $pro['countrytxt'];
-        $args_join[] = $pro['region'];
-        $set .= ", e.`adr1` = {?}, e.`adr2` = {?}, e.`adr3` = {?}, e.`postcode` = {?}, e.`city` = {?}, e.`country` = gp.a2, e.`region` = gr.region, e.`adr_pub` = {?}";
-        $args_set[] = $pro['adr1'];
-        $args_set[] = $pro['adr2'];
-        $args_set[] = $pro['adr3'];
-        $args_set[] = $pro['postcode'];
-        $args_set[] = $pro['city'];
-        $args_set[] = $pro['adr_pub'];
-    }
-
-    if (isset($pro['email'])) {
-        $set .= ", e.`email` = {?}, e.`email_pub` = {?}";
-        $args_set[] = $pro['email'];
-        $args_set[] = $pro['email_pub'];
-    }
-    $query = "UPDATE entreprises AS e ".$join." SET ".substr($set,1)." WHERE e.uid = {?} AND e.entrid = {?}";
-    $args_where = array($uid, $entrid);
-    $args = array_merge(array($query), $args_join, $args_set, $args_where);
-    call_user_func_array(array('XDB', 'execute'), $args);
-
-
-    if (isset($pro['tels']) && is_array($pro['tels'])) {
-        $res = XDB::query("SELECT tel_id FROM profile_phones WHERE uid = {?} AND link_type = 'pro' AND link_id = {?} ORDER BY tel_id", $uid, $entrid);
-        $telids = $res->fetchColumn();
-        foreach ($pro['tels'] as $tel) {
-            if (isset($tel['telid']) && isset($tel['remove']) && $tel['remove']) {
-                remove_user_tel($uid, 'pro', $entrid, $tel['telid']);
-                if (isset($telids[$tel['telid']])) unset($telids[$tel['telid']]);
-            } else if (isset($tel['telid'])) {
-                update_user_tel($uid, 'pro', $entrid, $tel['telid'], $tel);
-            } else {
-                for ($telid = 0; isset($telids[$telid]) && ($telids[$telid] == $telid); $telid++);
-                add_user_tel($uid, 'pro', $entrid, $telid, $tel);
-            }
-        }
-    }
-}
-// }}}
-// {{{ function remove_user_pro()
-function remove_user_pro($uid, $entrid) {
-    XDB::execute("DELETE FROM entreprises WHERE entrid = {?} AND uid = {?}", $entrid, $uid);
-    XDB::execute("DELETE FROM profile_phones WHERE link_id = {?} AND uid = {?} AND link_type = 'pro'", $entrid, $uid);
-}
-// }}}
-// {{{ function set_user_details_addresses()
-function set_user_details_addresses($uid, $adrs) {
-    $req = XDB::query('SELECT MAX(adrid) + 1
-                         FROM adresses
-                        WHERE uid = {?}', $uid);
-    $adrid = $req->fetchOneCell();
-    if (is_null($adrid)) {
-        $adrid = 0;
-    }
-    foreach ($adrs as $adr) {
-        if (!@$adr['remove']) {
-            add_user_address($uid, $adrid, $adr);
-            ++$adrid;
-        }
-    }
-    require_once 'geoloc.inc.php';
-    localize_addresses($uid);
-}
-// }}}
-// {{{ function set_user_details_pro()
-
-function set_user_details_pro($uid, $pros)
-{
-    $req = XDB::query('SELECT MAX(entrid) + 1
-                         FROM entreprises
-                        WHERE uid = {?}', $uid);
-    $entrid = $req->fetchOneCell();
-    if (is_null($entrid)) {
-        $entrid = 0;
-    }
-    foreach ($pros as $pro) {
-        if (!@$pro['remove']) {
-            add_user_pro($uid, $entrid, $pro);
-            ++$entrid;
-        }
-    }
-}
-
-// }}}
-// {{{ function set_user_details()
-function set_user_details($uid, $details) {
-    if (isset($details['nom_usage'])) {
-        XDB::execute("UPDATE auth_user_md5 SET nom_usage = {?} WHERE user_id = {?}", strtoupper($details['nom_usage']), $uid);
-    }
-    if (isset($details['nationalite'])) {
-        XDB::execute(
-            "UPDATE auth_user_md5 AS u
-                INNER JOIN geoloc_pays     AS gp
-            SET u.nationalite = gp.a2
-            WHERE (gp.a2 = {?} OR gp.nat = {?})
-                AND u.user_id = {?}",  $details['nationalite'], $details['nationalite'], $uid);
-    }
-    if (isset($details['adr']) && is_array($details['adr']))
-        set_user_details_addresses($uid, $details['adr']);
-    if (isset($details['adr_pro']) && is_array($details['adr_pro']))
-        set_user_details_pro($uid, $details['adr_pro']);
-    if (isset($details['binets']) && is_array($details['binets'])) {
-        XDB::execute("DELETE FROM binets_ins WHERE user_id = {?}", $uid);
-        foreach ($details['binets'] as $binet)
-            XDB::execute(
-            "INSERT INTO binets_ins (`user_id`, `binet_id`)
-                SELECT {?}, id FROM binets_def WHERE text = {?} LIMIT 1",
-                $uid, $binet);
-    }
-    if (isset($details['gpxs']) && is_array($details['gpxs'])) {
-        XDB::execute("DELETE FROM groupesx_ins WHERE user_id = {?}", $uid);
-        foreach ($details['gpxs'] as $groupex) {
-            if (preg_match('/<a href="[^"]*">([^<]+)</a>/u', $groupex, $a)) $groupex = $a[1];
-            XDB::execute(
-            "INSERT INTO groupesx_ins (`user_id`, `binet_id`)
-                SELECT {?}, id FROM groupesx_def WHERE text = {?} LIMIT 1",
-                $uid, $groupex);
-        }
-    }
-    if (isset($details['tels']) && is_array($details['tels'])) {
-        $res = XDB::query("SELECT tel_id FROM profile_phones WHERE uid = {?} AND link_type = 'user' ORDER BY tel_id", $uid);
-        $telids = $res->fetchColumn();
-        foreach ($details['tels'] as $tel) {
-            if (isset($tel['telid']) && isset($tel['remove']) && $tel['remove']) {
-                remove_user_tel($uid, 'user', 0, $tel['telid']);
-                if (isset($telids[$tel['telid']])) unset($telids[$tel['telid']]);
-            } else if (isset($tel['telid'])) {
-                update_user_tel($uid, 'user', 0, $tel['telid'], $tel);
-            } else {
-                for ($telid = 0; isset($telids[$telid]) && ($telids[$telid] == $telid); $telid++);
-                add_user_tel($uid, 'user', 0, $telid, $tel);
-            }
-        }
-    }
-
-    // education
-    // medals
-}
-// }}}
 // {{{ function _user_reindex
 
 function _user_reindex($uid, $keys)
@@ -723,27 +123,6 @@ function user_reindex($uid) {
 }
 
 // }}}
-// {{{ function set_new_usage()
-
-function set_new_usage($uid, $usage, $alias=false)
-{
-    XDB::execute("UPDATE auth_user_md5 set nom_usage={?} WHERE user_id={?}",$usage ,$uid);
-    XDB::execute("DELETE FROM aliases WHERE FIND_IN_SET('usage',flags) AND id={?}", $uid);
-    if ($alias && $usage) {
-        XDB::execute("UPDATE aliases SET flags=flags & 255-1 WHERE id={?}", $uid);
-        XDB::execute("INSERT INTO aliases VALUES({?}, 'alias', 'usage,bestalias', {?}, null)",
-            $alias, $uid);
-    }
-    $r = XDB::query("SELECT alias FROM aliases WHERE FIND_IN_SET('bestalias', flags) AND id = {?}", $uid);
-    if ($r->numRows() == "") {
-        XDB::execute("UPDATE aliases SET flags = 1 | flags WHERE id = {?} LIMIT 1", $uid);
-        $r = XDB::query("SELECT alias FROM aliases WHERE FIND_IN_SET('bestalias', flags) AND id = {?}", $uid);
-    }
-    user_reindex($uid);
-    return $r->fetchOneCell();
-}
-
-// }}}
 // {{{ function get_X_mat
 function get_X_mat($ourmat)
 {
index b824fc7..8c6040f 100644 (file)
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
  ***************************************************************************/
 
-require_once('user.func.inc.php');
-
-global $globals;
-
-@$globals->search->result_where_statement = "
-    LEFT JOIN  profile_education          AS edu ON (u.user_id = edu.uid)
-    LEFT JOIN  profile_education_enum     AS ede ON (ede.id = edu.eduid)
-    LEFT JOIN  profile_job                AS j   ON (j.id = 0 AND j.uid = u.user_id)
-    LEFT JOIN  profile_job_enum           AS je  ON (je.id = j.jobid)
-    LEFT JOIN  profile_job_sector_enum    AS es  ON (j.sectorid = es.id)
-    LEFT JOIN  fonctions_def              AS ef  ON (j.functionid = ef.id)
-    LEFT JOIN  geoloc_countries           AS n1  ON (u.nationalite = n1.iso_3166_1_a2)
-    LEFT JOIN  geoloc_countries           AS n2  ON (u.nationalite2 = n2.iso_3166_1_a2)
-    LEFT JOIN  geoloc_countries           AS n3  ON (u.nationalite2 = n3.iso_3166_1_a2)
-    LEFT JOIN  profile_addresses          AS adr ON (u.user_id = adr.pid
-                                                     AND FIND_IN_SET('current', adr.flags))
-    LEFT JOIN  geoloc_countries           AS gc  ON (adr.countryId = gc.iso_3166_1_a2)
-    LEFT JOIN  geoloc_administrativeareas AS gr  ON (adr.countryId = gr.country
-                                                     AND adr.administrativeAreaId = gr.id)
-    LEFT JOIN  emails                     AS em  ON (em.uid = u.user_id AND em.flags = 'active')";
-
 class UserSet extends PlSet
 {
-    public function __construct($joins = '', $where = '')
+    private $cond;
+
+    public function __construct($cond = null)
     {
-        global $globals;
-        parent::__construct('auth_user_md5 AS u',
-                            (!empty($GLOBALS['IS_XNET_SITE']) ?
-                                'INNER JOIN groupex.membres AS gxm ON (u.user_id = gxm.uid
-                                                                       AND gxm.asso_id = ' . $globals->asso('id') . ') ' : '')
-                           . 'LEFT JOIN auth_user_quick AS q USING (user_id)' . $joins,
-                            $where,
-                            'u.user_id');
+        $this->cond = new UFC_And();
+        if (!is_null($cond)) {
+            $this->cond->addChild($cond);
+        }
+    }
+
+    public function &get($fields, $joins, $where, $groupby, $order, $limitcount = null, $limitfrom = null)
+    {
+        $uf = new UserFilter($this->cond);
+        $users = $uf->getUsers($limitcount, $limitfrom);
+        $this->count = $uf->getTotalCount();
+        return $users;
     }
 }
 
@@ -171,93 +156,14 @@ class MinificheView extends MultipageView
         parent::__construct($set, $data, $params);
     }
 
-    public function fields()
-    {
-        global $globals;
-        return "u.user_id AS id, u.*, d.promo,
-                CONCAT(a.alias, '@{$globals->mail->domain}') AS bestemail,
-                u.perms != 'pending' AS inscrit,
-                u.perms != 'pending' AS wasinscrit,
-                u.deces != 0 AS dcd, u.deces, u.matricule_ax,
-                FIND_IN_SET('femme', u.flags) AS sexe,
-                je.name AS entreprise, je.url AS job_web, es.name AS sector, ef.fonction_fr AS fonction,
-                IF(n1.nat = '', n1.countryFR, n1.nat) AS nat1, n1.iso_3166_1_a2 AS iso3166_1,
-                IF(n2.nat = '', n2.countryFR, n2.nat) AS nat2, n2.iso_3166_1_a2 AS iso3166_2,
-                IF(n3.nat = '', n3.countryFR, n3.nat) AS nat3, n3.iso_3166_1_a2 AS iso3166_3,
-                IF(ede0.abbreviation = '', ede0.name, ede0.abbreviation) AS eduname0, ede0.url AS eduurl0,
-                IF(edd0.abbreviation = '', edd0.degree, edd0.abbreviation) AS edudegree0,
-                edu0.grad_year AS edugrad_year0, f0.field AS edufield0, edu0.program AS eduprogram0,
-                IF(ede1.abbreviation = '', ede1.name, ede1.abbreviation) AS eduname1, ede1.url AS eduurl1,
-                IF(edd1.abbreviation = '', edd1.degree, edd1.abbreviation) AS edudegree1,
-                edu1.grad_year AS edugrad_year1, f1.field AS edufield1, edu1.program AS eduprogram1,
-                IF(ede2.abbreviation = '', ede2.name, ede2.abbreviation) AS eduname2, ede2.url AS eduurl2,
-                IF(edd2.abbreviation = '', edd2.degree, edd2.abbreviation) AS edudegree2,
-                edu2.grad_year AS edugrad_year2, f2.field AS edufield2, edu2.program AS eduprogram2,
-                IF(ede3.abbreviation = '', ede3.name, ede3.abbreviation) AS eduname3, ede3.url AS eduurl3,
-                IF(edd3.abbreviation = '', edd3.degree, edd3.abbreviation) AS edudegree3,
-                edu3.grad_year AS edugrad_year3, f3.field AS edufield3, edu3.program AS eduprogram3,
-                "// adr.localityId, gr.name AS region
-              . "gc.iso_3166_1_a2, gc.countryFR AS countrytxt
-                (COUNT(em.email) > 0 OR FIND_IN_SET('googleapps', u.mail_storage) > 0) AS actif,
-                d.directory_name, d.sort_name" .
-                (S::logged() ? ", c.contact AS contact" : '');
-    }
-
-    public function joins()
+    public function bounds()
     {
-        return  "LEFT JOIN  aliases                       AS a    ON (u.user_id = a.id AND FIND_IN_SET('bestalias', a.flags))
-                 LEFT JOIN  search_name                   AS n    ON (u.user_id = n.uid)
-                 LEFT JOIN  profile_job                   AS j    ON (j.uid = u.user_id".(S::logged() ? "" : " AND j.pub = 'public'").")
-                 LEFT JOIN  profile_job_enum              AS je   ON (je.id = j.jobid)
-                 LEFT JOIN  profile_job_sector_enum       AS es   ON (j.sectorid = es.id)
-                 LEFT JOIN  fonctions_def                 AS ef   ON (j.functionid = ef.id)
-                 LEFT JOIN  geoloc_countries              AS n1   ON (u.nationalite = n1.iso_3166_1_a2)
-                 LEFT JOIN  geoloc_countries              AS n2   ON (u.nationalite2 = n2.iso_3166_1_a2)
-                 LEFT JOIN  geoloc_countries              AS n3   ON (u.nationalite3 = n3.iso_3166_1_a2)
-                 LEFT JOIN  profile_education             AS edu0 ON (u.user_id = edu0.uid AND edu0.id = 0)
-                 LEFT JOIN  profile_education_enum        AS ede0 ON (ede0.id = edu0.eduid)
-                 LEFT JOIN  profile_education_degree_enum AS edd0 ON (edd0.id = edu0.degreeid)
-                 LEFT JOIN  profile_education_field_enum  AS f0   ON (f0.id = edu0.fieldid)
-                 LEFT JOIN  profile_education             AS edu1 ON (u.user_id = edu1.uid AND edu1.id = 1)
-                 LEFT JOIN  profile_education_enum        AS ede1 ON (ede1.id = edu1.eduid)
-                 LEFT JOIN  profile_education_degree_enum AS edd1 ON (edd1.id = edu1.degreeid)
-                 LEFT JOIN  profile_education_field_enum  AS f1   ON (f1.id = edu1.fieldid)
-                 LEFT JOIN  profile_education             AS edu2 ON (u.user_id = edu2.uid AND edu2.id = 2)
-                 LEFT JOIN  profile_education_enum        AS ede2 ON (ede2.id = edu2.eduid)
-                 LEFT JOIN  profile_education_degree_enum AS edd2 ON (edd2.id = edu2.degreeid)
-                 LEFT JOIN  profile_education_field_enum  AS f2   ON (f2.id = edu2.fieldid)
-                 LEFT JOIN  profile_education             AS edu3 ON (u.user_id = edu3.uid AND edu3.id = 3)
-                 LEFT JOIN  profile_education_enum        AS ede3 ON (ede3.id = edu3.eduid)
-                 LEFT JOIN  profile_education_degree_enum AS edd3 ON (edd3.id = edu3.degreeid)
-                 LEFT JOIN  profile_education_field_enum  AS f3   ON (f3.id = edu3.fieldid)
-                 LEFT JOIN  profile_addresses             AS adr  ON (u.user_id = adr.pid
-                                                                      AND FIND_IN_SET('current', adr.flags)"
-                                                                      . (S::logged() ? "" :
-                                                                         "AND adr.pub = 'public'") . ")
-                 LEFT JOIN  geoloc_countries              AS gc   ON (adr.countryId = gc.iso_3166_a2)
-                 LEFT JOIN  geoloc_administrativeareas    AS gr   ON (adr.countryId = gr.country
-                                                                      AND adr.administrativeAreaId = gr.id)
-                 LEFT JOIN  emails                        AS em   ON (em.uid = u.user_id AND em.flags = 'active')
-                INNER JOIN  profile_display               AS d    ON (d.pid = u.user_id)" . (S::logged() ?
-                "LEFT JOIN  contacts                      AS c    ON (c.contact = u.user_id AND c.uid = " . S::v('uid') . ")"
-                 : "");
+        return null;
     }
 
-    public function bounds()
+    public function fields()
     {
-        $order = Env::v('order', $this->defaultkey);
-        $show_bounds = 0;
-        if (($order == "name") || ($order == "-name")) {
-            $this->bound_field = "nom";
-            $show_bounds = 1;
-        } elseif (($order == "promo") || ($order == "-promo")) {
-            $this->bound_field = "promo";
-            $show_bounds = -1;
-        }
-        if ($order{0} == '-') {
-            $show_bounds = -$show_bounds;
-        }
-        return $show_bounds;
+        return null;
     }
 
     public function templateName()
index fef4df2..abcb134 100644 (file)
@@ -85,10 +85,7 @@ abstract class Validate
         $this->stamp  = date('YmdHis');
         $this->unique = $_unique;
         $this->type   = $_type;
-        $res = XDB::query("SELECT  promo
-                             FROM  profile_display
-                            WHERE  pid={?}", $this->user->id());
-        $this->promo = $res->fetchOneCell();
+        $this->promo  = $this->user->promo();
     }
 
     // }}}
index 461b969..69509c1 100644 (file)
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
  ***************************************************************************/
 
-// {{{ class AliasReq
-
+// class AliasReq {{{1
 class AliasReq extends Validate
 {
-    // {{{ properties
-
+    // properties {{{2
     public $alias;
     public $raison;
     public $unique = true;
 
-    public $old='';
-    public $public='private';
+    public $old    = '';
+    public $public = 'private';
 
     public $rules = "Interdire ce qui peut nous servir (virus@, postmaster@, ...),
                   les alias vulgaires, et les prenom.nom (sauf si c'est pour l'utilisateur prenom.nom).
                   Pas de contrainte pour les tirets ou les points, en revanche le souligné (_) est interdit";
 
-    // }}}
-    // {{{ constructor
-
+    // constructor {{{2
     public function __construct(User &$_user, $_alias, $_raison, $_public, $_stamp=0)
     {
         global $globals;
@@ -46,97 +42,67 @@ class AliasReq extends Validate
         $this->alias  = $_alias.'@'.$globals->mail->alias_dom;
         $this->raison = $_raison;
         $this->public = $_public;
-
-        $res = XDB::query("
-                SELECT  v.alias
-                  FROM  virtual_redirect AS vr
-            INNER JOIN  virtual          AS v  ON (v.vid=vr.vid AND v.alias LIKE '%@{$globals->mail->alias_dom}')
-                 WHERE  vr.redirect = {?} OR vr.redirect = {?}",
-                $this->user->forlifeEmail(),
-                // TODO: remove this über-ugly hack. The issue is that you need
-                // to remove all @m4x.org addresses in virtual_redirect first.
-                $this->user->login() . '@' . $globals->mail->domain2);
-        $this->old = $res->fetchOneCell();
+        $this->old    = $user->emailAlias();
         if (empty($this->old)) {
             unset($this->old);
         }
     }
 
-    // }}}
-    // {{{ function get_request()
-
+    // function get_request() {{{2
     static public function get_request($uid)
     {
         return parent::get_typed_request($uid, 'alias');
     }
 
-    // }}}
-    // {{{ function formu()
-
+    // function formu() {{{2
     public function formu()
     {
         return 'include/form.valid.aliases.tpl';
     }
 
-    // }}}
-    // {{{ function _mail_subj
-
+    // function _mail_subj {{{2
     protected function _mail_subj()
     {
         return "[Polytechnique.org/MELIX] Demande de l'alias {$this->alias}";
     }
 
-    // }}}
-    // {{{ function _mail_body
-
+    // function _mail_body {{{2
     protected function _mail_body($isok)
     {
         if ($isok) {
-            return "  L'adresse email {$this->alias} que tu avais demandée vient d'être créée, tu peux désormais l'utiliser à ta convenance.".(($this->public == 'public')?" A ta demande, cette adresse apparaît maintenant sur ta fiche.":"");
+            return "  L'adresse email {$this->alias} que tu avais demandée vient d'être créée, tu peux désormais l'utiliser à ta convenance."
+                 . ($this->public == 'public' ? ' A ta demande, cette adresse apparaît maintenant sur ta fiche.' : '');
         } else {
             return "  La demande que tu avais faite pour l'alias {$this->alias} a été refusée.";
         }
     }
 
-    // }}}
-    // {{{ function shorter_domain
-
-    private function shorter_domain()
+    // function commit() {{{2
+    public function commit()
     {
-        global $globals;
-
-        $mail = $globals->mail;
-
-        if (empty($mail->domain2) || strlen($mail->domain2) > strlen($mail->domain)) {
-            return $mail->domain;
-        } else {
-            return $mail->domain2;
+        if ($this->user->hasProfile()) {
+            XDB::execute('UPDATE  profiles
+                             SET  alias_pub = {?}
+                           WHERE  pid = {?}',
+                         $this->public, $this->user->profile()->id());
         }
-    }
-
-    // }}}
-    // {{{ function commit()
-
-    public function commit ()
-    {
-        XDB::execute("UPDATE auth_user_quick SET emails_alias_pub = {?} WHERE user_id = {?}",
-                     $this->public, $this->user->id());
 
         if ($this->old) {
-            return XDB::execute("UPDATE virtual SET alias = {?} WHERE alias = {?}",
+            return XDB::execute('UPDATE  virtual
+                                    SET  alias = {?}
+                                  WHERE  alias = {?}',
                                 $this->alias, $this->old);
         } else {
-            XDB::execute("INSERT INTO virtual SET alias = {?},type='user'", $this->alias);
+            XDB::execute('INSERT INTO  virtual
+                                  SET  alias = {?}, type=\'user\'',
+                         $this->alias);
             $vid = XDB::insertId();
-            return XDB::query("INSERT INTO virtual_redirect (vid,redirect) VALUES ({?}, {?})",
-                              $vid, $this->user->forlifeEmail());
+            return XDB::execute('INSERT INTO  virtual_redirect (vid, redirect)
+                                      VALUES  ({?}, {?})',
+                                $vid, $this->user->forlifeEmail());
         }
     }
-
-    // }}}
 }
 
-// }}}
-
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
 ?>
index 10663c5..5f3e4d8 100644 (file)
@@ -121,9 +121,8 @@ est ambigu pour des raisons d'homonymie et signalera ton email exact.";
 
     public function commit()
     {
-        require_once('homonymes.inc.php');
-
-        switch_bestalias($this->user->id(), $this->loginbis);
+        Platal::load('admin', 'homonyms.inc.php');
+        switch_bestalias($this->user, $this->loginbis);
         if (!$this->warning) {
             XDB::execute("UPDATE aliases SET type = 'homonyme', expire = NOW() WHERE alias = {?}", $this->loginbis);
             XDB::execute("REPLACE INTO homonymes (homonyme_id, user_id) VALUES({?}, {?})", $this->user->id(), $this->user->id());
index ab60fb1..5d33ad3 100644 (file)
@@ -139,7 +139,7 @@ class ListeReq extends Validate
             return 1;
         }
 
-        $list = new MMList(S::user()->id(), S::v('password'), $this->domain);
+        $list = new MMList(S::user()->id(), $this->domain);
         $ret = $list->create_list($this->liste, utf8_decode($this->desc), $this->advertise,
                                   $this->modlevel, $this->inslevel,
                                   $this->owners, $this->members);
index 9f2161c..3d724d5 100644 (file)
@@ -55,10 +55,10 @@ class MarkReq extends Validate
     public function formu()
     {
         $res = XDB::query('SELECT  IF(MAX(m.last)>p.relance, MAX(m.last), p.relance)
-                             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  user_id = {?}',
+                             FROM  accounts           AS a
+                        LEFT JOIN  register_pending   AS p ON p.uid = a.uid
+                        LEFT JOIN  register_marketing AS m ON m.uid = a.uid
+                            WHERE  a.uid = {?}',
                           $this->m_user->id());
         $this->m_relance = $res->fetchOneCell();
         return 'include/form.valid.mark.tpl';
index 59eb6f5..619f954 100644 (file)
@@ -37,7 +37,7 @@ class VCard extends PlVCard
 
     public function addUser($user)
     {
-        $user = User::getSilent($user);
+        $user = Profile::get($user);
         if ($user) {
             $this->user_list[] = $user;
             $this->count++;
@@ -59,7 +59,7 @@ class VCard extends PlVCard
     {
         global $globals;
         $login = $entry['value'];
-        $user  = get_user_details($login->login());
+        $user  = get_user_details($login->hrid());
 
         if (empty($user['nom_usage'])) {
             $entry = new PlVCardEntry($user['prenom'], $user['nom'], null, null, @$user['nickname']);
@@ -137,8 +137,8 @@ class VCard extends PlVCard
         // Melix
         $res = XDB::query(
                 "SELECT alias
-                   FROM virtual
-             INNER JOIN virtual_redirect USING(vid)
+                   FROM virtual AS v
+             INNER JOIN virtual_redirect AS vr ON (v.vid = vr.vid)
              INNER JOIN auth_user_quick  ON ( user_id = {?} AND emails_alias_pub = 'public' )
                   WHERE ( redirect={?} OR redirect={?} )
                         AND alias LIKE '%@{$globals->mail->alias_dom}'",
index d461c25..617ebfb 100644 (file)
@@ -97,16 +97,8 @@ function doBicol($column=false)
 function doPlatalLink($link, $text)
 {
     if (strlen(trim($text)) == 0) {
-        $res = XDB::query("SELECT u.nom, u.prenom, u.promo, q.profile_nick AS surnom
-                             FROM auth_user_md5   AS u
-                       INNER JOIN auth_user_quick AS q USING(user_id)
-                       INNER JOIN aliases         AS a ON u.user_id = a.id
-                            WHERE a.alias = {?}", $link);
-        $row = $res->fetchOneAssoc();
-        $text = $row['prenom'] . ' ' . $row['nom'] . ' X' . $row['promo'];
-        if ($row['surnom']) {
-            $text .= ' (alias ' . $row['surnom'] . ')';
-        }
+        $user = User::get($link);
+        $text = $user->fullName();
     }
     return '<a href="profile/' . $link . '" class="popup2">' . $text . '</a>';
 }
index 775d4ff..37bb102 100644 (file)
@@ -25,6 +25,7 @@ class AdminModule extends PLModule
     {
         return array(
             'phpinfo'                      => $this->make_hook('phpinfo',                AUTH_MDP, 'admin'),
+            'get_rights'                   => $this->make_hook('get_rights',             AUTH_MDP, 'admin'),
             'admin'                        => $this->make_hook('default',                AUTH_MDP, 'admin'),
             'admin/ax-xorg'                => $this->make_hook('ax_xorg',                AUTH_MDP, 'admin'),
             'admin/dead-but-active'        => $this->make_hook('dead_but_active',        AUTH_MDP, 'admin'),
@@ -48,6 +49,7 @@ class AdminModule extends PLModule
             'admin/ipwatch'                => $this->make_hook('ipwatch',                AUTH_MDP, 'admin'),
             'admin/icons'                  => $this->make_hook('icons',                  AUTH_MDP, 'admin'),
             'admin/accounts'               => $this->make_hook('accounts',               AUTH_MDP, 'admin'),
+            'admin/account/types'          => $this->make_hook('account_types',          AUTH_MDP, 'admin'),
             'admin/jobs'                   => $this->make_hook('jobs',                   AUTH_MDP, 'admin'),
         );
     }
@@ -58,6 +60,17 @@ class AdminModule extends PLModule
         exit;
     }
 
+    function handler_get_rights(&$page, $level)
+    {
+        if (S::suid()) {
+            $page->kill('Déjà en SUID');
+        }
+        $user =& S::user();
+        Platal::session()->startSUID($user, $level);
+
+        pl_redirect('/');
+    }
+
     function handler_default(&$page)
     {
         $page->changeTpl('admin/index.tpl');
@@ -356,301 +369,233 @@ class AdminModule extends PLModule
     {
         global $globals;
         $page->changeTpl('admin/utilisateurs.tpl');
-        $page->setTitle('Administration - Edit/Su/Log');
-        require_once("emails.inc.php");
+        $page->setTitle('Administration - Compte');
 
-        if (S::has('suid')) {
+        if (S::suid()) {
             $page->kill("Déjà en SUID !!!");
         }
 
         // Loads the user identity using the environment.
-        $user = null;
-        if ($login) {
-            $user = User::get($login);
-        } else if (Env::has('user_id')) {
-            $user = User::get(Env::i('user_id'));
-        } else if (Env::has('login')) {
-            $user = User::get(Env::v('login'));
+        $user = User::get($login);
+        if (!$user) {
+            return;
         }
 
-        if ($user) {
-            $login = $user->login();
-            $registered = ($user->forlifeEmail() != null);
-        } else {
-            return;
+        $login = $user->login();
+        $registered = ($user->state != 'pending');
+
+        // Form processing
+        if (!empty($_POST)) {
+            S::assert_xsrf_token();
+            if (Post::has('uid') && Post::i('uid') != $user->id()) {
+                $page->kill('Une erreur s\'est produite');
+            }
         }
 
         // Handles specific requests (AX sync, su, ...).
-        if(Env::has('logs_button') && $registered) {
+        if(Post::has('logs_account')) {
             pl_redirect("admin/logger?loguser=$login&year=".date('Y')."&month=".date('m'));
         }
 
-        if (Env::has('ax_button') && $registered) {
-            pl_redirect("admin/synchro_ax/" . $user->login());
-        }
-
-        if(Env::has('suid_button') && $registered) {
-            S::logger()->log("suid_start", "login on " . $user->login());
-            if (!Platal::session()->startSUID($user->id())) {
-                $page->trigError('Impossible d\'effectuer un SUID sur ' . $user->id());
+        if(Post::has('su_button') && $registered) {
+            if (!Platal::session()->startSUID($user)) {
+                $page->trigError('Impossible d\'effectuer un SUID sur ' . $user->login());
             } else {
                 pl_redirect("");
             }
         }
 
-        // Fetches user data.
-        $userinfo_query = "SELECT  *, FIND_IN_SET('watch', flags) AS watch, FIND_IN_SET('femme', flags) AS sexe,
-                                   (year(naissance) > promo - 15 or year(naissance) < promo - 25) AS naiss_err
-                             FROM  auth_user_md5
-                            WHERE  user_id = {?}";
-        $mr = XDB::query($userinfo_query, $user->id())->fetchOneAssoc();
-        $redirect = ($registered ? new Redirect($user) : null);
-
-        // Processes admin requests, if any.
-        foreach($_POST as $key => $val) {
-            S::assert_xsrf_token();
-
-            switch ($key) {
-                // Email redirection actions.
-                case "add_fwd":
-                    $email = trim(Env::v('email'));
-                    if (!isvalid_email_redirection($email)) {
-                        $page->trigError("Email non valide: $email");
-                    } else {
-                        $redirect->add_email($email);
-                        $page->trigSuccess("Ajout de $email effectué");
-                    }
-                    break;
-
-                case "del_fwd":
-                    if (!empty($val)) {
-                        $redirect->delete_email($val);
-                    }
-                    break;
-
-                case "activate_fwd":
-                    if (!empty($val)) {
-                        $redirect->modify_one_email($val, true);
-                    }
-                    break;
-                case "deactivate_fwd":
-                    if (!empty($val)) {
-                        $redirect->modify_one_email($val, false);
-                    }
-                    break;
-                case "disable_fwd":
-                    $redirect->disable();
-                    break;
-                case "enable_fwd":
-                    $redirect->enable();
-                    break;
-                case "clean_fwd":
-                    if (!empty($val)) {
-                        $redirect->clean_errors($val);
-                    }
-                    break;
-
-                // Alias actions.
-                case "add_alias":
-                    global $globals;
-
-                    // Splits new alias in user and fqdn.
-                    $alias = trim(Env::v('email'));
-                    if (strpos($alias, '@') !== false) {
-                        list($alias, $domain) = explode('@', $alias);
-                    } else {
-                        $domain = $globals->mail->domain;
-                    }
-
-                    // Checks for alias' user validity.
-                    if (!preg_match('/[-a-z0-9\.]+/s', $alias)) {
-                        $page->trigError("'$alias' n'est pas un alias valide");
-                    }
-
-                    // Eventually adds the alias to the right domain.
-                    if ($domain == $globals->mail->alias_dom || $domain == $globals->mail->alias_dom2) {
-                        $req = new AliasReq($user, $alias, 'Admin request', false);
-                        if ($req->commit()) {
-                            $page->trigSuccess("Nouvel alias '$alias@$domain' attribué");
-                        } else {
-                            $page->trigError("Impossible d'ajouter l'alias '$alias@$domain', il est probablement déjà attribué");
-                        }
-                    } elseif ($domain == $globals->mail->domain || $domain == $globals->mail->domain2) {
-                        $res = XDB::execute("INSERT INTO aliases (id,alias,type) VALUES ({?}, {?}, 'alias')",
-                                            $user->id(), $alias);
-                        if ($res) {
-                            $page->trigSuccess("Nouvel alias '$alias' ajouté");
-                        } else {
-                            $page->trigError("Impossible d'ajouter l'alias '$alias', il est probablement déjà attribué");
-                        }
-                    } else {
-                        $page->trigError("Le domaine '$domain' n'est pas valide");
-                    }
-                    break;
-
-                case "del_alias":
-                    if (!empty($val)) {
-                        XDB::execute("DELETE FROM  aliases
-                                            WHERE  id = {?} AND alias = {?} AND
-                                                   type NOT IN ('a_vie', 'homonyme')",
-                                     $user->id(), $val);
-                        XDB::execute("UPDATE  emails
-                                         SET  rewrite = ''
-                                       WHERE  uid = {?} AND rewrite LIKE CONCAT({?}, '@%')",
-                                     $user->id(), $val);
-                        fix_bestalias($user);
-                        $page->trigSuccess("L'alias '$val' a été supprimé");
-                    }
-                    break;
-
-                case "best":
-                    XDB::execute("UPDATE  aliases
-                                     SET  flags = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', flags, ','), ',bestalias,', ','))
-                                   WHERE  id = {?}", $user->id());
-                    XDB::execute("UPDATE  aliases
-                                     SET  flags = CONCAT_WS(',', IF(flags = '', NULL, flags), 'bestalias')
-                                   WHERE  id = {?} AND alias = {?}", $user->id(), $val);
-
-                    // As having a non-null bestalias value is critical in
-                    // plat/al's code, we do an a posteriori check on the
-                    // validity of the bestalias.
-                    fix_bestalias($user);
-                    break;
-
-                // Profile edition.
-                case "u_edit":
-                    // Loads new values from environment.
-                    require_once('secure_hash.inc.php');
-                    $pass_encrypted = Env::v('newpass_clair') != "********" ? hash_encrypt(Env::v('newpass_clair')) : Env::v('passw');
-                    $naiss    = Env::v('naissanceN');
-                    $deces    = Env::v('decesN');
-                    $perms    = Env::v('permsN');
-                    $prenom    = Env::v('prenomN');
-                    $nom      = Env::v('nomN');
-                    $nomusage = Env::v('nomusageN');
-                    $promo    = Env::i('promoN');
-                    $sexe     = Env::v('sexeN');
-                    $comm     = trim(Env::v('commentN'));
-                    $watch    = Env::v('watchN');
-
-                    $flags    = ($sexe ? 'femme' : '');
-                    if ($watch) {
-                        $flags .= ($flags ? ',watch' : 'watch');
-                    }
-                    if ($watch && !$comm) {
-                        $page->trigError("Il est nécessaire de mettre un commentaire pour surveiller un compte");
-                        break;
-                    }
-
-                    // Fetches fields to watch for changes.
-                    $watch_query = "SELECT  naissance, deces, password, perms, nom_usage,
-                                           prenom, nom, flags, promo, comment
-                                      FROM  auth_user_md5
-                                     WHERE user_id = {?}";
-                    $old_fields = XDB::query($watch_query, $user->id())->fetchOneAssoc();
-
-                    // If user was newly banned, we need to ensure her php session
-                    // is killed. This hack is ugly (and largely overkill); it should
-                    // however suits our needs.
-                    if ($perms == 'disabled' && $old_fields['perms'] != 'disabled') {
-                        kill_sessions();
-
-                        // Also serve a reminder to the admin: disabling an account
-                        // does not deactivate email forwarding.
-                        $page->trigWarning("N'oubliez pas, le cas échéant, de désactiver les redirections et le compte GoogleApps de l'utilisateur.");
-                    }
-
-                    // Updates the user profile with the new values.
-                    $res = XDB::execute("UPDATE  auth_user_md5
-                                            SET  naissance = {?}, deces = {?}, password = {?},
-                                                 perms = {?}, prenom = {?}, nom = {?}, nom_usage = {?},
-                                                 flags = {?}, promo = {?}, comment = {?}
-                                          WHERE  user_id = {?}",
-                                        $naiss, $deces, $pass_encrypted,
-                                        $perms, $prenom, $nom, $nomusage,
-                                        $flags, $promo, $comm, $user->id());
-                    if ($res) {
-                        require_once("user.func.inc.php");
-                        user_reindex($user->id());
-                        $new_fields = XDB::query($watch_query, $user->id())->fetchOneAssoc();
-
-                        // Redacts the password in the notification, to avoid transmitting
-                        // sensitive information by email.
-                        $new_fields['password'] = ($old_fields['password'] != $new_fields['password'] ? 'new' : 'old');
-                        $old_fields['password'] = 'old';
-
-                        // Notifies the admins of the profile update.
-                        $mailer = new PlMailer("admin/useredit.mail.tpl");
-                        $mailer->assign("admin", S::user()->login());
-                        $mailer->assign("user", $user->login());
-                        $mailer->assign('old', $old_fields);
-                        $mailer->assign('new', $new_fields);
-                        $mailer->send();
-
-                        $globals->updateNbIns();
-                        $page->trigSuccess("La mise à jour a été faite avec succès.");
-                    } else {
-                        $page->trigError("La mise à jour a échoué. S'il te plaît, vérifie les valeurs.");
-                    }
-
-                    // Checks for changes, and updates other tables of plat/al.
-                    if (Env::v('nomusageN') != $mr['nom_usage']) {
-                        set_new_usage($user->id(), Env::v('nomusageN'), make_username(Env::v('prenomN'), Env::v('nomusageN')));
-                    }
-                    if (Env::v('decesN') != $mr['deces']) {
-                        require_once 'notifs.inc.php';
-                        register_watch_op($user->id(), WATCH_DEATH, $mr['deces']);
-                        user_clear_all_subs($user->id(), false);
-                    }
+        // Account Form {{{
+        $to_update = array();
+        if (Post::has('disable_weak_access')) {
+            $to_update['weak_password'] = null;
+        } else if (Post::has('update_account')) {
+            if (Post::s('full_name') != $user->fullName()) {
+                // XXX: Update profile if a profile is associated
+                $to_update['full_name'] = Post::s('full_name');
+            }
+            if (Post::s('display_name') != $user->displayName()) {
+                // XXX: Update profile if a profile is associated
+                $to_update['display_name'] = Post::s('display_name');
+            }
+            if (Post::s('sex') != ($user->isFemale() ? 'female' : 'male')) {
+                $to_update['sex'] = Post::s('sex');
+            }
+            if (!Post::blank('hashpass')) {
+                $to_update['password'] = Post::s('hashpass');
+                // TODO: Propagate the password update to GoogleApps, when required. Eg:
+                // $account = new GoogleAppsAccount($user);
+                // if ($account->active() && $account->sync_password) {
+                //     $account->set_password($pass_encrypted);
+                // }
+            }
+            if (!Post::blank('weak_password')) {
+                $to_update['weak_password'] = Post::s('weak_password');
+            }
+            if (Post::i('token_access', 0) != ($user->token_access ? 1 : 0)) {
+                $to_update['token'] = Post::i('token_access') ? rand_url_id(16) : null;
+            }
+            if (Post::i('skin', 0) != $user->skin) {
+                $to_update['skin'] = Post::i('skin', 0);
+                if ($to_update['skin'] == 0) {
+                    $to_update['skin'] = null;
+                }
+            }
+            if (Post::s('state') != $user->state) {
+                $to_update['state'] = Post::s('state');
+            }
+            if (Post::i('is_admin', 0) != ($user->is_admin ? 1 : 0)) {
+                $to_update['is_admin'] = Post::b('is_admin');
+            }
+            if (Post::s('type') != $user->type) {
+                $to_update['type'] = Post::s('type');
+            }
+            if (Post::i('watch', 0) != ($user->watch ? 1 : 0)) {
+                $to_update['flags'] = new PlFlagset();
+                $to_update['flags']->addFlag('watch', Post::i('watch'));
+            }
+            if (Post::t('comment') != $user->comment) {
+                $to_update['comment'] = Post::blank('comment') ? null : Post::t('comment');
+            }
+        }
+        if (!empty($to_update)) {
+            // TODO: fetch the initial values of the fields, and eventually send
+            // a summary of the changes to an admin.
+            $set = array();
+            foreach ($to_update as $k => $value) {
+                $set[] = XDB::format($k . ' = {?}', $value);
+            }
+            XDB::execute('UPDATE  accounts
+                             SET  ' . implode(', ', $set) . ' 
+                           WHERE  uid = ' . XDB::format('{?}', $user->id()));
+            $page->trigSuccess('Données du compte mise à jour avec succès');
+            $user = User::getWithUID($user->id());
+        }
+        // }}}
+
+        // Profile form {{{
+        if (Post::has('add_profile') || Post::has('del_profile') || Post::has('owner')) {
+            if (Post::i('del_profile', 0) != 0) {
+                XDB::execute('DELETE FROM  account_profiles
+                                    WHERE  uid = {?} AND pid = {?}',
+                             $user->id(), Post::i('del_profile'));
+            } else if (!Post::blank('new_profile')) {
+                $profile = Profile::get(Post::t('new_profile'));
+                if (!$profile) {
+                    $page->trigError('Le profil ' . Post::t('new_profile') . ' n\'existe pas');
+                } else {
+                    XDB::execute('INSERT IGNORE INTO  account_profiles (uid, pid)
+                                              VALUES  ({?}, {?})',
+                                 $user->id(), $profile->id());
+                }
+            }
+            XDB::execute('UPDATE  account_profiles
+                             SET  perms = IF(pid = {?}, CONCAT(perms, \',owner\'), REPLACE(perms, \'owner\', \'\'))
+                           WHERE  uid = {?}',
+                         Post::i('owner'), $user->id());
+        }
+        // }}}
 
-                    // Eventually updates the Google Apps account.
-                    if ($globals->mailstorage->googleapps_domain) {
-                        // If the user did choose to use synchronized passwords,
-                        // and the password was changed, updates the Google Apps
-                        // password as well.
-                        if (Env::v('newpass_clair') != "********") {
-                            require_once 'googleapps.inc.php';
-                            $account = new GoogleAppsAccount($user);
-                            if ($account->active() && $account->sync_password) {
-                                $account->set_password($pass_encrypted);
-                            }
-                        }
-                    }
+        // Email forwards form {{{
+        require_once("emails.inc.php");
+        $redirect = ($registered ? new Redirect($user) : null);
+        if (Post::has('add_fwd')) {
+            $email = Post::t('email');
+            if (!isvalid_email_redirection($email)) {
+                $page->trigError("Email non valide: $email");
+            } else {
+                $redirect->add_email($email);
+                $page->trigSuccess("Ajout de $email effectué");
+            }
+        } else if (!Post::blank('del_fwd')) {
+            $redirect->delete_email(Post::t('del_fwd'));
+        } else if (!Post::blank('activate_fwd')) {
+            $redirect->modify_one_email(Post::t('activate_fwd', true));
+        } else if (!Post::blank('deactivate_fwd')) {
+            $redirect->modify_one_email(Post::t('deactivate_fwd', false));
+        } else if (Post::has('disable_fwd')) {
+            $redirect->disable();
+        } else if (Post::has('enable_fwd')) {
+            $redirect->enable();
+        } else if (!Post::blank('clean_fwd')) {
+            $redirect->clean_errors(Post::t('clean_fwd'));
+        }
+        // }}}
+
+        // Email alias form {{{
+        if (Post::has('add_alias')) {
+            // Splits new alias in user and fqdn.
+            $alias = Env::t('email');
+            if (strpos($alias, '@') !== false) {
+                list($alias, $domain) = explode('@', $alias);
+            } else {
+                $domain = $globals->mail->domain;
+            }
 
+            // Checks for alias' user validity.
+            if (!preg_match('/[-a-z0-9\.]+/s', $alias)) {
+                $page->trigError("'$alias' n'est pas un alias valide");
+            }
 
-                    // Reloads the user profile, to ensure the latest version will
-                    // be served to the administrator.
-                    $mr = XDB::query($userinfo_query, $user->id())->fetchOneAssoc();
+            // Eventually adds the alias to the right domain.
+            if ($domain == $globals->mail->alias_dom || $domain == $globals->mail->alias_dom2) {
+                $req = new AliasReq($user, $alias, 'Admin request', false);
+                if ($req->commit()) {
+                    $page->trigSuccess("Nouvel alias '$alias@$domain' attribué");
+                } else {
+                    $page->trigError("Impossible d'ajouter l'alias '$alias@$domain', il est probablement déjà attribué");
+                }
+            } elseif ($domain == $globals->mail->domain || $domain == $globals->mail->domain2) {
+                $res = XDB::execute("INSERT INTO  aliases (id, alias, type)
+                                          VALUES  ({?}, {?}, 'alias')",
+                                    $user->id(), $alias);
+                $page->trigSuccess("Nouvel alias '$alias' ajouté");
+            } else {
+                $page->trigError("Le domaine '$domain' n'est pas valide");
+            }
+        } else if (!Post::blank('del_alias')) {
+            XDB::execute("DELETE FROM  aliases
+                                WHERE  id = {?} AND alias = {?} AND
+                                       type NOT IN ('a_vie', 'homonyme')",
+                         $user->id(), $val);
+            XDB::execute("UPDATE  emails
+                             SET  rewrite = ''
+                           WHERE  uid = {?} AND rewrite LIKE CONCAT({?}, '@%')",
+                         $user->id(), $val);
+            fix_bestalias($user);
+            $page->trigSuccess("L'alias '$val' a été supprimé");
+        } else if (!Post::blank('best')) {
+            XDB::execute("UPDATE  aliases
+                             SET  flags = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', flags, ','), ',bestalias,', ','))
+                           WHERE  id = {?}", $user->id());
+            XDB::execute("UPDATE  aliases
+                             SET  flags = CONCAT_WS(',', IF(flags = '', NULL, flags), 'bestalias')
+                           WHERE  id = {?} AND alias = {?}", $user->id(), $val);
+            // As having a non-null bestalias value is critical in
+            // plat/al's code, we do an a posteriori check on the
+            // validity of the bestalias.
+            fix_bestalias($user);
+        }
+        // }}}
+
+        // Forum form {{{
+        if (Post::has('b_edit')) {
+            XDB::execute("DELETE FROM  forum_innd
+                                WHERE  uid = {?}", $user->id());
+            if (Env::v('write_perm') != "" || Env::v('read_perm') != ""  || Env::v('commentaire') != "" ) {
+                XDB::execute("INSERT INTO  forum_innd
+                                      SET  ipmin = '0', ipmax = '4294967295',
+                                           write_perm = {?}, read_perm = {?},
+                                           comment = {?}, priority = '200', uid = {?}",
+                             Env::v('write_perm'), Env::v('read_perm'), Env::v('comment'), $user->id());
+            }
+        }
+        // }}}
 
-                    break;
 
-                // User re-registration.
-                case "u_kill":
-                    require_once('user.func.inc.php');
-                    user_clear_all_subs($user->id());
-                    $globals->updateNbIns();
-                    $page->trigSuccess($user->login() . ' a été désinscrit !');
-
-                    $mailer = new PlMailer("admin/useredit.mail.tpl");
-                    $mailer->assign("admin", S::user()->login());
-                    $mailer->assign("user", $user->login());
-                    $mailer->assign("deletion", true);
-                    $mailer->send();
-                    break;
+        $page->addJsLink('ui.core.js');
+        $page->addJsLink('ui.tabs.js');
 
-                // Forum ban update.
-                case "b_edit":
-                    XDB::execute("DELETE FROM forums.innd WHERE uid = {?}", $user->id());
-                    if (Env::v('write_perm') != "" || Env::v('read_perm') != ""  || Env::v('commentaire') != "" ) {
-                        XDB::execute("INSERT INTO  forums.innd
-                                              SET  ipmin = '0', ipmax = '4294967295',
-                                                   write_perm = {?}, read_perm = {?},
-                                                   comment = {?}, priority = '200', uid = {?}",
-                                     Env::v('write_perm'), Env::v('read_perm'), Env::v('comment'), $user->id());
-                    }
-                    break;
-            }
-        }
 
         // Displays last login and last host information.
         $res = XDB::query("SELECT  start, host
@@ -663,33 +608,29 @@ class AdminModule extends PLModule
         $page->assign('host', $host);
 
         // Display active aliases.
-        $page->assign('virtuals', XDB::iterator(
-                "SELECT  alias
-                   FROM  virtual
-             INNER JOIN  virtual_redirect USING (vid)
-                  WHERE  type = 'user' AND (redirect = {?} OR redirect = {?})",
-                $user->forlifeEmail(),
-                // TODO: remove this über-ugly hack. The issue is that you need
-                // to remove all @m4x.org addresses in virtual_redirect first.
-                $user->login() . '@' . $globals->mail->domain2));
-
-        $page->assign('aliases', XDB::iterator(
-                "SELECT  alias, type='a_vie' AS for_life,FIND_IN_SET('bestalias',flags) AS best,expire
-                   FROM  aliases
-                  WHERE  id = {?} AND type != 'homonyme'
-               ORDER BY  type != 'a_vie'", $user->id()));
+        $page->assign('virtuals', $user->emailAliases());
+        $page->assign('aliases', XDB::iterator("SELECT  alias, type='a_vie' AS for_life,
+                                                        FIND_IN_SET('bestalias',flags) AS best, expire
+                                                  FROM  aliases
+                                                 WHERE  id = {?} AND type != 'homonyme'
+                                              ORDER BY  type != 'a_vie'", $user->id()));
+        $page->assign('account_types', XDB::iterator('SELECT * FROM account_types ORDER BY type'));
+        $page->assign('skins', XDB::iterator('SELECT id, name FROM skins ORDER BY name'));
+        $page->assign('profiles', XDB::iterator('SELECT  p.pid, p.hrpid, FIND_IN_SET(\'owner\', ap.perms) AS owner
+                                                   FROM  account_profiles AS ap
+                                             INNER JOIN  profiles AS p ON (ap.pid = p.pid)
+                                                  WHERE  ap.uid = {?}', $user->id()));
 
         // Displays email redirection and the general profile.
         if ($registered && $redirect) {
             $page->assign('emails', $redirect->emails);
         }
 
-        $page->assign('mr', $mr);
         $page->assign('user', $user);
 
         // Displays forum bans.
         $res = XDB::query("SELECT  write_perm, read_perm, comment
-                             FROM  forums.innd
+                             FROM  forum_innd
                             WHERE  uid = {?}", $user->id());
         $bans = $res->fetchOneAssoc();
         $page->assign('bans', $bans);
@@ -760,15 +701,14 @@ class AdminModule extends PLModule
     {
         $page->changeTpl('admin/homonymes.tpl');
         $page->setTitle('Administration - Homonymes');
-        require_once("homonymes.inc.php");
+        $this->load("homonyms.inc.php");
 
         if ($target) {
-            if (! list($prenom,$nom,$forlife,$loginbis) = select_if_homonyme($target)) {
-                $target=0;
+            $user = User::getSilent($target);
+            if (!$user || !($loginbis = select_if_homonyme($user))) {
+                $target = 0;
             } else {
-                $page->assign('nom',$nom);
-                $page->assign('prenom',$prenom);
-                $page->assign('forlife',$forlife);
+                $page->assign('user', $user);
                 $page->assign('loginbis',$loginbis);
             }
         }
@@ -783,37 +723,40 @@ class AdminModule extends PLModule
                 case 'mail':
                     S::assert_xsrf_token();
 
-                    send_warning_homonyme($prenom, $nom, $forlife, $loginbis);
-                    switch_bestalias($target, $loginbis);
+                    send_warning_homonyme($user, $loginbis);
+                    switch_bestalias($user, $loginbis);
                     $op = 'list';
-                    $page->trigSuccess('Email envoyé à ' . $forlife . '.');
+                    $page->trigSuccess('Email envoyé à ' . $user->forlifeEmail() . '.');
                     break;
 
                 case 'correct':
                     S::assert_xsrf_token();
 
-                    switch_bestalias($target, $loginbis);
-                    XDB::execute("UPDATE aliases SET type='homonyme',expire=NOW() WHERE alias={?}", $loginbis);
-                    XDB::execute("REPLACE INTO homonymes (homonyme_id,user_id) VALUES({?},{?})", $target, $target);
-                    send_robot_homonyme($prenom, $nom, $forlife, $loginbis);
+                    switch_bestalias($user, $loginbis);
+                    XDB::execute("UPDATE  aliases
+                                     SET  type = 'homonyme', expire=NOW()
+                                   WHERE  alias = {?}", $loginbis);
+                    XDB::execute("REPLACE INTO  homonymes (homonyme_id,user_id)
+                                        VALUES  ({?}, {?})", $target, $target);
+                    send_robot_homonyme($user, $loginbis);
                     $op = 'list';
-                    $page->trigSuccess('Email envoyé à ' . $forlife . ', alias supprimé.');
+                    $page->trigSuccess('Email envoyé à ' . $user->forlifeEmail() . ', alias supprimé.');
                     break;
             }
         }
 
         if ($op == 'list') {
             $res = XDB::iterator(
-                    "SELECT  a.alias AS homonyme,s.id AS user_id,s.alias AS forlife,
-                             promo,prenom,nom,
-                             IF(h.homonyme_id=s.id, a.expire, NULL) AS expire,
-                             IF(h.homonyme_id=s.id, a.type, NULL) AS type
+                    "SELECT  a.alias AS homonyme, s.alias AS forlife,
+                             IF(h.homonyme_id = s.id, a.expire, NULL) AS expire,
+                             IF(h.homonyme_id = s.id, a.type, NULL) AS type,
+                             ac.uid AS user_id
                        FROM  aliases       AS a
                   LEFT JOIN  homonymes     AS h ON (h.homonyme_id = a.id)
                  INNER JOIN  aliases       AS s ON (s.id = h.user_id AND s.type='a_vie')
-                 INNER JOIN  auth_user_md5 AS u ON (s.id=u.user_id)
-                      WHERE  a.type='homonyme' OR a.expire!=''
-                   ORDER BY  a.alias,promo");
+                 INNER JOIN  accounts      AS ac ON (ac.uid = a.id)
+                      WHERE  a.type = 'homonyme' OR a.expire != ''
+                   ORDER BY  a.alias, forlife");
             $hnymes = Array();
             while ($tab = $res->next()) {
                 $hnymes[$tab['homonyme']][] = $tab;
@@ -822,123 +765,70 @@ class AdminModule extends PLModule
         }
     }
 
-    function handler_ax_xorg(&$page) {
-        $page->changeTpl('admin/ax-xorg.tpl');
-        $page->setTitle('Administration - AX/X.org');
-
-        // liste des différences
-        $res = XDB::query(
-                'SELECT  u.promo,u.nom AS nom,u.prenom AS prenom,ia.nom AS nomax,ia.prenom AS prenomax,u.matricule AS mat,ia.matricule_ax AS matax
-                   FROM  auth_user_md5 AS u
-             INNER JOIN  identification_ax AS ia ON u.matricule_ax = ia.matricule_ax
-                  WHERE  (SOUNDEX(u.nom) != SOUNDEX(ia.nom) AND SOUNDEX(CONCAT(ia.particule,u.nom)) != SOUNDEX(ia.nom)
-                         AND SOUNDEX(u.nom) != SOUNDEX(ia.nom_patro) AND SOUNDEX(CONCAT(ia.particule,u.nom)) != SOUNDEX(ia.nom_patro))
-                         OR u.prenom != ia.prenom OR (u.promo != ia.promo AND u.promo != ia.promo+1 AND u.promo != ia.promo-1)
-               ORDER BY  u.promo,u.nom,u.prenom');
-        $page->assign('diffs', $res->fetchAllAssoc());
-
-        // gens à l'ax mais pas chez nous
-        $res = XDB::query(
-                'SELECT  ia.promo,ia.nom,ia.nom_patro,ia.prenom
-                   FROM  identification_ax as ia
-              LEFT JOIN  auth_user_md5 AS u ON u.matricule_ax = ia.matricule_ax
-                  WHERE  u.nom IS NULL');
-        $page->assign('mank', $res->fetchAllAssoc());
-
-        // gens chez nous et pas à l'ax
-        $res = XDB::query('SELECT promo,nom,prenom FROM auth_user_md5 WHERE matricule_ax IS NULL');
-        $page->assign('plus', $res->fetchAllAssoc());
-    }
-
-    function handler_deaths(&$page, $promo = 0, $validate = false) {
+    function handler_deaths(&$page, $promo = 0, $validate = false)
+    {
         $page->changeTpl('admin/deces_promo.tpl');
         $page->setTitle('Administration - Deces');
 
-        if (!$promo)
-            $promo = Env::i('promo');
-        if (Env::has('sub10')) $promo -= 10;
-        if (Env::has('sub01')) $promo -=  1;
-        if (Env::has('add01')) $promo +=  1;
-        if (Env::has('add10')) $promo += 10;
-
-        $page->assign('promo',$promo);
+        if (!$promo) {
+            $promo = Env::t('promo', 'X1923');
+        }
+        $page->assign('promo', $promo);
+        if (!$promo) {
+            return;
+        }
 
         if ($validate) {
             S::assert_xsrf_token();
 
-            $res = XDB::iterRow("SELECT user_id,matricule,nom,prenom,deces FROM auth_user_md5 WHERE promo = {?}", $promo);
-            while (list($uid,$mat,$nom,$prenom,$deces) = $res->next()) {
-                $val = Env::v($mat);
+            $res = XDB::iterRow('SELECT  p.hrpid, pd.directory_name, p.deathdate
+                                   FROM  profiles AS p
+                             INNER JOIN  profile_display AS pd ON (p.pid = pd.pid)
+                                  WHERE  pd.promo = {?}', $promo);
+            while (list($pid, $name, $death) = $res->next()) {
+                $val = Env::v($pid);
                 if($val == $deces || empty($val)) {
                     continue;
                 }
 
-                XDB::execute('UPDATE auth_user_md5 SET deces={?} WHERE matricule = {?}', $val, $mat);
-                $page->trigSuccess('Ajout du décès de ' . $prenom . " " . $nom . ' le ' . $val . '.');
-                if($deces == '0000-00-00' || empty($deces)) {
-                    require_once('notifs.inc.php');
-                    register_watch_op($uid, WATCH_DEATH, $val);
+                XDB::execute('UPDATE  profiles
+                                 SET  deathdate = {?}, deathdate_rec = NOW()
+                               WHERE  hrpid = {?}', $val, $pid);
+                $page->trigSuccess('Ajout du décès de ' . $name . ' le ' . $val . '.');
+                if($death == '0000-00-00' || empty($death)) {
+                    // TODO: FIX THIS DEPRECATED CALL
                     require_once('user.func.inc.php');
                     user_clear_all_subs($uid, false);   // by default, dead ppl do not loose their email
                 }
             }
         }
 
-        $res = XDB::iterator('SELECT matricule, nom, prenom, deces FROM auth_user_md5 WHERE promo = {?} ORDER BY nom,prenom', $promo);
+        $res = XDB::iterator('SELECT  p.hrpid, pd.directory_name, p.deathdate
+                                FROM  profiles AS p
+                          INNER JOIN  profile_display AS pd ON (p.pid = pd.pid)
+                               WHERE  pd.promo = {?}
+                            ORDER BY  pd.sort_name', $promo);
         $page->assign('decedes', $res);
     }
 
-    function handler_dead_but_active(&$page) {
+    function handler_dead_but_active(&$page)
+    {
         $page->changeTpl('admin/dead_but_active.tpl');
         $page->setTitle('Administration - Décédés');
 
         $res = XDB::iterator(
-                "SELECT  u.promo, u.nom, u.prenom, u.deces, u.matricule_ax, u.hruid, DATE(MAX(s.start)) AS last
-                   FROM  auth_user_md5 AS u
-              LEFT JOIN  logger.sessions AS s ON (s.uid = u.user_id AND suid = 0)
-                  WHERE  perms IN ('admin', 'user') AND deces <> 0
-               GROUP BY  u.user_id
-               ORDER BY  u.promo, u.nom");
+                'SELECT  a.hruid, pd.promo, p.ax_id, pd.directory_name, p.deathdate, DATE(MAX(s.start)) AS last
+                   FROM  accounts AS a
+             INNER JOIN  account_profiles AS ap ON (ap.uid = a.uid AND FIND_IN_SET(\'owner\', ap.perms))
+             INNER JOIN  profiles AS p ON (p.pid = ap.pid)
+             INNER JOIN  profile_display AS pd ON (pd.pid = p.pid)
+              LEFT JOIN  logger.sessions AS s ON (s.uid = a.uid AND suid = 0)
+                  WHERE  a.state = \'active\' AND p.deathdate IS NOT NULL
+               GROUP BY  a.uid
+               ORDER BY  pd.promo, pd.sort_name');
         $page->assign('dead', $res);
     }
 
-    function handler_synchro_ax(&$page, $login = null, $action = null) {
-        $page->changeTpl('admin/synchro_ax.tpl');
-        $page->setTitle('Administration - Synchro AX');
-
-        // Checks for synchronization requirements.
-        require_once('synchro_ax.inc.php');
-        if (is_ax_key_missing()) {
-            $page->assign('no_private_key', true);
-            $page->run();
-        }
-
-        // Determines user identity using environment.
-        if ($login) {
-            $user = User::get($login);
-        } else if (Env::has('user')) {
-            $user = User::get(Env::v('user'));
-        } else if (Env::has('mat')) {
-            $res = XDB::query("SELECT user_id FROM auth_user_md5 WHERE matricule = {?}", Env::i('mat'));
-            $user = User::get($res->fetchOneCell());
-        } else {
-            return;
-        }
-
-        // Finally synchronizes the AX and plat/al information.
-        if ($action == 'import') {
-            ax_synchronize($user->login(), S::v('uid'));
-        }
-
-        require_once 'profil.func.inc.php';
-        $userxorg = get_user_details($user->login(), S::v('uid'), 'ax');
-        $userax = get_user_ax($userxorg['matricule_ax']);
-        $diff = diff_user_details($userax, $userxorg, 'ax');
-
-        $page->assign('x', $userxorg);
-        $page->assign('diff', $diff);
-    }
-
     function handler_validate(&$page, $action = 'list', $id = null)
     {
         $page->changeTpl('admin/valider.tpl');
@@ -993,7 +883,8 @@ class AdminModule extends PLModule
         $page->assign('vit', new ValidateIterator());
     }
 
-    function handler_validate_answers(&$page, $action = 'list', $id = null) {
+    function handler_validate_answers(&$page, $action = 'list', $id = null)
+    {
         $page->setTitle('Administration - Réponses automatiques de validation');
         $page->assign('title', 'Gestion des réponses automatiques');
         $table_editor = new PLTableEditor('admin/validate/answers','requests_answers','id');
@@ -1002,7 +893,9 @@ class AdminModule extends PLModule
         $table_editor->describe('answer','texte',false);
         $table_editor->apply($page, $action, $id);
     }
-    function handler_skins(&$page, $action = 'list', $id = null) {
+
+    function handler_skins(&$page, $action = 'list', $id = null)
+    {
         $page->setTitle('Administration - Skins');
         $page->assign('title', 'Gestion des skins');
         $table_editor = new PLTableEditor('admin/skins','skins','id');
@@ -1015,7 +908,8 @@ class AdminModule extends PLModule
         $table_editor->apply($page, $action, $id);
     }
 
-    function handler_postfix_blacklist(&$page, $action = 'list', $id = null) {
+    function handler_postfix_blacklist(&$page, $action = 'list', $id = null)
+    {
         $page->setTitle('Administration - Postfix : Blacklist');
         $page->assign('title', 'Blacklist de postfix');
         $table_editor = new PLTableEditor('admin/postfix/blacklist','postfix_blacklist','email', true);
@@ -1023,14 +917,18 @@ class AdminModule extends PLModule
         $table_editor->describe('email','email',true);
         $table_editor->apply($page, $action, $id);
     }
-    function handler_postfix_whitelist(&$page, $action = 'list', $id = null) {
+
+    function handler_postfix_whitelist(&$page, $action = 'list', $id = null)
+    {
         $page->setTitle('Administration - Postfix : Whitelist');
         $page->assign('title', 'Whitelist de postfix');
         $table_editor = new PLTableEditor('admin/postfix/whitelist','postfix_whitelist','email', true);
         $table_editor->describe('email','email',true);
         $table_editor->apply($page, $action, $id);
     }
-    function handler_mx_broken(&$page, $action = 'list', $id = null) {
+
+    function handler_mx_broken(&$page, $action = 'list', $id = null)
+    {
         $page->setTitle('Administration - MX Défaillants');
         $page->assign('title', 'MX Défaillant');
         $table_editor = new PLTableEditor('admin/mx/broken', 'mx_watch', 'host', true);
@@ -1039,7 +937,9 @@ class AdminModule extends PLModule
         $table_editor->describe('text', 'Description du problème', false);
         $table_editor->apply($page, $action, $id);
     }
-    function handler_logger_actions(&$page, $action = 'list', $id = null) {
+
+    function handler_logger_actions(&$page, $action = 'list', $id = null)
+    {
         $page->setTitle('Administration - Actions');
         $page->assign('title', 'Gestion des actions de logger');
         $table_editor = new PLTableEditor('admin/logger/actions','logger.actions','id');
@@ -1047,7 +947,9 @@ class AdminModule extends PLModule
         $table_editor->describe('description','description',true);
         $table_editor->apply($page, $action, $id);
     }
-    function handler_downtime(&$page, $action = 'list', $id = null) {
+
+    function handler_downtime(&$page, $action = 'list', $id = null)
+    {
         $page->setTitle('Administration - Coupures');
         $page->assign('title', 'Gestion des coupures');
         $table_editor = new PLTableEditor('admin/downtime','coupures','id');
@@ -1059,11 +961,21 @@ class AdminModule extends PLModule
         $table_editor->apply($page, $action, $id);
     }
 
+    function handler_account_types(&$page, $action = 'list', $id = null) 
+    {
+        $page->setTitle('Administration - Types de comptes');
+        $page->assign('title', 'Gestion des types de comptes');
+        $table_editor = new PLTableEditor('admin/account/types', 'account_types', 'type', true);
+        $table_editor->describe('type', 'Catégorie', true);
+        $table_editor->describe('perms', 'Permissions associées', true);
+        $table_editor->apply($page, $action, $id);
+    }
+
     function handler_wiki(&$page, $action = 'list', $wikipage = null, $wikipage2 = null)
     {
-        if (S::v('core_rss_hash')) {
+        if (S::hasAuthToken()) {
            $page->setRssLink('Changement Récents',
-                             '/Site/AllRecentChanges?action=rss&user=' . S::v('hruid') . '&hash=' . S::v('core_rss_hash'));
+                             '/Site/AllRecentChanges?action=rss&user=' . S::v('hruid') . '&hash=' . S::v('token'));
         }
 
         // update wiki perms
@@ -1123,7 +1035,6 @@ class AdminModule extends PLModule
         }
 
         $page->changeTpl('admin/wiki.tpl');
-        $page->addJsLink('jquery.js');
         $page->assign('wiki_pages', $wiki_tree);
         $page->assign('perms_opts', $perms);
     }
@@ -1172,13 +1083,13 @@ class AdminModule extends PLModule
             $sql = "SELECT  w.ip, IF(s.ip IS NULL,
                                      IF(w.ip = s2.ip, s2.host, s2.forward_host),
                                      IF(w.ip = s.ip, s.host, s.forward_host)),
-                            w.mask, w.detection, w.state, u.hruid
+                            w.mask, w.detection, w.state, a.hruid
                       FROM  ip_watch        AS w
                  LEFT JOIN  logger.sessions AS s  ON (s.ip = w.ip)
                  LEFT JOIN  logger.sessions AS s2 ON (s2.forward_ip = w.ip)
-                 LEFT JOIN  auth_user_md5   AS u  ON (u.user_id = s.uid)
-                  GROUP BY  w.ip, u.hruid
-                  ORDER BY  w.state, w.ip, u.hruid";
+                 LEFT JOIN  accounts        AS a  ON (a.uid = s.uid)
+                  GROUP BY  w.ip, a.hruid
+                  ORDER BY  w.state, w.ip, a.hruid";
             $it = Xdb::iterRow($sql);
 
             $table = array();
@@ -1206,14 +1117,14 @@ class AdminModule extends PLModule
             $page->assign('table', $table);
         } elseif ($action == 'edit') {
             $sql = "SELECT  w.detection, w.state, w.last, w.description, w.mask,
-                            u1.hruid AS edit, u2.hruid AS hruid, s.host
+                            a1.hruid AS edit, a2.hruid AS hruid, s.host
                       FROM  ip_watch        AS w
-                 LEFT JOIN  auth_user_md5   AS u1 ON (u1.user_id = w.uid)
+                 LEFT JOIN  accounts        AS a1 ON (a1.uid = w.uid)
                  LEFT JOIN  logger.sessions AS s  ON (w.ip = s.ip)
-                 LEFT JOIN  auth_user_md5   AS u2 ON (u2.user_id = s.uid)
+                 LEFT JOIN  accounts        AS a2 ON (a2.uid = s.uid)
                      WHERE  w.ip = {?}
-                  GROUP BY  u2.hruid
-                  ORDER BY  u2.hruid";
+                  GROUP BY  a2.hruid
+                  ORDER BY  a2.hruid";
             $it = Xdb::iterRow($sql, ip_to_uint($ip));
 
             $props = array();
@@ -1256,14 +1167,15 @@ class AdminModule extends PLModule
     function handler_accounts(&$page)
     {
         $page->changeTpl('admin/accounts.tpl');
-        $page->assign('disabled', XDB::iterator('SELECT  u.nom, u.prenom, u.promo, u.comment, u.hruid
-                                                   FROM  auth_user_md5 AS u
-                                                  WHERE  perms = \'disabled\'
-                                               ORDER BY  nom, prenom'));
-        $page->assign('admins', XDB::iterator('SELECT  u.nom, u.prenom, u.promo, u.hruid
-                                                 FROM  auth_user_md5 AS u
-                                                WHERE  perms = \'admin\'
-                                             ORDER BY  nom, prenom'));
+        $page->assign('disabled', XDB::iterator('SELECT  a.hruid, FIND_IN_SET(\'watch\', a.flags) AS watch,
+                                                         a.state = \'disabled\' AS disabled, a.comment
+                                                   FROM  accounts AS a
+                                                  WHERE  a.state = \'disabled\' OR FIND_IN_SET(\'watch\', a.flags)
+                                               ORDER BY  a.hruid'));
+        $page->assign('admins', XDB::iterator('SELECT  a.hruid
+                                                 FROM  accounts AS a
+                                                WHERE  a.is_admin
+                                             ORDER BY  a.hruid'));
     }
 
     function handler_jobs(&$page, $id = -1)
similarity index 63%
rename from include/homonymes.inc.php
rename to modules/admin/homonyms.inc.php
index 881f676..d7bae79 100644 (file)
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
  ***************************************************************************/
 
-function select_if_homonyme($uid) {
-    $res = XDB::query("SELECT  prenom,nom,a.alias AS forlife,h.alias AS loginbis
-                                   FROM  auth_user_md5 AS u
-                             INNER JOIN  aliases       AS a ON (a.id=u.user_id AND a.type='a_vie')
-                             INNER JOIN  aliases       AS h ON (h.id=u.user_id AND h.expire!='')
-                                  WHERE  user_id = {?}", $uid);
-    return $res->fetchOneRow();
+function select_if_homonyme(PlUser &$user) {
+    return XDB::fetchOneCell("SELECT  a.alias
+                                FROM  aliases AS a
+                               WHERE  a.id = {?} AND a.expire != ''",
+                             $user->id());
 }
 
-function send_warning_homonyme($prenom, $nom, $forlife, $loginbis) {
+function send_warning_homonyme(PlUser &$user, $loginbis) {
     global $globals;
     $cc = "support+homonyme@" . $globals->mail->domain;
     $FROM = "\"Support Polytechnique.org\" <$cc>";
     $mymail = new PlMailer();
     $mymail->setFrom($FROM);
-    $mymail->setSubject("Dans 2 semaines, suppression de $loginbis@" . $globals->mail->domain);
-    $mymail->addTo("$prenom $nom <$forlife@" . $globals->mail->domain . '>');
     $mymail->addCc($cc);
+    $mymail->setSubject("Dans 2 semaines, suppression de $loginbis@" . $globals->mail->domain);
     $mymail->setTxtBody(Env::v('mailbody'));
-    $mymail->send();
+    $mymail->sendTo($user);
 }
 
-function send_robot_homonyme($prenom, $nom, $forlife, $loginbis) {
+function send_robot_homonyme(PlUser &$user, $loginbis) {
     global $globals;
     $cc = "support+homonyme@" . $globals->mail->domain;
     $FROM = "\"Support Polytechnique.org\" <$cc>";
     $mymail = new PlMailer();
     $mymail->setFrom($FROM);
     $mymail->setSubject("Mise en place du robot $loginbis@" . $globals->mail->domain);
-    $mymail->addTo("$prenom $nom <$forlife@" . $globals->mail->domain . '>');
     $mymail->addCc($cc);
     $mymail->setTxtBody(Env::v('mailbody'));
-    $mymail->send();
+    $mymail->sendTo($user);
 }
 
-function switch_bestalias($uid, $loginbis) {
+function switch_bestalias(PlUser &$user, $loginbis) {
     // check if loginbis was the bestalias
-    $res = XDB::query("SELECT alias FROM aliases WHERE id = {?} AND FIND_IN_SET('bestalias', flags)", $uid);
-    $bestalias = $res->fetchOneCell();
-    if ($bestalias && $bestalias != $loginbis) return false;
+    $bestailas = XDB::fetchOneCell("SELECT  alias
+                                      FROM  aliases
+                                     WHERE  id = {?} AND FIND_IN_SET('bestalias', flags)",
+                                   $user->id());
+    if ($bestalias && $bestalias != $loginbis) {
+        return false;
+    }
 
     // select the shortest alias still alive
-    $res = XDB::query("SELECT alias FROM aliases WHERE id = {?} AND alias != {?} AND expire IS NULL ORDER BY LENGTH(alias) LIMIT 1", $uid, $loginbis);
-    $newbest = $res->fetchOneCell();
+    $newbest = XDB::fetchOneCell("SELECT  alias
+                                    FROM  aliases
+                                   WHERE  id = {?} AND alias != {?} AND expire IS NULL
+                                ORDER BY  LENGTH(alias)
+                                   LIMIT  1", $user->id(), $loginbis);
     // change the bestalias flag
-    XDB::execute("UPDATE aliases SET flags = (flags & (255 - 1)) | IF(alias = {?}, 1, 0) WHERE id = {?}", $newbest, $uid);
-
+    XDB::execute("UPDATE  aliases
+                     SET  flags = (flags & (255 - 1)) | IF(alias = {?}, 1, 0)
+                   WHERE  id = {?}", $newbest, $user->id());
     return $newbest;
 }
 
index 424361c..5376034 100644 (file)
@@ -49,43 +49,25 @@ class AuthModule extends PLModule
 
         $cle = $globals->core->econfiance;
 
-        if (S::v('chall') && $_GET['PASS'] == md5(S::v('chall').$cle)) {
-
-            $res  = XDB::query("SELECT password FROM auth_user_md5 WHERE user_id=10154");
-            $pass = $res->fetchOneCell();
+        $res = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<membres>\n\n";
 
-            $list = new MMList(10154, $pass, "x-econfiance.polytechnique.org");
+        if (S::v('chall') && $_GET['PASS'] == md5(S::v('chall').$cle)) {
+            $list = new MMList(User::getWithUID(10154), "x-econfiance.polytechnique.org");
             $members = $list->get_members('membres');
             if (is_array($members)) {
                 $membres = Array();
                 foreach($members[1] as $member) {
-                    if (preg_match('/^([^.]*.[^.]*.(\d\d\d\d))@polytechnique.org$/',
-                                   $member[1], $matches))
-                    {
-                        $membres[] = "a.alias='{$matches[1]}'";
+                    $user = User::getSilent($member[1]);
+                    if ($user && $user->hasProfile()) {
+                        $profile = $user->profile();
+                        $res .= "<membre>\n";
+                        $res .= "\t<nom>" . $profile->lastName() . "</nom>\n";
+                        $res .= "\t<prenom>" . $profile->firstName() . "</prenom>\n";
+                        $res .= "\t<email>" . $user->forlifeEmail() . "</email>\n";
+                        $res .= "</membre>\n\n";
                     }
                 }
             }
-
-            $where = join(' OR ',$membres);
-
-            $all = XDB::iterRow(
-                    "SELECT  u.prenom,u.nom,a.alias
-                       FROM  auth_user_md5 AS u
-                 INNER JOIN  aliases       AS a ON ( u.user_id = a.id AND a.type!='homonyme' )
-                      WHERE  $where
-                   ORDER BY  nom");
-
-            $res = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<membres>\n\n";
-
-            while (list ($prenom1,$nom1,$email1) = $all->next()) {
-                    $res .= "<membre>\n";
-                    $res .= "\t<nom>$nom1</nom>\n";
-                    $res .= "\t<prenom>$prenom1</prenom>\n";
-                    $res .= "\t<email>$email1</email>\n";
-                    $res .= "</membre>\n\n";
-            }
-
             $res .= "</membres>\n\n";
 
             header('Content-Type: text/xml; charset="UTF-8"');
@@ -148,7 +130,7 @@ class AuthModule extends PLModule
 
         // Update the last login information (unless the user is in SUID).
         $uid = S::i('uid');
-        if (!isset($_SESSION['suid'])) {
+        if (!S::suid()) {
             global $platal;
             S::logger($uid)->log('connexion_auth_ext', $platal->path);
         }
index c2b5737..6febc2c 100644 (file)
@@ -32,13 +32,20 @@ function gpex_make($chlg, $privkey, $datafields, $charset)
     $params   = "";
     $fieldarr = explode(',', $datafields);
 
-    $res = XDB::query("SELECT  matricule, matricule_ax, promo,
-                               promo_sortie, flags, deces, nom,
-                               prenom, nationalite, section,
-                               naissance
-                         FROM  auth_user_md5 WHERE user_id = {?}",
-                       S::v('uid'));
-    $personnal_data = $res->fetchOneAssoc();
+    $user =& S::user();
+    if ($user->hasProfile()) {
+        // XXX: Transition table for auth.
+        $personnal_data = $user->profile()->data();
+        $personnal_data['matricule'] = $personnal_data['xorg_id'];
+        $personnal_data['matricule_ax'] = $personnal_data['ax_id'];
+        $personnal_data['promo_sortie'] = $personnal_data['promo'] + 3; // FIXME: Hum, not that good
+        $personnal_data['nationalite'] = $personnal_data['nationality1'];
+        $personnal_data['naissance'] = $personnal_data['birthdate'];
+        $personnal_data['deces'] = $personnal_data['deathdate'];
+        $personnal_data['flags'] = $user->profile()->isFemale() ? 'femme' : '';
+    } else {
+        $personnal_data = array();
+    }
 
     foreach ($fieldarr as $val) {
         // Determine the requested value, and add it to the answer.
@@ -51,9 +58,10 @@ function gpex_make($chlg, $privkey, $datafields, $charset)
         } else if (isset($personnal_data[$val])) {
             $params .= gpex_prepare_param($val, $personnal_data[$val], $tohash, $charset);
         } else if ($val == 'username') {
-            $res = XDB::query("SELECT  alias FROM aliases
+            $res = XDB::query("SELECT  alias
+                                 FROM  aliases
                                 WHERE  id = {?} AND FIND_IN_SET('bestalias', flags)",
-                              S::v('uid'));
+                              S::i('uid'));
             $min_username = $res->fetchOneCell();
             $params      .= gpex_prepare_param($val, $min_username, $tohash, $charset);
         } else if ($val == 'grpauth') {
@@ -69,6 +77,8 @@ function gpex_make($chlg, $privkey, $datafields, $charset)
                 $perms = S::admin() ? 'admin' : 'membre';
             }
             $params .= gpex_prepare_param($val, $perms, $tohash, $charset);
+        } else {
+            $params .= gpex_prepare_param($val, '', $tohash, $charset);
         }
     }
     $tohash .= "1";
index b1f3a86..1d695fd 100644 (file)
@@ -179,14 +179,10 @@ class AXLetterModule extends PLModule
                                       . "https://www.polytechnique.org/ax/edit\n"
                                       . "-- \n"
                                       . "Association Polytechnique.org\n");
-                    $res = XDB::iterRow("SELECT IF(u.nom_usage != '', u.nom_usage, u.nom) AS nom,
-                                                u.prenom, a.alias AS bestalias
-                                           FROM axletter_rights AS ar
-                                     INNER JOIN auth_user_md5   AS u USING(user_id)
-                                     INNER JOIN aliases         AS a ON (u.user_id = a.id
-                                     AND FIND_IN_SET('bestalias', a.flags))");
-                    while (list($nom, $prenom, $alias) = $res->next()) {
-                        $mailer->addTo("$nom $prenom <$alias@{$globals->mail->domain}>");
+                    $users = User::getBulkUsersWithUIDs(XDB::fetchColumn('SELECT  user_id
+                                                                            FROM  axletter_rights'));
+                    foreach ($users as $user) {
+                        $mailer->addTo($user);
                     }
                     $mailer->send();
                 }
@@ -276,15 +272,14 @@ class AXLetterModule extends PLModule
 
         try {
             $nl = new AXLetter($nid);
+            $user =& S::user();
             if (Get::has('text')) {
-                $nl->toText($page, S::v('prenom'), S::v('nom'), S::v('femme'));
+                $nl->toText($page, $user);
             } else {
-                $nl->toHtml($page, S::v('prenom'), S::v('nom'), S::v('femme'));
+                $nl->toHtml($page, $user);
             }
             if (Post::has('send')) {
-                $nl->sendTo(S::user()->login(), S::user()->bestEmail(),
-                            S::v('prenom'), S::v('nom'),
-                            S::v('femme'), S::v('mail_fmt') != 'texte');
+                $nl->sendTo($user);
             }
         } catch (MailNotFound $e) {
             return PL_NOT_FOUND;
@@ -318,11 +313,8 @@ class AXLetterModule extends PLModule
         }
 
         $page->changeTpl('axletter/admin.tpl');
-        $res = XDB::iterator("SELECT IF(u.nom_usage != '', u.nom_usage, u.nom) AS nom,
-                                     u.prenom, u.promo, u.hruid
-                                FROM axletter_rights AS ar
-                          INNER JOIN auth_user_md5   AS u USING(user_id)");
-        $page->assign('admins', $res);
+        $page->assign('admins', User::getBulkUsersWithUIDs(XDB::fetchColumn('SELECT  user_id
+                                                                               FROM  axletter_rights')));
 
         $importer = new CSVImporter('axletter_ins');
         $importer->registerFunction('user_id', 'email vers Id X.org', array($this, 'idFromMail'));
@@ -343,36 +335,9 @@ class AXLetterModule extends PLModule
                 }
             }
         }
-        $email = $line[$field];
-        if (strpos($email, '@') === false) {
-            $user  = $email;
-            $domain = $globals->mail->domain2;
-        } else {
-            list($user, $domain) = explode('@', $email);
-        }
-        if ($domain != $globals->mail->domain && $domain != $globals->mail->domain2
-                && $domain != $globals->mail->alias_dom && $domain != $globals->mail->alias_dom2) {
-            $res = XDB::query("SELECT uid FROM emails WHERE email = {?}", $email);
-            if ($res->numRows() == 1) {
-                return $res->fetchOneCell();
-            }
-            return '0';
-        }
-        list($user) = explode('+', $user);
-        list($user) = explode('_', $user);
-        if ($domain == $globals->mail->alias_dom || $domain == $globals->mail->alias_dom2) {
-            $res = XDB::query("SELECT a.id
-                                 FROM virtual          AS v
-                           INNER JOIN virtual_redirect AS r USING(vid)
-                           INNER JOIN aliases          AS a ON (a.type = 'a_vie'
-                                                            AND r.redirect = CONCAT(a.alias, '@{$globals->mail->domain2}'))
-                                WHERE v.alias = CONCAT({?}, '@{$globals->mail->alias_dom}')", $user);
-            $id = $res->fetchOneCell();
-            return $id ? $id : '0';
-        }
-        $res = XDB::query("SELECT id FROM aliases WHERE alias = {?}", $user);
-        $id = $res->fetchOneCell();
-        return $id ? $id : '0';
+        $uf = new UserFilter(new UFC_Email($line[$field]));
+        $id = $uf->getUIDs();
+        return count($id) == 1 ? $id[0] : 0;
     }
 
     function createHash($line, $key, $relation)
index e238c41..d13985e 100644 (file)
@@ -100,26 +100,6 @@ class AXLetter extends MassMailer
                        WHERE  id={?}", $this->_id);
     }
 
-    protected function getAllRecipients()
-    {
-        global $globals;
-        return "SELECT  ni.user_id, IF(ni.user_id = 0, NULL, u.hruid) AS hruid,
-                        IF(ni.user_id = 0, ni.email, CONCAT(a.alias, '@{$globals->mail->domain}')) AS alias,
-                        IF(ni.user_id = 0, ni.prenom, u.prenom) AS prenom,
-                        IF(ni.user_id = 0, ni.nom, IF(u.nom_usage='', u.nom, u.nom_usage)) AS nom,
-                        FIND_IN_SET('femme', IF(ni.user_id = 0, ni.flag, u.flags)) AS sexe,
-                        IF(ni.user_id = 0, 'html', q.core_mail_fmt) AS pref,
-                        IF(ni.user_id = 0, ni.hash, 0) AS hash
-                  FROM  axletter_ins  AS ni
-             LEFT JOIN  auth_user_md5   AS u  USING(user_id)
-             LEFT JOIN  auth_user_quick AS q  ON(q.user_id = u.user_id)
-             LEFT JOIN  aliases         AS a  ON(u.user_id=a.id AND FIND_IN_SET('bestalias',a.flags))
-             LEFT JOIN  emails          AS e  ON(e.uid=u.user_id AND e.flags='active')
-                 WHERE  ni.last < {?} AND {$this->subscriptionWhere()}
-                        AND (e.email IS NOT NULL OR FIND_IN_SET('googleapps', u.mail_storage) OR ni.user_id = 0)
-              GROUP BY  u.user_id";
-    }
-
     static public function subscriptionState($uid = null)
     {
         $user = is_null($uid) ? S::v('uid') : $uid;
index 5ac29ba..f3b1ebd 100644 (file)
@@ -39,11 +39,11 @@ class CarnetModule extends PLModule
 
     function _add_rss_link(&$page)
     {
-        if (!S::has('core_rss_hash')) {
+        if (!S::hasAuthToken()) {
             return;
         }
         $page->setRssLink('Polytechnique.org :: Carnet',
-                          '/carnet/rss/'.S::v('hruid').'/'.S::v('core_rss_hash').'/rss.xml');
+                          '/carnet/rss/'.S::v('hruid').'/'.S::v('token').'/rss.xml');
     }
 
     function handler_index(&$page)
@@ -58,104 +58,195 @@ class CarnetModule extends PLModule
         $page->changeTpl('carnet/panel.tpl');
 
         if (Get::has('read')) {
-            S::set('watch_last', Get::v('read'));
+            XDB::execute('UPDATE  watch
+                             SET  last = FROM_UNIXTIME({?})
+                           WHERE  uid = {?}',
+                         Get::i('read'), S::i('uid'));
+            S::set('watch_last', Get::i('read'));
             Platal::session()->updateNbNotifs();
             pl_redirect('carnet/panel');
         }
 
         require_once 'notifs.inc.php';
+        $page->assign('now', time());
 
-        $page->assign('now',date('YmdHis'));
-        $notifs = new Notifs(S::v('uid'), true);
-
+        $user = S::user();
+        $notifs = Watch::getEvents($user, time() - (7 * 86400));
         $page->assign('notifs', $notifs);
         $page->assign('today', date('Y-m-d'));
         $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) . ')');
+    }
 
-        $watch = new Watch(S::v('uid'));
+    public function addNonRegistered(PlPage &$page, PlUser &$user)
+    {
+        XDB::execute('INSERT IGNORE INTO  watch_nonins (uid, ni_id)
+                                  VALUES  ({?}, {?})', 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 delNonRegistered(PlPage &$page, PlUser &$user)
+    {
+        XDB::execute('DELETE FROM  watch_nonins
+                            WHERE  uid = {?} AND ni_id = {?}',
+                    S::i('uid'), $user->id());
+    }
+
+    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)
@@ -163,12 +254,12 @@ class CarnetModule extends PLModule
         $page->setTitle('Mes contacts');
         $this->_add_rss_link($page);
 
-        $uid  = S::v('uid');
+        $uid  = S::i('uid');
         $user = Env::v('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::v('core_rss_hash')) {
+        if (Env::v('action') && Env::v('token') !== S::v('token')) {
             S::assert_xsrf_token();
         }
         switch (Env::v('action')) {
@@ -193,14 +284,13 @@ class CarnetModule extends PLModule
                 break;
         }
 
-        $search = false;
+/*        $search = false;
         if ($action == 'search') {
             $action = $subaction;
             $subaction = $ssaction;
             $search = true;
         }
         if ($search && trim(Env::v('quick'))) {
-            require_once 'userset.inc.php';
             $base = 'carnet/contacts/search';
 
             Platal::load('search', 'classes.inc.php');
@@ -209,14 +299,18 @@ class CarnetModule extends PLModule
         } else {
             $base = 'carnet/contacts';
             $view = new UserSet("INNER JOIN contacts AS c2 ON (u.user_id = c2.contact)", " c2.uid = $uid ");
-        }
+        }*/
+
+        require_once 'userset.inc.php';
+        $user = S::user();
+        $view = new UserSet(new UFC_Contact($user));
         $view->addMod('minifiche', 'Mini-fiches', true);
         $view->addMod('trombi', 'Trombinoscope', false, array('with_admin' => false, 'with_promo' => true));
         $view->addMod('geoloc', 'Planisphère', false, array('with_annu' => 'carnet/contacts/search'));
-        $view->apply($base, $page, $action, $subaction);
-        if ($action != 'geoloc' || ($search && !$ssaction) || (!$search && !$subaction)) {
-            $page->changeTpl('carnet/mescontacts.tpl');
-        }
+        $view->apply('carnet/contacts', $page, $action, $subaction);
+        //if ($action != 'geoloc' || ($search && !$ssaction) || (!$search && !$subaction)) {
+        $page->changeTpl('carnet/mescontacts.tpl');
+        //}
     }
 
     function handler_pdf(&$page, $arg0 = null, $arg1 = null)
@@ -263,16 +357,13 @@ class CarnetModule extends PLModule
 
     function handler_ical(&$page, $alias = null, $hash = null)
     {
-        require_once 'rss.inc.php';
-        $uid = init_rss(null, $alias, $hash, false);
-        if (S::logged()) {
-            if (!$uid) {
-                $uid = S::i('uid');
-            } else if ($uid != S::i('uid')) {
-                send_warning_email("Récupération d\'un autre utilisateur ($uid)");
+        $user = Platal::session()->tokenAuth($alias, $hash);
+        if (is_null($user)) {
+            if (S::logged()) {
+                $user == S::user();
+            } else {
+                return PL_FORBIDDEN;
             }
-        } else if (!$uid) {
-            exit;
         }
 
         require_once 'ical.inc.php';
@@ -290,7 +381,7 @@ class CarnetModule extends PLModule
                    FROM contacts      AS c
              INNER JOIN auth_user_md5 AS u ON (u.user_id = c.contact)
              INNER JOIN aliases       AS a ON (u.user_id = a.id AND a.type = \'a_vie\')
-                  WHERE c.uid = {?}', $uid);
+                  WHERE c.uid = {?}', $user->id());
 
         $annivs = Array();
         while (list($prenom, $nom, $promo, $naissance, $end, $ts, $hruid) = $res->next()) {
index 3172b4a..2f1a926 100644 (file)
  ***************************************************************************/
 
 require_once 'notifs.inc.php';
+@require_once 'Date.php';
 
 class CarnetFeedIterator implements PlIterator
 {
     private $notifs;
     private $it;
 
-    public function __construct(Notifs& $notifs)
+    public function __construct(PlUser &$owner)
     {
-        $this->notifs =& $notifs;
-        $this->it = PlIteratorUtils::fromArray($notifs->_data, 3);
+        $notifs = Watch::getEvents($owner);
+        $infos  = array();
+        foreach ($notifs as $n) {
+            foreach ($n['users'] as $user) {
+                $op   = $n['operation'];
+                $date = $op->getDate($user);
+                @$datetext = new Date($date);
+                @$datetext = $datetext->format('%e %B %Y');
+                $infos[] = array('operation'   => $op,
+                                 'title'       => '[' . $op->getTitle(1) . ']  - ' . $user->fullName() . ' le ' . $datetext,
+                                 'author'      => $user->fullName(),
+                                 'publication' => $op->publicationDate($user),
+                                 'date'        => strtotime($date),
+                                 'id'          => $op->flag . '-' . $user->id() . '-' . strtotime($date),
+                                 'data'        => $op->getData($user),
+                                 'hruid'       => $user->login(),
+                                 'dead'        => $user->deathdate,
+                                 'profile'     => $user->profile()->hrid(),
+                                 'user'        => $user,
+                                 'contact'     => $owner->isContact($user));
+            }
+        }
+        $this->it = PlIteratorUtils::fromArray($infos);
     }
 
     public function next()
     {
         $data = $this->it->next();
-        if (is_null($data)) {
-            return null;
-        }
-        $cid  = $data['keys'][0];
-        $x    = $data['value'];
-
-        global $globals;
-        @require_once 'Date.php';
-        @$date = new Date($x['date']);
-        @$date = $date->format('%e %B %Y');
-        $author = $x['prenom'] . ' ' . $x['nom'] . ' (X' . $x['promo'] . ')';
-        return array_merge($x, 
-                    array('author' => $author,
-                          'publication' => $x['known'],
-                          'id' => 'carnet' . $x['known'] . $cid . $x['bestalias'],
-                          'link' => $globals->baseurl . '/profile/private/'
-                                    . $x['bestalias'],
-                          'title' => '[' . $this->notifs->_cats[$cid]['short'] . '] '
-                                     . $author . ' - le ' . $date));
+        return $data['value'];
     }
 
     public function total()
@@ -86,7 +90,7 @@ class CarnetFeed extends PlFeed
 
     protected function fetch(PlUser &$user)
     {
-        return new CarnetFeedIterator(new Notifs($user->id(), false));
+        return new CarnetFeedIterator($user);
     }
 }
 
index 787bbae..b7a2fa6 100644 (file)
@@ -129,25 +129,12 @@ class EmailModule extends PLModule
                        FROM  virtual
                  INNER JOIN  virtual_redirect USING (vid)
                       WHERE  alias = {?} AND (redirect = {?} OR redirect = {?})",
-                    $value, $user->forlifeEmail(),
-                    // TODO: remove this über-ugly hack. The issue is that you need
-                    // to remove all @m4x.org addresses in virtual_redirect first.
-                    $user->login() . '@' . $globals->mail->domain2);
+                    $value, $user->forlifeEmail(), $user->m4xForlifeEmail());
         }
 
         // Fetch existing @alias_dom aliases.
-        $res = XDB::query(
-                "SELECT  alias, emails_alias_pub
-                   FROM  auth_user_quick, virtual
-             INNER JOIN  virtual_redirect USING(vid)
-                  WHERE  (redirect = {?} OR redirect = {?})
-                         AND alias LIKE '%@{$globals->mail->alias_dom}' AND user_id = {?}",
-                $user->forlifeEmail(),
-                // TODO: remove this über-ugly hack. The issue is that you need
-                // to remove all @m4x.org addresses in virtual_redirect first.
-                $user->login() . '@' . $globals->mail->domain2, $user->id());
-        list($alias, $visibility) = $res->fetchOneRow();
-        $page->assign('actuel', $alias);
+        $alias = $user->emailAlias();
+        $visibility = $user->hasProfile() && $user->profile()->alias_pub;
 
         if ($action == 'ask' && Env::has('alias') && Env::has('raison')) {
             S::assert_xsrf_token();
@@ -155,7 +142,7 @@ class EmailModule extends PLModule
             //Si l'utilisateur vient de faire une damande
             $alias  = Env::v('alias');
             $raison = Env::v('raison');
-            $public = (Env::v('public', 'off') == 'on')?"public":"private";
+            $public = (Env::v('public', 'off') == 'on') ? 'public' : 'private';
 
             $page->assign('r_alias', $alias);
             $page->assign('r_raison', $raison);
@@ -164,27 +151,31 @@ class EmailModule extends PLModule
             }
 
             //Quelques vérifications sur l'alias (caractères spéciaux)
-            if (!preg_match( "/^[a-zA-Z0-9\-.]{3,20}$/", $alias)) {
+            if (!preg_match("/^[a-zA-Z0-9\-.]{3,20}$/", $alias)) {
                 $page->trigError("L'adresse demandée n'est pas valide."
                             . " Vérifie qu'elle comporte entre 3 et 20 caractères"
                             . " et qu'elle ne contient que des lettres non accentuées,"
                             . " des chiffres ou les caractères - et .");
                 return;
             } else {
+                $alias_mail = $alias.'@'.$globals->mail->alias_dom;
+
                 //vérifier que l'alias n'est pas déja pris
-                $res = XDB::query('SELECT COUNT(*) FROM virtual WHERE alias={?}',
-                                            $alias.'@'.$globals->mail->alias_dom);
+                $res = XDB::query('SELECT  COUNT(*)
+                                     FROM  virtual
+                                    WHERE  alias={?}',
+                                  $alias_mail);
                 if ($res->fetchOneCell() > 0) {
-                    $page->trigError("L'alias $alias@{$globals->mail->alias_dom} a déja été attribué.
-                                Tu ne peux donc pas l'obtenir.");
+                    $page->trigError("L'alias $alias_mail a déja été attribué.
+                                      Tu ne peux donc pas l'obtenir.");
                     return;
                 }
 
                 //vérifier que l'alias n'est pas déja en demande
-                $it = new ValidateIterator ();
+                $it = new ValidateIterator();
                 while($req = $it->next()) {
-                    if ($req->type == "alias" and $req->alias == $alias . '@' . $globals->mail->alias_dom) {
-                        $page->trigError("L'alias $alias@{$globals->mail->alias_dom} a déja été demandé.
+                    if ($req->type == 'alias' and $req->alias == $alias_mail) {
+                        $page->trigError("L'alias $alias_mail a déja été demandé.
                                     Tu ne peux donc pas l'obtenir pour l'instant.");
                         return ;
                     }
@@ -201,18 +192,18 @@ class EmailModule extends PLModule
                 return PL_FORBIDDEN;
             }
 
-            if ($value == 'public') {
-                XDB::execute("UPDATE auth_user_quick SET emails_alias_pub = 'public'
-                                         WHERE user_id = {?}", $user->id());
-            } else {
-                XDB::execute("UPDATE auth_user_quick SET emails_alias_pub = 'private'
-                                         WHERE user_id = {?}", $user->id());
+            if ($user->hasProfile()) {
+                XDB::execute("UPDATE  profiles
+                                 SET  alias_pub = {?}
+                               WHERE  pid = {?}", 
+                            $value, $user->profile()->id());
             }
-
-            $visibility = $value;
+            $visibility = ($value == 'public');
         }
 
-        $page->assign('mail_public', ($visibility == 'public'));
+        $page->assign('actuel', $alias);
+        $page->assign('user', $user);
+        $page->assign('mail_public', $visibility);
     }
 
     function handler_redirect(&$page, $action = null, $email = null)
@@ -479,12 +470,12 @@ class EmailModule extends PLModule
         }
 
         $res = XDB::query(
-                "SELECT  u.prenom, u.nom, u.promo, a.alias as forlife
-                   FROM  auth_user_md5 AS u
-             INNER JOIN  contacts      AS c ON (u.user_id = c.contact)
-             INNER JOIN  aliases       AS a ON (u.user_id=a.id AND FIND_IN_SET('bestalias',a.flags))
+                "SELECT  ac.full_name, a.alias as forlife
+                   FROM  accounts      AS ac
+             INNER JOIN  contacts      AS c ON (ac.uid = c.contact)
+             INNER JOIN  aliases       AS a ON (ac.uid = a.id AND FIND_IN_SET('bestalias', a.flags))
                   WHERE  c.uid = {?}
-                 ORDER BY u.nom, u.prenom", S::v('uid'));
+                 ORDER BY ac.full_name", S::i('uid'));
         $page->assign('contacts', $res->fetchAllAssoc());
         $page->assign('maxsize', ini_get('upload_max_filesize') . 'o');
         $page->assign('user', S::user());
@@ -635,36 +626,16 @@ class EmailModule extends PLModule
 
             $email = valide_email($email);
             // vérifications d'usage
-            $sel = XDB::query("SELECT uid FROM emails WHERE email = {?}", $email);
-            if (($uid = $sel->fetchOneCell())) {
-                $dest = User::getSilent($uid);
-
-                // envoi du mail
-                $message = "Bonjour !
-
-Cet email a été généré automatiquement par le service de patte cassée de
-Polytechnique.org car un autre utilisateur, " . S::user()->fullName() . ",
-nous a signalé qu'en t'envoyant un email, il avait reçu un message d'erreur
-indiquant que ton adresse de redirection $email
-ne fonctionnait plus !
-
-Nous te suggérons de vérifier cette adresse, et le cas échéant de mettre
-à jour sur le site <{$globals->baseurl}/emails> tes adresses
-de redirection...
-
-Pour plus de renseignements sur le service de patte cassée, n'hésite pas à
-consulter la page <{$globals->baseurl}/emails/broken>.
-
-
-À bientôt sur Polytechnique.org !
-L'équipe d'administration <support@" . $globals->mail->domain . '>';
-
-                $mail = new PlMailer();
-                $mail->setFrom('"Polytechnique.org" <support@' . $globals->mail->domain . '>');
-                $mail->addTo($dest->bestEmail());
-                $mail->setSubject("Une de tes adresse de redirection Polytechnique.org ne marche plus !!");
-                $mail->setTxtBody($message);
-                $mail->send();
+            $uid = XDB::fetchOneCell("SELECT  uid
+                                        FROM  emails
+                                       WHERE  email = {?}", $email);
+            if ($uid) {
+                $dest = User::getWithUID($uid);
+
+                $mail = new PlMailer('emails/broken-web.mail.tpl');
+                $mail->assign('email', $email);
+                $mail->assign('request', S::user());
+                $mail->sendTo($dest);
                 $page->trigSuccess("Email envoyé !");
             }
         } elseif (Post::has('email')) {
@@ -678,30 +649,27 @@ L'équipe d'administration <support@" . $globals->mail->domain . '>';
                 $page->assign('neuneu', true);
             } else {
                 $page->assign('email',$email);
-                $sel = XDB::query(
-                        "SELECT  e1.uid, e1.panne != 0 AS panne,
-                                 (count(e2.uid) + IF(FIND_IN_SET('googleapps', u.mail_storage), 1, 0)) AS nb_mails,
-                                 u.nom, u.prenom, u.promo, u.hruid
-                           FROM  emails as e1
-                      LEFT JOIN  emails as e2 ON(e1.uid = e2.uid
+                $x = XDB::fetchOneAssoc("SELECT  e1.uid, e1.panne != 0 AS panne,
+                                                 (count(e2.uid) + IF(FIND_IN_SET('googleapps', eo.storage), 1, 0)) AS nb_mails
+                                           FROM  emails as e1
+                                     INNER JOIN  email_options AS eo ON (eo.uid = e1.uid)
+                                      LEFT JOIN  emails as e2 ON(e1.uid = e2.uid
                                                  AND FIND_IN_SET('active', e2.flags)
                                                  AND e1.email != e2.email)
-                     INNER JOIN  auth_user_md5 as u ON(e1.uid = u.user_id)
-                          WHERE  e1.email = {?}
-                       GROUP BY  e1.uid", $email);
-                if ($x = $sel->fetchOneAssoc()) {
+                                          WHERE  e1.email = {?}
+                                       GROUP BY  e1.uid", $email);
+                if ($x) {
                     // on écrit dans la base que l'adresse est cassée
                     if (!$x['panne']) {
-                        XDB::execute("UPDATE emails
-                                         SET panne=NOW(),
-                                             last=NOW(),
-                                             panne_level = 1
-                                       WHERE email = {?}", $email);
+                        XDB::execute("UPDATE  emails
+                                         SET  panne=NOW(), last=NOW(), panne_level = 1
+                                       WHERE  email = {?}", $email);
                     } else {
-                        XDB::execute("UPDATE emails
-                                         SET panne_level = 1
-                                       WHERE email = {?} AND panne_level = 0", $email);
+                        XDB::execute("UPDATE  emails
+                                         SET  panne_level = 1
+                                       WHERE  email = {?} AND panne_level = 0", $email);
                     }
+                    $x['user'] = User::getWithUID($x['uid']);
                     $page->assign_by_ref('x', $x);
                 }
             }
@@ -801,17 +769,20 @@ L'équipe d'administration <support@" . $globals->mail->domain . '>';
             $page->assign('doublon', $props);
         }
     }
+
     function handler_lost(&$page, $action = 'list', $email = null)
     {
         $page->changeTpl('emails/lost.tpl');
 
-        $page->assign('lost_emails', XDB::iterator("
-            SELECT  u.user_id, u.hruid
-              FROM  auth_user_md5 AS u
-         LEFT JOIN  emails        AS e ON (u.user_id = e.uid AND FIND_IN_SET('active', e.flags))
-             WHERE  e.uid IS NULL AND FIND_IN_SET('googleapps', u.mail_storage) = 0 AND
-                    u.deces = 0 AND u.perms IN ('user', 'admin', 'disabled')
-          ORDER BY  u.promo DESC, u.nom, u.prenom"));
+        // TODO: Order by promo.
+        $page->assign('lost_emails',
+                      XDB::iterator("SELECT  a.uid, a.hruid
+                                       FROM  accounts AS a
+                                 INNER JOIN  email_options AS eo ON (eo.uid = a.uid)
+                                  LEFT JOIN  emails   AS e ON (a.uid = e.uid AND FIND_IN_SET('active', e.flags))
+                                      WHERE  e.uid IS NULL AND FIND_IN_SET('googleapps', eo.storage) = 0 AND
+                                             a.state = 'active'
+                                   ORDER BY  a.hruid"));
     }
 }
 
index e49dc70..6cd7771 100644 (file)
@@ -41,9 +41,9 @@ class EventsModule extends PLModule
         global $globals;
         // Add a new special tip when changing plat/al version
         if ($globals->version != S::v('last_version') && is_null($exclude)) {
-            XDB::execute('UPDATE auth_user_quick
+            XDB::execute('UPDATE accounts
                              SET last_version = {?}
-                           WHERE user_id = {?}',
+                           WHERE uid = {?}',
                            $globals->version, S::i('uid'));
             return array('id' => 0,
                          'titre' => 'Bienvenue sur la nouvelle version du site !',
@@ -114,18 +114,19 @@ class EventsModule extends PLModule
         }
 
         // Wishes "Happy birthday" when required
-        $res = XDB::query(
-            'SELECT  MONTH(naissance) = MONTH(NOW())
-                     AND DAYOFMONTH(naissance) = DAYOFMONTH(NOW()) AS is_birthday
-               FROM  auth_user_md5
-              WHERE  user_id = {?}',
-            $user->id());
-        $page->assign('birthday', $res->fetchOneCell());
+        $profile = $user->profile();
+        if (!is_null($profile)) {
+            if ($profile->next_birthday == date('Y-m-d')) {
+                $birthyear = (int)date('Y', strtotime($profile->birthdate));
+                $curyear   = (int)date('Y');
+                $page->assign('birthday', $curyear - $birthyear);
+            }
+        }
 
         // Direct link to the RSS feed, when available.
-        if (S::rssActivated()) {
+        if (S::hasAuthToken()) {
             $page->setRssLink('Polytechnique.org :: News',
-                              '/rss/'.S::v('hruid') .'/'.S::v('core_rss_hash').'/rss.xml');
+                              '/rss/'.S::v('hruid') .'/'.S::v('token').'/rss.xml');
         }
 
         // Hide the read event, and reload the page to get to the next event.
@@ -149,24 +150,23 @@ class EventsModule extends PLModule
 
         // 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();
+
+        $this->load('feed.inc.php');
+        $user = S::user();
+        $body  = EventFeed::nextEvent($it, $user);
         foreach ($cats as $cat) {
             $data = array();
             if (!$body) {
@@ -178,12 +178,13 @@ class EventsModule extends PLModule
                 } else {
                     break;
                 }
-                $body = $it->next();
+                $body = EventFeed::nextEvent($it, $user);
             } while ($body);
             if (!empty($data)) {
                 $array[$cat] = $data;
             }
         }
+
         $page->assign_by_ref('events', $array);
     }
 
@@ -451,16 +452,14 @@ class EventsModule extends PLModule
             }
 
             $pid = ($eid && $action == 'preview') ? $eid : -1;
-            $sql = "SELECT  e.id, e.titre, e.texte,e.id = $pid AS preview,
+            $sql = "SELECT  e.id, e.titre, e.texte,e.id = $pid AS preview, e.user_id,
                             DATE_FORMAT(e.creation_date,'%d/%m/%Y %T') AS creation_date,
                             DATE_FORMAT(e.peremption,'%d/%m/%Y') AS peremption,
                             e.promo_min, e.promo_max,
                             FIND_IN_SET('valide', e.flags) AS fvalide,
                             FIND_IN_SET('archive', e.flags) AS farch,
-                            u.promo, u.nom, u.prenom, u.hruid,
                             FIND_IN_SET('wiki', e.flags) AS wiki
                       FROM  evenements    AS e
-                INNER JOIN  auth_user_md5 AS u ON(e.user_id = u.user_id)
                      WHERE  ".($arch ? "" : "!")."FIND_IN_SET('archive',e.flags)
                   ORDER BY  FIND_IN_SET('valide',e.flags), e.peremption DESC";
             $page->assign('evs', XDB::iterator($sql));
index 6e80063..802725c 100644 (file)
@@ -31,21 +31,35 @@ class EventFeed extends PlFeed
                             'events/rss.tpl');
     }
 
+    public static function nextEvent(PlIterator &$it, PlUser &$user)
+    {
+        while ($body = $it->next()) {
+            $uf = UserFilter::getLegacy($body['promo_min'], $body['promo_max']);
+            if ($uf->checkUser($user)) {
+                return $body;
+            }
+        }
+        return null;
+    }
+
     protected function fetch(PlUser &$user)
     {
         global $globals;
-        return XDB::iterator(
-                'SELECT  e.id, e.titre AS title, e.texte, e.creation_date AS publication, e.post_id, p.attachmime IS NOT NULL AS photo,
-                         CONCAT(u2.prenom, " ", IF(u2.nom_usage = "", u2.nom, u2.nom_usage), " (X", u2.promo, ")") AS author,
-                         FIND_IN_SET(\'wiki\', e.flags) AS wiki,
-                         CONCAT({?}, "/events#newsid", e.id) AS link
-                   FROM  auth_user_md5   AS u
-             INNER JOIN  evenements      AS e ON ( (e.promo_min = 0 || e.promo_min <= u.promo)
-                                                 AND (e.promo_max = 0 || e.promo_max >= u.promo) )
-              LEFT JOIN  evenements_photo AS p ON (p.eid = e.id)
-             INNER JOIN  auth_user_md5   AS u2 ON (u2.user_id = e.user_id)
-                  WHERE  u.user_id = {?} AND FIND_IN_SET("valide", e.flags)
-                                         AND peremption >= NOW()', $globals->baseurl, $user->id());
+        $events = XDB::iterator('SELECT  e.id, e.titre AS title, e.texte, e.creation_date AS publication, e.post_id,
+                                         p.attachmime IS NOT NULL AS photo, FIND_IN_SET(\'wiki\', e.flags) AS wiki,
+                                         e.user_id, e.promo_min, e.promo_max
+                                   FROM  evenements       AS e
+                              LEFT JOIN  evenements_photo AS p ON (p.eid = e.id)
+                                  WHERE  FIND_IN_SET("valide", e.flags) AND peremption >= NOW()');
+        $data = array();
+        while ($e = self::nextEvent($events, $user)) {
+            $author = User::getWithUID($e['user_id']);
+            $promo  = $author->promo();
+            $e['author'] = $author->fullName() . ($promo ? ' (' . $promo . ')' : '');
+            $e['link'] = $globals->baseurl . '/events#newsid' . $e['id'];
+            $data[] = $e;
+        }
+        return PlIteratorUtils::fromArray($data, 1, true);
     }
 }
 
index bccc607..975ac43 100644 (file)
@@ -48,23 +48,17 @@ class ForumsModule extends PLModule
     {
         if (is_null($file)) {
             if (is_null($hash)) {
-                exit;
+                return PL_FORBIDDEN;
             }
             $this->handler_rss($page, null, $group, $alias, $hash);
         }
-        require_once('rss.inc.php');
-        $uid = init_rss(null, $alias, $hash);
-        if (!$uid) {
-            exit;
+        $user = Platal::session()->tokenAuth($alias, $hash);
+        if (is_null($user)) {
+            return PL_FORBIDDEN;
         }
-        $res = XDB::query("SELECT id AS uid, alias AS forlife
-                             FROM aliases
-                            WHERE type = 'a_vie' AND id = {?}", $uid);
-        $row = $res->fetchOneAssoc();
-        $_SESSION = array_merge($row, $_SESSION);
 
         require_once 'banana/forum.inc.php';
-        $banana = new ForumsBanana(S::user(), array('group' => $group, 'action' => 'rss2'));
+        $banana = new ForumsBanana($user, array('group' => $group, 'action' => 'rss2'));
         $banana->run();
         exit;
     }
@@ -73,7 +67,7 @@ class ForumsModule extends PLModule
     {
         $page->setTitle('Administration - Bannissements des forums');
         $page->assign('title', 'Gestion des mises au ban');
-        $table_editor = new PLTableEditor('admin/forums','forums.innd','id_innd');
+        $table_editor = new PLTableEditor('admin/forums','forum_innd','id_innd');
         $table_editor->add_sort_field('priority', true, true);
         $table_editor->describe('read_perm','lecture',true);
         $table_editor->describe('write_perm','écriture',true);
@@ -81,7 +75,6 @@ class ForumsModule extends PLModule
         $table_editor->describe('comment','commentaire',true);
         $table_editor->apply($page, $action, $id);
         $page->changeTpl('forums/admin.tpl');
-        $page->addJsLink('jquery.js');
     }
 
     static function run_banana(&$page, $params = null)
index fac47d1..ab452ab 100644 (file)
@@ -66,7 +66,6 @@ class FusionAxModule extends PLModule
 
         if ($action == 'index') {
             $page->changeTpl('fusionax/import.tpl');
-            $page->addJsLink('jquery.js');
             if (isset($globals->fusionax) && isset($globals->fusionax->LastUpdate)) {
                 $page->assign(
                     'lastimport',
@@ -278,7 +277,6 @@ class FusionAxModule extends PLModule
         $globals = Platal::globals();
         $nbToLink = 100;
 
-        $page->addJsLink('jquery.js');
         $page->assign('xorg_title', 'Polytechnique.org - Fusion - Mise en correspondance simple');
         if ($part == 'missingInAX') {
             // locate all persons from this database that are not in AX's
index e99d031..b02b686 100644 (file)
@@ -31,31 +31,37 @@ class GadgetsModule extends PLModule
         );
     }
 
-    function handler_ig_events_xml(&$page) {
+    function handler_ig_events_xml(&$page)
+    {
         require_once 'gadgets/gadgets.inc.php';
         init_igoogle_xml('gadgets/ig-events.xml.tpl');
     }
 
-    function handler_ig_events(&$page) {
+    function handler_ig_events(&$page)
+    {
         require_once 'gadgets/gadgets.inc.php';
         init_igoogle_html('gadgets/ig-events.tpl', AUTH_COOKIE);
 
-        $events = XDB::iterator(
-            'SELECT  SQL_CALC_FOUND_ROWS
-                     e.id, e.titre, UNIX_TIMESTAMP(e.creation_date) AS creation_date,
-                     IF(u.nom_usage = "", u.nom, u.nom_usage) AS nom, u.prenom, u.promo,
-                     ev.user_id IS NULL AS nonlu
-               FROM  evenements AS e
-         INNER JOIN  auth_user_md5 AS u ON e.user_id = u.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  e.creation_date DESC
-              LIMIT  {?}',
-            S::i('uid'), S::i('promo'), S::i('promo'), 5);
-        $page->assign('events', $events);
+        $events = XDB::iterator('SELECT  SQL_CALC_FOUND_ROWS
+                                         e.id, e.titre, UNIX_TIMESTAMP(e.creation_date) AS creation_date,
+                                         IF(u.nom_usage = "", u.nom, u.nom_usage) AS nom, u.prenom, u.promo,
+                                         ev.user_id IS NULL AS nonlu, e.user_id
+                                   FROM  evenements AS e
+                              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()
+                               ORDER BY  e.creation_date DESC', S::i('uid'));
         $page->assign('event_count', XDB::query("SELECT FOUND_ROWS()")->fetchOneCell());
+
+        Platal::load('events', 'feed.inc.php');
+        $user = S::user();
+        $data = array();
+        while ($e = PlFeed::nextEvent($events, $user)) {
+            $data[] = $e;
+            if (count($data) == 5) {
+                break;
+            }
+        }
+        $page->assign('events', $data);
     }
 
     function handler_ig_search_xml(&$page) {
index 7648c87..b2ec0ab 100644 (file)
@@ -206,12 +206,10 @@ class GoogleAppsModule extends PLModule
                 $account->do_unsuspend();
                 $page->trigSuccess('Le compte est en cours de réactivation.');
             } else if (Post::has('forcesync') && $account->active() && $account->sync_password) {
-                $res = XDB::query("SELECT password FROM auth_user_md5 WHERE user_id = {?}", $user->id());
-                $account->set_password($res->fetchOneCell());
+                $account->set_password($user->password());
                 $page->trigSuccess('Le mot de passe est en cours de synchronisation.');
             } else if (Post::has('sync') && $account->active()) {
-                $res = XDB::query("SELECT password FROM auth_user_md5 WHERE user_id = {?}", $user->id());
-                $account->set_password($res->fetchOneCell());
+                $account->set_password($user->password());
                 $account->set_password_sync(true);
             } else if (Post::has('nosync') && $account->active()) {
                 $account->set_password_sync(false);
index 11c5d3f..7a2584e 100644 (file)
@@ -47,13 +47,16 @@ class ListsModule extends PLModule
         );
     }
 
-    function prepare_client(&$page)
+    function prepare_client(&$page, $user = null)
     {
         global $globals;
 
         $this->load('lists.inc.php');
+        if (is_null($user)) {
+            $user = S::user();
+        }
 
-        $this->client = new MMList(S::v('uid'), S::v('password'));
+        $this->client = new MMList($user);
         return $globals->mail->domain;
     }
 
@@ -436,27 +439,22 @@ class ListsModule extends PLModule
 
     function handler_rss(&$page, $liste = null, $alias = null, $hash = null)
     {
-        require_once('rss.inc.php');
-        $uid = init_rss(null, $alias, $hash);
-        if (!$uid || !$liste) {
-            exit;
+        if (!$liste) {
+            return PL_NOT_FOUND;
+        }
+        $user = Platal::session()->tokenAuth($alias, $hash);
+        if (is_null($user)) {
+            return PL_FORBIDDEN;
         }
 
-        $res = XDB::query("SELECT user_id AS uid, password, alias AS forlife
-                             FROM auth_user_md5 AS u
-                       INNER JOIN aliases       AS a ON (a.id = u.user_id AND a.type = 'a_vie')
-                            WHERE u.user_id = {?}", $uid);
-        $row = $res->fetchOneAssoc();
-        $_SESSION = array_merge($row, $_SESSION);
-
-        $domain = $this->prepare_client($page);
+        $domain = $this->prepare_client($page, $user);
         if (list($det) = $this->client->get_members($liste)) {
             if (substr($liste,0,5) != 'promo' && ($det['ins'] || $det['priv'])
                     && !$det['own'] && ($det['sub'] < 2)) {
                 exit;
             }
             require_once('banana/ml.inc.php');
-            $banana = new MLBanana(S::user(), Array('listname' => $liste, 'domain' => $domain, 'action' => 'rss2'));
+            $banana = new MLBanana($user, Array('listname' => $liste, 'domain' => $domain, 'action' => 'rss2'));
             $banana->run();
         }
         exit;
@@ -911,12 +909,13 @@ class ListsModule extends PLModule
         }
     }
 
-    function handler_admin_all(&$page) {
+    function handler_admin_all(&$page)
+    {
         $page->changeTpl('lists/admin_all.tpl');
         $page->setTitle('Administration - Mailing lists');
 
-        $client = new MMList(S::v('uid'), S::v('password'));
-        $listes = $client->get_all_lists();
+        $this->prepare_client($page);
+        $listes = $this->client->get_all_lists();
         $page->assign_by_ref('listes', $listes);
     }
 }
index 2b2af8a..733bb38 100644 (file)
 
 // {{{ function list_sort_owners
 
-function list_sort_owners(&$members, $tri_promo = true) {
+function list_sort_owners(&$members, $tri_promo = true)
+{
     global $globals;
 
     $membres = Array();
 
     foreach($members as $mem) {
-        list($m, $dom) = explode('@', $mem);
-        $info = list_fetch_name($mem);
-        if (!isset($info['uid']) || is_null($info['uid'])) {
+        $user = User::getSilent($mem);
+        if (!$user) {
             $membres[0][] = array('l' => $mem, 'p' => (!$tri_promo ? 'inconnue' : null));
         } else {
-            $uid = $info['uid'];
-            $nom = $info['nom'];
-            $prenom = $info['prenom'];
-            $promo = $info['promo'];
-            $broken = $info['lost'];
+            $uid = $user->id();
+            $nom = $user->fullName(); # XXX: Get a notion of 'last name' here, I want to sort user by lastnames
+            $promo = $user->promo();
+            if (!$promo) {
+                $promo = 'non-X';
+            }
+            $broken = false; # XXX: fill it with the good value if the user has no valid email
             $key = $tri_promo ? ($promo != 'non-X' ? $promo : 0) : strtoupper(@$nom{0});
             if ($tri_promo) {
                 $promo = null;
             }
-            $membres[$key][$nom.$m] = Array('n' => "$prenom $nom", 'l' => $m, 'p' => $promo, 'x' => $uid, 'b' => $broken);
+            $membres[$key][$nom.$m] = Array('n' => $nom, 'l' => $m, 'p' => $promo, 'x' => $uid, 'b' => $broken);
         }
     }
 
@@ -73,44 +75,17 @@ function list_sort_members($members, $tri_promo = true)
 }
 
 // }}}
-// {{{ function list_fetch_names
-
-function list_fetch_name($member)
-{
-    global $globals;
-    list($m, $dom) = explode('@', $member);
-    if ($dom == $globals->mail->domain || $dom == $globals->mail->domain2) {
-        $res = XDB::query('SELECT  u.user_id AS uid, prenom AS prenom, IF(nom_usage="", nom, nom_usage) AS nom,
-                                   promo AS promo,
-                                   (e.uid IS NULL AND FIND_IN_SET("googleapps", u.mail_storage) = 0) AS lost
-                             FROM  auth_user_md5 AS u
-                       INNER JOIN  aliases AS a ON u.user_id = a.id
-                        LEFT JOIN  emails AS e ON (e.flags = "active" AND e.uid = u.user_id)
-                            WHERE  a.alias = {?}
-                         GROUP BY  u.user_id', $m);
-    } else {
-        $res = XDB::query('SELECT m2.uid AS uid,
-                                  IF(m2.origine="X", u.prenom, m1.prenom) AS prenom,
-                                  IF(m2.origine="X", u.nom, m1.nom) AS nom,
-                                  IF(m2.origine="X", u.promo, "non-X") AS promo,
-                                  0 AS lost
-                             FROM groupex.membres AS m1
-                        LEFT JOIN groupex.membres AS m2 ON(m1.email=m2.email AND m2.asso_id={?})
-                        LEFT JOIN auth_user_md5   AS u  ON(m2.origine = "X" AND m2.uid = u.user_id)
-                            WHERE m1.email={?}', $globals->asso('id'), $member);
-    }
-    if ($res->numRows() == 0) {
-        return array('email' => $member);
-    } else {
-        return array_merge(array('email' => $member), $res->fetchOneAssoc());
-    }
-}
 
 function list_fetch_names($members)
 {
     $res = array();
     foreach ($members as $member) {
-        $res[] = list_fetch_name($member);
+        $user = User::getSilent($member);
+        if (!$user) {
+            $res[] = $member;
+        } else {
+            $res[] = $user->fullName();
+        }
     }
     return $res;
 }
index baa5eaa..52294fb 100644 (file)
@@ -41,56 +41,7 @@ class MarketingModule extends PLModule
         $page->changeTpl('marketing/index.tpl');
 
         $page->setTitle('Marketing');
-
-        // Some statistics
-        $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(*) AS count
-                             FROM  register_marketing
-                         GROUP BY  sender = 0');
-        $nbInsMarketNo = $res->fetchAllAssoc();
-        $res = XDB::query('SELECT  COUNT(*)
-                             FROM  register_marketing
-                            WHERE  TO_DAYS(NOW()) - TO_DAYS(last) <= 7');
-        $page->assign('nbInsMarketNoPerso', $nbInsMarketNo[0]['count']);
-        $page->assign('nbInsMarketNoXorg', $nbInsMarketNo[1]['count']);
-        $page->assign('nbInsMarketNoWeek', $res->fetchOneCell());
-
-        $res = XDB::query('SELECT  COUNT(*) AS count
-                             FROM  register_mstats
-                         GROUP BY  sender = 0');
-        $nbInsMarketOk = $res->fetchAllAssoc();
-        $res = XDB::query('SELECT  COUNT(*)
-                             FROM  register_mstats
-                            WHERE  TO_DAYS(NOW()) - TO_DAYS(success) <= 7');
-        $page->assign('nbInsMarketOkPerso', $nbInsMarketOk[0]['count']);
-        $page->assign('nbInsMarketOkXorg', $nbInsMarketOk[1]['count']);
-        $page->assign('nbInsMarketOkWeek', $res->fetchOneCell());
+        $page->trigWarning("Les statistiques sont momentanéement désactivées");
     }
 
     function handler_private(&$page, $hruid = null,
@@ -105,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());
@@ -204,13 +154,15 @@ class MarketingModule extends PLModule
             pl_redirect('emails/redirect');
         }
 
-        $res = XDB::query(
-                "SELECT  u.deces = '0000-00-00' AS alive, e.last,
-                         IF(e.email IS NOT NULL, e.email, IF(FIND_IN_SET('googleapps', u.mail_storage), 'googleapps', NULL)) AS email
-                   FROM  auth_user_md5 AS u
-              LEFT JOIN  emails        AS e ON (e.flags = 'active' AND e.uid = u.user_id)
-                  WHERE  u.user_id = {?}
-               ORDER BY  e.panne_level, e.last", $user->id());
+        $res = XDB::query('SELECT  p.deathdate IS NULL AS alive, e.last,
+                                   IF(e.email IS NOT NULL, e.email,
+                                         IF(FIND_IN_SET(\'googleapps\', eo.storage), \'googleapps\', NULL)) AS email
+                             FROM  email_options AS eo
+                        LEFT JOIN  account_profiles AS ap ON (ap.uid = eo.uid AND FIND_IN_SET(\'owner\', ap.perms))
+                        LEFT JOIN  profiles AS p ON (p.pid = ap.pid)
+                        LEFT JOIN  emails        AS e ON (e.flags = \'active\' AND e.uid = eo.uid)
+                            WHERE  eo.uid = {?}
+                         ORDER BY  e.panne_level, e.last', $user->id());
         if (!$res->numRows()) {
             return PL_NOT_FOUND;
         }
@@ -258,15 +210,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)
@@ -275,16 +223,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.
@@ -318,14 +262,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)
@@ -333,22 +273,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);
         }
     }
 
@@ -357,24 +296,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 ee6447e..c69e216 100644 (file)
@@ -58,20 +58,14 @@ class NewsletterModule extends PLModule
 
         try {
             $nl = new NewsLetter($nid);
+            $user =& S::user();
             if (Get::has('text')) {
-                $nl->toText($page, S::v('prenom'), S::v('nom'), S::v('femme'));
+                $nl->toText($page, $user);
             } else {
-                $nl->toHtml($page, S::v('prenom'), S::v('nom'), S::v('femme'));
+                $nl->toHtml($page, $user);
             }
             if (Post::has('send')) {
-                $res = XDB::query("SELECT  hash
-                                     FROM  newsletter_ins
-                                    WHERE  user_id = {?}",
-                                  S::i('uid'));
-                $nl->sendTo(S::user()->login(), S::user()->bestEmail(),
-                            S::v('prenom'), S::v('nom'),
-                            S::v('femme'), S::v('mail_fmt') != 'texte',
-                            $res->fetchOneCell());
+                $nl->sendTo($user);
             }
         } catch (MailNotFound $e) {
             return PL_NOT_FOUND;
index 8f1cd61..13c853c 100644 (file)
@@ -180,35 +180,31 @@ class PaymentModule extends PLModule
         $montant = "$champ201 $champ202";
 
         /* on extrait les informations sur l'utilisateur */
-        $res = XDB::query("
-            SELECT  a.prenom,a.nom,a.promo,l.alias,FIND_IN_SET('femme', a.flags)
-              FROM  auth_user_md5 AS a
-        INNER JOIN  aliases       AS l ON (a.user_id=l.id AND type!='homonyme')
-             WHERE  a.user_id={?}", $uid);
-        if (!list($prenom,$nom,$promo,$forlife,$femme) = $res->fetchOneRow()) {
+        $user = User::get($uid);
+        if (!$user) {
             cb_erreur("uid invalide");
         }
 
 
         /* on extrait la reference de la commande */
-        if (!ereg('-xorg-([0-9]+)$',$champ200,$matches)) {
+        if (!ereg('-xorg-([0-9]+)$', $champ200, $matches)) {
             cb_erreur("référence de commande invalide");
         }
 
         echo ($ref = $matches[1]);
-        $res = XDB::query("SELECT  mail,text,confirmation
+        $res = XDB::query("SELECT  mail, text, confirmation
                              FROM  paiement.paiements
                             WHERE  id={?}", $ref);
-        if (!list($conf_mail,$conf_title,$conf_text) = $res->fetchOneRow()) {
+        if (!list($conf_mail, $conf_title, $conf_text) = $res->fetchOneRow()) {
             cb_erreur("référence de commande inconnue");
         }
 
         /* on extrait le code de retour */
         if ($champ906 != "0000") {
-            $res = XDB::query("SELECT  rcb.text,c.id,c.text
+            $res = XDB::query('SELECT  rcb.text, c.id, c.text
                                  FROM  paiement.codeRCB AS rcb
-                            LEFT JOIN  paiement.codeC   AS c ON rcb.codeC=c.id
-                                WHERE  rcb.id={?}", $champ906);
+                            LEFT JOIN  paiement.codeC   AS c ON (rcb.codeC = c.id)
+                                WHERE  rcb.id = {?}', $champ906);
             if (list($rcb_text, $c_id, $c_text) = $res->fetchOneRow()) {
                 cb_erreur("erreur lors du paiement : $c_text ($c_id)");
             } else{
@@ -217,35 +213,32 @@ class PaymentModule extends PLModule
         }
 
         /* on fait l'insertion en base de donnees */
-        XDB::execute("INSERT INTO  paiement.transactions (id,uid,ref,fullref,montant,cle,comment)
-                           VALUES  ({?},{?},{?},{?},{?},{?},{?})",
-                     $champ901, $uid, $ref, $champ200, $montant, $champ905,Env::v('comment'));
+        XDB::execute("INSERT INTO  paiement.transactions (id, uid, ref, fullref, montant, cle, comment)
+                           VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?})",
+                     $champ901, $user->id(), $ref, $champ200, $montant, $champ905, Env::v('comment'));
 
         /* on genere le mail de confirmation */
-        $conf_text = str_replace("<prenom>",$prenom,$conf_text);
-        $conf_text = str_replace("<nom>",$nom,$conf_text);
-        $conf_text = str_replace("<promo>",$promo,$conf_text);
-        $conf_text = str_replace("<montant>",$montant,$conf_text);
-        $conf_text = str_replace("<comment>", Env::v('comment'), $conf_text);
-        $conf_text = str_replace("<salutation>",$femme ? "Chère" : "Cher",$conf_text);
-        $conf_text = str_replace("<cher>",$femme ? "Chère" : "Cher",$conf_text);
+        $conf_text = str_replace(
+            array('<prenom>', '<nom>', '<promo>', '<montant>', '<salutation>', '<cher>', 'comment>'),
+            array($user->firstName(), $user->lastName(), $user->promo(), $montant,
+                  $user->isFemale() ? 'Chère' : 'Cher', $user->isFemale() ? 'Chère' : 'Cher',
+                  Env::v('comment')), $conf_text);
 
         global $globals;
         $mymail = new PlMailer();
         $mymail->setFrom($conf_mail);
-        $mymail->addTo("\"$prenom $nom\" <$forlife@" . $globals->mail->domain . '>');
         $mymail->addCc($conf_mail);
         $mymail->setSubject($conf_title);
         $mymail->setWikiBody($conf_text);
-        $mymail->send(S::v('mail_fmt') == 'html');
+        $mymail->sendTo($user);
 
         /* on envoie les details de la transaction à telepaiement@ */
         $mymail = new PlMailer();
         $mymail->setFrom("webmaster@" . $globals->mail->domain);
         $mymail->addTo($globals->money->email);
         $mymail->setSubject($conf_title);
-        $msg = "utilisateur : $prenom $nom ($uid)\n".
-               "mail : $forlife@polytechnique.org\n\n".
+        $msg = 'utilisateur : ' . $user->login() . ' (' . $user->id() . ')' . "\n" .
+               'mail : ' . $user->forlifeEmail() . "\n\n" .
                "paiement : $conf_title ($conf_mail)\n".
                "reference : $champ200\n".
                "montant : $montant\n\n".
@@ -285,59 +278,52 @@ class PaymentModule extends PLModule
         }
 
         /* on extrait les informations sur l'utilisateur */
-        $res = XDB::query("
-            SELECT  a.prenom,a.nom,a.promo,l.alias,FIND_IN_SET('femme', a.flags)
-              FROM  auth_user_md5 AS a
-        INNER JOIN  aliases       AS l ON (a.user_id=l.id AND type!='homonyme')
-             WHERE  a.user_id={?}", $uid);
-        if (!list($prenom,$nom,$promo,$forlife,$femme) = $res->fetchOneRow()) {
+        $user = User::get($uid);
+        if (!$user) {
             paypal_erreur("uid invalide");
         }
 
         /* on extrait la reference de la commande */
-        if (!ereg('-xorg-([0-9]+)$',$fullref,$matches)) {
+        if (!ereg('-xorg-([0-9]+)$', $fullref, $matches)) {
             paypal_erreur("référence de commande invalide");
         }
 
         $ref = $matches[1];
-        $res = XDB::query("SELECT  mail,text,confirmation
+        $res = XDB::query("SELECT  mail, text, confirmation
                              FROM  paiement.paiements
-                            WHERE  id={?}", $ref);
+                            WHERE  id = {?}", $ref);
         if (!list($conf_mail,$conf_title,$conf_text) = $res->fetchOneRow()) {
             paypal_erreur("référence de commande inconnue");
         }
 
         /* on fait l'insertion en base de donnees */
-        XDB::execute("INSERT INTO  paiement.transactions (id,uid,ref,fullref,montant,cle,comment)
-                           VALUES  ({?},{?},{?},{?},{?},{?},{?})",
-                    $no_transaction, $uid, $ref, $fullref, $montant, $clef, Env::v('comment'));
+        XDB::execute("INSERT INTO  paiement.transactions (id, uid, ref, fullref, montant, cle, comment)
+                           VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?})",
+                    $no_transaction, $user->id(), $ref, $fullref, $montant, $clef, Env::v('comment'));
 
         /* on genere le mail de confirmation */
-        $conf_text = str_replace("<prenom>",$prenom,$conf_text);
-        $conf_text = str_replace("<nom>",$nom,$conf_text);
-        $conf_text = str_replace("<promo>",$promo,$conf_text);
-        $conf_text = str_replace("<montant>",$montant,$conf_text);
-        $conf_text = str_replace("<salutation>",$femme ? "Chère" : "Cher",$conf_text);
-        $conf_text = str_replace("<cher>",$femme ? "Chère" : "Cher",$conf_text);
+        $conf_text = str_replace(array('<prenom>', '<nom>', '<promo>', '<montant>', '<salutation>', '<cher>'),
+                                 array($user->firstName(), $user->lastName(), $user->promo(), $montant,
+                                       $user->isFemale() ? 'Chère' : 'Cher',
+                                       $user->isFemale() ? 'Chère' : 'Cher'), $conf_text);
 
         global $globals;
         $mymail = new PlMailer();
         $mymail->setFrom($conf_mail);
-        $mymail->addTo("\"$prenom $nom\" <$forlife@" . $globals->mail->domain . '>');
         $mymail->addCc($conf_mail);
         $mymail->setSubject($conf_title);
         $mymail->setWikiBody($conf_text);
-        $mymail->send(S::v('mail_fmt') == 'html');
+        $mymail->sendTo($user);
 
         /* on envoie les details de la transaction à telepaiement@ */
         $mymail = new PlMailer();
         $mymail->setFrom("webmaster@" . $globals->mail->domain);
         $mymail->addTo($globals->money->email);
         $mymail->setSubject($conf_title);
-        $msg = "utilisateur : $prenom $nom ($uid)\n".
-               "mail : $forlife@polytechnique.org\n\n".
+        $msg = 'utilisateur : ' . $user->login() . ' (' . $user->id() . ')' . "\n" .
+               'mail : ' . $user->forlifeEmail() . "\n\n" .
                "paiement : $conf_title ($conf_mail)\n".
-               "reference : $no_transaction\n".
+               "reference : $champ200\n".
                "montant : $montant\n\n".
                "dump de REQUEST:\n".
                var_export($_REQUEST,true);
@@ -380,58 +366,24 @@ class PaymentModule extends PLModule
         $tit = $res->fetchAllAssoc();
         $page->assign('titres', $tit);
 
-        $order = Env::v('order', 'timestamp');
-        $orders = array('timestamp', 'nom', 'promo', 'montant', 'comment');
-        if (!in_array($order, $orders)) {
-            $order = 'timestamp';
-        } elseif ($order == 'comment') {
-            $order = 't.comment';
-        }
-        $inv_order = Env::v('order_inv', 0);
-        $page->assign('order', $order);
-        $page->assign('order_inv', !$inv_order);
-
-        if ($order == 'timestamp') {
-            $inv_order = !$inv_order;
-        }
-
-        if ($inv_order) {
-            $inv_order = ' DESC';
-        } else {
-            $inv_order = '';
-        }
-        if ($order == 'montant') {
-            $order = 'LENGTH(montant) '.$inv_order.', montant';
-        }
-
-        $orderby = 'ORDER BY '.$order.$inv_order;
-        if ($order != 'nom') {
-            $orderby .= ', nom'; $inv_order = '';
-        }
-        $orderby .= ', prenom'.$inv_order;
-        if ($order != 'timestamp') {
-            $orderby .= ', timestamp DESC';
-        }
 
+        // TODO: replug sort.
         $trans = array();
         $event = array();
         foreach($tit as $foo) {
             $pid = $foo['id'];
             if (may_update()) {
-                $res = XDB::query("SELECT  IF(u.nom_usage<>'', u.nom_usage, u.nom) AS nom,
-                                           u.prenom, u.promo, a.alias, timestamp AS `date`, t.comment, montant
-                                     FROM  {$globals->money->mpay_tprefix}transactions AS t
-                               INNER JOIN  auth_user_md5  AS u ON ( t.uid = u.user_id )
-                               INNER JOIN  aliases        AS a ON ( t.uid = a.id AND a.type='a_vie' )
-                                    WHERE  ref = {?} ".$orderby, $pid);
-                    $trans[$pid] = $res->fetchAllAssoc();
-                    $sum = 0;
-                    foreach ($trans[$pid] as $i => $t) {
-                        $sum += strtr(substr($t['montant'], 0, strpos($t['montant'], 'EUR')), ',', '.');
-                        $trans[$pid][$i]['montant'] = str_replace('EUR', '€', $t['montant']);
-                    }
-                    $trans[$pid][] = array('nom' => 'somme totale',
-                                           'montant' => strtr($sum, '.', ',').' €');
+                $res = XDB::query('SELECT  t.uid, timestamp AS `date`, t.comment, montant
+                                     FROM  ' . $globals->money->mpay_tprefix . 'transactions AS t
+                                    WHERE  t.ref = {?}', $pid);
+                $trans[$pid] = User::getBulkUsersWithUIDs($res->fetchAllAssoc(), 'uid', 'user');
+                $sum = 0;
+                foreach ($trans[$pid] as $i => $t) {
+                    $sum += strtr(substr($t['montant'], 0, strpos($t['montant'], 'EUR')), ',', '.');
+                    $trans[$pid][$i]['montant'] = str_replace('EUR', '€', $t['montant']);
+                }
+                $trans[$pid][] = array('nom' => 'somme totale',
+                                       'montant' => strtr($sum, '.', ',').' €');
             }
             $res = XDB::iterRow("SELECT e.eid, e.short_name, e.intitule, ep.nb, ei.montant, ep.paid
                                    FROM groupex.evenements AS e
index 27c034e..462bae7 100644 (file)
@@ -49,10 +49,8 @@ class CyberPayment
 
         $roboturl = str_replace("https://","http://", $globals->baseurl)
             . '/' . $platal->ns . "payment/cyber_return/".S::v('uid')."?comment=".urlencode(Env::v('comment'))."&CHAMPBPX";
-        $req = XDB::query("SELECT IF(nom_usage!='', nom_usage, nom) AS nom
-                             FROM auth_user_md5
-                            WHERE user_id = {?}",S::v('uid'));
-        $name = $req->fetchOneCell();
+        $user = S::user();
+        $name = $user->lastName();
 
         // on constuit la reference de la transaction
         $prefix = ($pay->flags->hasflag('unique')) ? str_pad("",15,"0") : rand_url_id();
index 08d83f4..231c86d 100644 (file)
@@ -43,10 +43,8 @@ class PayPal
         global $globals, $platal;
 
         $this->urlform = 'https://' . $globals->money->paypal_site . '/cgi-bin/webscr';
-        $req = XDB::query("SELECT  IF(nom_usage!='', nom_usage, nom) AS nom
-                             FROM  auth_user_md5
-                            WHERE  user_id = {?}", S::v('uid'));
-        $name = $req->fetchOneCell();
+        $user = S::user();
+        $name = $user->lastName();
 
         $roboturl = str_replace("https://","http://",$globals->baseurl)
                   . '/' . $platal->ns . "payment/paypal_return/" . S::v('uid')
@@ -71,6 +69,7 @@ class PayPal
             'email'      => S::user()->bestEmail()
         );
 
+        // XXX: waiting for port of adresses.
         $res = XDB::query(
                 "SELECT  a.text, l.name AS city, a.postalCode AS zip, a.countryiId AS country,
                          IF(t1.display_tel != '', t1.display_tel, t2.display_tel) AS night_phone_b
index af0bf35..94a4077 100644 (file)
@@ -69,7 +69,7 @@ class PlatalModule extends PLModule
         if (S::logged()) {
             pl_redirect('events');
         } else if (!@$GLOBALS['IS_XNET_SITE']) {
-            pl_redirect('review');
+            $this->handler_review($page);
         }
     }
 
@@ -86,40 +86,48 @@ class PlatalModule extends PLModule
         exit;
     }
 
-    function handler_changelog(&$page)
+    function handler_changelog(&$page, $core = null)
     {
         $page->changeTpl('platal/changeLog.tpl');
 
-        $clog = pl_entities(file_get_contents(dirname(__FILE__).'/../ChangeLog'));
-        $clog = preg_replace('/===+\s*/', '</pre><hr /><pre>', $clog);
-        // url catch only (not all wiki syntax)
-        $clog = preg_replace(array(
-            '/((?:https?|ftp):\/\/(?:\.*,*[\w@~%$£µ&i#\-+=_\/\?;])*)/ui',
-            '/(\s|^)www\.((?:\.*,*[\w@~%$£µ&i#\-+=_\/\?;])*)/iu',
-            '/(?:mailto:)?([a-z0-9.\-+_]+@([\-.+_]?[a-z0-9])+)/i'),
-          array(
-            '<a href="\\0">\\0</a>',
-            '\\1<a href="http://www.\\2">www.\\2</a>',
-            '<a href="mailto:\\0">\\0</a>'),
-          $clog);
-        $clog = preg_replace('!(#[0-9]+(,[0-9]+)*)!e', 'bugize("\1")', $clog);
-        $clog = preg_replace('!vim:.*$!', '', $clog);
-        $clog = preg_replace("!(<hr />(\\s|\n)*)?<pre>(\s|\n)*</pre>((\\s|\n)*<hr />)?!m", "", "<pre>$clog</pre>");
-        $page->assign('ChangeLog', $clog);
+        function formatChangeLog($file) {
+            $clog = pl_entities(file_get_contents($file));
+            $clog = preg_replace('/===+\s*/', '</pre><hr /><pre>', $clog);
+            // url catch only (not all wiki syntax)
+            $clog = preg_replace(array(
+                '/((?:https?|ftp):\/\/(?:\.*,*[\w@~%$£µ&i#\-+=_\/\?;])*)/ui',
+                '/(\s|^)www\.((?:\.*,*[\w@~%$£µ&i#\-+=_\/\?;])*)/iu',
+                '/(?:mailto:)?([a-z0-9.\-+_]+@([\-.+_]?[a-z0-9])+)/i'),
+              array(
+                '<a href="\\0">\\0</a>',
+                '\\1<a href="http://www.\\2">www.\\2</a>',
+                '<a href="mailto:\\0">\\0</a>'),
+              $clog);
+            $clog = preg_replace('!(#[0-9]+(,[0-9]+)*)!e', 'bugize("\1")', $clog);
+            $clog = preg_replace('!vim:.*$!', '', $clog);
+            return preg_replace("!(<hr />(\\s|\n)*)?<pre>(\s|\n)*</pre>((\\s|\n)*<hr />)?!m", "", "<pre>$clog</pre>");
+        }
+        if ($core != 'core') {
+            $page->assign('core', false);
+            $page->assign('ChangeLog', formatChangeLog(dirname(__FILE__).'/../ChangeLog'));
+        } else {
+            $page->assign('core', true);
+            $page->assign('ChangeLog', formatChangeLog(dirname(__FILE__).'/../core/ChangeLog'));
+        }
     }
 
     function __set_rss_state($state)
     {
         if ($state) {
-            $_SESSION['core_rss_hash'] = rand_url_id(16);
-            XDB::execute('UPDATE  auth_user_quick
-                                   SET  core_rss_hash={?} WHERE user_id={?}',
-                                   S::v('core_rss_hash'), S::v('uid'));
+            S::set('token', rand_url_id(16));
+            XDB::execute('UPDATE  accounts
+                             SET  token = {?}
+                           WHERE  uid = {?}', S::s('token'), S::i('uid'));
         } else {
-            XDB::execute('UPDATE  auth_user_quick
-                                   SET  core_rss_hash="" WHERE user_id={?}',
-                                   S::v('uid'));
-            S::kill('core_rss_hash');
+            S::kill('token');
+            XDB::execute('UPDATE  accounts
+                             SET  token = NULL
+                           WHERE  uid = {?}', S::i('uid'));
         }
     }
 
@@ -128,14 +136,13 @@ class PlatalModule extends PLModule
         $page->changeTpl('platal/preferences.tpl');
         $page->setTitle('Mes préférences');
 
-        if (Post::has('mail_fmt')) {
-            $fmt = Post::v('mail_fmt');
-            if ($fmt != 'texte') $fmt = 'html';
-            XDB::execute("UPDATE auth_user_quick
-                                       SET core_mail_fmt = '$fmt'
-                                     WHERE user_id = {?}",
-                                     S::v('uid'));
-            $_SESSION['mail_fmt'] = $fmt;
+        if (Post::has('email_format')) {
+            $fmt = Post::s('email_format');
+            XDB::execute("UPDATE accounts
+                             SET email_format = {?}
+                           WHERE uid = {?}",
+                         $fmt, S::v('uid'));
+            S::set('email_format', $fmt);
         }
 
         if (Post::has('rss')) {
@@ -154,33 +161,31 @@ class PlatalModule extends PLModule
     function handler_webredir(&$page)
     {
         $page->changeTpl('platal/webredirect.tpl');
-
         $page->setTitle('Redirection de page WEB');
 
-        $log =& S::v('log');
-        $url = Env::v('url');
-
-        if (Env::v('submit') == 'Valider' and Env::has('url')) {
-            XDB::execute('UPDATE auth_user_quick
-                                       SET redirecturl = {?} WHERE user_id = {?}',
-                                   $url, S::v('uid'));
-            S::logger()->log('carva_add', 'http://'.Env::v('url'));
-            $page->trigSuccess("Redirection activée vers <a href='http://$url'>$url</a>");
-        } elseif (Env::v('submit') == "Supprimer") {
-            XDB::execute("UPDATE auth_user_quick
-                                       SET redirecturl = ''
-                                     WHERE user_id = {?}",
-                                   S::v('uid'));
-            S::logger()->log("carva_del", $url);
+        if (Env::v('submit') == 'Valider' && !Env::blank('url')) {
+            if (Env::blank('url')) {
+                $page->trigError('URL invalide');
+            } else {
+                $url = Env::t('url');
+                XDB::execute('REPLACE INTO  carvas (uid, url)
+                                    VALUES  ({?}, {?})',
+                             S::i('uid'), $url);
+                S::logger()->log('carva_add', 'http://' . $url);
+                $page->trigSuccess("Redirection activée vers <a href='http://$url'>$url</a>");
+            }
+        } elseif (Env::v('submit') == 'Supprimer') {
+            XDB::execute('DELETE FROM carvas
+                                WHERE uid = {?}', S::i('uid'));
             Post::kill('url');
+            S::logger()->log('carva_del');
             $page->trigSuccess('Redirection supprimée');
         }
 
-        $res = XDB::query('SELECT redirecturl
-                                       FROM auth_user_quick
-                                      WHERE user_id = {?}',
-                                    S::v('uid'));
-        $page->assign('carva', $res->fetchOneCell());
+        $url = XDB::fetchOneCell('SELECT  url
+                                    FROM  carvas
+                                   WHERE  uid = {?}', S::i('uid'));
+        $page->assign('carva', $url);
 
         # FIXME: this code is not multi-domain compatible. We should decide how
         # carva will extend to users not in the main domain.
@@ -208,15 +213,13 @@ class PlatalModule extends PLModule
         global $globals;
 
         if (Post::has('response2'))  {
-            require_once 'secure_hash.inc.php';
             S::assert_xsrf_token();
 
-            $_SESSION['password'] = $password = Post::v('response2');
-
-            XDB::execute('UPDATE  auth_user_md5
-                             SET  password={?}
-                           WHERE  user_id={?}', $password,
-                           S::v('uid'));
+            S::set('password', $password = Post::v('response2'));
+            XDB::execute('UPDATE  accounts
+                             SET  password = {?}
+                           WHERE  uid={?}', $password,
+                         S::i('uid'));
 
             // If GoogleApps is enabled, and the user did choose to use synchronized passwords,
             // updates the Google Apps password as well.
@@ -250,27 +253,27 @@ class PlatalModule extends PLModule
         $wp = new PlWikiPage('Xorg.NNTPSécurisé');
         $wp->buildCache();
 
-        $uid  = S::v('uid');
+        $uid  = S::i('uid');
         $pass = Env::v('smtppass1');
-        $log  = S::v('log');
 
         if (Env::v('op') == "Valider" && strlen($pass) >= 6
-        &&  Env::v('smtppass1') == Env::v('smtppass2'))
-        {
-            XDB::execute('UPDATE auth_user_md5 SET smtppass = {?}
-                                     WHERE user_id = {?}', $pass, $uid);
+            &&  Env::v('smtppass1') == Env::v('smtppass2')) {
+            XDB::execute('UPDATE  accounts
+                             SET  weak_password = {?}
+                           WHERE  uid = {?}', $pass, $uid);
             $page->trigSuccess('Mot de passe enregistré');
             S::logger()->log("passwd_ssl");
         } elseif (Env::v('op') == "Supprimer") {
-            XDB::execute('UPDATE auth_user_md5 SET smtppass = ""
-                                     WHERE user_id = {?}', $uid);
+            XDB::execute('UPDATE  accounts
+                             SET  weak_password = NULL
+                           WHERE  uid = {?}', $uid);
             $page->trigSuccess('Compte SMTP et NNTP supprimé');
             S::logger()->log("passwd_del");
         }
 
-        $res = XDB::query("SELECT IF(smtppass != '', 'actif', '')
-                                       FROM auth_user_md5
-                                      WHERE user_id = {?}", $uid);
+        $res = XDB::query("SELECT  weak_password IS NOT NULL
+                             FROM  accounts
+                            WHERE  uid = {?}", $uid);
         $page->assign('actif', $res->fetchOneCell());
     }
 
@@ -296,48 +299,50 @@ class PlatalModule extends PLModule
 
         $mailorg = strtok(Env::v('login'), '@');
 
-        // paragraphe rajouté : si la date de naissance dans la base n'existe pas, on l'update
-        // avec celle fournie ici en espérant que c'est la bonne
-
-        $res = XDB::query(
-                "SELECT  user_id, naissance
-                   FROM  auth_user_md5 AS u
-             INNER JOIN  aliases       AS a ON (u.user_id=a.id AND type != 'homonyme')
-                  WHERE  a.alias={?} AND u.perms IN ('admin','user') AND u.deces=0", $mailorg);
-        list($uid, $naissance) = $res->fetchOneRow();
-
-        if ($naissance == $birth) {
-            $res = XDB::query("SELECT  COUNT(*)
-                                 FROM  emails
-                                WHERE  uid = {?} AND flags != 'panne' AND flags != 'filter'", $uid);
-            $count = intval($res->fetchOneCell());
-            if ($count == 0) {
-                $page->assign('no_addr', true);
-                return;
-            }
+        $profile = Profile::get(Env::t('login'));
+        if (is_null($profile) || $profile->birthdate != $birth) {
+            $page->trigError('Les informations que tu as rentrées ne permettent pas de récupérer ton mot de passe.<br />'.
+                        'Si tu as un homonyme, utilise prenom.nom.promo comme login');
+            return;
+        }
 
-            $page->assign('ok', true);
+        $user = $profile->owner();
+        if ($user->state != 'active') {
+            $page->trigError('Ton compte n\'est pas activé.');
+            return;
+        }
+
+        $res = XDB::query("SELECT  COUNT(*)
+                             FROM  emails
+                            WHERE  uid = {?} AND flags != 'panne' AND flags != 'filter'", $user->id());
+        $count = intval($res->fetchOneCell());
+        if ($count == 0) {
+            $page->assign('no_addr', true);
+            return;
+        }
 
-            $url   = rand_url_id();
-            XDB::execute('INSERT INTO  perte_pass (certificat,uid,created)
-                               VALUES  ({?},{?},NOW())', $url, $uid);
+        $page->assign('ok', true);
+
+        $url   = rand_url_id();
+        XDB::execute('INSERT INTO  perte_pass (certificat,uid,created)
+                           VALUES  ({?},{?},NOW())', $url, $user->id());
+        $res   = XDB::query('SELECT  email
+                               FROM  emails
+                              WHERE  uid = {?} AND email = {?}',
+                            $user->id(), Post::v('email'));
+        if ($res->numRows()) {
+            $mails = $res->fetchOneCell();
+        } else {
             $res   = XDB::query('SELECT  email
                                    FROM  emails
-                                  WHERE  uid = {?} AND email = {?}',
-                                $uid, Post::v('email'));
-            if ($res->numRows()) {
-                $mails = $res->fetchOneCell();
-            } else {
-                $res   = XDB::query('SELECT  email
-                                       FROM  emails
-                                      WHERE  uid = {?} AND NOT FIND_IN_SET("filter", flags)', $uid);
-                $mails = implode(', ', $res->fetchColumn());
-            }
-            $mymail = new PlMailer();
-            $mymail->setFrom('"Gestion des mots de passe" <support+password@' . $globals->mail->domain . '>');
-            $mymail->addTo($mails);
-            $mymail->setSubject('Ton certificat d\'authentification');
-            $mymail->setTxtBody("Visite la page suivante qui expire dans six heures :
+                                  WHERE  uid = {?} AND NOT FIND_IN_SET("filter", flags)', $user->id());
+            $mails = implode(', ', $res->fetchColumn());
+        }
+        $mymail = new PlMailer();
+        $mymail->setFrom('"Gestion des mots de passe" <support+password@' . $globals->mail->domain . '>');
+        $mymail->addTo($mails);
+        $mymail->setSubject('Ton certificat d\'authentification');
+        $mymail->setTxtBody("Visite la page suivante qui expire dans six heures :
 {$globals->baseurl}/tmpPWD/$url
 
 Si en cliquant dessus tu n'y arrives pas, copie intégralement l'adresse dans la barre de ton navigateur. Si tu n'as pas utilisé ce lien dans six heures, tu peux tout simplement recommencer cette procédure.
@@ -348,23 +353,21 @@ Polytechnique.org
 
 Email envoyé à ".Env::v('login') . (Post::has('email') ? "
 Adresse de secours : " . Post::v('email') : ""));
-            $mymail->send();
+        $mymail->send();
 
-            // on cree un objet logger et on log l'evenement
-            S::logger(uid)->log('recovery', $mails);
-        } else {
-            $page->trigError('Les informations que tu as rentrées ne permettent pas de récupérer ton mot de passe.<br />'.
-                        'Si tu as un homonyme, utilise prenom.nom.promo comme login');
-        }
+        // on cree un objet logger et on log l'evenement
+        S::logger($user->id())->log('recovery', $mails);
     }
 
     function handler_tmpPWD(&$page, $certif = null)
     {
         global $globals;
-        XDB::execute('DELETE FROM perte_pass
-                                      WHERE DATE_SUB(NOW(), INTERVAL 380 MINUTE) > created');
+        // XXX: recovery requires data from the profile
+        XDB::execute('DELETE FROM  perte_pass
+                            WHERE  DATE_SUB(NOW(), INTERVAL 380 MINUTE) > created');
 
-        $res   = XDB::query('SELECT uid FROM perte_pass WHERE certificat={?}', $certif);
+        $res = XDB::query('SELECT  uid
+                             FROM  perte_pass WHERE certificat={?}', $certif);
         $ligne = $res->fetchOneAssoc();
         if (!$ligne) {
             $page->changeTpl('platal/index.tpl');
@@ -374,10 +377,12 @@ Adresse de secours : " . Post::v('email') : ""));
         $uid = $ligne["uid"];
         if (Post::has('response2')) {
             $password = Post::v('response2');
-            XDB::query('UPDATE  auth_user_md5 SET password={?}
-                                   WHERE  user_id={?} AND perms IN("admin","user")',
-                                 $password, $uid);
-            XDB::query('DELETE FROM perte_pass WHERE certificat={?}', $certif);
+            XDB::query('UPDATE  accounts
+                           SET  password={?}
+                         WHERE  uid = {?} AND state = \'active\'',
+                       $password, $uid);
+            XDB::query('DELETE FROM  perte_pass
+                              WHERE  certificat={?}', $certif);
 
             // If GoogleApps is enabled, and the user did choose to use synchronized passwords,
             // updates the Google Apps password as well.
@@ -405,30 +410,31 @@ Adresse de secours : " . Post::v('email') : ""));
         $page->setTitle('Skins');
 
         if (Env::has('newskin'))  {  // formulaire soumis, traitons les données envoyées
-            XDB::execute('UPDATE auth_user_quick
-                             SET skin={?} WHERE user_id={?}',
-                         Env::i('newskin'), S::v('uid'));
+            XDB::execute('UPDATE  accounts
+                             SET  skin = {?}
+                           WHERE  uid = {?}',
+                         Env::i('newskin'), S::i('uid'));
             S::kill('skin');
             Platal::session()->setSkin();
         }
 
-        $res = XDB::query('SELECT id FROM skins WHERE skin_tpl={?}', S::v('skin'));
+        $res = XDB::query('SELECT  id
+                             FROM  skins
+                            WHERE  skin_tpl = {?}', S::v('skin'));
         $page->assign('skin_id', $res->fetchOneCell());
 
-        $sql = "SELECT s.*,auteur,count(*) AS nb
-                  FROM skins AS s
-             LEFT JOIN auth_user_quick AS a ON s.id=a.skin
-                 WHERE skin_tpl != '' AND ext != ''
-              GROUP BY id ORDER BY s.date DESC";
+        $sql = 'SELECT  s.*, auteur, COUNT(*) AS nb
+                  FROM  skins AS s
+             LEFT JOIN  accounts AS a ON (a.skin = s.id)
+                 WHERE  skin_tpl != \'\' AND ext != \'\'
+              GROUP BY  id ORDER BY s.date DESC';
         $page->assign('skins', XDB::iterator($sql));
     }
 
     function handler_exit(&$page, $level = null)
     {
-        if (S::has('suid')) {
-            $suid = S::v('suid');
-            $log  = S::v('log');
-            S::logger()->log("suid_stop", S::user()->login() . " by " . $suid['hruid']);
+        if (S::suid()) {
+            S::logger()->log('suid_stop', S::user()->login() . " by " . S::suid('hruid'));
             Platal::session()->stopSUID();
             pl_redirect('admin/user/' . S::user()->login());
         }
index 298d49c..38e6dc8 100644 (file)
@@ -236,8 +236,11 @@ class ProfileModule extends PLModule
             return PL_NOT_FOUND;
         }
 
-        $login = S::logged() ? User::get($x) : User::getSilent($x);
+        $login = (!is_numeric($x) || S::has_perms()) ? Profile::get($x) : null;
         if (!$login) {
+            if (S::logged()) {
+                $page->trigError($x . ' inconnu dans l\'annuaire');
+            }
             return PL_NOT_FOUND;
         }
 
@@ -257,30 +260,29 @@ class ProfileModule extends PLModule
 
         // Determines is the user is registered, and fetches the user infos in
         // the appropriate way.
-        $res = XDB::query("SELECT  perms IN ('admin','user','disabled')
-                             FROM  auth_user_md5
-                            WHERE  user_id = {?}", $login->id());
-        if ($res->fetchOneCell()) {
+        $owner = $login->owner();
+        if (!$owner || $owner->state != 'pending') {
             $new  = Env::v('modif') == 'new';
-            $user = get_user_details($login->login(), S::v('uid'), $view);
+            // XXX: Deprecated...
+            $user = get_user_details($login->hrid(), S::i('uid'), $view);
         } else {
             $new  = false;
             $user = array();
             if (S::logged()) {
-                pl_redirect('marketing/public/' . $login->login());
+                pl_redirect('marketing/public/' . $owner->login());
             }
         }
 
         // Profile view are logged.
         if (S::logged()) {
-            S::logger()->log('view_profile', $login->login());
+            S::logger()->log('view_profile', $login->hrid());
         }
 
         // Sets the title of the html page.
         $page->setTitle($login->fullName());
 
         // Prepares the display of the user's mugshot.
-        $photo = 'photo/' . $login->login() . ($new ? '/req' : '');
+        $photo = 'photo/' . $login->hrid() . ($new ? '/req' : '');
         if (!isset($user['photo_pub']) || !has_user_right($user['photo_pub'], $view)) {
             $photo = "";
         }
@@ -306,24 +308,15 @@ class ProfileModule extends PLModule
 
         // Determines and displays the virtual alias.
         global $globals;
-        $res = XDB::query(
-                "SELECT  alias
-                   FROM  virtual
-             INNER JOIN  virtual_redirect USING (vid)
-             INNER JOIN  auth_user_quick ON (user_id = {?} AND emails_alias_pub = 'public')
-                  WHERE  (redirect={?} OR redirect={?})
-                         AND alias LIKE '%@{$globals->mail->alias_dom}'",
-                $login->id(),
-                $login->forlifeEmail(),
-                // TODO(vzanotti): get ride of all @m4x.org addresses in the
-                // virtual redirect base, and remove this über-ugly hack.
-                $login->login() . '@' . $globals->mail->domain2);
-        $page->assign('virtualalias', $res->fetchOneCell());
+        $owner = $login->owner();
+        if ($owner) {
+            $page->assign('virtualalias', $owner->emailAlias());
+        }
 
         // Adds miscellaneous properties to the display.
         // Adds the global user property array to the display.
         $page->assign_by_ref('x', $user);
-        $page->assign_by_ref('user', $login);
+        $page->assign_by_ref('user', $owner);
         $page->assign('logged', has_user_right('private', $view));
         $page->assign('view', $view);
 
@@ -335,33 +328,34 @@ class ProfileModule extends PLModule
 
     function handler_ax(&$page, $user = null)
     {
-        $user = User::get($user);
+        $user = Profile::get($user);
         if (!$user) {
             return PL_NOT_FOUND;
         }
-
-        $res = XDB::query("SELECT  matricule_ax
-                             FROM  auth_user_md5
-                            WHERE  user_id = {?}", $user->id());
-        $mat = $res->fetchOneCell();
-        if (!intval($mat)) {
-            $page->kill("Le matricule AX de {$user->login()} est inconnu");
+        if (!$user->ax_id) {
+            $page->kill("Le matricule AX de {$user->hrid()} est inconnu");
         }
-        http_redirect("http://www.polytechniciens.com/?page=AX_FICHE_ANCIEN&anc_id=$mat");
+        http_redirect("http://www.polytechniciens.com/?page=AX_FICHE_ANCIEN&anc_id=" . $user->ax_id);
     }
 
-    function handler_p_edit(&$page, $opened_tab = null, $mode = null, $success = null)
+    function handler_p_edit(&$page, $user = null, $opened_tab = null, $mode = null, $success = null)
     {
         global $globals;
 
-        // AX Synchronization
-        require_once 'synchro_ax.inc.php';
-        if (is_ax_key_missing()) {
-            $page->assign('no_private_key', true);
-        }
-        if (Env::v('synchro_ax') == 'confirm' && !is_ax_key_missing()) {
-            ax_synchronize(S::user()->login(), S::v('uid'));
-            $page->trigSuccess('Ton profil a été synchronisé avec celui du site polytechniciens.com');
+        if (is_null($user)) {
+            $user = S::user();
+            if (!$user->hasProfile()) {
+                return PL_NOT_FOUND;
+            } else {
+                pl_redirect('profile/edit/' . $user->profile()->hrid());
+            }
+        } else {
+            $user = Profile::get($user);
+            if (!$user) {
+                return PL_NOT_FOUND;
+            } else if (!S::user()->canEdit($user) && Platal::notAllowed()) {
+                return PL_FORBIDDEN;
+            }
         }
 
         // Build the page
@@ -370,7 +364,9 @@ class ProfileModule extends PLModule
         $page->addJsLink('grades.js');
         $page->addJsLink('profile.js');
         $page->addJsLink('jquery.autocomplete.js');
-        $wiz = new PlWizard('Profil', PlPage::getCoreTpl('plwizard.tpl'), true, true);
+        $wiz = new PlWizard('Profil', PlPage::getCoreTpl('plwizard.tpl'), true, true, false);
+        $wiz->addUserData('profile', $user);
+        $wiz->addUserData('owner', $user->owner());
         $this->load('page.inc.php');
         $wiz->addPage('ProfileGeneral', 'Général', 'general');
         $wiz->addPage('ProfileAddresses', 'Adresses personnelles', 'adresses');
@@ -379,13 +375,9 @@ class ProfileModule extends PLModule
         $wiz->addPage('ProfileJobs', 'Informations professionnelles', 'emploi');
         $wiz->addPage('ProfileSkills', 'Compétences diverses', 'skill');
         $wiz->addPage('ProfileMentor', 'Mentoring', 'mentor');
-        $wiz->apply($page, 'profile/edit', $opened_tab, $mode);
+        $wiz->apply($page, 'profile/edit/' . $user->hrid(), $opened_tab, $mode);
 
-         // Misc checks
-        $res = XDB::query("SELECT  user_id
-                             FROM  auth_user_md5
-                            WHERE  user_id = {?} AND naissance = '0000-00-00'", S::i('uid'));
-        if ($res->numRows()) {
+        if (!$user->birthdate) {
             $page->trigWarning("Ta date de naissance n'est pas renseignée, ce qui t'empêcheras de réaliser"
                       . " la procédure de récupération de mot de passe si un jour tu le perdais.");
         }
@@ -573,23 +565,19 @@ class ProfileModule extends PLModule
         $page->assign('names', build_javascript_names($data));
     }
 
-    function handler_p_orange(&$page)
+    function handler_p_orange(&$page, $pid = null)
     {
         $page->changeTpl('profile/orange.tpl');
 
         require_once 'validations.inc.php';
-
-        $res = XDB::query("SELECT  e.entry_year, e.grad_year, d.promo, FIND_IN_SET('femme', u.flags) AS sexe
-                             FROM  auth_user_md5     AS u
-                       INNER JOIN  profile_display   AS d ON (d.pid = u.user_id)
-                       INNER JOIN  profile_education AS e ON (e.uid = u.user_id AND FIND_IN_SET('primary', e.flags))
-                            WHERE  u.user_id = {?}", S::v('uid'));
-
-        list($promo, $promo_sortie_old, $promo_display, $sexe) = $res->fetchOneRow();
-        $page->assign('promo_sortie_old', $promo_sortie_old);
-        $page->assign('promo', $promo);
-        $page->assign('promo_display', $promo_display);
-        $page->assign('sexe', $sexe);
+        $profile = Profile::get($pid);
+        if (is_null($profile)) {
+            return PL_NOT_FOUND;
+        }
+        $page->assign('promo_sortie_old', $profile->grad_year);
+        $page->assign('promo', $profile->entry_year);
+        $page->assign('promo_display', $profile->promo());
+        $page->assign('sexe', $profile->isFemale());
 
         if (!Env::has('promo_sortie')) {
             return;
@@ -598,24 +586,21 @@ class ProfileModule extends PLModule
         }
 
         $promo_sortie = Env::i('promo_sortie');
-
+        $promo = $profile->entry_year;
         if ($promo_sortie < 1000 || $promo_sortie > 9999) {
             $page->trigError('L\'année de sortie doit être un nombre de quatre chiffres.');
-        }
-        elseif ($promo_sortie < $promo + 3) {
+        } elseif ($promo_sortie < $promo + 3) {
             $page->trigError('Trop tôt !');
-        }
-        elseif ($promo_sortie == $promo_sortie_old) {
+        } elseif ($promo_sortie == $promo_sortie_old) {
             $page->trigWarning('Tu appartiens déjà à la promotion correspondante à cette année de sortie.');
-        }
-        elseif ($promo_sortie == $promo + 3) {
-            XDB::execute("UPDATE  profile_education
+        } elseif ($promo_sortie == $promo + 3) {
+            XDB::execute('UPDATE  profile_education
                              SET  grad_year = {?}
-                           WHERE  uid = {?} AND FIND_IN_SET('primary', flags)", $promo_sortie, S::v('uid'));
-                $page->trigSuccess('Ton statut "orange" a été supprimé.');
-                $page->assign('promo_sortie_old', $promo_sortie);
-        }
-        else {
+                           WHERE  uid = {?} AND FIND_IN_SET(\'primary\', flags)',
+                         $promo_sortie, $profile->id());
+            $page->trigSuccess('Ton statut "orange" a été supprimé.');
+            $page->assign('promo_sortie_old', $promo_sortie);
+        else {
             $page->assign('promo_sortie', $promo_sortie);
 
             if (Env::has('submit')) {
@@ -626,27 +611,27 @@ class ProfileModule extends PLModule
         }
     }
 
-    function handler_referent(&$page, $x = null)
+    function handler_referent(&$page, $user)
     {
         require_once 'user.func.inc.php';
         $page->changeTpl('profile/fiche_referent.tpl', SIMPLE);
 
-        $user = User::get($x);
-        if ($user == null) {
+        $user = Profile::get($user);
+        if (!$user) {
             return PL_NOT_FOUND;
         }
 
-        $res = XDB::query("SELECT cv FROM auth_user_md5 WHERE user_id = {?}", $user->id());
-        $cv = $res->fetchOneCell();
-
         $page->assign_by_ref('user', $user);
-        $page->assign('cv', MiniWiki::WikiToHTML($cv, true));
-        $page->assign('adr_pro', get_user_details_pro($user->id()));
+        $page->assign('cv', MiniWiki::WikiToHTML($user->cv, true));
+        //TODO: waiting for job refactoring to be done
+        //$page->assign('adr_pro', get_user_details_pro($user->id()));
 
         /////  recuperations infos referent
 
         //expertise
-        $res = XDB::query("SELECT expertise FROM profile_mentor WHERE uid = {?}", $user->id());
+        $res = XDB::query('SELECT  expertise
+                             FROM  profile_mentor
+                            WHERE  uid = {?}', $user->id());
         $page->assign('expertise', $res->fetchOneCell());
 
         // Sectors
index a59fa30..11220b4 100644 (file)
@@ -83,38 +83,18 @@ class ProfileAddress extends ProfileGeocoding
         return $value;
     }
 
-    private function saveTel($addrid, $telid, array &$tel)
-    {
-        XDB::execute("INSERT INTO  profile_phones (uid, link_type, link_id, tel_id, tel_type,
-                                                   search_tel, display_tel, pub)
-                           VALUES  ({?}, 'address', {?}, {?}, {?},
-                                    {?}, {?}, {?})",
-                     S::i('uid'), $addrid, $telid, $tel['type'],
-                     format_phone_number($tel['tel']), $tel['tel'], $tel['pub']);
-    }
-
-    public function saveAddress($addrid, array &$address, $type)
+    private function saveAddress($pid, $addrid, array &$address, $type)
     {
         require_once "geocoding.inc.php";
 
         $flags = new PlFlagSet();
-        if ($address['current']) {
-            $flags->addFlag('current');
-        }
-        if ($address['temporary']) {
-            $flags->addFlag('temporary');
-        }
-        if ($address['secondary']) {
-            $flags->addFlag('secondary');
-        }
-        if ($address['mail']) {
-            $flags->addFlag('mail');
-        }
-        if ($address['cedex'] =
+        $flags->addFlag('current', $address['current']);
+        $flags->addFlag('temporary', $address['temporary']);
+        $flags->addFlag('secondary', $address['secondary']);
+        $flags->addFlag('mail', $address['mail']);
+        $flags->addFlag('cedex', $address['cedex'] =
             (strpos(strtoupper(preg_replace(array("/[0-9,\"'#~:;_\- ]/", "/\r\n/"),
-                                            array("", "\n"), $address['text'])), 'CEDEX')) !== false) {
-            $flags->addFlag('cedex');
-        }
+                                            array("", "\n"), $address['text'])), 'CEDEX')) !== false);
         Geocoder::getAreaId($address, "administrativeArea");
         Geocoder::getAreaId($address, "subAdministrativeArea");
         Geocoder::getAreaId($address, "locality");
@@ -125,7 +105,7 @@ class ProfileAddress extends ProfileGeocoding
                                                       north, south, east, west)
                            VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?},
                                     {?}, {?}, FROM_UNIXTIME({?}), {?}, {?}, {?}, {?}, {?}, {?})",
-                     S::i('uid'), $type, $addrid, $flags, $address['accuracy'],
+                     $pid, $type, $addrid, $flags, $address['accuracy'],
                      $address['text'], $address['postalText'], $address['postalCode'], $address['localityId'],
                      $address['subAdministrativeAreaId'], $address['administrativeAreaId'],
                      $address['countryId'], $address['latitude'], $address['longitude'],
@@ -137,14 +117,14 @@ class ProfileAddress extends ProfileGeocoding
     {
         XDB::execute("DELETE FROM  profile_addresses
                             WHERE  pid = {?} AND type = 'home'",
-                     S::i('uid'));
+                     $page->pid());
         XDB::execute("DELETE FROM  profile_phones
                             WHERE  uid = {?} AND link_type = 'address'",
-                     S::i('uid'));
+                     $page->pid());
         foreach ($value as $addrid => &$address) {
-            $this->saveAddress($addrid, $address, 'home');
+            $this->saveAddress($page->pid(), $addrid, $address, 'home');
             $profiletel = new ProfilePhones('address', $addrid);
-            $profiletel->saveTels('tel', $address['tel']);
+            $profiletel->saveTels($page->pid(), 'tel', $address['tel']);
         }
     }
 }
@@ -174,7 +154,7 @@ class ProfileAddresses extends ProfilePage
                              FROM  profile_addresses
                             WHERE  pid = {?} AND type = 'home'
                          ORDER BY  id",
-                           S::i('uid'));
+                           $this->pid());
         if ($res->numRows() == 0) {
             $this->values['addresses'] = array();
         } else {
@@ -185,13 +165,13 @@ class ProfileAddresses extends ProfilePage
                                 FROM  profile_phones
                                WHERE  uid = {?} AND link_type = 'address'
                             ORDER BY  link_id",
-                             S::i('uid'));
+                             $this->pid());
         $i = 0;
         $adrNb = count($this->values['addresses']);
         while ($tel = $res->next()) {
-            $adrid = $tel['addrid'];
+            $addrid = $tel['addrid'];
             unset($tel['addrid']);
-            while ($i < $adrNb && $this->values['addresses'][$i]['id'] < $adrid) {
+            while ($i < $adrNb && $this->values['addresses'][$i]['id'] < $addrid) {
                 $i++;
             }
             if ($i >= $adrNb) {
@@ -201,7 +181,7 @@ class ProfileAddresses extends ProfilePage
             if (!isset($address['tel'])) {
                 $address['tel'] = array();
             }
-            if ($address['id'] == $adrid) {
+            if ($address['id'] == $addrid) {
                 $address['tel'][] = $tel;
             }
         }
index 31d68cd..9d46347 100644 (file)
@@ -30,7 +30,7 @@ class ProfileDeco implements ProfileSetting
                                    FROM  profile_medals_sub    AS s
                              INNER JOIN  profile_medals        AS m ON ( s.mid = m.id )
                                   WHERE  s.uid = {?}",
-                                S::i('uid'));
+                                $page->pid());
             $value = array();
             while (list($id, $grade) = $res->next()) {
                 $value[$id] = array('grade' => $grade,
@@ -63,7 +63,7 @@ class ProfileDeco implements ProfileSetting
                 if ($val['valid']) {
                     XDB::execute("DELETE FROM  profile_medals_sub
                                         WHERE  uid = {?} AND mid = {?}",
-                                 S::i('uid'), $id);
+                                 $page->pid(), $id);
                 } else {
                     $req = MedalReq::get_request(S::i('uid'), $id);
                     if ($req) {
@@ -98,20 +98,20 @@ class ProfileDecos extends ProfilePage
 
     protected function _fetchData()
     {
-        $res = XDB::query("SELECT  profile_medals_pub
-                             FROM  auth_user_quick
-                            WHERE  user_id = {?}",
-                          S::i('uid'));
+        $res = XDB::query("SELECT  medals_pub
+                             FROM  profiles
+                            WHERE  pid = {?}",
+                          $this->pid());
         $this->values['medals_pub'] = $res->fetchOneCell();
     }
 
     protected function _saveData()
     {
         if ($this->changed['medals_pub']) {
-            XDB::execute("UPDATE  auth_user_quick
-                             SET  profile_medals_pub = {?}
-                           WHERE  user_id = {?}",
-                         $this->values['medals_pub'], S::i('uid'));
+            XDB::execute("UPDATE  profiles
+                             SET  medals_pub = {?}
+                           WHERE  pid = {?}",
+                         $this->values['medals_pub'], $this->pid());
         }
     }
 
index 708c2dc..4884303 100644 (file)
@@ -24,7 +24,8 @@ class ProfileSearchNames implements ProfileSetting
     private $private_name_end;
     private $search_names;
 
-    private function matchWord($old, $new, $newLen) {
+    private function matchWord($old, $new, $newLen)
+    {
         return ($i = strpos($old, $new)) !== false
             && ($i == 0 || $old{$i-1} == ' ')
             && ($i + $newLen == strlen($old) || $old{$i + $newLen} == ' ');
@@ -67,7 +68,7 @@ class ProfileSearchNames implements ProfileSetting
                                  INNER JOIN  profile_name_enum AS e  ON (e.id = sn.typeid)
                                       WHERE  sn.pid = {?} AND NOT FIND_IN_SET('not_displayed', e.flags)
                                    ORDER BY  NOT FIND_IN_SET('always_displayed', e.flags), e.id, sn.name",
-                                    S::v('uid'));
+                                     $page->pid());
 
             $sn_types = XDB::iterator("SELECT  id, type, name,
                                                FIND_IN_SET('has_particle', flags) AS has_particle
@@ -81,7 +82,9 @@ class ProfileSearchNames implements ProfileSetting
             while ($sn_type = $sn_types->next()) {
                 if ($sn_type['id'] == $sn['typeid']) {
                     $value[] = $sn;
-                    $sn = $sn_all->next();
+                    if ($sn) {
+                        $sn = $sn_all->next();
+                    }
                 } else {
                     $value[] = array('name'             => '',
                                      'particle'         => '',
@@ -106,7 +109,7 @@ class ProfileSearchNames implements ProfileSetting
                            INNER JOIN  profile_name_enum AS e ON (e.id = s.typeid)
                                 WHERE  s.pid = {?} AND e.type LIKE '%ini'
                              ORDER BY  e.type = 'firstname_ini'",
-                             S::i('uid'));
+                             $page->pid());
             $res = $res->fetchAllAssoc();
             $initial = array();
             $initial['lastname'] = $res[0]['particle'] . $res[0]['name'];
@@ -174,7 +177,7 @@ class ProfileSearchNames implements ProfileSetting
                             USING  profile_name      AS s
                        INNER JOIN  profile_name_enum AS e ON (s.typeid = e.id)
                             WHERE  s.pid = {?} AND NOT FIND_IN_SET('not_displayed', e.flags)",
-                     S::i('uid'));
+                     $page->pid());
         $has_new = set_alias_names($this->search_names, $sn_old);
 
         // Only requires validation if modification in public names
@@ -193,7 +196,8 @@ class ProfileSearchNames implements ProfileSetting
 
 class ProfileEdu implements ProfileSetting
 {
-    public function __construct(){}
+    public function __construct() {
+    }
 
     static function sortByGradYear($line1, $line2) {
         $a = (int) $line1['grad_year'];
@@ -209,14 +213,11 @@ class ProfileEdu implements ProfileSetting
         $success = true;
         if (is_null($value) || !is_array($value)) {
             $value = array();
-            $res = XDB::iterator("SELECT  eduid, degreeid, fieldid, grad_year, program
-                                    FROM  profile_education
-                                   WHERE  uid = {?} AND !FIND_IN_SET('primary', flags)
-                                ORDER BY  id",
-                                 S::v('uid'));
-            while($edu = $res->next()) {
-                $value[] = $edu;
-            }
+            $value = XDB::fetchAllAssoc("SELECT  eduid, degreeid, fieldid, grad_year, program
+                                           FROM  profile_education
+                                          WHERE  uid = {?} AND !FIND_IN_SET('primary', flags)
+                                       ORDER BY  id",
+                                        $page->pid());
         } else {
             $i = 0;
             foreach ($value as $key=>&$edu) {
@@ -240,13 +241,13 @@ class ProfileEdu implements ProfileSetting
     {
         XDB::execute("DELETE FROM  profile_education
                             WHERE  uid = {?} AND !FIND_IN_SET('primary', flags)",
-                     S::i('uid'));
+                     $page->pid());
         foreach ($value as $eduid=>&$edu) {
             if ($edu['eduid'] != '') {
                 XDB::execute("INSERT INTO  profile_education
                                       SET  id = {?}, uid = {?}, eduid = {?}, degreeid = {?},
                                            fieldid = {?}, grad_year = {?}, program = {?}",
-                             $eduid, S::i('uid'), $edu['eduid'], $edu['degreeid'],
+                             $eduid, $page->pid(), $edu['eduid'], $edu['degreeid'],
                              $edu['fieldid'], $edu['grad_year'], $edu['program']);
             }
         }
@@ -296,25 +297,17 @@ class ProfileNetworking implements ProfileSetting
     public function value(ProfilePage &$page, $field, $value, &$success)
     {
         if (is_null($value)) {
-            $value = array();
-            $res = XDB::iterator("SELECT  n.address, n.network_type AS type, n.pub, m.name
-                                    FROM  profile_networking AS n
-                              INNER JOIN  profile_networking_enum AS m ON (n.network_type = m.network_type)
-                                   WHERE  n.uid = {?}",
-                                 S::i('uid'));
-            while($network = $res->next()) {
-                $value[] = $network;
-            }
+            $value = XDB::fetchAllAssoc("SELECT  n.address, n.network_type AS type, n.pub, m.name
+                                           FROM  profile_networking AS n
+                                     INNER JOIN  profile_networking_enum AS m ON (n.network_type = m.network_type)
+                                          WHERE  n.uid = {?}",
+                                         $page->pid());
         }
         if (!is_array($value)) {
             $value = array();
         }
-        $res = XDB::iterator("SELECT  filter, network_type AS type
-                                FROM  profile_networking_enum;");
-        $filters = array();
-        while($filter = $res->next()) {
-            $filters[$filter['type']] = $filter['filter'];
-        }
+        $filters = XDB::fetchAllAssoc('type', 'SELECT  filter, network_type AS type
+                                                 FROM  profile_networking_enum;');
         $success = true;
         foreach($value as $i=>&$network) {
             if (!trim($network['address'])) {
@@ -346,7 +339,7 @@ class ProfileNetworking implements ProfileSetting
     {
         XDB::execute("DELETE FROM profile_networking
                             WHERE uid = {?}",
-                     S::i('uid'));
+                     $page->pid());
         if (!count($value)) {
             return;
         }
@@ -354,7 +347,7 @@ class ProfileNetworking implements ProfileSetting
         foreach ($value as $id=>$network) {
             XDB::execute("INSERT INTO  profile_networking (uid, nwid, network_type, address, pub)
                                VALUES  ({?}, {?}, {?}, {?}, {?})",
-                         S::i('uid'), $id, $network['type'], $network['address'], $network['pub']);
+                         $page->pid(), $id, $network['type'], $network['address'], $network['pub']);
         }
     }
 }
@@ -368,15 +361,14 @@ class ProfileGeneral extends ProfilePage
         parent::__construct($wiz);
         $this->settings['search_names']
                                   = new ProfileSearchNames();
-        $this->settings['naissance'] 
-                                  = new ProfileDate();
+        $this->settings['birthdate'] = new ProfileDate();
         $this->settings['freetext_pub']
                                   = $this->settings['photo_pub']
                                   = new ProfilePub();
         $this->settings['freetext']
-                                  = $this->settings['nationalite']
-                                  = $this->settings['nationalite2']
-                                  = $this->settings['nationalite3']
+                                  = $this->settings['nationality1']
+                                  = $this->settings['nationality2']
+                                  = $this->settings['nationality3']
                                   = $this->settings['yourself']
                                   = $this->settings['promo']
                                   = null;
@@ -389,39 +381,44 @@ class ProfileGeneral extends ProfilePage
         $this->settings['edus']   = new ProfileEdu();
         $this->watched= array('freetext' => true, 'tels' => true,
                               'networking' => true, 'edus' => true,
-                              'nationalite' => true, 'nationalite2' => true,
-                              'nationalite3' => true, 'search_names' => true);
+                              'nationality1' => true, 'nationality2' => true,
+                              'nationality3' => true, 'search_names' => true);
     }
 
     protected function _fetchData()
     {
         // Checkout all data...
         $res = XDB::query("SELECT  p.promo, e.entry_year AS entry_year, e.grad_year AS grad_year,
-                                   u.nationalite, u.nationalite2, u.nationalite3, u.naissance,
+                                   pr.nationality1, pr.nationality2, pr.nationality3, pr.birthdate,
                                    t.display_tel as mobile, t.pub as mobile_pub,
                                    d.email_directory as email_directory,
-                                   q.profile_freetext as freetext, q.profile_freetext_pub as freetext_pub,
-                                   u.matricule_ax, p.yourself
-                             FROM  auth_user_md5         AS u
-                       INNER JOIN  auth_user_quick       AS q ON (u.user_id = q.user_id)
-                       INNER JOIN  profile_display       AS p ON (p.pid = u.user_id)
-                       INNER JOIN  profile_education     AS e ON (e.uid = u.user_id AND FIND_IN_SET('primary', e.flags))
-                        LEFT JOIN  profile_phones        AS t ON (u.user_id = t.uid AND link_type = 'user')
-                        LEFT JOIN  profile_directory     AS d ON (d.uid = u.user_id)
-                            WHERE  u.user_id = {?}", S::v('uid', -1));
+                                   pr.freetext, pr.freetext_pub, pr.ax_id AS matricule_ax, p.yourself
+                             FROM  profiles              AS pr
+                       INNER JOIN  profile_display       AS p ON (p.pid = pr.pid)
+                       INNER JOIN  profile_education     AS e ON (e.uid = pr.pid AND FIND_IN_SET('primary', e.flags))
+                        LEFT JOIN  profile_phones        AS t ON (t.uid = pr.pid AND link_type = 'user')
+                        LEFT JOIN  profile_directory     AS d ON (d.uid = pr.pid)
+                            WHERE  pr.pid = {?}", $this->pid());
         $this->values = $res->fetchOneAssoc();
+        if ($this->owner) {
+            $this->values['yourself'] = $this->owner->displayName();
+        }
 
         // Retreive photo informations
         $res = XDB::query("SELECT  pub
                              FROM  photo
-                            WHERE  uid = {?}", S::v('uid'));
+                            WHERE  uid = {?}", $this->pid());
         $this->values['photo_pub'] = $res->fetchOneCell();
 
-        $res = XDB::query("SELECT  COUNT(*)
-                             FROM  requests
-                            WHERE  type='photo' AND user_id = {?}",
-                          S::v('uid'));
-        $this->values['nouvellephoto'] = $res->fetchOneCell();
+        if ($this->owner) {
+            $res = XDB::query("SELECT  COUNT(*)
+                                 FROM  requests
+                                WHERE  type='photo' AND user_id = {?}",
+                              $this->owner->id());
+            $this->values['nouvellephoto'] = $res->fetchOneCell();
+        } else {
+            $this->values['nouvellephoto'] = 0;
+        }
 
         // Proposes choice for promotion
         if ($this->values['entry_year'] != $this->values['grad_year'] - 3) {
@@ -433,33 +430,28 @@ class ProfileGeneral extends ProfilePage
 
     protected function _saveData()
     {
-        if ($this->changed['nationalite'] || $this->changed['nationalite2'] || $this->changed['nationalite3']
-            || $this->changed['naissance']) {
-            if ($this->values['nationalite3'] == "") {
-                $this->values['nationalite3'] = NULL;
+        if ($this->changed['nationality1'] || $this->changed['nationality2'] || $this->changed['nationality3']
+            || $this->changed['birthdate'] || $this->changed['freetext'] || $this->changed['freetext_pub']) {
+            if ($this->values['nationality3'] == "") {
+                $this->values['nationality3'] = NULL;
             }
-            if ($this->values['nationalite2'] == "") {
-                $this->values['nationalite2'] = $this->values['nationalite3'];
-                $this->values['nationalite3'] = NULL;
+            if ($this->values['nationality2'] == "") {
+                $this->values['nationality2'] = $this->values['nationality3'];
+                $this->values['nationality3'] = NULL;
             }
-            if ($this->values['nationalite'] == "") {
-                $this->values['nationalite']  = $this->values['nationalite2'];
-                $this->values['nationalite2'] = $this->values['nationalite3'];
-                $this->values['nationalite3'] = NULL;
+            if ($this->values['nationality1'] == "") {
+                $this->values['nationality1']  = $this->values['nationality2'];
+                $this->values['nationality2'] = $this->values['nationality3'];
+                $this->values['nationality3'] = NULL;
             }
 
-            XDB::execute("UPDATE  auth_user_md5
-                             SET  nationalite = {?}, nationalite2 = {?}, nationalite3 = {?}, naissance={?}
-                           WHERE  user_id = {?}",
-                         $this->values['nationalite'], $this->values['nationalite2'], $this->values['nationalite3'],
-                         preg_replace('@(\d{2})/(\d{2})/(\d{4})@', '\3-\2-\1', $this->values['naissance']),
-                         S::v('uid'));
-        }
-        if ($this->changed['freetext'] || $this->changed['freetext_pub']) {
-            XDB::execute("UPDATE  auth_user_quick
-                             SET  profile_freetext={?}, profile_freetext_pub={?}
-                           WHERE  user_id = {?}",
-                         $this->values['freetext'], $this->values['freetext_pub'], S::v('uid'));
+            XDB::execute("UPDATE  profiles
+                             SET  nationality1 = {?}, nationality2 = {?}, nationality3 = {?}, birthdate = {?},
+                                  freetext = {?}, freetext_pub = {?}
+                           WHERE  pid = {?}",
+                          $this->values['nationality1'], $this->values['nationality2'], $this->values['nationality3'],
+                          preg_replace('@(\d{2})/(\d{2})/(\d{4})@', '\3-\2-\1', $this->values['birthdate']),
+                          $this->values['freetext'], $this->values['freetext_pub'], $this->pid());
         }
         if ($this->changed['email_directory']) {
             $new_email = ($this->values['email_directory'] == "new@example.org") ?
@@ -469,25 +461,24 @@ class ProfileGeneral extends ProfilePage
             }
             XDB::execute("REPLACE INTO  profile_directory (uid, email_directory)
                                 VALUES  ({?}, {?})",
-                         S::v('uid'), $new_email);
+                         $this->pid(), $new_email);
         }
         if ($this->changed['photo_pub']) {
             XDB::execute("UPDATE  photo
                              SET  pub = {?}
                            WHERE  uid = {?}",
-                         $this->values['photo_pub'], S::v('uid'));
+                         $this->values['photo_pub'], $this->pid());
         }
         if ($this->changed['yourself']) {
-            XDB::execute("UPDATE  profile_display
-                             SET  yourself = {?}
-                           WHERE  pid = {?}",
-                         $this->values['yourself'], S::v('uid'));
+            XDB::execute('UPDATE  accounts
+                             SET  display_name = {?}
+                           WHERE  pid = {?}', $this->pid());
         }
         if ($this->changed['promo']) {
             XDB::execute("UPDATE  profile_display
                              SET  promo = {?}
                            WHERE  pid = {?}",
-                         $this->values['promo'], S::v('uid'));
+                         $this->values['promo'], $this->pid());
         }
     }
 
@@ -495,23 +486,23 @@ class ProfileGeneral extends ProfilePage
     {
         require_once "education.func.inc.php";
 
-        $res = XDB::iterator("SELECT  id, field
-                                FROM  profile_education_field_enum
-                            ORDER BY  field");
+        $res = XDB::query("SELECT  id, field
+                             FROM  profile_education_field_enum
+                         ORDER BY  field");
         $page->assign('edu_fields', $res->fetchAllAssoc());
 
         require_once "emails.combobox.inc.php";
-        fill_email_combobox($page);
+        fill_email_combobox($page, $this->owner, $this->profile);
 
-        $res = XDB::iterator("SELECT  nw.network_type AS type, nw.name
-                                FROM  profile_networking_enum AS nw
-                            ORDER BY  name");
+        $res = XDB::query("SELECT  nw.network_type AS type, nw.name
+                             FROM  profile_networking_enum AS nw
+                         ORDER BY  name");
         $page->assign('network_list', $res->fetchAllAssoc());
 
         $res = XDB::query("SELECT  public_name, private_name
                              FROM  profile_display
                             WHERE  pid = {?}",
-                             S::v('uid'));
+                          $this->pid());
         $res = $res->fetchOneRow();
         $page->assign('public_name', $res[0]);
         $page->assign('private_name', $res[1]);
index 5fb7b45..97f85f5 100644 (file)
@@ -26,9 +26,9 @@ class ProfileSection implements ProfileSetting
         $success = true;
         if (is_null($value)) {
             $res = XDB::query("SELECT  section
-                                 FROM  auth_user_md5
-                                WHERE  user_id = {?}",
-                              S::i('uid'));
+                                 FROM  profiles
+                                WHERE  pid = {?}",
+                              $page->pid());
             return intval($res->fetchOneCell());
         }
         return intval($value);
@@ -36,10 +36,10 @@ class ProfileSection implements ProfileSetting
 
     public function save(ProfilePage &$page, $field, $value)
     {
-        XDB::execute("UPDATE  auth_user_md5
+        XDB::execute("UPDATE  profiles
                          SET  section = {?}
-                       WHERE  user_id = {?}",
-                     $value, S::i('uid'));
+                       WHERE  pid = {?}",
+                     $value, $page->pid());
     }
 }
 
@@ -64,7 +64,7 @@ class ProfileGroup implements ProfileSetting
                                    FROM  {$this->table}_def AS g
                              INNER JOIN  {$this->table}_ins AS i ON (i.{$this->group_field} = g.id)
                                   WHERE  i.{$this->user_field} = {?}",
-                                S::i('uid'));
+                                $page->pid());
             while (list($gid, $text) = $res->next()) {
                 $value[intval($gid)] = $text;
             }
@@ -81,13 +81,13 @@ class ProfileGroup implements ProfileSetting
     {
         XDB::execute("DELETE FROM  {$this->table}_ins
                             WHERE  {$this->user_field} = {?}",
-                     S::i('uid'));
+                     $page->pid());
         if (!count($value)) {
             return;
         }
         $insert = array();
         foreach ($value as $id=>$text) {
-            $insert[] = '(' . S::i('uid') . ", $id)";
+            $insert[] = XDB::format('({?}, {?})', $page->pid(), $id);
         }
         XDB::execute("INSERT INTO  {$this->table}_ins ({$this->user_field}, {$this->group_field})
                            VALUES  " . implode(',', $insert));
@@ -112,7 +112,7 @@ class ProfileGroups extends ProfilePage
                                                    FROM  groupex.asso    AS a
                                              INNER JOIN  groupex.membres AS m ON (m.asso_id = a.id)
                                                   WHERE  m.uid = {?} AND (a.cat = 'GroupesX' OR a.cat = 'Institutions')",
-                                                  S::i('uid')));
+                                                $this->pid()));
         $page->assign('listgroups', XDB::iterator("SELECT  a.nom, a.diminutif, a.sub_url,
                                                            IF (a.cat = 'Institutions', a.cat, d.nom) AS dom
                                                      FROM  groupex.asso  AS a
@@ -120,6 +120,7 @@ class ProfileGroups extends ProfilePage
                                                     WHERE  a.inscriptible != 0
                                                            AND (a.cat = 'GroupesX' OR a.cat = 'Institutions')
                                                  ORDER BY  a.cat, a.dom, a.nom"));
+        # XXX: FIXME: promo_sortie
         $page->assign('old', (int)date('Y') >= S::i('promo_sortie'));
     }
 }
index c376f12..18a8f6a 100644 (file)
@@ -270,9 +270,9 @@ class ProfileJobs extends ProfilePage
     {
         // Checkout the CV
         $res = XDB::query("SELECT  cv
-                             FROM  auth_user_md5
-                            WHERE  user_id = {?}",
-                          S::i('uid'));
+                             FROM  profiles
+                            WHERE  pid = {?}",
+                          $this->pid());
         $this->values['cv'] = $res->fetchOneCell();
 
         // Checkout the corps
@@ -280,7 +280,7 @@ class ProfileJobs extends ProfilePage
                                    rankid AS rank, corps_pub AS pub
                              FROM  profile_corps
                             WHERE  uid = {?}",
-                          S::i('uid'));
+                        $this->pid());
         $this->values['corps'] = $res->fetchOneAssoc();
 
         // Build the jobs tree
@@ -303,7 +303,7 @@ class ProfileJobs extends ProfilePage
                           LEFT JOIN  profile_addresses             AS ah ON (ah.jobid = j.jobid AND ah.type = 'hq')
                               WHERE  j.uid = {?}
                            ORDER BY  j.id",
-                            S::i('uid'));
+                            $this->pid());
         $this->values['jobs'] = array();
 
         if ($res->numRows() > 0) {
@@ -453,10 +453,10 @@ class ProfileJobs extends ProfilePage
     protected function _saveData()
     {
         if ($this->changed['cv']) {
-            XDB::execute("UPDATE  auth_user_md5
+            XDB::execute("UPDATE  profiles
                              SET  cv = {?}
-                           WHERE  user_id = {?}",
-                         $this->values['cv'], S::i('uid'));
+                           WHERE  pid = {?}",
+                         $this->values['cv'], $this->pid());
         }
 
         if ($this->changed['corps']) {
@@ -465,14 +465,14 @@ class ProfileJobs extends ProfilePage
                                   rankid = {?}, corps_pub = {?}
                            WHERE  uid = {?}",
                           $this->values['corps']['original'], $this->values['corps']['current'],
-                          $this->values['corps']['rank'], $this->values['corps']['pub'], S::i('uid'));
+                          $this->values['corps']['rank'], $this->values['corps']['pub'], $this->pid());
         }
     }
 
     public function _prepare(PlPage &$page, $id)
     {
         require_once "emails.combobox.inc.php";
-        fill_email_combobox($page);
+        fill_email_combobox($page, $this->owner, $this->profile);
 
         $res = XDB::query("SELECT  id, name AS label
                              FROM  profile_job_sector_enum");
index e85318c..2ecb60b 100644 (file)
@@ -31,7 +31,7 @@ class ProfileSectors implements ProfileSetting
                              INNER JOIN  profile_job_sector_enum    AS s  ON (m.sectorid = s.id)
                              INNER JOIN  profile_job_subsector_enum AS ss ON (s.id = ss.sectorid AND m.subsectorid = ss.id)
                                   WHERE  m.uid = {?}",
-                                S::i('uid'));
+                                $page->pid());
             while (list($s, $ss, $ssname) = $res->next()) {
                 if (!isset($value[$s])) {
                     $value[$s] = array($ss => $ssname);
@@ -57,7 +57,7 @@ class ProfileSectors implements ProfileSetting
 
         XDB::execute("DELETE FROM  profile_mentor_sector
                             WHERE  uid = {?}",
-                     S::i('uid'));
+                     $page->pid());
         if (!count($value)) {
             return;
         }
@@ -65,7 +65,7 @@ class ProfileSectors implements ProfileSetting
             foreach ($sect as $sid => $name) {
                 XDB::execute("INSERT INTO  profile_mentor_sector (uid, sectorid, subsectorid)
                                    VALUES  ({?}, {?}, {?})",
-                             S::i('uid'), $id, $sid);
+                             $page->pid(), $id, $sid);
             }
         }
     }
@@ -82,7 +82,7 @@ class ProfileCountry implements ProfileSetting
                                    FROM  profile_mentor_country AS m
                              INNER JOIN  geoloc_countries       AS gc ON (m.country = gc.iso_3166_1_a2)
                                   WHERE  m.uid = {?}",
-                                S::i('uid'));
+                                $page->pid());
             while (list($id, $name) = $res->next()) {
                 $value[$id] = $name;
             }
@@ -100,11 +100,11 @@ class ProfileCountry implements ProfileSetting
     {
         XDB::execute("DELETE FROM  profile_mentor_country
                             WHERE  uid = {?}",
-                     S::i('uid'));
+                     $page->pid());
         foreach ($value as $id=>&$name) {
             XDB::execute("INSERT INTO  profile_mentor_country (uid, country)
                                VALUES  ({?}, {?})",
-                         S::i('uid'), $id);
+                         $page->pid(), $id);
         }
     }
 }
@@ -127,7 +127,7 @@ class ProfileMentor extends ProfilePage
         $res = XDB::query("SELECT  expertise
                              FROM  profile_mentor
                             WHERE  uid = {?}",
-                          S::i('uid'));
+                          $this->pid());
         $this->values['expertise'] = $res->fetchOneCell();
     }
 
@@ -138,12 +138,12 @@ class ProfileMentor extends ProfilePage
             if (empty($expertise)) {
                 XDB::execute("DELETE FROM  profile_mentor
                                     WHERE  uid = {?}",
-                             S::i('uid'));
+                             $this->pid());
                 $this->values['expertise'] = null;
             } else {
                 XDB::execute("REPLACE INTO  profile_mentor (uid, expertise)
                                     VALUES  ({?}, {?})",
-                             S::i('uid'), $expertise);
+                             $this->pid(), $expertise);
                 $this->values['expertise'] = $expertise;
             }
         }
index a23b1e2..1aaf2c2 100644 (file)
@@ -119,17 +119,11 @@ class ProfilePhones implements ProfileSetting
 {
     private $tel;
     private $pub;
-    protected $id;
     protected $link_type;
     protected $link_id;
 
-    public function __construct($type, $link_id, $id = 0)
+    public function __construct($type, $link_id)
     {
-        if ($id != 0) {
-            $this->id = $id;
-        } else {
-            $this->id = S::i('uid');
-        }
         $this->tel = new ProfileTel();
         $this->pub = new ProfilePub();
         $this->link_type = $type;
@@ -182,14 +176,14 @@ class ProfilePhones implements ProfileSetting
         return $value;
     }
 
-    private function saveTel($telid, array &$phone)
+    private function saveTel($pid, $telid, array &$phone)
     {
         if ($phone['tel'] != '') {
             XDB::execute("INSERT INTO  profile_phones (uid, link_type, link_id, tel_id, tel_type,
                                        search_tel, display_tel, pub, comment)
                                VALUES  ({?}, {?}, {?}, {?}, {?},
                                        {?}, {?}, {?}, {?})",
-                         $this->id, $this->link_type, $this->link_id, $telid, $phone['type'],
+                         $pid, $this->link_type, $this->link_id, $telid, $phone['type'],
                          format_phone_number($phone['tel']), $phone['tel'], $phone['pub'], $phone['comment']);
         }
     }
@@ -198,15 +192,15 @@ class ProfilePhones implements ProfileSetting
     {
         XDB::execute("DELETE FROM  profile_phones
                             WHERE  uid = {?} AND link_type = {?} AND link_id = {?}",
-                            $this->id, $this->link_type, $this->link_id);
-        $this->saveTels($field, $value);
+                     $page->pid(), $this->link_type, $this->link_id);
+        $this->saveTels($page->pid(), $field, $value);
     }
 
     //Only saves phones without a delete operation
-    public function saveTels($field, $value)
+    public function saveTels($pid, $field, $value)
     {
         foreach ($value as $telid=>&$phone) {
-            $this->saveTel($telid, $phone);
+            $this->saveTel($pid, $telid, $phone);
         }
     }
 }
@@ -301,10 +295,14 @@ abstract class ProfilePage implements PlWizardPage
 
     public $orig     = array();
     public $values   = array();
+    public $profile  = null;
+    public $owner    = null;
 
     public function __construct(PlWizard &$wiz)
     {
         $this->wizard =& $wiz;
+        $this->profile = $this->wizard->getUserData('profile');
+        $this->owner   = $this->wizard->getUserData('owner');
     }
 
     protected function _fetchData()
@@ -343,19 +341,17 @@ abstract class ProfilePage implements PlWizardPage
                 $setting->save($this, $field, $this->values[$field]);
             }
             if ($this->changed[$field] && @$this->watched[$field]) {
-                register_profile_update(S::i('uid'), $field);
+                WatchProfileUpdate::register($this->profile, $field);
             }
         }
         $this->_saveData();
 
         // Update the last modification date
-        XDB::execute('REPLACE INTO  user_changes
-                               SET  user_id = {?}', S::v('uid'));
-        if (!S::has('suid')) {
-            register_watch_op(S::i('uid'), WATCH_FICHE);
-        }
+        XDB::execute('UPDATE  profiles
+                         SET  last_change = NOW()
+                       WHERE  pid = {?}', $this->pid());
         global $platal;
-        S::logger()->log('profil', $platal->pl_self(1));
+        S::logger()->log('profil', $platal->pl_self(2));
     }
 
     protected function checkChanges()
@@ -385,6 +381,16 @@ abstract class ProfilePage implements PlWizardPage
         return 'profile/base.tpl';
     }
 
+    public function pid()
+    {
+        return $this->profile->id();
+    }
+
+    public function hrpid()
+    {
+        return $this->profile->hrpid();
+    }
+
     protected function _prepare(PlPage &$page, $id)
     {
     }
@@ -398,6 +404,8 @@ abstract class ProfilePage implements PlWizardPage
             $page->assign($field, $value);
         }
         $this->_prepare($page, $id);
+        $page->assign('profile', $this->profile);
+        $page->assign('owner', $this->owner);
         $page->assign('profile_page', $this->pg_template);
         $page->assign('errors', $this->errors);
     }
index 16ce379..668cbb3 100644 (file)
@@ -40,7 +40,7 @@ class ProfileSkill implements ProfileSetting
                                    FROM  {$this->table}_def AS s
                              INNER JOIN  {$this->table}_ins AS i ON(s.id = i.{$this->skill_field})
                                   WHERE  i.uid = {?}",
-                                S::i('uid'));
+                                $page->pid());
             while (list($sid, $text, $level) = $res->next()) {
                 $value[$sid] = array('text' => $text, 'level' => $level);
             }
@@ -66,14 +66,14 @@ class ProfileSkill implements ProfileSetting
     {
         XDB::execute("DELETE FROM  {$this->table}_ins
                             WHERE  uid = {?}",
-                     S::i('uid'));
+                     $page->pid());
         if (!count($value)) {
             return;
         }
         foreach ($value as $id=>&$skill) {
             XDB::execute("INSERT INTO  {$this->table}_ins (uid, {$this->skill_field}, level)
                                VALUES  ({?}, {?}, {?})",
-                         S::i('uid'), $id, $skill['level']);
+                         $page->pid(), $id, $skill['level']);
         }
     }
 }
index 3668521..7a64e32 100644 (file)
@@ -348,7 +348,7 @@ class RegisterModule extends PLModule
         foreach ($registered_forums as $forum) {
             XDB::execute("INSERT INTO  forums.abos (fid,uid)
                                SELECT  fid, {?}
-                                 FROM   forums.list
+                                 FROM  forums.list
                                 WHERE  nom = {?}",
                                 $uid, $val);
 
index 5e153d7..4d220c6 100644 (file)
@@ -229,7 +229,6 @@ function finish_ins($sub_state)
 {
     global $globals;
     extract($sub_state);
-    require_once('secure_hash.inc.php');
 
     $hash = rand_url_id(12);
     XDB::execute(
index 8acb63d..902f9f1 100644 (file)
@@ -73,9 +73,9 @@ class SearchModule extends PLModule
     {
         global $globals;
 
-        $res = XDB::query("SELECT  MIN(`diminutif`), MAX(`diminutif`)
-                             FROM  `groupex`.`asso`
-                            WHERE  `cat` = 'Promotions'");
+        $res = XDB::query("SELECT  MIN(diminutif), MAX(diminutif)
+                             FROM  groupex.asso
+                            WHERE  cat = 'Promotions'");
         list($min, $max) = $res->fetchOneRow();
         $page->assign('promo_min', $min);
         $page->assign('promo_max', $max);
@@ -231,15 +231,15 @@ class SearchModule extends PLModule
                            array('',
                                  '\\\\\1',
                                  '.*'),
-                           $_REQUEST['q']);
+                           Env::s('q'));
         if (!$q) exit();
 
         // try to look in cached results
-        $cache = XDB::query('SELECT  `result`
-                               FROM  `search_autocomplete`
-                              WHERE  `name` = {?} AND
-                                     `query` = {?} AND
-                                     `generated` > NOW() - INTERVAL 1 DAY',
+        $cache = XDB::query('SELECT  result
+                               FROM  search_autocomplete
+                              WHERE  name = {?} AND
+                                     query = {?} AND
+                                     generated > NOW() - INTERVAL 1 DAY',
                              $type, $q);
         if ($res = $cache->fetchOneCell()) {
             echo $res;
@@ -247,8 +247,8 @@ class SearchModule extends PLModule
         }
 
         // default search
-        $unique = '`user_id`';
-        $db = '`auth_user_md5`';
+        $unique = 'pid';
+        $db = 'profiles';
         $realid = false;
         $beginwith = true;
         $field2 = false;
@@ -257,19 +257,19 @@ class SearchModule extends PLModule
 
         switch ($type) {
           case 'binetTxt':
-            $db = '`binets_def` INNER JOIN
-                   `binets_ins` ON(`binets_def`.`id` = `binets_ins`.`binet_id`)';
-            $field = '`binets_def`.`text`';
+            $db = 'binets_def INNER JOIN
+                   binets_ins ON(binets_def.id = binets_ins.binet_id)';
+            $field = 'binets_def.text';
             if (strlen($q) > 2)
                 $beginwith = false;
-            $realid = '`binets_def`.`id`';
+            $realid = 'binets_def.id';
             break;
           case 'networking_typeTxt':
-            $db = '`profile_networking_enum` INNER JOIN
-                   `profile_networking` ON(`profile_networking`.`network_type` = `profile_networking_enum`.`network_type`)';
-            $field = '`profile_networking_enum`.`name`';
+            $db = 'profile_networking_enum INNER JOIN
+                   profile_networking ON(profile_networking.network_type = profile_networking_enum.network_type)';
+            $field = 'profile_networking_enum.name';
             $unique = 'uid';
-            $realid = '`profile_networking_enum`.`network_type`';
+            $realid = 'profile_networking_enum.network_type';
             break;
           case 'city':
             $db     = 'geoloc_localities INNER JOIN
@@ -312,9 +312,7 @@ class SearchModule extends PLModule
             break;
           case 'nationaliteTxt':
             $db     = 'geoloc_countries INNER JOIN
-                       auth_user_md5 ON (geoloc_countries.a2 = auth_user_md5.nationalite
-                                         OR geoloc_countries.a2 = auth_user_md5.nationalite2
-                                         OR geoloc_countries.a2 = auth_user_md5.nationalite3)';
+                       profile ON (geoloc_countries.a2 IN (profile.nationality1, profile.nationality2, profile.nationality3))';
             $field  = 'geoloc_countries.nationalityFR';
             $realid = 'geoloc_countries.iso_3166_1_a2';
             break;
@@ -348,10 +346,10 @@ class SearchModule extends PLModule
             $distinct  = false;
             break;
           case 'sectionTxt':
-            $db = '`sections` INNER JOIN
-                   `auth_user_md5` ON(`auth_user_md5`.`section` = `sections`.`id`)';
-            $field = '`sections`.`text`';
-            $realid = '`sections`.`id`';
+            $db = 'sections AS acs
+                   INNER JOIN profiles AS acp ON (acp.section = acs.id)';
+            $field = 'acs.text';
+            $realid = 'acs.id';
             $beginwith = false;
             break;
           default: exit();
@@ -401,7 +399,7 @@ class SearchModule extends PLModule
                 $res .= "\n";
             }
         }
-        XDB::query('REPLACE INTO  `search_autocomplete`
+        XDB::query('REPLACE INTO  search_autocomplete
                           VALUES  ({?}, {?}, {?}, NOW())',
                     $type, $q, $res);
         echo $res;
@@ -411,18 +409,18 @@ class SearchModule extends PLModule
     function handler_list(&$page, $type = null, $idVal = null)
     {
         // Give the list of all values possible of type and builds a select input for it
-        $field = '`text`';
-        $id = '`id`';
+        $field = 'text';
+        $id = 'id';
         $where = '';
 
         switch ($type) {
           case 'binet':
-            $db = '`binets_def`';
+            $db = 'binets_def';
             break;
           case 'networking_type':
-            $db = '`profile_networking_enum`';
-            $field = '`name`';
-            $id = '`network_type`';
+            $db = 'profile_networking_enum';
+            $field = 'name';
+            $id = 'network_type';
             break;
           case 'country':
             $db    = 'geoloc_countries';
@@ -431,8 +429,8 @@ class SearchModule extends PLModule
             $page->assign('onchange', 'changeCountry(this.value)');
             break;
           case 'fonction':
-            $db = '`fonctions_def`';
-            $field = '`fonction_fr`';
+            $db = 'fonctions_def';
+            $field = 'fonction_fr';
             break;
           case 'diploma':
             header('Content-Type: text/xml; charset="UTF-8"');
@@ -446,9 +444,7 @@ class SearchModule extends PLModule
             break;
           case 'nationalite':
             $db    = 'geoloc_countries INNER JOIN
-                      auth_user_md5 ON (geoloc_countries.iso_3166_1_a2 = auth_user_md5.nationalite
-                                        OR geoloc_countries.iso_3166_1_a2 = auth_user_md5.nationalite2
-                                        OR geoloc_countries.iso_3166_1_a2 = auth_user_md5.nationalite3)';
+                   profiles AS acp ON (acgp.a2 IN (acp.nationality1, acp.nationality2, acp.nationality3))';
             $field = 'nationalityFR';
             $id    = 'iso_3166_1_a2';
             break;
@@ -467,7 +463,7 @@ class SearchModule extends PLModule
             $page->assign('onchange', 'changeSchool(this.value)');
             break;
           case 'section':
-            $db = '`sections`';
+            $db = 'sections';
             break;
           case 'secteur':
             $db    = 'profile_job_sector_enum INNER JOIN
index 06ad2d2..38ed64c 100644 (file)
@@ -60,17 +60,18 @@ class StatsModule extends PLModule
 
     function handler_graph_evo(&$page, $jours = 365)
     {
-        define('DUREEJOUR',24*3600);
+        define('DUREEJOUR', 24 * 3600);
 
         //recupere le nombre d'inscriptions par jour sur la plage concernée
-        $res = XDB::iterRow(
-                "SELECT  IF( date_ins>DATE_SUB(NOW(),INTERVAL $jours DAY),
-                             TO_DAYS(date_ins)-TO_DAYS(NOW()),
-                            ".(-($jours+1)).") AS jour,
-                         COUNT(user_id) AS nb
-                   FROM  auth_user_md5
-                  WHERE  perms IN ('admin','user') AND deces = 0
-               GROUP BY  jour");
+        $res = XDB::iterRow('SELECT  IF(registration_date > DATE_SUB(NOW(), INTERVAL {?} DAY),
+                                        TO_DAYS(registration_date) - TO_DAYS(NOW()),
+                                        -{?}) AS jour,
+                                     COUNT(uid) AS nb
+                               FROM  accounts AS a
+                          LEFT JOIN  account_profiles AS ap ON(ap.uid = a.uid AND FIND_IN_SET(\'owner\', ap.flags))
+                          LEFT JOIN  profiles AS p ON (ap.pid = p.pid)
+                              WHERE  state = \'active\' AND p.deathdate IS NULL
+                           GROUP BY  jour', (int)$jours, 1 + (int)$jours);
 
         //genere des donnees compatibles avec GNUPLOT
         $inscrits='';
@@ -128,11 +129,13 @@ EOF2;
             $depart = 1930;
 
             //recupere le nombre d'inscriptions par jour sur la plage concernée
-            $res = XDB::iterRow(
-                    "SELECT  promo, SUM(perms IN ('admin', 'user')) / COUNT(*) * 100
-                       FROM  auth_user_md5
-                      WHERE  promo >= $depart AND deces = 0
-                   GROUP BY  promo");
+            $res = XDB::iterRow("SELECT  pe.entry_year AS promo, SUM(state = 'active') / COUNT(*) * 100
+                                   FROM  accounts AS a
+                             INNER JOIN  account_profiles AS ap ON (ap.uid = a.uid AND FIND_IN_SET('owner', ap.perms))
+                             INNER JOIN  profiles AS p ON (p.pid = ap.pid)
+                             INNER JOIN  profile_education AS pe ON (pe.uid = ap.pid AND FIND_IN_SET('primary', pe.flags))
+                                  WHERE  pe.entry_year >= {?} AND p.deathdate IS NULL
+                               GROUP BY  promo", $depart);
 
             //genere des donnees compatibles avec GNUPLOT
             $inscrits='';
@@ -174,23 +177,25 @@ EOF2;
         } else {
             //nombre de jours sur le graph
             $jours = 365;
-            define('DUREEJOUR',24*3600);
-            $res = XDB::query(
-                    "SELECT  min(TO_DAYS(date_ins)-TO_DAYS(now()))
-                       FROM  auth_user_md5
-                      WHERE  promo = {?} AND perms IN ('admin', 'user') AND deces = 0",
-                    $promo);
+            define('DUREEJOUR', 24 * 3600);
+
+            $res = XDB::query("SELECT  MIN(TO_DAYS(a.registration_date) - TO_DAYS(NOW()))
+                                 FROM  accounts AS a
+                           INNER JOIN  account_profiles AS ap ON (ap.uid = a.uid AND FIND_IN_SET('owner', ap.perms))
+                           INNER JOIN  profile_education AS pe ON (pe.uid = ap.pid AND FIND_IN_SET('primary', pe.flags))
+                                WHERE  pe.entry_year = {?} AND a.state = 'active'", (int)$promo);
             $jours = -$res->fetchOneCell();
 
             //recupere le nombre d'inscriptions par jour sur la plage concernée
-            $res = XDB::iterRow(
-                    "SELECT  IF( date_ins>DATE_SUB(NOW(),INTERVAL $jours DAY),
-                                 TO_DAYS(date_ins)-TO_DAYS(NOW()),
-                                ".(-($jours+1)).") AS jour,
-                             COUNT(user_id) AS nb
-                       FROM  auth_user_md5
-                      WHERE  promo = {?} AND perms IN ('admin','user') AND deces = 0
-                   GROUP BY  jour", $promo);
+            $res = XDB::iterRow("SELECT  IF(a.registration_date > DATE_SUB(NOW(), INTERVAL {?} DAY),
+                                            TO_DAYS(a.registration_date) - TO_DAYS(NOW()),
+                                            -{?}) AS jour,
+                                         COUNT(a.uid) AS nb
+                                   FROM  accounts AS a
+                             INNER JOIN  account_profiles AS ap ON (ap.uid = a.uid AND FIND_IN_SET('owner', ap.perms))
+                             INNER JOIN  profile_education AS pe ON (pe.uid = ap.pid AND FIND_IN_SET('primary', pe.flags))
+                                  WHERE  pe.entry_year = {?} AND a.state = 'active'
+                               GROUP BY  jour", (int)$jours, 1 + (int)$jours, (int)$promo);
 
             //genere des donnees compatibles avec GNUPLOT
             $inscrits='';
@@ -246,12 +251,13 @@ EOF2;
     {
         $page->changeTpl('stats/nb_by_promo.tpl');
 
-        $res = XDB::iterRow(
-                "SELECT  promo,COUNT(*)
-                   FROM  auth_user_md5
-                  WHERE  promo > 1900 AND perms IN ('admin','user') AND deces = 0
-               GROUP BY  promo
-               ORDER BY  promo");
+        $res = XDB::iterRow('SELECT  pe.entry_year AS promo, COUNT(*)
+                               FROM  accounts AS a
+                         INNER JOIN  account_profiles AS ap ON (ap.uid = a.uid AND FIND_IN_SET(\'owner\', ap.perms))
+                         INNER JOIN  profile_education AS pe ON (pe.uid = ap.pid AND FIND_IN_SET(\'primary\', pe.flags))
+                              WHERE  pe.entry_year >= 1900  AND a.state = \'active\'
+                           GROUP BY  promo
+                           ORDER BY  promo');
         $max=0; $min=3000;
 
         while (list($p,$nb) = $res->next()) {
@@ -306,16 +312,17 @@ EOF2;
             $time = ' AND e.stamp > DATE_SUB(CURDATE(), INTERVAL 1 ' . strtoupper($period) . ')';
             break;
         }
-        $rows = XDB::iterator("SELECT  IF(u.nom_usage != '', u.nom_usage, u.nom) AS nom,
-                                       u.prenom, u.promo, e.data AS forlife, COUNT(*) AS count
-                                 FROM  logger.events AS e
-                           INNER JOIN  logger.actions AS act ON (e.action = act.id)
-                           INNER JOIN  aliases AS a ON (a.alias = e.data)
-                           INNER JOIN  auth_user_md5 AS u ON (u.user_id = a.id)
-                                WHERE  act.text = 'view_profile' $time
-                             GROUP BY  e.data
-                             ORDER BY  count DESC
-                                LIMIT  10");
+        $rows = XDB::fetchAllAssoc("SELECT  p.pid AS profile, COUNT(*) AS count
+                                      FROM  logger.events AS e
+                                INNER JOIN  logger.actions AS act ON (e.action = act.id)
+                                INNER JOIN  profiles AS p ON (p.hrpid = e.data)
+                                     WHERE  act.text = 'view_profile' $time
+                                  GROUP BY  e.data
+                                  ORDER BY  count DESC
+                                     LIMIT  10");
+        foreach ($rows as $key=>$row) {
+            $rows[$key]['profile'] = Profile::get($rows[$key]['profile']);
+        }
         $page->assign('profiles', $rows);
         $page->assign('period', $period);
     }
index c50cc12..5d5087a 100644 (file)
@@ -189,16 +189,11 @@ class Survey
         $nbf = count($line);
         $users = array();
         if ($this->isMode(self::MODE_XIDENT)) { // if the mode is non anonymous
-            $sql = 'SELECT v.id AS vid, a.nom, a.prenom, a.promo
-                      FROM survey_votes AS v
-                INNER JOIN auth_user_md5 AS a
-                        ON a.user_id=v.user_id
-                     WHERE v.survey_id={?}
-                  ORDER BY vid ASC;';
-            $res = XDB::iterator($sql, $this->id); // retrieves all users data
-            for ($u = $res->next(); $u != null; $u = $res->next()) {
-                $users[$u['vid']] = array('nom' => $u['nom'], 'prenom' => $u['prenom'], 'promo' => $u['promo']);
-            }
+            $users = User::getBulkUsersWithUIDs(XDB::fetchAllAssoc('vid', 'SELECT  v.id AS vid, v.user_id
+                                                                             FROM  survey_votes AS v
+                                                                            WHERE  v.survey_id = {?}
+                                                                         ORDER BY  vid ASC',
+                                                                    $this->id));
         }
         $sql = 'SELECT v.id AS vid, a.question_id AS qid, a.answer AS answer
                   FROM survey_votes AS v
@@ -207,20 +202,19 @@ class Survey
                  WHERE v.survey_id={?}
               ORDER BY vid ASC, qid ASC, answer ASC;';
         $res = XDB::iterator($sql, $this->id); // retrieves all answers from database
-        $cur = $res->next();
         $vid = -1;
         $vid_ = 0;
-        while ($cur != null) {
+        while (($cur = $res->next()) != null) {
             if ($vid != $cur['vid']) { // if the vote id changes, then starts a new line
                 fputcsv($csv, $line, $sep, $enc); // stores the former line into $csv_output
                 $vid = $cur['vid'];
                 $line = array_fill(0, $nbf, ''); // creates an array full of empty string
                 $line[0] = $vid_; // the first field is a 'clean' vote id (not the one stored in database)
                 if ($this->isMode(self::MODE_XIDENT)) { // if the mode is non anonymous
-                    if (array_key_exists($vid, $users) && is_array($users[$vid])) { // and if the user data can be found
-                        $line[1] = $users[$vid]['nom']; // adds the user data (in the first fields of the line)
-                        $line[2] = $users[$vid]['prenom'];
-                        $line[3] = $users[$vid]['promo'];
+                    if (array_key_exists($vid, $users)) { // and if the user data can be found
+                        $line[1] = $users[$vid]->lastName(); // adds the user data (in the first fields of the line)
+                        $line[2] = $users[$vid]->firstName();;
+                        $line[3] = $users[$vid]->promo();
                     }
                 }
                 $vid_++;
@@ -239,7 +233,6 @@ class Survey
                 }
                 $line[$fid] .= $a; // adds the current answer to the correct field
             }
-            $cur = $res->next(); // gets next answer
         }
         fputcsv($csv, $line, $sep, $enc); // stores the last line into $csv_output
         return $csv_output;
index f5cd0f4..889346e 100644 (file)
@@ -116,20 +116,18 @@ class XnetEventsModule extends PLModule
         }
 
         $page->assign('archive', $archive);
-        $evenements = XDB::iterator(
-                "SELECT  e.*, LEFT(10, e.debut) AS first_day, LEFT(10, e.fin) AS last_day,
-                         IF(e.deadline_inscription, e.deadline_inscription >= LEFT(NOW(), 10),
-                            1) AS inscr_open, e.deadline_inscription,
-                         u.nom, u.prenom, u.promo, a.alias,
-                         MAX(ep.nb) IS NOT NULL AS inscrit, MAX(ep.paid) AS paid
-                  FROM  groupex.evenements  AS e
-            INNER JOIN  x4dat.auth_user_md5 AS u ON u.user_id = e.organisateur_uid
-            INNER JOIN  x4dat.aliases       AS a ON (a.type = 'a_vie' AND a.id = u.user_id)
-             LEFT JOIN  groupex.evenements_participants AS ep ON (ep.eid = e.eid AND ep.uid = {?})
-                 WHERE  asso_id = {?}
-                   AND  archive = " . ($archive ? "1 " : "0 ")
-              . "GROUP BY  e.eid
-                 ORDER BY  inscr_open DESC, debut DESC", S::v('uid'), $globals->asso('id'));
+        $evenements = XDB::iterator('SELECT  e.*, LEFT(10, e.debut) AS first_day, LEFT(10, e.fin) AS last_day,
+                                             IF(e.deadline_inscription,
+                                                     e.deadline_inscription >= LEFT(NOW(), 10),
+                                                     1) AS inscr_open,
+                                             e.deadline_inscription,
+                                             MAX(ep.nb) IS NOT NULL AS inscrit, MAX(ep.paid) AS paid
+                                       FROM  groupex.evenements              AS e
+                                  LEFT JOIN  groupex.evenements_participants AS ep ON (ep.eid = e.eid AND ep.uid = {?})
+                                      WHERE  asso_id = {?} AND  archive = {?}
+                                   GROUP BY  e.eid
+                                   ORDER BY  inscr_open DESC, debut DESC',
+                                     S::i('uid'), $globals->asso('id'), $archive ? 1 : 0);
 
         $evts = array();
         $undisplayed_events = 0;
@@ -142,14 +140,12 @@ class XnetEventsModule extends PLModule
             }
 
             $e['show_participants'] = ($e['show_participants'] && (is_member() || may_update()));
-            $res = XDB::query(
-                "SELECT titre, details, montant, ei.item_id, nb, ep.paid
-                   FROM groupex.evenements_items AS ei
-              LEFT JOIN groupex.evenements_participants AS ep
-                        ON (ep.eid = ei.eid AND ep.item_id = ei.item_id AND uid = {?})
-                  WHERE ei.eid = {?}",
-                    S::v('uid'), $e['eid']);
-            $e['moments'] = $res->fetchAllAssoc();
+            $e['moments'] = XDB::fetchAllAssoc('SELECT  titre, details, montant, ei.item_id, nb, ep.paid
+                                                  FROM  groupex.evenements_items AS ei
+                                             LEFT JOIN  groupex.evenements_participants AS ep
+                                                           ON (ep.eid = ei.eid AND ep.item_id = ei.item_id AND ep.uid = {?})
+                                                 WHERE ei.eid = {?}',
+                                                S::i('uid'), $e['eid']);
 
             $e['topay'] = 0;
             $e['paid']  = $e['moments'][0]['paid'];
@@ -298,7 +294,7 @@ class XnetEventsModule extends PLModule
 
         $admin = may_update();
 
-        $tri = (Env::v('order') == 'alpha' ? 'promo, nom, prenom' : 'nom, prenom, promo');
+        $tri = (Env::v('order') == 'alpha' ? UserFilter::sortByPromo() : UserFilter::sortByName());
 
         $page->assign('participants',
                       get_event_participants($evt, $item_id, $tri));
@@ -334,7 +330,7 @@ class XnetEventsModule extends PLModule
         $page->assign('admin', may_update());
 
         if (may_update()) {
-            $page->assign('participants', get_event_participants($evt, null, 'promo, nom, prenom'));
+            $page->assign('participants', get_event_participants($evt, null, UserFilter::sortByPromo()));
         }
         $page->register_function('display_ical', 'display_ical');
         $page->assign_by_ref('e', $evt);
@@ -597,63 +593,26 @@ class XnetEventsModule extends PLModule
             $page->assign('moments', $evt['moments']);
         }
 
-        $tri = (Env::v('order') == 'alpha' ? 'promo, nom, prenom' : 'nom, prenom, promo');
-        $whereitemid = is_null($item_id) ? '' : "AND ep.item_id = $item_id";
-        $res = XDB::iterRow(
-                    'SELECT  UPPER(SUBSTRING(IF(u.nom IS NULL, m.nom,
-                                                IF(u.nom_usage<>"", u.nom_usage, u.nom)), 1, 1)),
-                             COUNT(DISTINCT ep.uid)
-                       FROM  groupex.evenements_participants AS ep
-                 INNER JOIN  groupex.evenements AS e ON (ep.eid = e.eid)
-                  LEFT JOIN  groupex.membres AS m ON ( ep.uid = m.uid AND e.asso_id = m.asso_id)
-                  LEFT JOIN  auth_user_md5   AS u ON ( u.user_id = ep.uid )
-                      WHERE  ep.eid = {?} '.$whereitemid . '
-                   GROUP BY  UPPER(SUBSTRING(IF(u.nom IS NULL,m.nom,u.nom), 1, 1))', $evt['eid']);
-
-        $alphabet = array();
-        $nb_tot = 0;
-        while (list($char, $nb) = $res->next()) {
-            $alphabet[ord($char)] = $char;
-            $nb_tot += $nb;
-            if (Env::has('initiale') && $char == strtoupper(Env::v('initiale'))) {
-                $tot = $nb;
-            }
-        }
-        ksort($alphabet);
-        $page->assign('alphabet', $alphabet);
-
+        $page->assign('alphabet', array());
         if ($evt['paiement_id']) {
-            $res = XDB::iterator(
-                "SELECT IF(u.nom_usage<>'', u.nom_usage, u.nom) AS nom, u.prenom,
-                        u.promo, a.alias AS email, t.montant
-                   FROM {$globals->money->mpay_tprefix}transactions AS t
-             INNER JOIN auth_user_md5 AS u ON(t.uid = u.user_id)
-             INNER JOIN aliases AS a ON (a.id = t.uid AND a.type='a_vie' )
-              LEFT JOIN groupex.evenements_participants AS ep ON(ep.uid = t.uid AND ep.eid = {?})
-                  WHERE t.ref = {?} AND ep.uid IS NULL",
-                  $evt['eid'], $evt['paiement_id']);
-            $page->assign('oublis', $res->total());
-            $page->assign('oubliinscription', $res);
-        }
-
-        $absents = XDB::iterator("SELECT  p.uid,
-                                          IF(m.origine = 'X', IF(u.nom_usage != '', u.nom_usage, u.nom), m.nom) AS nom,
-                                          IF(m.origine = 'X', u.prenom, u.prenom) AS prenom,
-                                          IF(m.origine = 'X', u.promo, m.origine) AS promo,
-                                          IF(m.origine = 'X', FIND_IN_SET('femme', u.flags), m.sexe) AS sexe,
-                                          IF(m.origine = 'X', a.alias, m.email) AS email
-                                    FROM  groupex.evenements_participants AS p
-                              INNER JOIN  groupex.membres                 AS m USING(uid)
-                               LEFT JOIN  groupex.evenements_participants AS p2 ON (p2.uid = m.uid AND p2.eid = p.eid
-                                                                                    AND p2.nb != 0)
-                               LEFT JOIN  auth_user_md5                   AS u ON (u.user_id = m.uid)
-                               LEFT JOIN  aliases                         AS a ON (a.id = u.user_id AND a.type = 'a_vie')
-                                   WHERE  p.eid = {?} AND p2.eid IS NULL
-                                       " . (Env::v('initiale') ? " AND IF(u.nom IS NULL, m.nom,
-                                          IF(u.nom_usage<>'', u.nom_usage, u.nom)) LIKE '" . Env::v('initiale') . "%'"
-                                         : "") . "
-                                GROUP BY  m.uid
-                                ORDER BY  nom, prenom, promo", $evt['eid']);
+            $infos = User::getBulkUsersWithUIDs(
+                            XDB::fetchAllAssoc('SELECT  t.uid, t.montant
+                                                  FROM  ' . $globals->money->mpay_tprefix . 'transactions AS t
+                                             LEFT JOIN  groupex.evenements_participants AS ep ON(ep.uid = t.uid AND ep.eid = {?})
+                                                 WHERE  t.ref = {?} AND ep.uid IS NULL',
+                                               $evt['eid'], $evt['paiement_id']),
+                            'uid', 'user');
+            $page->assign('oublis', count($infos));
+            $page->assign('oubliinscription', $infos);
+        }
+
+        $absents = User::getBulkUsersFromDB('SELECT  p.uid
+                                               FROM  groupex.evenements_participants AS p
+                                          LEFT JOIN  groupex.evenements_participants AS p2 ON (p2.uid = p.uid
+                                                                                               AND p2.eid = p.eid
+                                                                                               AND p2.nb != 0)
+                                              WHERE  p.eid = {?} AND p2.eid IS NULL
+                                           GROUP BY  p.uid', $evt['eid']);
 
         $ofs   = Env::i('offset');
         $tot   = (Env::v('initiale') ? $tot : $nb_tot);
@@ -672,11 +631,10 @@ class XnetEventsModule extends PLModule
             $page->assign('links', $links);
         }
 
-
         $page->assign('absents', $absents);
         $page->assign('participants',
-                      get_event_participants($evt, $item_id, $tri,
-                                             "LIMIT ".($ofs*NB_PER_PAGE).", ".NB_PER_PAGE));
+                      get_event_participants($evt, $item_id, UserFilter::sortByName(),
+                                             NB_PER_PAGE, $ofs * NB_PER_PAGE));
     }
 }
 
index fd17320..57cffaf 100644 (file)
@@ -27,28 +27,23 @@ function get_event_detail($eid, $item_id = false, $asso_id = null)
     if (is_null($asso_id)) {
         $asso_id = $globals->asso('id');
     }
-    $res = XDB::query(
-        "SELECT SUM(nb) AS nb_tot, COUNT(DISTINCT ep.uid) AS nb, e.*,
-                IF(e.deadline_inscription, e.deadline_inscription >= LEFT(NOW(), 10),
-                   1) AS inscr_open,
-                LEFT(10, e.debut) AS first_day, LEFT(10, e.fin) AS last_day,
-                LEFT(NOW(), 10) AS now,
-                ei.titre,
-                al.vid AS absent_list, pl.vid AS participant_list,
-                a.nom, a.prenom, a.promo, aa.alias
-           FROM groupex.evenements              AS e
-     INNER JOIN x4dat.auth_user_md5             AS a  ON a.user_id = e.organisateur_uid
-     INNER JOIN x4dat.aliases                   AS aa ON (aa.type = 'a_vie' AND aa.id = a.user_id)
-     INNER JOIN groupex.evenements_items        AS ei ON (e.eid = ei.eid)
-      LEFT JOIN groupex.evenements_participants AS ep ON(e.eid = ep.eid AND ei.item_id = ep.item_id)
-      LEFT JOIN virtual AS al ON(al.type = 'evt' AND al.alias = CONCAT(short_name, {?}))
-      LEFT JOIN virtual AS pl ON(pl.type = 'evt' AND pl.alias = CONCAT(short_name, {?}))
-          WHERE (e.eid = {?} OR e.short_name = {?}) AND ei.item_id = {?} AND e.asso_id = {?}
-       GROUP BY ei.item_id",
-       '-absents@'.$globals->xnet->evts_domain,
-       '-participants@'.$globals->xnet->evts_domain,
-       $eid, $eid, $item_id ? $item_id : 1, $asso_id);
-
+    $res = XDB::query('SELECT  SUM(nb) AS nb_tot, COUNT(DISTINCT ep.uid) AS nb, e.*,
+                               IF(e.deadline_inscription,
+                                     e.deadline_inscription >= LEFT(NOW(), 10),
+                                     1) AS inscr_open,
+                               LEFT(10, e.debut) AS start_day, LEFT(10, e.fin) AS last_day,
+                               LEFT(NOW(), 10) AS now,
+                               ei.titre, al.vid AS absent_list, pl.vid AS participant_list
+                         FROM  groupex.evenements              AS e
+                   INNER JOIN  groupex.evenements_items        AS ei ON (e.eid = ei.eid)
+                    LEFT JOIN  groupex.evenements_participants AS ep ON(e.eid = ep.eid AND ei.item_id = ep.item_id)
+                    LEFT JOIN  virtual AS al ON(al.type = \'evt\' AND al.alias = CONCAT(short_name, {?}))
+                    LEFT JOIN  virtual AS pl ON(pl.type = \'evt\' AND pl.alias = CONCAT(short_name, {?}))
+                        WHERE  (e.eid = {?} OR e.short_name = {?}) AND ei.item_id = {?} AND e.asso_id = {?}
+                     GROUP BY  ei.item_id',
+                   '-absents@'.$globals->xnet->evts_domain,
+                   '-participants@'.$globals->xnet->evts_domain,
+                   $eid, $eid, $item_id ? $item_id : 1, $asso_id);
     $evt = $res->fetchOneAssoc();
 
     if (!$evt) {
@@ -60,28 +55,24 @@ function get_event_detail($eid, $item_id = false, $asso_id = null)
 
     // smart calculation of the total number
     if (!$item_id) {
-        $res = XDB::query(
-               "SELECT MAX(nb)
-                  FROM groupex.evenements              AS e
-            INNER JOIN groupex.evenements_items        AS ei ON (e.eid = ei.eid)
-             LEFT JOIN groupex.evenements_participants AS ep
-                       ON (e.eid = ep.eid AND ei.item_id = ep.item_id)
-                 WHERE e.eid = {?}
-              GROUP BY ep.uid", $evt['eid']);
+        $res = XDB::query('SELECT  MAX(nb)
+                             FROM  groupex.evenements              AS e
+                       INNER JOIN  groupex.evenements_items        AS ei ON (e.eid = ei.eid)
+                        LEFT JOIN  groupex.evenements_participants AS ep ON (e.eid = ep.eid AND ei.item_id = ep.item_id)
+                            WHERE  e.eid = {?}
+                         GROUP BY  ep.uid', $evt['eid']);
         $evt['nb_tot'] = array_sum($res->fetchColumn());
         $evt['titre'] = '';
         $evt['item_id'] = 0;
     }
 
-    $res = XDB::query(
-        "SELECT titre, details, montant, ei.item_id, nb, ep.paid, FIND_IN_SET('notify_payment', ep.flags) AS notify_payment
-           FROM groupex.evenements_items        AS ei
-      LEFT JOIN groupex.evenements_participants AS ep
-                ON (ep.eid = ei.eid AND ep.item_id = ei.item_id AND uid = {?})
-          WHERE ei.eid = {?}",
-            S::v('uid'), $evt['eid']);
-    $evt['moments'] = $res->fetchAllAssoc();
-
+    $evt['moments'] = XDB::fetchAllAssoc('SELECT  titre, details, montant, ei.item_id, nb,
+                                                  ep.paid, FIND_IN_SET(\'notify_payment\', ep.flags) AS notify_payment
+                                            FROM  groupex.evenements_items        AS ei
+                                       LEFT JOIN  groupex.evenements_participants AS ep ON (ep.eid = ei.eid AND ep.item_id = ei.item_id
+                                                                                                             AND uid = {?})
+                                           WHERE  ei.eid = {?}',
+                                           S::i('uid'), $evt['eid']);
     $evt['topay'] = 0;
     $evt['paid'] = 0;
     $evt['notify_payment'] = false;
@@ -94,12 +85,10 @@ function get_event_detail($eid, $item_id = false, $asso_id = null)
         $evt['notify_payment'] = $evt['notify_payment'] || $m['notify_payment'];
     }
 
-    $req = XDB::query(
-        "SELECT montant
-           FROM {$globals->money->mpay_tprefix}transactions AS t
-         WHERE ref = {?} AND uid = {?}", $evt['paiement_id'], S::v('uid'));
-    $montants = $req->fetchColumn();
-
+    $montants = XDB::fetchColumn('SELECT  montant
+                                    FROM  ' . $globals->money->mpay_tprefix . 'transactions AS t
+                                   WHERE  ref = {?} AND uid = {?}',
+                                   $evt['paiement_id'], S::v('uid'));
     $evt['telepaid'] = 0;
     foreach ($montants as $m) {
         $p = strtr(substr($m, 0, strpos($m, 'EUR')), ',', '.');
@@ -115,85 +104,60 @@ function get_event_detail($eid, $item_id = false, $asso_id = null)
 // }}}
 
 // {{{ function get_event_participants()
-function get_event_participants(&$evt, $item_id, $tri, $limit = '') {
+function get_event_participants(&$evt, $item_id, array $tri = array(), $count = null, $offset = null)
+{
     global $globals;
 
-    if (Env::has('initiale')) {
-        $where = 'AND IF(u.nom IS NULL, m.nom,
-                         IF(u.nom_usage<>"", u.nom_usage, u.nom))
-                  LIKE "'.addslashes(Env::v('initiale')).'%"';
-    } else {
-        $where = '';
-    }
-
     $eid    = $evt['eid'];
     $money  = $evt['money'] && (function_exists('may_update')) && may_update();
     $pay_id = $evt['paiement_id'];
 
-    $query =
-          "SELECT  IF(m.origine != 'X',m.nom,IF(u.nom_usage<>'', u.nom_usage, u.nom)) AS nom,
-                   IF(m.origine != 'X',m.prenom,u.prenom) AS prenom,
-                   IF(m.origine != 'X','extérieur',u.promo) AS promo,
-                   IF(m.origine != 'X' OR u.perms = 'pending',m.email,a.alias) AS email,
-                   IF(m.origine != 'X',m.sexe,FIND_IN_SET('femme', u.flags)) AS femme,
-                   m.perms='admin' AS admin,
-                   (m.origine = 'X' OR m.origine IS NULL) AS x,
-                   ep.uid, SUM(ep.paid) AS paid, SUM(ep.nb) AS nb,
-                   FIND_IN_SET('notify_payment', ep.flags) AS notify_payment
-             FROM  groupex.evenements_participants AS ep
-       INNER JOIN  groupex.evenements AS e ON (ep.eid = e.eid)
-        LEFT JOIN  groupex.membres AS m ON ( ep.uid = m.uid AND e.asso_id = m.asso_id)
-        LEFT JOIN  auth_user_md5   AS u ON ( u.user_id = ep.uid )
-        LEFT JOIN  aliases         AS a ON ( a.id = ep.uid AND a.type='a_vie' )
-            WHERE  ep.eid = {?}
-                    ".(($item_id)?" AND item_id = $item_id":"")."
-                    $where
-         GROUP BY  ep.uid
-         ORDER BY  $tri $limit";
+    $append = $item_id ? XDB::foramt(' AND ep.item_id = {?}', $item_id) : '';
+    $query = XDB::fetchAllAssoc('uid', 'SELECT  ep.uid, SUM(ep.paid) AS paid, SUM(ep.nb) AS nb,
+                                                FIND_IN_SET(\'notify_payment\', ep.flags) AS notify_payment
+                                          FROM  groupex.evenements_participants AS ep
+                                         WHERE  ep.eid = {?} AND nb > 0 ' . $append . '
+                                      GROUP BY  ep.uid', $eid);
+    $uf = new UserFilter(new UFC_True(), $tri);
+    $users = User::getBulkUsersWithUIDs($uf->filter(array_keys($query), $count, $offset));
+    $tab = array();
+    foreach ($users as $user) {
+        $uid = $user->id();
+        $tab[$uid] = $query[$uid];
+        $tab[$uid]['user'] = $user;
+    }
 
     if ($item_id) {
-        $res = XDB::query($query, $eid);
-        return $res->fetchAllAssoc();
+        return $tab;
     }
 
-    $res = XDB::iterator($query, $eid);
-    $tab = array();
-    $user = 0;
-
     $evt['adminpaid'] = 0;
     $evt['telepaid']  = 0;
     $evt['topay']     = 0;
     $evt['paid']      = 0;
-    while ($u = $res->next()) {
-        if ($u['nb'] == 0) {
-            continue;
-        }
+    foreach ($tab as $uid=>&$u) {
         $u['adminpaid'] = $u['paid'];
         $u['montant'] = 0;
         if ($money && $pay_id) {
-            $res_ = XDB::query(
-                "SELECT montant
-                   FROM {$globals->money->mpay_tprefix}transactions AS t
-                  WHERE ref = {?} AND uid = {?}",
-                $pay_id, $u['uid']);
-            $montants = $res_->fetchColumn();
+            $montants = XDB::fetchColumn('SELECT  montant
+                                            FROM  ' . $globals->money->mpay_tprefix . 'transactions AS t
+                                           WHERE  ref = {?} AND uid = {?}',
+                                         $pay_id, $uid);
             foreach ($montants as $m) {
                 $p = strtr(substr($m, 0, strpos($m, "EUR")), ",", ".");
                 $u['paid'] += trim($p);
             }
         }
         $u['telepayment'] = $u['paid'] - $u['adminpaid'];
-        $res_ = XDB::iterator(
-                "SELECT  ep.nb, ep.item_id, ei.montant
-                   FROM  groupex.evenements_participants AS ep
-             INNER JOIN  groupex.evenements_items AS ei ON (ei.eid = ep.eid AND ei.item_id = ep.item_id)
-                  WHERE  ep.eid = {?} AND ep.uid = {?}",
-            $eid, $u['uid']);
+        $res_ = XDB::iterator('SELECT  ep.nb, ep.item_id, ei.montant
+                                 FROM  groupex.evenements_participants AS ep
+                           INNER JOIN  groupex.evenements_items AS ei ON (ei.eid = ep.eid AND ei.item_id = ep.item_id)
+                                WHERE  ep.eid = {?} AND ep.uid = {?}',
+                            $eid, $uid);
         while ($i = $res_->next()) {
             $u[$i['item_id']] = $i['nb'];
             $u['montant'] += $i['montant']*$i['nb'];
         }
-        $tab[] = $u;
         $evt['telepaid']  += $u['telepayment'];
         $evt['adminpaid'] += $u['adminpaid'];
         $evt['paid']      += $u['paid'];
@@ -310,29 +274,27 @@ function event_change_shortname(&$page, $eid, $old, $new)
                 $new.'-participants@'.$globals->xnet->evts_domain);
 
         $lastid = XDB::insertId();
-        XDB::execute(
-          "INSERT IGNORE INTO virtual_redirect (
-                SELECT {?} AS vid, IF(u.nom IS NULL, m.email, CONCAT(a.alias, {?})) AS redirect
-                  FROM groupex.evenements_participants AS ep
-             LEFT JOIN groupex.membres AS m ON (ep.uid = m.uid)
-             LEFT JOIN auth_user_md5   AS u ON (u.user_id = ep.uid)
-             LEFT JOIN aliases         AS a ON (a.id = ep.uid AND a.type = 'a_vie')
-                 WHERE ep.eid = {?} AND ep.nb > 0
-              GROUP BY ep.uid)",
+        XDB::execute('INSERT IGNORE INTO  virtual_redirect (
+                                  SELECT  {?} AS vid, IF(al.alias IS NULL, a.email, CONCAT(al.alias, {?})) AS redirect
+                                    FROM  groupex.evenements_participants AS ep
+                               LEFT JOIN  accounts        AS a ON (ep.uid = a.uid)
+                               LEFT JOIN  aliases         AS al ON (al.id = a.uid AND al.type = \'a_vie\')
+                                   WHERE  ep.eid = {?} AND ep.nb > 0
+                                GROUP BY  ep.uid)',
               $lastid, '@'.$globals->mail->domain, $eid);
 
         XDB::execute("INSERT INTO virtual SET type = 'evt', alias = {?}",
                 $new.'-absents@'.$globals->xnet->evts_domain);
 
         $lastid = XDB::insertId();
-        XDB::execute("INSERT IGNORE INTO virtual_redirect (
-            SELECT {?} AS vid, IF(a.alias IS NULL, m.email, CONCAT(a.alias, {?})) AS redirect
-                  FROM groupex.membres AS m
-             LEFT JOIN groupex.evenements_participants AS ep ON (ep.uid = m.uid AND ep.eid = {?})
-             LEFT JOIN auth_user_md5   AS u ON (u.user_id = m.uid)
-             LEFT JOIN aliases         AS a ON (a.id = m.uid AND a.type = 'a_vie')
-                 WHERE m.asso_id = {?} AND ep.uid IS NULL
-              GROUP BY m.uid)",
+        XDB::execute("INSERT IGNORE INTO  virtual_redirect (
+                                  SELECT  {?} AS vid, IF(al.alias IS NULL, a.email, CONCAT(al.alias, {?})) AS redirect
+                                    FROM  groupex.membres AS m
+                               LEFT JOIN  groupex.evenements_participants AS ep ON (ep.uid = m.uid AND ep.eid = {?})
+                               LEFT JOIN  accounts        AS a ON (a.uid = m.uid)
+                               LEFT JOIN  aliases         AS al ON (al.id = a.uid AND al.type = 'a_vie')
+                                   WHERE  m.asso_id = {?} AND ep.uid IS NULL
+                                GROUP BY  m.uid)",
              $lastid, "@".$globals->mail->domain, $eid, $globals->asso('id'));
 
         return $new;
@@ -360,7 +322,7 @@ function make_event_date(&$e)
 {
     $start     = strtotime($e['debut']);
     $end       = strtotime($e['fin']);
-    $first_day = strtotime($e['first_day']);
+    $first_day = @strtotime($e['first_day']);
     $last_day  = strtotime($e['last_day']);
     unset($e['debut'], $e['fin'], $e['first_day'], $e['last_day']);
 
index e6ebd1e..bb1cda1 100644 (file)
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
  ***************************************************************************/
 
-function get_infos($email)
-{
-    global $globals;
-    // look for uid instead of email if numeric
-    $field = is_numeric($email) ? 'uid' : 'email';
-
-    if ($field == 'email') {
-        $email = strtolower($email);
-        if (strpos($email, '@') === false) {
-            $email .= '@m4x.org';
-        }
-        list($mbox,$dom) = explode('@', $email);
-    }
-
-    $res = XDB::query(
-            "SELECT  uid, nom, prenom, email, email AS email2, perms='admin', origine, comm, sexe
-               FROM  groupex.membres
-              WHERE  $field = {?} AND asso_id = {?}", $email, $globals->asso('id'));
-
-    if ($res->numRows()) {
-        $user = $res->fetchOneAssoc();
-        if ($user['origine'] == 'X') {
-            $res = XDB::query("SELECT nom, prenom, promo, FIND_IN_SET('femme', flags) AS sexe
-                                 FROM auth_user_md5
-                                WHERE user_id = {?}", $user['uid']);
-            $user = array_merge($user, $res->fetchOneAssoc());
-        }
-        return $user;
-    } elseif ($dom == 'polytechnique.org' || $dom == 'm4x.org') {
-        $res = XDB::query(
-                "SELECT  user_id AS uid, u.promo,
-                         IF(u.nom_usage<>'', u.nom_usage, u.nom) AS nom,
-                         u.prenom, b.alias,
-                         CONCAT(b.alias, '@m4x.org') AS email,
-                         CONCAT(b.alias, '@polytechnique.org') AS email2,
-                         m.perms = 'admin' AS perms, m.origine, m.comm,
-                         FIND_IN_SET('femme', u.flags) AS sexe
-                   FROM  auth_user_md5   AS u
-             INNER JOIN  aliases         AS a ON ( u.user_id = a.id AND a.type != 'homonyme' )
-             INNER JOIN  aliases         AS b ON ( u.user_id = b.id AND b.type = 'a_vie' )
-              LEFT JOIN  groupex.membres AS m ON ( m.uid = u.user_id AND asso_id={?})
-                  WHERE  a.alias = {?} AND u.user_id < 50000", $globals->asso('id'), $mbox);
-        return $res->fetchOneAssoc();
-    }
-
-    return null;
-}
-
 
 class XnetGrpModule extends PLModule
 {
@@ -107,7 +59,6 @@ class XnetGrpModule extends PLModule
     function handler_index(&$page, $arg = null)
     {
         global $globals, $platal;
-
         if (!is_null($arg)) {
             return PL_NOT_FOUND;
         }
@@ -130,10 +81,9 @@ class XnetGrpModule extends PLModule
                             Env::i('unread'), S::i('uid'));
                 pl_redirect("#art" . Env::i('unread'));
             }
-            $arts = XDB::iterator("SELECT a.*, u.nom, u.prenom, u.promo, u.hruid,
-                                          FIND_IN_SET('photo', a.flags) AS photo
+            // XXX: Fix promo_min; promo_max
+            $arts = XDB::iterator("SELECT a.*, FIND_IN_SET('photo', a.flags) AS photo
                                      FROM groupex.announces AS a
-                               INNER JOIN auth_user_md5 AS u USING(user_id)
                                 LEFT JOIN groupex.announces_read AS r ON (r.user_id = {?} AND r.announce_id = a.id)
                                     WHERE asso_id = {?} AND peremption >= CURRENT_DATE()
                                           AND (promo_min = 0 OR promo_min <= {?})
@@ -151,11 +101,10 @@ class XnetGrpModule extends PLModule
                                    S::i('uid'), $globals->asso('id'), S::i('promo'), S::i('promo'));
             $page->assign('article_index', $index);
         } else {
-            $arts = XDB::iterator("SELECT a.*, u.nom, u.prenom, u.promo, FIND_IN_SET('photo', a.flags) AS photo
+            $arts = XDB::iterator("SELECT a.*, FIND_IN_SET('photo', a.flags) AS photo
                                      FROM groupex.announces AS a
-                               INNER JOIN auth_user_md5 AS u USING(user_id)
                                     WHERE asso_id = {?} AND peremption >= CURRENT_DATE()
-                                          AND FIND_IN_SET('public', u.flags)",
+                                          AND FIND_IN_SET('public', a.flags)",
                                   $globals->asso('id'));
         }
         if (may_update()) {
@@ -166,12 +115,12 @@ class XnetGrpModule extends PLModule
             $page->assign('requests', $subs_valid->numRows());
         }
 
-        if (!S::has('core_rss_hash')) {
+        if (!S::hasAuthToken()) {
             $page->setRssLink("Polytechnique.net :: {$globals->asso("nom")} :: News publiques",
                               $platal->ns . "rss/rss.xml");
         } else {
             $page->setRssLink("Polytechnique.net :: {$globals->asso("nom")} :: News",
-                              $platal->ns . 'rss/'.S::v('hruid') .'/'.S::v('core_rss_hash').'/rss.xml');
+                              $platal->ns . 'rss/'.S::v('hruid') .'/'.S::v('token').'/rss.xml');
         }
 
         $page->assign('articles', $arts);
@@ -181,13 +130,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');
@@ -226,10 +171,8 @@ class XnetGrpModule extends PLModule
             S::assert_xsrf_token();
 
             $flags = new PlFlagSet('wiki_desc');
-            if (Post::has('notif_unsub') && Post::i('notif_unsub') == 1) {
-                $flags->addFlag('notif_unsub');
-            }
-            $site = trim(Post::v('site'));
+            $flags->addFlag('notif_unsub', Post::i('notif_unsub') == 1);
+            $site = Post::t('site');
             if ($site && ($site != "http://")) {
                 $scheme = parse_url($site, PHP_URL_SCHEME);
                 if (!$scheme) {
@@ -238,9 +181,9 @@ class XnetGrpModule extends PLModule
             } else {
                 $site = "";
             }
-            if (S::admin()) {
+            if (S::has_perms()) {
                 if (Post::v('mail_domain') && (strstr(Post::v('mail_domain'), '.') === false)) {
-                    $page->trigError("le domaine doit être un FQDN (aucune modif effectuée) !!!");
+                    $page->trigError("Le domaine doit être un FQDN (aucune modification effectuée) !!!");
                     return;
                 }
                 XDB::execute(
@@ -277,13 +220,18 @@ class XnetGrpModule extends PLModule
                       $flags, $globals->asso('id'));
             }
 
+
             if ($_FILES['logo']['name']) {
-                $logo = file_get_contents($_FILES['logo']['tmp_name']);
-                $mime = $_FILES['logo']['type'];
-                XDB::execute('UPDATE groupex.asso
-                                 SET logo={?}, logo_mime={?}
-                               WHERE id={?}', $logo, $mime,
-                             $globals->asso('id'));
+                $upload = PlUpload::get($_FILES['logo'], $globals->asso('id'), 'asso.logo', true);
+                if (!$upload) {
+                    $page->trigError("Impossible de télécharger le logo");
+                } else {
+                    XDB::execute('UPDATE groupex.asso
+                                     SET logo={?}, logo_mime={?}
+                                   WHERE id={?}', $upload->getContents(), $upload->contentType(),
+                                 $globals->asso('id'));
+                    $upload->rm();
+                }
             }
 
             pl_redirect('../'.Post::v('diminutif', $globals->asso('diminutif')).'/edit');
@@ -371,103 +319,33 @@ class XnetGrpModule extends PLModule
         }
         $page->changeTpl('xnetgrp/annuaire.tpl');
 
-        $sort = Env::v('order');
-        switch (Env::v('order')) {
-            case 'promo'    : $group = 'promo';    $tri = 'promo_o DESC, nom, prenom'; break;
-            case 'promo_inv': $group = 'promo';    $tri = 'promo_o, nom, prenom'; break;
-            case 'alpha_inv': $group = 'initiale'; $tri = 'nom DESC, prenom DESC, promo'; break;
-            default         : $group = 'initiale'; $tri = 'nom, prenom, promo'; $sort = 'alpha';
+        $sort = Env::s('order', 'directory_name');
+        $ofs  = Env::i('offset');
+        if ($ofs < 0) {
+            $ofs = 0;
         }
-        $page->assign('sort', $sort);
-
-        if ($group == 'initiale') {
-            $res = XDB::iterRow(
-                        'SELECT  UPPER(SUBSTRING(
-                                    IF(m.origine="X", IF(u.nom_usage<>"", u.nom_usage, u.nom),m.nom),
-                                     1, 1)) as letter, COUNT(*)
-                           FROM  groupex.membres AS m
-                      LEFT JOIN  auth_user_md5   AS u ON ( u.user_id = m.uid)
-                          WHERE  asso_id = {?} and (u.perms != \'pending\' OR m.email IS NOT NULL)
-                       GROUP BY  letter
-                       ORDER BY  letter', $globals->asso('id'));
+
+        $sdesc = $sort{0} == '-';
+        $sf    = $sdesc ? substr($sort, 1) : $sort;
+        if ($sf == 'promo') {
+            $se = new UFO_Promo(null, $sdesc);
         } else {
-            $res = XDB::iterRow(
-                        'SELECT  IF(m.origine="X",u.promo,
-                                    IF(m.origine="ext", "extérieur", "personne morale")) AS promo,
-                                 COUNT(*), IF(m.origine="X",u.promo,"") AS promo_o
-                           FROM  groupex.membres AS m
-                      LEFT JOIN  auth_user_md5   AS u ON ( u.user_id = m.uid )
-                          WHERE  asso_id = {?}
-                       GROUP BY  promo
-                       ORDER BY  promo_o DESC', $globals->asso('id'));
-        }
-        $alphabet = array();
-        $nb_tot = 0;
-        while (list($char, $nb) = $res->next()) {
-            $alphabet[] = $char;
-            $nb_tot += $nb;
-            if (Env::has($group) && $char == strtoupper(Env::v($group))) {
-                $tot = $nb;
-            }
-        }
-        $page->assign('group', $group);
-        $page->assign('request_group', Env::v($group));
-        $page->assign('only_admin', Env::has('admin'));
-        $page->assign('alphabet', $alphabet);
-        $page->assign('nb_tot',   $nb_tot);
-
-        $ofs   = Env::i('offset');
-        $tot   = Env::v($group) ? $tot : $nb_tot;
-        $nbp   = intval(($tot-1)/NB_PER_PAGE);
-        $links = array();
-        if ($ofs) {
-            $links['précédent'] = $ofs-1;
-        }
-        for ($i = 0; $i <= $nbp; $i++) {
-            $links[(string)($i+1)] = $i;
-        }
-        if ($ofs < $nbp) {
-            $links['suivant'] = $ofs+1;
-        }
-        if (count($links)>1) {
-            $page->assign('links', $links);
+            $se = new UFO_Name($sf, null, null, $sdesc);
         }
 
-        $ini = '';
-        if (Env::has('initiale')) {
-            $ini = 'AND IF(m.origine="X",
-                           IF(u.nom_usage<>"", u.nom_usage, u.nom),
-                           m.nom) LIKE "'.addslashes(Env::v('initiale')).'%"';
-        } elseif (Env::has('promo')) {
-            $ini = 'AND IF(m.origine="X", u.promo, IF(m.origine="ext", "extérieur", "personne morale")) = "'
-                 .addslashes(Env::v('promo')).'"';
-        } elseif (Env::has('admin')) {
-            $ini = 'AND m.perms = "admin"';
+        if (Env::b('admin')) {
+            $uf = $globals->asso()->getAdmins(null, $se);
+        } else {
+            $uf = $globals->asso()->getMembers(null, $se);
         }
-
-        $ann = XDB::iterator(
-                  "SELECT  IF(m.origine='X',IF(u.nom_usage<>'', u.nom_usage, u.nom) ,m.nom) AS nom,
-                           IF(m.origine='X',u.prenom,m.prenom) AS prenom,
-                           IF(m.origine='X', u.promo, IF(m.origine='ext', 'extérieur', 'personne morale')) AS promo,
-                           IF(m.origine='X',u.promo,'') AS promo_o,
-                           IF(m.origine='X' AND u.perms != 'pending',a.alias,m.email) AS email,
-                           IF(m.origine='X',FIND_IN_SET('femme', u.flags), m.sexe) AS femme,
-                           m.perms='admin' AS admin,
-                           m.origine='X' AS x,
-                           u.perms!='pending' AS inscrit,
-                           m.comm as comm,
-                           m.uid, IF(e.email IS NULL AND FIND_IN_SET('googleapps', u.mail_storage) = 0, NULL, 1) AS actif
-                     FROM  groupex.membres AS m
-                LEFT JOIN  auth_user_md5   AS u ON ( u.user_id = m.uid )
-                LEFT JOIN  aliases         AS a ON ( a.id = m.uid AND a.type='a_vie' )
-                LEFT JOIN  emails          AS e ON ( e.flags = 'active' AND e.uid = m.uid)
-                    WHERE  m.asso_id = {?} $ini
-                           AND (m.origine != 'X' OR u.perms != 'pending' OR m.email IS NOT NULL)
-                 GROUP BY  m.uid
-                 ORDER BY  $tri
-                    LIMIT  {?},{?}", $globals->asso('id'), $ofs*NB_PER_PAGE, NB_PER_PAGE);
-        $page->assign('ann', $ann);
-        $page->jsonAssign('ann', $ann);
+        $users = $uf->getUsers(NB_PER_PAGE, $ofs * NB_PER_PAGE);
+        $count = $uf->getTotalCount();
+
+        $page->assign('pages', floor(($count + NB_PER_PAGE - 1) / NB_PER_PAGE));
+        $page->assign('current', $ofs);
+        $page->assign('order', $sort);
+        $page->assign('users', $users);
+        $page->assign('only_admin', Env::b('admin'));
     }
 
     function handler_trombi(&$page)
@@ -483,11 +361,8 @@ class XnetGrpModule extends PLModule
     function handler_vcard(&$page, $photos = null)
     {
         global $globals;
-        $res = XDB::query('SELECT  uid
-                             FROM  groupex.membres
-                            WHERE  asso_id = {?}', $globals->asso('id'));
         $vcard = new VCard($photos == 'photos', 'Membre du groupe ' . $globals->asso('nom'));
-        $vcard->addUsers($res->fetchColumn());
+        $vcard->addUsers($globals->asso()->getMembers()->getUIDs());
         $vcard->show();
     }
 
@@ -497,26 +372,12 @@ class XnetGrpModule extends PLModule
         if (is_null($filename)) {
             $filename = $globals->asso('diminutif') . '.csv';
         }
-        $ann = XDB::iterator(
-                  "SELECT  IF(m.origine='X',IF(u.nom_usage<>'', u.nom_usage, u.nom) ,m.nom) AS nom,
-                           IF(m.origine='X',u.prenom,m.prenom) AS prenom,
-                           IF(m.origine='X', u.promo, IF(m.origine='ext', 'extérieur', 'personne morale')) AS promo,
-                           IF(m.origine='X' AND u.perms != 'pending',CONCAT(a.alias, '@', {?}), m.email) AS email,
-                           IF(m.origine='X',FIND_IN_SET('femme', u.flags), m.sexe) AS femme,
-                           m.comm as comm
-                     FROM  groupex.membres AS m
-                LEFT JOIN  auth_user_md5   AS u ON ( u.user_id = m.uid )
-                LEFT JOIN  aliases         AS a ON ( a.id = m.uid AND a.type = 'a_vie' )
-                    WHERE  m.asso_id = {?}
-                           AND (m.origine != 'X' OR u.perms != 'pending' OR m.email IS NOT NULL)
-                 GROUP BY  m.uid
-                 ORDER BY  nom, prenom",
-                 $globals->mail->domain, $globals->asso('id'));
+        $users = $globals->asso()->getMembers(null, new UFO_Name('directory_name'))->getUsers();
         header('Content-Type: text/x-csv; charset=utf-8;');
         header('Pragma: ');
         header('Cache-Control: ');
         $page->changeTpl('xnetgrp/annuaire-csv.tpl', NO_SKIN);
-        $page->assign('ann', $ann);
+        $page->assign('users', $users);
     }
 
     private function removeSubscriptionRequest($uid)
@@ -690,21 +551,18 @@ class XnetGrpModule extends PLModule
             }
         }
 
-        $it = XDB::iterator("SELECT  IF(u.nom_usage != '', u.nom_usage, u.nom) AS nom,
-                                     u.prenom, u.promo, u.hruid, s.ts AS date
+        $it = XDB::iterator('SELECT  s.uid, a.hruid, s.ts AS date
                                FROM  groupex.membres_sub_requests AS s
-                         INNER JOIN  auth_user_md5 AS u ON (s.uid = u.user_id)
-                              WHERE  asso_id = {?}
-                           ORDER BY  nom, prenom",
-                           $globals->asso('id'));
-
+                         INNER JOIN  accounts AS a ON(s.uid = a.uid)
+                              WHERE  s.asso_id = {?}
+                           ORDER BY  s.ts',  $globals->asso('id'));
         $page->changeTpl('xnetgrp/subscribe-valid.tpl');
         $page->assign('valid', $it);
     }
 
     function handler_change_rights(&$page)
     {
-        if (Env::has('right') && (may_update() || S::has('suid'))) {
+        if (Env::has('right') && (may_update() || S::suid())) {
             switch (Env::v('right')) {
               case 'admin':
                 Platal::session()->stopSUID();
@@ -726,7 +584,6 @@ class XnetGrpModule extends PLModule
                 break;
             }
         }
-//        var_dump($_SESSION);
         http_redirect($_SERVER['HTTP_REFERER']);
     }
 
@@ -736,8 +593,8 @@ class XnetGrpModule extends PLModule
 
         $this->load('mail.inc.php');
         $page->changeTpl('xnetgrp/annuaire-admin.tpl');
-        $mmlist = new MMList(S::v('uid'), S::v('password'),
-                             $globals->asso('mail_domain'));
+        $user = S::user();
+        $mmlist = new MMList($user, $globals->asso('mail_domain'));
         $lists  = $mmlist->get_lists();
         if (!$lists) $lists = array();
         $listes = array_map(create_function('$arr', 'return $arr["list"];'), $lists);
@@ -754,16 +611,10 @@ class XnetGrpModule extends PLModule
         $not_in_group_ext = array();
 
         foreach ($subscribers as $mail) {
-            $res = XDB::query(
-                       'SELECT  COUNT(*)
-                          FROM  groupex.membres AS m
-                     LEFT JOIN  auth_user_md5   AS u ON (m.uid=u.user_id AND m.uid<50000)
-                     LEFT JOIN  aliases         AS a ON (a.id=u.user_id and a.type="a_vie")
-                         WHERE  asso_id = {?} AND
-                                (m.email = {?} OR CONCAT(a.alias, "@polytechnique.org") = {?})',
-                        $globals->asso('id'), $mail, $mail);
-            if ($res->fetchOneCell() == 0) {
-                if (strstr($mail, '@polytechnique.org') === false) {
+            $uf = new UserFilter(new UFC_And(new UFC_Group($globals->asso('id')),
+                                             new UFC_Email($mail)));
+            if ($uf->getTotalCount() == 0) {
+                if (User::isForeignEmailAddress($mail)) {
                     $not_in_group_ext[] = $mail;
                 } else {
                     $not_in_group_x[] = $mail;
@@ -799,12 +650,10 @@ class XnetGrpModule extends PLModule
             }
         } else {
             if (isvalid_email($email)) {
-                if (Env::v('x') && Env::has('userid') && Env::i('userid')) {
+                if (Env::v('x') && Env::i('userid')) {
                     $uid = Env::i('userid');
-                    $res = XDB::query("SELECT *
-                                         FROM auth_user_md5
-                                        WHERE user_id = {?} AND perms = 'pending'", $uid);
-                    if ($res->numRows() == 1) {
+                    $user = User::getWithUID($uid);
+                    if ($user && $user->state == 'pending') {
                         if (Env::v('market')) {
                             $market = Marketing::get($uid, $email);
                             if (!$market) {
@@ -837,102 +686,91 @@ class XnetGrpModule extends PLModule
     function handler_admin_member_new_ajax(&$page)
     {
         header('Content-Type: text/html; charset="UTF-8"');
-        $page->changeTpl('xnetgrp/membres-new-search.tpl', NO_SKIN);
-        $res = null;
+        $page->changeTpl('xnetgrp/membres-new-search.tpl',  NO_SKIN);
+        $users = array();
         if (Env::has('login')) {
-            require_once 'user.func.inc.php';
-            $res = get_not_registered_user(Env::v('login'), true);
+            $user = User::getSilent(Env::t('login'));
+            if ($user && $user->state != 'pending') {
+                $users = array($user);
+            }
         }
-        if (is_null($res)) {
-            list($nom, $prenom) = str_replace(array('-', ' ', "'"), '%', array(Env::v('nom'), Env::v('prenom')));
-            $where = "perms = 'pending'";
+        if (empty($users)) {
+            list($nom, $prenom) = str_replace(array('-', ' ', "'"), '%', array(Env::t('nom'), Env::t('prenom')));
+            $cond = new UFC_And(new UFC_Not(new UFC_Registered()));
             if (!empty($nom)) {
-                $where .= " AND nom LIKE '%$nom%'";
+                $cond->addChild(new UFC_Name(UserFilter::LASTNAME, $nom, UFC_Name::CONTAINS));
             }
             if (!empty($prenom)) {
-                $where .= " AND prenom LIKE '%$prenom%'";
+                $cond->addChild(new UFC_Name(UserFilter::FIRSTNAME, $prenom, UFC_Name::CONTAINS));
             }
-            if (preg_match('/^[0-9]{4}$/', Env::v('promo'))) {
-                $where .= " AND promo = " . Env::i('promo');
-            } elseif (preg_match('/^[0-9]{2}$/', Env::v('promo'))) {
-                $where .= " AND MOD(promo, 100) = " . Env::i('promo');
-            } elseif (Env::has('promo')) {
-                return;
+            if (Env::i('promo')) {
+                $cond->addChild(new UFC_Promo('=', UserFilter::GRADE_ING, Env::i('promo')));
+            }
+            $uf = new UserFilter($cond);
+            $users = $uf->getUsers(30);
+            if ($uf->getTotalCount() > 30) {
+                $page->assign('too_many', true);
+                $users = array();
             }
-            $res = XDB::iterator("SELECT user_id, nom, prenom, promo
-                                    FROM auth_user_md5
-                                   WHERE $where");
-        }
-        if ($res && $res->total() < 30) {
-            $page->assign("choix", $res);
         }
+        $page->assign('users', $users);
     }
 
-    function unsubscribe(&$user)
+    function unsubscribe(PlUser &$user)
     {
         global $globals;
-        XDB::execute(
-                "DELETE FROM  groupex.membres WHERE uid={?} AND asso_id={?}",
-                $user['uid'], $globals->asso('id'));
+        XDB::execute("DELETE FROM  groupex.membres
+                            WHERE  uid = {?} AND asso_id = {?}",
+                     $user->id(), $globals->asso('id'));
 
         if ($globals->asso('notif_unsub')) {
             $mailer = new PlMailer('xnetgrp/unsubscription-notif.mail.tpl');
-            $res = XDB::iterRow("SELECT  a.alias, u.prenom, IF(u.nom_usage != '', u.nom_usage, u.nom) AS nom
-                                   FROM  groupex.membres AS m
-                             INNER JOIN  aliases AS a ON (m.uid = a.id AND FIND_IN_SET('bestalias', a.flags))
-                             INNER JOIn  auth_user_md5 AS u ON (u.user_id = a.id)
-                                  WHERE  m.asso_id = {?} AND m.perms = 'admin'",
-                                  $globals->asso('id'));
-            while (list($alias, $prenom, $nom) = $res->next()) {
-                $mailer->addTo("\"$prenom $nom\" <$alias@{$globals->mail->domain}>");
+            foreach ($globals->asso()->getMembers()->getUsers() as $user) {
+                $mailer->addTo($user);
             }
             $mailer->assign('group', $globals->asso('nom'));
-            $mailer->assign('prenom', $user['prenom']);
-            $mailer->assign('nom', $user['nom']);
-            $mailer->assign('mail', $user['email2']);
-            $mailer->assign('selfdone', $user['uid'] == S::i('uid'));
+            $mailer->assign('user', $user);
+            $mailer->assign('selfdone', $user->id() == S::i('uid'));
             $mailer->send();
         }
 
-        $user_same_email = get_infos($user['email']);
         $domain = $globals->asso('mail_domain');
-
-        if (!$domain || (!empty($user_same_email) && $user_same_email['uid'] != $user['uid'])) {
+        if (!$domain) {
             return true;
         }
 
-        $mmlist = new MMList(S::v('uid'), S::v('password'), $domain);
-        $listes = $mmlist->get_lists($user['email2']);
+        $mmlist = new MMList($user, $domain);
+        $listes = $mmlist->get_lists($user->forlifeEmail());
 
         $may_update = may_update();
         $warning    = false;
         foreach ($listes as $liste) {
             if ($liste['sub'] == 2) {
                 if ($may_update) {
-                    $mmlist->mass_unsubscribe($liste['list'], Array($user['email2']));
+                    $mmlist->mass_unsubscribe($liste['list'], Array($user->forlifeEmail()));
                 } else {
                     $mmlist->unsubscribe($liste['list']);
                 }
             } elseif ($liste['sub']) {
-                Platal::page()->trigWarning("{$user['prenom']} {$user['nom']} a une"
+                Platal::page()->trigWarning($user->fullName() . " a une"
                                            ." demande d'inscription en cours sur la"
                                            ." liste {$liste['list']}@ !");
                 $warning = true;
             }
         }
 
-        XDB::execute(
-                "DELETE FROM  virtual_redirect
-                       USING  virtual_redirect
-                  INNER JOIN  virtual USING(vid)
-                       WHERE  redirect={?} AND alias LIKE {?}", $user['email'], '%@'.$domain);
+        XDB::execute("DELETE FROM  virtual_redirect
+                            USING  virtual_redirect
+                       INNER JOIN  virtual USING(vid)
+                            WHERE  redirect={?} AND alias LIKE {?}",
+                       $user->forlifeEmail(), '%@'.$domain);
         return !$warning;
     }
 
     function handler_unsubscribe(&$page)
     {
         $page->changeTpl('xnetgrp/membres-del.tpl');
-        $user = get_infos(S::user()->id());
+        $user = S::user()->id();
         if (empty($user)) {
             return PL_NOT_FOUND;
         }
@@ -956,7 +794,7 @@ class XnetGrpModule extends PLModule
     function handler_admin_member_del(&$page, $user = null)
     {
         $page->changeTpl('xnetgrp/membres-del.tpl');
-        $user = get_infos($user);
+        $user = User::getSilent($user);
         if (empty($user)) {
             return PL_NOT_FOUND;
         }
@@ -969,13 +807,13 @@ class XnetGrpModule extends PLModule
         }
 
         if ($this->unsubscribe($user)) {
-            $page->trigSuccess("{$user['prenom']} {$user['nom']} a été désabonné du groupe !");
+            $page->trigSuccess("{$user->fullName()} a été désinscrit du groupe !");
         } else {
-            $page->trigWarning("{$user['prenom']} {$user['nom']} a été désabonné du groupe, mais des erreurs subsistent !");
+            $page->trigWarning("{$user->fullName()} a été désinscrit du groupe, mais des erreurs subsistent !");
         }
     }
 
-    private function changeLogin(PlPage &$page, array &$user, MMList &$mmlist, $login)
+    private function changeLogin(PlPage &$page, PlUser &$user, MMList &$mmlist, $login)
     {
         require_once 'user.func.inc.php';
         // Search the uid of the user...
@@ -1050,20 +888,20 @@ class XnetGrpModule extends PLModule
 
         $page->changeTpl('xnetgrp/membres-edit.tpl');
 
-        $user = get_infos($user);
+        $user = User::getSilent($user);
         if (empty($user)) {
             return PL_NOT_FOUND;
         }
 
-        $mmlist = new MMList(S::v('uid'), S::v('password'),
-                             $globals->asso('mail_domain'));
+        $mmlist = new MMList($user, $globals->asso('mail_domain'));
 
         if (Post::has('change')) {
             S::assert_xsrf_token();
 
             // Convert user status to X
-            if ($user['origine'] == 'ext' && trim(Post::v('login_X'))) {
-                $forlife = $this->changeLogin($page, $user, $mmlist, trim(Post::v('login_X')));
+            if (Post::blank('login_X')) {
+                // TODO: Rewrite changeLogin!!!
+                $forlife = $this->changeLogin($page, $user, $mmlist, Post::t('login_X'));
                 if ($forlife) {
                     pl_redirect('member/' . $forlife);
                 }
@@ -1089,7 +927,7 @@ class XnetGrpModule extends PLModule
             }
 
             $perms = Post::i('is_admin');
-            $comm  = trim(Post::s('comm'));
+            $comm  = Post::t('comm');
             if ($user['perms'] != $perms || $user['comm'] != $comm) {
                 XDB::query('UPDATE groupex.membres
                                SET perms={?}, comm={?}
@@ -1154,16 +992,8 @@ class XnetGrpModule extends PLModule
         }
 
         $page->assign('user', $user);
-        $listes = $mmlist->get_lists($user['email2']);
-        $page->assign('listes', $listes);
-
-        $res = XDB::query(
-                'SELECT  alias, redirect IS NOT NULL as sub
-                   FROM  virtual          AS v
-              LEFT JOIN  virtual_redirect AS vr ON(v.vid=vr.vid AND (redirect = {?} OR redirect = {?}))
-                  WHERE  alias LIKE {?} AND type="user"',
-                $user['email'], $user['email2'], '%@'.$globals->asso('mail_domain'));
-        $page->assign('alias', $res->fetchAllAssoc());
+        $page->assign('listes', $mmlist->get_lists($user->forlifeEmail()));
+        $page->assign('alias', $user->emailAliases($globals->asso('mail_domain'), 'user', true));
     }
 
     function handler_rss(&$page, $user = null, $hash = null)
@@ -1355,11 +1185,9 @@ class XnetGrpModule extends PLModule
         }
 
         if (empty($art) && !is_null($aid)) {
-            $res = XDB::query("SELECT a.*, u.nom, u.prenom, u.promo, u.hruid,
-                                      FIND_IN_SET('public', a.flags) AS public,
+            $res = XDB::query("SELECT a.*, FIND_IN_SET('public', a.flags) AS public,
                                       FIND_IN_SET('photo', a.flags) AS photo
                                  FROM groupex.announces AS a
-                           INNER JOIN auth_user_md5 AS u USING(user_id)
                                 WHERE asso_id = {?} AND a.id = {?}",
                               $globals->asso('id'), $aid);
             if ($res->numRows()) {
index c367967..d3f72b8 100644 (file)
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
  ***************************************************************************/
 
+class UserFilterIterator implements PlIterator
+{
+    private $it;
+    private $user;
+    public function __construct(PlIterator &$it, PlUser &$user)
+    {
+        $this->it =& $it;
+        $this->user =& $user;
+    }
+
+    public function total()
+    {
+        return $this->it->total();
+    }
+
+    public function first()
+    {
+        return $this->it->first();
+    }
+
+    public function last()
+    {
+        return $this->it->last();
+    }
+
+    public function next()
+    {
+        while ($n = $this->it->next()) {
+            $uf = UserFilter::getLegacy($n['promo_min'], $n['promo_max']);
+            if ($uf->checkUser($this->user)) {
+                return $n;
+            }
+        }
+        return null;
+    }
+}
+
 class XnetGrpEventFeed extends PlFeed
 {
     public function __construct()
@@ -37,25 +74,20 @@ class XnetGrpEventFeed extends PlFeed
     {
         global $globals;
         if (!is_null($user)) {
-            return XDB::iterator("SELECT a.id, a.titre AS title, a.texte, a.contacts,
-                                         a.create_date AS publication,
-                                         CONCAT(u2.prenom, ' ', IF(u2.nom_usage != '', u2.nom_usage, u2.nom), ' (X',  u2.promo, ')') AS author,
-                                         FIND_IN_SET('photo', a.flags) AS photo,
-                                         CONCAT({?}, '/#art', a.id) AS link
-                                   FROM auth_user_md5 AS u
-                             INNER JOIN groupex.announces AS a ON ( (a.promo_min = 0 OR a.promo_min <= u.promo)
-                                                                  AND (a.promo_max = 0 OR a.promo_max <= u.promo))
-                             INNER JOIN auth_user_md5 AS u2 ON (u2.user_id = a.user_id)
-                             WHERE u.user_id = {?} AND peremption >= NOW() AND a.asso_id = {?}",
-                                   $this->link, $user->id(), $globals->asso('id'));
+            return new UserFilterIterator(
+                   XDB::iterator("SELECT  a.id, a.titre AS title, a.texte, a.contacts,
+                                          a.create_date AS publication,
+                                          FIND_IN_SET('photo', a.flags) AS photo,
+                                          CONCAT({?}, '/#art', a.id) AS link
+                                    FROM  groupex.announces AS a
+                                   WHERE  peremption >= NOW() AND a.asso_id = {?}",
+                                   $this->link, $globals->asso('id'), $user));
         } else {
-            return  XDB::iterator("SELECT a.id, a.titre AS title, a.texte, a.create_date AS publication,
-                                         CONCAT(u.prenom, ' ', IF(u.nom_usage != '', u.nom_usage, u.nom), ' (X',  u.promo, ')') AS author,
-                                         CONCAT({?}, '/#art', a.id) AS link,
-                                         NULL AS photo, NULL AS contacts
-                                    FROM groupex.announces AS a
-                              INNER JOIN auth_user_md5 AS u USING(user_id)
-                                   WHERE FIND_IN_SET('public', a.flags) AND peremption >= NOW() AND a.asso_id = {?}",
+            return  XDB::iterator("SELECT  a.id, a.titre AS title, a.texte, a.create_date AS publication,
+                                           CONCAT({?}, '/#art', a.id) AS link,
+                                           NULL AS photo, NULL AS contacts
+                                     FROM  groupex.announces AS a
+                                    WHERE  FIND_IN_SET('public', a.flags) AND peremption >= NOW() AND a.asso_id = {?}",
                                   $this->link, $globals->asso('id'));
         }
     }
index 5751457..090b5b5 100644 (file)
@@ -27,44 +27,21 @@ function get_all_redirects($membres, $mls, &$client)
 
     $tos = array();
 
+    // TODO: add more filters to choose users
     if (!empty($membres)) {
-        $membres = array_map(create_function('$str', 'return "\"$str\"";'), $membres);
-        $membres = join(',', $membres);
-        $res = XDB::query(
-                    'SELECT  IF(u.nom <> "", u.nom, m.nom) AS nom,
-                             IF(u.prenom <> "", u.prenom, m.prenom) AS prenom,
-                             IF(m.email <> "", m.email, CONCAT(a.alias, "@polytechnique.org")) as email,
-                             IF(m.sexe IS NULL, FIND_IN_SET("femme", u.flags), m.sexe) AS sexe
-                       FROM  groupex.membres AS m
-                  LEFT JOIN  auth_user_md5   AS u ON (m.uid=u.user_id AND m.uid<50000)
-                  LEFT JOIN  aliases         AS a ON (a.id=u.user_id and a.type="a_vie")
-                      WHERE  asso_id = {?}
-                             AND m.origine IN (' . $membres . ')
-                             AND (m.email <> "" OR u.perms <> "pending")', $globals->asso('id'));
-        $tos = $res->fetchAllAssoc();
+        $uf = new UserFilter(new UFC_Group($globals->asso('id')));
+        $tos = $uf->getUsers();
     }
 
     foreach ($mls as $ml) {
         if (list(,$members) = $client->get_members($ml)) {
             foreach ($members as $mem) {
-                list($m, $dom) = explode('@',$mem[1]);
-                if ($dom == $globals->mail->domain || $dom == $globals->mail->domain2) {
-                    $res = XDB::query('SELECT  prenom, nom, FIND_IN_SET("femme", u.flags) AS sexe
-                                         FROM  auth_user_md5 AS u
-                                   INNER JOIN  aliases       AS a ON u.user_id = a.id
-                                        WHERE  a.alias = {?}', $m);
-                    if ($person = $res->fetchOneAssoc()) {
-                        $person['email'] = $mem[1];
-                        $tos[] = $person;
-                    }
+                $uf = new UserFilter(new UFC_Mail($mem[1]));
+                $user = $uf->getUsers();
+                if ($user) {
+                    $tos[] = $user;
                 } else {
-                    $res = XDB::query('SELECT prenom, nom, sexe FROM groupex.membres WHERE email={?}', $mem[1]);
-                    if ($person = $res->fetchOneAssoc()) {
-                        $person['email'] = $mem[1];
-                        $tos[] = $person;
-                    } else {
-                        $tos[] = array('email' => $mem[1]);
-                    }
+                    $tos[] = $mem[1];
                 }
             }
         }
@@ -78,17 +55,19 @@ function get_all_redirects($membres, $mls, &$client)
 
 function _send_xnet_mail($user, $body, $wiki, $mailer, $replyto = null)
 {
-    $cher = isset($user['sexe']) ? ($user['sexe'] ? 'Chère' : 'Cher') : 'Cher(e)';
-    $nom  = isset($user['nom']) ? $user['nom'] : "";
-    $pnom = isset($user['prenom']) ? $user['prenom'] : preg_replace('!@.*!u', '', $user['email']);
-    $to   = isset($user['prenom']) ? "\"{$user['prenom']} {$user['nom']}\" <{$user['email']}>" : $user['email'];
-
-    $text = $body;
-    $text = preg_replace('!<cher>!i',   $cher, $text);
-    $text = preg_replace('!<nom>!i',    $nom,  $text);
-    $text = preg_replace('!<prenom>!i', $pnom, $text);
+    if ($user instanceof PlUser) {
+        $cher = $user->isFemale() ? 'Chère' : 'Cher';
+        $nom  = $user->displayName();
+        $pnom = '';
+    } else {
+        $cher = 'Cher(e)';
+        $nom  = $user;
+        $pnom = '';
+    }
 
-    $mailer->addHeader('To', $to);
+    $text = str_ireplace(array('<cher>', '<nom>', '<prenom>'),
+                         array($cher, $nom, $pnom), $body);
+    $mailer->addTo($user);
     if ($replyto) {
         $mailer->addHeader('Reply-To', $replyto);
     }
@@ -116,9 +95,16 @@ function send_xnet_mails($from, $sujet, $body, $wiki, $tos, $replyto = null, $up
     }
 
     foreach ($tos as $user) {
-        if ($sent[$user['email']]) continue;
+        if ($user instanceof $user) {
+            $email = $user->bestEmail();
+        } else {
+            $email = $user;
+        }
+        if ($sent[$email]) {
+            continue;
+        }
         _send_xnet_mail($user, $body, $wiki, $mailer, $replyto);
-        $sent[$user['email']] = true;
+        $sent[$email] = true;
     }
 }
 
index 036452e..8442956 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /***************************************************************************
- *  Copyright (C) 2003-2009 Polytechnique.org                              *
+ *  Copyright (C) 2003-2008 Polytechnique.org                              *
  *  http://opensource.polytechnique.org/                                   *
  *                                                                         *
  *  This program is free software; you can redistribute it and/or modify   *
@@ -54,13 +54,15 @@ class XnetListsModule extends ListsModule
         );
     }
 
-    function prepare_client(&$page)
+    function prepare_client(&$page, $user = null)
     {
         global $globals;
         Platal::load('lists', 'lists.inc.php');
 
-        $this->client = new MMList(S::v('uid'), S::v('password'),
-                                   $globals->asso('mail_domain'));
+        if (is_null($user)) {
+            $user =& S::user();
+        }
+        $this->client = new MMList($user, $globals->asso('mail_domain'));
 
         $page->assign('asso', $globals->asso());
         $page->setType($globals->asso('cat'));
@@ -219,25 +221,14 @@ class XnetListsModule extends ListsModule
         $not_in_group_x = array();
         $not_in_group_ext = array();
 
-        $ann = XDB::iterator(
-                  "SELECT  if (m.origine='X',if (u.nom_usage<>'', u.nom_usage, u.nom) ,m.nom) AS nom,
-                           if (m.origine='X',u.prenom,m.prenom) AS prenom,
-                           if (m.origine='X',u.promo,'extérieur') AS promo,
-                           if (m.origine='X',CONCAT(a.alias, '@{$globals->mail->domain}'),m.email) AS email,
-                           if (m.origine='X',FIND_IN_SET('femme', u.flags),0) AS femme,
-                           m.perms='admin' AS admin,
-                           m.origine='X' AS x
-                     FROM  groupex.membres AS m
-                LEFT JOIN  auth_user_md5   AS u ON ( u.user_id = m.uid )
-                LEFT JOIN  aliases         AS a ON ( a.id = m.uid AND a.type='a_vie' )
-                    WHERE  m.asso_id = {?}
-                 ORDER BY  promo, nom, prenom", $globals->asso('id'));
-
+        $ann = XDB::fetchColumn('SELECT  uid
+                                   FROM  groupex.membres
+                                  WHERE  asso_id = {?}', $globals->asso('id'));
+        $users = User::getBuildUsersWithUIDs($ann, 'promo,full_name');
         $not_in_list = array();
-
-        while ($tmp = $ann->next()) {
-            if (!in_array(strtolower($tmp['email']), $subscribers)) {
-                $not_in_list[] = $tmp;
+        foreach ($users as $user) {
+            if (!in_array(strtolower($user->forlifeEmail()), $subscribers)) {
+                $not_in_list[] = $user;
             }
         }
 
@@ -256,37 +247,21 @@ class XnetListsModule extends ListsModule
         if (Env::has('add_member')) {
             S::assert_xsrf_token();
 
-            $add = Env::v('add_member');
-            if (strstr($add, '@')) {
-                list($mbox,$dom) = explode('@', strtolower($add));
-            } else {
-                $mbox = $add;
-                $dom = 'm4x.org';
+            $add = Env::t('add_member');
+            $user = User::getSilent($add);
+            if ($user) {
+                $add = $user->forlifeEmail();
+            } else if (!User::isForeignEmailAddress($add)) {
+                $add = null;
             }
-            if ($dom == 'polytechnique.org' || $dom == 'm4x.org') {
-                $res = XDB::query(
-                        "SELECT  a.alias, b.alias
-                           FROM  x4dat.aliases AS a
-                      LEFT JOIN  x4dat.aliases AS b ON (a.id=b.id AND b.type = 'a_vie')
-                          WHERE  a.alias={?} AND a.type!='homonyme'", $mbox);
-                if (list($alias, $blias) = $res->fetchOneRow()) {
-                    $alias = empty($blias) ? $alias : $blias;
-                    XDB::query(
-                        "INSERT INTO  x4dat.virtual_redirect (vid,redirect)
-                              SELECT  vid, {?}
-                                FROM  x4dat.virtual
-                               WHERE  alias={?}", "$alias@m4x.org", $lfull);
-                   $page->trigSuccess("$alias@m4x.org ajouté");
-                } else {
-                    $page->trigError("$mbox@{$globals->mail->domain} n'existe pas.");
-                }
+            if (!empty($add)) {
+                XDB::execute('INSERT INTO  x4dat.virtual_redirect (vid, redirect)
+                                   SELECT  vid, {?},
+                                     FROM  x4dat.virtual
+                                    WHERE  alias = {?}', strtolower($add), $lfull);
+                $page->trigSuccess($add . ' ajouté.');
             } else {
-                XDB::query(
-                        "INSERT INTO  x4dat.virtual_redirect (vid,redirect)
-                              SELECT  vid,{?}
-                                FROM  x4dat.virtual
-                               WHERE  alias={?}", "$mbox@$dom", $lfull);
-                $page->trigSuccess("$mbox@$dom ajouté");
+                $page->trigError($add . ' n\'existe pas.');
             }
         }
 
@@ -301,23 +276,21 @@ class XnetListsModule extends ListsModule
         }
 
         global $globals;
-        $res = XDB::iterator("SELECT  IF(r.login IS NULL, m.nom, IF(u.nom_usage != '', u.nom_usage, u.nom)) AS nom,
-                                      IF(r.login IS NULL, m.prenom, u.prenom) AS prenom,
-                                      IF(r.login IS NULL, 'extérieur', u.promo) AS promo,
-                                      m.perms = 'admin' AS admin, r.redirect, r.login AS alias
-                                FROM  (SELECT  redirect AS redirect,
-                                               IF(SUBSTRING_INDEX(redirect, '@', -1) IN ({?}, {?}),
-                                                  SUBSTRING_INDEX(redirect, '@', 1), NULL) AS login
-                                         FROM  x4dat.virtual_redirect AS vr
-                                   INNER JOIN  x4dat.virtual          AS v  USING(vid)
-                                        WHERE  v.alias = {?}
-                                     ORDER BY  redirect) AS r
-                           LEFT JOIN  aliases AS a ON (r.login IS NOT NULL AND r.login = a.alias)
-                           LEFT JOIN  auth_user_md5 AS u ON (u.user_id = a.id)
-                           LEFT JOIN groupex.membres AS m ON (m.asso_id = {?} AND IF(r.login IS NULL, m.email = r.redirect, m.uid = u.user_id))",
-                $globals->mail->domain, $globals->mail->domain2,
-                $lfull, $globals->asso('id'));
-        $page->assign('mem', $res);
+        $emails = XDB::fetchColumn('SELECT  redirect
+                                      FROM  virtual_redirect AS vr
+                                INNER JOIN  virtual          AS v  USING(vid)
+                                     WHERE  v.alias = {?}
+                                  ORDER BY  redirect', $lfull);
+        $mem = array();
+        foreach ($emails as $email) {
+            $user = User::getSilent($email);
+            if ($user) {
+                $mem[] = array('user' => $user, 'email' => $email);
+            } else {
+                $mem[] = array('email' => $email);
+            }
+        }
+        $page->assign('mem', $mem);
     }
 
     function handler_acreate(&$page)
similarity index 60%
rename from include/rss.inc.php
rename to plugins/function.profile.php
index eb78f63..be02e7b 100644 (file)
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
  ***************************************************************************/
 
-function init_rss($template, $alias, $hash, $require_uid = true)
+function smarty_function_profile($params, &$smarty)
 {
-    $page =& Platal::page();
-    $page->changeTpl($template, NO_SKIN);
-    $user = Platal::session()->tokenAuth($alias, $hash);
-    if (is_null($user)) {
-        if ($require_uid) {
-            exit;
-        } else {
-            $user = null;
-        }
+    $params = new PlDict($params);
+    $with_promo = $params->b('promo', false);
+    $with_sex   = $params->b('sex', true);
+    $with_link  = $params->b('link', true);
+    $with_groupperms = $params->b('groupperms', true);
+    $user = $params->v('user');
+    if (ctype_digit($user)) {
+        $user = User::getWithUID($user);
     }
 
-    if ($template) {
-        $page->assign('rss_hash', $hash);
-        header('Content-Type: application/rss+xml; charset=utf8');
+    $name = pl_entities($user->fullName());
+    if ($with_sex && $user->isFemale()) {
+        $name = '&bull;' . $name;
+    }
+    if ($with_promo) {
+        $promo = $user->promo();
+        if ($promo) {
+            $name .= ' (' . pl_entities($promo) . ')';
+        }
+    }
+    if ($with_link) {
+        $profile = ($user instanceof Profile) ? $user : $user->profile();
+        if ($profile) {
+            $name = '<a href="profile/' . $profile->hrid() . '" class="popup2">' . $name . '</a>';
+        }
+    }
+    if ($with_groupperms && $user instanceof User && $user->group_perms == 'admin') {
+        $name = '<strong>' . $name . '</strong>';
     }
-    return is_null($user) ? null : $user->id();
+    return $name;
 }
 
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
diff --git a/plugins/insert.getName.php b/plugins/insert.getName.php
deleted file mode 100644 (file)
index 0b581b7..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-<?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                *
- ***************************************************************************/
-
-function smarty_insert_getName()
-{
-    $uid = Cookie::v('uid', -1);
-    if ($uid < 0) {
-        return "";
-    }
-    $res = XDB::query("SELECT prenom FROM auth_user_md5 WHERE user_id={?}", $uid);
-    return $res->fetchOneCell();
-}
-
-// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
-?>
index b260754..4bce448 100644 (file)
 {*                                                                        *}
 {**************************************************************************}
 
-<h1>Comptes désactivés</h1>
+<h1>{$disabled->total()} Comptes désactivés ou surveillés</h1>
 
 <table class="bicol">
-  <tr><th>Nom</th><th>Commentaire</th></tr>
+  <tr><th>Nom</th><th>Disabled</th><th>Surveillé</th><th>Commentaire</th></tr>
   {iterate from=$disabled item=user}
   <tr class="{cycle values="pair,impair"}">
     <td>
-      <a href="admin/user/{$user.hruid}">{$user.prenom} {$user.nom} ({$user.promo})</a>
+      <a href="admin/user/{$user.hruid}">{$user.hruid}</a>
+    </td>
+    <td>
+      <input type="checkbox" disabled="disabled" {if $user.disabled}checked="checked"{/if} />
+    </td>
+    <td>
+      <input type="checkbox" disabled="disabled" {if $user.watch}checked="checked"{/if} />
     </td>
     <td>
       {$user.comment|default='(none)'}
   {/iterate}
 </table>
 
-<h1>Administrateurs du site</h1>
+<h1>{$admins->total()} Administrateurs du site</h1>
 
 <table class="tinybicol">
   <tr><th>Utilisateur</th></tr>
   {iterate from=$admins item=user}
   <tr class="{cycle values="pair,impair"}">
     <td>
-      <a href="admin/user/{$user.hruid}">{$user.prenom} {$user.nom} ({$user.promo})</a>
+      <a href="admin/user/{$user.hruid}">{$user.hruid}</a>
     </td>
   </tr>
   {/iterate}
index b4a80bb..b8657db 100644 (file)
     <td style="text-align: center">{$d.promo}</td>
     <td>
       <a href="profile/{$d.hruid}" class="popup2">{icon name=user_suit title='Afficher la fiche'}</a>
-      <a href="http://www.polytechniciens.com/?page=AX_FICHE_ANCIEN&amp;anc_id={$d.matricule_ax}">{*
+      <a href="http://www.polytechniciens.com/?page=AX_FICHE_ANCIEN&amp;anc_id={$d.ax_id}">{*
         *}{icon name=user_gray title="fiche AX"}</a>
       <a href="admin/user/{$d.hruid}">{icon name=wrench title='Administrer user'}</a>
     </td>
-    <td>{$d.prenom} {$d.nom}</td>
-    <td style="text-align: center">{$d.deces}</td>
+    <td>{$d.directory_name}</td>
+    <td style="text-align: center">{$d.deathdate}</td>
     <td style="text-align: center">
-      {if $d.last gt $d.deces}<strong>{$d.last}</strong>{elseif $d.last}{$d.last}{else}-{/if}
+      {if $d.last gt $d.deathdate}<strong>{$d.last}</strong>{elseif $d.last}{$d.last}{else}-{/if}
     </td>
   </tr>
   {/iterate}
index 1bef29b..64dee3a 100644 (file)
   <table class="bicol">
     <tr>
       <td>
-        <input type="submit" value="GO" style="visibility: hidden" />
-        <input type="submit" value="&lt;&lt;" name="sub10" />
-      </td>
-      <td><input type="submit" value="&lt;"  name="sub01" /></td>
-      <td>
         Promotion&nbsp;:
-        <input type="text" name="promo" value="{$promo}" size="4" maxlength="4" />
+        <input type="text" name="promo" value="{$promo}" size="5" maxlength="5" />
         <input type="submit" value="GO" />
       </td>
-      <td><input type="submit" value="&gt;"  name="add01" /></td>
-      <td>
-        <input type="submit" value="&gt;&gt;" name="add10" />
-        <input type="submit" value="GO" style="visibility: hidden" />
-      </td>
     </tr>
   </table>
 </form>
 
+{if t($decedes)}
 <form action="admin/deaths/{$promo}/validate" id="deathDateList" method="post">
   {xsrf_token_field}
   <table class="bicol" summary="liste des dates de décès">
@@ -53,9 +44,9 @@
     </tr>
     {iterate item=x from=$decedes}
     <tr class="{cycle values="impair,pair"}">
-      <td>{$x.nom} {$x.prenom}</td>
+      <td>{$x.directory_name}</td>
       <td class="center">
-        <input type="text" class="deathDate" name="{$x.matricule}" value="{$x.deces}" size="10" maxlength="10" />
+        <input type="text" class="deathDate" name="{$x.hrpid}" value="{$x.deathdate}" size="10" maxlength="10" />
       </td>
     </tr>
     {/iterate}
@@ -67,7 +58,6 @@
   </table>
 </form>
 
-<script type='text/javascript' src='javascript/jquery.js'></script>
 <script type="text/javascript">//<![CDATA[
   {literal}
   $('input.deathDate').change(
@@ -84,6 +74,6 @@
     });
   {/literal}
 //]]></script>
-
+{/if}
 
 {* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index b217f1c..38f20cf 100644 (file)
     <tr>
       <td>
         <textarea cols="80" rows="20" name="mailbody">
-{$prenom},
+{$user->displayName()},
 
 
 Comme nous t'en avons informé par email il y a quelques temps,
 pour respecter nos engagements en terme d'adresses email devinables,
 tu te verras bientôt retirer l'alias {$loginbis}@{#globals.mail.domain#} pour
-ne garder que {$forlife}@{#globals.mail.domain#}.
+ne garder que {$user->forlifeEmail()}.
 
 Toute personne qui écrira à {$loginbis}@{#globals.mail.domain#} recevra la
 réponse d'un robot qui l'informera que {$loginbis}@{#globals.mail.domain#}
@@ -111,7 +111,7 @@ L'équipe Polytechnique.org
     <tr>
       <td>
         <textarea cols="80" rows="20" name="mailbody">
-{$prenom},
+{$user->displayName()},
 
 Comme nous t'en avons informé par email il y a quelques temps,
 nous t'avons retiré de façon définitive l'adresse
index 8d709af..e3fec0c 100644 (file)
 {**************************************************************************}
 
 
-<h1>
-  Gestion des utilisateurs
-</h1>
-
-
 {if $smarty.post.u_kill_conf}
 <form method="post" action="admin/user">
   {xsrf_token_field}
     <input type="submit" name="u_kill" value="continuer" />
   </div>
 </form>
-{else}
-
-<form method="post" action="admin/user">
-  {xsrf_token_field}
-  <table class="tinybicol" cellspacing="0" cellpadding="2">
-    <tr>
-      <th>
-        Administrer
-      </th>
-    </tr>
-    {if !$smarty.request.login && !$mr.hruid}
-    <tr class="pair">
-      <td class="center">
-        Il est possible d'entrer ici n'importe quelle adresse email&nbsp;: redirection, melix, ou alias.
-      </td>
-    </tr>
-    {/if}
-    <tr>
-      <td class="center">
-        <input type="text" name="login" size="40" maxlength="255" value="{$smarty.request.login|default:$mr.hruid}" />
-      </td>
-    </tr>
-    <tr>
-      <td class="center">
-        <input type="hidden" name="hashpass" value="" />
-        <input type="submit" name="select" value=" edit " /> &nbsp;&nbsp;
-        <input type="submit" name="suid_button" value=" su " />  &nbsp;&nbsp;
-        <input type="submit" name="ax_button" value=" AX " /> &nbsp;&nbsp;
-        <input type="submit" name="logs_button" value=" logs " />
-      </td>
-    </tr>
-  </table>
-</form>
-
-{if $mr}
-
-<p class="smaller">
-Dernière connexion le <strong>{$lastlogin|date_format:"%d %B %Y, %T"}</strong>
-depuis <strong>{$host}</strong>.
-</p>
-
+{elseif $user}
 {literal}
+
 <script type="text/javascript">
 //<![CDATA[
 function doEditUser() {
@@ -90,6 +46,11 @@ function del_alias(alias) {
   document.forms.alias.submit();
 }
 
+function del_profile(pid) {
+  document.forms.profiles.del_profile.value = pid;
+  document.forms.profiles.submit();
+}
+
 function del_fwd(fwd) {
   document.forms.fwds.del_fwd.value = fwd;
   document.forms.fwds.submit();
@@ -114,34 +75,66 @@ function ban_read()
     document.forms.bans.read_perm.value = "!xorg.*";
 }
 
+$(document).ready(function() {
+  $('#tabs > ul').tabs();
+  $('.ui-tabs-nav li').width('33%')
+    .click(function() { $(this).children('a').click() });
+});
+
 // ]]>
 </script>
 {/literal}
 
-<form id="auth" method="post" action="admin/user">
+<div id="tabs">
+  Compte de {$user->login()}.
+  <ul style="margin-top: 0">
+    <li><a href="{$platal->pl_self()}#account"><span >Compte</span></a></li>
+    <li><a href="{$platal->pl_self()}#emails"><span>Emails</span></a></li>
+    <li><a href="{$platal->pl_self()}#forums"><span>Forums</span></a></li>
+  </ul>
+</div>
+
+<div id="account">
+<form id="auth" method="post" action="admin/user/{$user->login()}#account">
   {xsrf_token_field}
-  <table cellspacing="0" cellpadding="2" class="tinybicol">
+  <h1>Informations sur le compte</h1>
+  <p class="smaller">
+    Dernière connexion le <strong>{$lastlogin|date_format:"%d %B %Y, %T"}</strong>
+    depuis <strong>{$host}</strong>.
+  </p>
+
+  <table class="bicol">
     <tr>
       <th colspan="2">
         <div style="float: right; text-align: right">
-          Matricule = {$mr.matricule}<br />
-          Matricule AX = {$mr.matricule_ax}
+          Inscrit le {$user->registration_date|date_format}
         </div>
         <div style="float: left; text-align: left">
-          UID = {$mr.user_id}<br />
-          Inscription = {$mr.date_ins|date_format}
+          {icon name=user_gray} {$mr.hruid} (uid {$user->id()})
         </div>
-        <input type="hidden" name="user_id" value="{$mr.user_id}" />
+        <input type="hidden" name="uid" value="{$user->id()}" />
       </th>
     </tr>
-    <tr class="pair">
-      <td class="titre">
-        Mot de passe
+    <tr>
+      <td class="titre">Nom complet</td>
+      <td><input type="text" name="full_name" maxlength="255" value="{$user->fullName()}" /></td>
+    </tr>
+    <tr>
+      <td class="titre">Nom affiché</td>
+      <td><input type="text" name="display_name" maxlength="255" value="{$user->displayName()}" /></td>
+    </tr>
+    <tr>
+      <td class="titre">Sexe</td>
+      <td>
+        <label>femme <input type="radio" name="sex" value="female" {if $user->isFemale()}checked="checked"{/if} /></label>
+        <label><input type="radio" name="sex" value="male" {if !$user->isFemale()}checked="checked"{/if} /> homme</label>
       </td>
+    </tr>
+    <tr class="impair">
+      <td class="titre">Mot de passe</td>
       <td>
         <div style="float: left">
-          <input type="text" name="newpass_clair" size="10" maxlength="10" value="********" />
-          <input type="hidden" name="passw" size="32" maxlength="32" value="{$mr.password}" />
+          <input type="text" name="newpass_clair" size="10" maxlength="255" value="********" />
           <input type="hidden" name="hashpass" value="" />
         </div>
         <div style="float: left; margin-top: 5px;">
@@ -149,6 +142,149 @@ function ban_read()
         </div>
       </td>
     </tr>
+    <tr class="impair">
+      <td class="titre">Mot de passe SMTP</td>
+      <td>
+        <div style="float: left">
+          <input type="password" name="weak_password" size="10" maxlength="256" value="" />
+          {if $user->weak_access}
+          <input type="submit" name="disable_weak_access" value="Supprimer" />
+          {/if}
+        </div>
+      </td>
+    </tr>
+    <tr class="impair">
+      <td class="titre">Accès RSS</td>
+      <td>
+        <label>
+          <input type="checkbox" name="token_access" {if $user->token_access}checked="checked"{/if} value="1" />
+          activer l'accès
+        </label>
+      </td>
+    </tr>
+    <tr class="impair">
+      <td class="titre">Skin</td>
+      <td>
+        <select name="skin">
+          <option value="" {if !$user->skin}selected="selected"{/if}>Aucune (défaut du système)</option>
+          {iterate from=$skins item=skin}
+          <option value="{$skin.id}" {if $user->skin eq $skin.id}selected="selected"{/if}>{$skin.name}</option>
+          {/iterate}
+        </select>
+      </td>
+    </tr>
+    <tr class="pair">
+      <td class="titre">Etat du compte</td>
+      <td>
+        <select name="state">
+          <option value="pending" {if $user->state eq 'pending'}selected="selected"{/if}>pending (Non-inscrit)</option>
+          <option value="active" {if $user->state eq 'active'}selected="selected"{/if}>active (Inscrit, peut se logguer)</option>
+          <option value="disabled" {if $user->state eq 'disabled'}selected="selected"{/if}>disabled (Inscrit, accès interdit)</option>
+        </select><br />
+        <label>
+          <input type="checkbox" name="is_admin" value="1" {if $user->is_admin}checked="checked"{/if} />
+          administrateur du site
+        </label>
+      </td>
+    </tr>
+    <tr class="pair">
+      <td class="titre">Type de compte</td>
+      <td>
+        <select name="type">
+          {iterate from=$account_types item=type}
+          <option value="{$type.type}" {if $user->type eq $type.type}selected="selected"{/if}>{$type.type} ({$type.perms})</option>
+          {/iterate}
+        </select>
+        <a href="admin/account/types">{icon name=wrench title=Gérer} gérer</a>
+      </td>
+    </tr>
+    <tr class="pair">
+      <td class="titre">
+        Surveillance
+      </td>
+      <td>
+        <label><input type="checkbox" name="watch" {if $user->watch}checked="checked"{/if} value="1" />
+        Surveiller l'activité de ce compte</label><br />
+        <span class="smaller">Cette option permet d'avoir des logs complets de l'activité
+        du compte via le logger, et d'être alerté lors des connexions de l'utilisateur.</span>
+      </td>
+    </tr>
+    <tr class="pair">
+      <td class="titre">
+        Commentaire
+      </td>
+      <td>
+        <input type="text" name="comment" size="40" maxlength="64" value="{$user->comment}" />
+      </td>
+    </tr>
+    <tr class="impair">
+      <td colspan="2" class="center">
+        {* TODO: on 'update_account', update the hashpass field before sending the form. *}
+        <input type="submit" name="update_account" value="Mettre à jour" />
+        <input type="submit" name="su_account" value="Prendre l'identité" />
+        <input type="submit" name="log_account" value="Consulter les logs" />
+      </td>
+    </tr>
+  </table>
+</form>
+
+<h1>Fiches associées au compte</h1>
+
+<form id="profiles" method="post" action="admin/user/{$user->login()}#account">
+  {xsrf_token_field}
+  <table class="bicol">
+    <tr>
+      <th></th>
+      <th>Identifiant de la fiche</th>
+      <th></th>
+    </tr>
+    {iterate from=$profiles item=profile}
+    <tr>
+      <td><input type="radio" name="owner" value="{$profile.pid}" {if $profile.owner}checked="checked"{/if}
+                 onclick="this.form.submit()" /></td>
+      <td>{$profile.hrpid}</td>
+      <td class="right">
+        <a href="profile/edit/{$profile.hrpid}">{icon name=user_edit}</a>
+        <a href="profile/{$profile.hrpid}" class="popup2">{icon name=user_suit}</a>
+        <a href="javascript:del_profile({$profile.pid})">{icon name=cross}</a>
+      </td>
+    </tr>
+    {/iterate}
+    <tr>
+      <td>
+        <input type="radio" name="owner" value="0" onclick="this.form.submit()" />
+      </td>
+      <td>None</td>
+      <td></td>
+    </tr>
+    <tr class="pair">
+      <td colspan="3">
+        <input type="hidden" name="del_profile" value="" />
+        <input type="text" maxlength="64" name="new_profile" />
+        <input type="submit" name="add_profile" value="Ajouter" />
+      </td>
+    </tr>
+  </table>
+</form>
+
+</div>
+
+<!--
+  <h1>Informations sur la fiche</h1>
+  <table cellspacing="0" cellpadding="2" class="tinybicol">
+    <tr>
+      <th colspan="2">
+        <div style="float: right; text-align: right">
+          Matricule = {$mr.matricule}<br />
+          Matricule AX = {$mr.matricule_ax}
+        </div>
+        <div style="float: left; text-align: left">
+          UID = {$mr.user_id}<br />
+          Inscription = {$mr.date_ins|date_format}
+        </div>
+        <input type="hidden" name="user_id" value="{$mr.user_id}" />
+      </th>
+    </tr>
     <tr class="pair">
       <td class="titre">
         Nom
@@ -228,25 +364,6 @@ function ban_read()
         <input type="text" name="promoN" size="4" maxlength="4" value="{$mr.promo}" />
       </td>
     </tr>
-    <tr class="impair">
-      <td class="titre">
-        Surveillance
-      </td>
-      <td>
-        <label><input type="checkbox" name="watchN" {if $mr.watch}checked="checked"{/if} />
-        Surveiller l'activité de ce compte</label><br />
-        <span class="smaller">Cette option permet d'avoir des logs complets de l'activité
-        du compte via le logger, et d'être alerté lors des connexions de l'utilisateur.</span>
-      </td>
-    </tr>
-    <tr class="impair">
-      <td class="titre">
-        Commentaire
-      </td>
-      <td>
-        <input type="text" name="commentN" size="40" maxlength="64" value="{$mr.comment}" />
-      </td>
-    </tr>
     {if $mr.perms eq 'pending'}
     <tr class="center">
       <td colspan="2">
@@ -279,12 +396,17 @@ function ban_read()
 Ne pas utiliser [Désinscrire] si le but est d'exclure la personne.
 Pour ceci changer ses permissions en 'disabled'.
 </p>
-<form id="alias" method="post" action="admin/user">
+-->
+
+<div id="emails">
+<h1>Gestion de l'adresse X.org</h1>
+
+<form id="alias" method="post" action="admin/user/{$user->login()}#emails">
   {xsrf_token_field}
-  <table class="tinybicol" cellpadding="2" cellspacing="0">
+  <table class="bicol" cellpadding="2" cellspacing="0">
     <tr>
       <th class="alias" colspan="3">
-        Alias email
+        Alias email de l'utilisateur
       </th>
     </tr>
     {iterate from=$aliases item=a}
@@ -300,18 +422,11 @@ Pour ceci changer ses permissions en 'disabled'.
       <td>garanti à vie*</td>
       {else}
       <td class="action">
-        <a href="javascript:del_alias('{$a.alias}')">delete</a>
+        <a href="javascript:del_alias('{$a.alias}')">{icon name=cross}</a>
       </td>
       {/if}
     </tr>
     {/iterate}
-    {iterate from=$virtuals item=virtual}
-    <tr class="{cycle values="impair,pair"}">
-      <td></td>
-      <td>{$virtual.alias}</td>
-      <td></td>
-    </tr>
-    {/iterate}
     <tr class="{cycle values="impair,pair"}">
       <td colspan="2" class="detail">
         <input type="text" name="email" size="29" maxlength="60" value="" />
@@ -322,62 +437,17 @@ Pour ceci changer ses permissions en 'disabled'.
         <input type="submit" name="add_alias" value="Ajouter" />
       </td>
     </tr>
-  </table>
-</form>
-
-<p><strong>* à ne modifier qu'avec l'accord express de l'utilisateur !!!</strong></p>
-
-<form id="bans" method="post" action="admin/user">
-  {xsrf_token_field}
-  <table cellspacing="0" cellpadding="2" class="tinybicol">
-    <tr>
-      <th colspan="4">
-        Permissions sur les forums
-      </th>
-    </tr>
-    <tr class="impair">
-      <td class="titre">
-        Poster
-      </td>
-      <td>
-        <input type="text" name="write_perm" size="32" maxlength="255" value="{$bans.write_perm}" />
-      </td>
-      <td class="action">
-        <a href="javascript:ban_write()">Bannir</a>
-      </td>
-    </tr>
-    <tr class="pair">
-      <td class="titre">
-        Lire
-      </td>
-      <td>
-        <input type="text" name="read_perm" size="32" maxlength="255" value="{$bans.read_perm}" />
-      </td>
-      <td class="action">
-        <a href="javascript:ban_read()">Bannir</a>
-      </td>
-    </tr>
-    <tr class="impair">
-      <td class="titre">
-        Commentaire
-      </td>
-      <td colspan="2">
-        <input type="text" name="comment" size="40" maxlength="255" value="{$bans.comment}" />
-      </td>
-    </tr>
-    <tr class="center">
-      <td colspan="3">
-        <input type="hidden" name="user_id" value="{$mr.user_id}" />
-        <input type="submit" name="b_edit" value="Modifier" />
+    <tr class="{cycle values="impair,pair"}">
+      <td colspan="3" class="desc">
+        <strong>* à ne modifier qu'avec l'accord express de l'utilisateur !!!</strong>
       </td>
     </tr>
   </table>
 </form>
 
-{javascript name="ajax"}
-{test_email hruid=$user->login()}
+<br />
 
-<form id="fwds" method="post" action="admin/user#fwds">
+<form id="fwds" method="post" action="admin/user/{$user->login()}#emails">
   {xsrf_token_field}
   <table class="bicol" cellpadding="2" cellspacing="0">
     <tr>
@@ -409,14 +479,14 @@ Pour ceci changer ses permissions en 'disabled'.
       </td>
       <td>
         {if $mail->broken}<span style="color: #f00">{/if}
-        {if $mail->email == 'googleapps'}<a href="admin/googleapps/user/{$mr.hruid}">{/if}
+        {if $mail->email == 'googleapps'}<a href="admin/googleapps/user/{$user->login()}">{/if}
         {$mail->display_email}
         {if $mail->email == 'googleapps'}</a>{/if}
         {if $mail->broken}<em> (en panne)</em></span>{/if}
       </td>
       <td class="action">
         {if $mail->is_removable()}
-        <a href="javascript:del_fwd('{$mail->email}')">delete</a>
+        <a href="javascript:del_fwd('{$mail->email}')">{icon name=cross}</a>
         {/if}
       </td>
     </tr>
@@ -463,7 +533,75 @@ Pour ceci changer ses permissions en 'disabled'.
   </table>
 </form>
 
-{/if}
+{javascript name="ajax"}
+{test_email hruid=$user->login()}
+
+<h1>Autres adresses de l'utilisateur</h1>
+
+<table class="bicol">
+  <th>Virtual aliases auquel l'utilisateur appartient</th>
+  {foreach from=$virtuals item=virtual}
+  <tr class="{cycle values="impair,pair"}">
+    <td>{$virtual}</td>
+  </tr>
+  {/foreach}
+</table>
+
+</div>
+
+<div id="forums">
+
+<h1>Gestion de l'accès au forums</h1>
+
+<form id="bans" method="post" action="admin/user/{$user->login()}#forums">
+  {xsrf_token_field}
+  <table class="bicol">
+    <tr>
+      <th colspan="4">
+        Permissions sur les forums
+      </th>
+    </tr>
+    <tr class="impair">
+      <td class="titre">
+        Poster
+      </td>
+      <td>
+        <input type="text" name="write_perm" size="32" maxlength="255" value="{$bans.write_perm}" />
+      </td>
+      <td class="action">
+        <a href="javascript:ban_write()">Bannir</a>
+      </td>
+    </tr>
+    <tr class="pair">
+      <td class="titre">
+        Lire
+      </td>
+      <td>
+        <input type="text" name="read_perm" size="32" maxlength="255" value="{$bans.read_perm}" />
+      </td>
+      <td class="action">
+        <a href="javascript:ban_read()">Bannir</a>
+      </td>
+    </tr>
+    <tr class="impair">
+      <td class="titre">
+        Commentaire
+      </td>
+      <td colspan="2">
+        <input type="text" name="comment" size="40" maxlength="255" value="{$bans.comment}" />
+      </td>
+    </tr>
+    <tr class="center">
+      <td colspan="3">
+        <input type="hidden" name="user_id" value="{$mr.user_id}" />
+        <input type="submit" name="b_edit" value="Modifier" />
+      </td>
+    </tr>
+  </table>
+</form>
+</div>
+
+
 {/if}
 {/if}
 
index d935d67..2144057 100644 (file)
@@ -68,7 +68,7 @@
 {/literal}
 
 <p class="center">
-   <a href="Site/AllRecentChanges?action=rss&user={$smarty.session.hruid}&hash={$smarty.session.core_rss_hash}" style="display:block;float:right" title="Changements">{icon name=feed title='fil rss'}</a>
+   <a href="Site/AllRecentChanges?action=rss&user={$smarty.session.hruid}&hash={$smarty.session.token}" style="display:block;float:right" title="Changements">{icon name=feed title='fil rss'}</a>
    {icon name=magnifier} <a href="Site/AllRecentChanges">Voir les changements récents</a>
 </p>
 
index ffa0fa5..4ebb6a0 100644 (file)
         <input type="submit" name="action" value="add" />
       </td>
     </tr>
-    {iterate item=a from=$admins}
+    {foreach item=a from=$admins}
     <tr class="{cycle values="impair, pair"}">
-      <td><a href="profile/{$a.hruid}" class="popup2">{$a.prenom} {$a.nom} (X{$a.promo}){icon name=user_suit}</a></td>
-      <td class="right"><a href="admin/axletter/del/{$a.hruid}?token={xsrf_token}">{icon name=cross title="Retirer"}</a></td>
+      <td>{profile user=$a promo=true}</td>
+      <td class="right"><a href="admin/axletter/del/{$a->login()}?token={xsrf_token}">{icon name=cross title="Retirer"}</a></td>
     </tr>
-    {/iterate}
+    {/foreach}
   </table>
 </form>
 
index 5f8f059..b63930d 100644 (file)
@@ -34,7 +34,7 @@
 {$am->title()}
 ====================================================================
 
-{$am->head($prenom, $nom, $sexe, 'text')}
+{$am->head($user, 'text')}
 
 {$am->body('text')}
 
@@ -75,7 +75,7 @@ ne plus recevoir : &lt;https://www.polytechnique.org/ax/out{if $hash}/{$hash}{/i
 {/if}
     <div class='ax_mail'>
       <div class="title">{$am->title()}</div>
-      <div class="intro">{$am->head($prenom, $nom, $sexe, 'html')|smarty:nodefaults}</div>
+      <div class="intro">{$am->head($user, 'html')|smarty:nodefaults}</div>
       <div class="body">{$am->body('html')|smarty:nodefaults}</div>
       <div class="signature">{$am->signature('html')|smarty:nodefaults}</div>
       <div class="foot1">
index f44ef2b..9525634 100644 (file)
@@ -53,8 +53,8 @@
 <table class="bicol">
   <tr>
     <th colspan="2">
-      {if $smarty.session.core_rss_hash}
-      <a href="carnet/rss/{$smarty.session.hruid}/{$smarty.session.core_rss_hash}/rss.xml" style="display:block;float:right" title="Notifications">
+      {if $smarty.session.token}
+      <a href="carnet/rss/{$smarty.session.hruid}/{$smarty.session.token}/rss.xml" style="display:block;float:right" title="Notifications">
         {icon name=feed title='fil rss'}
       </a>
       {else}
index 79352c7..d6d2dff 100644 (file)
@@ -64,7 +64,7 @@
   </li>
   <li>
     {icon name=calendar_view_day title='Anniversaires'} 
-    <a href="carnet/contacts/ical/{$smarty.session.hruid}/{$smarty.session.core_rss_hash}/anniv-x.ics" title="Anniversaires">
+    <a href="carnet/contacts/ical/{$smarty.session.hruid}/{$smarty.session.token}/anniv-x.ics" title="Anniversaires">
       Le calendrier des anniversaires
     </a>
   </li>
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 ea7705b..167432f 100644 (file)
@@ -38,61 +38,41 @@ Il faut pour cela se rendre sur la page de <a href='carnet/notifs'>configuration
 </p>
 
 <div class="right">
-{if $smarty.session.core_rss_hash}
-<a href="carnet/rss/{$smarty.session.hruid}/{$smarty.session.core_rss_hash}/rss.xml" title="Notifications">{icon name=feed title='fil rss'}</a>
+{if $smarty.session.token}
+<a href="carnet/rss/{$smarty.session.hruid}/{$smarty.session.token}/rss.xml" title="Notifications">{icon name=feed title='fil rss'}</a>
 {/if}
 </div>
 
-{foreach from=$notifs->_data item=c key=cid}
-<h2>{if ($c|@count) > 1}
-{$notifs->_cats[$cid].mail}&nbsp;:
-{else}
-  {foreach from=$c item=promo}
-    {if ($promo|@count) > 1}
-      {$notifs->_cats[$cid].mail}&nbsp;:
-    {else}
-      {if $promo[0].sexe}
-        {$notifs->_cats[$cid].mail_sg_xette}&nbsp;:
-      {else}
-        {$notifs->_cats[$cid].mail_sg}&nbsp;:
-      {/if}
+{foreach from=$notifs item=cat}
+<fieldset style="width: 75%; margin-left: auto; margin-right: auto">
+  <legend>{$cat.title}</legend>
+  {assign var=date value=false}
+    {foreach from=$cat.users item=user}
+    {assign var=userdate value=$cat.operation->getDate($user)}
+    {if !$date || $date ne $userdate}
+    {if $date}
+    </ul>
     {/if}
-  {/foreach}
-{/if}</h2>
-
-<br />
-
-<table class='tinybicol'>
-  {foreach from=$c key=p item=promo}
-  {section name=row loop=$promo}
-  <tr {if ( $promo[row].known > $smarty.session.watch_last ) || ( $promo[row].date eq $today ) }style="font-weight: bold"{/if}>
-    <td class='titre' style="width:15%" {if $promo[row].data}rowspan="2"{/if}>{if $smarty.section.row.first}{$p}{/if}</td>
-    <td>
-      {if $promo[row].inscrit}
-      <a href="profile/{$promo[row].bestalias}" class="popup2">
-        {$promo[row].prenom} {$promo[row].nom}
-      </a>
-      {if !$promo[row].contact}
-      <a href="carnet/contacts?action=ajouter&amp;user={$promo[row].bestalias}&amp;token={xsrf_token}">{*
-        *}{icon name=add title="ajouter à mes contacts"}</a>
-      {/if}
-      {else}
-      {$promo[row].prenom} {$promo[row].nom}
-      {/if}
-    </td>
-    <td style="width:25%">
-      {$promo[row].date|date_format}
-    </td>
-    {if $promo[row].data}
-    </tr><tr><td colspan="2">{$promo[row].data|smarty:nodefaults}</td>
+    {assign var=date value=$userdate}
+    <p>Le {$date|date_format}&nbsp;:</p>
+    <ul>
     {/if}
-  </tr>
-  {/section}
-  {/foreach}
-</table>
-
-<br />
+    <li>
+      {if $cat.operation->seen($user,$smarty.session.watch_last)}<strong>{/if}
+      {profile user=$user promo=true}
+      {if $cat.operation->seen($user,$smarty.session.watch_last)}</strong>{/if}
+      {assign var=data value=$cat.operation->getData($user)}
+      {if $data}
+      <ul>
+        {foreach from=$data item=a}
+        <li>{$a}</li>
+        {/foreach}
+      </ul>
+      {/if}
+    </li>
+    {/foreach}
+  </ul>
+</fieldset>
 {/foreach}
 
-
 {* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index 9b97c1d..0630157 100644 (file)
 {*                                                                        *}
 {**************************************************************************}
 
-{if $article->data}{$article->prenom} {$article->nom} a mis à jours les données suivantes&nbsp;:<br />{$article->data}<br />{/if}
-{if !$article->contact and !$article->dcd}
-<a href="{#globals.baseurl#}/carnet/contacts?action=ajouter&amp;user={$article->bestalias}&amp;token={$rss_hash}">
+{if $article->data}
+<p>{profile user=$article->user promo=false link=false} a mis à jours les données suivantes&nbsp;:</p>
+<ul>
+{foreach from=$article->data item=f}
+  <li>{$f}</li>
+{/foreach}
+</ul>
+{/if}
+{if !$article->contact and !$article->dead}
+<a href="{#globals.baseurl#}/carnet/contacts?action=ajouter&amp;user={$article->hruid}&amp;token={$rss_hash}">
   {icon name=add title="Ajouter" full=true} Ajouter &agrave; mes contacts
 </a><br />
 {/if}
-{if !$article->dcd}
-<a href="{#globals.baseurl#}/vcard/{$article->bestalias}.vcf">
+{if !$article->dead}
+<a href="{#globals.baseurl#}/vcard/{$article->profile}.vcf">
   {icon name=vcard title="Carte de visite" full=true} T&eacute;l&eacute;charger la carte de visite &eacute;lectronique
 </a>
 {/if}
index f478942..720a82e 100644 (file)
   Accès réservé aux polytechniciens
 </h1>
 {/if}
-{if $smarty.session.auth ge AUTH_COOKIE}
-<p>
-<strong>Merci de rentrer ton mot de passe pour démarrer une connexion au site.</strong>
-Si tu n'es pas {insert name="getName"}, change le login ci-dessous, ou rends-toi sur
-<a href="register/">la page d'inscription</a>.
-</p>
-{/if}
 
 <form action="{$smarty.server.REQUEST_URI}" method="post" id="login" onsubmit="doChallengeResponse(); return false;" style="display: none">
   <table class="bicol" cellpadding="4" summary="Formulaire de login">
index f963a20..0591c9d 100644 (file)
@@ -37,6 +37,7 @@
 
 {if $actuel}
   {javascript name=ajax}
+  {if $user->hasProfile()}
   <table class="flags">
     <tr>
       <td class="orange">
@@ -52,7 +53,7 @@
       </td>
     </tr>
   </table>
-    
+  {/if}
 {else}
   <p>
     Pour plus de <strong>convivialité</strong> dans l'utilisation de tes emails, tu peux choisir une adresse
@@ -93,6 +94,7 @@
       <tr>
         <td><input type="text" name="alias" value="{$r_alias}" />@{#globals.mail.alias_dom#} et @{#globals.mail.alias_dom2#}</td>
       </tr>
+      {if $user->hasProfile()}
       <tr>
         <td>
           <table class="flags" summary="Flags" cellpadding="0" cellspacing="0">
           </table>
         </td>
       </tr>
+      {/if}
       <tr>
         <td>Brève explication&nbsp;:</td>
       </tr>
diff --git a/templates/emails/broken-web.mail.tpl b/templates/emails/broken-web.mail.tpl
new file mode 100644 (file)
index 0000000..c47674d
--- /dev/null
@@ -0,0 +1,47 @@
+{**************************************************************************}
+{*                                                                        *}
+{*  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               *}
+{*                                                                        *}
+{**************************************************************************}
+
+{config_load file="mails.conf" section="emails_broken"}
+{if $mail_part eq 'head'}
+{from full=#from#}
+{subject text=#subject#}
+{elseif $mail_part eq 'wiki'}
+Bonjour !
+
+Cet email a été généré automatiquement par le service de patte cassée de
+Polytechnique.org car un autre utilisateur, {$request->fullName()},
+nous a signalé qu'en t'envoyant un email, il avait reçu un message d'erreur
+indiquant que ton adresse de redirection {$email}
+ne fonctionnait plus !
+
+Nous te suggérons de vérifier cette adresse, et le cas échéant de mettre
+à jour tes adresses de redirection [[{$globals->baseurl}/emails|sur le site]].
+
+Pour plus de renseignements sur le service de patte cassée, n'hésite pas à
+consulter [[{$globals->baseurl}/emails/broken|la documentation sur le site]].
+
+
+À bientôt sur Polytechnique.org !\\
+[[support@{$globals->mail->domain}|L'équipe d'administration]]
+{/if}
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index 69eefeb..29ab6bc 100644 (file)
@@ -49,7 +49,7 @@ correspondant si tu veux que nous puissions te répondre.
 {elseif $x}
 <h2>Patte cassée</h2>
   <p>
-    Désolé, mais ton correspondant, {$x.prenom} {$x.nom} (X{$x.promo}),
+    Désolé, mais ton correspondant, {$x.user->fullName()},
     n'a actuellement <span class="erreur">aucune adresse email de redirection 
       active autre que celle que tu viens de rentrer.</span>
     Nous t'invitons à prendre contact avec lui autrement que par email,
index a365aa6..4194e34 100644 (file)
           {foreach key=key item=contact from=$contacts}
           {if in_array($contact.forlife, $smarty.request.to_contacts)}
           <option value="{$contact.forlife}">
-            {$contact.prenom} {$contact.nom} (X{$contact.promo})
+            {$contact.full_name}
           </option>
           {/if}
           {/foreach}
           {foreach key=key item=contact from=$contacts}
           {if in_array($contact.forlife, $smarty.request.cc_contacts)}
           <option value="{$contact.forlife}">
-            {$contact.prenom} {$contact.nom} (X{$contact.promo})
+            {$contact.full_name}
           </option>
           {/if}
           {/foreach}
             {foreach item=contact from=$contacts}
             {if !in_array($contact.forlife, $smarty.request.to_contacts) && !in_array($contact.forlife, $smarty.request.cc_contacts)}
             <option value="{$contact.forlife}">
-              {$contact.prenom} {$contact.nom} (X{$contact.promo})
+              {$contact.full_name}
             </option>
             {/if}
             {/foreach}
index 2caa447..cf503fb 100644 (file)
@@ -60,7 +60,7 @@
       <a href="admin/events/preview/{$ev.id}#event{$ev.id}">{$ev.titre}</a><br />
       {if !$ev.fvalide}</strong>{/if}
       <small>
-        Proposée par <a href="profile/{$ev.hruid}" class='popup2'>{$ev.prenom} {$ev.nom} (X{$ev.promo})</a>
+        Proposée par {profile user=$ev.user_id promo=true sex=false}
       </small>
     </td>
     <td class="right">{if !$ev.fvalide}<strong>{/if}{$ev.peremption}{if !$ev.fvalide}</strong>{/if}</td>
index a24a212..d7dad61 100644 (file)
@@ -27,7 +27,7 @@
 {else}
 
 <h1 id='pagetop'>
-Bienvenue {$smarty.session.yourself_name}{if $birthday}
+Bienvenue {$smarty.session.display_name}{if $birthday}
   &nbsp;et joyeux anniversaire de la part de toute l'équipe !
 {else},
 {/if}
@@ -52,8 +52,8 @@ Bienvenue {$smarty.session.yourself_name}{if $birthday}
     <tr class="pair" style="height: 18px">
       <td class="half titre" style="height: 18px; padding-top: 1px; padding-bottom: 1px;">
         {if $smarty.foreach.events.first}
-        {if $smarty.session.core_rss_hash}
-        <a href="rss/{$smarty.session.hruid}/{$smarty.session.core_rss_hash}/rss.xml" style="display:block;float:right" title="Annonces">
+        {if $smarty.session.token}
+        <a href="rss/{$smarty.session.hruid}/{$smarty.session.token}/rss.xml" style="display:block;float:right" title="Annonces">
           {icon name=feed title='fil rss'}
         </a>
         {else}
@@ -92,8 +92,8 @@ Bienvenue {$smarty.session.yourself_name}{if $birthday}
     {if !$has_evts}
     <tr>
       <td class="half">
-        {if $smarty.session.core_rss_hash}
-        <a href="rss/{$smarty.session.hruid}/{$smarty.session.core_rss_hash}/rss.xml" style="display:block;float:right" title="Annonces">
+        {if $smarty.session.token}
+        <a href="rss/{$smarty.session.hruid}/{$smarty.session.token}/rss.xml" style="display:block;float:right" title="Annonces">
           {icon name=feed title='fil rss'}
         </a>
         {else}
@@ -189,10 +189,7 @@ Bienvenue {$smarty.session.yourself_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 1caa179..028e0b9 100644 (file)
@@ -1,6 +1,6 @@
 {**************************************************************************}
 {*                                                                        *}
-{*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+{*  Copyright (C) 2003-2009 Polytechnique.org                             *}
 {*  http://opensource.polytechnique.org/                                  *}
 {*                                                                        *}
 {*  This program is free software; you can redistribute it and/or modify  *}
index e4032ba..673d6bd 100644 (file)
@@ -22,7 +22,7 @@
 
 <div class="events">
   <ul>
-  {iterate from=$events item=ev}
+  {foreach from=$events item=ev}
     <li class="{if $ev.nonlu}unread{else}read{/if}" id="evt-{$ev.id}">
       {if $ev.nonlu}
       <div  id="mark-read-{$ev.id}" style="float: right">
       </div>
       {/if}
       <a href="events{if !$ev.nonlu}/unread/{$ev.id}{else}#newsid{$ev.id}{/if}" target="_blank" id="link-{$ev.id}"
-         title="Ajouté le {$ev.creation_date|date_format} par {$ev.prenom} {$ev.nom} (X{$ev.promo})">
+         title="Ajouté le {$ev.creation_date|date_format} par {profile user=$ev.user_id link=false sex=false promo=true}">
         {tidy}
           {$ev.titre|nl2br}
         {/tidy}
       </a>
     </li>
   {assign var="has_evts" value=true}
-  {/iterate}
+  {/foreach}
   {if !$has_evts}
     <li><em>Aucun article actuellement.</em></li>
   {/if}
index fe39841..53f7d6b 100644 (file)
 {*                                                                        *}
 {**************************************************************************}
 
-<div class="contact {if (!$c.inscrit && $smarty.session.auth ge AUTH_COOKIE) || $c.dcd}grayed{/if}"
-     {if $c.inscrit}{if $smarty.session.auth ge AUTH_COOKIE}title="fiche mise à jour le {$c.date|date_format}"{/if}{/if}>
+{assign var=profile value=$user->profile()}
+{assign var=dead    value=$profile->deathdate}
+{if $user->state neq 'pending'}
+{assign var=registered value=true}
+{else}
+{assign var=registered value=false}
+{/if}
+{if $smarty.session.auth ge AUTH_COOKIE}
+{assign var=withAuth value=true}
+{else}
+{assign var=withAuth value=false}
+{/if}
+
+
+<div class="contact {if (!$registered && $withAuth) || $dead }grayed{/if}"
+     {if $registered && $withAuth}title="fiche mise à jour le {$profile->last_change|date_format}"{/if}>
   <div class="identity">
-    {if $smarty.session.auth ge AUTH_COOKIE}
+    {if $withAuth}
     <div class="photo">
-      <img src="photo/{$c.hruid}"
-           alt="{$c.name_display}" />
+      <img src="photo/{$profile->hrid()}" alt="{$profile->directory_name}" />
     </div>
     {/if}
 
     <div class="nom">
-      {if $c.sexe}&bull;{/if}
-      {if !$c.dcd && ($c.inscrit || $smarty.session.auth eq AUTH_PUBLIC)}<a href="profile/{$c.hruid}" class="popup2">{/if}
-      <span {if $c.name_tooltip}class="hinted" title="{$c.name_tooltip}"{/if}>{$c.name_display}</span>
-      {if !$c.dcd && ($c.inscrit || $smarty.session.auth eq AUTH_PUBLIC)}</a>{/if}
+      {if $profile->isFemale()}&bull;{/if}
+      {if !$dead && (!$registered || $withAuth)}<a href="profile/{$profile->hrid}" class="popup2">{/if}
+      {$profile->full_name}
+      {if !$dead && (!$registered || $withAuth)}</a>{/if}
     </div>
 
     <div class="edu">
-      {if $c.iso3166_1}
-      <img src='images/flags/{$c.iso3166_1}.gif' alt='{$c.nat1}' height='11' title='{$c.nat1}' />&nbsp;
+      {if $profile->nationality1}
+      <img src='images/flags/{$profile->nationality1}.gif' alt='{$profile->nationality1}' height='11' title='{$profile->nationality1}' />&nbsp;
       {/if}
-      {if $c.iso3166_2}
-      <img src='images/flags/{$c.iso3166_2}.gif' alt='{$c.nat2}' height='11' title='{$c.nat2}' />&nbsp;
+      {if $profile->nationality2}
+      <img src='images/flags/{$profile->nationality2}.gif' alt='{$profile->nationality2}' height='11' title='{$profile->nationality2}' />&nbsp;
       {/if}
-      {if $c.iso3166_3}
-      <img src='images/flags/{$c.iso3166_3}.gif' alt='{$c.nat3}' height='11' title='{$c.nat3}' />&nbsp;
+      {if $profile->nationality3}
+      <img src='images/flags/{$profile->nationality3}.gif' alt='{$profile->nationality3}' height='11' title='{$profile->nationality3}' />&nbsp;
       {/if}
-      {$c.promo_display}{if $c.eduname0}, {education_fmt name=$c.eduname0 url=$c.eduurl0 degree=$c.edudegree0
-                                     grad_year=$c.edugrad_year0 field=$c.edufield0 program=$c.eduprogram0 sexe=$c.sexe}{*
-      *}{/if}{if $c.eduname1}, {education_fmt name=$c.eduname1 url=$c.eduurl1 degree=$c.edudegree1
-                                     grad_year=$c.edugrad_year1 field=$c.edufield1 program=$c.eduprogram1 sexe=$c.sexe}{*
-      *}{/if}{if $c.eduname2}, {education_fmt name=$c.eduname2 url=$c.eduurl2 degree=$c.edudegree2
-                                     grad_year=$c.edugrad_year2 field=$c.edufield2 program=$c.eduprogram2 sexe=$c.sexe}{*
-      *}{/if}{if $c.eduname3}, {education_fmt name=$c.eduname3 url=$c.eduurl3 degree=$c.edudegree3
-                                     grad_year=$c.edugrad_year3 field=$c.edufield3 program=$c.eduprogram3 sexe=$c.sexe}{*
-      *}{/if}{if $c.dcd}, décédé{if $c.sexe}e{/if} le {$c.deces|date_format}{/if}
+      {$profile->promo()}{*
+      *}{iterate from=$profile->getExtraEducations(4) item=edu}, {education_fmt edu=$edu profile=$profile}{/iterate}{*
+      *}{if $dead}, {"décédé"|sex:"décédée":$user} le {$orfile->deathdate|date_format}{/if}
     </div>
   </div>
 
-  {if $smarty.session.auth ge AUTH_COOKIE}
+  {if $withAuth}
   <div class="noprint bits">
     <div>
-      {if !$c.wasinscrit && !$c.dcd}
-        {if $show_action eq ajouter}
-    <a href="carnet/notifs/add_nonins/{$c.user_id}?token={xsrf_token}">{*
+      {if !$registered && !$dead}
+        {if $show_action eq 'ajouter'}
+    <a href="carnet/notifs/add_nonins/{$user->login()}?token={xsrf_token}">{*
     *}{icon name=add title="Ajouter à la liste de mes surveillances"}</a>
         {else}
-    <a href="carnet/notifs/del_nonins/{$c.user_id}?token={xsrf_token}">{*
+    <a href="carnet/notifs/del_nonins/{$user->login()}?token={xsrf_token}">{*
     *}{icon name=cross title="Retirer de la liste de mes surveillances"}</a>
         {/if}
-      {elseif $c.wasinscrit}
-    <a href="profile/{$c.hruid}" class="popup2">{*
+      {elseif $registered}
+    <a href="profile/{$profile->hrid()}" class="popup2">{*
     *}{icon name=user_suit title="Afficher la fiche"}</a>
-        {if !$c.dcd}
-    <a href="vcard/{$c.hruid}.vcf">{*
+        {if !$dead}
+    <a href="vcard/{$profile->hrid()}.vcf">{*
     *}{icon name=vcard title="Afficher la carte de visite"}</a>
-    <a href="mailto:{$c.bestemail}">{*
+    <a href="mailto:{$user->bestEmail()}">{*
     *}{icon name=email title="Envoyer un email"}</a>
-          {if $show_action eq ajouter}
-    <a href="carnet/contacts?action={$show_action}&amp;user={$c.hruid}&amp;token={xsrf_token}">{*
+          {if !$smarty.session.user->isContact($user)}
+    <a href="carnet/contacts?action=ajouter&amp;user={$user->login()}&amp;token={xsrf_token}">{*
     *}{icon name=add title="Ajouter à mes contacts"}</a>
           {else}
-    <a href="carnet/contacts?action={$show_action}&amp;user={$c.hruid}&amp;token={xsrf_token}">{*
+    <a href="carnet/contacts?action=retirer&amp;user={$user->login()}&amp;token={xsrf_token}">{*
     *}{icon name=cross title="Retirer de mes contacts"}</a>
           {/if}
         {/if}
 
     {if hasPerm('admin')}
     <div>
-      [{if !$c.wasinscrit && !$c.dcd}
-      <a href="marketing/private/{$c.hruid}">{*
+      [{if $registered && !$dead}
+      <a href="marketing/private/{$user->login()}">{*
         *}{icon name=email title="marketter user"}</a>
       {/if}
-      <a href="admin/user/{$c.hruid}">{*
+      <a href="admin/user/{$user->login()}">{*
       *}{icon name=wrench title="administrer user"}</a>
-      <a href="http://www.polytechniciens.com/?page=AX_FICHE_ANCIEN&amp;anc_id={$c.matricule_ax}">{*
+      <a href="http://www.polytechniciens.com/?page=AX_FICHE_ANCIEN&amp;anc_id={$profile->ax_id}">{*
       *}{icon name=user_gray title="fiche AX"}</a>]
     </div>
     {/if}
   {/if}
 
   <div class="long">
-  {if $c.wasinscrit || !$c.dcd}
-    {if $c.web || $c.mobile || $c.countrytxt || $c.city || $c.region || $c.entreprise || $c.freetext || (!$c.dcd && !$c.actif )}
+  {if !$dead}
+    {assign var=address value=$profile->getMainAddress()}
+    {assign var=web     value=$profile->getWebSite()}
+    {assign var=job     value=$profile->getMailJob()}
+    {if $web || $profile->mobile || $address.country || $job || (!$dead && !$registered)}
     <table cellspacing="0" cellpadding="0">
-      {if $c.web}
+      {if $web}
       <tr>
         <td class="lt">Page web&nbsp;:</td>
-        <td class="rt"><a href="{$c.web}">{$c.web}</a></td>
+        <td class="rt"><a href="{$web}">{$web}</a></td>
       </tr>
       {/if}
-      {if ($c.countrytxt || $c.city) && !$c.dcd}
+      {if $address.country && !$c.dcd}
       <tr>
         <td class="lt">Géographie&nbsp;:</td>
-        <td class="rt">{$c.city}{if $c.city && $c.countrytxt}, {/if}{$c.countrytxt}</td>
+        <td class="rt">{if $address.locality}{$address.locality}, {/if}{$address.country}</td>
       </tr>
       {/if}
-      {if $c.mobile && !$c.dcd}
+      {if $profile->mobile && !$dead}
       <tr>
         <td class="lt">Mobile&nbsp;:</td>
-        <td class="rt">{$c.mobile}</td>
+        <td class="rt">{$profile->mobile}</td>
       </tr>
       {/if}
-      {if $c.entreprise}
+      {if $job}
       <tr>
         <td class="lt">Profession&nbsp;:</td>
         <td class="rt">
-          {if $c.job_web}<a href="{$c.job_web}">{$c.entreprise}</a>{else}{$c.entreprise}{/if}
-          {if $c.sector} ({$c.sector}){/if}{if $c.fonction}<br />{$c.fonction}{/if}
+          {if $job.url|default:$job.user_site}<a href="{$job.url|default:$job.user_site}">{$job.name}</a>{else}{$job.name}{/if}
+          {if $job.subsubsector}&nbsp;({$job.subsubsector}){/if}{if $job.description}<br />{$job.description}{/if}
         </td>
       </tr>
       {/if}
-      {if $c.freetext}
+      {if $withAuth}
+      {if !$registered}
       <tr>
-        <td class="lt">Commentaire&nbsp;:</td>
-        <td class="rt">{$c.freetext|nl2br}</td>
+        <td class="smaller" colspan="2">
+          {"Ce"|sex:"Cette":$user} camarade n'est pas {"inscrit"|sex:"inscrite":$user}.
+          <a href="marketing/public/{$user->login()}" class='popup'>Si tu connais son adresse email,
+          <strong>n'hésite pas à nous la transmettre !</a>
+        </td>
       </tr>
-      {/if}
-      {if !$c.dcd && (!$c.actif || !$c.wasinscrit) && $smarty.session.auth ge AUTH_COOKIE}
+      {elseif $user->state neq 'disabled' && $user->lost}
       <tr>
         <td class="smaller" colspan="2">
-          {if !$c.wasinscrit}
-          Ce{if $c.sexe}tte{/if} camarade n'est pas inscrit{if $c.sexe}e{/if}.
-          <a href="marketing/public/{$c.hruid}" class='popup'>Si tu connais son adresse email,
-          <strong>n'hésite pas à nous la transmettre !</a>
-          {elseif !$c.actif}
-          Ce{if $c.sexe}tte{/if} camarade n'a plus d'adresse de redirection valide.
-          <a href="marketing/broken/{$c.hruid}">
+          {"Ce"|sex:"Cette":$user} camarade n'a plus d'adresse de redirection valide.
+          <a href="marketing/broken/{$user->login()}">
             Si tu en connais une, <strong>n'hésite pas à nous la transmettre</strong>.
           </a>
-          {/if}
         </td>
       </tr>
       {/if}
+      {/if}
     </table>
     {/if}
   {/if}
index 38e3c78..d6ef8c3 100644 (file)
 
 <div class="contact-list" style="clear: both">
 {foreach from=$set item=res}
-  {if $res.contact}
-  {include file="include/minifiche.tpl" c=$res show_action="retirer"}
-  {else}
-  {include file="include/minifiche.tpl" c=$res show_action="ajouter"}
-  {/if}
+  {include file="include/minifiche.tpl" user=$res}
 {/foreach}
 </div>
 
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>
index a7af201..6c23ac5 100644 (file)
@@ -34,7 +34,7 @@
 {$nl->title()}
 ====================================================================
 
-{$nl->head($prenom, $nom, $sexe, 'text')}
+{$nl->head($user, 'text')}
 
 
 {foreach from=$nl->_arts key=cid item=arts name=cats}
@@ -51,7 +51,7 @@
 --------------------------------------------------------------------
 
 {foreach from=$arts item=art}
-{$art->toText($hash, $alias)}
+{$art->toText($hash, $user->login())}
 
 {/foreach}
 {/foreach}
@@ -93,7 +93,7 @@ ne plus recevoir : &lt;https://www.polytechnique.org/nl/out&gt;
 {/if}
     <div class='nl'>
       <div class="title">{$nl->title()}</div>
-      <div class="intro">{$nl->head($prenom, $nom, $sexe, 'html')|smarty:nodefaults}</div>
+      <div class="intro">{$nl->head($user, 'html')|smarty:nodefaults}</div>
       <a id="top_lnk"></a>
       {foreach from=$nl->_arts key=cid item=arts name=cats}
       <div class="lnk">
@@ -109,7 +109,7 @@ ne plus recevoir : &lt;https://www.polytechnique.org/nl/out&gt;
         {$nl->_cats[$cid]}
       </h1>
       {foreach from=$arts item=art}
-        {$art->toHtml($hash, $alias)|smarty:nodefaults}
+        {$art->toHtml($hash, $user->login())|smarty:nodefaults}
         <div class="top_lnk"><a href="{$prefix}#top_lnk">Revenir au sommaire</a></div>
       {/foreach}
       {/foreach}
index 4f661ce..a89e9c5 100644 (file)
 {*                                                                        *}
 {**************************************************************************}
 
-<h1>{$asso.nom}&nbsp;: Gestion des télépaiements </h1>
+<h1>{$asso->nom}&nbsp;: Gestion des télépaiements </h1>
 
 <p class="descr">
-Voici la liste des paiements en ligne possible pour le groupe {$asso.nom} :
+Voici la liste des paiements en ligne possible pour le groupe {$asso->nom} :
 </p>
 
 {foreach from=$titres item=p}
@@ -114,14 +114,12 @@ Voici la liste des paiements en ligne possible pour le groupe {$asso.nom} :
   <tr>
     <td class="center">{$p.date|date_format:"%d/%m/%y"}</td>
     <td>
-      <a href="https://www.polytechnique.org/profile/{$p.alias}" class="popup2">
-        {$p.nom|strtoupper} {$p.prenom}
-       </a>
+      {profile user=$p.user promo=false}
     </td>
     <td>
-      <a href="mailto:{$p.alias}@{#globals.mail.domain#}">{icon name=email title="email"}</a>
+      <a href="mailto:{$p.user->bestEmail()}">{icon name=email title="email"}</a>
     </td>
-    <td class="center">{$p.promo}</td>
+    <td class="center">{$p.user->promo()}</td>
     <td>{$p.comment|comment_decode}</td>
     <td class="right">{$p.montant}</td>
   </tr>
index d1d8215..24dbf2f 100644 (file)
 {*                                                                        *}
 {**************************************************************************}
 <h1>ChangeLog</h1>
+{if !$core}
 <p>Voici la liste des modifications faites sur <a href="http://opensource.polytechnique.org/platal/">plat/al</a>, le support libre de ce site.</p>
+
+<p>Cette version utilise <a href="changelog/core">plat/al-core {$globals->coreVersion}</a>.</p>
+{else}
+<p>Voici la liste des modifications faites sur la bibliothèque plat/al-core.</p>
+{/if}
+
 {$ChangeLog|smarty:nodefaults}
 {* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index a03d18a..8cbd273 100644 (file)
@@ -22,7 +22,7 @@
 
 <h1>Fil RSS</h1>
 
-{if !$smarty.session.core_rss_hash}
+{if !$smarty.session.token}
 <p>
   Tu viens de cliquer sur le lien d'activation des fils RSS. Les fils RSS du site
   ne sont pas activés dans tes préférences.
@@ -52,11 +52,11 @@ En voici les adresses&nbsp;:
 <ul>
   <li>
   Anonces sur la page d'entrée&nbsp;:
-  <a href="rss/{$smarty.session.hruid}/{$smarty.session.core_rss_hash}/rss.xml" title="Annonces">{icon name=feed title='fil rss'}</a>
+  <a href="rss/{$smarty.session.hruid}/{$smarty.session.token}/rss.xml" title="Annonces">{icon name=feed title='fil rss'}</a>
   </li>
   <li>
   Ton carnet polytechnicien&nbsp;:
-  <a href="carnet/rss/{$smarty.session.hruid}/{$smarty.session.core_rss_hash}/rss.xml" title="Notifications">{icon name=feed title='fil rss'}</a>
+  <a href="carnet/rss/{$smarty.session.hruid}/{$smarty.session.token}/rss.xml" title="Notifications">{icon name=feed title='fil rss'}</a>
   </li>
 </ul>
 <p>
index 38e3bcf..d914993 100644 (file)
@@ -61,9 +61,9 @@
   </tr>
   <tr class="impair">
     <td class="half">
-      {if $smarty.session.mail_fmt eq html}
+      {if $smarty.session.email_format eq html}
       <h3>
-        <a href="javascript:dynpostkv('prefs', 'mail_fmt', 'texte')">Recevoir les emails en format texte</a>
+        <a href="javascript:dynpostkv('prefs', 'email_format', 'text')">Recevoir les emails en format texte</a>
       </h3>
       <div class='explication'>
         Tu recois tous les emails envoyés par le site
@@ -72,7 +72,7 @@
       </div>
       {else}
       <h3>
-        <a href="javascript:dynpostkv('prefs', 'mail_fmt', 'html')">Recevoir les emails en HTML</a>
+        <a href="javascript:dynpostkv('prefs', 'email_format', 'html')">Recevoir les emails en HTML</a>
       </h3>
       <div class='explication'>
         Tu recois tous les emails envoyés par le site
@@ -83,7 +83,7 @@
     </td>
     <td class="half">
       <h3>
-        {if $smarty.session.core_rss_hash}
+        {if $smarty.session.token}
         <a href="javascript:dynpostkv('prefs', 'rss', 0)">Désactiver les fils rss</a>
         {else}
         <a href="javascript:dynpostkv('prefs', 'rss', 1)">Activer les fils rss</a>
index c3c301f..fde9623 100644 (file)
 <h1>
   Mise en place de la redirection
 </h1>
-<p>
-{if $carva}
-  Actuellement, les adresses
-  <a href="http://www.carva.org/{$bestalias}">http://www.carva.org/{$bestalias}</a> et
-  <a href="http://www.carva.org/{$smarty.session.hruid}">http://www.carva.org/{$smarty.session.hruid}</a>
-  sont redirigées sur <a href="http://{$carva}">http://{$carva}</a>
-{else}
-  La redirection n'est pas utilisée ...
-{/if}
-</p>
 
 <p>
-  Pour modifier cette redirection remplis le champ suivant et clique sur <strong>Valider</strong>.
+  Pour modifier ta redirection remplis le champ suivant et clique sur <strong>Valider</strong>.
 {if $carva}
   Si tu veux annuler ta redirection, clique sur <strong>Supprimer</strong>.
 {/if}
index 799004a..4e3bdc4 100644 (file)
     <td>
       <span class="titre">Date de naissance</span>
     </td>
-    <td><input type="text" {if $errors.naissance}class="error"{/if} name="naissance" value="{$naissance}" /></td>
+    <td><input type="text" {if $errors.birthdate}class="error"{/if} name="birthdate" value="{$birthdate}" /></td>
   </tr>
   <tr>
     <td>
       <span class="titre">Nationalité</span>
     </td>
     <td>
-      <select name="nationalite">
-        {select_nat valeur=$nationalite pad=1}
+      <select name="nationality1">
+        {select_nat valeur=$nationality1 pad=1}
       </select>
       <a href="javascript:addNationality();">{icon name=add title="Ajouter une nationalité"}</a>
     </td>
   </tr>
-  <tr id="nationalite2" {if !$nationalite2}style="display: none"{/if}>
+  <tr id="nationality2" {if !$nationality2}style="display: none"{/if}>
     <td></td>
     <td>
-      <select name="nationalite2">
-        {select_nat valeur=$nationalite2 pad=1}
+      <select name="nationality2">
+        {select_nat valeur=$nationality2 pad=1}
       </select>
       <a href="javascript:delNationality('2');">{icon name=cross title="Supprimer cette nationalité"}</a>
     </td>
   </tr>
-  <tr id="nationalite3" {if !$nationalite3}style="display: none"{/if}>
+  <tr id="nationality3" {if !$nationality3}style="display: none"{/if}>
     <td></td>
     <td>
-      <select name="nationalite3">
-        {select_nat valeur=$nationalite3 pad=1}
+      <select name="nationality3">
+        {select_nat valeur=$nationality3 pad=1}
       </select>
       <a href="javascript:delNationality('3');">{icon name=cross title="Supprimer cette nationalité"}</a>
     </td>
   <tr>
     <td {if !$nouvellephoto}colspan="2"{/if} class="center" style="width: 49%">
       <div class="titre">Ta photo actuelle</div>
-      <img src="photo/{$smarty.session.hruid}" alt=" [ PHOTO ] " style="max-height: 250px; margin-top: 1em" />
+      <img src="photo/{$profile->hrid()}" alt=" [ PHOTO ] " style="max-height: 250px; margin-top: 1em" />
     </td>
     {if $nouvellephoto}
     <td class="center" style="width: 49%">
       <div class="titre">Photo en attente de validation</div>
       <div>
-        <a href="profile/{$smarty.session.hruid}?modif=new" class="popup2">
+        <a href="profile/{$profile->hrid()}?modif=new" class="popup2">
           Ta fiche avec cette photo
         </a>
       </div>
-      <img src="photo/{$smarty.session.hruid}/req" alt=" [ PHOTO ] " style="max-height: 250px; margin-top: 1em" />
+      <img src="photo/{$profile->hrid()}/req" alt=" [ PHOTO ] " style="max-height: 250px; margin-top: 1em" />
     </td>
     {/if}
   </tr>
index 26e242b..ca0550d 100644 (file)
 
 <!-- Don't copy this list of emails!!!
 
+{assign var="login" value="false"}
+{if !t($login)}
+  {if t($smarty.session.auth)}
+  {assign var="login" value="true"}
+  {/if}
+{/if}
+
   {poison seed=$login}
 
   -->
 
-{if !$login && $smarty.session.auth}
-  {assign var="login" value="true"}
-{/if}
 
 <div id="bandeau-X">
   <img src="bandeau/icone.png" alt=""/>
@@ -49,9 +53,9 @@
   <a href="http://www.polytechniciens.com/">AX</a>
   &tilde;&tilde;
   <a href="https://www.polytechnique.org">Polytechnique.org</a> &middot;
-  <a href="http://www.polytechnique.net{if $login}/login{/if}">Associations polytechniciennes</a> &middot;
+  <a href="http://www.polytechnique.net{if t($login)}/login{/if}">Associations polytechniciennes</a> &middot;
   <a href="http://www.polytechnique.fr/eleves/">&Eacute;l&egrave;ves</a> &middot;
-  <a href="http://www.manageurs.com/{if $login}anciens_accueil.php?asso=X.org{/if}">Manageurs</a>
+  <a href="http://www.manageurs.com/{if t($login)}anciens_accueil.php?asso=X.org{/if}">Manageurs</a>
 </div>
 
 {* vim:set et sw=2 sts=2 sws=2 enc=utf8: *}
index aa133a5..0f7e24e 100644 (file)
@@ -43,9 +43,9 @@
     {include core=plpage.header.tpl}
     <link rel="stylesheet" type="text/css" href="css/base.css" media="all"/>
     <link rel="stylesheet" type="text/css" href="css/print.css" media="print"/>
-    <script type="text/javascript">
+    <script type="text/javascript">//<![CDATA[
       var platal_baseurl = "{$globals->baseurl}/";
-    </script>
+    //]]></script>
     {javascript name=overlib}
     {javascript name=md5}
     {javascript name=sha1}
index 339f0e4..4f030c2 100644 (file)
     <th>Nom</th>
     {if hasPerms('admin')}<th>Consultations</th>{/if}
   </tr>
-  {iterate from=$profiles item=profile}
+  {foreach from=$profiles item=profile}
   <tr class="{cycle values="pair,impair"}">
-    <td><a href="profile/{$profile.forlife}" class="popup">{$profile.prenom} {$profile.nom} (X{$profile.promo})</a></td>
+    <td>{profile user=$profile.profile promo=true}</td>
     {if hasPerms('admin')}<td class="right">{$profile.count}</td>{/if}
   </tr>
-  {/iterate}
+  {/foreach}
 </table>
 
 {* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index f133987..73d879b 100644 (file)
     <link rel="bookmark" href="http://www.polytechnique.fr/eleves/" title="| Site d'élèves" />
 
     {include core=plpage.header.tpl}
-    <script type="text/javascript">
+    <script type="text/javascript">//<![CDATA[
     var platal_baseurl = "{$globals->baseurl}/"
     if (window.top != window)
       document.write('<link rel="stylesheet" type="text/css" href="css/onlycontent.css" media="all"/>');
-    </script>
+    //]]></script>
     {javascript name=overlib}
     {include file=skin/common.bandeau.head.tpl}
   </head>
   <body>
     {include core=plpage.devel.tpl}
-    {if !$simple}
+    {if !t($simple)}
       {include file=skin/common.bandeau.tpl}
     {/if}
 
     <table id="layout" cellspacing="0" cellpadding="0">
-    {if !$simple}
+    {if !t($simple)}
       <tr>
         <td colspan="2">
         <table cellspacing="0" cellpadding="0" id="top">
               <a href="{if $is_logged}login{/if}"><img src="images/asso-montants.png" alt="Logo Assos" /></a>
             </td>
             <td style="width: 106px">
-              {if $xnet_type}
+              {if t($xnet_type)}
               <img src="images/logo_{$xnet_type}.png" alt="Logo {$xnet_type}" width="106" height="96" />
               {else}
-              <img src="images/logo_institutions.png" alt="Logo {$xnet_type}" width="106" height="96" />
+              <img src="images/logo_institutions.png" alt="Logo institutions" width="106" height="96" />
               {/if}
             </td>
             <td style="width: 44px">
             <td style="width: auto;">
               <img src="images/bandeau.jpg" alt="bandeau" height="96" width="100%" />
             </td>
-            {if $xnet_type}
+            {if t($xnet_type)}
             <td style="width: 280px">
-              <a href="{if $xnet_type eq plan}plan{else}groups/{$xnet_type}{/if}"><img src="images/texte_{$xnet_type}.jpg" alt="{$xnet_type}" width="280" height="96" /></a>
+              <a href="{if $xnet_type eq 'plan'}plan{else}groups/{$xnet_type}{/if}"><img src="images/texte_{$xnet_type}.jpg" alt="{$xnet_type}" width="280" height="96" /></a>
             </td>
-            {if $asso}
+            {if t($asso)}
             <td class="logo">
-              {if $asso.site}
-                <a href="{$asso.site}"><img src='{$platal->ns}logo' alt="LOGO" height="80" /></a>
+              {if t($asso->site)}
+                <a href="{$asso->site}"><img src='{$platal->ns}logo' alt="LOGO" height="80" /></a>
               {else}
                 <img src='{$platal->ns}logo' alt="LOGO" height="80"/>
               {/if}
       </tr>
     {/if}{* fin simple *}
 
-      {if $menu && !$simple}
+      {if $menu && !t($simple)}
       <tr>
         <td id="menu">
           {foreach from=$menu key=title item=submenu}
               {/if}
             {/foreach}
           {/foreach}
-          {if $asso && ($is_admin ||
+          {assign var=asso_id value=$asso->id}
+          {if $asso && $is_admin ||
                       ($smarty.session.suid && ($smarty.session.suid.perms->hasFlag('admin') ||
-                                                $smarty.session.suid.may_update[$asso.id])))}
+                                                $smarty.session.suid.may_update[$asso_id]))}
           <h1>Voir le site comme...</h1>
           <form method="post" action="{$platal->ns}change_rights">
             <div>
           {include core=plpage.content.tpl}
         </td>
       </tr>
-      {if !$simple}
+      {if !t($simple)}
       <tr class="hideable"><td colspan="2"><img src="images/barre.png" alt="----------" width="100%" /></td></tr>
 
       <tr class="hideable">
       </tr>
       {/if}
       {/if}
-    {if !$simple}
+    {if !t($simple)}
       <tr class="hideable"><td colspan="2"><img src="images/barre.png" alt="----------" width="100%" /></td></tr>
 
       <tr class="hideable">
index ab83d43..377a5a6 100644 (file)
@@ -20,7 +20,7 @@
 {*                                                                        *}
 {**************************************************************************}
 
-<h1>{$asso.nom}&nbsp;: <a href='{$platal->ns}events'>Événements</a> </h1>
+<h1>{$asso->nom}&nbsp;: <a href='{$platal->ns}events'>Événements</a> </h1>
 
 <p>
   {if $evt.titre || count($moments) eq 1}
@@ -83,19 +83,15 @@ Ils ont payé mais ont oublié de s'inscrire&nbsp;:
   {iterate from=$oubliinscription item=m}
   <tr class="pair">
     <td>
-      <a href="" {if $is_admin}onclick="return remplitAuto('{$m.email}')"{/if}>
-        {if !$m.prenom && !$m.nom}
-        {$m.email}
-        {else}
-        {$m.prenom} {$m.nom}
-        {/if}
+      <a href="" {if $is_admin}onclick="return remplitAuto('{$m.user->login()}')"{/if}>
+        {profile user=$m.user link=false}
       </a>
     </td>
-    <td>{$m.promo}</td>
+    <td>{$m.user->promo()}</td>
     <td>
-      <a href="https://www.polytechnique.org/profile/{$m.email}">{icon name=user_suit title="fiche"}</a>
-      <a href="https://www.polytechnique.org/vcard/{$m.email}.vcf">{icon name=vcard title="vcard"}</a>
-      <a href="mailto:{$m.email}@{#globals.mail.domain#}">{icon name=email title="email"}</a>
+      <a href="https://www.polytechnique.org/profile/{$m.user->login()}">{icon name=user_suit title="fiche"}</a>
+      <a href="https://www.polytechnique.org/vcard/{$m.user->login()}.vcf">{icon name=vcard title="vcard"}</a>
+      <a href="mailto:{$m.user->bestEmail()}">{icon name=email title="email"}</a>
     </td>
     <td>{$m.montant}</td>
   </tr>
@@ -141,18 +137,18 @@ Ils ont payé mais ont oublié de s'inscrire&nbsp;:
   {foreach from=$participants item=m}
   <tr>
     <td>
-      {if $is_admin}<a href="javascript:remplitAuto('{$m.email}')">{/if}
-        {if $m.femme}&bull;{/if}{if !$m.prenom && !$m.nom}{$m.email}{else}{$m.prenom} {$m.nom}{/if}
+      {if $is_admin}<a href="javascript:remplitAuto('{$m.user->login()}')">{/if}
+        {profile user=$m.user promo=false link=false}
       {if $is_admin}</a>{/if}
     </td>
-    <td>{$m.promo}</td>
+    <td>{$m.user->promo()}</td>
     <td>
-      {if $m.x}
-      <a href="https://www.polytechnique.org/profile/{$m.email}">{icon name=user_suit title="fiche"}</a>
-      <a href="https://www.polytechnique.org/vcard/{$m.email}.vcf">{icon name=vcard title="vcard"}</a>
-      <a href="mailto:{$m.email}@{#globals.mail.domain#}">{icon name=email title="email"}</a>
+      {if $m.user->hasProfile()}
+      <a href="https://www.polytechnique.org/profile/{$m.user->login()}">{icon name=user_suit title="fiche"}</a>
+      <a href="https://www.polytechnique.org/vcard/{$m.user->login()}.vcf">{icon name=vcard title="vcard"}</a>
+      <a href="mailto:{$m.user->bestEmail()}">{icon name=email title="email"}</a>
       {else}
-      <a href="mailto:{$m.email}">{icon name=email title="email"}</a>
+      <a href="mailto:{$m.user->bestEmail()}">{icon name=email title="email"}</a>
       {/if}
     </td>
     {if $tout}
@@ -198,7 +194,7 @@ Ils ont payé mais ont oublié de s'inscrire&nbsp;:
 {/foreach}
 </p>
 
-{if $absents->total()}
+{if $absents|@count}
 
 <hr />
 
@@ -206,18 +202,18 @@ Ils ont payé mais ont oublié de s'inscrire&nbsp;:
 
 <table class="tinybicol">
   <tr><th>Prénom NOM</th><th>Origine</th></tr>
-  {iterate from=$absents item=m}
+  {foreach from=$absents item=m}
   <tr>
     <td>
-      {if $is_admin}<a href="javascript:remplitAuto('{$m.email}')">{/if}
-      {if $m.sexe}&bull;{/if}{$m.prenom} {$m.nom}
+      {if $is_admin}<a href="javascript:remplitAuto('{$m->login()}')">{/if}
+      {profile user=$m link=false promo=false}
       {if $is_admin}</a>{/if}
     </td>
     <td>
-      {$m.promo}
+      {$m->promo()}
     </td>
   </tr>
-  {/iterate}
+  {/foreach}
 </table>
 
 {/if}
index 4798a0d..9b50789 100644 (file)
@@ -25,13 +25,13 @@ VERSION:2.0
 CALSCALE:GREGORIAN
 X-WR-TIMEZONE:Europe/Paris
 METHOD:PUBLISH
-{display_ical name="x-wr-calname" value=$asso.nom}
+{display_ical name="x-wr-calname" value=$asso->nom}
 BEGIN:VEVENT
 DSTAMP:{$timestamp|date_format:"%Y%m%dT%H%M%SZ"}
 DTSTART;VALUE=DATE;TZID=Europe/Paris:{$e.debut}
 DTEND;VALUE=DATE;TZID=Europe/Paris:{$e.fin}
 ORGANIZER;CN="{$e.prenom} {$e.nom}":MAILTO:{$e.alias}@polytechnique.org
-UID:event-{$e.short_name}-{$e.eid}@{$asso.diminutif}.polytechnique.org
+UID:event-{$e.short_name}-{$e.eid}@{$asso->diminutif}.polytechnique.org
 {if $admin}
 {foreach from=$participants item=m}
 {if $m.x}
index 1ed7346..f4d206d 100644 (file)
@@ -26,7 +26,7 @@ $telepayment}Télépaiement;Liquide/Chèque;{/if}Payé{/if}{else};Nombre{/if}
 {foreach from=$participants item=m}
 
 ;
-{$m.nom};{$m.prenom};{$m.promo}{if $tout}{foreach from=$moments item=i};{$m[$i.item_id]}{/foreach}{if $admin &&
+{$m.user->lastName()};{$m.user->firstName()};{$m.user->promo()}{if $tout}{foreach from=$moments item=i};{$m[$i.item_id]}{/foreach}{if $admin &&
 $money};{$m.montant};{if $telepayment}{$m.telepayment};{$m.adminpaid};{/if}{$m.paid}{/if}{else};{$m.nb}{/if}
 
 {/foreach}
index 5670261..8ce2eb1 100644 (file)
@@ -35,7 +35,7 @@ function deadlineChange(box)
 {/literal}
 </script>
 
-<h1>{$asso.nom}&nbsp;: {$evt.intitule|default:"Nouvel événement"}</h1>
+<h1>{$asso->nom}&nbsp;: {$evt.intitule|default:"Nouvel événement"}</h1>
 
 <p class="descr">
   Un événement peut être une réunion, un séminaire, une conférence, un voyage promo,
index 5311d07..95d5abd 100644 (file)
 {**************************************************************************}
 
 {if !$is_admin}
-<h1>{$asso.nom}&nbsp;: Événements</h1>
+<h1>{$asso->nom}&nbsp;: Événements</h1>
 {else}
 <h1>
-  {$asso.nom}&nbsp;: 
+  {$asso->nom}&nbsp;: 
   {if $archive}[<a href="{$platal->ns}events">Événements</a>] {else}Événements {/if}
   {if $archive}Archives {else}[<a href="{$platal->ns}events/archive">Archives</a>] {/if}
 </h1>
@@ -97,9 +97,7 @@
 
   <tr>
     <td class="titre">Annonceur&nbsp;:</td>
-    <td>
-      <a href='https://www.polytechnique.org/profile/{$e.alias}' class='popup2'>{$e.prenom} {$e.nom} ({$e.promo})</a>
-    </td>
+    <td>{profile user=$e.organisateur_uid promo=true groupperms=false}</td>
   </tr>
 
   {if $is_admin || $e.show_participants || ($e.deadline_inscription && $e.inscr_open)}
index 695fe59..688876a 100644 (file)
@@ -20,7 +20,7 @@
 {*                                                                        *}
 {**************************************************************************}
 
-<h1>{$asso.nom}&nbsp;: Evénement {$event.intitule}</h1>
+<h1>{$asso->nom}&nbsp;: Evénement {$event.intitule}</h1>
 
 <p>
   [<a href="{$platal->ns}events">Revenir à la liste des événements</a>]
index bbfe549..5b5aec4 100644 (file)
@@ -20,7 +20,7 @@
 {*                                                                        *}
 {**************************************************************************}
 
-<h1>{$asso.nom}&nbsp;: Administration des annonces</h1>
+<h1>{$asso->nom}&nbsp;: Administration des announces</h1>
 
 <table class="bicol">
   <tr>
index ce18b19..e1317f1 100644 (file)
@@ -32,7 +32,7 @@ function visibilityChange(box)
 }
 {/literal}
 </script>
-<h1>{$asso.nom}&nbsp;: Édition d'une annonce</h1>
+<h1>{$asso->nom}&nbsp;: Édition d'une annonce</h1>
 
 {if $art.texte}
 <div>
index e1172d7..3521905 100644 (file)
@@ -1,6 +1,6 @@
 {**************************************************************************}
 {*                                                                        *}
-{*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+{*  Copyright (C) 2003-2009 Polytechnique.org                             *}
 {*  http://opensource.polytechnique.org/                                  *}
 {*                                                                        *}
 {*  This program is free software; you can redistribute it and/or modify  *}
index 1ce4ca9..62b9270 100644 (file)
 {*                                                                        *}
 {**************************************************************************}
 Nom,Prénom,Sexe,Promotion,Email,Commentaire
-{if $ann}
-{iterate from=$ann item=m}
+{if $users|@count}
+{foreach from=$users item=user}
 
-{$m.nom},{$m.prenom},{if $m.sexe}F{else}M{/if},{$m.promo},{$m.email},{$m.comm|replace:',':'\,'}
+{$user->firstName()},{$user->lastName()},{if $user->isFemale()}F{else}M{/if},{$user->promo()},{$user->forlifeEmail()},{$user->group_comm|replace:',':'\,'}
 
-{/iterate}
+{/foreach}
 {/if}
 {* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index 0e46aaa..9d0d235 100644 (file)
 {*                                                                        *}
 {**************************************************************************}
 
-<h1>{$asso.nom}&nbsp;: Annuaire du groupe </h1>
+<h1>{$asso->nom}&nbsp;: Annuaire du groupe </h1>
 
 <p class="descr">
-Le groupe {$asso.nom} compte {$nb_tot} membres&nbsp;:
+Le groupe {$asso->nom} compte {$nb_tot} membres&nbsp;:
 </p>
 
 <ul class="descr">
@@ -44,17 +44,17 @@ Le groupe {$asso.nom} compte {$nb_tot} membres&nbsp;:
   {/if}
   {/if}
   <li>
-    <a href="{$platal->ns}annuaire/csv/{$asso.diminutif}.csv">
+    <a href="{$platal->ns}annuaire/csv/{$asso->diminutif}.csv">
       {icon name=page_excel title="Fichier Excel"} 
       Obtenir au format Excel
     </a>
   </li>
   <li>
-    <a href="{$platal->ns}annuaire/vcard/photos/{$asso.diminutif}.vcf">
+    <a href="{$platal->ns}annuaire/vcard/photos/{$asso->diminutif}.vcf">
       {icon name=vcard title="Carte de visite"} 
       Ajouter les membres à ton carnet d'adresse
     </a>
-    (<a href="{$platal->ns}annuaire/vcard/{$asso.diminutif}.vcf">sans les photos</a>)
+    (<a href="{$platal->ns}annuaire/vcard/{$asso->diminutif}.vcf">sans les photos</a>)
   </li>
 </ul>
 
@@ -63,35 +63,38 @@ Le groupe {$asso.nom} compte {$nb_tot} membres&nbsp;:
 {else}
 
 <p class="center">
-[<a href="{$platal->ns}annuaire?order={$smarty.request.order}" {if !$only_admin}class="erreur"{/if}>tous les membres</a>]
-[<a href="{$platal->ns}annuaire?order={$smarty.request.order}&amp;admin=1" {if $only_admin}class="erreur"{/if}>animateurs</a>]<br/>
+[<a href="{$platal->ns}annuaire?order={$order}" {if !$only_admin}class="erreur"{/if}>tous les membres</a>]
+[<a href="{$platal->ns}annuaire?order={$order}&amp;admin=1" {if $only_admin}class="erreur"{/if}>animateurs</a>]<br/>
+{*
+ XXX: This code has been temporary dropped, waiting for a cleaner way to do that stuff
 {foreach from=$alphabet item=c}
 {if $c}
-[<a href="{$platal->ns}annuaire?{$group}={$c}&amp;order={$smarty.request.order}{if $only_admin}&amp;admin=1{/if}"{if $request_group eq $c} class="erreur"{/if}>{$c}</a>]
+[<a href="{$platal->ns}annuaire?order={$order}&amp;admin={$only_admin}"{if $request_group eq $c} class="erreur"{/if}>{$c}</a>]
 {/if}
 {/foreach}
+*}
 </p>
 
 <table summary="membres du groupe" class="bicol">
   <tr>
     <th>
-      <a href="{$platal->ns}annuaire?order=alpha{if $sort neq "alpha_inv"}_inv{/if}{if $request_group and $group eq 'initiale'}&amp;initiale={$request_group}{/if}{if $only_admin}&amp;admin=1{/if}">
-      {if $sort eq 'alpha'}
+      <a href="{$platal->ns}annuaire?order={if $order eq 'directory_name'}-{/if}directory_name&amp;admin={$only_admin}">
+      {if $order eq 'directory_name'}
         <img src="{$platal->baseurl}images/dn.png" alt="" title="Tri croissant" />
-      {elseif $sort eq 'alpha_inv'}
+      {elseif $order eq '-directory_name'}
         <img src="{$platal->baseurl}images/up.png" alt="" title="Tri décroissant" />
       {/if}
-      Prénom NOM 
+      Prénom NOM
       </a>
     </th>
     <th>
-      <a href="{$platal->ns}annuaire?order=promo{if $sort eq "promo"}_inv{/if}{if $request_group and $group eq 'promo'}&amp;promo={$request_group}{/if}">
-      {if $sort eq 'promo_inv'}
+      <a href="{$platal->ns}annuaire?order={if $order eq 'promo'}-{/if}promo&amp;admin={$only_admin}">
+      {if $order eq '-promo'}
         <img src="{$platal->baseurl}images/dn.png" alt="" title="Tri croissant" />
-      {elseif $sort eq 'promo'}
+      {elseif $order eq 'promo'}
         <img src="{$platal->baseurl}images/up.png" alt="" title="Tri décroissant" />
       {/if}
-        Promo
+      Promo
       </a>
     </th>
     <th colspan="2">Infos</th>
@@ -99,49 +102,51 @@ Le groupe {$asso.nom} compte {$nb_tot} membres&nbsp;:
     <th>Actions</th>
     {/if}
   </tr>
-  {iterate from=$ann item=m}
+  {foreach from=$users item=user}
   <tr>
     <td>
-      {if $m.admin}<strong>{/if}
-      {if $m.inscrit}
-      <a href="https://www.polytechnique.org/profile/{$m.email}" class="popup2">
-      {elseif $m.x}
-      <a href="https://www.polytechnique.org/marketing/public/{$m.uid}">
-      {/if}
-      {if $m.femme}&bull;{/if}{if $m.prenom || $m.nom}{$m.prenom} {$m.nom|strtoupper}{else}{$m.email}{/if}
-      {if $m.x}</a>{/if} 
-      {if $m.admin}</strong>{/if}
-      {if $m.inscrit && !$m.actif}
-      <a href="https://www.polytechnique.org/marketing/broken/{$m.email}">{icon name=error title="Recherche d'email"}</a>
-      {assign var=broken value=true}
-      {/if}</td>
-    <td>{if $m.admin}<strong>{/if}{$m.promo}{if $m.admin}</strong>{/if}</td>
-    {if $m.comm}
-    <td>{$m.comm}</td>
+      {profile user=$user promo=false}
+    <td>
+      {if $user->group_perms eq 'admin'}<strong>{/if}
+      {$user->promo()}
+      {if $user->group_perms eq 'admin'}</strong>{/if}
+    </td>
+    {if $user->group_comm}
+    <td>{$user->group_comm}</td>
     {/if}
-    <td class="right" {if !$m.comm}colspan="2"{/if}>
-      {if $m.inscrit}
-      <a href="https://www.polytechnique.org/vcard/{$m.email}.vcf">{icon name=vcard title="[vcard]"}</a>
-      <a href="mailto:{$m.email}@polytechnique.org">{icon name=email title="email"}</a>
-      {else}
-      <a href="mailto:{$m.email}">{icon name=email title="email"}</a>
+    <td class="right" {if !$user->group_comm}colspan="2"{/if}>
+      {if $user->hasProfile()}
+      <a href="https://www.polytechnique.org/vcard/{$user->login()}.vcf">{icon name=vcard title="[vcard]"}</a>
       {/if}
+      <a href="mailto:{$user->bestEmail()}">{icon name=email title="email"}</a>
     </td>
     {if $is_admin}
     <td class="center">
-      <a href="{$platal->ns}member/{if $m.x}{$m.email}{else}{$m.uid}{/if}">{icon name=user_edit title="Édition du profil"}</a>
-      <a href="{$platal->ns}member/del/{if $m.x}{$m.email}{else}{$m.uid}{/if}">{icon name=delete title="Supprimer de l'annuaire"}</a>
+      <a href="{$platal->ns}member/{$user->login()}">{icon name=user_edit title="Édition du profil"}</a>
+      <a href="{$platal->ns}member/del/{$user->login()}">{icon name=delete title="Supprimer de l'annuaire"}</a>
     </td>
     {/if}
   </tr>
-  {/iterate}
+  {/foreach}
 </table>
 
+{if $pages gt 1}
 <p class="descr" style="text-align: center">
-{foreach from=$links item=ofs key=txt}
-<a href="{$platal->ns}annuaire?offset={$ofs}&amp;initiale={$smarty.request.initiale}&amp;order={$sort}"{if $smarty.request.offset eq $ofs} class="erreur"{/if}>{$txt}</a>
-{/foreach}
+{section name="links" loop=$pages}
+{if $smarty.section.links.index eq $current}
+<span class="erreur">{$smarty.section.links.iteration}</span>
+{else}
+{if $smarty.section.links.first}
+<a href="{$platal->ns}annuaire?offset={$current-1}&amp;order={$order}&amp;admin={$only_admin}">précédente</a>
+{/if}
+<a href="{$platal->ns}annuaire?offset={$smarty.section.links.index}&amp;order={$order}&amp;admin={$only_admin}">{$smarty.section.links.iteration}</a>
+{if $smarty.section.links.last}
+<a href="{$platal->ns}annuaire?offset={$current+1}&amp;order={$order}&amp;admin={$only_admin}">suivante</a>
+{/if}
+{/if}
+{/section}
 </p>
+{/if}
 
 {if $broken}
 <p class="smaller">
index 35f3727..41b468f 100644 (file)
 {*                                                                        *}
 {**************************************************************************}
 
-<h1>{$asso.nom}&nbsp;: Accueil</h1>
+<h1>{$asso->nom}&nbsp;: Accueil</h1>
 
 <table cellpadding="0" cellspacing="0" class='tiny'>
-  {if $asso.site}
+  {if $asso->site}
   <tr>
     <td class="titre">
       Site Web&nbsp;:
     </td>
-    <td><a href="{$asso.site}">{$asso.site}</a></td>
+    <td><a href="{$asso->site}">{$asso->site}</a></td>
   </tr>
   {/if}
 
-  {if $asso.resp || $asso.mail}
+  {if $asso->resp || $asso->mail}
   <tr>
     <td class="titre">
       Contact&nbsp;:
     </td>
     <td>
-      {if $asso.mail}
-      {mailto address=$asso.mail text=$asso.resp|utf8_decode|default:"par email" encode=javascript}
+      {if $asso->mail}
+      {mailto address=$asso->mail text=$asso->resp|utf8_decode|default:"par email" encode=javascript}
       {else}
-      {$asso.resp}
+      {$asso->resp}
       {/if}
     </td>
   </tr>
   {/if}
 
-  {if $asso.forum}
+  {if $asso->forum}
   <tr>
     <td class="titre">
       Forum&nbsp;:
     </td>
     <td>
       <a href="{$platal->ns}forum">par le web</a>
-      ou <a href="news://ssl.polytechnique.org/{$asso.forum}">par nntp</a>
+      ou <a href="news://ssl.polytechnique.org/{$asso->forum}">par nntp</a>
     </td>
   </tr>
   {/if}
 
-  {if !$is_member && $is_logged && $asso.inscriptible && $xnet_type != 'promotions'}
+  {if !$is_member && $is_logged && $asso->inscriptible && $xnet_type != 'promotions'}
   <tr>
     <td class="titre">
       M'inscrire&nbsp;:
     </td>
     <td>
-      <a href="{if $asso.sub_url}{$asso.sub_url}{else}{$platal->ns}subscribe{/if}">m'inscrire</a>
+      <a href="{if $asso->sub_url}{$asso->sub_url}{else}{$platal->ns}subscribe{/if}">m'inscrire</a>
     </td>
   </tr>
   {elseif $is_member}
       Me désinscrire&nbsp;:
     </td>
     <td>
-      <a href="{if $asso.unsub_url}{$asso.unsub_url}{else}{$platal->ns}unsubscribe{/if}">me désinscrire</a>
+      <a href="{if $asso->unsub_url}{$asso->unsub_url}{else}{$platal->ns}unsubscribe{/if}">me désinscrire</a>
     </td>
   </tr>
   {/if}
 
-  {if $asso.ax}
+  {if $asso->ax}
   <tr>
     <td class="titre center" colspan="2">
       groupe agréé par l'AX
 <br />
 
 <div style="text-align: justify">
-  {if $asso.wiki_desc}
-  {$asso.descr|miniwiki:title|smarty:nodefaults}
+  {if $asso->wiki_desc}
+  {$asso->descr|miniwiki:title|smarty:nodefaults}
   {else}
-  {$asso.descr|smarty:nodefaults}
+  {$asso->descr|smarty:nodefaults}
   {/if}
 </div>
 
 <br />
 
-{if $article_index && $article_index->total()}
+{if t($article_index) && $article_index->total()}
 <table class="tinybicol">
   <tr>
     <th>
-      {if $smarty.session.core_rss_hash}
-      <a href='{$platal->ns}rss/{$smarty.session.hruid}/{$smarty.session.core_rss_hash}/rss.xml' style="display:block;float:right">
+      {if $smarty.session.token}
+      <a href='{$platal->ns}rss/{$smarty.session.hruid}/{$smarty.session.token}/rss.xml' style="display:block;float:right">
         {icon name=feed title='fil rss'}
       </a>
       {else}
index 2c5765f..112026e 100644 (file)
@@ -20,7 +20,7 @@
 {*                                                                        *}
 {**************************************************************************}
 
-<h1>{if $asso.nom}{$asso.nom}&nbsp;: {/if}Éditer l'accueil</h1>
+<h1>{if $asso->nom}{$asso->nom}&nbsp;: {/if}Éditer l'accueil</h1>
 
 <form method="post" action="{$platal->ns}edit" enctype="multipart/form-data">
   {xsrf_token_field}
@@ -31,7 +31,7 @@
         Nom&nbsp;:
       </td>
       <td>
-        <input type="text" size="40" value="{$asso.nom}" name="nom" />
+        <input type="text" size="40" value="{$asso->nom}" name="nom" />
       </td>
     </tr>
     <tr>
@@ -39,7 +39,7 @@
         Diminutif&nbsp;:
       </td>
       <td>
-        <input type="text" size="40" value="{$asso.diminutif}" name="diminutif" />
+        <input type="text" size="40" value="{$asso->diminutif}" name="diminutif" />
       </td>
     </tr>
     <tr>
@@ -47,7 +47,7 @@
         Domaine DNS&nbsp;:
       </td>
       <td>
-        <input type="text" size="40" value="{$asso.mail_domain}" name="mail_domain" />
+        <input type="text" size="40" value="{$asso->mail_domain}" name="mail_domain" />
       </td>
     </tr>
     <tr>
       </td>
       <td>
         <select name="cat">
-          <option value="groupesx" {if $asso.cat eq GroupesX}selected="selected"{/if}>Groupes X</option>
-          <option value="binets" {if $asso.cat eq Binets}selected="selected"{/if}>Binets</option>
-          <option value="promotions" {if $asso.cat eq Promotions}selected="selected"{/if}>Promotions</option>
-          <option value="institutions" {if $asso.cat eq Institutions}selected="selected"{/if}>Institutions</option>
+          <option value="groupesx" {if $asso->cat eq GroupesX}selected="selected"{/if}>Groupes X</option>
+          <option value="binets" {if $asso->cat eq Binets}selected="selected"{/if}>Binets</option>
+          <option value="promotions" {if $asso->cat eq Promotions}selected="selected"{/if}>Promotions</option>
+          <option value="institutions" {if $asso->cat eq Institutions}selected="selected"{/if}>Institutions</option>
         </select>
       </td>
     </tr>
@@ -71,7 +71,7 @@
         <select name="dom">
           <option value=""></option>
           {iterate from=$dom item=d}
-          <option value="{$d.id}" {if $d.id eq $asso.dom}selected="selected"{/if}>{$d.nom} [{$d.cat}]</option>
+          <option value="{$d.id}" {if $d.id eq $asso->dom}selected="selected"{/if}>{$d.nom} [{$d.cat}]</option>
           {/iterate}
         </select>
       </td>
         Site web&nbsp;:
       </td>
       <td>
-        <input type="text" size="40" value="{$asso.site|default:"http://"}" name="site" />
+        <input type="text" size="40" value="{$asso->site|default:"http://"}" name="site" />
       </td>
     </tr>
 
         Contact&nbsp;:
       </td>
       <td>
-        <input type="text" size="40" name="resp" value="{$asso.resp}" />
+        <input type="text" size="40" name="resp" value="{$asso->resp}" />
       </td>
     </tr>
 
         Adresse email&nbsp;:
       </td>
       <td>
-        <input type="text" size="40" name="mail" value="{$asso.mail}" />
+        <input type="text" size="40" name="mail" value="{$asso->mail}" />
       </td>
     </tr>
 
         Forum&nbsp;:
       </td>
       <td>
-        <input type="text" size="40" name="forum" value="{$asso.forum}" />
+        <input type="text" size="40" name="forum" value="{$asso->forum}" />
       </td>
     </tr>
 
       </td>
       <td>
         <input type="radio" value="1" id="inscr_yes"
-          {if $asso.inscriptible eq 1}checked="checked"{/if}
+          {if $asso->inscriptible eq 1}checked="checked"{/if}
           name="inscriptible" />
         <label for="inscr_yes">oui</label>
         <input type="radio" value="0" id="inscr_no"
-          {if $asso.inscriptible neq 1}checked="checked"{/if}
+          {if $asso->inscriptible neq 1}checked="checked"{/if}
           name="inscriptible" />
         <label for="inscr_no">non</label>
       </td>
         <em>laisser vide par défaut</em>
       </td>
       <td>
-        <input type="text" size="40" name="sub_url" value="{$asso.sub_url}" />
+        <input type="text" size="40" name="sub_url" value="{$asso->sub_url}" />
       </td>
     </tr>
 
         <em>laisser vide par défaut</em>
       </td>
       <td>
-        <input type="text" size="40" name="unsub_url" value="{$asso.unsub_url}" />
+        <input type="text" size="40" name="unsub_url" value="{$asso->unsub_url}" />
       </td>
     </tr>
 
       <td class="titre center" colspan="2">
         Diffusion de la liste des membres&nbsp;:
         <select name="pub">
-          <option value="public" {if $asso.pub eq 'public'}selected="selected"{/if}>Publique</option>
-          <option value="membre" {if $asso.pub eq 'membre'}selected="selected"{/if}>Aux membres du groupe</option>
-          <option value="private" {if $asso.pub eq 'private'}selected="selected"{/if}>Aux animateurs du groupe</option>
+          <option value="public" {if $asso->pub eq 'public'}selected="selected"{/if}>Publique</option>
+          <option value="membre" {if $asso->pub eq 'membre'}selected="selected"{/if}>Aux membres du groupe</option>
+          <option value="private" {if $asso->pub eq 'private'}selected="selected"{/if}>Aux animateurs du groupe</option>
         </select>
       </td>
     </tr>
     <tr>
       <td class="titre center" colspan="2">
-        <label><input type="checkbox" value="1" name="notif_unsub" {if $asso.notif_unsub}checked="checked"{/if} />
+        <label><input type="checkbox" value="1" name="notif_unsub" {if $asso->notif_unsub}checked="checked"{/if} />
         prévenir les animateurs lors de la désinscription d'un membre</label>
       </td>
     </tr>
       {icon name=information title="Syntaxe wiki"} Voir la syntaxe wiki autorisée pour la description.
     </a>
     <textarea name="descr" cols="70" rows="15" id="descr"
-              {if !$asso.wiki_desc && $asso.descr}class="error"{/if}>{$asso.descr}</textarea>
+              {if !$asso->wiki_desc && $asso->descr}class="error"{/if}>{$asso->descr}</textarea>
     <input type="submit" name="preview" value="Aperçu de la description"
            onclick="previewWiki('descr', 'preview_descr', true, 'preview_descr'); return false;" /><br />
     <input type="submit" name="submit" value="Enregistrer" />
index 554cbdc..3975155 100644 (file)
     <td {if $art.photo}colspan="2"{/if}>
       <div style="float: right">
       <small>
-        Annonce proposée par
-        <a class="popup2" href="https://www.polytechnique.org/profile/{$art.hruid}">
-          {$art.prenom} {$art.nom} (X{$art.promo})
-        </a>
+        Annonce proposée par {profile user=$art.user_id sex=false promo=true groupperms=false}
       </small>
       </div>
       <small>
index b56abee..80604c7 100644 (file)
@@ -20,7 +20,7 @@
 {*                                                                        *}
 {**************************************************************************}
 
-<h1>{$asso.nom}&nbsp;: Forum</h1>
+<h1>{$asso->nom}&nbsp;: Forum</h1>
 
 {$banana|smarty:nodefaults}
 
index 26aa4a3..d2c8a29 100644 (file)
@@ -20,7 +20,7 @@
 {*                                                                        *}
 {**************************************************************************}
 
-<h1>Demande d'inscription à {$asso.nom}</h1>
+<h1>Demande d'inscription à {$asso->nom}</h1>
 
 {if $user && $is_admin && $show_form}
 
 <p class="descr">
 <strong>Ta demande d'inscription a bien été envoyée !</strong> Tu seras averti{if $user->isFemale()}e{/if} par email de la suite qui lui sera donnée.
 <p>
-<p class="descr">[<a href="{$platal->ns}">Retour à la page d'accueil de {$asso.nom}</a>]</p>
+<p class="descr">[<a href="{$platal->ns}">Retour à la page d'accueil de {$asso->nom}</a>]</p>
 
 {else}
 
 <p class="descr">
-Pour t'inscrire à {$asso.nom}, il te faut en demander l'autorisation aux animateurs du groupe via le
+Pour t'inscrire à {$asso->nom}, il te faut en demander l'autorisation aux animateurs du groupe via le
 formulaire ci-dessous. Vérifie et corrige au besoin les différents champs, puis clique sur
 [&nbsp;M'inscrire&nbsp;!&nbsp;].
 </p>
 <form action="{$platal->ns}subscribe" method="post">
   {xsrf_token_field}
   <p class="descr">
-  <strong>OUI, je souhaite être inscrit au groupe {$asso.nom}.</strong>
+  <strong>OUI, je souhaite être inscrit au groupe {$asso->nom}.</strong>
   </p>
   <p class="descr">
   Indique ci-après <strong>tes motivations</strong> qui seront communiquées aux animateurs du groupe&nbsp;:
   </p> <textarea cols=80 rows=12 name="message">
 Chers Camarades,
 
-Je souhaite m'inscrire à {$asso.nom}.
+Je souhaite m'inscrire à {$asso->nom}.
 
 Merci d'avance d'avoir la gentillesse de valider mon inscription.
 
index 1e01018..e66c6ff 100644 (file)
@@ -21,7 +21,7 @@
 {**************************************************************************}
 
 
-<h1>{$asso.nom}&nbsp;: Envoyer un email</h1>
+<h1>{$asso->nom}&nbsp;: Envoyer un email</h1>
 
 <p class="descr">
 Ton message peut être personnalisé&nbsp;: si tu rentres les mots &lt;cher&gt;, &lt;prenom&gt;,
@@ -131,11 +131,11 @@ masculin ou féminin, par son prénom, ou son nom.
 {else}
 &lt;cher&gt; &lt;prenom&gt;,
 
-Nous avons le plaisir de t'adresser la lettre mensuelle du groupe {$asso.nom}.
+Nous avons le plaisir de t'adresser la lettre mensuelle du groupe {$asso->nom}.
 
 (insérer le texte...)
 
-Le bureau du groupe {$asso.nom}.
+Le bureau du groupe {$asso->nom}.
 {/if}</textarea>
       </td>
     </tr>
index b01018d..b0e339d 100644 (file)
@@ -52,7 +52,7 @@ function searchX()
 {/literal}
 //]]></script>
 
-<h1>{$asso.nom}&nbsp;: Ajout d'un membre</h1>
+<h1>{$asso->nom}&nbsp;: Ajout d'un membre</h1>
 
 <form method="post" action="{$platal->ns}member/new/">
   {xsrf_token_field}
index 7bbd86e..9a46b52 100644 (file)
@@ -32,7 +32,7 @@
 
 {else}
  
-<h1>{$asso.nom}&nbsp;: gestion des membres</h1>
+<h1>{$asso->nom}&nbsp;: gestion des membres</h1>
 
 <h2>
   Suppression du membre&nbsp;: {$user.prenom} {$user.nom}
@@ -44,7 +44,7 @@
   <div class="center">
     <p class="descr">
     {if $self}
-    Êtes-vous sûr de vouloir vous désinscrire du groupe {$asso.nom} et de toutes
+    Êtes-vous sûr de vouloir vous désinscrire du groupe {$asso->nom} et de toutes
     les listes de diffusion associées ?
     {else}
     Êtes-vous sûr de vouloir supprimer {$user.prenom} {$user.nom} du groupe,
index e1769dd..044f821 100644 (file)
 {/literal}
 </script>
 
-<h1>{$asso.nom}&nbsp;: gestion des membres</h1>
+<h1>{$asso->nom}&nbsp;: gestion des membres</h1>
 
 <p>
 [<a href='{$platal->ns}annuaire'>Retour à l'annuaire</a>]
 </p>
 
 <h2>
-  Édition du profil de {if "`$user.prenom` `$user.nom`"|trim}{$user.prenom} {$user.nom}{else}{$user.email}{/if}
-  {if $user.origine eq 'X'}
-  &nbsp;(X{$user.promo})
-  <a href="https://www.polytechnique.org/profile/{$user.alias}">{icon name=user_suit title="fiche"}</a>
-  {/if}
-  <a href="{$platal->ns}member/del/{$user.email}">{icon name=delete title="Suppression du compte"}</a>
-  <a href="mailto:{$user.email}">{icon name=email title="mail"}</a>
+  Édition du profil de {profile user=$user groupperms=false sex=false promo=true}
+  <a href="mailto:{$user->bestEmail()}">{icon name=email title="mail"}</a>
 </h2>
 
 <form method="post" action="{$platal->ns}member/{$platal->argv[1]}">
       </td>
       <td>
         <select name="is_admin">
-          <option value="0" {if !$user.perms}selected="selected"{/if}>Membre</option>
-          <option value="1" {if $user.perms}selected="selected"{/if}>Animateur</option>
+          <option value="0" {if $user->group_perms eq 'membre'}</option>}selected="selected"{/if}>Membre</option>
+          <option value="1" {if $user->group_perms eq 'admin'}</option>}selected="selected"{/if}>Animateur</option>
         </select>
       </td>
     </tr>
-    {if $user.origine neq X}
     <tr class="impair">
       <td class="titre">
         Type d'utilisateur&nbsp;:
       </td>
       <td>
         <select name="origine" onchange="showInformations(this); return true">
-          <option value="ext" {if $user.origine eq "ext"}selected="selected"{/if}>Personne physique</option>
-          <option value="groupe" {if $user.origine eq "groupe"}selected="selected"{/if}>Personne morale</option>
+          <option value="ext" {if $user->type neq 'virtual'}selected="selected"{/if}>Personne physique</option>
+          <option value="groupe" {if $user->type eq "virtual"}selected="selected"{/if}>Personne morale</option>
         </select>
       </td>
     </tr>
-    <tr id="prenom" class="impair" {if $user.origine eq "groupe"}style="display: none"{/if}>
+      <tr id="prenom" class="impair" {if $user->type eq "virtual"}style="display: none"{/if}>
       <td class="titre">
         Prénom&nbsp;:
       </td>
       <td>
-        <input type="text" value="{$user.prenom}" name="prenom" size="40" />
+        <input type="text" value="{$user->displayName()}" name="prenom" size="40" />
       </td>
     </tr>
     <tr class="impair">
         Nom&nbsp;:
       </td>
       <td>
-        <input type="text" value="{$user.nom}" name="nom" size="40" />
+        <input type="text" value="{$user->fullName()}" name="nom" size="40" />
       </td>
     </tr>
-    <tr id="sexe" class="impair" {if $user.origine eq "groupe"}style="display: none"{/if}>
+    <tr id="sexe" class="impair" {if $user->type eq "virtual"}style="display: none"{/if}>
       <td class="titre">
         Sexe&nbsp;:
       </td>
       <td>
         <select name="sexe">
-          <option value="0"{if $user.sexe eq 0} selected="selected"{/if}>Homme</option>
-          <option value="1"{if $user.sexe eq 1} selected="selected"{/if}>Femme</option>
+          <option value="0"{if !$user->isFemale()} selected="selected"{/if}>Homme</option>
+          <option value="1"{if $user->isFemale()} selected="selected"{/if}>Femme</option>
         </select>
       </td>
     </tr>
         Email&nbsp;:
       </td>
       <td>
-        <input type="text" value="{$user.email}" name="email" size="40" />
+        <input type="text" value="{$user->forlifeEmail()}" name="email" size="40" />
       </td>
     </tr>
-    {/if}
     <tr class="impair">
       <td class="titre">
         Commentaire&nbsp;:
       </td>
       <td>
-        <input type="text" name="comm" value="{$user.comm}" size="40" maxlength="255" /><br />
+        <input type="text" name="comm" value="{$user->group_comm}" size="40" maxlength="255" /><br />
         <small>Poste, origine, ... (accessible à toutes les personnes autorisées à consulter l'annuaire)</small>
       </td>
     </tr>
-    {if $user.origine neq X}
-    <tr id="make_X" {if $user.origine eq "groupe"}style="display: none"{/if}>
+    {if $user->type eq 'ext'}
+    <tr id="make_X">
       <td colspan="2">
         <span id="make_X_cb">
           <input type="checkbox" name="is_x" id="is_x" onclick="showXInput(this);" onchange="showXInput(this);" />
       <th>Alias</th>
     </tr>
 
-    {foreach from=$alias item=a}
+    {foreach from=$alias key=address item=sub}
     <tr>
       <td align='right'>
-        <input type='hidden' name='ml3[{$a.alias}]' value='{$a.sub}' />
-        <input type='checkbox' name='ml4[{$a.alias}]' {if $a.sub}checked="checked"{/if} />
+        <input type='hidden' name='ml3[{$address}]' value='{$sub}' />
+        <input type='checkbox' name='ml4[{$address}]' {if $sub}checked="checked"{/if} />
       </td>
       <td>
-        <a href='{$platal->ns}alias/admin/{$a.alias}'>{$a.alias}</a>
+        <a href='{$platal->ns}alias/admin/{$address}'>{$address}</a>
       </td>
     </tr>
     {foreachelse}
index 572411f..b19118a 100644 (file)
 {*                                                                        *}
 {**************************************************************************}
 
-  {if !$choix}
+  {if t($too_many)}
   Les critères de recherche ne sont pas assez précis.
-  {elseif !$choix->total()}
+  {elseif $users|@count eq 0}
   Aucun camarade non-inscrit ne correspond aux informations fournies.
-  {elseif $choix->total()}
+  {else}
   Camarades correspondants&nbsp;:
   <select name="userid" onchange="document.getElementById('marketing').style.display = (this.value == 0 ? 'none' : '')">
     <option value="0"></option>
-    {iterate item=x from=$choix}
-    <option value="{$x.user_id}" {if $choix->total() == 1}selected="selected"{/if}>{$x.prenom} {$x.nom} (X{$x.promo})</option>
-    {/iterate}
+    {foreach item=user from=$users}
+    <option value="{$user->id()}" {if $users|@count == 1}selected="selected"{/if}>{profile user=$user link=false promo=true}</option>
+    {/foreach}
   </select>
-  <span id="marketing" {if $choix->total() != 1}style="display: none"{/if}><br />
+  <span id="marketing" {if $users|@count != 1}style="display: none"{/if}><br />
     <label><input type="checkbox" name="market" checked="checked"
         onchange="document.getElementById('from').style.display = (this.checked ? '' : 'none')"/>
     Lui envoyer un marketing</label>
index 51348c9..2dcf9ff 100644 (file)
@@ -20,7 +20,7 @@
 {*                                                                        *}
 {**************************************************************************}
 
-<h1>{$asso.nom}&nbsp;: Validation des inscriptions</h1>
+<h1>{$asso->nom}&nbsp;: Validation des inscriptions</h1>
 
 <script type="text/javascript">//<![CDATA[
 {literal}
@@ -50,7 +50,7 @@
     {iterate from=$valid item=user}
     <tr>
       <td><input type="checkbox" name="subs[{$user.hruid}]" value="1" class="select_sub" /></td>
-      <td><a href="profile/{$user.hruid}" class="popup2">{$user.prenom} {$user.nom} (X{$user.promo})</a></td>
+      <td>{profile user=$user.uid promo=true}</td>
       <td>{$user.date|date_format}</td>
       <td><a href="{$platal->ns}subscribe/{$user.hruid}">{icon name=magnifier title="Détails"}</a></td>
     </tr>
index 8636f73..3bc6b91 100644 (file)
 {config_load file="mails.conf" section="xnet_unsubscription"}
 {if $mail_part eq 'head'}
 {from full=#from#}
-{subject text="[`$group`] Désinscription de `$prenom` `$nom`"}
+{subject text="[`$group`] Désinscription de `$prenom->fullName()`"}
 {elseif $mail_part eq 'wiki'}
 Chers animateurs du groupe {$group},
 
 {if $selfdone}
-{$prenom} {$nom} ({$mail}) vient de se désinscrire du groupe.
+{$user->fullName()} ({$user->forlifeEmail()}) vient de se désinscrire du groupe.
 {else}
-{$prenom} {$nom} ({$mail}) vient d'être désinscrit du groupe par {$smarty.session.prenom} {$smarty.session.nom}.
+{$user->fullName()} ({$user->forlifeEmail()}) vient d'être désinscrit du groupe par {$smarty.session.user->fullName()}.
 {/if}
 
 Cordialement,\\
index 4195959..eb530fe 100644 (file)
 <h1>Membres de {$platal->argv[1]}</h1>
       
 <table class='tinybicol'>
-  {if $mem->total()}
-  {iterate from=$mem item=m}
+  {if $mem|@count}
+  {foreach from=$mem item=m}
   <tr>
     <td>
-      {if $m.nom}
+      {if $m.user}
       {if $m.admin}<strong>{/if}
-      {if $m.alias}<a href="https://www.polytechnique.org/profile/{$m.alias}" class="popup2">{/if}
-      {$m.prenom} {$m.nom}
-      {if $m.alias}</a>{/if}
+      <a href="https://www.polytechnique.org/profile/{$m.user->login()}" class="popup2">{$m.user->fullName()}</a>
       {if $m.admin}</strong>{/if}
       {else}
-      {$m.redirect}
+      {$m.email}
       {/if}
     </td>
     <td class="right">
+      {if $m.user}
       {if $m.admin}<strong>{/if}
-      {$m.promo}
+      {$m.user->promo()}
       {if $m.admin}</strong>{/if}
+      {/if}
     </td>
     <td class="center">
-      <a href='{$platal->ns}alias/admin/{$platal->argv[1]}?del_member={$m.redirect|urlencode}&amp;token={xsrf_token}'>
+      <a href='{$platal->ns}alias/admin/{$platal->argv[1]}?del_member={$m.email|urlencode}&amp;token={xsrf_token}'>
       {icon name=delete title='retirer membre'}
       </a>
     </td>
   </tr>
-  {/iterate}
+  {/foreach}
   {else}
   <tr>
     <td colspan="3">
index 4c3d79d..29719e5 100644 (file)
@@ -54,7 +54,7 @@ de modération), il est recommandé de créer <a href="{$platal->ns}lists/create
     <tr>
       <td><strong>Adresse&nbsp;souhaitée&nbsp;:</strong></td>
       <td>
-        <input type='text' name='liste' value='{$smarty.post.liste}' />@{$asso.mail_domain}
+        <input type='text' name='liste' value='{$smarty.post.liste}' />@{$asso->mail_domain}
       </td>
     </tr>
   </table>
index 7fc9f43..db7cb14 100644 (file)
@@ -20,7 +20,7 @@
 {*                                                                        *}
 {**************************************************************************}
 
-<h1>{$asso.nom}&nbsp;: Création d'une liste de diffusion</h1>
+<h1>{$asso->nom}&nbsp;: Création d'une liste de diffusion</h1>
 
 <p class="descr">
 <strong>Note&nbsp;:</strong> les listes de diffusion sont un outil particulièrement adapté pour des
@@ -42,7 +42,7 @@ Si tu as besoin de cette fonctionnalité, il faut alors <strong>impérativement<
     <tr>
       <td><strong>Adresse&nbsp;souhaitée&nbsp;:</strong></td>
       <td colspan='3'>
-        <input type='text' name='liste' value='{$smarty.post.liste}' />@{$asso.mail_domain}
+        <input type='text' name='liste' value='{$smarty.post.liste}' />@{$asso->mail_domain}
       </td>
     </tr>
     <tr>
index 3a2dcda..de9c8e8 100644 (file)
@@ -34,9 +34,9 @@
 
 {else}
 
-<h1>{$asso.nom}&nbsp;: Listes de diffusion</h1>
+<h1>{$asso->nom}&nbsp;: Listes de diffusion</h1>
 
-<h2>Listes de diffusion du groupe {$asso.nom}&nbsp;:</h2>
+<h2>Listes de diffusion du groupe {$asso->nom}&nbsp;:</h2>
 
 <p class="descr">
 Une liste dont <strong>la diffusion</strong> est modérée est une liste dont les emails sont validés
@@ -62,7 +62,7 @@ croix verte te permet de t'inscrire, après accord des responsables si l'inscrip
   {foreach from=$listes item=l}
   <tr>
     <td class='center'>
-      <a href="mailto:{$l.list}@{$asso.mail_domain}">{icon name=email title="email"}</a>
+      <a href="mailto:{$l.list}@{$asso->mail_domain}">{icon name=email title="email"}</a>
     </td>
     <td>
       {if $l.own}
@@ -106,7 +106,7 @@ croix verte te permet de t'inscrire, après accord des responsables si l'inscrip
 t'empêcherait de t'y réabonner par la suite sans l'aide d'un administrateur.
 </p>
         
-<h2>Voici les alias existants pour le groupe {$asso.nom}&nbsp;:</h2>
+<h2>Voici les alias existants pour le groupe {$asso->nom}&nbsp;:</h2>
 
 <table cellspacing="0" cellpadding="0" class='large'>
   <tr>
index eb720dd..a1cf661 100644 (file)
@@ -1,6 +1,6 @@
 {**************************************************************************}
 {*                                                                        *}
-{*  Copyright (C) 2003-2009 Polytechnique.org                             *}
+{*  Copyright (C) 2003-2008 Polytechnique.org                             *}
 {*  http://opensource.polytechnique.org/                                  *}
 {*                                                                        *}
 {*  This program is free software; you can redistribute it and/or modify  *}
@@ -21,7 +21,7 @@
 {**************************************************************************}
 
 {include file='lists/header_listes.tpl' on='sync'}
-<h1>Non abonnés à la liste {$platal->argv[1]}@{$asso.mail_domain}</h1>
+<h1>Non abonnés à la liste {$platal->argv[1]}@{$asso->mail_domain}</h1>
 
 <form action="{$platal->ns}lists/sync/{$platal->argv[1]}" method="post">
   {xsrf_token_field}
@@ -34,9 +34,9 @@
     </tr>
     {foreach from=$not_in_list item=u}
     <tr>
-      <td class='checkboxToggle'>{$u.nom|strtoupper} {$u.prenom}</td>
-      <td class='checkboxToggle'>{$u.promo}</td>
-      <td class='checkboxToggle'><input type="checkbox" class="moderate_email" name="add[{$u.email}]" id="add{$u.email}"/></td>
+      <td class='checkboxToggle'>{profile user=$u promo=false}</td>
+      <td class='checkboxToggle'>{$u->promo()}</td>
+      <td class='checkboxToggle'><input type="checkbox" class="moderate_email" name="add[{$u->forlifeEmail()}]" id="add{$u->forlifeEmail()}"/></td>
     </tr>
     {/foreach}
     <tr>
diff --git a/upgrade/account/00_account.sql b/upgrade/account/00_account.sql
new file mode 100644 (file)
index 0000000..e8523d3
--- /dev/null
@@ -0,0 +1,54 @@
+CREATE TABLE accounts (
+  # Account identifier and type
+  uid int(6) not null auto_increment,
+  hruid varchar(255) not NULL,
+
+  # Account type and state
+  type varchar(16) default null,
+  is_admin bool default false,
+  state enum('pending', 'active', 'disabled') not null default 'pending',
+
+  # Access
+  password char(40) default null,
+  token varchar(32) default null,
+  weak_password varchar(256) default null,
+  registration_date datetime not null,
+
+  # Administrative tools
+  flags set('watch') not null default '',
+  comment varchar(255) default null,
+
+  # User settings
+  email varchar(255) default null,
+  full_name varchar(255) default null,
+  display_name varchar(255) default null,
+  sex enum('female', 'male') not null default 'male',
+  email_format enum('text', 'html') not null default 'html',
+  skin varchar(32) default null,
+  last_version varchar(16) not null,
+
+  primary key uid (uid),
+  unique key hruid (hruid),
+  key full_name (full_name),
+  key state (state),
+  key type (type)
+);
+
+CREATE TABLE account_types (
+  type varchar(16) not null,
+  perms set('mail', 'groups', 'forums', 'list', 'search', 'portal') default '',
+
+  primary key type (type)
+);
+
+CREATE TABLE account_profiles (
+  uid int(6) not null,
+  pid int(6) not null,
+  perms set('owner') not null default '',
+
+  primary key id (uid, pid),
+  key uid (uid),
+  key pid (pid)
+);
+
+# vim:set syntax=mysql:
diff --git a/upgrade/account/01_profiles.sql b/upgrade/account/01_profiles.sql
new file mode 100644 (file)
index 0000000..02fa34b
--- /dev/null
@@ -0,0 +1,42 @@
+create table profiles (
+  # Profile identifiers
+  pid int(6) not null auto_increment,
+  hrpid varchar(255) not null,
+
+  # Who is this?
+  xorg_id int(8) not null,
+  ax_id varchar(8) default null,
+
+  # Some singletons
+  # birthdate and birthdate given by reference directory (library, school...)
+  birthdate date default null,
+  birthdate_ref date default null,
+  next_birthday 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,
+  cv text default null,
+  freetext mediumtext default null,
+  freetext_pub enum('private', 'public') not null default 'private',
+  medals_pub enum('private', 'public') not null default 'private',
+  alias_pub enum('private', 'public') not null default 'private',
+
+  nationality1 char(2) default null,
+  nationality2 char(2) default null,
+  nationality3 char(2) default null,
+
+  # Last modification date (for notifications)
+  last_change date not null,
+
+  primary key pid (pid),
+  unique key hrpid (hrpid),
+  unique key xorg_id (xorg_id),
+  key ax_id (ax_id),
+  key nationality1 (nationality1),
+  key nationality2 (nationality2),
+  key nationality3 (nationality3)
+);
+
+# vim:set syntax=mysql:
diff --git a/upgrade/account/02_forums.sql b/upgrade/account/02_forums.sql
new file mode 100644 (file)
index 0000000..26f18f4
--- /dev/null
@@ -0,0 +1,47 @@
+# Move forums tables to x4dat
+#RENAME  forums.list
+#    TO  x4dat.forums;
+#RENAME  forums.abos
+#    TO  x4dat.forum_subs;
+#RENAME  forums.innd
+#    TO  x4dat.forum_innd;
+#RENAME  forums.porfils
+#    TO  x4dat.forum_profiles;
+#DROP DATABASE forums;
+
+## Dev version of previous line
+# (non destructive)
+CREATE TABLE  x4dat.forums
+        LIKE  forums.list;
+INSERT INTO  x4dat.forums
+     SELECT  *
+       FROM  forums.list;
+
+CREATE TABLE  x4dat.forum_subs
+        LIKE  forums.abos;
+INSERT INTO  x4dat.forum_subs
+     SELECT  *
+       FROM  forums.abos;
+
+CREATE TABLE  x4dat.forum_innd
+        LIKE  forums.innd;
+INSERT INTO  x4dat.forum_innd
+     SELECT  *
+       FROM  forums.innd;
+
+CREATE TABLE  x4dat.forum_profiles
+        LIKE  forums.profils;
+INSERT INTO  x4dat.forum_profiles
+     SELECT  *
+       FROM  forums.profils;
+
+
+# Conform to naming convention.
+  ALTER TABLE  forums
+CHANGE COLUMN  nom name VARCHAR(64) NOT NULL;
+
+  ALTER TABLE  forum_profiles
+CHANGE COLUMN  nom name VARCHAR(64) NOT NULL,
+   ADD COLUMN  last_seen TIMESTAMP NOT NULL DEFAULT '0000-00-00';
+
+# vim:set syntax=mysql:
diff --git a/upgrade/account/03_carnet.sql b/upgrade/account/03_carnet.sql
new file mode 100644 (file)
index 0000000..8e635fa
--- /dev/null
@@ -0,0 +1,11 @@
+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),
+  key flags (flags)
+);
+
+# vim:set syntax=mysql:
diff --git a/upgrade/account/04_carva.sql b/upgrade/account/04_carva.sql
new file mode 100644 (file)
index 0000000..b583fc0
--- /dev/null
@@ -0,0 +1,8 @@
+create table carvas (
+  uid int(6) not null,
+  url varchar(255) not null,
+
+  primary key uid (uid)
+);
+
+# vim:set syntax=mysql:
diff --git a/upgrade/account/05_emails.sql b/upgrade/account/05_emails.sql
new file mode 100644 (file)
index 0000000..c8df1a1
--- /dev/null
@@ -0,0 +1,8 @@
+create table email_options (
+  uid int(6) not null,
+  storage set('imap', 'googleapps') not null default '',
+
+  primary key uid (uid)
+);
+
+# vim:set syntax=mysql:
diff --git a/upgrade/account/99_insertion.sql b/upgrade/account/99_insertion.sql
new file mode 100644 (file)
index 0000000..f0cb142
--- /dev/null
@@ -0,0 +1,91 @@
+# Create a type 'X' with all permissions
+insert into account_types
+     values ('x', 'mail,groups,forums,list,search,portal'),
+            ('xnet', 'groups');
+
+
+# Insert all existing accounts
+insert into accounts
+     select u.user_id AS uid, hruid AS hruid, 'x' AS type,
+            perms = 'admin' AS is_admin,
+            IF(perms = 'admin' or perms = 'user', 'active', perms) AS state,
+            IF(LENGTH(password) = 40, password, NULL) AS password,
+            IF(LENGTH(q.core_rss_hash) > 0, q.core_rss_hash, NULL) AS token,
+            IF(LENGTH(smtppass) = 0, NULL, smtppass) AS weak_password,
+            date_ins AS registration_date,
+            IF(FIND_IN_SET('watch', flags), 'watch', '') AS flags,
+            IF(LENGTH(comment) > 0, comment, NULL) AS comment,
+            NULL as email,
+            CONCAT(prenom, ' ', IF (nom_usage != '' and nom_usage IS NOT NULL, nom_usage, nom)) AS full_name,
+            prenom AS display_name,
+            IF(FIND_IN_SET('femme', flags), 'female', 'male') AS sex,
+            IF(q.core_mail_fmt = 'html', 'html', 'text') AS email_format,
+            q.skin AS skin,
+            q.last_version AS last_version
+       from auth_user_md5 as u
+  left join auth_user_quick as q on (q.user_id = u.user_id)
+      where hruid is not null;
+
+# Insert carnet-relative data
+insert into watch
+     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
+     select user_id, redirecturl
+       from auth_user_quick
+      where LENGTH(redirecturl) > 0;
+
+# Insert all existing profiles
+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,
+            u.naissance AS next_birthday,
+            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,
+            IF(LENGTH(q.profile_freetext) > 0, q.profile_freetext, NULL) AS freetext,
+            IF(q.profile_freetext_pub = 'public', 'public', 'private') AS freetext_pub,
+            IF(q.profile_medals_pub = 'public', 'public', 'private') AS medals_pub,
+            IF(q.emails_alias_pub = 'public', 'public', 'private') AS alias_pub,
+            u.nationalite AS nationality1, u.nationalite2 AS nationality2,
+            u.nationalite3 AS nationality3, u.date AS last_change
+       from auth_user_md5 AS u
+  left join auth_user_quick AS q ON (u.user_id = q.user_id)
+      where u.hruid is not null;
+
+# Add associations account <-> profile
+insert into account_profiles
+     select user_id AS uid, user_id AS pid, 'owner' AS perms
+       from auth_user_md5
+      where hruid is not null;
+
+# Update banana last_seen timetamp
+    update  forum_profiles as fp
+inner join  auth_user_quick as q ON (q.user_id = fp.uid)
+       set  fp.uid = fp.uid, fp.tree_unread = fp.tree_unread, fp.tree_read = fp.tree_read,
+            fp.last_seen = q.banana_last;
+
+insert ignore into  forum_profiles (uid, last_seen)
+            select  user_id as uid, banana_last as last_seen
+              from  auth_user_quick
+             where  banana_last >= DATE_SUB(NOW(), INTERVAL 6 MONTH);
+
+# Mail storage has been moved out of account settings
+insert into email_options
+     select user_id as uid, mail_storage as storage
+       from auth_user_md5;
+
+# vim:set syntax=mysql:
diff --git a/upgrade/account/README b/upgrade/account/README
new file mode 100644 (file)
index 0000000..8ab4c37
--- /dev/null
@@ -0,0 +1,24 @@
+DataBase upgrade:
+-----------------
+
+* Activate forums database drop
+
+
+Configuration changes:
+----------------------
+
+[Banana]
+* table_prefix deprecated
+
+
+Affected services:
+------------------
+
+News:
+* authentication must use account + account_types with weakpass.
+* forums base dropped and moved to forum_ namespace.
+
+
+Email:
+* auth_user_md5.smtppass -> accounts.weak_password. This password is NULL when empty, but a check must be added for empty passwords.
+* auth_user_md5.mail_storage -> email_options.storage
diff --git a/upgrade/account/birthday.php b/upgrade/account/birthday.php
new file mode 120000 (symlink)
index 0000000..cae0f40
--- /dev/null
@@ -0,0 +1 @@
+../../bin/cron/notifs.birthday.php
\ No newline at end of file
diff --git a/upgrade/account/connect.db.inc.php b/upgrade/account/connect.db.inc.php
new file mode 120000 (symlink)
index 0000000..442fab7
--- /dev/null
@@ -0,0 +1 @@
+../../bin/connect.db.inc.php
\ No newline at end of file
diff --git a/upgrade/account/upgrade.sh b/upgrade/account/upgrade.sh
new file mode 100644 (file)
index 0000000..e9658df
--- /dev/null
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+echo "Upgrading database"
+mysql x4dat < *.sql
+
+echo "Updating birthday date"
+php birthday.php