X-Git-Url: http://git.polytechnique.org/?a=blobdiff_plain;f=classes%2Fuserfilter%2Fconditions.inc.php;h=4070c3fdf0cd43e5e06c2c7b57ff50d931228335;hb=86668a58a94fc57493a335eb75a37171238c0220;hp=28f493d5f687969fd0ccc604869716a3530c04aa;hpb=cc9a4dad330cf1b41b7974d2480442e121518276;p=platal.git diff --git a/classes/userfilter/conditions.inc.php b/classes/userfilter/conditions.inc.php index 28f493d..4070c3f 100644 --- a/classes/userfilter/conditions.inc.php +++ b/classes/userfilter/conditions.inc.php @@ -1,6 +1,6 @@ '; + const OP_NOTGREATER = '<='; + const OP_LESSER = '<'; + const OP_NOTLESSER = '>='; + const OP_NULL = 'null'; + const OP_NOTNULL = 'not null'; + const OP_CONTAINS = 'contains'; + const OP_PREFIX = 'prefix'; + const OP_SUFFIX = 'suffix'; + + protected function buildExport($type) + { + $export = array('type' => $type); + return $export; + } + public function export() { throw new Exception("This class is not exportable"); } + + public static function comparisonFromXDBWildcard($wildcard) + { + switch ($wildcard) { + case XDB::WILDCARD_EXACT: + return self::OP_EQUALS; + case XDB::WILDCARD_PREFIX: + return self::OP_PREFIX; + case XDB::WILDCARD_SUFFIX: + return self::OP_SUFFIX; + case XDB::WILDCARD_CONTAINS: + return self::OP_CONTAINS; + } + throw new Exception("Unknown wildcard mode: $wildcard"); + } + + public static function xdbWildcardFromComparison($comparison) + { + if (!self::isStringComparison($comparison)) { + throw new Exception("Unknown string coparison: $comparison"); + } + switch ($comparison) { + case self::OP_EQUALS: + return XDB::WILDCARD_EXACT; + case self::OP_PREFIX: + return XDB::WILDCARD_PREFIX; + case self::OP_SUFFIX: + return XDB::WILDCARD_SUFFIX; + case self::OP_CONTAINS: + return XDB::WILDCARD_CONTAINS; + } + } + + private static function isNumericComparison($comparison) + { + return $comparison == self::OP_EQUALS + || $comparison == self::OP_GREATER + || $comparison == self::OP_NOTGREATER + || $comparison == self::OP_LESSER + || $comparison == self::OP_NOTLESSER; + } + + private static function isStringComparison($comparison) + { + return $comparison == self::OP_EQUALS + || $comparison == self::OP_CONTAINS + || $comparison == self::OP_PREFIX + || $comparison == self::OP_SUFFIX; + } + + public static function fromExport(array $export) + { + $export = new PlDict($export); + if (!$export->has('type')) { + throw new Exception("Missing type in export"); + } + $type = $export->s('type'); + $cond = null; + switch ($type) { + case 'and': + case 'or': + case 'not': + case 'true': + case 'false': + $class = 'pfc_' . $type; + $cond = new $class(); + break; + + case 'host': + if ($export->has('ip')) { + $cond = new UFC_Ip($export->s('ip')); + } + break; + + case 'comment': + if ($export->has('text') && $export->s('comparison') == self::OP_CONTAINS) { + $cond = new UFC_Comment($export->s('text')); + } + break; + + case 'promo': + if ($export->has('promo') && self::isNumericComparison($export->s('comparison'))) { + $cond = new UFC_Promo($export->s('comparison'), + $export->s('grade', UserFilter::DISPLAY), + $export->s('promo')); + } + break; + + case 'lastname': + case 'name': + case 'firstname': + case 'nickname': + case 'pseudonym': + if ($export->has('text')) { + $flag = self::xdbWildcardFromComparison($export->s('comparison')); + if ($export->b('search_in_variants')) { + $flag |= UFC_Name::VARIANTS; + } + if ($export->b('search_in_particle')) { + $flag |= UFC_Name::PARTICLE; + } + $cond = new UFC_Name($type, $export->s('text'), $flag); + } + break; + + case 'account_type': + case 'account_perm': + case 'hrpid': + case 'hruid': + $values = $export->v('values', array()); + $class = 'ufc_' . str_replace('_', '', $type); + $cond = new $class($values); + break; + + case 'school_id': + $values = $export->v('values', array()); + $school_type = $export->s('school_type'); + $cond = new UFC_SchoolId($school_type, $values); + break; + + case 'has_profile': + case 'has_email_redirect': + case 'has_valid_email': + $class = 'ufc_' . str_replace('_', '', $type); + $cond = new $class(); + break; + + default: + throw new Exception("Unknown condition type: $type"); + } + if (is_null($cond)) { + throw new Exception("Unsupported $type definition"); + } + if ($cond instanceof PFC_NChildren) { + $children = $export->v('children', array()); + foreach ($children as $child) { + $cond->addChild(self::fromExport($child)); + } + } else if ($cond instanceof PFC_OneChild) { + if ($export->has('child')) { + $cond->setChild(self::fromExport($export->v('child'))); + } + } + return $cond; + } } // }}} - // {{{ class UFC_HasProfile /** Filters users who have a profile */ @@ -48,9 +209,13 @@ class UFC_HasProfile extends UserFilterCondition $uf->requireProfiles(); return '$PID IS NOT NULL'; } + + public function export() + { + return $this->buildExport('has_profile'); + } } // }}} - // {{{ class UFC_AccountType /** Filters users who have one of the given account types */ @@ -68,9 +233,15 @@ class UFC_AccountType extends UserFilterCondition $uf->requireAccounts(); return XDB::format('a.type IN {?}', $this->types); } + + public function export() + { + $export = $this->buildExport('account_type'); + $export['values'] = $this->types; + return $export; + } } // }}} - // {{{ class UFC_AccountPerm /** Filters users who have one of the given permissions */ @@ -98,9 +269,15 @@ class UFC_AccountPerm extends UserFilterCondition return implode(' OR ', $conds); } } + + public function export() + { + $export = $this->buildExport('account_perm'); + $export['values'] = $this->perms; + return $export; + } } // }}} - // {{{ class UFC_Hruid /** Filters users based on their hruid * @param $val Either an hruid, or a list of those @@ -119,9 +296,15 @@ class UFC_Hruid extends UserFilterCondition $uf->requireAccounts(); return XDB::format('a.hruid IN {?}', $this->hruids); } + + public function export() + { + $export = $this->buildExport('hruid'); + $export['values'] = $this->hruids; + return $export; + } } // }}} - // {{{ class UFC_Hrpid /** Filters users based on the hrpid of their profiles * @param $val Either an hrpid, or a list of those @@ -140,9 +323,52 @@ class UFC_Hrpid extends UserFilterCondition $uf->requireProfiles(); return XDB::format('p.hrpid IN {?}', $this->hrpids); } + + public function export() + { + $export = $this->buildExport('hrpid'); + $export['values'] = $this->hrpids; + return $export; + } +} +// }}} +// {{{ class UFC_HasEmailRedirect +/** Filters users, keeping only those with a valid email redirection (only X.org accounts). + */ +class UFC_HasEmailRedirect extends UserFilterCondition +{ + public function buildCondition(PlFilter $uf) + { + $sub_redirect = $uf->addActiveEmailRedirectFilter(); + return 'rf.redirect IS NOT NULL'; + } + + public function export() + { + $export = $this->buildExport('has_email_redirect'); + return $export; + } } // }}} +// {{{ class UFC_HasValidEmail +/** Filters users, keeping only those with a valid email address (all accounts). + */ +class UFC_HasValidEmail extends UserFilterCondition +{ + public function buildCondition(PlFilter $uf) + { + $sub_redirect = $uf->addEmailRedirectFilter(); + $uf->requireAccounts(); + return 'ra' . $sub_redirect . '.flags = \'active\' OR a.email IS NOT NULL'; + } + public function export() + { + $export = $this->buildExport('has_valid_email'); + return $export; + } +} +// }}} // {{{ class UFC_Ip /** Filters users based on one of their last IPs * @param $ip IP from which connection are checked @@ -162,9 +388,15 @@ class UFC_Ip extends UserFilterCondition $ip = ip_to_uint($this->ip); return XDB::format($sub . '.ip = {?} OR ' . $sub . '.forward_ip = {?}', $ip, $ip); } + + public function export() + { + $export = $this->buildExport('host'); + $export['ip'] = $this->ip; + return $export; + } } // }}} - // {{{ class UFC_Comment class UFC_Comment extends UserFilterCondition { @@ -180,9 +412,16 @@ class UFC_Comment extends UserFilterCondition $uf->requireProfiles(); return $uf->getVisibilityCondition('p.freetext_pub') . ' AND p.freetext ' . XDB::formatWildcards(XDB::WILDCARD_CONTAINS, $this->text); } + + public function export() + { + $export = $this->buildExport('comment'); + $export['comparison'] = self::OP_CONTAINS; + $export['text'] = $this->text; + return $export; + } } // }}} - // {{{ class UFC_Promo /** Filters users based on promotion * @param $comparison Comparison operator (>, =, ...) @@ -221,13 +460,23 @@ class UFC_Promo extends UserFilterCondition return $field . ' IS NOT NULL AND ' . $field . ' ' . $this->comparison . ' ' . XDB::format('{?}', $this->promo); } } + + public function export() + { + $export = $this->buildExport('promo'); + $export['comparison'] = $this->comparison; + if ($this->grade != UserFilter::DISPLAY) { + $export['grade'] = $this->grade; + } + $export['promo'] = $this->promo; + return $export; + } } // }}} - // {{{ class UFC_SchoolId /** Filters users based on their shoold identifier * @param type Parameter type (Xorg, AX, School) - * @param value School id value + * @param value Array of school ids */ class UFC_SchoolId extends UserFilterCondition { @@ -245,27 +494,41 @@ class UFC_SchoolId extends UserFilterCondition } } - public function __construct($type, $id) + /** Construct a UFC_SchoolId + * The first argument is the type, all following arguments can be either ids + * or arrays of ids to use: + * $ufc = new UFC_SchoolId(UFC_SchoolId::AX, $id1, $id2, array($id3, $id4)); + */ + public function __construct($type) { $this->type = $type; - $this->id = $id; + $ids = func_get_args(); + array_shift($ids); + $this->ids = pl_flatten($ids); self::assertType($type); } public function buildCondition(PlFilter $uf) { $uf->requireProfiles(); - $id = $this->id; + $ids = $this->ids; $type = $this->type; if ($type == self::School) { $type = self::Xorg; - $id = Profile::getXorgId($id); + $ids = array_map(array('Profile', 'getXorgId'), $ids); } - return XDB::format('p.' . $type . '_id = {?}', $id); + return XDB::format('p.' . $type . '_id IN {?}', $ids); + } + + public function export() + { + $export = $this->buildExport('school_id'); + $export['school_type'] = $this->type; + $export['values'] = $this->ids; + return $export; } } // }}} - // {{{ class UFC_EducationSchool /** Filters users by formation * @param $val The formation to search (either ID or array of IDs) @@ -286,7 +549,6 @@ class UFC_EducationSchool extends UserFilterCondition } } // }}} - // {{{ class UFC_EducationDegree class UFC_EducationDegree extends UserFilterCondition { @@ -304,7 +566,6 @@ class UFC_EducationDegree extends UserFilterCondition } } // }}} - // {{{ class UFC_EducationField class UFC_EducationField extends UserFilterCondition { @@ -322,59 +583,39 @@ class UFC_EducationField extends UserFilterCondition } } // }}} - -// {{{ class UFC_Name -/** Filters users based on name - * @param $type Type of name field on which filtering is done (firstname, lastname...) - * @param $text Text on which to filter - * @param $mode Flag indicating search type (prefix, suffix, with particule...) +// {{{ class UFC_NameInitial +/** Filters users based on sort_name + * @param $initial Initial on which to filter */ -class UFC_Name extends UserFilterCondition +class UFC_NameInitial extends UserFilterCondition { - const EXACT = XDB::WILDCARD_EXACT; // 0x000 - const PREFIX = XDB::WILDCARD_PREFIX; // 0x001 - const SUFFIX = XDB::WILDCARD_SUFFIX; // 0x002 - const CONTAINS = XDB::WILDCARD_CONTAINS; // 0x003 - const PARTICLE = 0x004; - const VARIANTS = 0x008; - - private $type; - private $text; - private $mode; + private $initial; - public function __construct($type, $text, $mode) + public function __construct($initial) { - $this->type = $type; - $this->text = $text; - $this->mode = $mode; - } - - private function buildNameQuery($type, $variant, $where, UserFilter $uf) - { - $sub = $uf->addNameFilter($type, $variant); - return str_replace('$ME', 'pn' . $sub, $where); + $this->initial = $initial; } public function buildCondition(PlFilter $uf) { - $left = '$ME.name'; - if (($this->mode & self::PARTICLE) == self::PARTICLE) { - $left = 'CONCAT($ME.particle, \' \', $ME.name)'; + $table = 'sort_name'; + if ($uf->accountsRequired()) { + $table = Profile::getAccountEquivalentName($table); + $sub = 'a'; + } else { + $uf->addDisplayFilter(); + $sub = 'pd'; } - $right = XDB::formatWildcards($this->mode & self::CONTAINS, $this->text); + return 'SUBSTRING(' . $sub . '.' . $table . ', 1, 1) ' . XDB::formatWildcards(XDB::WILDCARD_PREFIX, $this->initial); + } - $cond = $left . $right; - $conds = array($this->buildNameQuery($this->type, null, $cond, $uf)); - if (($this->mode & self::VARIANTS) != 0 && isset(Profile::$name_variants[$this->type])) { - foreach (Profile::$name_variants[$this->type] as $var) { - $conds[] = $this->buildNameQuery($this->type, $var, $cond, $uf); - } - } - return implode(' OR ', $conds); + public function export() + { + $export = $this->buildExport($this->initial); + return $export; } } // }}} - // {{{ class UFC_NameTokens /** Selects users based on tokens in their name (for quicksearch) * @param $tokens An array of tokens to search @@ -390,8 +631,9 @@ class UFC_NameTokens extends UserFilterCondition private $flags; private $soundex; private $exact; + private $general_type; - public function __construct($tokens, $flags = array(), $soundex = false, $exact = false) + public function __construct($tokens, $flags = array(), $soundex = false, $exact = false, $general_type = '') { if (is_array($tokens)) { $this->tokens = $tokens; @@ -405,6 +647,7 @@ class UFC_NameTokens extends UserFilterCondition } $this->soundex = $soundex; $this->exact = $exact; + $this->general_type = $general_type; } public function buildCondition(PlFilter $uf) @@ -422,6 +665,9 @@ class UFC_NameTokens extends UserFilterCondition if ($this->flags != null) { $c .= XDB::format(' AND ' . $sub . '.flags IN {?}', $this->flags); } + if ($this->general_type) { + $c .= XDB::format(' AND ' . $sub . '.general_type = {?}', $this->general_type); + } $conds[] = $c; } @@ -429,7 +675,6 @@ class UFC_NameTokens extends UserFilterCondition } } // }}} - // {{{ class UFC_Nationality class UFC_Nationality extends UserFilterCondition { @@ -453,7 +698,6 @@ class UFC_Nationality extends UserFilterCondition } } // }}} - // {{{ class UFC_Dead /** Filters users based on death date * @param $comparison Comparison operator @@ -481,7 +725,6 @@ class UFC_Dead extends UserFilterCondition } } // }}} - // {{{ class UFC_Registered /** Filters users based on registration state * @param $active Whether we want to use only "active" users (i.e with a valid redirection) @@ -516,7 +759,6 @@ class UFC_Registered extends UserFilterCondition } } // }}} - // {{{ class UFC_ProfileUpdated /** Filters users based on profile update date * @param $comparison Comparison operator @@ -540,7 +782,6 @@ class UFC_ProfileUpdated extends UserFilterCondition } } // }}} - // {{{ class UFC_Birthday /** Filters users based on next birthday date * @param $comparison Comparison operator @@ -564,7 +805,6 @@ class UFC_Birthday extends UserFilterCondition } } // }}} - // {{{ class UFC_Sex /** Filters users based on sex * @parm $sex One of User::GENDER_MALE or User::GENDER_FEMALE, for selecting users @@ -588,7 +828,28 @@ class UFC_Sex extends UserFilterCondition } } // }}} +// {{{ class UFC_NLSubscribed +/** Filters users based on NL subscription + * @param $nlid NL whose subscribers we are selecting + * @param $issue Select only subscribers who have not yet received that issue + */ +class UFC_NLSubscribed extends UserFilterCondition +{ + private $nlid; + private $issue_id; + public function __construct($nlid, $issue_id) + { + $this->nlid = $nlid; + $this->issue_id = $issue_id; + } + public function buildCondition(PlFilter $uf) + { + $sub = $uf->addNewsLetterFilter($this->nlid); + return XDB::format($sub . '.nlid IS NOT NULL AND ( ' . $sub . '.last IS NULL OR ' . $sub . '.last < {?})', $this->issue_id); + } +} +// }}} // {{{ class UFC_Group /** Filters users based on group membership * @param $group Group whose members we are selecting @@ -606,9 +867,9 @@ class UFC_Group extends UserFilterCondition public function buildCondition(PlFilter $uf) { - // Groups have AX visibility. - if ($uf->getVisibilityLevel() == ProfileVisibility::VIS_PUBLIC) { - return self::COND_TRUE; + // Groups are only visible for users with perm 'groups'. + if (!S::user()->checkPerms(User::PERM_GROUPS)) { + return self::COND_FALSE; } $sub = $uf->addGroupFilter($this->group); $where = 'gpm' . $sub . '.perms IS NOT NULL'; @@ -619,7 +880,30 @@ class UFC_Group extends UserFilterCondition } } // }}} +// {{{ class UFC_GroupFormerMember +/** Filters users based on group former membership + * @param $group Group whose former members we are selecting + */ +class UFC_GroupFormerMember extends UserFilterCondition +{ + private $group; + public function __construct($group) + { + $this->group = $group; + } + + public function buildCondition(PlFilter $uf) + { + // Groups are only visible for users with perm 'groups'. + if (!S::user()->checkPerms(User::PERM_GROUPS)) { + return self::COND_FALSE; + } + $sub = $uf->addGroupFormerMemberFilter(); + return XDB::format('gpfm' . $sub . '.asso_id = {?}', $this->group); + } +} +// }}} // {{{ class UFC_Binet /** Selects users based on their belonging to a given (list of) binet * @param $binet either a binet_id or an array of binet_ids @@ -637,14 +921,13 @@ class UFC_Binet extends UserFilterCondition { // Binets are private. if ($uf->getVisibilityLevel() != ProfileVisibility::VIS_PRIVATE) { - return self::CONF_TRUE; + return self::COND_TRUE; } $sub = $uf->addBinetsFilter(); return XDB::format($sub . '.binet_id IN {?}', $this->val); } } // }}} - // {{{ class UFC_Section /** Selects users based on section * @param $section ID of the section @@ -662,14 +945,13 @@ class UFC_Section extends UserFilterCondition { // Sections are private. if ($uf->getVisibilityLevel() != ProfileVisibility::VIS_PRIVATE) { - return self::CONF_TRUE; + return self::COND_TRUE; } $uf->requireProfiles(); return XDB::format('p.section IN {?}', $this->section); } } // }}} - // {{{ class UFC_Email /** Filters users based on an email or a list of emails * @param $emails List of emails whose owner must be selected @@ -685,9 +967,8 @@ class UFC_Email extends UserFilterCondition public function buildCondition(PlFilter $uf) { $foreign = array(); - $virtual = array(); - $aliases = array(); - $cond = array(); + $local = array(); + $cond = array(); if (count($this->emails) == 0) { return PlFilterCondition::COND_TRUE; @@ -696,45 +977,41 @@ class UFC_Email extends UserFilterCondition foreach ($this->emails as $entry) { if (User::isForeignEmailAddress($entry)) { $foreign[] = $entry; - } else if (User::isVirtualEmailAddress($entry)) { - $virtual[] = $entry; } else { - @list($user, $domain) = explode('@', $entry); - $aliases[] = $user; + list($local_part, ) = explode('@', $entry); + $local[] = $local_part; } } if (count($foreign) > 0) { $sub = $uf->addEmailRedirectFilter($foreign); - $cond[] = XDB::format('e' . $sub . '.email IS NOT NULL OR a.email IN {?}', $foreign); + $cond[] = XDB::format('ra' . $sub . '.redirect IS NOT NULL OR ra' . $sub . '.redirect IN {?} OR a.email IN {?}', $foreign, $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'; + if (count($local) > 0) { + $sub = $uf->addAliasFilter($local); + $cond[] = 'sa' . $sub . '.email IS NOT NULL'; } return '(' . implode(') OR (', $cond) . ')'; } } // }}} - // {{{ class UFC_Address abstract class UFC_Address extends UserFilterCondition { - /** Valid address type ('hq' is reserved for company addresses) + /** Valid address type */ - const TYPE_HOME = 1; - const TYPE_PRO = 2; - const TYPE_ANY = 3; + const TYPE_HOME = 1; + const TYPE_PRO = 2; + const TYPE_NON_HQ = 3; + const TYPE_HQ = 4; + const TYPE_ANY = 7; /** Text for these types */ protected static $typetexts = array( self::TYPE_HOME => 'home', self::TYPE_PRO => 'pro', + self::TYPE_HQ => 'hq', ); protected $type; @@ -779,13 +1056,13 @@ abstract class UFC_Address extends UserFilterCondition } } if (count($types)) { - $conds[] = XDB::format($sub . '.type IN {?}', $types); + $conds[] = XDB::format('pa' . $sub . '.type IN {?}', $types); } if ($this->flags != self::FLAG_ANY) { foreach(self::$flagtexts as $flag => $text) { if ($flag & $this->flags) { - $conds[] = 'FIND_IN_SET(' . XDB::format('{?}', $text) . ', ' . $sub . '.flags)'; + $conds[] = 'FIND_IN_SET(' . XDB::format('{?}', $text) . ', pa' . $sub . '.flags)'; } } } @@ -794,63 +1071,6 @@ abstract class UFC_Address extends UserFilterCondition } // }}} - -// {{{ class UFC_AddressText -/** Select users based on their address, using full text search - * @param $text Text for filter in fulltext search - * @param $textSearchMode Mode for search (one of XDB::WILDCARD_*) - * @param $type Filter on address type - * @param $flags Filter on address flags - * @param $country Filter on address country - * @param $locality Filter on address locality - */ -class UFC_AddressText extends UFC_Address -{ - - private $text; - private $textSearchMode; - - public function __construct($text = null, $textSearchMode = XDB::WILDCARD_CONTAINS, - $type = null, $flags = self::FLAG_ANY, $country = null, $locality = null) - { - parent::__construct($type, $flags); - $this->text = $text; - $this->textSearchMode = $textSearchMode; - $this->country = $country; - $this->locality = $locality; - } - - private function mkMatch($txt) - { - return XDB::formatWildcards($this->textSearchMode, $txt); - } - - public function buildCondition(PlFilter $uf) - { - $sub = $uf->addAddressFilter(); - $conds = $this->initConds($sub, $uf->getVisibilityCondition($sub . '.pub')); - if ($this->text != null) { - $conds[] = $sub . '.text' . $this->mkMatch($this->text); - } - - if ($this->country != null) { - $subc = $uf->addAddressCountryFilter(); - $subconds = array(); - $subconds[] = $subc . '.country' . $this->mkMatch($this->country); - $subconds[] = $subc . '.countryFR' . $this->mkMatch($this->country); - $conds[] = implode(' OR ', $subconds); - } - - if ($this->locality != null) { - $subl = $uf->addAddressLocalityFilter(); - $conds[] = $subl . '.name' . $this->mkMatch($this->locality); - } - - return implode(' AND ', $conds); - } -} -// }}} - // {{{ class UFC_AddressField /** Filters users based on their address, * @param $val Either a code for one of the fields, or an array of such codes @@ -858,61 +1078,41 @@ class UFC_AddressText extends UFC_Address * @param $type Filter on address type * @param $flags Filter on address flags */ -class UFC_AddressField extends UFC_Address +class UFC_AddressComponent extends UFC_Address { - const FIELD_COUNTRY = 1; - const FIELD_ADMAREA = 2; - const FIELD_SUBADMAREA = 3; - const FIELD_LOCALITY = 4; - const FIELD_ZIPCODE = 5; + static $components = array('postal_code', 'locality', 'administrative_area_level_3', 'administrative_area_level_2', 'administrative_area_level_1', 'country'); /** Data of the filter */ private $val; private $fieldtype; + private $exact; - public function __construct($val, $fieldtype, $type = null, $flags = self::FLAG_ANY) + public function __construct($val, $fieldtype, $exact = true, $type = null, $flags = self::FLAG_ANY) { - parent::__construct($type, $flags); + if (!in_array($fieldtype, self::$components)) { + Platal::page()->killError('Invalid address field type: ' . $this->fieldtype); + } + parent::__construct($type, $flags); if (!is_array($val)) { $val = array($val); } $this->val = $val; $this->fieldtype = $fieldtype; + $this->exact = $exact; } public function buildCondition(PlFilter $uf) { - $sub = $uf->addAddressFilter(); - $conds = $this->initConds($sub, $uf->getVisibilityCondition($sub . '.pub')); - - switch ($this->fieldtype) { - case self::FIELD_COUNTRY: - $field = 'countryId'; - break; - case self::FIELD_ADMAREA: - $field = 'administrativeAreaId'; - break; - case self::FIELD_SUBADMAREA: - $field = 'subAdministrativeAreaId'; - break; - case self::FIELD_LOCALITY: - $field = 'localityId'; - break; - case self::FIELD_ZIPCODE: - $field = 'postalCode'; - break; - default: - Platal::page()->killError('Invalid address field type: ' . $this->fieldtype); - } - $conds[] = XDB::format($sub . '.' . $field . ' IN {?}', $this->val); + $sub = $uf->addAddressFilter($this->fieldtype); + $conds = $this->initConds($sub, $uf->getVisibilityCondition('pa' . $sub . '.pub')); + $conds[] = XDB::format('pace' . $sub . '.id IN {?}', $this->val); return implode(' AND ', $conds); } } // }}} - // {{{ class UFC_Corps /** Filters users based on the corps they belong to * @param $corps Corps we are looking for (abbreviation) @@ -924,11 +1124,13 @@ class UFC_Corps extends UserFilterCondition const ORIGIN = 2; private $corps; + private $id; private $type; - public function __construct($corps, $type = self::CURRENT) + public function __construct($corps, $id = null, $type = self::CURRENT) { $this->corps = $corps; + $this->id = $id; $this->type = $type; } @@ -940,13 +1142,18 @@ class UFC_Corps extends UserFilterCondition * pcec for profile_corps_enum - current */ $sub = $uf->addCorpsFilter($this->type); - $cond = $sub . '.abbreviation = ' . $corps; - $cond .= ' AND ' . $uf->getVisibilityCondition($sub . '.corps_pub'); + if (is_null($this->id)) { + $cond = $sub . '.abbreviation = ' . $this->corps; + } else { + $cond = $sub . '.id = ' . $this->id; + } + // XXX(x2006barrois): find a way to get rid of that hardcoded + // reference to 'pc'. + $cond .= ' AND ' . $uf->getVisibilityCondition('pc.corps_pub'); return $cond; } } // }}} - // {{{ class UFC_Corps_Rank /** Filters users based on their rank in the corps * @param $rank Rank we are looking for (abbreviation) @@ -954,9 +1161,12 @@ class UFC_Corps extends UserFilterCondition class UFC_Corps_Rank extends UserFilterCondition { private $rank; - public function __construct($rank) + private $id; + + public function __construct($rank, $id = null) { $this->rank = $rank; + $this->id = $id; } public function buildCondition(PlFilter $uf) @@ -966,7 +1176,11 @@ class UFC_Corps_Rank extends UserFilterCondition * pcr for profile_corps_rank */ $sub = $uf->addCorpsRankFilter(); - $cond = $sub . '.abbreviation = ' . $rank; + if (is_null($this->id)) { + $cond = $sub . '.abbreviation = ' . $this->rank; + } else { + $cond = $sub . '.id = ' . $this->id; + } // XXX(x2006barrois): find a way to get rid of that hardcoded // reference to 'pc'. $cond .= ' AND ' . $uf->getVisibilityCondition('pc.corps_pub'); @@ -974,7 +1188,6 @@ class UFC_Corps_Rank extends UserFilterCondition } } // }}} - // {{{ class UFC_Job_Company /** Filters users based on the company they belong to * @param $type The field being searched (self::JOBID, self::JOBNAME or self::JOBACRONYM) @@ -1013,7 +1226,6 @@ class UFC_Job_Company extends UserFilterCondition } } // }}} - // {{{ class UFC_Job_Terms /** Filters users based on the job terms they assigned to one of their * jobs. @@ -1044,7 +1256,6 @@ class UFC_Job_Terms extends UserFilterCondition } } // }}} - // {{{ class UFC_Job_Description /** Filters users based on their job description * @param $description The text being searched for @@ -1071,12 +1282,9 @@ class UFC_Job_Description extends UserFilterCondition // don't do anything. Otherwise restrict to standard job visibility. if ($this->fields == UserFilter::JOB_CV) { if ($uf->getVisibilityLevel() != ProfileVisibility::VIS_PRIVATE) { - return self::CONF_TRUE; + return self::COND_TRUE; } - } else { - $conds[] = $uf->getVisibilityCondition($jsub . '.pub'); } - if ($this->fields & UserFilter::JOB_USERDEFINED) { $conds[] = $jsub . '.description ' . XDB::formatWildcards(XDB::WILDCARD_CONTAINS, $this->description); } @@ -1084,11 +1292,13 @@ class UFC_Job_Description extends UserFilterCondition $uf->requireProfiles(); $conds[] = 'p.cv ' . XDB::formatWildcards(XDB::WILDCARD_CONTAINS, $this->description); } - return implode(' OR ', $conds); + if (count($conds) == 0) { + return self::COND_TRUE; + } + return $uf->getVisibilityCondition($jsub . '.pub') . ' AND ( ' . implode(' OR ', $conds) . ' )'; } } // }}} - // {{{ class UFC_Networking /** Filters users based on network identity (IRC, ...) * @param $type Type of network (-1 for any) @@ -1118,7 +1328,6 @@ class UFC_Networking extends UserFilterCondition } } // }}} - // {{{ class UFC_Phone /** Filters users based on their phone number * @param $num_type Type of number (pro/user/home) @@ -1145,7 +1354,7 @@ class UFC_Phone extends UserFilterCondition { $phone = new Phone(array('display' => $number)); $phone->format(); - $this->number = $phone->search(); + $this->number = $phone->search; $this->num_type = $num_type; $this->phone_type = $phone_type; } @@ -1168,7 +1377,6 @@ class UFC_Phone extends UserFilterCondition } } // }}} - // {{{ class UFC_Medal /** Filters users based on their medals * @param $medal ID of the medal @@ -1202,7 +1410,6 @@ class UFC_Medal extends UserFilterCondition } } // }}} - // {{{ class UFC_Photo /** Filters profiles with photo */ @@ -1215,7 +1422,6 @@ class UFC_Photo extends UserFilterCondition } } // }}} - // {{{ class UFC_Mentor class UFC_Mentor extends UserFilterCondition { @@ -1226,8 +1432,6 @@ class UFC_Mentor extends UserFilterCondition } } // }}} - - // {{{ class UFC_Mentor_Expertise /** Filters users by mentoring expertise * @param $expertise Domain of expertise @@ -1248,7 +1452,6 @@ class UFC_Mentor_Expertise extends UserFilterCondition } } // }}} - // {{{ class UFC_Mentor_Country /** Filters users by mentoring country * @param $country Two-letters code of country being searched @@ -1269,7 +1472,6 @@ class UFC_Mentor_Country extends UserFilterCondition } } // }}} - // {{{ class UFC_Mentor_Terms /** Filters users based on the job terms they used in mentoring. * @param $val The ID of the job term, or an array of such IDs @@ -1290,7 +1492,6 @@ class UFC_Mentor_Terms extends UserFilterCondition } } // }}} - // {{{ class UFC_UserRelated /** Filters users based on a relation toward a user * @param $user User to which searched users are related @@ -1298,13 +1499,42 @@ class UFC_Mentor_Terms extends UserFilterCondition abstract class UFC_UserRelated extends UserFilterCondition { protected $user; - public function __construct(PlUser &$user) + public function __construct(PlUser $user) { $this->user =& $user; } } // }}} +// {{{ class UFC_DeltaTen +class UFC_DeltaTen extends UserFilterCondition +{ + public function buildCondition(PlFilter $uf) + { + $sub = $uf->addDeltaTenFilter(UserFilter::DELTATEN); + return $sub . '.message IS NOT NULL'; + } +} +// }}} +// {{{ class UFC_DeltaTen_Message +/** Filters users by deltaten message + * @param $message Message for the DeltaTen program + */ +class UFC_DeltaTen_Message extends UserFilterCondition +{ + private $message; + public function __construct($message) + { + $this->message = $message; + } + + public function buildCondition(PlFilter $uf) + { + $sub = $uf->addDeltaTenFilter(UserFilter::DELTATEN_MESSAGE); + return $sub . '.message ' . XDB::formatWildcards(XDB::WILDCARD_CONTAINS, $this->message); + } +} +// }}} // {{{ class UFC_Contact /** Filters users who belong to selected user's contacts */ @@ -1317,7 +1547,6 @@ class UFC_Contact extends UFC_UserRelated } } // }}} - // {{{ class UFC_WatchRegistration /** Filters users being watched by selected user */ @@ -1337,7 +1566,6 @@ class UFC_WatchRegistration extends UFC_UserRelated } } // }}} - // {{{ class UFC_WatchPromo /** Filters users belonging to a promo watched by selected user * @param $user Selected user (the one watching promo) @@ -1346,7 +1574,7 @@ class UFC_WatchRegistration extends UFC_UserRelated class UFC_WatchPromo extends UFC_UserRelated { private $grade; - public function __construct(PlUser &$user, $grade = UserFilter::GRADE_ING) + public function __construct(PlUser $user, $grade = UserFilter::GRADE_ING) { parent::__construct($user); $this->grade = $grade; @@ -1365,7 +1593,6 @@ class UFC_WatchPromo extends UFC_UserRelated } } // }}} - // {{{ class UFC_WatchContact /** Filters users watched by selected user */ @@ -1380,7 +1607,6 @@ class UFC_WatchContact extends UFC_Contact } } // }}} - // {{{ class UFC_MarketingHash /** Filters users using the hash generated * to send marketing emails to him.