Commit 5bc6c5d3 authored by Richard Mansfield's avatar Richard Mansfield
Browse files

Change interpretation of admin user search query (bug #799591)



In admin user search, in the internal search plugin, use similar behaviour
to ordinary user searches: Join search terms by "AND", search quoted phrases
within a single field, respect the exact searches setting in the internal
search plugin configuration.

Change-Id: I41de40ce0f74c50c08da9ced9edeb29021865aa3
Signed-off-by: default avatarRichard Mansfield <richard.mansfield@catalyst.net.nz>
parent d96c14ea
......@@ -150,38 +150,63 @@ function parse_name_query($text) {
}
function get_admin_user_search_results($search, $offset, $limit, $sortby, $sortdir) {
// In admin search, the search string is interpreted as either a
// name search or an email search depending on its contents
$queries = array();
$plugin = get_config('searchplugin');
safe_require('search', $plugin);
$constraints = array();
if (!empty($search->query)) {
list($words, $fullnames) = parse_name_query($search->query);
foreach ($words as $word) {
if (strpos($word, '@') !== false) {
$queries[] = array('field' => 'email',
'type' => 'contains',
'string' => $word);
} else {
$queries[] = array('field' => 'firstname',
'type' => 'contains',
'string' => $word);
$queries[] = array('field' => 'lastname',
'type' => 'contains',
'string' => $word);
$queries[] = array('field' => 'username',
'type' => 'contains',
'string' => $word);
if ($plugin == 'internal') {
// For the internal plugin, just pass the raw query through as a string, it
// is parsed in the plugin.
$queries = $search->query;
}
else {
// In admin search, the search string is interpreted as either a
// name search or an email search depending on its contents
$queries = array();
if (!empty($search->query)) {
list($words, $fullnames) = parse_name_query($search->query);
foreach ($words as $word) {
if (strpos($word, '@') !== false) {
$queries[] = array(
'field' => 'email',
'type' => 'contains',
'string' => $word
);
}
else {
$queries[] = array(
'field' => 'firstname',
'type' => 'contains',
'string' => $word
);
$queries[] = array(
'field' => 'lastname',
'type' => 'contains',
'string' => $word
);
$queries[] = array(
'field' => 'username',
'type' => 'contains',
'string' => $word
);
}
}
foreach ($fullnames as $n) {
$constraints[] = array(
'field' => 'firstname',
'type' => 'contains',
'string' => $n[0]
);
$constraints[] = array(
'field' => 'lastname',
'type' => 'contains',
'string' => $n[1]
);
}
}
foreach ($fullnames as $n) {
$constraints[] = array('field' => 'firstname',
'type' => 'contains',
'string' => $n[0]);
$constraints[] = array('field' => 'lastname',
'type' => 'contains',
'string' => $n[1]);
}
}
if (!empty($search->f)) {
$constraints[] = array('field' => 'firstname',
'type' => 'starts',
......@@ -192,6 +217,7 @@ function get_admin_user_search_results($search, $offset, $limit, $sortby, $sortd
'type' => 'starts',
'string' => $search->l);
}
// Filter by viewable institutions:
global $USER;
if (!$USER->get('admin')) {
......@@ -218,7 +244,11 @@ function get_admin_user_search_results($search, $offset, $limit, $sortby, $sortd
'string' => $search->institution);
}
$results = admin_user_search($queries, $constraints, $offset, $limit, $sortby, $sortdir);
$results = call_static_method(
generate_class_name('search', $plugin), 'admin_search_user',
$queries, $constraints, $offset, $limit, $sortby, $sortdir
);
if ($results['count']) {
foreach ($results['data'] as &$result) {
$result['name'] = display_name($result);
......@@ -227,6 +257,7 @@ function get_admin_user_search_results($search, $offset, $limit, $sortby, $sortd
}
}
}
return $results;
}
......@@ -288,14 +319,6 @@ function build_admin_user_search_results($search, $offset, $limit, $sortby, $sor
}
function admin_user_search($queries, $constraints, $offset, $limit, $sortfield, $sortdir) {
$plugin = get_config('searchplugin');
safe_require('search', $plugin);
return call_static_method(generate_class_name('search', $plugin), 'admin_search_user',
$queries, $constraints, $offset, $limit, $sortfield, $sortdir);
}
/**
* Returns search results for users in a particular group
*
......
......@@ -311,7 +311,7 @@ class PluginSearchInternal extends PluginSearch {
}
public static function admin_search_user($queries, $constraints, $offset, $limit,
public static function admin_search_user($query_string, $constraints, $offset, $limit,
$sortfield, $sortdir) {
$sort = 'TRUE';
if (preg_match('/^[a-zA-Z_0-9"]+$/', $sortfield)) {
......@@ -329,20 +329,24 @@ class PluginSearchInternal extends PluginSearch {
// Get the correct keyword for case insensitive LIKE
$ilike = db_ilike();
// Only handle OR/AND expressions at the top level. Eventually we may need subexpressions.
// Generate the part that matches the search term
$querydata = self::split_query_string(strtolower(trim($query_string)));
if (!empty($queries)) {
$where .= ' AND ( ';
$str = array();
foreach ($queries as $f) {
if (!preg_match('/^[a-zA-Z_0-9"]+$/', $f['field'])) {
continue; // skip this field as it fails validation
}
$str[] = 'u.' . $f['field']
. PluginSearchInternal::match_expression($f['type'], $f['string'], $values, $ilike);
}
$where .= join(' OR ', $str) . ') ';
}
$matches = array();
foreach (array('firstname', 'lastname', 'username', 'email') as $f) {
$matches[] = self::match_user_field_expression($f, 'u');
}
$termsql = join(" OR ", $matches);
$values = array();
foreach ($querydata as $term) {
$where .= '
AND (
' . $termsql . '
)';
$values = array_pad($values, count($values) + 4, $term);
}
// @todo: Institution stuff is messy and will probably need to
// be rewritten when we get multiple institutions per user
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment