From 64d04f7aa60ffdf30cc856456afa2d0b27550ce7 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Mon, 7 Jul 2014 17:36:10 -0400 Subject: [PATCH] closes #1803 --- public/language/en_GB/search.json | 2 +- public/src/forum/search.js | 9 ++-- src/categories/recentreplies.js | 2 +- src/controllers/index.js | 52 ++++-------------- src/controllers/topics.js | 2 +- src/groups.js | 2 +- src/posts.js | 12 +++-- src/search.js | 89 +++++++++++++++++++++++++++++++ 8 files changed, 114 insertions(+), 56 deletions(-) create mode 100644 src/search.js diff --git a/public/language/en_GB/search.json b/public/language/en_GB/search.json index dad7bdee0d..20d27c2a46 100644 --- a/public/language/en_GB/search.json +++ b/public/language/en_GB/search.json @@ -1,3 +1,3 @@ { - "results_matching": "%1 result(s) matching \"%2\"" + "results_matching": "%1 result(s) matching \"%2\", (%3 seconds)" } \ No newline at end of file diff --git a/public/src/forum/search.js b/public/src/forum/search.js index 39c47558d2..13ef9750c8 100644 --- a/public/src/forum/search.js +++ b/public/src/forum/search.js @@ -2,22 +2,21 @@ define('forum/search', function() { var Search = {}; Search.init = function() { - var searchQuery = $('#topic-results').attr('data-search-query'); + var searchQuery = $('#post-results').attr('data-search-query'); $('.search-result-text').each(function() { var result = $(this); var text = result.html(); var regex = new RegExp(searchQuery, 'gi'); - text = text.replace(regex, '' + searchQuery + ''); - result.html(text); - result.find('img').addClass('img-responsive'); + text = text.replace(regex, '' + searchQuery + ''); + result.html(text).find('img').addClass('img-responsive'); }); $('#search-form input').val(searchQuery); $('#mobile-search-form').off('submit').on('submit', function() { var input = $(this).find('input'); - ajaxify.go("search/" + input.val(), null, "search"); + ajaxify.go('search/' + input.val(), null, 'search'); input.val(''); return false; }); diff --git a/src/categories/recentreplies.js b/src/categories/recentreplies.js index 75ea5b637f..beb7290c1b 100644 --- a/src/categories/recentreplies.js +++ b/src/categories/recentreplies.js @@ -19,7 +19,7 @@ module.exports = function(Categories) { return callback(err, []); } - posts.getPostSummaryByPids(pids, true, callback); + posts.getPostSummaryByPids(pids, {stripTags: true}, callback); }); }; diff --git a/src/controllers/index.js b/src/controllers/index.js index e033e186a2..0a81ff47cc 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -12,11 +12,13 @@ var topicsController = require('./topics'), async = require('async'), nconf = require('nconf'), + winston = require('winston'), auth = require('../routes/authentication'), meta = require('../meta'), user = require('../user'), posts = require('../posts'), topics = require('../topics'), + search = require('../search'), plugins = require('../plugins'), categories = require('../categories'), privileges = require('../privileges'); @@ -83,69 +85,35 @@ Controllers.home = function(req, res, next) { }); } }, function (err, data) { + if (err) { + return next(err); + } res.render('home', data); }); }; Controllers.search = function(req, res, next) { - var start = process.hrtime(); - if (!req.params.term) { return res.render('search', { + time: 0, search_query: '', posts: [], topics: [] }); } + var uid = req.user ? req.user.uid : 0; + if (!plugins.hasListeners('filter:search.query')) { return res.redirect('/404'); } - function search(index, callback) { - plugins.fireHook('filter:search.query', { - index: index, - query: req.params.term - }, callback); - } - - async.parallel({ - pids: function(next) { - search('post', next); - }, - tids: function(next) { - search('topic', next); - } - }, function (err, results) { + search.search(req.params.term, uid, function(err, results) { if (err) { return next(err); } - if(!results) { - results = {pids:[], tids: []}; - } - - async.parallel({ - posts: function(next) { - posts.getPostSummaryByPids(results.pids, false, next); - }, - topics: function(next) { - topics.getTopicsByTids(results.tids, 0, next); - } - }, function(err, results) { - if (err) { - return next(err); - } - - return res.render('search', { - time: process.elapsedTimeSince(start), - search_query: req.params.term, - posts: results.posts, - topics: results.topics, - post_matches : results.posts.length, - topic_matches : results.topics.length - }); - }); + return res.render('search', results); }); }; diff --git a/src/controllers/topics.js b/src/controllers/topics.js index 75cd9c2565..8953ff87ec 100644 --- a/src/controllers/topics.js +++ b/src/controllers/topics.js @@ -203,7 +203,7 @@ topicsController.teaser = function(req, res, next) { return res.json(404, 'not-found'); } - posts.getPostSummaryByPids([pid], false, function(err, posts) { + posts.getPostSummaryByPids([pid], {stripTags: false}, function(err, posts) { if (err) { return next(err); } diff --git a/src/groups.js b/src/groups.js index 4d8dd0cb27..0b495c2432 100644 --- a/src/groups.js +++ b/src/groups.js @@ -325,7 +325,7 @@ return callback(err); } - posts.getPostSummaryByPids(pids, false, callback); + posts.getPostSummaryByPids(pids, {stripTags: false}, callback); }); }); }; diff --git a/src/posts.js b/src/posts.js index 28d8b588b9..6c96d2602f 100644 --- a/src/posts.js +++ b/src/posts.js @@ -183,7 +183,7 @@ var async = require('async'), next(!err && canRead); }); }, function(pids) { - Posts.getPostSummaryByPids(pids, true, callback); + Posts.getPostSummaryByPids(pids, {stripTags: true}, callback); }); }); }; @@ -231,7 +231,9 @@ var async = require('async'), }); }; - Posts.getPostSummaryByPids = function(pids, stripTags, callback) { + Posts.getPostSummaryByPids = function(pids, options, callback) { + options.stripTags = options.hasOwnProperty('stripTags') ? options.stripTags : false; + options.parse = options.hasOwnProperty('parse') ? options.parse : true; function getPostSummary(post, callback) { @@ -261,7 +263,7 @@ var async = require('async'), }); }, content: function(next) { - if (!post.content) { + if (!post.content || !options.parse) { return next(null, post.content); } @@ -280,7 +282,7 @@ var async = require('async'), post.category = results.topicCategory.category; post.index = results.index; - if (stripTags) { + if (options.stripTags) { var s = S(results.content); post.content = s.stripTags.apply(s, utils.stripTags).s; } else { @@ -443,7 +445,7 @@ var async = require('async'), return callback(null, {posts: [], nextStart: 0}); } - Posts.getPostSummaryByPids(pids, false, function(err, posts) { + Posts.getPostSummaryByPids(pids, {stripTags: false}, function(err, posts) { if (err) { return callback(err); } diff --git a/src/search.js b/src/search.js new file mode 100644 index 0000000000..7ea5dd7677 --- /dev/null +++ b/src/search.js @@ -0,0 +1,89 @@ +'use strict'; + +var async = require('async'), + posts = require('./posts'), + topics = require('./topics'), + plugins = require('./plugins'), + privileges = require('./privileges'); + +var search = {}; + +module.exports = search; + +search.search = function(term, uid, callback) { + var start = process.hrtime(); + + async.parallel({ + pids: function(next) { + searchTerm('post', term, next); + }, + tids: function(next) { + searchTerm('topic', term, next); + } + }, function (err, results) { + if (err) { + return callback(err); + } + + if (!results || (!results.pids.length && !results.tids.length)) { + return callback(null, { + time: (process.elapsedTimeSince(start) / 1000).toFixed(2), + search_query: term, + results: [], + matchCount: 0 + }); + } + + getMainPids(results.tids, function(err, mainPids) { + if (err) { + return callback(err); + } + + results.pids.forEach(function(pid) { + if (mainPids.indexOf(pid) === -1) { + mainPids.push(pid); + } + }); + + async.filter(mainPids, function(pid, next) { + privileges.posts.can('read', pid, uid, function(err, canRead) { + next(!err && canRead); + }); + }, function(pids) { + posts.getPostSummaryByPids(pids, {stripTags: false, parse: false}, function(err, posts) { + if (err) { + return callback(err); + } + + callback(null, { + time: (process.elapsedTimeSince(start) / 1000).toFixed(2), + search_query: term, + results: posts, + matchCount: posts.length + }); + }); + }); + }); + }); +}; + + +function getMainPids(tids, callback) { + topics.getTopicsFields(tids, ['mainPid'], function(err, topics) { + if (err) { + return callback(err); + } + topics = topics.map(function(topics) { + return topics.mainPid; + }); + callback(null, topics); + }); +} + +function searchTerm(index, term, callback) { + plugins.fireHook('filter:search.query', { + index: index, + query: term + }, callback); +} +