+
+
+ /** GROUPS
+ */
+ private $gpm = array();
+ public function addGroupFilter($group = null)
+ {
+ $this->requireAccounts();
+ if (!is_null($group)) {
+ if (is_int($group) || ctype_digit($group)) {
+ $index = $sub = $group;
+ } else {
+ $index = $group;
+ $sub = self::getDBSuffix($group);
+ }
+ } else {
+ $sub = 'group_' . $this->option++;
+ $index = null;
+ }
+ $sub = '_' . $sub;
+ $this->gpm[$sub] = $index;
+ return $sub;
+ }
+
+ private $gpfm = array();
+ public function addGroupFormerMemberFilter()
+ {
+ $this->requireAccounts();
+ $sub = '_' . $this->option++;
+ $this->gpfm[] = $sub;
+ return $sub;
+ }
+
+ protected function groupJoins()
+ {
+ $joins = array();
+ foreach ($this->gpm as $sub => $key) {
+ if (is_null($key)) {
+ $joins['gpa' . $sub] = PlSqlJoin::inner('groups');
+ $joins['gpm' . $sub] = PlSqlJoin::left('group_members', '$ME.uid = $UID AND $ME.asso_id = gpa' . $sub . '.id');
+ } else if (is_int($key) || ctype_digit($key)) {
+ $joins['gpm' . $sub] = PlSqlJoin::left('group_members', '$ME.uid = $UID AND $ME.asso_id = ' . $key);
+ } else {
+ $joins['gpa' . $sub] = PlSqlJoin::inner('groups', '$ME.diminutif = {?}', $key);
+ $joins['gpm' . $sub] = PlSqlJoin::left('group_members', '$ME.uid = $UID AND $ME.asso_id = gpa' . $sub . '.id');
+ }
+ }
+ foreach ($this->gpfm as $sub) {
+ $joins['gpfm' . $sub] = PlSqlJoin::left('group_former_members', '$ME.uid = $UID');
+ }
+ return $joins;
+ }
+
+ /** NLS
+ */
+ private $nls = array();
+ public function addNewsLetterFilter($nlid)
+ {
+ $this->requireAccounts();
+ $sub = 'nl_' . $nlid;
+ $this->nls[$nlid] = $sub;
+ return $sub;
+ }
+
+ protected function newsLetterJoins()
+ {
+ $joins = array();
+ foreach ($this->nls as $key => $sub) {
+ $joins[$sub] = PlSqlJoin::left('newsletter_ins', '$ME.nlid = {?} AND $ME.uid = $UID', $key);
+ }
+ return $joins;
+ }
+
+ /** BINETS
+ */
+
+ private $with_bi = false;
+ private $with_bd = false;
+ public function addBinetsFilter($with_enum = false)
+ {
+ $this->requireProfiles();
+ $this->with_bi = true;
+ if ($with_enum) {
+ $this->with_bd = true;
+ return 'bd';
+ } else {
+ return 'bi';
+ }
+ }
+
+ protected function binetsJoins()
+ {
+ $joins = array();
+ if ($this->with_bi) {
+ $joins['bi'] = PlSqlJoin::left('profile_binets', '$ME.pid = $PID');
+ }
+ if ($this->with_bd) {
+ $joins['bd'] = PlSqlJoin::left('profile_binet_enum', '$ME.id = bi.binet_id');
+ }
+ return $joins;
+ }
+
+ /** EMAILS
+ */
+ private $ra = array();
+ /** Allows filtering by redirection.
+ * @param $email If null, enable a left join on the email redirection table
+ * (email_redirect_account); otherwise, perform a left join on users having
+ * that email as a redirection.
+ * @return Suffix to use to access the adequate table.
+ */
+ public function addEmailRedirectFilter($email = null)
+ {
+ $this->requireAccounts();
+ return $this->register_optional($this->ra, $email);
+ }
+
+ const ALIAS_BEST = 'bestalias';
+ const ALIAS_FORLIFE = 'forlife';
+ const ALIAS_AUXILIARY = 'alias_aux';
+ private $sa = array();
+ /** Allows filtering by source email.
+ * @param $email If null, enable a left join on the email source table
+ * (email_source_account); otherwise, perform a left join on users having
+ * that email as a source email.
+ * @return Suffix to use to access the adequate table.
+ */
+ public function addAliasFilter($email = null)
+ {
+ $this->requireAccounts();
+ return $this->register_optional($this->sa, $email);
+ }
+
+ private $with_rf = false;
+ /** Allows filtering by active redirection.
+ * @return Suffix to use to access the adequate table.
+ */
+ public function addActiveEmailRedirectFilter($email = null)
+ {
+ $this->requireAccounts();
+ $this->with_rf = true;
+ }
+
+ protected function emailJoins()
+ {
+ global $globals;
+ $joins = array();
+ foreach ($this->ra as $sub => $redirections) {
+ if (is_null($redirections)) {
+ $joins['ra' . $sub] = PlSqlJoin::left('email_redirect_account', '$ME.uid = $UID AND $ME.type != \'imap\'');
+ } else {
+ if (!is_array($redirections)) {
+ $key = array($redirections);
+ }
+ $joins['ra' . $sub] = PlSqlJoin::left('email_redirect_account', '$ME.uid = $UID AND $ME.type != \'imap\'
+ AND $ME.redirect IN {?}', $redirections);
+ }
+ }
+ foreach ($this->sa as $sub => $emails) {
+ if (is_null($emails)) {
+ $joins['sa' . $sub] = PlSqlJoin::left('email_source_account', '$ME.uid = $UID');
+ } else if ($sub == self::ALIAS_BEST) {
+ $joins['sa' . $sub] = PlSqlJoin::left('email_source_account', '$ME.uid = $UID AND FIND_IN_SET(\'bestalias\', $ME.flags)');
+ } else if ($sub == self::ALIAS_FORLIFE) {
+ $joins['sa' . $sub] = PlSqlJoin::left('email_source_account', '$ME.uid = $UID AND $ME.type = \'forlife\'');
+ } else if ($sub == self::ALIAS_AUXILIARY) {
+ $joins['sa' . $sub] = PlSqlJoin::left('email_source_account', '$ME.uid = $UID AND $ME.type = \'alias_aux\'');
+ } else {
+ if (!is_array($emails)) {
+ $key = array($emails);
+ }
+ $joins['sa' . $sub] = PlSqlJoin::left('email_source_account', '$ME.uid = $UID AND $ME.email IN {?}', $emails);
+ }
+ }
+ if ($this->with_rf) {
+ $joins['rf'] = PlSqlJoin::left('email_redirect_account', '$ME.uid = $UID AND $ME.type != \'imap\' AND $ME.flags = \'active\'');;
+ }
+ return $joins;
+ }
+
+
+ /** ADDRESSES
+ */
+ private $types = array();
+ public function addAddressFilter($type)
+ {
+ $this->requireProfiles();
+ $this->with_pa = true;
+
+ $sub = '_' . $this->option++;
+ $this->types[$type] = $sub;
+ return $sub;
+ }
+
+ protected function addressJoins()
+ {
+ $joins = array();
+ foreach ($this->types as $type => $sub) {
+ $joins['pa' . $sub] = PlSqlJoin::inner('profile_addresses', '$ME.pid = $PID');
+ $joins['pac' . $sub] = PlSqlJoin::inner('profile_addresses_components',
+ '$ME.pid = pa' . $sub . '.pid AND $ME.jobid = pa' . $sub . '.jobid AND $ME.groupid = pa' . $sub . '.groupid AND $ME.type = pa' . $sub . '.type AND $ME.id = pa' . $sub . '.id');
+ $joins['pace' . $sub] = PlSqlJoin::inner('profile_addresses_components_enum',
+ '$ME.id = pac' . $sub . '.component_id AND FIND_IN_SET({?}, $ME.types)', $type);
+ }
+
+ return $joins;
+ }
+
+
+ /** CORPS
+ */
+
+ private $pc = false;
+ private $pce = array();
+ private $pcr = false;
+ public function addCorpsFilter($type)
+ {
+ $this->requireProfiles();
+ $this->pc = true;
+ if ($type == UFC_Corps::CURRENT) {
+ $this->pce['pcec'] = 'current_corpsid';
+ return 'pcec';
+ } else if ($type == UFC_Corps::ORIGIN) {
+ $this->pce['pceo'] = 'original_corpsid';
+ return 'pceo';
+ }
+ }
+
+ public function addCorpsRankFilter()
+ {
+ $this->requireProfiles();
+ $this->pc = true;
+ $this->pcr = true;
+ return 'pcr';
+ }
+
+ protected function corpsJoins()
+ {
+ $joins = array();
+ if ($this->pc) {
+ $joins['pc'] = PlSqlJoin::left('profile_corps', '$ME.pid = $PID');
+ }
+ if ($this->pcr) {
+ $joins['pcr'] = PlSqlJoin::left('profile_corps_rank_enum', '$ME.id = pc.rankid');
+ }
+ foreach($this->pce as $sub => $field) {
+ $joins[$sub] = PlSqlJoin::left('profile_corps_enum', '$ME.id = pc.' . $field);
+ }
+ return $joins;
+ }
+
+ /** JOBS
+ */
+
+ const JOB_USERDEFINED = 0x0001;
+ const JOB_CV = 0x0002;
+ const JOB_ANY = 0x0003;
+
+ /** Joins :
+ * pj => profile_job
+ * pje => profile_job_enum
+ * pjt => profile_job_terms
+ */
+ private $with_pj = false;
+ private $with_pje = false;
+ private $with_pjt = 0;
+
+ public function addJobFilter()
+ {
+ $this->requireProfiles();
+ $this->with_pj = true;
+ return 'pj';
+ }
+
+ public function addJobCompanyFilter()
+ {
+ $this->addJobFilter();
+ $this->with_pje = true;
+ return 'pje';
+ }
+
+ /**
+ * 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->with_pjt = $nb;
+ $jobtermstable = array();
+ for ($i = 1; $i <= $nb; ++$i) {
+ $jobtermstable[] = 'pjtr_'.$i;
+ }
+ return $jobtermstable;
+ }
+
+ protected function jobJoins()
+ {
+ $joins = array();
+ if ($this->with_pj) {
+ $joins['pj'] = PlSqlJoin::left('profile_job', '$ME.pid = $PID');
+ }
+ if ($this->with_pje) {
+ $joins['pje'] = PlSqlJoin::left('profile_job_enum', '$ME.id = pj.jobid');
+ }
+ 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;
+ }
+
+ /** NETWORKING
+ */
+
+ private $with_pnw = false;
+ public function addNetworkingFilter()
+ {
+ $this->requireAccounts();
+ $this->with_pnw = true;
+ return 'pnw';
+ }
+
+ protected function networkingJoins()
+ {
+ $joins = array();
+ if ($this->with_pnw) {
+ $joins['pnw'] = PlSqlJoin::left('profile_networking', '$ME.pid = $PID');
+ }
+ return $joins;
+ }
+
+ /** PHONE
+ */
+
+ private $with_ptel = false;
+
+ public function addPhoneFilter()
+ {
+ $this->requireAccounts();
+ $this->with_ptel = true;
+ return 'ptel';
+ }
+
+ protected function phoneJoins()
+ {
+ $joins = array();
+ if ($this->with_ptel) {
+ $joins['ptel'] = PlSqlJoin::left('profile_phones', '$ME.pid = $PID');
+ }
+ return $joins;
+ }
+
+ /** MEDALS
+ */
+
+ private $with_pmed = false;
+ public function addMedalFilter()
+ {
+ $this->requireProfiles();
+ $this->with_pmed = true;
+ return 'pmed';
+ }
+
+ protected function medalJoins()
+ {
+ $joins = array();
+ if ($this->with_pmed) {
+ $joins['pmed'] = PlSqlJoin::left('profile_medals', '$ME.pid = $PID');
+ }
+ return $joins;
+ }
+
+ /** DELTATEN
+ */
+ private $dts = array();
+ const DELTATEN = 1;
+ const DELTATEN_MESSAGE = 2;
+ // TODO: terms
+
+ public function addDeltaTenFilter($type)
+ {
+ $this->requireProfiles();
+ switch ($type) {
+ case self::DELTATEN:
+ $this->dts['pdt'] = 'profile_deltaten';
+ return 'pdt';
+ case self::DELTATEN_MESSAGE:
+ $this->dts['pdtm'] = 'profile_deltaten';
+ return 'pdtm';
+ default:
+ Platal::page()->killError("Undefined DeltaTen filter.");
+ }
+ }
+
+ protected function deltatenJoins()
+ {
+ $joins = array();
+ foreach ($this->dts as $sub => $tab) {
+ $joins[$sub] = PlSqlJoin::left($tab, '$ME.pid = $PID');
+ }
+ return $joins;
+ }
+
+ /** MENTORING
+ */
+
+ private $pms = array();
+ private $mjtr = false;
+ const MENTOR = 1;
+ const MENTOR_EXPERTISE = 2;
+ const MENTOR_COUNTRY = 3;
+ const MENTOR_TERM = 4;
+
+ public function addMentorFilter($type)
+ {
+ $this->requireProfiles();
+ 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_TERM:
+ $this->pms['pmt'] = 'profile_mentor_term';
+ $this->mjtr = true;
+ return 'mjtr';
+ default:
+ Platal::page()->killError("Undefined mentor filter.");
+ }
+ }
+
+ protected function mentorJoins()
+ {
+ $joins = array();
+ 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;
+ }
+
+ /** CONTACTS
+ */
+ private $cts = array();
+ public function addContactFilter($uid = null)
+ {
+ $this->requireProfiles();
+ return $this->register_optional($this->cts, is_null($uid) ? null : 'user_' . $uid);
+ }
+
+ protected function contactJoins()
+ {
+ $joins = array();
+ foreach ($this->cts as $sub=>$key) {
+ if (is_null($key)) {
+ $joins['c' . $sub] = PlSqlJoin::left('contacts', '$ME.contact = $PID');
+ } else {
+ $joins['c' . $sub] = PlSqlJoin::left('contacts', '$ME.uid = {?} AND $ME.contact = $PID', substr($key, 5));
+ }
+ }
+ return $joins;
+ }
+
+
+ /** CARNET
+ */
+ private $wn = array();
+ public function addWatchRegistrationFilter($uid = null)
+ {
+ $this->requireAccounts();
+ return $this->register_optional($this->wn, is_null($uid) ? null : 'user_' . $uid);
+ }
+
+ private $wp = array();
+ public function addWatchPromoFilter($uid = null)
+ {
+ $this->requireAccounts();
+ return $this->register_optional($this->wp, is_null($uid) ? null : 'user_' . $uid);
+ }
+
+ private $w = array();
+ public function addWatchFilter($uid = null)
+ {
+ $this->requireAccounts();
+ return $this->register_optional($this->w, is_null($uid) ? null : 'user_' . $uid);
+ }
+
+ protected function watchJoins()
+ {
+ $joins = array();
+ foreach ($this->w as $sub=>$key) {
+ if (is_null($key)) {
+ $joins['w' . $sub] = PlSqlJoin::left('watch');
+ } else {
+ $joins['w' . $sub] = PlSqlJoin::left('watch', '$ME.uid = {?}', substr($key, 5));
+ }
+ }
+ foreach ($this->wn as $sub=>$key) {
+ if (is_null($key)) {
+ $joins['wn' . $sub] = PlSqlJoin::left('watch_nonins', '$ME.ni_id = $UID');
+ } else {
+ $joins['wn' . $sub] = PlSqlJoin::left('watch_nonins', '$ME.uid = {?} AND $ME.ni_id = $UID', substr($key, 5));
+ }
+ }
+ foreach ($this->wn as $sub=>$key) {
+ if (is_null($key)) {
+ $joins['wn' . $sub] = PlSqlJoin::left('watch_nonins', '$ME.ni_id = $UID');
+ } else {
+ $joins['wn' . $sub] = PlSqlJoin::left('watch_nonins', '$ME.uid = {?} AND $ME.ni_id = $UID', substr($key, 5));
+ }
+ }
+ foreach ($this->wp as $sub=>$key) {
+ if (is_null($key)) {
+ $joins['wp' . $sub] = PlSqlJoin::left('watch_promo');
+ } else {
+ $joins['wp' . $sub] = PlSqlJoin::left('watch_promo', '$ME.uid = {?}', substr($key, 5));
+ }
+ }
+ return $joins;
+ }
+
+
+ /** PHOTOS
+ */
+ private $with_photo;
+ public function addPhotoFilter()
+ {
+ $this->requireProfiles();
+ $this->with_photo = true;
+ return 'photo';
+ }
+
+ protected function photoJoins()
+ {
+ if ($this->with_photo) {
+ return array('photo' => PlSqlJoin::left('profile_photos', '$ME.pid = $PID'));
+ } else {
+ return array();
+ }
+ }
+
+
+ /** MARKETING
+ */
+ private $with_rm;
+ public function addMarketingHash()
+ {
+ $this->requireAccounts();
+ $this->with_rm = true;
+ }
+
+ protected function marketingJoins()
+ {
+ if ($this->with_rm) {
+ return array('rm' => PlSqlJoin::left('register_marketing', '$ME.uid = $UID'));
+ } else {
+ return array();
+ }
+ }
+
+
+ /** PARTNER SHARING
+ */
+
+ // Lists partner shortnames in use, as a $partner_shortname => true map.
+ private $ppss = array();
+
+ /** Add a filter on user having settings for a given partner.
+ * @param $partner_id the ID of the partner
+ * @return the name of the table to use in joins (e.g ppss_$partner_id).
+ */
+ public function addPartnerSharingFilter($partner_id)
+ {
+ $this->requireProfiles();
+ $sub = "ppss_" . $partner_id;
+ $this->ppss[$sub] = $partner_id;
+ return $sub;
+ }
+
+ protected function partnerSharingJoins()
+ {
+ $joins = array();
+ foreach ($this->ppss as $sub => $partner_id) {
+ $joins[$sub] = PlSqlJoin::left('profile_partnersharing_settings', '$ME.pid = $PID AND $ME.partner_id = {?} AND $ME.sharing_level != \'none\'', $partner_id);
+ }
+ return $joins;
+ }
+
+ public function restrictVisibilityForPartner($partner_id)
+ {
+ $sub = $this->addPartnerSharingFilter($partner_id);
+ $this->visibility_field = $sub . '.sharing_level';
+ }
+
+ /** VISIBILITY
+ */
+ private $vlevels = array();
+ private $vfields = array();
+ public function addVisibilityAbsoluteFilter($level)
+ {
+ $sub = 'pvel_' . $level;
+ $this->vlevels[$level] = $sub;
+ return $sub;
+ }
+
+ public function addVisibilityFieldFilter($field)
+ {
+ $sub = 'pvef_' . self::getDBSuffix($field);
+ $this->vfields[$field] = $sub;
+ return $sub;
+ }
+
+ /** Since this method might perform inner joins on tables which have been
+ * joined previously (e.g when using addVisibilityFieldFilter), it has to
+ * come after the Joins() methods for those tables.
+ * This is due to the implementation logic for discovering joins and the
+ * ordering used by PHP introspection.
+ */
+ protected function visibilityJoins()
+ {
+ $joins = array();
+ foreach ($this->vlevels as $level => $sub) {
+ $joins[$sub] = PlSqlJoin::inner('profile_visibility_enum', '$ME.access_level = {?}', $level);
+ }
+ foreach ($this->vfields as $field => $sub) {
+ $joins[$sub] = PlSqlJoin::inner('profile_visibility_enum', '$ME.access_level = ' . $field);
+ }
+ return $joins;
+ }
+
+}
+// }}}
+// {{{ class ProfileFilter
+class ProfileFilter extends UserFilter
+{
+ public function get($limit = null)
+ {
+ return $this->getProfiles($limit);
+ }
+
+ public function getIds($limit = null)
+ {
+ return $this->getPIDs();
+ }
+
+ public function filter(array $profiles, $limit = null)
+ {
+ return $this->filterProfiles($profiles, self::defaultLimit($limit));
+ }
+
+ public function getTotalCount()
+ {
+ return $this->getTotalProfileCount();
+ }
+
+ public function getGroups()
+ {
+ return $this->getPIDGroups();
+ }