Port email/send
[platal.git] / classes / user.php
index 3d8063e..7db7df4 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /***************************************************************************
- *  Copyright (C) 2003-2009 Polytechnique.org                              *
+ *  Copyright (C) 2003-2010 Polytechnique.org                              *
  *  http://opensource.polytechnique.org/                                   *
  *                                                                         *
  *  This program is free software; you can redistribute it and/or modify   *
@@ -24,11 +24,18 @@ class User extends PlUser
     private $_profile_fetched = false;
     private $_profile = null;
 
+    // Additional fields (non core)
+    protected $promo = null;
+
     // Implementation of the login to uid method.
     protected function getLogin($login)
     {
         global $globals;
 
+        if (!$login) {
+            throw new UserNotFoundException();
+        }
+
         if ($login instanceof User) {
             $machin->id();
         }
@@ -78,7 +85,7 @@ class User extends PlUser
         if ($fqdn == $globals->mail->domain || $fqdn == $globals->mail->domain2) {
             $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\'))
+                           INNER JOIN  aliases AS al ON (al.uid = a.uid AND al.type IN (\'alias\', \'a_vie\'))
                                 WHERE  al.alias = {?}', $mbox);
             if ($res->numRows()) {
                 return $res->fetchOneCell();
@@ -109,7 +116,7 @@ class User extends PlUser
                 list($alias, $alias_fqdn) = explode('@', $redir);
                 $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'))
+                                LEFT JOIN  aliases AS al ON (al.uid = a.uid AND al.type IN ('alias', 'a_vie'))
                                     WHERE  al.alias = {?}", $alias);
                 if ($res->numRows()) {
                     return $res->fetchOneCell();
@@ -139,13 +146,13 @@ class User extends PlUser
         throw new UserNotFoundException($res->fetchColumn(1));
     }
 
-    protected static function loadMainFieldsFromUIDs(array $uids)
+    protected static function loadMainFieldsFromUIDs(array $uids, $respect_order = true)
     {
         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'));
+            $joins .= XDB::format("LEFT JOIN group_members 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';
         }
@@ -154,23 +161,39 @@ class User extends PlUser
         } else {
             $fields = '';
         }
+
+        if ($respect_order) {
+            $order = 'ORDER BY ' . XDB::formatCustomOrder('a.uid', $uids);
+        } else {
+            $order = '';
+        }
+
         $uids = array_map(array('XDB', 'escape'), $uids);
-        return XDB::iterator('SELECT  a.uid, a.hruid, a.registration_date,
+
+        return XDB::iterator('SELECT  a.uid, a.hruid, a.registration_date, ah.alias AS homonym,
                                       CONCAT(af.alias, \'@' . $globals->mail->domain . '\') AS forlife,
+                                      CONCAT(af.alias, \'@' . $globals->mail->domain2 . '\') AS forlife_alternate,
                                       CONCAT(ab.alias, \'@' . $globals->mail->domain . '\') AS bestalias,
+                                      CONCAT(ab.alias, \'@' . $globals->mail->domain2 . '\') AS bestalias_alternate,
                                       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 ' . $fields . '
+                                      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  aliases AS af ON (af.uid = a.uid AND af.type = \'a_vie\')
+                           LEFT JOIN  aliases AS ab ON (ab.uid = a.uid AND FIND_IN_SET(\'bestalias\', ab.flags))
+                           LEFT JOIN  aliases AS ah ON (ah.uid = a.uid AND ah.type = \'homonyme\')
+                           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');
+                            GROUP BY  a.uid
+                                   ' . $order);
     }
 
     // Implementation of the data loader.
@@ -410,7 +433,7 @@ class User extends PlUser
         $this->fillFromArray($watch);
     }
 
-    public function watch($type)
+    public function watchType($type)
     {
         $this->fetchWatchData();
         return $this->watch_actions->hasFlag($type);
@@ -449,7 +472,7 @@ class User extends PlUser
 
     // Contacts
     private $contacts = null;
-    public function isContact(PlUser &$user)
+    private function fetchContacts()
     {
         if (is_null($this->contacts)) {
             $this->contacts = XDB::fetchAllAssoc('contact', 'SELECT  *
@@ -457,9 +480,39 @@ class User extends PlUser
                                                               WHERE  uid = {?}',
                                                  $this->id());
         }
+    }
+
+    public function iterContacts()
+    {
+        $this->fetchContacts();
+        return self::iterOverUIDs(array_keys($this->contacts));
+    }
+
+    public function getContacts()
+    {
+        $this->fetchContacts();
+        return self::getBulkUsersWithUIDs(array_keys($this->contacts));
+    }
+
+    public function isContact(PlUser &$user)
+    {
+        $this->fetchContacts();
         return isset($this->contacts[$user->id()]);
     }
 
+    // Groupes X
+    private $groups = null;
+    public function groups()
+    {
+        if (is_null($this->groups)) {
+            $this->groups = XDB::fetchAllAssoc('asso_id', 'SELECT  asso_id, perms, comm
+                                                             FROM  group_members
+                                                            WHERE  uid = {?}',
+                                                $this->id());
+        }
+        return $this->groups;
+    }
+
     // Return permission flags for a given permission level.
     public static function makePerms($perms, $is_admin)
     {
@@ -475,7 +528,7 @@ class User extends PlUser
     public static function _default_user_callback($login, $results)
     {
         $result_count = count($results);
-        if ($result_count == 0 || !S::has_perms()) {
+        if ($result_count == 0 || !S::admin()) {
             Platal::page()->trigError("Il n'y a pas d'utilisateur avec l'identifiant : $login");
         } else {
             Platal::page()->trigError("Il y a $result_count utilisateurs avec cet identifiant : " . join(', ', $results));
@@ -509,7 +562,18 @@ class User extends PlUser
             || $dom == $globals->mail->alias_dom2;
     }
 
-    // Fetch a set of users from a list of UIDs
+    public static function iterOverUIDs($uids, $respect_order = true)
+    {
+        return new UserIterator(self::loadMainFieldsFromUIDs($uids, $respect_order));
+    }
+
+    /** Fetch a set of users from a list of UIDs
+     * @param $data The list of uids to fetch, or an array of arrays
+     * @param $orig If $data is an array of arrays, the subfield where uids are stored
+     * @param $dest If $data is an array of arrays, the subfield to fill with Users
+     * @param $fetchProfile Whether to fetch Profiles as well
+     * @return either an array of $uid => User, or $data with $data[$i][$dest] = User
+     */
     public static function getBulkUsersWithUIDs(array $data, $orig = null, $dest = null, $fetchProfile = true)
     {
         // Fetch the list of uids
@@ -531,30 +595,33 @@ class User extends PlUser
         if (count($uids) == 0) {
             return $data;
         }
-        $fields = self::loadMainFieldsFromUIDs($uids);
+        $users = self::iterOverUIDs($uids, true);
+
         $table = array();
         if ($fetchProfile) {
-            $profiles = Profile::getBulkProfilesWithUIDS($uids);
+            $profiles = Profile::iterOverUIDS($uids, true);
+            $profile = $profiles->next();
         }
-        while (($list = $fields->next())) {
-            $uid  = $list['uid'];
-            $user = User::getSilentWithValues(null, $list);
+
+        /** We iterate through the users, moving in
+         * profiles when they match the user ID :
+         * there can be users without a profile, but not
+         * the other way around.
+         */
+        while (($user = $users->next())) {
             if ($fetchProfile) {
-                if (isset($profiles[$uid])) {
-                    $user->_profile = $profiles[$uid];
+                if ($profile->owner_id == $user->id()) {
+                    $user->_profile = $profile;
+                    $profile = $profiles->next();
                 }
                 $user->_profile_fetched = true;
             }
-            $table[$list['uid']] = $user;
+            $table[$user->id()] = $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;
+            return $table;
         } else {
             foreach ($data as $key=>$entry) {
                 if (isset($entry[$orig])) {
@@ -574,5 +641,43 @@ class User extends PlUser
     }
 }
 
+/** Iterator over a set of Users
+ * @param an XDB::Iterator obtained from a User::loadMainFieldsFromUIDs
+ */
+class UserIterator implements PlIterator
+{
+    private $dbiter;
+
+    public function __construct($dbiter)
+    {
+        $this->dbiter = $dbiter;
+    }
+
+    public function next()
+    {
+        $data = $this->dbiter->next();
+        if ($data == null) {
+            return null;
+        } else {
+            return User::getSilentWithValues(null, $data);
+        }
+    }
+
+    public function total()
+    {
+        return $this->dbiter->total();
+    }
+
+    public function first()
+    {
+        return $this->dbiter->first();
+    }
+
+    public function last()
+    {
+        return $this->dbiter->last();
+    }
+}
+
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
 ?>