Merge UFC_Email and UFC_EmailList into a single class (UFC_Email).
[platal.git] / classes / userfilter.php
index 63157e5..720817d 100644 (file)
@@ -39,10 +39,10 @@ interface UserFilterCondition extends PlFilterCondition
 }
 // }}}
 
-// {{{ class UFC_Profile
+// {{{ class UFC_HasProfile
 /** Filters users who have a profile
  */
-class UFC_Profile implements UserFilterCondition
+class UFC_HasProfile implements UserFilterCondition
 {
     public function buildCondition(PlFilter &$uf)
     {
@@ -70,12 +70,35 @@ class UFC_Hruid implements UserFilterCondition
     public function buildCondition(PlFilter &$uf)
     {
         $ufc->requireAccounts();
-
         return 'a.hruid IN ' . XDB::formatArray($this->hruids);
     }
 }
 // }}}
 
+// {{{ class UFC_Hrpid
+/** Filters users based on the hrpid of their profiles
+ * @param $val Either an hrpid, or a list of those
+ */
+class UFC_Hrpid implements UserFilterCondition
+{
+    private $hrpids;
+
+    public function __construct($val)
+    {
+        if (!is_array($val)) {
+            $val = array($val);
+        }
+        $this->hrpids = $val;
+    }
+
+    public function buildCondition(PlFilter &$uf)
+    {
+        $uf->requireProfiles();
+        return 'p.hrpid IN ' . XDB::formatArray($this->hrpids);
+    }
+}
+// }}}
+
 // {{{ class UFC_Ip
 /** Filters users based on one of their last IPs
  * @param $ip IP from which connection are checked
@@ -153,6 +176,48 @@ class UFC_Promo implements UserFilterCondition
 }
 // }}}
 
+// {{{ class UFC_SchoolId
+/** Filters users based on their shoold identifier
+ * @param type Parameter type (Xorg, AX, School)
+ * @param value School id value
+ */
+class UFC_SchooldId implements UserFilterCondition
+{
+    const AX     = 'ax';
+    const Xorg   = 'xorg';
+    const School = 'school';
+
+    private $type;
+    private $id;
+
+    static public function assertType($type)
+    {
+        if ($type != self::AX && $type != self::Xorg && $type != self::School) {
+            Platal::page()->killError("Type de matricule invalide: $type");
+        }
+    }
+
+    public function __construct($type, $id)
+    {
+        $this->type = $type;
+        $this->id   = $id;
+        self::assertType($type);
+    }
+
+    public function buildCondition(PlFilter &$uf)
+    {
+        $uf->requireProfiles();
+        $id = $this->id;
+        $type = $this->type;
+        if ($type == self::School) {
+            $type = self::Xorg;
+            $id   = Profile::getXorgId($id);
+        }
+        return XDB::format('p.' . $type . '_id = {?}', $id);
+    }
+}
+// }}}
+
 // {{{ class UFC_EducationSchool
 /** Filters users by formation
  * @param $val The formation to search (either ID or array of IDs)
@@ -558,51 +623,22 @@ class UFC_Section implements UserFilterCondition
 // }}}
 
 // {{{ class UFC_Email
-/** Filters users based on email address
- * @param $email Email whose owner we are looking for
- */
-class UFC_Email implements UserFilterCondition
-{
-    private $email;
-    public function __construct($email)
-    {
-        $this->email = $email;
-    }
-
-    public function buildCondition(PlFilter &$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
-/** Filters users based on an email list
+/** Filters users based on an email or a list of emails
  * @param $emails List of emails whose owner must be selected
  */
-class UFC_EmailList implements UserFilterCondition
+class UFC_Email implements UserFilterCondition
 {
     private $emails;
-    public function __construct($emails)
+    public function __construct()
     {
-        $this->emails = $emails;
+        $this->emails = func_get_args();
     }
 
     public function buildCondition(PlFilter &$uf)
     {
-        $email   = null;
-        $virtual = null;
-        $alias   = null;
+        $foreign = array();
+        $virtual = array();
+        $aliases = array();
         $cond = array();
 
         if (count($this->emails) == 0) {
@@ -611,23 +647,27 @@ class UFC_EmailList implements UserFilterCondition
 
         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);
+                $foreign[] = $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);
+                $virtual[] = $entry;
             } else {
-                if (is_null($alias)) {
-                    $alias = $uf->addAliasFilter();
-                }
                 @list($user, $domain) = explode('@', $entry);
-                $cond[] = XDB::format('al' . $alias . '.alias = {?}', $user);
+                $aliases[] = $user;
             }
         }
+
+        if (count($foreign) > 0) {
+            $sub = $uf->addEmailRedirectFilter($foreign);
+            $cond[] = 'e' . $sub . '.email IS NOT NULL OR a.email IN ' . XDB::formatArray($foreign);
+        }
+        if (count($virtual) > 0) {
+            $sub = $uf->addVirtualEmailFilter($virtual);
+            $cond[] = 'vr' . $sub . '.redirect IS NOT NULL';
+        }
+        if (count($aliases) > 0) {
+            $sub = $uf->addAliasFilter($aliases);
+            $cond[] = 'al' . $sub . '.alias IS NOT NULL';
+        }
         return '(' . implode(') OR (', $cond) . ')';
     }
 }
