diff --git a/src/postTools.js b/src/postTools.js index b610e19415..814ea277a2 100644 --- a/src/postTools.js +++ b/src/postTools.js @@ -1,3 +1,5 @@ +'use strict'; + var winston = require('winston'), async = require('async'), nconf = require('nconf'), @@ -14,15 +16,20 @@ var winston = require('winston'), meta = require('./meta'); (function(PostTools) { + PostTools.isMain = function(pid, tid, callback) { db.getSortedSetRange('tid:' + tid + ':posts', 0, 0, function(err, pids) { if(err) { return callback(err); } + if(!Array.isArray(pids) || !pids.length) { + callback(null, false); + } + callback(null, parseInt(pids[0], 10) === parseInt(pid, 10)); }); - } + }; PostTools.privileges = function(pid, uid, callback) { async.parallel({ @@ -48,7 +55,6 @@ var winston = require('winston'), }); } } - // [getThreadPrivileges, isOwnPost, hasEnoughRep] }, function(err, results) { if(err) { return callback(err); @@ -61,71 +67,78 @@ var winston = require('winston'), move: results.topicPrivs.admin || results.topicPrivs.moderator }); }); - } + }; - PostTools.edit = function(uid, pid, title, content, options) { - options || (options = {}); + PostTools.edit = function(uid, pid, title, content, options, callback) { + options = options || {}; - var websockets = require('./socket.io'), - success = function() { - posts.setPostFields(pid, { - edited: Date.now(), - editor: uid, - content: content - }); + function success(postData) { + posts.setPostFields(pid, { + edited: Date.now(), + editor: uid, + content: postData.content + }); - events.logPostEdit(uid, pid); + events.logPostEdit(uid, pid); - async.parallel([ - function(next) { - posts.getPostField(pid, 'tid', function(err, tid) { - PostTools.isMain(pid, tid, function(err, isMainPost) { - if (isMainPost) { - title = title.trim(); - var slug = tid + '/' + utils.slugify(title); + async.parallel({ + topic: function(next) { + var tid = postData.tid; + PostTools.isMain(pid, tid, function(err, isMainPost) { + if (err) { + return next(err); + } + + if (isMainPost) { + title = title.trim(); + var slug = tid + '/' + utils.slugify(title); - topics.setTopicField(tid, 'title', title); - topics.setTopicField(tid, 'slug', slug); + topics.setTopicField(tid, 'title', title); + topics.setTopicField(tid, 'slug', slug); - topics.setTopicField(tid, 'thumb', options.topic_thumb); + topics.setTopicField(tid, 'thumb', options.topic_thumb); - plugins.fireHook('action:topic.edit', tid); - } + plugins.fireHook('action:topic.edit', tid); + } - posts.getPostData(pid, function(err, postData) { - plugins.fireHook('action:post.edit', postData); - }); + plugins.fireHook('action:post.edit', postData); - next(null, { - tid: tid, - isMainPost: isMainPost - }); - }); + next(null, { + tid: tid, + title: validator.escape(title), + isMainPost: isMainPost }); - }, - function(next) { - PostTools.parse(content, next); - } - ], function(err, results) { - websockets.in('topic_' + results[0].tid).emit('event:post_edited', { - pid: pid, - title: validator.escape(title), - isMainPost: results[0].isMainPost, - content: results[1] }); - }); - }; + + }, + content: function(next) { + PostTools.parse(postData.content, next); + } + }, callback); + } PostTools.privileges(pid, uid, function(err, privileges) { - if (privileges.editable) { - plugins.fireHook('filter:post.save', content, function(err, parsedContent) { - if (!err) content = parsedContent; - success(); - }); + if (err || !privileges.editable) { + return callback(err || new Error('not-privileges-to-edit')); } + + posts.getPostData(pid, function(err, postData) { + if (err) { + return callback(err); + } + + postData.content = content; + plugins.fireHook('filter:post.save', postData, function(err, postData) { + if (err) { + return callback(err); + } + + success(postData); + }); + }); }); - } + }; PostTools.delete = function(uid, pid, callback) { var success = function() { @@ -183,7 +196,7 @@ var winston = require('winston'), } }); }); - } + }; PostTools.restore = function(uid, pid, callback) { var success = function() { @@ -238,7 +251,7 @@ var winston = require('winston'), } }); }); - } + }; PostTools.parse = function(raw, callback) { raw = raw || ''; @@ -246,7 +259,7 @@ var winston = require('winston'), plugins.fireHook('filter:post.parse', raw, function(err, parsed) { callback(null, !err ? parsed : raw); }); - } + }; PostTools.parseSignature = function(raw, callback) { raw = raw || ''; @@ -254,5 +267,6 @@ var winston = require('winston'), plugins.fireHook('filter:post.parseSignature', raw, function(err, parsedSignature) { callback(null, !err ? parsedSignature : raw); }); - } + }; + }(exports)); diff --git a/src/posts.js b/src/posts.js index ac428870d0..0afee2166f 100644 --- a/src/posts.js +++ b/src/posts.js @@ -29,9 +29,12 @@ var db = require('./database'), toPid = data.toPid; if (uid === null) { - return callback(new Error('invalid-user'), null); + return callback(new Error('invalid-user')); } + var timestamp = Date.now(), + postData; + async.waterfall([ function(next) { topics.isLocked(tid, next); @@ -44,46 +47,38 @@ var db = require('./database'), db.incrObjectField('global', 'nextPid', next); }, function(pid, next) { - plugins.fireHook('filter:post.save', content, function(err, newContent) { - next(err, pid, newContent); - }); - }, - function(pid, newContent, next) { - var timestamp = Date.now(), - postData = { - 'pid': pid, - 'uid': uid, - 'tid': tid, - 'content': newContent, - 'timestamp': timestamp, - 'reputation': '0', - 'votes': '0', - 'editor': '', - 'edited': 0, - 'deleted': 0 - }; + + postData = { + 'pid': pid, + 'uid': uid, + 'tid': tid, + 'content': content, + 'timestamp': timestamp, + 'reputation': 0, + 'votes': 0, + 'editor': '', + 'edited': 0, + 'deleted': 0 + }; if (toPid) { postData.toPid = toPid; } - db.setObject('post:' + pid, postData, function(err) { - if(err) { - return next(err); - } - - db.sortedSetAdd('posts:pid', timestamp, pid); + plugins.fireHook('filter:post.save', postData, next); + }, + function(postData, next) { + db.setObject('post:' + postData.pid, postData, next); + }, + function(result, next) { + db.sortedSetAdd('posts:pid', timestamp, postData.pid); - db.incrObjectField('global', 'postCount'); + db.incrObjectField('global', 'postCount'); - topics.onNewPostMade(tid, pid, timestamp); - categories.onNewPostMade(uid, tid, pid, timestamp); - user.onNewPostMade(uid, tid, pid, timestamp); + topics.onNewPostMade(tid, postData.pid, timestamp); + categories.onNewPostMade(uid, tid, postData.pid, timestamp); + user.onNewPostMade(uid, tid, postData.pid, timestamp); - next(null, postData); - }); - }, - function(postData, next) { plugins.fireHook('filter:post.get', postData, next); }, function(postData, next) { @@ -103,36 +98,34 @@ var db = require('./database'), }; Posts.getPostsByTid = function(tid, start, end, reverse, callback) { - if (typeof reverse === 'function') { - callback = reverse; - reverse = false; - } - db[reverse ? 'getSortedSetRevRange' : 'getSortedSetRange']('tid:' + tid + ':posts', start, end, function(err, pids) { if(err) { return callback(err); } - if(!pids.length) { + if(!Array.isArray(pids) || !pids.length) { return callback(null, []); } - plugins.fireHook('filter:post.getTopic', pids, function(err, posts) { + Posts.getPostsByPids(pids, function(err, posts) { if(err) { return callback(err); } - if(!posts.length) { + if(!Array.isArray(posts) || !posts.length) { return callback(null, []); } - - Posts.getPostsByPids(pids, function(err, posts) { + plugins.fireHook('filter:post.getPosts', {tid: tid, posts: posts}, function(err, data) { if(err) { return callback(err); } - plugins.fireHook('action:post.gotTopic', posts); - callback(null, posts); + + if(!data || !Array.isArray(data.posts)) { + return callback(null, []); + } + + callback(null, data.posts); }); }); }); diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js index df0ebfeebd..c29df33ad8 100644 --- a/src/socket.io/posts.js +++ b/src/socket.io/posts.js @@ -151,8 +151,20 @@ SocketPosts.edit = function(socket, data, callback) { return callback(new Error('content-too-short')); } - postTools.edit(socket.uid, data.pid, data.title, data.content, {topic_thumb: data.topic_thumb}); - callback(); + postTools.edit(socket.uid, data.pid, data.title, data.content, {topic_thumb: data.topic_thumb}, function(err, results) { + if(err) { + return callback(err); + } + + index.server.sockets.in('topic_' + results.topic.tid).emit('event:post_edited', { + pid: data.pid, + title: results.topic.title, + isMainPost: results.topic.isMainPost, + content: results.content + }); + + callback(); + }); }; SocketPosts.delete = function(socket, data, callback) {