Fixes SQL query in list deletion.
[platal.git] / classes / user.php
index 4c531ea..304c1fa 100644 (file)
@@ -31,6 +31,13 @@ class User extends PlUser
     const PERM_MAIL              = 'mail';
     const PERM_PAYMENT           = 'payment';
 
+    public static $sub_mail_domains = array(
+        'x'      => '',
+        'master' => 'master.',
+        'phd'    => 'doc.',
+        'all'    => 'alumni.'
+    );
+
     private $_profile_fetched = false;
     private $_profile = null;
 
@@ -84,22 +91,22 @@ class User extends PlUser
         }
 
         // From now, $login can only by an email alias, or an email redirection.
-        // If it doesn't look like a valid address, appends the plat/al's main domain.
         $login = trim(strtolower($login));
         if (strstr($login, '@') === false) {
-            $email = $login;
-            $domain = $globals->mail->domain;
+            $res = XDB::fetchOneCell('SELECT  uid
+                                        FROM  email_source_account
+                                       WHERE  email = {?}',
+                                     $login);
         } else {
             list($email, $domain) = explode('@', $login);
+            $res = XDB::fetchOneCell('SELECT  s.uid
+                                        FROM  email_source_account  AS s
+                                  INNER JOIN  email_virtual_domains AS m ON (s.domain = m.id)
+                                  INNER JOIN  email_virtual_domains AS d ON (d.aliasing = m.id)
+                                       WHERE  s.email = {?} AND d.name = {?}',
+                                     $email, $domain);
         }
 
-        // Checks if $login is a valid alias on any domain.
-        $res = XDB::fetchOneCell('SELECT  s.uid
-                                    FROM  email_source_account  AS s
-                              INNER JOIN  email_virtual_domains AS m ON (s.domain = m.id)
-                              INNER JOIN  email_virtual_domains AS d ON (d.aliasing = m.id)
-                                   WHERE  s.email = {?} AND d.name = {?}',
-                                 $email, $login);
         if ($res) {
             return $res;
         }
