<?php
/***************************************************************************
- * Copyright (C) 2003-2011 Polytechnique.org *
+ * Copyright (C) 2003-2014 Polytechnique.org *
* http://opensource.polytechnique.org/ *
* *
* This program is free software; you can redistribute it and/or modify *
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;
}
// 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()
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) {
}
}
- 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);
}
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
}
// }}}
-// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker fenc=utf-8:
?>