diff --git a/src/search.js b/src/search.js index 190a764bf2..8ccdf77d78 100644 --- a/src/search.js +++ b/src/search.js @@ -58,14 +58,14 @@ function searchInContent(query, data, callback) { async.parallel({ pids: function(next) { if (data.searchIn === 'posts' || data.searchIn === 'titlesposts') { - searchQuery('post', query, next); + search.searchQuery('post', query, next); } else { next(null, []); } }, tids: function(next) { if (data.searchIn === 'titles' || data.searchIn === 'titlesposts') { - searchQuery('topic', query, next); + search.searchQuery('topic', query, next); } else { next(null, []); } @@ -93,6 +93,7 @@ function searchInContent(query, data, callback) { mainPids.push(pid); } }); + privileges.posts.filter('read', mainPids, data.uid, next); }, function(pids, next) { @@ -475,10 +476,10 @@ function getMainPids(tids, callback) { }); } -function searchQuery(index, query, callback) { +search.searchQuery = function(index, query, callback) { plugins.fireHook('filter:search.query', { index: index, query: query }, callback); -} +}; diff --git a/src/topics.js b/src/topics.js index a9514dabba..274ffbcf70 100644 --- a/src/topics.js +++ b/src/topics.js @@ -25,6 +25,7 @@ var async = require('async'), require('./topics/follow')(Topics); require('./topics/tags')(Topics); require('./topics/teaser')(Topics); + require('./topics/suggested')(Topics); Topics.exists = function(tid, callback) { db.isSortedSetMember('topics:tid', tid, callback); diff --git a/src/topics/suggested.js b/src/topics/suggested.js new file mode 100644 index 0000000000..3c18d50dbe --- /dev/null +++ b/src/topics/suggested.js @@ -0,0 +1,74 @@ + +'use strict'; + +var async = require('async'), + _ = require('underscore'), + + categories = require('../categories'), + search = require('../search'), + db = require('../database'); + + +module.exports = function(Topics) { + + Topics.getSuggestedTopics = function(tid, uid, start, end, callback) { + async.parallel({ + tagTids: function(next) { + getTidsWithSameTags(tid, next); + }, + searchTids: function(next) { + getSearchTids(tid, uid, next); + }, + categoryTids: function(next) { + getCategoryTids(tid, next); + } + }, function(err, results) { + if (err) { + return callback(err); + } + var tids = results.tagTids.concat(results.searchTids).concat(results.categoryTids); + tids = tids.filter(function(_tid, index, array) { + return parseInt(_tid, 10) !== parseInt(tid, 10) && array.indexOf(_tid) === index; + }).slice(start, end + 1); + + Topics.getTopics(tids, uid, callback); + }); + }; + + function getTidsWithSameTags(tid, callback) { + async.waterfall([ + function(next) { + Topics.getTopicTags(tid, next); + }, + function(tags, next) { + async.map(tags, function(tag, next) { + Topics.getTagTids(tag, 0, -1, next); + }, next); + }, + function(data, next) { + next(null, _.unique(_.flatten(data))); + } + ], callback); + } + + function getSearchTids(tid, uid, callback) { + async.waterfall([ + function(next) { + Topics.getTopicField(tid, 'title', next); + }, + function(title, next) { + search.searchQuery('topic', title, next); + } + ], callback); + } + + function getCategoryTids(tid, callback) { + Topics.getTopicField(tid, 'cid', function(err, cid) { + if (err || !cid) { + return callback(err, []); + } + categories.getTopicIds('cid:' + cid + ':tids', true, 0, 9, callback); + }); + } + +}; \ No newline at end of file