diff --git a/src/categories/data.js b/src/categories/data.js index ef5ced757b..96ed3214a5 100644 --- a/src/categories/data.js +++ b/src/categories/data.js @@ -13,7 +13,7 @@ const intFields = [ module.exports = function (Categories) { Categories.getCategoriesFields = function (cids, fields, callback) { if (!Array.isArray(cids) || !cids.length) { - return callback(null, []); + return setImmediate(callback, null, []); } var keys = cids.map(cid => 'category:' + cid); diff --git a/src/categories/index.js b/src/categories/index.js index 3065e7a06c..efb3cbad70 100644 --- a/src/categories/index.js +++ b/src/categories/index.js @@ -64,6 +64,9 @@ Categories.getCategoryById = function (data, callback) { }; Categories.isIgnored = function (cids, uid, callback) { + if (parseInt(uid, 10) <= 0) { + return setImmediate(callback, null, cids.map(() => false)); + } db.isSortedSetMembers('uid:' + uid + ':ignored:cids', cids, callback); }; @@ -119,19 +122,14 @@ Categories.getCategories = function (cids, uid, callback) { if (!cids.length) { return callback(null, []); } - + uid = parseInt(uid, 10); + let results; async.waterfall([ function (next) { async.parallel({ categories: function (next) { Categories.getCategoriesData(cids, next); }, - children: function (next) { - Categories.getChildren(cids, uid, next); - }, - parents: function (next) { - Categories.getParents(cids, next); - }, tagWhitelist: function (next) { Categories.getTagWhitelist(cids, next); }, @@ -140,19 +138,19 @@ Categories.getCategories = function (cids, uid, callback) { }, }, next); }, - function (results, next) { - uid = parseInt(uid, 10); - results.categories.forEach(function (category, i) { + function (_results, next) { + results = _results; + Categories.getParentsAndChildren(results.categories, uid, next); + }, + function (categories, next) { + categories.forEach(function (category, i) { if (category) { - category.children = results.children[i]; - category.parent = results.parents[i] || undefined; category.tagWhitelist = results.tagWhitelist[i]; category['unread-class'] = (category.topic_count === 0 || (results.hasRead[i] && uid !== 0)) ? '' : 'unread'; calculateTopicPostCount(category); } }); - - next(null, results.categories); + next(null, categories); }, ], callback); }; @@ -211,10 +209,33 @@ Categories.getParents = function (cids, callback) { ], callback); }; +Categories.getParentsAndChildren = function (categoryData, uid, callback) { + const parentCids = categoryData.filter(c => c && c.parentCid).map(c => c.parentCid); + async.waterfall([ + function (next) { + async.parallel({ + parents: function (next) { + Categories.getCategoriesData(parentCids, next); + }, + children: function (next) { + async.each(categoryData, function (category, next) { + getChildrenRecursive(category, uid, next); + }, next); + }, + }, next); + }, + function (results, next) { + const cidToParent = _.zipObject(parentCids, results.parents); + categoryData.forEach(function (category) { + category.parent = cidToParent[category.parentCid]; + }); + next(null, categoryData); + }, + ], callback); +}; + Categories.getChildren = function (cids, uid, callback) { - var categories = cids.map(function (cid) { - return { cid: cid }; - }); + var categories = cids.map(cid => ({ cid: cid })); async.each(categories, function (category, next) { Categories.getCategoryField(category.cid, 'parentCid', function (err, parentCid) { @@ -238,9 +259,7 @@ function getChildrenRecursive(category, uid, callback) { privileges.categories.filterCids('find', children, uid, next); }, function (children, next) { - children = children.filter(function (cid) { - return parseInt(category.cid, 10) !== parseInt(cid, 10); - }); + children = children.filter(cid => parseInt(category.cid, 10) !== parseInt(cid, 10)); if (!children.length) { category.children = []; return callback(); @@ -261,9 +280,6 @@ function getChildrenRecursive(category, uid, callback) { child['unread-class'] = (child.topic_count === 0 || (read && uid !== 0)) ? '' : 'unread'; }); - next(); - }, - function (next) { async.each(category.children, function (child, next) { if (parseInt(category.parentCid, 10) === parseInt(child.cid, 10)) { return next(); diff --git a/src/categories/unread.js b/src/categories/unread.js index d1869b5620..c1a6b3d626 100644 --- a/src/categories/unread.js +++ b/src/categories/unread.js @@ -7,8 +7,8 @@ var db = require('../database'); module.exports = function (Categories) { Categories.markAsRead = function (cids, uid, callback) { callback = callback || function () {}; - if (!Array.isArray(cids) || !cids.length) { - return callback(); + if (!Array.isArray(cids) || !cids.length || parseInt(uid, 10) <= 0) { + return setImmediate(callback); } var keys = cids.map(cid => 'cid:' + cid + ':read_by_uid'); @@ -33,12 +33,18 @@ module.exports = function (Categories) { }; Categories.hasReadCategories = function (cids, uid, callback) { - var sets = cids.map(cid => 'cid:' + cid + ':read_by_uid'); + if (parseInt(uid, 10) <= 0) { + return setImmediate(callback, null, cids.map(() => false)); + } + const sets = cids.map(cid => 'cid:' + cid + ':read_by_uid'); db.isMemberOfSets(sets, uid, callback); }; Categories.hasReadCategory = function (cid, uid, callback) { + if (parseInt(uid, 10) <= 0) { + return setImmediate(callback, null, false); + } db.isSetMember('cid:' + cid + ':read_by_uid', uid, callback); }; }; diff --git a/src/user/categories.js b/src/user/categories.js index 7403a1ebc6..541256e464 100644 --- a/src/user/categories.js +++ b/src/user/categories.js @@ -7,10 +7,16 @@ var categories = require('../categories'); module.exports = function (User) { User.getIgnoredCategories = function (uid, callback) { + if (parseInt(uid, 10) <= 0) { + return setImmediate(callback, null, []); + } db.getSortedSetRange('uid:' + uid + ':ignored:cids', 0, -1, callback); }; User.getWatchedCategories = function (uid, callback) { + if (parseInt(uid, 10) <= 0) { + return setImmediate(callback, null, []); + } async.waterfall([ function (next) { async.parallel({