Commit 2cb7bdd4 authored by Richard Mansfield's avatar Richard Mansfield Committed by Nigel McNie
Browse files

New admin user search: works without js, can search by initials

parent e9ca21f2
......@@ -47,18 +47,16 @@ if ($action == 'suspend') {
if ($action == 'search') {
require('searchlib.php');
try {
$query = param_variable('query');
}
catch (ParameterException $e) {
json_reply('missingparameter','Missing parameter \'query\'');
}
$limit = param_integer('limit', 20);
$offset = param_integer('offset', 0);
$data = search_user($query, $limit, $offset);
$params = new StdClass;
$params->query = trim(param_variable('query', ''));
$params->offset = param_integer('offset', 0);
$params->limit = param_integer('limit', 10);
$params->f = param_alpha('f', null);
$params->l = param_alpha('l', null);
json_headers();
$data['data'] = build_admin_user_search_results($params);
$data['error'] = false;
$data['message'] = '';
echo json_encode($data);
......
......@@ -32,117 +32,21 @@ define('TITLE', get_string('usersearch', 'admin'));
define('SECTION_PLUGINTYPE', 'core');
define('SECTION_PLUGINNAME', 'admin');
define('SECTION_PAGE', 'usersearch');
$query = param_variable('query',null);
if (isset($query) && trim($query) == '') {
$query = null;
}
$wwwroot = get_config('wwwroot');
$str_profileimage = json_encode(get_string('profileimage'));
$str_institution = json_encode(get_string('institution'));
$str_suspenduser = json_encode(get_string('suspenduser', 'admin'));
$str_suspensionreason = json_encode(get_string('suspensionreason', 'admin'));
$str_errorwhilesuspending = json_encode(get_string('errorwhilesuspending', 'admin'));
$str_noresults = json_encode(get_string('noresultsfound'));
$str_cancel = json_encode(get_string('cancel'));
$str_sesskey = json_encode($USER->get('sesskey'));
$javascript = <<<EOF
var results = new TableRenderer(
'searchresults',
'search.json.php',
[
function(r) { return TD(null,IMG({'src': '{$wwwroot}thumb.php?type=profileicon&size=40x40&id=' + r.id, 'alt': {$str_profileimage}})); },
function(r) {
return TD({'style': 'vertical-align: top'},
A({'href': '{$wwwroot}user/view.php?id=' + r.id}, r.name),
BR(),
STRONG(null, {$str_institution} + ': '),
SPAN(null, r.institution)
);
},
function(r) {
return TD({'style': 'vertical-align: top'},
A({'href': '', 'onclick': 'suspendDisplay(this); return false;'}, $str_suspenduser),BR()
// A({'href': ''}, 'some other action'),BR()
);
}
]
require('searchlib.php');
$search = (object) array(
'query' => trim(param_variable('query', '')),
'sort' => param_alpha('sort', 'lastname'),
'f' => param_alpha('f', null),
'l' => param_alpha('l', null),
'offset' => param_integer('offset', 0),
'limit' => param_integer('limit', 10)
);
results.rowfunction = function(r) { var row = TR(); row.data = r; return row; };
results.statevars.push('query');
results.statevars.push('action');
results.statevars.push('sesskey');
results.action = 'search';
results.sesskey = {$str_sesskey};
results.emptycontent = {$str_noresults};
results.query = '';
results.updateOnLoad();
function doSearch() {
results.query = $('usersearch').value;
results.offset = 0;
results.doupdate();
}
addLoadEvent(function() {
$('usersearch').focus();
connect('usersearch', 'onkeypress', function (k) {
if (k.key().code == 13) {
doSearch();
}
});
});
function suspendDisplay(ref) {
ref = ref.parentNode.parentNode; // get the TR
var reason = INPUT({'type': 'text'});
var cancelButton = BUTTON({'type': 'button'}, {$str_cancel});
var saveButton = BUTTON({'type': 'button'}, {$str_suspenduser});
insertSiblingNodesAfter(ref, TR(null, TD({'colSpan': 3},
{$str_suspensionreason} + ': ',
reason,
cancelButton,
saveButton
)));
reason.focus();
connect(reason, 'onkeypress', function (k) {
if (k.key().code == 13) {
suspendSave(reason);
}
if (k.key().code == 27) {
suspendCancel(reason);
}
});
connect(cancelButton, 'onclick', partial(suspendCancel, reason));
connect(saveButton, 'onclick', partial(suspendSave, reason));
}
function suspendSave(reason) {
var susReason = reason.value;
var data = reason.parentNode.parentNode.previousSibling.data;
removeElement(reason.parentNode.parentNode);
sendjsonrequest('search.json.php', {'action': 'suspend', 'reason': susReason, 'id': data.id}, 'GET',
function(response) {
results.doupdate();
});
}
function suspendCancel(reason) {
removeElement(reason.parentNode.parentNode);
}
EOF;
$smarty = smarty(array('tablerenderer'));
$smarty->assign('INLINEJAVASCRIPT', $javascript);
$smarty = smarty(array('usersearch'));
$smarty->assign('search', $search);
$smarty->assign('alphabet', explode(',', get_string('alphabet')));
$smarty->assign('results', build_admin_user_search_results($search));
$smarty->display('admin/users/search.tpl');
?>
......@@ -469,7 +469,8 @@ $string['groupconfirmdelete'] = 'Are you sure you wish to delete this community?
$string['groupconfirmdeletehasviews'] = 'Are you sure you wish to delete this community? Some of your views use this community for access control, removing this community would mean that the members of that community would not have access to the views.';
$string['deletegroup'] = 'Group Deleted Successfully';
$string['alphabet'] = 'A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z';
$string['all'] = 'All';
// friendslist
$string['reasonoptional'] = 'Reason (optional)';
......
......@@ -116,6 +116,41 @@ function search_user($query_string, $limit, $offset = 0) {
return $results;
}
function build_admin_user_search_results($search) {
$smarty = smarty_core();
$results = admin_user_search($search);
$params = array();
foreach ($search as $k => $v) {
if (!empty($v) && $k != 'offset') {
$params[] = $k . '=' . $v;
}
}
$params = join('&amp;', $params);
$smarty->assign_by_ref('params', $params);
$results['pages'] = ceil($results['count'] / $results['limit']);
$results['page'] = $results['offset'] / $results['limit']; // $results['pages'];
$lastpage = $results['pages'] - 1;
$results['next'] = min($lastpage, $results['page'] + 1);
$results['prev'] = max(0, $results['page'] - 1);
$range = min(1, $lastpage);
$pagenumbers = array_unique(array_merge(range(0, min($range, $results['page'])),
range(max($range, $results['page']-$range),
min($results['page']+$range, $lastpage)),
range(max($range, $lastpage-$range), $lastpage)));
$smarty->assign_by_ref('results', $results);
$smarty->assign_by_ref('pagenumbers', $pagenumbers);
return $smarty->fetch('admin/users/resulttable.tpl');
}
function admin_user_search($searchparams) {
$plugin = 'internal'; // No admin search with solr yet.
safe_require('search', $plugin);
return call_static_method(generate_class_name('search', $plugin), 'admin_search_user', $searchparams);
}
/**
* Given a query string and limits, return an array of matching groups using the
* search plugin defined in config.php
......
......@@ -236,6 +236,80 @@ class PluginSearchInternal extends PluginSearch {
);
}
public static function admin_search_user($s) {
if (is_postgres()) {
return self::admin_search_user_pg($s);
}
//else if (is_mysql()) {
// return self::admin_search_user_my($query_string, $limit, $offset);
//}
else {
throw new SQLException('admin_search_user() is not implemented for your database engine (' . get_config('dbtype') . ')');
}
}
public static function admin_search_user_pg($s) {
$values = array();
$where = 'WHERE u.id <> 0 AND u.deleted = 0';
if (!empty($s->query)) {
$where .= '
AND ( u.firstname ILIKE \'%\' || ? || \'%\'
OR u.lastname ILIKE \'%\' || ? || \'%\'
) ';
$values = array($s->query, $s->query);
} else {
if (!empty($s->f)) {
$where .= ' AND u.firstname ILIKE ? || \'%\'';
$values[] = $s->f;
}
if (!empty($s->l)) {
$where .= ' AND u.lastname ILIKE ? || \'%\'';
$values[] = $s->l;
}
}
if (!empty($s->institution)) {
$where .= ' AND u.institution = ? ';
$values[] = $s->institution;
}
if (!empty($s->email)) {
$where .= ' AND u.email ILIKE \'%\' || ? || \'%\'';
$values[] = $s->email;
}
$count = get_field_sql('SELECT COUNT(*) FROM {usr} u ' . $where, $values);
if ($count > 0) {
$data = get_records_sql_array('
SELECT
u.id, u.firstname, u.lastname, u.username, u.institution, u.email, u.staff,
u.active, u.suspendedctime
FROM
{usr} u ' . $where . '
ORDER BY u.firstname, u.lastname, u.id',
$values,
$s->offset,
$s->limit);
if ($data) {
foreach ($data as &$item) {
$item = (array)$item;
}
}
}
else {
$data = false;
}
return array(
'count' => $count,
'limit' => $s->limit,
'offset' => $s->offset,
'data' => $data,
);
}
/**
* Implement group searching with SQL
*
......
......@@ -1547,3 +1547,10 @@ a.pieform-calendar-toggle img {
.maincontent .maharatable {
border: none;
}
#initials span.selected a,
.search-results-pages span.selected a {
color: #000 !important;
text-decoration: none;
font-weight: bold;
}
{include file="header.tpl"}
{include file="columnfullstart.tpl"}
<div class="searchform">
<h2>{str tag="usersearch" section="admin"}</h2>
<table id="initials"><tbody>
<tr id="firstnamelist">
<td>{str tag="firstname"}:</td>
<td>
<span class="first-initial{if empty($search->f)} selected{/if} all">
<a href="?{if $search->l}l={$search->l}{/if}">{str tag="all"}</a>
</span>
{foreach from=$alphabet item=a}
<span class="first-initial{if $a == $search->f} selected{/if}">
<a href="?f={$a}{if $search->l}&amp;l={$search->l}{/if}">{$a}</a>
</span>
{/foreach}
</td>
</tr>
<tr id="lastnamelist">
<td>{str tag="lastname"}:</td>
<td>
<span class="last-initial{if empty($search->l)} selected{/if} all">
<a href="?{if $search->f}f={$search->f}{/if}">{str tag="all"}</a>
</span>
{foreach from=$alphabet item=a}
<span class="last-initial{if $a == $search->l} selected{/if}">
<a href="?l={$a}{if $search->f}&amp;f={$search->f}{/if}">{$a}</a>
</span>
{/foreach}
</td>
</tr>
</tbody></table>
<form action="" method="post">
<div class="searchform">
<label>Query:
<input type="text" name="usersearch" id="usersearch">
<button type="button" onclick="doSearch();">{str tag="go"}</button>
<input type="text" name="query" id="query">
<button id="query-button" type="submit">{str tag="go"}</button>
</label>
</div>
<div id="results">
<h3>{str tag="results"}</h3>
<table id="searchresults" class="hidden tablerenderer">
<tbody>
</tbody>
</table>
{$results}
</div>
</form>
{include file="columnfullend.tpl"}
{include file="footer.tpl"}
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