mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-29 10:06:13 +01:00
user search changes
This commit is contained in:
@@ -2,6 +2,8 @@
|
|||||||
"banned": "Banned",
|
"banned": "Banned",
|
||||||
"offline": "Offline",
|
"offline": "Offline",
|
||||||
"username": "User Name",
|
"username": "User Name",
|
||||||
|
"joindate": "Join Date",
|
||||||
|
"postcount": "Post Count",
|
||||||
|
|
||||||
"email": "Email",
|
"email": "Email",
|
||||||
"confirm_email": "Confirm Email",
|
"confirm_email": "Confirm Email",
|
||||||
|
|||||||
@@ -5,5 +5,8 @@
|
|||||||
"search": "Search",
|
"search": "Search",
|
||||||
"enter_username": "Enter a username to search",
|
"enter_username": "Enter a username to search",
|
||||||
"load_more": "Load More",
|
"load_more": "Load More",
|
||||||
"users-found-search-took": "%1 user(s) found! Search took %2 ms."
|
"users-found-search-took": "%1 user(s) found! Search took %2 ms.",
|
||||||
|
"filter-by": "Filter By",
|
||||||
|
"online-only": "Online only",
|
||||||
|
"picture-only": "Picture only"
|
||||||
}
|
}
|
||||||
@@ -150,7 +150,7 @@ define('admin/manage/groups', [
|
|||||||
var searchText = groupDetailsSearch.val(),
|
var searchText = groupDetailsSearch.val(),
|
||||||
foundUser;
|
foundUser;
|
||||||
|
|
||||||
socket.emit('admin.user.search', {type: 'username', query:searchText}, function(err, results) {
|
socket.emit('admin.user.search', {query: searchText}, function(err, results) {
|
||||||
if (!err && results && results.users.length > 0) {
|
if (!err && results && results.users.length > 0) {
|
||||||
var numResults = results.users.length, x;
|
var numResults = results.users.length, x;
|
||||||
if (numResults > 4) {
|
if (numResults > 4) {
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ define('admin/manage/users', ['admin/modules/selectable'], function(selectable)
|
|||||||
timeoutId = setTimeout(function() {
|
timeoutId = setTimeout(function() {
|
||||||
$('.fa-spinner').removeClass('hidden');
|
$('.fa-spinner').removeClass('hidden');
|
||||||
|
|
||||||
socket.emit('admin.user.search', {type: type, query: $this.val()}, function(err, data) {
|
socket.emit('admin.user.search', {searchBy: [type], query: $this.val()}, function(err, data) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return app.alertError(err.message);
|
return app.alertError(err.message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,65 +86,93 @@ define('forum/users', function() {
|
|||||||
|
|
||||||
function handleSearch() {
|
function handleSearch() {
|
||||||
var timeoutId = 0;
|
var timeoutId = 0;
|
||||||
var lastSearch = null;
|
|
||||||
|
|
||||||
$('#search-user').on('keyup', function() {
|
$('#search-user').on('keyup', function() {
|
||||||
if (timeoutId !== 0) {
|
if (timeoutId) {
|
||||||
clearTimeout(timeoutId);
|
clearTimeout(timeoutId);
|
||||||
timeoutId = 0;
|
timeoutId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
timeoutId = setTimeout(function() {
|
timeoutId = setTimeout(doSearch, 250);
|
||||||
function reset() {
|
});
|
||||||
notify.html('<i class="fa fa-search"></i>');
|
|
||||||
notify.parent().removeClass('btn-warning label-warning btn-success label-success');
|
|
||||||
}
|
|
||||||
var username = $('#search-user').val();
|
|
||||||
var notify = $('#user-notfound-notify');
|
|
||||||
|
|
||||||
if (username === '') {
|
$('.search select, .search .checkbox input').on('change', function() {
|
||||||
notify.html('<i class="fa fa-circle-o"></i>');
|
console.log('doing search');
|
||||||
notify.parent().removeClass('btn-warning label-warning btn-success label-success');
|
doSearch();
|
||||||
return;
|
});
|
||||||
}
|
|
||||||
|
|
||||||
if (lastSearch === username) {
|
$('.pagination').on('click', 'a', function() {
|
||||||
return;
|
console.log('loading page', $(this).attr('data-page'));
|
||||||
}
|
doSearch($(this).attr('data-page'));
|
||||||
lastSearch = username;
|
return false;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
notify.html('<i class="fa fa-spinner fa-spin"></i>');
|
function doSearch(page) {
|
||||||
|
function reset() {
|
||||||
|
notify.html('<i class="fa fa-search"></i>');
|
||||||
|
notify.parent().removeClass('btn-warning label-warning btn-success label-success');
|
||||||
|
}
|
||||||
|
|
||||||
socket.emit('user.search', {query: username, by: $('.search select').val()}, function(err, data) {
|
var username = $('#search-user').val();
|
||||||
if (err) {
|
var notify = $('#user-notfound-notify');
|
||||||
reset();
|
page = page || 1;
|
||||||
return app.alertError(err.message);
|
if (!username) {
|
||||||
}
|
notify.html('<i class="fa fa-circle-o"></i>');
|
||||||
|
notify.parent().removeClass('btn-warning label-warning btn-success label-success');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!data) {
|
notify.html('<i class="fa fa-spinner fa-spin"></i>');
|
||||||
return reset();
|
var filters = [];
|
||||||
}
|
$('.user-filter').each(function() {
|
||||||
|
var $this = $(this);
|
||||||
templates.parse('users', 'users', data, function(html) {
|
if($this.is(':checked')) {
|
||||||
translator.translate(html, function(translated) {
|
filters.push({
|
||||||
$('#users-container').html(translated);
|
field:$this.attr('data-filter-field'),
|
||||||
|
type: $this.attr('data-filter-type'),
|
||||||
if (!data.users.length) {
|
value: $this.attr('data-filter-value')
|
||||||
translator.translate('[[error:no-user]]', function(translated) {
|
|
||||||
notify.html(translated);
|
|
||||||
notify.parent().addClass('btn-warning label-warning');
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
translator.translate('[[users:users-found-search-took, ' + data.users.length + ', ' + data.timing + ']]', function(translated) {
|
|
||||||
notify.html(translated);
|
|
||||||
notify.parent().addClass('btn-success label-success');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}, 250);
|
socket.emit('user.search', {
|
||||||
|
query: username,
|
||||||
|
page: page,
|
||||||
|
searchBy: ['username', 'fullname'],
|
||||||
|
sortBy: $('.search select').val(),
|
||||||
|
filterBy: filters
|
||||||
|
}, function(err, data) {
|
||||||
|
if (err) {
|
||||||
|
reset();
|
||||||
|
return app.alertError(err.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
return reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
templates.parse('users', 'pages', data, function(html) {
|
||||||
|
$('.pagination').html(html);
|
||||||
|
});
|
||||||
|
|
||||||
|
templates.parse('users', 'users', data, function(html) {
|
||||||
|
translator.translate(html, function(translated) {
|
||||||
|
$('#users-container').html(translated);
|
||||||
|
|
||||||
|
if (!data.users.length) {
|
||||||
|
translator.translate('[[error:no-user]]', function(translated) {
|
||||||
|
notify.html(translated);
|
||||||
|
notify.parent().removeClass('btn-success label-success').addClass('btn-warning label-warning');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
translator.translate('[[users:users-found-search-took, ' + data.matchCount + ', ' + data.timing + ']]', function(translated) {
|
||||||
|
notify.html(translated);
|
||||||
|
notify.parent().removeClass('btn-warning label-warning').addClass('btn-success label-success');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ var usersController = {};
|
|||||||
|
|
||||||
var async = require('async'),
|
var async = require('async'),
|
||||||
user = require('../user'),
|
user = require('../user'),
|
||||||
|
meta = require('../meta'),
|
||||||
db = require('../database');
|
db = require('../database');
|
||||||
|
|
||||||
usersController.getOnlineUsers = function(req, res, next) {
|
usersController.getOnlineUsers = function(req, res, next) {
|
||||||
@@ -59,25 +60,14 @@ usersController.getUsersSortedByJoinDate = function(req, res, next) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function getUsers(set, res, next) {
|
function getUsers(set, res, next) {
|
||||||
async.parallel({
|
getUsersAndCount(set, 50, function(err, data) {
|
||||||
users: function(next) {
|
|
||||||
user.getUsersFromSet(set, 0, 49, next);
|
|
||||||
},
|
|
||||||
count: function(next) {
|
|
||||||
db.getObjectField('global', 'userCount', next);
|
|
||||||
}
|
|
||||||
}, function(err, results) {
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
results.users = results.users.filter(function(user) {
|
|
||||||
return user && parseInt(user.uid, 10);
|
|
||||||
});
|
|
||||||
|
|
||||||
var userData = {
|
var userData = {
|
||||||
search_display: 'hidden',
|
search_display: 'hidden',
|
||||||
loadmore_display: results.count > 50 ? 'block' : 'hide',
|
loadmore_display: data.count > 50 ? 'block' : 'hide',
|
||||||
users: results.users,
|
users: data.users,
|
||||||
show_anon: 'hide'
|
show_anon: 'hide'
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -85,15 +75,42 @@ function getUsers(set, res, next) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
usersController.getUsersForSearch = function(req, res, next) {
|
function getUsersAndCount(set, count, callback) {
|
||||||
var data = {
|
async.parallel({
|
||||||
search_display: 'block',
|
users: function(next) {
|
||||||
loadmore_display: 'hidden',
|
user.getUsersFromSet(set, 0, count - 1, next);
|
||||||
users: [],
|
},
|
||||||
show_anon: 'hide'
|
count: function(next) {
|
||||||
};
|
db.getObjectField('global', 'userCount', next);
|
||||||
|
}
|
||||||
|
}, function(err, results) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
results.users = results.users.filter(function(user) {
|
||||||
|
return user && parseInt(user.uid, 10);
|
||||||
|
});
|
||||||
|
|
||||||
res.render('users', data);
|
callback(null, {users: results.users, count: results.count});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
usersController.getUsersForSearch = function(req, res, next) {
|
||||||
|
var resultsPerPage = parseInt(meta.config.userSearchResultsPerPage, 10) || 20;
|
||||||
|
getUsersAndCount('users:joindate', resultsPerPage, function(err, data) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = {
|
||||||
|
search_display: 'block',
|
||||||
|
loadmore_display: 'hidden',
|
||||||
|
users: data.users,
|
||||||
|
show_anon: 'hide'
|
||||||
|
};
|
||||||
|
|
||||||
|
res.render('users', result);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ module.exports = function(Posts) {
|
|||||||
var userData = results.userData;
|
var userData = results.userData;
|
||||||
for(var i=0; i<userData.length; ++i) {
|
for(var i=0; i<userData.length; ++i) {
|
||||||
userData[i].groups = results.groups[i];
|
userData[i].groups = results.groups[i];
|
||||||
userData[i].status = results.online[i] ? (userData[i].status || 'online') : 'offline';
|
userData[i].status = user.getStatus(userData[i].status, results.online[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
async.map(userData, function(userData, next) {
|
async.map(userData, function(userData, next) {
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ User.deleteUsers = function(socket, uids, callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
User.search = function(socket, data, callback) {
|
User.search = function(socket, data, callback) {
|
||||||
user.search({query: data.query, by: data.type, startsWith: false}, function(err, searchData) {
|
user.search({query: data.query, searchBy: data.searchBy, startsWith: false}, function(err, searchData) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,14 +54,6 @@ SocketUser.emailConfirm = function(socket, data, callback) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SocketUser.increaseViewCount = function(socket, uid, callback) {
|
|
||||||
if (uid) {
|
|
||||||
if (socket.uid !== parseInt(uid, 10)) {
|
|
||||||
user.incrementUserFieldBy(uid, 'profileviews', 1, callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
SocketUser.search = function(socket, data, callback) {
|
SocketUser.search = function(socket, data, callback) {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return callback(new Error('[[error:invalid-data]]'))
|
return callback(new Error('[[error:invalid-data]]'))
|
||||||
@@ -69,7 +61,13 @@ SocketUser.search = function(socket, data, callback) {
|
|||||||
if (!socket.uid) {
|
if (!socket.uid) {
|
||||||
return callback(new Error('[[error:not-logged-in]]'));
|
return callback(new Error('[[error:not-logged-in]]'));
|
||||||
}
|
}
|
||||||
user.search({query: data.query, by: data.by}, callback);
|
user.search({
|
||||||
|
query: data.query,
|
||||||
|
page: data.page,
|
||||||
|
searchBy: data.searchBy,
|
||||||
|
sortBy: data.sortBy,
|
||||||
|
filterBy: data.filterBy
|
||||||
|
}, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Password Reset
|
// Password Reset
|
||||||
|
|||||||
@@ -83,7 +83,6 @@ var async = require('async'),
|
|||||||
};
|
};
|
||||||
|
|
||||||
User.getUsersData = function(uids, callback) {
|
User.getUsersData = function(uids, callback) {
|
||||||
|
|
||||||
if (!Array.isArray(uids) || !uids.length) {
|
if (!Array.isArray(uids) || !uids.length) {
|
||||||
return callback(null, []);
|
return callback(null, []);
|
||||||
}
|
}
|
||||||
@@ -237,8 +236,7 @@ var async = require('async'),
|
|||||||
if (!user) {
|
if (!user) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
user.status = !user.status ? 'online' : user.status;
|
user.status = User.getStatus(user.status, results.isOnline[index]);
|
||||||
user.status = !results.isOnline[index] ? 'offline' : user.status;
|
|
||||||
user.administrator = results.isAdmin[index];
|
user.administrator = results.isAdmin[index];
|
||||||
user.banned = parseInt(user.banned, 10) === 1;
|
user.banned = parseInt(user.banned, 10) === 1;
|
||||||
user['email:confirmed'] = parseInt(user['email:confirmed'], 10) === 1;
|
user['email:confirmed'] = parseInt(user['email:confirmed'], 10) === 1;
|
||||||
@@ -248,6 +246,10 @@ var async = require('async'),
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
User.getStatus = function(status, isOnline) {
|
||||||
|
return isOnline ? (status || 'online') : 'offline';
|
||||||
|
};
|
||||||
|
|
||||||
User.createGravatarURLFromEmail = function(email) {
|
User.createGravatarURLFromEmail = function(email) {
|
||||||
var customGravatarDefaultImage = meta.config.customGravatarDefaultImage;
|
var customGravatarDefaultImage = meta.config.customGravatarDefaultImage;
|
||||||
if (customGravatarDefaultImage && customGravatarDefaultImage.indexOf('http') === -1) {
|
if (customGravatarDefaultImage && customGravatarDefaultImage.indexOf('http') === -1) {
|
||||||
|
|||||||
@@ -2,65 +2,198 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var async = require('async'),
|
var async = require('async'),
|
||||||
|
meta = require('../meta'),
|
||||||
|
user = require('../user'),
|
||||||
db = require('../database');
|
db = require('../database');
|
||||||
|
|
||||||
module.exports = function(User) {
|
module.exports = function(User) {
|
||||||
|
|
||||||
User.search = function(data, callback) {
|
User.search = function(data, callback) {
|
||||||
var query = data.query;
|
var query = data.query;
|
||||||
var by = data.by || 'username';
|
var searchBy = data.searchBy || ['username'];
|
||||||
var startsWith = data.hasOwnProperty('startsWith') ? data.startsWith : true;
|
var startsWith = data.hasOwnProperty('startsWith') ? data.startsWith : true;
|
||||||
|
var page = data.page || 1;
|
||||||
|
|
||||||
if (!query || query.length === 0) {
|
if (!query) {
|
||||||
return callback(null, {timing:0, users:[]});
|
return callback(null, {timing: 0, users: [], matchCount: 0, pages: []});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (by === 'ip') {
|
if (searchBy === 'ip') {
|
||||||
return searchByIP(query, callback);
|
return searchByIP(query, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
var start = process.hrtime();
|
var startTime = process.hrtime();
|
||||||
var key = by + ':uid';
|
var keys = searchBy.map(function(searchBy) {
|
||||||
|
return searchBy + ':uid';
|
||||||
|
});
|
||||||
|
|
||||||
db.getObject(key, function(err, hash) {
|
var resultsPerPage = parseInt(meta.config.userSearchResultsPerPage, 10) || 20;
|
||||||
if (err || !hash) {
|
var start = Math.max(0, page - 1) * resultsPerPage;
|
||||||
return callback(null, {timing: 0, users:[]});
|
var end = start + resultsPerPage;
|
||||||
|
var pageCount = 1;
|
||||||
|
var matchCount = 0;
|
||||||
|
var filterBy = Array.isArray(data.filterBy) ? data.filterBy : [];
|
||||||
|
|
||||||
|
async.waterfall([
|
||||||
|
function(next) {
|
||||||
|
findUids(query, keys, startsWith, next);
|
||||||
|
},
|
||||||
|
function(uids, next) {
|
||||||
|
filterAndSortUids(uids, filterBy, data.sortBy, next);
|
||||||
|
},
|
||||||
|
function(uids, next) {
|
||||||
|
matchCount = uids.length;
|
||||||
|
uids = uids.slice(start, end);
|
||||||
|
|
||||||
|
User.getUsers(uids, next);
|
||||||
|
},
|
||||||
|
function(userData, next) {
|
||||||
|
|
||||||
|
var pages = [];
|
||||||
|
if (matchCount > resultsPerPage) {
|
||||||
|
pageCount = Math.ceil(matchCount / resultsPerPage);
|
||||||
|
var currentPage = Math.max(1, Math.ceil((start + 1) / resultsPerPage));
|
||||||
|
for(var i=1; i<=pageCount; ++i) {
|
||||||
|
pages.push({page: i, active: i === currentPage});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var diff = process.hrtime(startTime);
|
||||||
|
var timing = (diff[0] * 1e3 + diff[1] / 1e6).toFixed(1);
|
||||||
|
next(null, {
|
||||||
|
timing: timing,
|
||||||
|
users: userData,
|
||||||
|
matchCount: matchCount,
|
||||||
|
pages: pages
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
], callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
function findUids(query, keys, startsWith, callback) {
|
||||||
|
db.getObjects(keys, function(err, hashes) {
|
||||||
|
if (err || !hashes) {
|
||||||
|
return callback(err, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
hashes = hashes.filter(Boolean);
|
||||||
|
|
||||||
query = query.toLowerCase();
|
query = query.toLowerCase();
|
||||||
|
|
||||||
var values = Object.keys(hash);
|
|
||||||
var uids = [];
|
var uids = [];
|
||||||
|
var resultsPerPage = parseInt(meta.config.userSearchResultsPerPage, 10) || 20;
|
||||||
|
var hardCap = resultsPerPage * 10;
|
||||||
|
|
||||||
for(var i=0; i<values.length; ++i) {
|
for(var i=0; i<hashes.length; ++i) {
|
||||||
if (startsWith) {
|
for(var field in hashes[i]) {
|
||||||
if (values[i].toLowerCase().indexOf(query) === 0) {
|
if ((startsWith && field.toLowerCase().startsWith(query)) || (!startsWith && field.toLowerCase().indexOf(query) !== -1)) {
|
||||||
uids.push(values[i]);
|
uids.push(hashes[i][field]);
|
||||||
|
if (uids.length >= hardCap) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (values[i].toLowerCase().indexOf(query) !== -1) {
|
}
|
||||||
uids.push(values[i]);
|
|
||||||
|
if (uids.length >= hardCap) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uids = uids.slice(0, 20)
|
if (hashes.length > 1) {
|
||||||
.sort(function(a, b) {
|
uids = uids.filter(function(uid, index, array) {
|
||||||
return a > b;
|
return array.indexOf(uid) === index;
|
||||||
})
|
|
||||||
.map(function(username) {
|
|
||||||
return hash[username];
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
User.getUsers(uids, function(err, userdata) {
|
callback(null, uids);
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
var diff = process.hrtime(start);
|
|
||||||
var timing = (diff[0] * 1e3 + diff[1] / 1e6).toFixed(1);
|
|
||||||
callback(null, {timing: timing, users: userdata});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
|
function filterAndSortUids(uids, filterBy, sortBy, callback) {
|
||||||
|
sortBy = sortBy || 'joindate';
|
||||||
|
|
||||||
|
var fields = filterBy.map(function(filter) {
|
||||||
|
return filter.field;
|
||||||
|
}).concat(['uid', sortBy]).filter(function(field, index, array) {
|
||||||
|
return array.indexOf(field) === index;
|
||||||
|
});
|
||||||
|
|
||||||
|
async.parallel({
|
||||||
|
userData: function(next) {
|
||||||
|
user.getMultipleUserFields(uids, fields, next);
|
||||||
|
},
|
||||||
|
isOnline: function(next) {
|
||||||
|
if (fields.indexOf('status') !== -1) {
|
||||||
|
require('../socket.io').isUsersOnline(uids, next);
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, function(err, results) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
var userData = results.userData;
|
||||||
|
|
||||||
|
if (results.isOnline) {
|
||||||
|
userData.forEach(function(userData, index) {
|
||||||
|
userData.status = user.getStatus(userData.status, results.isOnline[index]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
userData = filterUsers(userData, filterBy);
|
||||||
|
|
||||||
|
sortUsers(userData, sortBy);
|
||||||
|
|
||||||
|
uids = userData.map(function(user) {
|
||||||
|
return user && user.uid;
|
||||||
|
});
|
||||||
|
callback(null, uids);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function filterUsers(userData, filterBy) {
|
||||||
|
function passesFilter(user, filter) {
|
||||||
|
if (!user || !filter) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var userValue = user[filter.field];
|
||||||
|
if (filter.type === '=') {
|
||||||
|
return userValue === filter.value;
|
||||||
|
} else if (filter.type === '!=') {
|
||||||
|
return userValue !== filter.value;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!filterBy.length) {
|
||||||
|
return userData;
|
||||||
|
}
|
||||||
|
|
||||||
|
return userData.filter(function(user) {
|
||||||
|
for(var i=0; i<filterBy.length; ++i) {
|
||||||
|
if (!passesFilter(user, filterBy[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortUsers(userData, sortBy) {
|
||||||
|
userData.sort(function(user1, user2) {
|
||||||
|
if (sortBy === 'joindate' || sortBy === 'postcount') {
|
||||||
|
return user2[sortBy] - user1[sortBy];
|
||||||
|
} else {
|
||||||
|
if(user1[sortBy] < user2[sortBy]) {
|
||||||
|
return -1;
|
||||||
|
} else if(user1[sortBy] > user2[sortBy]) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function searchByIP(ip, callback) {
|
function searchByIP(ip, callback) {
|
||||||
var start = process.hrtime();
|
var start = process.hrtime();
|
||||||
|
|||||||
@@ -141,4 +141,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">User Search</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<form>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Number of results to display</label>
|
||||||
|
<input type="text" class="form-control" value="24" data-field="userSearchResultsPerPage">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- IMPORT admin/settings/footer.tpl -->
|
<!-- IMPORT admin/settings/footer.tpl -->
|
||||||
Reference in New Issue
Block a user