Skip to content

Commit

Permalink
Filter by user - Attribute filter: allow having multiple users or gro…
Browse files Browse the repository at this point in the history
…ups separated by comma
  • Loading branch information
mdouchin committed Aug 19, 2024
1 parent 6c0c124 commit 114c7c4
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 32 deletions.
39 changes: 14 additions & 25 deletions lizmap/modules/lizmap/lib/Form/QgisForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -1794,41 +1794,30 @@ protected function filterDataByLogin($layername)
return null;
}

// Optionnaly add a filter parameter
$lproj = $this->layer->getProject();
$loginFilteredConfig = $lproj->getLoginFilteredConfig($layername);
// Optionally add a filter parameter
$layerProject = $this->layer->getProject();
$loginFilteredConfig = $layerProject->getLoginFilteredConfig($layername);

if ($loginFilteredConfig) {
// Get filter type
$type = 'groups';
$attribute = $loginFilteredConfig->filterAttribute;

// check filter type
if (property_exists($loginFilteredConfig, 'filterPrivate')
&& $loginFilteredConfig->filterPrivate == 'True') {
&& $loginFilteredConfig->filterPrivate == 'True') {
$type = 'login';
}

// Check if a user is authenticated
$isConnected = $this->appContext->userIsConnected();
$cnx = $this->appContext->getDbConnection($this->layer->getId());
if ($isConnected) {
$user = $this->appContext->getUserSession();
$login = $user->login;
if ($type == 'login') {
$where = ' "'.$attribute."\" IN ( '".$login."' , 'all' )";
} else {
$userGroups = $this->appContext->aclUserPublicGroupsId();
// Set XML Filter if getFeature request
$flatGroups = implode("' , '", $userGroups);
$where = ' "'.$attribute."\" IN ( '".$flatGroups."' , 'all' )";
}
} else {
// The user is not authenticated: only show data with attribute = 'all'
$where = ' "'.$attribute.'" = '.$cnx->quote('all');
// Filter attribute
$attribute = $loginFilteredConfig->filterAttribute;

// SQL filter
$layerFilter = $layerProject->getLoginFilter($layername);
if (empty($layerFilter)) {
return null;
}

// Set filter when multiple layers concerned
return array(
'where' => $where,
'where' => $layerFilter['filter'],
'type' => $type,
'attribute' => $attribute,
);
Expand Down
54 changes: 49 additions & 5 deletions lizmap/modules/lizmap/lib/Project/Project.php
Original file line number Diff line number Diff line change
Expand Up @@ -1226,7 +1226,9 @@ public function getLoginFilteredConfig($layerName, $edition = false)
* @param string[] $layers : layers' name list
* @param bool $edition : get login filters for edition
*
* @return array
* @return array Array containing layers names as key and filter configuration
* and SQL filters as values. Array might be empty if no filter
* is configured for the layer.
*/
public function getLoginFilters($layers, $edition = false)
{
Expand Down Expand Up @@ -1258,22 +1260,64 @@ public function getLoginFilters($layers, $edition = false)
// attribute to filter
$attribute = $loginFilteredConfig->filterAttribute;

# Quoted attribute with double-quotes
$cnx = \jDb::getConnection();
$quotedField = $cnx->encloseName($attribute);

// default no user connected
$filter = "\"{$attribute}\" = 'all'";
$filter = "$quotedField = 'all'";

// A user is connected
if ($this->appContext->userIsConnected()) {
// Get the user
$user = $this->appContext->getUserSession();
$login = $user->login;

# List of values for expression
$values = array();
if (property_exists($loginFilteredConfig, 'filterPrivate')
&& $this->optionToBoolean($loginFilteredConfig->filterPrivate)
) {
$filter = "\"{$attribute}\" IN ( '".$login."' , 'all' )";
# If filter is private use user_login
$values[] = $login;
} else {
# Else use user groups
$userGroups = $this->appContext->aclUserPublicGroupsId();
$flatGroups = implode("' , '", $userGroups);
$filter = "\"{$attribute}\" IN ( '".$flatGroups."' , 'all' )";
$values = $userGroups;
}

# Add all to values
$values[] = 'all';
$allValuesFilters = array();

# For each value (group, all, login, etc.), create a filter
# combining all the possibility: equality & LIKE
foreach ($values as $value) {
$valueFilters = array();
# Quote the value with single quotes
$quotedValue = $cnx->quote($value);

# equality
$valueFilters[] = "$quotedField = $quotedValue";

# begins with value & comma
$quotedLikeValue = $cnx->quote("$value,%");
$valueFilters[] = "$quotedField LIKE $quotedLikeValue";

# ends with comma & value
$quotedLikeValue = $cnx->quote("%,$value");
$valueFilters[] = "$quotedField LIKE $quotedLikeValue";

# value between two commas
$quotedLikeValue = $cnx->quote("%,$value,%");
$valueFilters[] = "$quotedField LIKE $quotedLikeValue";

# Build the filter for this value
$allValuesFilters[] = implode(' OR ', $valueFilters);
}

# Build filter for all values
$filter = implode(' OR ', $allValuesFilters);
}

$filters[$layerName] = array_merge(
Expand Down
4 changes: 2 additions & 2 deletions lizmap/modules/lizmap/lib/Request/WFSRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -643,13 +643,13 @@ protected function parseExpFilter($cnx, $params)
if (strpos($validFilter, '$id') !== false) {
$key = $this->datasource->key;
if (count(explode(',', $key)) == 1) {
return ' AND '.str_replace('$id ', $cnx->encloseName($key).' ', $validFilter);
return ' AND ( '.str_replace('$id ', $cnx->encloseName($key).' ', $validFilter).' ) ';
}

return false;
}

return ' AND '.$validFilter;
return ' AND ( '.$validFilter . ' ) ';
}

return '';
Expand Down

0 comments on commit 114c7c4

Please sign in to comment.