X-Git-Url: http://git.polytechnique.org/?a=blobdiff_plain;ds=sidebyside;f=classes%2Fuserfilter.php;h=26241f3e377063b63bee7cbf76a7aaaa71465fea;hb=19be891efcb710b3c19c1fe1fc937c7f3c69de47;hp=becf26b4b396ffc3b3da61b0e1bc33ee7433e652;hpb=aab2ffddfc8597dfce114b18c737b791e949b6ea;p=platal.git diff --git a/classes/userfilter.php b/classes/userfilter.php index becf26b..26241f3 100644 --- a/classes/userfilter.php +++ b/classes/userfilter.php @@ -52,6 +52,25 @@ class UFC_HasProfile implements UserFilterCondition } // }}} +// {{{ class UFC_AccountType +/** Filters users who have the given account types + */ +class UFC_AccountType implements UserFilterCondition +{ + private $types; + + public function __construct() + { + $this->types = pl_flatten(func_get_args()); + } + + public function buildCondition(PlFilter &$uf) + { + $uf->requireAccounts(); + return XDB::format('a.type IN {?}', $this->types); + } +} + // {{{ class UFC_Hruid /** Filters users based on their hruid * @param $val Either an hruid, or a list of those @@ -129,7 +148,7 @@ class UFC_Comment implements UserFilterCondition public function buildCondition(PlFilter &$uf) { $uf->requireProfiles(); - return 'p.freetext ' . XDB::formatWildcards(XDB::WILDCARD_CONTAINS, $this->text); + return $uf->getVisibilityCondition('p.freetext_pub') . ' AND p.freetext ' . XDB::formatWildcards(XDB::WILDCARD_CONTAINS, $this->text); } } // }}} @@ -557,6 +576,10 @@ class UFC_Group implements UserFilterCondition public function buildCondition(PlFilter &$uf) { + // Groups have AX visibility. + if ($uf->getVisibilityLevel() == ProfileVisibility::VIS_PUBLIC) { + return PlFilter::COND_TRUE; + } $sub = $uf->addGroupFilter($this->group); $where = 'gpm' . $sub . '.perms IS NOT NULL'; if ($this->anim) { @@ -582,6 +605,10 @@ class UFC_Binet implements UserFilterCondition public function buildCondition(PlFilter &$uf) { + // Binets are private. + if ($uf->getVisibilityLevel() != ProfileVisibility::VIS_PRIVATE) { + return PlFilter::COND_TRUE; + } $sub = $uf->addBinetsFilter(); return XDB::format($sub . '.binet_id IN {?}', $this->val); } @@ -603,6 +630,10 @@ class UFC_Section implements UserFilterCondition public function buildCondition(PlFilter &$uf) { + // Sections are private. + if ($uf->getVisibilityLevel() != ProfileVisibility::VIS_PRIVATE) { + return PlFilter::COND_TRUE; + } $uf->requireProfiles(); return XDB::format('p.section IN {?}', $this->section); } @@ -707,9 +738,10 @@ abstract class UFC_Address implements UserFilterCondition $this->flags = $flags; } - protected function initConds($sub) + protected function initConds($sub, $vis_cond) { - $conds = array(); + $conds = array($vis_cond); + $types = array(); foreach (self::$typetexts as $flag => $type) { if ($flag & $this->type) { @@ -766,7 +798,7 @@ class UFC_AddressText extends UFC_Address public function buildCondition(PlFilter &$uf) { $sub = $uf->addAddressFilter(); - $conds = $this->initConds($sub); + $conds = $this->initConds($sub, $uf->getVisibilityCondition($sub . '.pub')); if ($this->text != null) { $conds[] = $sub . '.text' . $this->mkMatch($this->text); } @@ -823,7 +855,7 @@ class UFC_AddressField extends UFC_Address public function buildCondition(PlFilter &$uf) { $sub = $uf->addAddressFilter(); - $conds = $this->initConds($sub); + $conds = $this->initConds($sub, $uf->getVisibilityCondition($sub . '.pub')); switch ($this->fieldtype) { case self::FIELD_COUNTRY: @@ -879,6 +911,7 @@ class UFC_Corps implements UserFilterCondition */ $sub = $uf->addCorpsFilter($this->type); $cond = $sub . '.abbreviation = ' . $corps; + $cond .= ' AND ' . $uf->getVisibilityCondition($sub . '.corps_pub'); return $cond; } } @@ -899,10 +932,14 @@ class UFC_Corps_Rank implements UserFilterCondition public function buildCondition(PlFilter &$uf) { /** Tables shortcuts: + * pc for profile_corps * pcr for profile_corps_rank */ $sub = $uf->addCorpsRankFilter(); $cond = $sub . '.abbreviation = ' . $rank; + // XXX(x2006barrois): find a way to get rid of that hardcoded + // reference to 'pc'. + $cond .= ' AND ' . $uf->getVisibilityCondition('pc.corps_pub'); return $cond; } } @@ -940,42 +977,40 @@ class UFC_Job_Company implements UserFilterCondition { $sub = $uf->addJobCompanyFilter(); $cond = $sub . '.' . $this->type . XDB::formatWildcards(XDB::WILDCARD_CONTAINS, $this->value); + $jsub = $uf->addJobFilter(); + $cond .= ' AND ' . $uf->getVisibilityCondition($jsub . '.pub'); return $cond; } } // }}} -// {{{ class UFC_Job_Sectorization -/** Filters users based on the ((sub)sub)sector they work in - * @param $val The ID of the sector, or an array of such IDs - * @param $type The kind of search (subsubsector/subsector/sector) +// {{{ class UFC_Job_Terms +/** Filters users based on the job terms they assigned to one of their + * jobs. + * @param $val The ID of the job term, or an array of such IDs */ -class UFC_Job_Sectorization implements UserFilterCondition +class UFC_Job_Terms implements UserFilterCondition { private $val; - private $type; - public function __construct($val, $type = UserFilter::JOB_SECTOR) + public function __construct($val) { - self::assertType($type); if (!is_array($val)) { $val = array($val); } $this->val = $val; - $this->type = $type; - } - - private static function assertType($type) - { - if ($type != UserFilter::JOB_SECTOR && $type != UserFilter::JOB_SUBSECTOR && $type != UserFilter::JOB_SUBSUBSECTOR) { - Platal::page()->killError("Type de secteur non valide."); - } } public function buildCondition(PlFilter &$uf) { - $sub = $uf->addJobSectorizationFilter($this->type); - return $sub . '.id = ' . XDB::format('{?}', $this->val); + $sub = $uf->addJobTermsFilter(count($this->val)); + $conditions = array(); + foreach ($this->val as $i => $jtid) { + $conditions[] = $sub[$i] . '.jtid_1 = ' . XDB::escape($jtid); + } + $jsub = $uf->addJobFilter(); + $conditions[] = $uf->getVisibilityCondition($jsub . '.pub'); + return implode(' AND ', $conditions); } } // }}} @@ -983,7 +1018,7 @@ class UFC_Job_Sectorization implements UserFilterCondition // {{{ class UFC_Job_Description /** Filters users based on their job description * @param $description The text being searched for - * @param $fields The fields to search for (user-defined, ((sub|)sub|)sector) + * @param $fields The fields to search for (CV, user-defined) */ class UFC_Job_Description implements UserFilterCondition { @@ -1000,28 +1035,25 @@ class UFC_Job_Description implements UserFilterCondition public function buildCondition(PlFilter &$uf) { $conds = array(); + + $jsub = $uf->addJobFilter(); + // CV is private => if only CV requested, and not private, + // don't do anything. Otherwise restrict to standard job visibility. + if ($this->fields == UserFilter::JOB_CV) { + if ($uf->getVisibilityLevel() != ProfileVisibility::VIS_PRIVATE) { + return PlFilter::COND_TRUE; + } + } else { + $conds[] = $uf->getVisibilityCondition($jsub . '.pub'); + } + if ($this->fields & UserFilter::JOB_USERDEFINED) { - $sub = $uf->addJobFilter(); - $conds[] = $sub . '.description ' . XDB::formatWildcards(XDB::WILDCARD_CONTAINS, $this->description); + $conds[] = $jsub . '.description ' . XDB::formatWildcards(XDB::WILDCARD_CONTAINS, $this->description); } - if ($this->fields & UserFilter::JOB_CV) { + if ($this->fields & UserFilter::JOB_CV && $uf->getVisibilityLevel == ProfileVisibility::VIS_PRIVATE) { $uf->requireProfiles(); $conds[] = 'p.cv ' . XDB::formatWildcards(XDB::WILDCARD_CONTAINS, $this->description); } - if ($this->fields & UserFilter::JOB_SECTOR) { - $sub = $uf->addJobSectorizationFilter(UserFilter::JOB_SECTOR); - $conds[] = $sub . '.name ' . XDB::formatWildcards(XDB::WILDCARD_CONTAINS, $this->description); - } - if ($this->fields & UserFilter::JOB_SUBSECTOR) { - $sub = $uf->addJobSectorizationFilter(UserFilter::JOB_SUBSECTOR); - $conds[] = $sub . '.name ' . XDB::formatWildcards(XDB::WILDCARD_CONTAINS, $this->description); - } - if ($this->fields & UserFilter::JOB_SUBSUBSECTOR) { - $sub = $uf->addJobSectorizationFilter(UserFilter::JOB_SUBSUBSECTOR); - $conds[] = $sub . '.name ' . XDB::formatWildcards(XDB::WILDCARD_CONTAINS, $this->description); - $sub = $uf->addJobSectorizationFilter(UserFilter::JOB_ALTERNATES); - $conds[] = $sub . '.name ' . XDB::formatWildcards(XDB::WILDCARD_CONTAINS, $this->description); - } return implode(' OR ', $conds); } } @@ -1047,6 +1079,7 @@ class UFC_Networking implements UserFilterCondition { $sub = $uf->addNetworkingFilter(); $conds = array(); + $conds[] = $uf->getVisibilityCondition($sub . '.pub'); $conds[] = $sub . '.address ' . XDB::formatWildcards(XDB::WILDCARD_CONTAINS, $this->value); if ($this->type != -1) { $conds[] = $sub . '.nwid = ' . XDB::format('{?}', $this->type); @@ -1080,16 +1113,20 @@ class UFC_Phone implements UserFilterCondition public function __construct($number, $num_type = self::NUM_ANY, $phone_type = self::PHONE_ANY) { - require_once('profil.func.inc.php'); - $this->number = $number; + $phone = new Phone(array('display' => $number)); + $phone->format(); + $this->number = $phone->search(); $this->num_type = $num_type; - $this->phone_type = format_phone_number($phone_type); + $this->phone_type = $phone_type; } public function buildCondition(PlFilter &$uf) { $sub = $uf->addPhoneFilter(); $conds = array(); + + $conds[] = $uf->getVisibilityCondition($sub . '.pub'); + $conds[] = $sub . '.search_tel = ' . XDB::format('{?}', $this->number); if ($this->num_type != self::NUM_ANY) { $conds[] = $sub . '.link_type = ' . XDB::format('{?}', $this->num_type); @@ -1121,7 +1158,12 @@ class UFC_Medal implements UserFilterCondition public function buildCondition(PlFilter &$uf) { $conds = array(); + + // This will require profiles => table 'p' will be available. $sub = $uf->addMedalFilter(); + + $conds[] = $uf->getVisibilityCondition('p.medals_pub'); + $conds[] = $sub . '.mid = ' . XDB::format('{?}', $this->medal); if ($this->grade != null) { $conds[] = $sub . '.gid = ' . XDB::format('{?}', $this->grade); @@ -1138,12 +1180,24 @@ class UFC_Photo implements UserFilterCondition { public function buildCondition(PlFilter &$uf) { - $uf->addPhotoFilter(); - return 'photo.attach IS NOT NULL'; + $sub = $uf->addPhotoFilter(); + return $sub . '.attach IS NOT NULL AND ' . $uf->getVisibilityCondition($sub . '.pub'); } } // }}} +// {{{ class UFC_Mentor +class UFC_Mentor implements UserFilterCondition +{ + public function buildCondition(PlFilter &$uf) + { + $sub = $uf->addMentorFilter(UserFilter::MENTOR); + return $sub . '.expertise IS NOT NULL'; + } +} +// }}} + + // {{{ class UFC_Mentor_Expertise /** Filters users by mentoring expertise * @param $expertise Domain of expertise @@ -1186,33 +1240,23 @@ class UFC_Mentor_Country implements UserFilterCondition } // }}} -// {{{ class UFC_Mentor_Sectorization -/** Filters users based on mentoring (sub|)sector - * @param $sector ID of (sub)sector - * @param $type Whether we are looking for a sector or a subsector +// {{{ 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 */ -class UFC_Mentor_Sectorization implements UserFilterCondition +class UFC_Mentor_Terms implements UserFilterCondition { - const SECTOR = 1; - const SUBSECTOR = 2; - private $sector; - private $type; + private $val; - public function __construct($sector, $type = self::SECTOR) + public function __construct($val) { - $this->sector = $sector; - $this->type = $type; + $this->val = $val; } public function buildCondition(PlFilter &$uf) { - $sub = $uf->addMentorFilter(UserFilter::MENTOR_SECTOR); - if ($this->type == self::SECTOR) { - $field = 'sectorid'; - } else { - $field = 'subsectorid'; - } - return $sub . '.' . $field . ' = ' . XDB::format('{?}', $this->sector); + $sub = $uf->addMentorFilter(UserFilter::MENTOR_TERM); + return $sub . '.jtid_1 = ' . XDB::escape($this->val); } } // }}} @@ -1332,28 +1376,12 @@ class UFC_MarketingHash implements UserFilterCondition * ORDERS ******************/ -// {{{ class UserFilterOrder -/** Base class for ordering results of a query. - * Parameters for the ordering must be given to the constructor ($desc for a - * descending order). - * The getSortTokens function is used to get actual ordering part of the query. - */ -abstract class UserFilterOrder extends PlFilterOrder -{ - /** This function must return the tokens to use for ordering - * @param &$uf The UserFilter whose results must be ordered - * @return The name of the field to use for ordering results - */ -// abstract protected function getSortTokens(UserFilter &$uf); -} -// }}} - // {{{ class UFO_Promo /** Orders users by promotion * @param $grade Formation whose promotion users should be sorted by (restricts results to users of that formation) * @param $desc Whether sort is descending */ -class UFO_Promo extends UserFilterOrder +class UFO_Promo extends PlFilterGroupableOrder { private $grade; @@ -1383,7 +1411,7 @@ class UFO_Promo extends UserFilterOrder * @param $particle Set to true if particles should be included in the sorting order * @param $desc If sort order should be descending */ -class UFO_Name extends UserFilterOrder +class UFO_Name extends PlFilterOrder { private $type; private $variant; @@ -1421,7 +1449,7 @@ class UFO_Name extends UserFilterOrder // }}} // {{{ class UFO_Score -class UFO_Score extends UserFilterOrder +class UFO_Score extends PlFilterOrder { protected function getSortTokens(PlFilter &$uf) { @@ -1444,7 +1472,7 @@ class UFO_Score extends UserFilterOrder // {{{ class UFO_Registration /** Sorts users based on registration date */ -class UFO_Registration extends UserFilterOrder +class UFO_Registration extends PlFilterOrder { protected function getSortTokens(PlFilter &$uf) { @@ -1457,7 +1485,7 @@ class UFO_Registration extends UserFilterOrder // {{{ class UFO_Birthday /** Sorts users based on next birthday date */ -class UFO_Birthday extends UserFilterOrder +class UFO_Birthday extends PlFilterOrder { protected function getSortTokens(PlFilter &$uf) { @@ -1470,7 +1498,7 @@ class UFO_Birthday extends UserFilterOrder // {{{ class UFO_ProfileUpdate /** Sorts users based on last profile update */ -class UFO_ProfileUpdate extends UserFilterOrder +class UFO_ProfileUpdate extends PlFilterOrder { protected function getSortTokens(PlFilter &$uf) { @@ -1483,7 +1511,7 @@ class UFO_ProfileUpdate extends UserFilterOrder // {{{ class UFO_Death /** Sorts users based on death date */ -class UFO_Death extends UserFilterOrder +class UFO_Death extends PlFilterOrder { protected function getSortTokens(PlFilter &$uf) { @@ -1496,7 +1524,7 @@ class UFO_Death extends UserFilterOrder // {{{ class UFO_Uid /** Sorts users based on their uid */ -class UFO_Uid extends UserFilterOrder +class UFO_Uid extends PlFilterOrder { protected function getSortTokens(PlFilter &$uf) { @@ -1509,7 +1537,7 @@ class UFO_Uid extends UserFilterOrder // {{{ class UFO_Hruid /** Sorts users based on their hruid */ -class UFO_Hruid extends UserFilterOrder +class UFO_Hruid extends PlFilterOrder { protected function getSortTokens(PlFilter &$uf) { @@ -1522,7 +1550,7 @@ class UFO_Hruid extends UserFilterOrder // {{{ class UFO_Pid /** Sorts users based on their pid */ -class UFO_Pid extends UserFilterOrder +class UFO_Pid extends PlFilterOrder { protected function getSortTokens(PlFilter &$uf) { @@ -1535,7 +1563,7 @@ class UFO_Pid extends UserFilterOrder // {{{ class UFO_Hrpid /** Sorts users based on their hrpid */ -class UFO_Hrpid extends UserFilterOrder +class UFO_Hrpid extends PlFilterOrder { protected function getSortTokens(PlFilter &$uf) { @@ -1604,9 +1632,13 @@ class UserFilter extends PlFilter private $root; private $sort = array(); + private $grouper = null; private $query = null; private $orderby = null; + // Store the current 'search' visibility. + private $profile_visibility = null; + private $lastusercount = null; private $lastprofilecount = null; @@ -1627,7 +1659,7 @@ class UserFilter extends PlFilter } } if (!is_null($sort)) { - if ($sort instanceof UserFilterOrder) { + if ($sort instanceof PlFilterOrder) { $this->addSort($sort); } else if (is_array($sort)) { foreach ($sort as $s) { @@ -1635,6 +1667,29 @@ class UserFilter extends PlFilter } } } + + // This will set the visibility to the default correct level. + $this->profile_visibility = new ProfileVisibility(); + } + + public function getVisibilityLevels() + { + return $this->profile_visibility->levels(); + } + + public function getVisibilityLevel() + { + return $this->profile_visibility->level(); + } + + public function restrictVisibilityTo($level) + { + $this->profile_visibility->setLevel($level); + } + + public function getVisibilityCondition($field) + { + return $field . ' IN ' . XDB::formatArray($this->getVisibilityLevels()); } private function buildQuery() @@ -1675,6 +1730,42 @@ class UserFilter extends PlFilter } } + public function hasGroups() + { + return $this->grouper != null; + } + + public function getGroups() + { + return $this->getUIDGroups(); + } + + public function getUIDGroups() + { + $this->requireAccounts(); + $this->buildQuery(); + $token = $this->grouper->getGroupToken($this); + + $groups = XDB::fetchAllRow('SELECT ' . $token . ', COUNT(a.uid) + ' . $this->query . ' + GROUP BY ' . $token, + 0); + return $groups; + } + + public function getPIDGroups() + { + $this->requireProfiles(); + $this->buildQuery(); + $token = $this->grouper->getGroupToken($this); + + $groups = XDB::fetchAllRow('SELECT ' . $token . ', COUNT(p.pid) + ' . $this->query . ' + GROUP BY ' . $token, + 0); + return $groups; + } + private function getUIDList($uids = null, PlLimit &$limit) { $this->requireAccounts(); @@ -1915,6 +2006,10 @@ class UserFilter extends PlFilter public function addSort(PlFilterOrder &$sort) { + if (count($this->sort) == 0 && $sort instanceof PlFilterGroupableOrder) + { + $this->grouper = $sort; + } $this->sort[] = $sort; $this->orderby = null; } @@ -2430,30 +2525,18 @@ class UserFilter extends PlFilter /** JOBS */ - const JOB_SECTOR = 0x0001; - const JOB_SUBSECTOR = 0x0002; - const JOB_SUBSUBSECTOR = 0x0004; - const JOB_ALTERNATES = 0x0008; - const JOB_USERDEFINED = 0x0010; - const JOB_CV = 0x0020; - - const JOB_SECTORIZATION = 0x000F; - const JOB_ANY = 0x003F; + const JOB_USERDEFINED = 0x0001; + const JOB_CV = 0x0002; + const JOB_ANY = 0x0003; /** Joins : * pj => profile_job * pje => profile_job_enum - * pjse => profile_job_sector_enum - * pjsse => profile_job_subsector_enum - * pjssse => profile_job_subsubsector_enum - * pja => profile_job_alternates + * pjt => profile_job_terms */ - private $with_pj = false; + private $with_pj = false; private $with_pje = false; - private $with_pjse = false; - private $with_pjsse = false; - private $with_pjssse = false; - private $with_pja = false; + private $with_pjt = 0; public function addJobFilter() { @@ -2469,22 +2552,19 @@ class UserFilter extends PlFilter return 'pje'; } - public function addJobSectorizationFilter($type) + /** + * Adds a filter on job terms of profile. + * @param $nb the number of job terms to use + * @return an array of the fields to filter (one for each term). + */ + public function addJobTermsFilter($nb = 1) { - $this->addJobFilter(); - if ($type == self::JOB_SECTOR) { - $this->with_pjse = true; - return 'pjse'; - } else if ($type == self::JOB_SUBSECTOR) { - $this->with_pjsse = true; - return 'pjsse'; - } else if ($type == self::JOB_SUBSUBSECTOR) { - $this->with_pjssse = true; - return 'pjssse'; - } else if ($type == self::JOB_ALTERNATES) { - $this->with_pja = true; - return 'pja'; + $this->with_pjt = $nb; + $jobtermstable = array(); + for ($i = 1; $i <= $nb; ++$i) { + $jobtermstable[] = 'pjtr_'.$i; } + return $jobtermstable; } protected function jobJoins() @@ -2496,17 +2576,11 @@ class UserFilter extends PlFilter if ($this->with_pje) { $joins['pje'] = PlSqlJoin::left('profile_job_enum', '$ME.id = pj.jobid'); } - if ($this->with_pjse) { - $joins['pjse'] = PlSqlJoin::left('profile_job_sector_enum', '$ME.id = pj.sectorid'); - } - if ($this->with_pjsse) { - $joins['pjsse'] = PlSqlJoin::left('profile_job_subsector_enum', '$ME.id = pj.subsectorid'); - } - if ($this->with_pjssse) { - $joins['pjssse'] = PlSqlJoin::left('profile_job_subsubsector_enum', '$ME.id = pj.subsubsectorid'); - } - if ($this->with_pja) { - $joins['pja'] = PlSqlJoin::left('profile_job_alternates', '$ME.subsubsectorid = pj.subsubsectorid'); + if ($this->with_pjt > 0) { + for ($i = 1; $i <= $this->with_pjt; ++$i) { + $joins['pjt_'.$i] = PlSqlJoin::left('profile_job_term', '$ME.pid = $PID'); + $joins['pjtr_'.$i] = PlSqlJoin::left('profile_job_term_relation', '$ME.jtid_2 = pjt_'.$i.'.jtid'); + } } return $joins; } @@ -2576,23 +2650,29 @@ class UserFilter extends PlFilter */ private $pms = array(); - const MENTOR_EXPERTISE = 1; - const MENTOR_COUNTRY = 2; - const MENTOR_SECTOR = 3; + private $mjtr = false; + const MENTOR = 1; + const MENTOR_EXPERTISE = 2; + const MENTOR_COUNTRY = 3; + const MENTOR_TERM = 4; public function addMentorFilter($type) { $this->requireAccounts(); switch($type) { + case self::MENTOR: + $this->pms['pm'] = 'profile_mentor'; + return 'pm'; case self::MENTOR_EXPERTISE: $this->pms['pme'] = 'profile_mentor'; return 'pme'; case self::MENTOR_COUNTRY: $this->pms['pmc'] = 'profile_mentor_country'; return 'pmc'; - case self::MENTOR_SECTOR: - $this->pms['pms'] = 'profile_mentor_sector'; - return 'pms'; + case self::MENTOR_TERM: + $this->pms['pmt'] = 'profile_mentor_term'; + $this->mjtr = true; + return 'mjtr'; default: Platal::page()->killError("Undefined mentor filter."); } @@ -2604,6 +2684,9 @@ class UserFilter extends PlFilter foreach ($this->pms as $sub => $tab) { $joins[$sub] = PlSqlJoin::left($tab, '$ME.pid = $PID'); } + if ($this->mjtr) { + $joins['mjtr'] = PlSqlJoin::left('profile_job_term_relation', '$ME.jtid_2 = pmt.jtid'); + } return $joins; } @@ -2695,6 +2778,7 @@ class UserFilter extends PlFilter { $this->requireProfiles(); $this->with_photo = true; + return 'photo'; } protected function photoJoins() @@ -2744,6 +2828,11 @@ class ProfileFilter extends UserFilter { return $this->getTotalProfileCount(); } + + public function getGroups() + { + return $this->getPIDGroups(); + } } // }}}