search in categories and children

v1.18.x
barisusakli 10 years ago
parent f7ccdc3668
commit def600e927

@ -3,5 +3,7 @@
"no-matches": "No matches found", "no-matches": "No matches found",
"in": "In", "in": "In",
"by": "By", "by": "By",
"posted-by": "Posted by" "posted-by": "Posted by",
"in-categories": "In Categories",
"search-child-categories": "Search child categories"
} }

@ -10,17 +10,25 @@ define('forum/search', ['search'], function(searchModule) {
$('#advanced-search #search-input').val(searchQuery); $('#advanced-search #search-input').val(searchQuery);
var params = utils.params(); var params = utils.params();
var select = $('#advanced-search select'); var searchIn = $('#advanced-search #search-in');
if (params && params.in) { if (params && params.in) {
select.val(params.in); searchIn.val(params.in);
} }
if (params && params.by) { if (params && params.by) {
$('.by-container #posted-by-input').val(params.by); $('.by-container #posted-by-user').val(params.by);
} }
select.on('change', function() { if (params && params['categories[]']) {
$('.by-container').toggleClass('hide', select.val() !== 'posts'); $('#posted-in-categories').val(params['categories[]']);
}
if (params && params.searchChildren) {
$('#search-children').prop('checked', true);
}
searchIn.on('change', function() {
$('.by-container').toggleClass('hide', searchIn.val() !== 'posts');
}); });
highlightMatches(searchQuery); highlightMatches(searchQuery);
@ -28,13 +36,13 @@ define('forum/search', ['search'], function(searchModule) {
$('#advanced-search').off('submit').on('submit', function(e) { $('#advanced-search').off('submit').on('submit', function(e) {
e.preventDefault(); e.preventDefault();
var input = $(this).find('#search-input'); var input = $(this).find('#search-input');
var searchIn = $(this).find('select');
var postedBy = $(this).find('#posted-by-input');
searchModule.query({ searchModule.query({
term: input.val(), term: input.val(),
in: searchIn.val(), in: $(this).find('#search-in').val(),
by: postedBy.val() by: $(this).find('#posted-by-user').val(),
categories: $(this).find('#posted-in-categories').val(),
searchChildren: $(this).find('#search-children').is(':checked')
}, function() { }, function() {
input.val(''); input.val('');
}); });
@ -63,7 +71,7 @@ define('forum/search', ['search'], function(searchModule) {
function enableAutoComplete() { function enableAutoComplete() {
var input = $('.by-container #posted-by-input'); var input = $('.by-container #posted-by-user');
input.autocomplete({ input.autocomplete({
delay: 100, delay: 100,
source: function(request, response) { source: function(request, response) {

@ -27,6 +27,13 @@ define('search', ['navigator'], function(nav) {
if (postedBy && searchIn === 'posts') { if (postedBy && searchIn === 'posts') {
query.by = postedBy; query.by = postedBy;
} }
if (data.categories && data.categories.length) {
query.categories = data.categories;
if (data.searchChildren) {
query.searchChildren = data.searchChildren;
}
}
ajaxify.go('search/' + term + '?' + decodeURIComponent($.param(query))); ajaxify.go('search/' + term + '?' + decodeURIComponent($.param(query)));
callback(); callback();
} else { } else {

@ -256,7 +256,14 @@
value = options.skipToType[key] ? decodeURI(val[1]) : utils.toType(decodeURI(val[1])); value = options.skipToType[key] ? decodeURI(val[1]) : utils.toType(decodeURI(val[1]));
if (key) { if (key) {
if (!hash[key]) {
hash[key] = value; hash[key] = value;
} else {
if (!$.isArray(hash[key])) {
hash[key] = [hash[key]];
}
hash[key].push(value);
}
} }
}); });
return hash; return hash;

@ -5,6 +5,7 @@ var searchController = {},
validator = require('validator'), validator = require('validator'),
plugins = require('../plugins'), plugins = require('../plugins'),
search = require('../search'), search = require('../search'),
categories = require('../categories'),
helpers = require('./helpers'); helpers = require('./helpers');
@ -12,7 +13,15 @@ searchController.search = function(req, res, next) {
if (!plugins.hasListeners('filter:search.query')) { if (!plugins.hasListeners('filter:search.query')) {
return helpers.notFound(req, res); return helpers.notFound(req, res);
} }
var uid = req.user ? req.user.uid : 0;
var breadcrumbs = helpers.buildBreadcrumbs([{text: '[[global:search]]'}]); var breadcrumbs = helpers.buildBreadcrumbs([{text: '[[global:search]]'}]);
categories.getCategoriesByPrivilege(uid, 'read', function(err, categories) {
if (err) {
return next(err);
}
if (!req.params.term) { if (!req.params.term) {
return res.render('search', { return res.render('search', {
time: 0, time: 0,
@ -21,18 +30,19 @@ searchController.search = function(req, res, next) {
topics: [], topics: [],
users: [], users: [],
tags: [], tags: [],
categories: categories,
breadcrumbs: breadcrumbs breadcrumbs: breadcrumbs
}); });
} }
var uid = req.user ? req.user.uid : 0;
req.params.term = validator.escape(req.params.term); req.params.term = validator.escape(req.params.term);
search.search({ search.search({
query: req.params.term, query: req.params.term,
searchIn: req.query.in, searchIn: req.query.in,
postedBy: req.query.by, postedBy: req.query.by,
categories: req.query.categories,
searchChildren: req.query.searchChildren,
uid: uid uid: uid
}, function(err, results) { }, function(err, results) {
if (err) { if (err) {
@ -40,8 +50,10 @@ searchController.search = function(req, res, next) {
} }
results.breadcrumbs = breadcrumbs; results.breadcrumbs = breadcrumbs;
results.categories = categories;
res.render('search', results); res.render('search', results);
}); });
});
}; };

@ -3,6 +3,7 @@
var async = require('async'), var async = require('async'),
posts = require('./posts'), posts = require('./posts'),
topics = require('./topics'), topics = require('./topics'),
categories = require('./categories'),
user = require('./user'), user = require('./user'),
plugins = require('./plugins'), plugins = require('./plugins'),
privileges = require('./privileges'); privileges = require('./privileges');
@ -29,7 +30,6 @@ search.search = function(data, callback) {
var query = data.query; var query = data.query;
var searchIn = data.searchIn || 'posts'; var searchIn = data.searchIn || 'posts';
var uid = data.uid || 0;
var result = { var result = {
posts: [], posts: [],
@ -38,7 +38,7 @@ search.search = function(data, callback) {
}; };
if (searchIn === 'posts') { if (searchIn === 'posts') {
searchInPosts(query, data.postedBy, uid, done); searchInPosts(query, data, done);
} else if (searchIn === 'users') { } else if (searchIn === 'users') {
searchInUsers(query, done); searchInUsers(query, done);
} else if (searchIn === 'tags') { } else if (searchIn === 'tags') {
@ -48,7 +48,9 @@ search.search = function(data, callback) {
} }
}; };
function searchInPosts(query, postedBy, uid, callback) { function searchInPosts(query, data, callback) {
data.uid = data.uid || 0;
var postedBy = data.postedBy || '';
async.parallel({ async.parallel({
pids: function(next) { pids: function(next) {
searchQuery('post', query, next); searchQuery('post', query, next);
@ -56,12 +58,8 @@ function searchInPosts(query, postedBy, uid, callback) {
tids: function(next) { tids: function(next) {
searchQuery('topic', query, next); searchQuery('topic', query, next);
}, },
postedByUid: function(next) { searchCategories: function(next) {
if (postedBy) { getSearchCategories(data, next);
user.getUidByUsername(postedBy, next);
} else {
next(null, 0);
}
} }
}, function (err, results) { }, function (err, results) {
if (err) { if (err) {
@ -82,15 +80,18 @@ function searchInPosts(query, postedBy, uid, callback) {
mainPids.push(pid); mainPids.push(pid);
} }
}); });
privileges.posts.filter('read', mainPids, uid, next); privileges.posts.filter('read', mainPids, data.uid, next);
}, },
function(pids, next) { function(pids, next) {
posts.getPostSummaryByPids(pids, uid, {stripTags: true, parse: false}, next); posts.getPostSummaryByPids(pids, data.uid, {stripTags: true, parse: false}, next);
}, },
function(posts, next) { function(posts, next) {
if (postedBy) { var searchCategories = results.searchCategories;
if (postedBy || searchCategories.length) {
posts = posts.filter(function(post) { posts = posts.filter(function(post) {
return post && parseInt(post.uid, 10) === parseInt(results.postedByUid, 10); return post &&
(postedBy ? post.user.username === postedBy : true) &&
(searchCategories.length ? searchCategories.indexOf(post.category.cid) !== -1 : true);
}); });
} }
next(null, posts); next(null, posts);
@ -99,6 +100,56 @@ function searchInPosts(query, postedBy, uid, callback) {
}); });
} }
function getSearchCategories(data, callback) {
if (!Array.isArray(data.categories) || !data.categories.length || data.categories.indexOf('all') !== -1) {
return callback(null, []);
}
async.parallel({
watchedCids: function(next) {
if (data.categories.indexOf('watched') !== -1) {
user.getWatchedCategories(data.uid, next);
} else {
next(null, []);
}
},
childrenCids: function(next) {
if (data.searchChildren) {
getChildrenCids(data.categories, data.uid, next);
} else {
next(null, []);
}
}
}, function(err, results) {
if (err) {
return callback(err);
}
var cids = results.watchedCids.concat(results.childrenCids).concat(data.categories).filter(function(cid, index, array) {
return cid && array.indexOf(cid) === index;
});
callback(null, cids);
});
}
function getChildrenCids(cids, uid, callback) {
categories.getChildren(cids, uid, function(err, childrenCategories) {
if (err) {
return callback(err);
}
var childrenCids = [];
childrenCategories.forEach(function(childrens) {
childrenCids = childrenCids.concat(childrens.map(function(category) {
return category && category.cid;
}));
});
callback(null, childrenCids);
});
}
function searchInUsers(query, callback) { function searchInUsers(query, callback) {
user.search({query: query}, function(err, results) { user.search({query: query}, function(err, results) {
callback(err, results ? results.users : null); callback(err, results ? results.users : null);

@ -435,6 +435,26 @@ var async = require('async'),
db.getSortedSetRange('uid:' + uid + ':ignored:cids', 0, -1, callback); db.getSortedSetRange('uid:' + uid + ':ignored:cids', 0, -1, callback);
}; };
User.getWatchedCategories = function(uid, callback) {
async.parallel({
ignored: function(next) {
User.getIgnoredCategories(uid, next);
},
all: function(next) {
db.getSortedSetRange('categories:cid', 0, -1, next);
}
}, function(err, results) {
if (err) {
return callback(err);
}
var watched = results.all.filter(function(cid) {
return cid && results.ignored.indexOf(cid) === -1;
});
callback(null, watched);
});
};
User.ignoreCategory = function(uid, cid, callback) { User.ignoreCategory = function(uid, cid, callback) {
if (!uid) { if (!uid) {
return callback(); return callback();

Loading…
Cancel
Save