'use strict'; var db = require('./database'), posts = require('./posts'), utils = require('./../public/src/utils'), user = require('./user'), Groups = require('./groups'), topics = require('./topics'), plugins = require('./plugins'), meta = require('./meta'), validator = require('validator'), privileges = require('./privileges'), async = require('async'), winston = require('winston'), nconf = require('nconf'); (function(Categories) { require('./categories/delete')(Categories); require('./categories/activeusers')(Categories); require('./categories/recentreplies')(Categories); require('./categories/update')(Categories); Categories.create = function(data, callback) { db.incrObjectField('global', 'nextCid', function(err, cid) { if (err) { return callback(err); } var slug = cid + '/' + utils.slugify(data.name); var category = { cid: cid, name: data.name, description: data.description, icon: data.icon, bgColor: data.bgColor, color: data.color, slug: slug, parentCid: 0, topic_count: 0, post_count: 0, disabled: 0, order: data.order, link: '', numRecentReplies: 1, class: 'col-md-3 col-xs-6', imageClass: 'auto' }; async.series([ async.apply(db.setObject, 'category:' + cid, category), async.apply(db.sortedSetAdd, 'categories:cid', data.order, cid) ], function(err) { if (err) { return callback(err); } callback(null, category); }); }); }; Categories.exists = function(cid, callback) { db.isSortedSetMember('categories:cid', cid, callback); }; Categories.getCategoryById = function(data, callback) { Categories.getCategories([data.cid], data.uid, function(err, categories) { if (err || !Array.isArray(categories) || !categories[0]) { return callback(err || new Error('[[error:invalid-cid]]')); } var category = categories[0]; if (parseInt(data.uid, 10)) { Categories.markAsRead([data.cid], data.uid); } async.parallel({ topics: function(next) { Categories.getCategoryTopics({ cid: data.cid, start: data.start, stop: data.end, uid: data.uid, targetUid: data.targetUid }, next); }, pageCount: function(next) { Categories.getPageCount(data.cid, data.uid, next); }, isIgnored: function(next) { Categories.isIgnored([data.cid], data.uid, next); } }, function(err, results) { if(err) { return callback(err); } category.topics = results.topics.topics; category.nextStart = results.topics.nextStart; category.pageCount = results.pageCount; category.isIgnored = results.isIgnored[0]; category.topic_row_size = 'col-md-9'; plugins.fireHook('filter:category.get', category, data.uid, callback); }); }); }; Categories.getCategoryTopics = function(data, callback) { var tids; async.waterfall([ function(next) { Categories.getTopicIds(data.targetUid ? 'cid:' + data.cid + ':uid:' + data.targetUid + ':tids' : 'cid:' + data.cid + ':tids', data.start, data.stop, next); }, function(topicIds, next) { tids = topicIds; topics.getTopicsByTids(tids, data.uid, next); }, function(topics, next) { if (!Array.isArray(topics) || !topics.length) { return next(null, { topics: [], nextStart: 1 }); } var indices = {}, i = 0; for(i=0; i