@@ -1211,7 +1251,7 @@ class UFC_WatchRegistration extends UFC_UserRelated
 {
     public function buildCondition(PlFilter &$uf)
     {
-        if (!$this->user->watch('registration')) {
+        if (!$this->user->watchType('registration')) {
             return PlFilterCondition::COND_FALSE;
         }
         $uids = $this->user->watchUsers();
@@ -1267,6 +1307,25 @@ class UFC_WatchContact extends UFC_Contact
 }
 // }}}
 
+// {{{ class UFC_MarketingHash
+/** Filters users using the hash generated
+ * to send marketing emails to him.
+ */
+class UFC_MarketingHash implements UserFilterCondition
+{
+    private $hash;
+
+    public function __construct($hash)
+    {
+        $this->hash = $hash;
+    }
+
+    public function buildCondition(PlFilter &$uf)
+    {
+        $table = $uf->addMarketingHash();
+        return XDB::format('rm.hash = {?}', $this->hash);
+    }
+}
 
 /******************
  * ORDERS
@@ -1666,17 +1725,47 @@ class UserFilter extends PlFilter
         return $this->getUIDList(null, $limit);
     }
 
+    public function getUID($pos = 0)
+    {
+        $uids =$this->getUIDList(null, new PlFilter(1, $pos));
+        if (count($uids) == 0) {
+            return null;
+        } else {
+            return $uids[0];
+        }
+    }
+
     public function getPIDs($limit = null)
     {
         $limit = self::defaultLimit($limit);
         return $this->getPIDList(null, $limit);
     }
 
+    public function getPID($pos = 0)
+    {
+        $pids =$this->getPIDList(null, new PlFilter(1, $pos));
+        if (count($pids) == 0) {
+            return null;
+        } else {
+            return $pids[0];
+        }
+    }
+
     public function getUsers($limit = null)
     {
         return User::getBulkUsersWithUIDs($this->getUIDs($limit));
     }
 
+    public function getUser($pos = 0)
+    {
+        $uid = $this->getUID($pos);
+        if ($uid == null) {
+            return null;
+        } else {
+            return User::getWithUID($uid);
+        }
+    }
+
     public function iterUsers($limit = null)
     {
         return User::iterOverUIDs($this->getUIDs($limit));
@@ -1687,6 +1776,16 @@ class UserFilter extends PlFilter
         return Profile::getBulkProfilesWithPIDs($this->getPIDs($limit));
     }
 
+    public function getProfile($pos = 0)
+    {
+        $pid = $this->getPID($pos);
+        if ($pid == null) {
+            return null;
+        } else {
+            return Profile::get($pid);
+        }
+    }
+
     public function iterProfiles($limit = null)
     {
         return Profile::iterOverPIDs($this->getPIDs($limit));
@@ -1752,7 +1851,14 @@ class UserFilter extends PlFilter
 
     static private function getDBSuffix($string)
     {
-        return preg_replace('/[^a-z0-9]/i', '', $string);
+        if (is_array($string)) {
+            if (count($string) == 1) {
+                return self::getDBSuffix(array_pop($string));
+            }
+            return md5(implode('|', $string));
+        } else {
+            return preg_replace('/[^a-z0-9]/i', '', $string);
+        }
     }
 
 
@@ -1802,7 +1908,7 @@ class UserFilter extends PlFilter
         $joins = array();
         /** Quick search is much more efficient with sn first and PID second */
         if ($this->with_forced_sn) {
-            $joins['p'] = new PlSqlJoin(PlSqlJoin::MODE_LEFT, 'profiles', '$PID = sn.uid');
+            $joins['p'] = new PlSqlJoin(PlSqlJoin::MODE_LEFT, 'profiles', '$PID = sn.pid');
             if ($this->with_accounts) {
                 $joins['ap'] = new PlSqlJoin(PlSqlJoin::MODE_LEFT, 'account_profiles', '$ME.pid = $PID');
                 $joins['a'] = new PlSqlJoin(PlSqlJoin::MODE_LEFT, 'accounts', '$UID = ap.uid');
@@ -1947,7 +2053,7 @@ class UserFilter extends PlFilter
     static public function assertGrade($grade)
     {
         if (!self::isGrade($grade)) {
-            Platal::page()->killError("Diplôme non valide");
+            Platal::page()->killError("Diplôme non valide: $grade");
         }
     }
 
@@ -2098,7 +2204,10 @@ class UserFilter extends PlFilter
             if (is_null($key)) {
                 $joins['e' . $sub] = new PlSqlJoin(PlSqlJoin::MODE_LEFT, 'emails', '$ME.uid = $UID AND $ME.flags != \'filter\'');
             } else {
-                $joins['e' . $sub] = new PlSqlJoin(PlSqlJoin::MODE_LEFT, 'emails', XDB::format('$ME.uid = $UID AND $ME.flags != \'filter\' AND $ME.email = {?}', $key));
+                if (!is_array($key)) {
+                    $key = array($key);
+                }
+                $joins['e' . $sub] = new PlSqlJoin(PlSqlJoin::MODE_LEFT, 'emails', '$ME.uid = $UID AND $ME.flags != \'filter\' AND $ME.email IN ' . XDB::formatArray($key));
             }
         }
         foreach ($this->al as $sub=>$key) {
@@ -2109,14 +2218,20 @@ class UserFilter extends PlFilter
             } else if ($key == self::ALIAS_FORLIFE) {
                 $joins['al' . $sub] = new PlSqlJoin(PlSqlJoin::MODE_LEFT, 'aliases', '$ME.uid = $UID AND $ME.type = \'a_vie\'');
             } else {
-                $joins['al' . $sub] = new PlSqlJoin(PlSqlJoin::MODE_LEFT, 'aliases', XDB::format('$ME.uid = $UID AND $ME.type IN (\'alias\', \'a_vie\') AND $ME.alias = {?}', $key));
+                if (!is_array($key)) {
+                    $key = array($key);
+                }
+                $joins['al' . $sub] = new PlSqlJoin(PlSqlJoin::MODE_LEFT, 'aliases', '$ME.uid = $UID AND $ME.type IN (\'alias\', \'a_vie\') AND $ME.alias IN ' . XDB::formatArray($key));
             }
         }
         foreach ($this->ve as $sub=>$key) {
             if (is_null($key)) {
                 $joins['v' . $sub] = new PlSqlJoin(PlSqlJoin::MODE_LEFT, 'virtual', '$ME.type = \'user\'');
             } else {
-                $joins['v' . $sub] = new PlSqlJoin(PlSqlJoin::MODE_LEFT, 'virtual', XDB::format('$ME.type = \'user\' AND $ME.alias = {?}', $key));
+                if (!is_array($key)) {
+                    $key = array($key);
+                }
+                $joins['v' . $sub] = new PlSqlJoin(PlSqlJoin::MODE_LEFT, 'virtual', '$ME.type = \'user\' AND $ME.alias IN ' . XDB::formatArray($key));
             }
             $joins['vr' . $sub] = new PlSqlJoin(PlSqlJoin::MODE_LEFT, 'virtual_redirect', XDB::format('$ME.vid = v' . $sub . '.vid
                                                                                  AND ($ME.redirect IN (CONCAT(al_forlife.alias, \'@\', {?}),
@@ -2408,9 +2523,9 @@ class UserFilter extends PlFilter
         $joins = array();
         foreach ($this->cts as $sub=>$key) {
             if (is_null($key)) {
-                $joins['c' . $sub] = new PlSqlJoin(PlSqlJoin::MODE_LEFT, 'contacts', '$ME.contact = $UID');
+                $joins['c' . $sub] = new PlSqlJoin(PlSqlJoin::MODE_LEFT, 'contacts', '$ME.contact = $PID');
             } else {
-                $joins['c' . $sub] = new PlSqlJoin(PlSqlJoin::MODE_LEFT, 'contacts', XDB::format('$ME.uid = {?} AND $ME.contact = $UID', substr($key, 5)));
+                $joins['c' . $sub] = new PlSqlJoin(PlSqlJoin::MODE_LEFT, 'contacts', XDB::format('$ME.uid = {?} AND $ME.contact = $PID', substr($key, 5)));
             }
         }
         return $joins;
@@ -2473,6 +2588,25 @@ class UserFilter extends PlFilter
         }
         return $joins;
     }
+
+
+    /** MARKETING
+     */
+    private $with_rm;
+    public function addMarketingHash()
+    {
+        $this->requireAccounts();
+        $this->with_rm = true;
+    }
+
+    protected function marketingJoins()
+    {
+        if ($this->with_rm) {
+            return array('rm' => new PlSqlJoin(PlSqlJoin::MODE_LEFT, 'register_marketing', '$ME.uid = $UID'));
+        } else {
+            return array();
+        }
+    }
 }
 // }}}