@@ -153,11 +160,10 @@ class User extends PlUser
         $uids = array_map(array('XDB', 'escape'), $uids);
 
         return XDB::iterator('SELECT  a.uid, a.hruid, a.registration_date, h.uid IS NOT NULL AS homonym,
-                                      IF(ef.email IS NULL, NULL, CONCAT(ef.email, \'@\', MAX(df.name))) AS forlife,
-                                      IF(ef.email IS NULL, NULL, CONCAT(ef.email, \'@\', MIN(df.name))) AS forlife_alternate,
-                                      IF(eb.email IS NULL, NULL, CONCAT(eb.email, \'@\', MAX(db.name))) AS bestalias,
-                                      IF(eb.email IS NULL, NULL, CONCAT(eb.email, \'@\', MIN(db.name))) AS bestalias_alternate,
-                                      (er.redirect IS NULL AND a.state = \'active\') AS lost,
+                                      IF(ef.email IS NULL, NULL, CONCAT(ef.email, \'@\', mf.name)) AS forlife,
+                                      IF(ef.email IS NULL, NULL, CONCAT(ef.email, \'@\', df.name)) AS forlife_alternate,
+                                      IF(eb.email IS NULL, NULL, CONCAT(eb.email, \'@\', mb.name)) AS bestalias,
+                                      (er.redirect IS NULL AND a.state = \'active\' AND FIND_IN_SET(\'mail\', at.perms)) AS lost,
                                       a.email, a.full_name, a.directory_name, a.display_name, a.sex = \'female\' AS gender,
                                       IF(a.state = \'active\', CONCAT(at.perms, \',\', IF(a.user_perms IS NULL, \'\', a.user_perms)), \'\') AS perms,
                                       a.user_perms, a.email_format, a.is_admin, a.state, a.type, at.description AS type_description, a.skin,
@@ -170,10 +176,10 @@ class User extends PlUser
                           INNER JOIN  account_types          AS at ON (at.type = a.type)
                            LEFT JOIN  email_source_account   AS ef ON (ef.uid = a.uid AND ef.type = \'forlife\')
                            LEFT JOIN  email_virtual_domains  AS mf ON (ef.domain = mf.id)
-                           LEFT JOIN  email_virtual_domains  AS df ON (df.aliasing = mf.id)
-                           LEFT JOIN  email_source_account   AS eb ON (eb.uid = a.uid AND eb.flags = \'bestalias\')
-                           LEFT JOIN  email_virtual_domains  AS mb ON (eb.domain = mb.id)
-                           LEFT JOIN  email_virtual_domains  AS db ON (db.aliasing = mb.id)
+                           LEFT JOIN  email_virtual_domains  AS df ON (df.aliasing = mf.id AND
+                                                                       df.name LIKE CONCAT(\'%\', {?}) AND df.name NOT LIKE \'alumni.%\')
+                           LEFT JOIN  email_source_account   AS eb ON (eb.uid = a.uid AND FIND_IN_SET(\'bestalias\',eb.flags))
+                           LEFT JOIN  email_virtual_domains  AS mb ON (a.best_domain = mb.id)
                            LEFT JOIN  email_redirect_account AS er ON (er.uid = a.uid AND er.flags = \'active\' AND er.broken_level < 3
                                                                        AND er.type != \'imap\' AND er.type != \'homonym\')
                            LEFT JOIN  homonyms_list          AS h  ON (h.uid = a.uid)
@@ -184,7 +190,7 @@ class User extends PlUser
                                    ' . $joins . '
                                WHERE  a.uid IN (' . implode(', ', $uids) . ')
                             GROUP BY  a.uid
-                                   ' . $order);
+                                   ' . $order, $globals->mail->domain2, $globals->mail->domain2);
     }
 
     // Implementation of the data loader.
@@ -338,7 +344,33 @@ class User extends PlUser
                                  $this->id(), $profile->id());
     }
 
-    /** Fetch existing @alias_dom alias.
+    /** Determines main email domain for this user.
+     */
+    public function mainEmailDomain()
+    {
+        if (array_key_exists($this->type, self::$sub_mail_domains)) {
+            return self::$sub_mail_domains[$this->type] . Platal::globals()->mail->domain;
+        }
+    }
+
+    /** Determines alternate email domain for this user.
+     */
+    public function alternateEmailDomain()
+    {
+        if (array_key_exists($this->type, self::$sub_mail_domains)) {
+            return self::$sub_mail_domains[$this->type] . Platal::globals()->mail->domain2;
+        }
+    }
+
+    public function forlifeEmailAlternate()
+    {
+        if (!empty($this->forlife_alternate)) {
+            return $this->forlife_alternate;
+        }
+        return $this->email;
+    }
+
+    /** Fetch existing auxiliary alias.
      */
     public function emailAlias()
     {
@@ -349,7 +381,7 @@ class User extends PlUser
         return null;
     }
 
-    /** Fetch existing @alias_dom aliases.
+    /** Fetch existing auxiliary aliases.
      */
     public function emailAliases()
     {
@@ -357,9 +389,9 @@ class User extends PlUser
                                    FROM  email_source_account  AS s
                              INNER JOIN  email_virtual_domains AS m ON (s.domain = m.id)
                              INNER JOIN  email_virtual_domains AS d ON (d.aliasing = m.id)
-                                  WHERE  s.uid = {?} AND m.name = {?}
+                                  WHERE  s.uid = {?} AND s.type = \'alias_aux\'
                                ORDER BY  d.name',
-                                $this->id(), Platal::globals()->mail->alias_dom);
+                                $this->id());
     }
 
     /** Get all group aliases the user belongs to.
@@ -373,16 +405,19 @@ class User extends PlUser
                                  INNER JOIN  email_source_account  AS s  ON (s.uid = {?})
                                  INNER JOIN  email_virtual_domains AS ms ON (s.domain = ms.id)
                                  INNER JOIN  email_virtual_domains AS ds ON (ds.aliasing = ms.id)
-                                      WHERE  v.redirect = CONCAT(s.email, \'@\', ds.name) AND v.type = \'user\'',
+                                      WHERE  v.redirect = CONCAT(s.email, \'@\', ds.name) AND v.type = \'alias\'',
                                     $this->id());
         } else {
-            return XDB::fetchAllAssoc('SELECT  CONCAT(v.email, \'@\', dv.name) AS alias, v.uid IS NOT NULL AS sub
+            return XDB::fetchAllAssoc('alias',
+                                      'SELECT  CONCAT(v.email, \'@\', dv.name) AS alias, MAX(v.redirect = CONCAT(s.email, \'@\', ds.name)) AS sub
                                          FROM  email_virtual         AS v
                                    INNER JOIN  email_virtual_domains AS dv ON (v.domain = dv.id AND dv.name = {?})
                                    INNER JOIN  email_source_account  AS s  ON (s.uid = {?})
                                    INNER JOIN  email_virtual_domains AS ms ON (s.domain = ms.id)
                                    INNER JOIN  email_virtual_domains AS ds ON (ds.aliasing = ms.id)
-                                        WHERE  v.redirect = CONCAT(s.email, \'@\', ds.name) AND v.type = \'user\'',
+                                        WHERE  v.type = \'alias\'
+                                     GROUP BY  v.email
+                                     ORDER BY  v.email',
                                       $domain, $this->id());
         }
     }
@@ -595,6 +630,23 @@ class User extends PlUser
         }
     }
 
+    public function groupCount()
+    {
+        return XDB::fetchOneCell('SELECT  COUNT(DISTINCT(asso_id))
+                                    FROM  group_members
+                                   WHERE  uid = {?}',
+                                 $this->id());
+    }
+
+    public function inGroup($asso_id)
+    {
+        $res = XDB::fetchOneCell('SELECT  COUNT(*)
+                                    FROM  group_members
+                                   WHERE  uid = {?} AND asso_id = {?}',
+                                 $this->id(), $asso_id);
+        return ($res > 0);
+    }
+
     /**
      * Clears a user.
      *  *always deletes in: account_lost_passwords, register_marketing,
@@ -649,7 +701,7 @@ class User extends PlUser
             }
 
             $tables = array('account_auth_openid', 'announce_read', 'contacts',
-                            'email_send_save', 'email_virtual',
+                            'email_send_save',
                             'forum_innd', 'forum_profiles', 'forum_subs',
                             'group_announces_read', 'group_members',
                             'group_member_sub_requests', 'reminder', 'requests',
@@ -662,6 +714,9 @@ class User extends PlUser
             XDB::execute('DELETE FROM  email_redirect_account
                                 WHERE  uid = {?} AND type != \'homonym\'',
                          $this->id());
+            XDB::execute('DELETE FROM  email_virtual
+                                WHERE  redirect = {?}',
+                         $this->forlifeEmail());
 
             foreach (array('gapps_accounts', 'gapps_nicknames') as $t) {
                 XDB::execute('DELETE FROM  ' . $t . '
@@ -794,45 +849,50 @@ class User extends PlUser
         }
     }
 
-    // Implementation of the static email locality checker.
-    public static function isForeignEmailAddress($email)
+    public static function makeHomonymHrmid($alias)
+    {
+        return 'h.' . $alias . '.' . Platal::globals()->mail->domain;
+    }
+
+    public static function isMainMailDomain($domain)
     {
         global $globals;
-        if (strpos($email, '@') === false) {
-            return false;
-        }
 
-        list($user, $dom) = explode('@', $email);
-        return $dom != $globals->mail->domain &&
-               $dom != $globals->mail->domain2 &&
-               $dom != $globals->mail->alias_dom &&
-               $dom != $globals->mail->alias_dom2;
+        $is_main_domain = false;
+        foreach (self::$sub_mail_domains as $sub_domain) {
+            $is_main_domain = $is_main_domain || $domain == ($sub_domain . $globals->mail->domain) && $domain == ($sub_domain . $globals->mail->domain2);
+        }
+        return $is_main_domain;
     }
 
-    public static function isVirtualEmailAddress($email)
+    public static function isAliasMailDomain($domain)
     {
         global $globals;
+
+        return $domain == $globals->mail->alias_dom || $domain == $globals->mail->alias_dom2;
+    }
+
+    // Implementation of the static email locality checker.
+    public static function isForeignEmailAddress($email)
+    {
         if (strpos($email, '@') === false) {
             return false;
         }
 
-        list($user, $dom) = explode('@', $email);
-        return $dom == $globals->mail->alias_dom
-            || $dom == $globals->mail->alias_dom2;
+        list(, $domain) = explode('@', $email);
+        return !(self::isMainMailDomain($domain) || self::isAliasMailDomain($domain));
     }
 
     /* Tries to find pending accounts with an hruid close to $login. */
     public static function getPendingAccounts($login, $iterator = false)
     {
-        global $globals;
-
         if (strpos($login, '@') === false) {
             return null;
         }
 
         list($login, $domain) = explode('@', $login);
 
-        if ($domain && $domain != $globals->mail->domain && $domain != $globals->mail->domain2) {
+        if ($domain && !self::isMainMailDomain($domain)) {
             return null;
         }