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) { ...@@ -150,38 +150,63 @@ function parse_name_query($text) {
} }
function get_admin_user_search_results($search, $offset, $limit, $sortby, $sortdir) { function get_admin_user_search_results($search, $offset, $limit, $sortby, $sortdir) {
// In admin search, the search string is interpreted as either a $plugin = get_config('searchplugin');
// name search or an email search depending on its contents safe_require('search', $plugin);
$queries = array();
$constraints = array(); $constraints = array();
if (!empty($search->query)) {
list($words, $fullnames) = parse_name_query($search->query); if ($plugin == 'internal') {
foreach ($words as $word) { // For the internal plugin, just pass the raw query through as a string, it
if (strpos($word, '@') !== false) { // is parsed in the plugin.
$queries[] = array('field' => 'email', $queries = $search->query;
'type' => 'contains', }
'string' => $word); else {
} else { // In admin search, the search string is interpreted as either a
$queries[] = array('field' => 'firstname', // name search or an email search depending on its contents
'type' => 'contains', $queries = array();
'string' => $word); if (!empty($search->query)) {
$queries[] = array('field' => 'lastname', list($words, $fullnames) = parse_name_query($search->query);
'type' => 'contains', foreach ($words as $word) {
'string' => $word); if (strpos($word, '@') !== false) {
$queries[] = array('field' => 'username', $queries[] = array(
'type' => 'contains', 'field' => 'email',
'string' => $word); '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)) { if (!empty($search->f)) {
$constraints[] = array('field' => 'firstname', $constraints[] = array('field' => 'firstname',
'type' => 'starts', 'type' => 'starts',
...@@ -192,6 +217,7 @@ function get_admin_user_search_results($search, $offset, $limit, $sortby, $sortd ...@@ -192,6 +217,7 @@ function get_admin_user_search_results($search, $offset, $limit, $sortby, $sortd
'type' => 'starts', 'type' => 'starts',
'string' => $search->l); 'string' => $search->l);
} }
// Filter by viewable institutions: // Filter by viewable institutions:
global $USER; global $USER;
if (!$USER->get('admin')) { if (!$USER->get('admin')) {
...@@ -218,7 +244,11 @@ function get_admin_user_search_results($search, $offset, $limit, $sortby, $sortd ...@@ -218,7 +244,11 @@ function get_admin_user_search_results($search, $offset, $limit, $sortby, $sortd
'string' => $search->institution); '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']) { if ($results['count']) {
foreach ($results['data'] as &$result) { foreach ($results['data'] as &$result) {
$result['name'] = display_name($result); $result['name'] = display_name($result);
...@@ -227,6 +257,7 @@ function get_admin_user_search_results($search, $offset, $limit, $sortby, $sortd ...@@ -227,6 +257,7 @@ function get_admin_user_search_results($search, $offset, $limit, $sortby, $sortd
} }
} }
} }
return $results; return $results;
} }
...@@ -288,14 +319,6 @@ function build_admin_user_search_results($search, $offset, $limit, $sortby, $sor ...@@ -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 * Returns search results for users in a particular group
* *
......
...@@ -311,7 +311,7 @@ class PluginSearchInternal extends PluginSearch { ...@@ -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) { $sortfield, $sortdir) {
$sort = 'TRUE'; $sort = 'TRUE';
if (preg_match('/^[a-zA-Z_0-9"]+$/', $sortfield)) { if (preg_match('/^[a-zA-Z_0-9"]+$/', $sortfield)) {
...@@ -329,20 +329,24 @@ class PluginSearchInternal extends PluginSearch { ...@@ -329,20 +329,24 @@ class PluginSearchInternal extends PluginSearch {
// Get the correct keyword for case insensitive LIKE // Get the correct keyword for case insensitive LIKE
$ilike = db_ilike(); $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)) { $matches = array();
$where .= ' AND ( '; foreach (array('firstname', 'lastname', 'username', 'email') as $f) {
$str = array(); $matches[] = self::match_user_field_expression($f, 'u');
foreach ($queries as $f) { }
if (!preg_match('/^[a-zA-Z_0-9"]+$/', $f['field'])) {
continue; // skip this field as it fails validation $termsql = join(" OR ", $matches);
}
$str[] = 'u.' . $f['field'] $values = array();
. PluginSearchInternal::match_expression($f['type'], $f['string'], $values, $ilike); foreach ($querydata as $term) {
} $where .= '
$where .= join(' OR ', $str) . ') '; AND (
} ' . $termsql . '
)';
$values = array_pad($values, count($values) + 4, $term);
}
// @todo: Institution stuff is messy and will probably need to // @todo: Institution stuff is messy and will probably need to
// be rewritten when we get multiple institutions per user // 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