'use strict'; var async = require('async'); var posts = require('../../posts'); var events = require('../../events'); var websockets = require('../index'); var socketTopics = require('../topics'); var privileges = require('../../privileges'); var plugins = require('../../plugins'); var social = require('../../social'); var favourites = require('../../favourites'); module.exports = function(SocketPosts) { SocketPosts.loadPostTools = function(socket, data, callback) { if (!data) { return callback(new Error('[[error:invalid-data]]')); } async.parallel({ posts: function(next) { posts.getPostFields(data.pid, ['deleted', 'reputation', 'uid'], next); }, isAdminOrMod: function(next) { privileges.categories.isAdminOrMod(data.cid, socket.uid, next); }, favourited: function(next) { favourites.getFavouritesByPostIDs([data.pid], socket.uid, next); }, tools: function(next) { plugins.fireHook('filter:post.tools', {pid: data.pid, uid: socket.uid, tools: []}, next); }, postSharing: function(next) { social.getActivePostSharing(next); } }, function(err, results) { if (err) { return callback(err); } results.posts.tools = results.tools.tools; results.posts.deleted = parseInt(results.posts.deleted, 10) === 1; results.posts.favourited = results.favourited[0]; results.posts.selfPost = socket.uid && socket.uid === parseInt(results.posts.uid, 10); results.posts.display_moderator_tools = results.isAdminOrMod || results.posts.selfPost; results.posts.display_move_tools = results.isAdminOrMod; callback(null, results); }); }; SocketPosts.delete = function(socket, data, callback) { doPostAction('delete', 'event:post_deleted', socket, data, callback); }; SocketPosts.restore = function(socket, data, callback) { doPostAction('restore', 'event:post_restored', socket, data, callback); }; SocketPosts.deletePosts = function(socket, data, callback) { if (!data || !Array.isArray(data.pids)) { return callback(new Error('[[error:invalid-data]]')); } async.each(data.pids, function(pid, next) { SocketPosts.delete(socket, {pid: pid, tid: data.tid}, next); }, callback); }; SocketPosts.purgePosts = function(socket, data, callback) { if (!data || !Array.isArray(data.pids)) { return callback(new Error('[[error:invalid-data]]')); } async.each(data.pids, function(pid, next) { SocketPosts.purge(socket, {pid: pid, tid: data.tid}, next); }, callback); }; function doPostAction(command, eventName, socket, data, callback) { if (!data) { return callback(new Error('[[error:invalid-data]]')); } posts.tools[command](socket.uid, data.pid, function(err, postData) { if (err) { return callback(err); } websockets.in('topic_' + data.tid).emit(eventName, postData); events.log({ type: 'post-' + command, uid: socket.uid, pid: data.pid, ip: socket.ip }); callback(); }); } SocketPosts.purge = function(socket, data, callback) { function purgePost() { posts.tools.purge(socket.uid, data.pid, function(err) { if (err) { return callback(err); } websockets.in('topic_' + data.tid).emit('event:post_purged', data.pid); events.log({ type: 'post-purge', uid: socket.uid, pid: data.pid, ip: socket.ip }); callback(); }); } if (!data || !parseInt(data.pid, 10)) { return callback(new Error('[[error:invalid-data]]')); } isMainAndLastPost(data.pid, function(err, results) { if (err) { return callback(err); } if (!results.isMain) { return purgePost(); } if (!results.isLast) { return callback(new Error('[[error:cant-purge-main-post]]')); } posts.getTopicFields(data.pid, ['tid', 'cid'], function(err, topic) { if (err) { return callback(err); } socketTopics.doTopicAction('delete', 'event:topic_deleted', socket, {tids: [topic.tid], cid: topic.cid}, callback); }); }); }; function isMainAndLastPost(pid, callback) { async.parallel({ isMain: function(next) { posts.isMain(pid, next); }, isLast: function(next) { posts.getTopicFields(pid, ['postcount'], function(err, topic) { next(err, topic ? parseInt(topic.postcount, 10) === 1 : false); }); } }, callback); } };