X-Git-Url: http://git.polytechnique.org/?a=blobdiff_plain;ds=sidebyside;f=classes%2Fuserfilter.php;h=983b2ee8b1d18903a28e76edaed08d6e75d886f9;hb=a29666408c1ca175f2cc559388e2442b177523ad;hp=bbaceba4179b2fc0b7bd51a94ce8348bcc0ed7de;hpb=38a86f60ef2563469ac50ed1cc435d1ac554ff68;p=platal.git diff --git a/classes/userfilter.php b/classes/userfilter.php index bbaceba..983b2ee 100644 --- a/classes/userfilter.php +++ b/classes/userfilter.php @@ -85,7 +85,9 @@ class UserFilter extends PlFilter private $orderby = null; // Store the current 'search' visibility. - private $profile_visibility = null; + private $visibility = null; + // If the 'search' visibility should be based on a DB field instead. + private $visibility_field = null; private $lastusercount = null; private $lastprofilecount = null; @@ -117,22 +119,50 @@ class UserFilter extends PlFilter } // This will set the visibility to the default correct level. - $this->profile_visibility = ProfileVisibility::defaultForRead(); + $this->visibility = Visibility::defaultForRead(); } - public function isVisible($level) - { - return $this->profile_visibility->isVisible($level); - } - - public function getVisibilityLevel() - { - return $this->profile_visibility->level(); + /** Get the SQL condition to filter by visibility level for a field. + * This will return a SQL condition which evaluates to True if the given + * field display level is available from the current access level. + * @param $field Name of the field holding a display level + * @return string SQL condition, properly escaped, for that field. + */ + public function getVisibilityConditionForField($field) + { + if ($this->visibility_field != null) { + // Use enum 'bit' arithmetic. + // Display levels are ordered as 'hidden, private, ax, public' + // Thus ax > private. + // The $sub.display_level cell will contain the 'most private' display + // level available based on $field. If it is 'ax' and $field is + // 'private','ax' <= 'private' is false. + $sub = $this->addVisibilityFieldFilter($this->visibility_field); + return $sub . '.best_display_level + 0 <= 0 + ' . $field; + } else { + $sub = $this->addVisibilityAbsoluteFilter($this->visibility->level()); + return $sub . '.best_display_level + 0 <= 0 + ' . $field; + } } - public function getVisibilityCondition($field) + /** Get the SQL condition to filter by a given visibility level. + * @param $level One of Visibility::EXPORT_* + * @return string A SQL condition, properly escaped, which evaluates to 'true' if the $level can be viewed with the current access level. + */ + public function getVisibilityConditionAbsolute($level) { - return XDB::format($field . ' >= {?}', $this->getVisibilityLevel()); + if ($this->visibility_field != null) { + // The $sub.display_levels cell will contain allowed display levels + // for an access level of $this->visibility_field. + $sub = $this->addVisibilityFieldFilter($this->visibility_field); + return XDB::format('FIND_IN_SET({?}, ' . $sub . '.display_levels)', $level); + } else { + if ($this->visibility->isVisible($level)) { + return 'TRUE'; + } else { + return 'FALSE'; + } + } } private function buildQuery() @@ -388,12 +418,12 @@ class UserFilter extends PlFilter return User::iterOverUIDs($this->getUIDs($limit)); } - public function getProfiles($limit = null, $fields = 0x0000, ProfileVisibility $visibility = null) + public function getProfiles($limit = null, $fields = 0x0000, $visibility = null) { return Profile::getBulkProfilesWithPIDs($this->getPIDs($limit), $fields, $visibility); } - public function getProfile($pos = 0, $fields = 0x0000, ProfileVisibility $visibility = null) + public function getProfile($pos = 0, $fields = 0x0000, $visibility = null) { $pid = $this->getPID($pos); if ($pid == null) { @@ -403,7 +433,7 @@ class UserFilter extends PlFilter } } - public function iterProfiles($limit = null, $fields = 0x0000, ProfileVisibility $visibility = null) + public function iterProfiles($limit = null, $fields = 0x0000, $visibility = null) { return Profile::iterOverPIDs($this->getPIDs($limit), true, $fields, $visibility); } @@ -1347,6 +1377,77 @@ class UserFilter extends PlFilter 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