mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 11:05:54 +01:00 
			
		
		
		
	part 1
no upgrade script yet
This commit is contained in:
		| @@ -118,25 +118,18 @@ define('forum/users', ['translator'], function(translator) { | ||||
| 		var notify = $('#user-notfound-notify'); | ||||
| 		page = page || 1; | ||||
|  | ||||
| 		if (!username) { | ||||
| 			return loadPage(page); | ||||
| 		} | ||||
|  | ||||
| 		notify.html('<i class="fa fa-spinner fa-spin"></i>'); | ||||
| 		var filters = []; | ||||
| 		$('.user-filter').each(function() { | ||||
| 			var $this = $(this); | ||||
| 			if($this.is(':checked')) { | ||||
| 				filters.push({ | ||||
| 					field:$this.attr('data-filter-field'), | ||||
| 					type: $this.attr('data-filter-type'), | ||||
| 					value: $this.attr('data-filter-value') | ||||
| 				}); | ||||
| 			} | ||||
| 		}); | ||||
|  | ||||
| 		socket.emit('user.search', { | ||||
| 			query: username, | ||||
| 			page: page, | ||||
| 			searchBy: ['username', 'fullname'], | ||||
| 			searchBy: 'username', | ||||
| 			sortBy: $('.search select').val(), | ||||
| 			filterBy: filters | ||||
| 			onlineOnly: $('.search .online-only').is(':checked') | ||||
| 		}, function(err, data) { | ||||
| 			if (err) { | ||||
| 				reset(); | ||||
| @@ -147,26 +140,42 @@ define('forum/users', ['translator'], function(translator) { | ||||
| 				return reset(); | ||||
| 			} | ||||
|  | ||||
| 			templates.parse('partials/paginator', {pagination: data.pagination}, function(html) { | ||||
| 				$('.pagination-container').replaceWith(html); | ||||
| 			}); | ||||
| 			renderSearchResults(data); | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 			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'); | ||||
| 						}); | ||||
| 					} | ||||
| 				}); | ||||
| 	function loadPage(page) { | ||||
| 		socket.emit('user.loadPage', {page: page, sortBy: $('.search select').val(), onlineOnly: $('.search .online-only').is(':checked')}, function(err, data) { | ||||
| 			if (err) { | ||||
| 				return app.alertError(err.message); | ||||
| 			} | ||||
|  | ||||
| 			renderSearchResults(data); | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	function renderSearchResults(data) { | ||||
| 		var notify = $('#user-notfound-notify'); | ||||
| 		templates.parse('partials/paginator', {pagination: data.pagination}, function(html) { | ||||
| 			$('.pagination-container').replaceWith(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'); | ||||
| 					}); | ||||
| 				} | ||||
| 			}); | ||||
| 		}); | ||||
| 	} | ||||
|   | ||||
| @@ -48,26 +48,26 @@ usersController.getOnlineUsers = function(req, res, next) { | ||||
| }; | ||||
|  | ||||
| usersController.getUsersSortedByPosts = function(req, res, next) { | ||||
| 	usersController.getUsers('users:postcount', 50, req, res, next); | ||||
| 	usersController.getUsers('users:postcount', 0, 49, req, res, next); | ||||
| }; | ||||
|  | ||||
| usersController.getUsersSortedByReputation = function(req, res, next) { | ||||
| 	usersController.getUsers('users:reputation', 50, req, res, next); | ||||
| 	usersController.getUsers('users:reputation', 0, 49, req, res, next); | ||||
| }; | ||||
|  | ||||
| usersController.getUsersSortedByJoinDate = function(req, res, next) { | ||||
| 	usersController.getUsers('users:joindate', 50, req, res, next); | ||||
| 	usersController.getUsers('users:joindate', 0, 49, req, res, next); | ||||
| }; | ||||
|  | ||||
| usersController.getUsers = function(set, count, req, res, next) { | ||||
| 	getUsersAndCount(set, req.uid, count, function(err, data) { | ||||
| usersController.getUsers = function(set, start, stop, req, res, next) { | ||||
| 	usersController.getUsersAndCount(set, req.uid, start, stop, function(err, data) { | ||||
| 		if (err) { | ||||
| 			return next(err); | ||||
| 		} | ||||
| 		var pageCount = Math.ceil(data.count / (parseInt(meta.config.userSearchResultsPerPage, 10) || 20)); | ||||
| 		var userData = { | ||||
| 			search_display: 'hidden', | ||||
| 			loadmore_display: data.count > count ? 'block' : 'hide', | ||||
| 			loadmore_display: data.count > (stop - start + 1) ? 'block' : 'hide', | ||||
| 			users: data.users, | ||||
| 			pagination: pagination.create(1, pageCount) | ||||
| 		}; | ||||
| @@ -76,13 +76,13 @@ usersController.getUsers = function(set, count, req, res, next) { | ||||
| 	}); | ||||
| }; | ||||
|  | ||||
| function getUsersAndCount(set, uid, count, callback) { | ||||
| usersController.getUsersAndCount = function(set, uid, start, stop, callback) { | ||||
| 	async.parallel({ | ||||
| 		users: function(next) { | ||||
| 			user.getUsersFromSet(set, uid, 0, count - 1, next); | ||||
| 			user.getUsersFromSet(set, uid, start, stop, next); | ||||
| 		}, | ||||
| 		count: function(next) { | ||||
| 			db.getObjectField('global', 'userCount', next); | ||||
| 			db.sortedSetCard(set, next); | ||||
| 		} | ||||
| 	}, function(err, results) { | ||||
| 		if (err) { | ||||
| @@ -94,7 +94,7 @@ function getUsersAndCount(set, uid, count, callback) { | ||||
|  | ||||
| 		callback(null, results); | ||||
| 	}); | ||||
| } | ||||
| }; | ||||
|  | ||||
| usersController.getUsersForSearch = function(req, res, next) { | ||||
| 	if (!req.uid) { | ||||
| @@ -102,7 +102,7 @@ usersController.getUsersForSearch = function(req, res, next) { | ||||
| 	} | ||||
| 	var resultsPerPage = parseInt(meta.config.userSearchResultsPerPage, 10) || 20; | ||||
|  | ||||
| 	getUsersAndCount('users:joindate', req.uid, resultsPerPage, function(err, data) { | ||||
| 	usersController.getUsersAndCount('users:joindate', req.uid, 0, resultsPerPage - 1, function(err, data) { | ||||
| 		if (err) { | ||||
| 			return next(err); | ||||
| 		} | ||||
|   | ||||
| @@ -509,4 +509,28 @@ module.exports = function(db, module) { | ||||
| 			callback(err, result && result.value ? result.value.score : null); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.getSortedSetRangeByLex = function(key, min, max, start, count, callback) { | ||||
| 		var query = {_key: key}; | ||||
| 		if (min !== '-') { | ||||
| 			query.value = {$gte: min}; | ||||
| 		} | ||||
| 		if (max !== '+') { | ||||
| 			query.value = query.value || {}; | ||||
| 			query.value.$lte = max; | ||||
| 		} | ||||
| 		db.collection('objects').find(query, {_id: 0, value: 1}) | ||||
| 			.sort({value: 1}) | ||||
| 			.skip(start) | ||||
| 			.limit(count === -1 ? 0 : count) | ||||
| 			.toArray(function(err, data) { | ||||
| 				if (err) { | ||||
| 					return callback(err); | ||||
| 				} | ||||
| 				data = data.map(function(item) { | ||||
| 					return item && item.value; | ||||
| 				}); | ||||
| 				callback(err, data); | ||||
| 		}); | ||||
| 	}; | ||||
| }; | ||||
| @@ -246,4 +246,14 @@ module.exports = function(redisClient, module) { | ||||
| 	module.sortedSetIncrBy = function(key, increment, value, callback) { | ||||
| 		redisClient.zincrby(key, increment, value, callback); | ||||
| 	}; | ||||
|  | ||||
| 	module.getSortedSetRangeByLex = function(key, min, max, start, count, callback) { | ||||
| 		if (min !== '-') { | ||||
| 			min = '[' + min; | ||||
| 		} | ||||
| 		if (max !== '+') { | ||||
| 			max = '(' + max; | ||||
| 		} | ||||
| 		redisClient.zrangebylex([key, min, max, 'LIMIT', start, count], callback); | ||||
| 	}; | ||||
| }; | ||||
| @@ -1144,7 +1144,7 @@ var async = require('async'), | ||||
|  | ||||
| 	Groups.searchMembers = function(data, callback) { | ||||
|  | ||||
| 		function findUids(query, searchBy, startsWith, callback) { | ||||
| 		function findUids(query, searchBy, callback) { | ||||
| 			if (!query) { | ||||
| 				return Groups.getMembers(data.groupName, 0, -1, callback); | ||||
| 			} | ||||
| @@ -1154,25 +1154,16 @@ var async = require('async'), | ||||
| 					Groups.getMembers(data.groupName, 0, -1, next); | ||||
| 				}, | ||||
| 				function(members, next) { | ||||
| 					user.getMultipleUserFields(members, ['uid'].concat(searchBy), next); | ||||
| 					user.getMultipleUserFields(members, ['uid'].concat([searchBy]), next); | ||||
| 				}, | ||||
| 				function(users, next) { | ||||
| 					var uids = []; | ||||
|  | ||||
| 					for(var k=0; k<searchBy.length; ++k) { | ||||
| 						for(var i=0; i<users.length; ++i) { | ||||
| 							var field = users[i][searchBy[k]]; | ||||
| 							if ((startsWith && field.toLowerCase().startsWith(query)) || (!startsWith && field.toLowerCase().indexOf(query) !== -1)) { | ||||
| 								uids.push(users[i].uid); | ||||
| 							} | ||||
| 					for(var i=0; i<users.length; ++i) { | ||||
| 						var field = users[i][searchBy[k]]; | ||||
| 						if (field.toLowerCase().startsWith(query)) { | ||||
| 							uids.push(users[i].uid); | ||||
| 						} | ||||
| 					} | ||||
| 					if (searchBy.length > 1) { | ||||
| 						uids = uids.filter(function(uid, index, array) { | ||||
| 							return array.indexOf(uid) === index; | ||||
| 						}); | ||||
| 					} | ||||
|  | ||||
| 					next(null, uids); | ||||
| 				} | ||||
| 			], callback); | ||||
|   | ||||
| @@ -205,7 +205,7 @@ User.deleteUsers = function(socket, uids, callback) { | ||||
| }; | ||||
|  | ||||
| User.search = function(socket, data, callback) { | ||||
| 	user.search({query: data.query, searchBy: data.searchBy, startsWith: false, uid: socket.uid}, function(err, searchData) { | ||||
| 	user.search({query: data.query, searchBy: data.searchBy, uid: socket.uid}, function(err, searchData) { | ||||
| 		if (err) { | ||||
| 			return callback(err); | ||||
| 		} | ||||
|   | ||||
| @@ -77,7 +77,7 @@ SocketUser.search = function(socket, data, callback) { | ||||
| 		page: data.page, | ||||
| 		searchBy: data.searchBy, | ||||
| 		sortBy: data.sortBy, | ||||
| 		filterBy: data.filterBy, | ||||
| 		onlineOnly: data.onlineOnly, | ||||
| 		uid: socket.uid | ||||
| 	}, callback); | ||||
| }; | ||||
| @@ -431,6 +431,60 @@ SocketUser.loadMore = function(socket, data, callback) { | ||||
| 	}); | ||||
| }; | ||||
|  | ||||
| SocketUser.loadPage = function(socket, data, callback) { | ||||
| 	function done(err, result) { | ||||
| 		if (err) { | ||||
| 			return callback(err); | ||||
| 		} | ||||
| 		var pageCount = Math.ceil(result.count / resultsPerPage); | ||||
| 		var userData = { | ||||
| 			users: result.users, | ||||
| 			pagination: pagination.create(data.page, pageCount) | ||||
| 		}; | ||||
|  | ||||
| 		callback(null, userData); | ||||
| 	} | ||||
|  | ||||
| 	var controllers = require('../controllers/users'); | ||||
| 	var pagination = require('../pagination'); | ||||
| 	var set = ''; | ||||
| 	data.sortBy = data.sortBy || 'joindate'; | ||||
|  | ||||
| 	var resultsPerPage = parseInt(meta.config.userSearchResultsPerPage, 10) || 20; | ||||
| 	var start = Math.max(0, data.page - 1) * resultsPerPage; | ||||
| 	var stop = start + resultsPerPage - 1; | ||||
| 	if (data.onlineOnly) { | ||||
| 		async.parallel({ | ||||
| 			users: function(next) { | ||||
| 				user.getUsersFromSet('users:online', socket.uid, 0, 49, next); | ||||
| 			}, | ||||
| 			count: function(next) { | ||||
| 				var now = Date.now(); | ||||
| 				db.sortedSetCount('users:online', now - 300000, now, next); | ||||
| 			} | ||||
| 		}, done); | ||||
| 	} else if (data.sortBy === 'username') { | ||||
| 		async.parallel({ | ||||
| 			count: function(next) { | ||||
| 				db.sortedSetCard('username:sorted', next); | ||||
| 			}, | ||||
| 			users: function(next) { | ||||
| 				db.getSortedSetRangeByLex('username:sorted', '-', '+', start, stop - start + 1, function(err, result) { | ||||
| 					if (err) { | ||||
| 						return next(err); | ||||
| 					} | ||||
| 					var uids = result.map(function(user) { | ||||
| 						return user && user.split(':')[1]; | ||||
| 					}); | ||||
| 					user.getUsers(uids, socket.uid, next); | ||||
| 				}); | ||||
| 			} | ||||
| 		}, done); | ||||
| 	} else { | ||||
| 		controllers.getUsersAndCount('users:joindate', socket.uid, start, stop, done); | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| SocketUser.setStatus = function(socket, status, callback) { | ||||
| 	if (!socket.uid) { | ||||
| 		return callback(new Error('[[error:invalid-uid]]')); | ||||
|   | ||||
| @@ -93,6 +93,9 @@ module.exports = function(User) { | ||||
| 							function(next) { | ||||
| 								db.sortedSetAdd('username:uid', userData.uid, userData.username, next); | ||||
| 							}, | ||||
| 							function(next) { | ||||
| 								db.sortedSetAdd('username:sorted', 0, userData.username.toLowerCase() + ':' + userData.uid, next); | ||||
| 							}, | ||||
| 							function(next) { | ||||
| 								db.sortedSetAdd('userslug:uid', userData.uid, userData.userslug, next); | ||||
| 							}, | ||||
| @@ -107,7 +110,11 @@ module.exports = function(User) { | ||||
| 							}, | ||||
| 							function(next) { | ||||
| 								if (userData.email) { | ||||
| 									db.sortedSetAdd('email:uid', userData.uid, userData.email.toLowerCase(), next); | ||||
| 									async.parallel([ | ||||
| 										async.apply(db.sortedSetAdd, 'email:uid', userData.uid, userData.email.toLowerCase()), | ||||
| 										async.apply(db.sortedSetAdd, 'email:sorted', 0, userData.email.toLowerCase() + ':' + userData.uid) | ||||
| 									], next); | ||||
|  | ||||
| 									if (parseInt(userData.uid, 10) !== 1 && parseInt(meta.config.requireEmailConfirmation, 10) === 1) { | ||||
| 										User.email.sendValidationEmail(userData.uid, userData.email); | ||||
| 									} | ||||
|   | ||||
| @@ -51,6 +51,9 @@ module.exports = function(User) { | ||||
| 				function(next) { | ||||
| 					db.sortedSetRemove('username:uid', userData.username, next); | ||||
| 				}, | ||||
| 				function(next) { | ||||
| 					db.sortedSetRemove('username:sorted', userData.username.toLowerCase() + ':' + uid, next); | ||||
| 				}, | ||||
| 				function(next) { | ||||
| 					db.sortedSetRemove('userslug:uid', userData.userslug, next); | ||||
| 				}, | ||||
| @@ -59,7 +62,10 @@ module.exports = function(User) { | ||||
| 				}, | ||||
| 				function(next) { | ||||
| 					if (userData.email) { | ||||
| 						db.sortedSetRemove('email:uid', userData.email.toLowerCase(), next); | ||||
| 						async.parallel([ | ||||
| 							async.apply(db.sortedSetRemove, 'email:uid', userData.email.toLowerCase()), | ||||
| 							async.apply(db.sortedSetRemove, 'email:sorted', userData.email.toLowerCase() + ':' + uid) | ||||
| 						], next); | ||||
| 					} else { | ||||
| 						next(); | ||||
| 					} | ||||
|   | ||||
| @@ -164,8 +164,10 @@ module.exports = function(User) { | ||||
| 			if (userData.email === newEmail) { | ||||
| 				return callback(); | ||||
| 			} | ||||
|  | ||||
| 			db.sortedSetRemove('email:uid', userData.email.toLowerCase(), function(err) { | ||||
| 			async.series([ | ||||
| 				async.apply(db.sortedSetRemove, 'email:uid', userData.email.toLowerCase()), | ||||
| 				async.apply(db.sortedSetRemove, 'email:sorted', userData.email.toLowerCase() + ':' + uid) | ||||
| 			], function(err) { | ||||
| 				if (err) { | ||||
| 					return callback(err); | ||||
| 				} | ||||
| @@ -178,6 +180,9 @@ module.exports = function(User) { | ||||
| 					function(next) { | ||||
| 						db.sortedSetAdd('email:uid', uid, newEmail.toLowerCase(), next); | ||||
| 					}, | ||||
| 					function(next) { | ||||
| 						db.sortedSetAdd('email:sorted',  0, newEmail.toLowerCase() + ':' + uid, next); | ||||
| 					}, | ||||
| 					function(next) { | ||||
| 						User.setUserField(uid, 'email', newEmail, next); | ||||
| 					}, | ||||
| @@ -216,7 +221,13 @@ module.exports = function(User) { | ||||
| 				function(next) { | ||||
| 					var newUserslug = utils.slugify(newUsername); | ||||
| 					updateUidMapping('userslug', uid, newUserslug, userData.userslug, next); | ||||
| 				} | ||||
| 				}, | ||||
| 				function(next) { | ||||
| 					async.series([ | ||||
| 						async.apply(db.sortedSetRemove, 'username:sorted', userData.username.toLowerCase() + ':' + uid), | ||||
| 						async.apply(db.sortedSetAdd, 'username:sorted', 0, newUsername.toLowerCase() + ':' + uid) | ||||
| 					], next); | ||||
| 				}, | ||||
| 			], callback); | ||||
| 		}); | ||||
| 	} | ||||
|   | ||||
| @@ -11,8 +11,7 @@ module.exports = function(User) { | ||||
|  | ||||
| 	User.search = function(data, callback) { | ||||
| 		var query = data.query || ''; | ||||
| 		var searchBy = data.searchBy || ['username']; | ||||
| 		var startsWith = data.hasOwnProperty('startsWith') ? data.startsWith : true; | ||||
| 		var searchBy = data.searchBy || 'username'; | ||||
| 		var page = data.page || 1; | ||||
| 		var uid = data.uid || 0; | ||||
| 		var paginate = data.hasOwnProperty('paginate') ? data.paginate : true; | ||||
| @@ -27,14 +26,13 @@ module.exports = function(User) { | ||||
| 		async.waterfall([ | ||||
| 			function(next) { | ||||
| 				if (data.findUids) { | ||||
| 					data.findUids(query, searchBy, startsWith, next); | ||||
| 					data.findUids(query, searchBy, next); | ||||
| 				} else { | ||||
| 					findUids(query, searchBy, startsWith, next); | ||||
| 					findUids(query, searchBy, next); | ||||
| 				} | ||||
| 			}, | ||||
| 			function(uids, next) { | ||||
| 				var filterBy = Array.isArray(data.filterBy) ? data.filterBy : []; | ||||
| 				filterAndSortUids(uids, filterBy, data.sortBy, next); | ||||
| 				filterAndSortUids(uids, data, next); | ||||
| 			}, | ||||
| 			function(uids, next) { | ||||
| 				plugins.fireHook('filter:users.search', {uids: uids, uid: uid}, next); | ||||
| @@ -75,70 +73,39 @@ module.exports = function(User) { | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	function findUids(query, searchBy, startsWith, callback) { | ||||
| 	function findUids(query, searchBy, callback) { | ||||
| 		if (!query) { | ||||
| 			return db.getSortedSetRevRange('users:joindate', 0, -1, callback); | ||||
| 			return callback(null, []); | ||||
| 		} | ||||
| 		var min = query; | ||||
| 		var max = query.substr(0, query.length - 1) + String.fromCharCode(query.charCodeAt(query.length - 1) + 1); | ||||
|  | ||||
| 		var keys = searchBy.map(function(searchBy) { | ||||
| 			return searchBy + ':uid'; | ||||
| 		}); | ||||
| 		var resultsPerPage = parseInt(meta.config.userSearchResultsPerPage, 10) || 20; | ||||
| 		var hardCap = resultsPerPage * 10; | ||||
|  | ||||
| 		async.map(keys, function(key, next) { | ||||
| 			db.getSortedSetRangeWithScores(key, 0, -1, next); | ||||
| 		}, function(err, hashes) { | ||||
| 			if (err || !hashes) { | ||||
| 				return callback(err, []); | ||||
| 			} | ||||
|  | ||||
| 			hashes = hashes.filter(Boolean); | ||||
|  | ||||
| 			query = query.toLowerCase(); | ||||
|  | ||||
| 			var uids = []; | ||||
| 			var resultsPerPage = parseInt(meta.config.userSearchResultsPerPage, 10) || 20; | ||||
| 			var hardCap = resultsPerPage * 10; | ||||
|  | ||||
| 			for (var i=0; i<hashes.length; ++i) { | ||||
| 				for (var k=0; k<hashes[i].length; ++k) { | ||||
| 					var field = hashes[i][k].value; | ||||
| 					if ((startsWith && field.toLowerCase().startsWith(query)) || (!startsWith && field.toLowerCase().indexOf(query) !== -1)) { | ||||
| 						uids.push(hashes[i][k].score); | ||||
| 						if (uids.length >= hardCap) { | ||||
| 							break; | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 				if (uids.length >= hardCap) { | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			if (hashes.length > 1) { | ||||
| 				uids = uids.filter(function(uid, index, array) { | ||||
| 					return array.indexOf(uid) === index; | ||||
| 				}); | ||||
| 		db.getSortedSetRangeByLex(searchBy + ':sorted', min, max, 0, hardCap, function(err, data) { | ||||
| 			if (err) { | ||||
| 				return callback(err); | ||||
| 			} | ||||
|  | ||||
| 			var uids = data.map(function(data) { | ||||
| 				return data.split(':')[1]; | ||||
| 			}); | ||||
| 			callback(null, uids); | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	function filterAndSortUids(uids, filterBy, sortBy, callback) { | ||||
| 		sortBy = sortBy || 'joindate'; | ||||
| 	function filterAndSortUids(uids, data, callback) { | ||||
| 		var sortBy = data.sortBy || 'joindate'; | ||||
|  | ||||
| 		var fields = filterBy.map(function(filter) { | ||||
| 			return filter.field; | ||||
| 		}).concat(['uid', sortBy]).filter(function(field, index, array) { | ||||
| 			return array.indexOf(field) === index; | ||||
| 		}); | ||||
| 		var fields = ['uid', 'status', sortBy]; | ||||
|  | ||||
| 		async.parallel({ | ||||
| 			userData: function(next) { | ||||
| 				User.getMultipleUserFields(uids, fields, next); | ||||
| 			}, | ||||
| 			isOnline: function(next) { | ||||
| 				if (fields.indexOf('status') !== -1) { | ||||
| 				if (data.onlineOnly) { | ||||
| 					require('../socket.io').isUsersOnline(uids, next); | ||||
| 				} else { | ||||
| 					next(); | ||||
| @@ -148,53 +115,25 @@ module.exports = function(User) { | ||||
| 			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]); | ||||
| 			if (data.onlineOnly) { | ||||
| 				userData = userData.filter(function(user, index) { | ||||
| 					return user && user.status !== 'offline' && 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) { | ||||
| 		if (sortBy === 'joindate' || sortBy === 'postcount') { | ||||
| 			userData.sort(function(u1, u2) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user