- Affected version
- 2.0.10
When doing bulk user searches (ie user search, email users, alert users, message users), XF1 and XF2 behaviour is different.
In XF1, "Not in secondary groups " user criteria requires that there be no matches to the list.
In XF2, "Not in secondary groups " user criteria requires that at least one group doesn't match.
Note; this behaviour does not match XF2 user criteria for user promotions/notices.
On my dev site when searching for my username and not being a member of 3 groups (of which I am a member of 2 groups but not the 3rd). The finder generates the following SQL;
The FIND_IN_SET should be
In XF1, "Not in secondary groups " user criteria requires that there be no matches to the list.
In XF2, "Not in secondary groups " user criteria requires that at least one group doesn't match.
Note; this behaviour does not match XF2 user criteria for user promotions/notices.
On my dev site when searching for my username and not being a member of 3 groups (of which I am a member of 2 groups but not the 3rd). The finder generates the following SQL;
SQL:
SELECT `xf_user`.*
FROM `xf_user`
LEFT JOIN `xf_user_option` AS `xf_user_option_Option_2` ON (`xf_user_option_Option_2`.`user_id` = `xf_user`.`user_id`)
WHERE (`xf_user_option_Option_2`.`receive_admin_email` = 1) AND
(FIND_IN_SET('39', `xf_user`.`secondary_group_ids`) = 0 OR
FIND_IN_SET('3', `xf_user`.`secondary_group_ids`) = 0 OR
FIND_IN_SET('43', `xf_user`.`secondary_group_ids`) = 0) AND (`xf_user`.`email` <> '')
AND username = 'Xon'
ORDER BY `xf_user`.`username` ASC
The FIND_IN_SET should be
AND
ed not OR
ed together for 'not_secondary_group_ids' in XF\Searcher::applySpecialCriteriaValue
PHP:
protected function applySpecialCriteriaValue(Finder $finder, $key, $value, $column, $format, $relation)
{
if ($key == 'secondary_group_ids' || $key == 'not_secondary_group_ids')
{
if (!is_array($value))
{
$value = [$value];
}
$columnName = $finder->columnSqlName('secondary_group_ids');
$positiveMatch = ($key == 'secondary_group_ids');
$parts = [];
foreach ($value AS $part)
{
if ($positiveMatch)
{
$parts[] = 'FIND_IN_SET(' . $finder->quote($part) . ', '. $columnName . ')';
}
else
{
$parts[] = 'FIND_IN_SET(' . $finder->quote($part) . ', '. $columnName . ') = 0';
}
}
if ($parts)
{
$finder->whereSql(implode(' OR ', $parts));
}
return true;
}
...
return false;
}
Last edited: