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);
+}
+