}
}
+class UFC_Profile implements UserFilterCondition
+{
+ public function buildCondition(UserFilter &$uf)
+ {
+ return '$PID IS NOT NULL';
+ }
+}
+
class UFC_Promo implements UserFilterCondition
{
$this->grade = $grade;
$this->comparison = $comparison;
$this->promo = $promo;
- UserFilter::assertGrade($this->grade);
+ if ($this->grade != UserFilter::DISPLAY) {
+ UserFilter::assertGrade($this->grade);
+ }
}
public function buildCondition(UserFilter &$uf)
{
- $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);
+ 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_Dead implements UserFilterCondition
{
- private $dead;
- public function __construct($dead)
+ private $comparison;
+ private $date;
+
+ public function __construct($comparison = null, $date = null)
{
- $this->dead = $dead;
+ $this->comparison = $comparison;
+ $this->date = $date;
}
public function buildCondition(UserFilter &$uf)
{
- if ($this->dead) {
- return 'p.deathdate IS NOT NULL';
- } else {
- return 'p.deathdate IS NULL';
+ $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;
- public function __construct($active = false)
+ 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) {
- return 'a.uid IS NOT NULL AND a.state = \'active\'';
+ $date = 'a.uid IS NOT NULL AND a.state = \'active\'';
} else {
- return 'a.uid IS NOT NULL AND a.state != \'pending\'';
+ $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_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);
+ }
+}
/******************
abstract class UserFilterOrder
{
protected $desc = false;
+ public function __construct($desc = false)
+ {
+ $this->desc = $desc;
+ }
public function buildSort(UserFilter &$uf)
{
public function __construct($grade = null, $desc = false)
{
+ parent::__construct($desc);
$this->grade = $grade;
- $this->desc = $desc;
}
protected function getSortTokens(UserFilter &$uf)
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)
}
}
+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
private $query = null;
private $orderby = null;
- private $lastcount = 0;
+ private $lastcount = null;
public function __construct($cond = null, $sort = null)
{
$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 . ')';
}
$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 . '
$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();
public function getTotalCount()
{
- return $this->lastcount;
+ 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)
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()
{
}
private $pn = array();
- private $pno = 0;
public function addNameFilter($type, $variant = null)
{
if (!is_null($variant)) {
self::assertName($ft);
if (!is_null($variant) && $variant == 'other') {
- $sub .= $this->pno++;
+ $sub .= $this->option++;
}
$this->pn[$sub] = Profile::getNameTypeId($ft);
return $sub;
const GRADE_MST = 'M%';
static public function isGrade($grade)
{
- return $grade == self::GRADE_ING || self::$grade == GRADE_PHD || self::$grade == GRADE_MST;
+ return $grade == self::GRADE_ING || $grade == self::GRADE_PHD || $grade == self::GRADE_MST;
}
static public function assertGrade($grade)
private $pepe = array();
private $with_pee = false;
- private $pe_g = 0;
public function addEducationFilter($x = false, $grade = null)
{
if (!$x) {
- $index = $this->pe_g;
- $sub = $this->pe_g++;
+ $index = $this->option;
+ $sub = $this->option++;
} else {
self::assertGrade($grade);
$index = $grade;
/** GROUPS
*/
private $gpm = array();
- private $gpm_o = 0;
public function addGroupFilter($group = null)
{
if (!is_null($group)) {
$index = $sub = $group;
} else {
$index = $group;
- $sub = preg_replace('/[^a-z0-9]/i', '', $group);
+ $sub = self::getDBSuffix($group);
}
} else {
- $sub = 'group_' . $this->gpm_o++;
+ $sub = 'group_' . $this->option++;
$index = null;
}
$sub = '_' . $sub;
}
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:
?>