diff --git a/public/language/en_GB/search.json b/public/language/en_GB/search.json index 945e58c852..23519b038b 100644 --- a/public/language/en_GB/search.json +++ b/public/language/en_GB/search.json @@ -1,5 +1,7 @@ { "results_matching": "%1 result(s) matching \"%2\", (%3 seconds)", "no-matches": "No matches found", - "in": "In" + "in": "In", + "by": "By", + "posted-by": "Posted by" } diff --git a/public/src/app.js b/public/src/app.js index d894551064..a77200fdd9 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -437,7 +437,7 @@ app.uid = null; e.preventDefault(); var input = $(this).find('input'); - search.query(input.val(), 'posts', function() { + search.query({term: input.val(), in: 'posts'}, function() { input.val(''); }); }); diff --git a/public/src/client/search.js b/public/src/client/search.js index e08a5dc410..e536aaa160 100644 --- a/public/src/client/search.js +++ b/public/src/client/search.js @@ -1,18 +1,51 @@ +'use strict'; + +/* globals app, define, utils, socket*/ + define('forum/search', ['search'], function(searchModule) { var Search = {}; Search.init = function() { var searchQuery = $('#results').attr('data-search-query'); - var regexes = []; - var searchTerms = searchQuery.split(' '); - $('#advanced-search input').val(searchQuery); + $('#advanced-search #search-input').val(searchQuery); var params = utils.params(); + var select = $('#advanced-search select'); if (params && params.in) { - $('#advanced-search select').val(params.in); + select.val(params.in); } + if (params && params.by) { + $('.by-container #posted-by-input').val(params.by); + } + + select.on('change', function() { + $('.by-container').toggleClass('hide', select.val() !== 'posts'); + }); + + highlightMatches(searchQuery); + $('#advanced-search').off('submit').on('submit', function(e) { + e.preventDefault(); + var input = $(this).find('#search-input'); + var searchIn = $(this).find('select'); + var postedBy = $(this).find('#posted-by-input'); + + searchModule.query({ + term: input.val(), + in: searchIn.val(), + by: postedBy.val() + }, function() { + input.val(''); + }); + }); + + enableAutoComplete(); + }; + + function highlightMatches(searchQuery) { + var searchTerms = searchQuery.split(' '); + var regexes = []; for (var i=0; i'); - socket.emit('user.search', username, function(err, data) { + socket.emit('user.search', {query: username}, function(err, data) { if (err) { reset(); return app.alertError(err.message); } if (!data) { - reset(); - return; + return reset(); } 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); diff --git a/public/src/modules/search.js b/public/src/modules/search.js index 7dd7abddff..73ff828673 100644 --- a/public/src/modules/search.js +++ b/public/src/modules/search.js @@ -7,7 +7,11 @@ define('search', ['navigator'], function(nav) { current: {} }; - Search.query = function(term, searchIn, callback) { + Search.query = function(data, callback) { + var term = data.term; + var searchIn = data.in || 'posts'; + var postedBy = data.by || ''; + // Detect if a tid was specified var topicSearch = term.match(/in:topic-([\d]+)/); @@ -19,8 +23,11 @@ define('search', ['navigator'], function(nav) { } catch(e) { return app.alertError('[[error:invalid-search-term]]'); } - - ajaxify.go('search/' + term + (searchIn ? '?in=' + searchIn : '')); + var query = {in: searchIn}; + if (postedBy && searchIn === 'posts') { + query.by = postedBy; + } + ajaxify.go('search/' + term + '?' + decodeURIComponent($.param(query))); callback(); } else { var cleanedTerm = term.replace(topicSearch[0], ''), diff --git a/src/controllers/search.js b/src/controllers/search.js index 1d4aff306c..1a5690a6e7 100644 --- a/src/controllers/search.js +++ b/src/controllers/search.js @@ -28,7 +28,12 @@ searchController.search = function(req, res, next) { req.params.term = validator.escape(req.params.term); - search.search(req.params.term, req.query.in, uid, function(err, results) { + search.search({ + query: req.params.term, + searchIn: req.query.in, + postedBy: req.query.by, + uid: uid + }, function(err, results) { if (err) { return next(err); } diff --git a/src/search.js b/src/search.js index 869455b3de..c4a830f41a 100644 --- a/src/search.js +++ b/src/search.js @@ -11,7 +11,7 @@ var search = {}; module.exports = search; -search.search = function(query, searchIn, uid, callback) { +search.search = function(data, callback) { function done(err, data) { if (err) { return callback(err); @@ -20,12 +20,16 @@ search.search = function(query, searchIn, uid, callback) { result.search_query = query; result[searchIn] = data; result.matchCount = data.length; + result.hidePostedBy = searchIn !== 'posts'; result.time = (process.elapsedTimeSince(start) / 1000).toFixed(2); callback(null, result); } var start = process.hrtime(); - searchIn = searchIn || 'posts'; + + var query = data.query; + var searchIn = data.searchIn || 'posts'; + var uid = data.uid || 0; var result = { posts: [], @@ -34,7 +38,7 @@ search.search = function(query, searchIn, uid, callback) { }; if (searchIn === 'posts') { - searchInPosts(query, uid, done); + searchInPosts(query, data.postedBy, uid, done); } else if (searchIn === 'users') { searchInUsers(query, done); } else if (searchIn === 'tags') { @@ -44,13 +48,20 @@ search.search = function(query, searchIn, uid, callback) { } }; -function searchInPosts(query, uid, callback) { +function searchInPosts(query, postedBy, uid, callback) { async.parallel({ pids: function(next) { searchQuery('post', query, next); }, tids: function(next) { searchQuery('topic', query, next); + }, + postedByUid: function(next) { + if (postedBy) { + user.getUidByUsername(postedBy, next); + } else { + next(null, 0); + } } }, function (err, results) { if (err) { @@ -75,6 +86,14 @@ function searchInPosts(query, uid, callback) { }, function(pids, next) { posts.getPostSummaryByPids(pids, uid, {stripTags: true, parse: false}, next); + }, + function(posts, next) { + if (postedBy) { + posts = posts.filter(function(post) { + return post && parseInt(post.uid, 10) === parseInt(results.postedByUid, 10); + }); + } + next(null, posts); } ], callback); }); diff --git a/src/socket.io/user.js b/src/socket.io/user.js index e20ff65bbb..392327c93f 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -62,11 +62,14 @@ SocketUser.increaseViewCount = function(socket, uid, callback) { } }; -SocketUser.search = function(socket, username, callback) { +SocketUser.search = function(socket, data, callback) { + if (!data) { + return callback(new Error('[[error:invalid-data]]')) + } if (!socket.uid) { return callback(new Error('[[error:not-logged-in]]')); } - user.search({query: username}, callback); + user.search({query: data.query}, callback); }; // Password Reset