X-Git-Url: http://git.polytechnique.org/?a=blobdiff_plain;ds=inline;f=classes%2Fuserfilter.php;h=ebe69f4c508be53d199a01e814ce1df0cec55440;hb=da496b3758c9185e2d031f59707d037557d19a41;hp=1a88da72c69f232c15ff52a3af7c98e7490e9823;hpb=aa21c5687bbff1f218bf82bba6dfb73a717e4bdc;p=platal.git diff --git a/classes/userfilter.php b/classes/userfilter.php index 1a88da7..ebe69f4 100644 --- a/classes/userfilter.php +++ b/classes/userfilter.php @@ -161,6 +161,14 @@ class UFC_Or extends UFC_NChildren } } +class UFC_Profile implements UserFilterCondition +{ + public function buildCondition(UserFilter &$uf) + { + return '$PID IS NOT NULL'; + } +} + class UFC_Promo implements UserFilterCondition { @@ -292,6 +300,40 @@ class UFC_Registered implements UserFilterCondition } } +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; @@ -344,15 +386,123 @@ class UFC_Email implements UserFilterCondition 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 { - if (User::isVirtualEmailAddress($this->email)) { - $sub = $uf->addVirtualEmailFilter($this->email); + @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 { - list($user, $domain) = explode('@', $this->email); - $sub = $uf->addAliasFilter($user); + if (is_null($alias)) { + $alias = $uf->addAliasFilter(); + } + @list($user, $domain) = explode('@', $entry); + $cond[] = XDB::format('al' . $alias . '.alias = {?}', $user); } - return 'al' . $sub . '.alias IS NOT NULL'; } + 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); } } @@ -364,6 +514,10 @@ class UFC_Email implements UserFilterCondition abstract class UserFilterOrder { protected $desc = false; + public function __construct($desc = false) + { + $this->desc = $desc; + } public function buildSort(UserFilter &$uf) { @@ -388,8 +542,8 @@ class UFO_Promo extends UserFilterOrder public function __construct($grade = null, $desc = false) { + parent::__construct($desc); $this->grade = $grade; - $this->desc = $desc; } protected function getSortTokens(UserFilter &$uf) @@ -412,10 +566,10 @@ class UFO_Name extends UserFilterOrder public function __construct($type, $variant = null, $particle = false, $desc = false) { + parent::__construct($desc); $this->type = $type; $this->variant = $variant; $this->particle = $particle; - $this->desc = $desc; } protected function getSortTokens(UserFilter &$uf) @@ -436,17 +590,37 @@ class UFO_Name extends UserFilterOrder class UFO_Registration extends UserFilterOrder { - public function __construct($desc = false) + protected function getSortTokens(UserFilter &$uf) { - $this->desc = $desc; + return 'a.registration_date'; } +} +class UFO_Birthday extends UserFilterOrder +{ protected function getSortTokens(UserFilter &$uf) { - return 'a.registration_date'; + 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 @@ -508,8 +682,8 @@ class UserFilter $where = $this->root->buildCondition($this); $joins = $this->buildJoins(); $this->query = '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) + 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 . ')'; } @@ -552,14 +726,14 @@ class UserFilter $limit = ''; if (!is_null($count)) { if (!is_null($offset)) { - $limit = XDB::format('LIMIT {?}, {?}', $offset, $count); + $limit = XDB::format('LIMIT {?}, {?}', (int)$offset, (int)$count); } else { - $limit = XDB::format('LIMIT {?}', $count); + $limit = XDB::format('LIMIT {?}', (int)$count); } } $cond = ''; if (!is_null($uids)) { - $cond = ' AND a.uid IN (' . implode(', ', $uids) . ')'; + $cond = ' AND a.uid IN ' . XDB::formatArray($uids); } $fetched = XDB::fetchColumn('SELECT SQL_CALC_FOUND_ROWS a.uid ' . $this->query . $cond . ' @@ -588,8 +762,13 @@ class UserFilter $table = array(); $uids = array(); foreach ($users as $user) { - $uids[] = $user->id(); - $table[$user->id()] = $user; + if ($user instanceof PlUser) { + $uid = $user->id(); + } else { + $uid = $user; + } + $uids[] = $uid; + $table[$uid] = $user; } $fetched = $this->getUIDList($uids, $count, $offset); $output = array(); @@ -613,9 +792,8 @@ class UserFilter { if (is_null($this->lastcount)) { $this->buildQuery(); - return (int)XDB::fetchOneCell('SELECT COUNT(*) - ' . $this->query . ' - GROUP BY a.uid'); + return (int)XDB::fetchOneCell('SELECT COUNT(DISTINCT a.uid) + ' . $this->query); } else { return $this->lastcount; } @@ -648,6 +826,16 @@ class UserFilter 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); @@ -870,9 +1058,12 @@ class UserFilter 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) { @@ -890,27 +1081,110 @@ class UserFilter $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('inner', 'virtual_redirect', '$ME.vid = v' . $sub . '.vid'); - $joins['al' . $sub] = array('left', 'aliases', XDB::format('$ME.id = $UID AND (CONCAT($ME.alias, \'@\', {?}) = vr'. $sub . '.redirect - OR CONCAT($ME.alias, \'@\', {?}) = vr'. $sub . '.redirect)', - $globals->mail->domain, $globals->mail->domain2)); + $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)); } - foreach ($this->al as $sub=>$key) { + 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['al' . $sub] = array('left', 'aliases', '$ME.id = $UID'); + $joins['wn' . $sub] = array('left', 'watch_nonins', '$ME.ni_id = $UID'); } else { - $joins['al' . $sub] = array('left', 'aliases', XDB::format('$ME.id = $UID AND $ME.alias = {?}', $key)); + $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: ?>