| 
									
										
										
										
											2014-03-21 17:04:15 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-21 17:49:44 +02:00
										 |  |  | var async = require('async'); | 
					
						
							|  |  |  | var _ = require('underscore'); | 
					
						
							|  |  |  | var validator = require('validator'); | 
					
						
							| 
									
										
										
										
											2014-03-21 17:04:15 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-21 17:49:44 +02:00
										 |  |  | var db = require('../database'); | 
					
						
							|  |  |  | var user = require('../user'); | 
					
						
							|  |  |  | var posts = require('../posts'); | 
					
						
							|  |  |  | var meta = require('../meta'); | 
					
						
							| 
									
										
										
										
											2016-11-08 18:43:26 -06:00
										 |  |  | var plugins = require('../plugins'); | 
					
						
							| 
									
										
										
										
											2017-03-15 18:56:12 -04:00
										 |  |  | var utils = require('../../public/src/utils'); | 
					
						
							| 
									
										
										
										
											2014-03-21 17:04:15 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | module.exports = function (Topics) { | 
					
						
							|  |  |  | 	Topics.onNewPostMade = function (postData, callback) { | 
					
						
							| 
									
										
										
										
											2016-02-24 20:10:06 +02:00
										 |  |  | 		async.series([ | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			function (next) { | 
					
						
							| 
									
										
										
										
											2014-09-19 15:54:13 -04:00
										 |  |  | 				Topics.increasePostCount(postData.tid, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			function (next) { | 
					
						
							| 
									
										
										
										
											2014-09-19 15:54:13 -04:00
										 |  |  | 				Topics.updateTimestamp(postData.tid, postData.timestamp, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			function (next) { | 
					
						
							| 
									
										
										
										
											2016-04-19 20:04:32 +03:00
										 |  |  | 				Topics.addPostToTopic(postData.tid, postData, next); | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2014-09-19 15:54:13 -04:00
										 |  |  | 		], callback); | 
					
						
							| 
									
										
										
										
											2014-03-21 17:04:15 -04:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.getTopicPosts = function (tid, set, start, stop, uid, reverse, callback) { | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 		async.waterfall([ | 
					
						
							|  |  |  | 			function (next) { | 
					
						
							|  |  |  | 				async.parallel({ | 
					
						
							|  |  |  | 					posts: function (next) { | 
					
						
							|  |  |  | 						posts.getPostsFromSet(set, start, stop, uid, reverse, next); | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 					postCount: function (next) { | 
					
						
							|  |  |  | 						Topics.getTopicField(tid, 'postcount', next); | 
					
						
							| 
									
										
										
										
											2017-02-23 18:31:49 -07:00
										 |  |  | 					}, | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 				}, next); | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 			function (results, next) { | 
					
						
							|  |  |  | 				Topics.calculatePostIndices(results.posts, start, stop, results.postCount, reverse); | 
					
						
							| 
									
										
										
										
											2014-03-21 17:04:15 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 				Topics.addPostData(results.posts, uid, next); | 
					
						
							| 
									
										
										
										
											2017-02-23 18:31:49 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 		], callback); | 
					
						
							| 
									
										
										
										
											2014-06-06 22:12:14 -04:00
										 |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2014-03-21 17:04:15 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.addPostData = function (postData, uid, callback) { | 
					
						
							| 
									
										
										
										
											2014-11-11 19:47:56 -05:00
										 |  |  | 		if (!Array.isArray(postData) || !postData.length) { | 
					
						
							|  |  |  | 			return callback(null, []); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 		var pids = postData.map(function (post) { | 
					
						
							| 
									
										
										
										
											2014-08-30 11:56:29 -04:00
										 |  |  | 			return post && post.pid; | 
					
						
							| 
									
										
										
										
											2014-08-30 14:42:48 -04:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2014-08-30 11:56:29 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (!Array.isArray(pids) || !pids.length) { | 
					
						
							|  |  |  | 			return callback(null, []); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-03-21 17:04:15 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 		function getPostUserData(field, method, callback) { | 
					
						
							|  |  |  | 			var uids = []; | 
					
						
							| 
									
										
										
										
											2014-06-28 14:59:01 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 			postData.forEach(function (postData) { | 
					
						
							| 
									
										
										
										
											2017-04-06 17:44:25 -04:00
										 |  |  | 				if (postData && parseInt(postData[field], 10) >= 0 && uids.indexOf(postData[field]) === -1) { | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 					uids.push(postData[field]); | 
					
						
							| 
									
										
										
										
											2014-06-28 01:03:26 -04:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2014-06-28 01:03:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 			async.waterfall([ | 
					
						
							|  |  |  | 				function (next) { | 
					
						
							|  |  |  | 					method(uids, next); | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				function (users, next) { | 
					
						
							| 
									
										
										
										
											2014-06-28 01:03:26 -04:00
										 |  |  | 					var userData = {}; | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 					users.forEach(function (user, index) { | 
					
						
							| 
									
										
										
										
											2014-08-26 13:47:48 -04:00
										 |  |  | 						userData[uids[index]] = user; | 
					
						
							| 
									
										
										
										
											2014-06-12 16:45:00 -04:00
										 |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2014-06-28 01:03:26 -04:00
										 |  |  | 					next(null, userData); | 
					
						
							| 
									
										
										
										
											2017-02-23 18:31:49 -07:00
										 |  |  | 				}, | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 			], callback); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-06-28 01:03:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 		async.waterfall([ | 
					
						
							|  |  |  | 			function (next) { | 
					
						
							|  |  |  | 				async.parallel({ | 
					
						
							|  |  |  | 					bookmarks: function (next) { | 
					
						
							|  |  |  | 						posts.hasBookmarked(pids, uid, next); | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 					voteData: function (next) { | 
					
						
							|  |  |  | 						posts.getVoteStatusByPostIDs(pids, uid, next); | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 					userData: function (next) { | 
					
						
							|  |  |  | 						getPostUserData('uid', function (uids, next) { | 
					
						
							|  |  |  | 							posts.getUserInfoForPosts(uids, uid, next); | 
					
						
							|  |  |  | 						}, next); | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 					editors: function (next) { | 
					
						
							|  |  |  | 						getPostUserData('editor', function (uids, next) { | 
					
						
							|  |  |  | 							user.getUsersFields(uids, ['uid', 'username', 'userslug'], next); | 
					
						
							|  |  |  | 						}, next); | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 					parents: function (next) { | 
					
						
							|  |  |  | 						Topics.addParentPosts(postData, next); | 
					
						
							| 
									
										
										
										
											2017-02-23 18:31:49 -07:00
										 |  |  | 					}, | 
					
						
							| 
									
										
										
										
											2017-03-15 18:56:12 -04:00
										 |  |  | 					replies: function (next) { | 
					
						
							| 
									
										
										
										
											2017-03-17 13:35:24 -04:00
										 |  |  | 						getPostReplies(pids, uid, next); | 
					
						
							| 
									
										
										
										
											2017-03-15 18:56:12 -04:00
										 |  |  | 					}, | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 				}, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function (results, next) { | 
					
						
							|  |  |  | 				postData.forEach(function (postObj, i) { | 
					
						
							|  |  |  | 					if (postObj) { | 
					
						
							|  |  |  | 						postObj.deleted = parseInt(postObj.deleted, 10) === 1; | 
					
						
							|  |  |  | 						postObj.user = parseInt(postObj.uid, 10) ? results.userData[postObj.uid] : _.clone(results.userData[postObj.uid]); | 
					
						
							|  |  |  | 						postObj.editor = postObj.editor ? results.editors[postObj.editor] : null; | 
					
						
							|  |  |  | 						postObj.bookmarked = results.bookmarks[i]; | 
					
						
							|  |  |  | 						postObj.upvoted = results.voteData.upvotes[i]; | 
					
						
							|  |  |  | 						postObj.downvoted = results.voteData.downvotes[i]; | 
					
						
							|  |  |  | 						postObj.votes = postObj.votes || 0; | 
					
						
							| 
									
										
										
										
											2017-03-15 18:56:12 -04:00
										 |  |  | 						postObj.replies = results.replies[i]; | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 						postObj.selfPost = !!parseInt(uid, 10) && parseInt(uid, 10) === parseInt(postObj.uid, 10); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						// Username override for guests, if enabled
 | 
					
						
							|  |  |  | 						if (parseInt(meta.config.allowGuestHandles, 10) === 1 && parseInt(postObj.uid, 10) === 0 && postObj.handle) { | 
					
						
							|  |  |  | 							postObj.user.username = validator.escape(String(postObj.handle)); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2014-06-28 01:03:26 -04:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 				plugins.fireHook('filter:topics.addPostData', { | 
					
						
							|  |  |  | 					posts: postData, | 
					
						
							| 
									
										
										
										
											2017-02-23 18:31:49 -07:00
										 |  |  | 					uid: uid, | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 				}, next); | 
					
						
							| 
									
										
										
										
											2014-06-06 22:12:14 -04:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 			function (data, next) { | 
					
						
							|  |  |  | 				next(null, data.posts); | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 		], callback); | 
					
						
							| 
									
										
										
										
											2014-03-21 17:04:15 -04:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.modifyPostsByPrivilege = function (topicData, topicPrivileges) { | 
					
						
							| 
									
										
										
										
											2016-03-21 17:49:44 +02:00
										 |  |  | 		var loggedIn = !!parseInt(topicPrivileges.uid, 10); | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 		topicData.posts.forEach(function (post) { | 
					
						
							| 
									
										
										
										
											2015-10-06 18:36:03 -04:00
										 |  |  | 			if (post) { | 
					
						
							| 
									
										
										
										
											2016-08-09 09:50:49 -05:00
										 |  |  | 				post.display_edit_tools = topicPrivileges.isAdminOrMod || (post.selfPost && topicPrivileges['posts:edit']); | 
					
						
							|  |  |  | 				post.display_delete_tools = topicPrivileges.isAdminOrMod || (post.selfPost && topicPrivileges['posts:delete']); | 
					
						
							| 
									
										
										
										
											2016-08-06 20:28:55 -05:00
										 |  |  | 				post.display_moderator_tools = post.display_edit_tools || post.display_delete_tools; | 
					
						
							| 
									
										
										
										
											2015-10-06 18:36:03 -04:00
										 |  |  | 				post.display_move_tools = topicPrivileges.isAdminOrMod && post.index !== 0; | 
					
						
							| 
									
										
										
										
											2016-08-12 12:57:23 +03:00
										 |  |  | 				post.display_post_menu = topicPrivileges.isAdminOrMod || (post.selfPost && !topicData.locked) || ((loggedIn || topicData.postSharing.length) && !post.deleted); | 
					
						
							| 
									
										
										
										
											2016-03-08 19:06:59 +02:00
										 |  |  | 				post.ip = topicPrivileges.isAdminOrMod ? post.ip : undefined; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-02 13:21:51 +03:00
										 |  |  | 				posts.modifyPostByPrivilege(post, topicPrivileges.isAdminOrMod); | 
					
						
							| 
									
										
										
										
											2015-10-06 18:36:03 -04:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.addParentPosts = function (postData, callback) { | 
					
						
							|  |  |  | 		var parentPids = postData.map(function (postObj) { | 
					
						
							| 
									
										
										
										
											2015-09-29 16:36:37 -04:00
										 |  |  | 			return postObj && postObj.hasOwnProperty('toPid') ? parseInt(postObj.toPid, 10) : null; | 
					
						
							|  |  |  | 		}).filter(Boolean); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!parentPids.length) { | 
					
						
							|  |  |  | 			return callback(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var parentPosts; | 
					
						
							|  |  |  | 		async.waterfall([ | 
					
						
							|  |  |  | 			async.apply(posts.getPostsFields, parentPids, ['uid']), | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			function (_parentPosts, next) { | 
					
						
							| 
									
										
										
										
											2015-09-29 16:36:37 -04:00
										 |  |  | 				parentPosts = _parentPosts; | 
					
						
							| 
									
										
										
										
											2017-02-23 18:31:49 -07:00
										 |  |  | 				var parentUids = parentPosts.map(function (postObj) { | 
					
						
							|  |  |  | 					return parseInt(postObj.uid, 10); | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 				}).filter(function (uid, idx, users) { | 
					
						
							| 
									
										
										
										
											2015-09-29 16:36:37 -04:00
										 |  |  | 					return users.indexOf(uid) === idx; | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				user.getUsersFields(parentUids, ['username'], next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function (userData, next) { | 
					
						
							|  |  |  | 				var usersMap = {}; | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 				userData.forEach(function (user) { | 
					
						
							| 
									
										
										
										
											2015-09-29 16:36:37 -04:00
										 |  |  | 					usersMap[user.uid] = user.username; | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 				var parents = {}; | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 				parentPosts.forEach(function (post, i) { | 
					
						
							| 
									
										
										
										
											2017-02-18 12:30:49 -07:00
										 |  |  | 					parents[parentPids[i]] = { username: usersMap[post.uid] }; | 
					
						
							| 
									
										
										
										
											2015-09-29 16:36:37 -04:00
										 |  |  | 				}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 				postData.forEach(function (post) { | 
					
						
							| 
									
										
										
										
											2015-09-29 16:36:37 -04:00
										 |  |  | 					post.parent = parents[post.toPid]; | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 				next(); | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2015-09-29 16:36:37 -04:00
										 |  |  | 		], callback); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.calculatePostIndices = function (posts, start, stop, postCount, reverse) { | 
					
						
							|  |  |  | 		posts.forEach(function (post, index) { | 
					
						
							| 
									
										
										
										
											2015-02-07 00:12:47 -05:00
										 |  |  | 			if (reverse) { | 
					
						
							| 
									
										
										
										
											2015-09-15 17:19:03 -04:00
										 |  |  | 				post.index = postCount - (start + index + 1); | 
					
						
							| 
									
										
										
										
											2015-02-07 00:12:47 -05:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2015-09-15 17:19:03 -04:00
										 |  |  | 				post.index = start + index + 1; | 
					
						
							| 
									
										
										
										
											2015-02-07 00:12:47 -05:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-09-15 17:19:03 -04:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2015-02-07 00:12:47 -05:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.getLatestUndeletedPid = function (tid, callback) { | 
					
						
							| 
									
										
										
										
											2015-04-16 13:23:21 -04:00
										 |  |  | 		async.waterfall([ | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			function (next) { | 
					
						
							| 
									
										
										
										
											2015-04-16 13:23:21 -04:00
										 |  |  | 				Topics.getLatestUndeletedReply(tid, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			function (pid, next) { | 
					
						
							| 
									
										
										
										
											2015-04-16 13:23:21 -04:00
										 |  |  | 				if (parseInt(pid, 10)) { | 
					
						
							|  |  |  | 					return callback(null, pid.toString()); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				Topics.getTopicField(tid, 'mainPid', next); | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			function (mainPid, next) { | 
					
						
							| 
									
										
										
										
											2015-04-16 13:23:21 -04:00
										 |  |  | 				posts.getPostFields(mainPid, ['pid', 'deleted'], next); | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			function (mainPost, next) { | 
					
						
							| 
									
										
										
										
											2015-04-16 13:23:21 -04:00
										 |  |  | 				next(null, parseInt(mainPost.pid, 10) && parseInt(mainPost.deleted, 10) !== 1 ? mainPost.pid.toString() : null); | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2015-04-16 13:23:21 -04:00
										 |  |  | 		], callback); | 
					
						
							| 
									
										
										
										
											2014-04-24 20:05:05 -04:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.getLatestUndeletedReply = function (tid, callback) { | 
					
						
							| 
									
										
										
										
											2014-12-12 18:52:37 -05:00
										 |  |  | 		var isDeleted = false; | 
					
						
							|  |  |  | 		var done = false; | 
					
						
							|  |  |  | 		var latestPid = null; | 
					
						
							|  |  |  | 		var index = 0; | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 		var pids; | 
					
						
							| 
									
										
										
										
											2014-12-12 18:52:37 -05:00
										 |  |  | 		async.doWhilst( | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			function (next) { | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 				async.waterfall([ | 
					
						
							|  |  |  | 					function (_next) { | 
					
						
							|  |  |  | 						db.getSortedSetRevRange('tid:' + tid + ':posts', index, index, _next); | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 					function (_pids, _next) { | 
					
						
							|  |  |  | 						pids = _pids; | 
					
						
							| 
									
										
										
										
											2017-05-27 00:30:07 -04:00
										 |  |  | 						if (!pids.length) { | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 							done = true; | 
					
						
							|  |  |  | 							return next(); | 
					
						
							| 
									
										
										
										
											2014-12-12 18:52:37 -05:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2015-04-16 13:23:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 						posts.getPostField(pids[0], 'deleted', _next); | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 					function (deleted, _next) { | 
					
						
							| 
									
										
										
										
											2015-02-04 15:49:08 -05:00
										 |  |  | 						isDeleted = parseInt(deleted, 10) === 1; | 
					
						
							| 
									
										
										
										
											2015-04-16 13:23:21 -04:00
										 |  |  | 						if (!isDeleted) { | 
					
						
							|  |  |  | 							latestPid = pids[0]; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-02-18 01:12:18 -07:00
										 |  |  | 						index += 1; | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 						_next(); | 
					
						
							| 
									
										
										
										
											2017-02-23 18:31:49 -07:00
										 |  |  | 					}, | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 				], next); | 
					
						
							| 
									
										
										
										
											2014-12-12 18:52:37 -05:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			function () { | 
					
						
							| 
									
										
										
										
											2014-12-12 18:52:37 -05:00
										 |  |  | 				return isDeleted && !done; | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			function (err) { | 
					
						
							| 
									
										
										
										
											2014-12-12 18:52:37 -05:00
										 |  |  | 				callback(err, latestPid); | 
					
						
							| 
									
										
										
										
											2017-02-17 20:20:42 -07:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-12-12 18:52:37 -05:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2014-04-24 20:05:05 -04:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.addPostToTopic = function (tid, postData, callback) { | 
					
						
							| 
									
										
										
										
											2016-04-19 20:04:32 +03:00
										 |  |  | 		async.waterfall([ | 
					
						
							|  |  |  | 			function (next) { | 
					
						
							|  |  |  | 				Topics.getTopicField(tid, 'mainPid', next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function (mainPid, next) { | 
					
						
							|  |  |  | 				if (!parseInt(mainPid, 10)) { | 
					
						
							|  |  |  | 					Topics.setTopicField(tid, 'mainPid', postData.pid, next); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					async.parallel([ | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 						function (next) { | 
					
						
							| 
									
										
										
										
											2016-04-19 20:04:32 +03:00
										 |  |  | 							db.sortedSetAdd('tid:' + tid + ':posts', postData.timestamp, postData.pid, next); | 
					
						
							|  |  |  | 						}, | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 						function (next) { | 
					
						
							| 
									
										
										
										
											2016-06-14 10:07:39 +03:00
										 |  |  | 							var upvotes = parseInt(postData.upvotes, 10) || 0; | 
					
						
							|  |  |  | 							var downvotes = parseInt(postData.downvotes, 10) || 0; | 
					
						
							|  |  |  | 							var votes = upvotes - downvotes; | 
					
						
							|  |  |  | 							db.sortedSetAdd('tid:' + tid + ':posts:votes', votes, postData.pid, next); | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 						}, | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 					], function (err) { | 
					
						
							| 
									
										
										
										
											2016-04-19 20:04:32 +03:00
										 |  |  | 						next(err); | 
					
						
							|  |  |  | 					}); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function (next) { | 
					
						
							|  |  |  | 				db.sortedSetIncrBy('tid:' + tid + ':posters', 1, postData.uid, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function (count, next) { | 
					
						
							|  |  |  | 				Topics.updateTeaser(tid, next); | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-04-19 20:04:32 +03:00
										 |  |  | 		], callback); | 
					
						
							| 
									
										
										
										
											2014-03-21 17:04:15 -04:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.removePostFromTopic = function (tid, postData, callback) { | 
					
						
							| 
									
										
										
										
											2016-04-19 20:04:32 +03:00
										 |  |  | 		async.waterfall([ | 
					
						
							|  |  |  | 			function (next) { | 
					
						
							|  |  |  | 				db.sortedSetsRemove([ | 
					
						
							|  |  |  | 					'tid:' + tid + ':posts', | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 					'tid:' + tid + ':posts:votes', | 
					
						
							| 
									
										
										
										
											2016-04-19 20:04:32 +03:00
										 |  |  | 				], postData.pid, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function (next) { | 
					
						
							|  |  |  | 				db.sortedSetIncrBy('tid:' + tid + ':posters', -1, postData.uid, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function (count, next) { | 
					
						
							|  |  |  | 				Topics.updateTeaser(tid, next); | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-04-19 20:04:32 +03:00
										 |  |  | 		], callback); | 
					
						
							| 
									
										
										
										
											2014-03-21 17:04:15 -04:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.getPids = function (tid, callback) { | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 		async.waterfall([ | 
					
						
							|  |  |  | 			function (next) { | 
					
						
							|  |  |  | 				async.parallel({ | 
					
						
							|  |  |  | 					mainPid: function (next) { | 
					
						
							|  |  |  | 						Topics.getTopicField(tid, 'mainPid', next); | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 					pids: function (next) { | 
					
						
							|  |  |  | 						db.getSortedSetRange('tid:' + tid + ':posts', 0, -1, next); | 
					
						
							| 
									
										
										
										
											2017-02-23 18:31:49 -07:00
										 |  |  | 					}, | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 				}, next); | 
					
						
							| 
									
										
										
										
											2014-07-19 08:59:59 -04:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 			function (results, next) { | 
					
						
							|  |  |  | 				if (results.mainPid) { | 
					
						
							|  |  |  | 					results.pids = [results.mainPid].concat(results.pids); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				next(null, results.pids); | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 		], callback); | 
					
						
							| 
									
										
										
										
											2014-03-21 17:04:15 -04:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.increasePostCount = function (tid, callback) { | 
					
						
							| 
									
										
										
										
											2014-03-21 17:04:15 -04:00
										 |  |  | 		incrementFieldAndUpdateSortedSet(tid, 'postcount', 1, 'topics:posts', callback); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.decreasePostCount = function (tid, callback) { | 
					
						
							| 
									
										
										
										
											2014-03-21 17:04:15 -04:00
										 |  |  | 		incrementFieldAndUpdateSortedSet(tid, 'postcount', -1, 'topics:posts', callback); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.increaseViewCount = function (tid, callback) { | 
					
						
							| 
									
										
										
										
											2014-03-21 17:04:15 -04:00
										 |  |  | 		incrementFieldAndUpdateSortedSet(tid, 'viewcount', 1, 'topics:views', callback); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function incrementFieldAndUpdateSortedSet(tid, field, by, set, callback) { | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 		callback = callback || function () {}; | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 		async.waterfall([ | 
					
						
							|  |  |  | 			function (next) { | 
					
						
							|  |  |  | 				db.incrObjectFieldBy('topic:' + tid, field, by, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function (value, next) { | 
					
						
							|  |  |  | 				db.sortedSetAdd(set, value, tid, next); | 
					
						
							| 
									
										
										
										
											2017-02-23 18:31:49 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 		], callback); | 
					
						
							| 
									
										
										
										
											2014-03-21 17:04:15 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.getTitleByPid = function (pid, callback) { | 
					
						
							| 
									
										
										
										
											2014-03-21 17:04:15 -04:00
										 |  |  | 		Topics.getTopicFieldByPid('title', pid, callback); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.getTopicFieldByPid = function (field, pid, callback) { | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 		async.waterfall([ | 
					
						
							|  |  |  | 			function (next) { | 
					
						
							|  |  |  | 				posts.getPostField(pid, 'tid', next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function (tid, next) { | 
					
						
							|  |  |  | 				Topics.getTopicField(tid, field, next); | 
					
						
							| 
									
										
										
										
											2017-02-23 18:31:49 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 		], callback); | 
					
						
							| 
									
										
										
										
											2014-03-21 17:04:15 -04:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.getTopicDataByPid = function (pid, callback) { | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 		async.waterfall([ | 
					
						
							|  |  |  | 			function (next) { | 
					
						
							|  |  |  | 				posts.getPostField(pid, 'tid', next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function (tid, next) { | 
					
						
							|  |  |  | 				Topics.getTopicData(tid, next); | 
					
						
							| 
									
										
										
										
											2017-02-23 18:31:49 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2017-02-23 22:42:45 +03:00
										 |  |  | 		], callback); | 
					
						
							| 
									
										
										
										
											2014-03-21 17:04:15 -04:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.getPostCount = function (tid, callback) { | 
					
						
							| 
									
										
										
										
											2014-10-14 23:12:47 -04:00
										 |  |  | 		db.getObjectField('topic:' + tid, 'postcount', callback); | 
					
						
							| 
									
										
										
										
											2014-06-02 20:41:03 -04:00
										 |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2017-03-15 18:56:12 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	function getPostReplies(pids, callerUid, callback) { | 
					
						
							|  |  |  | 		async.map(pids, function (pid, next) { | 
					
						
							| 
									
										
										
										
											2017-05-19 17:14:46 -04:00
										 |  |  | 			var replyPids; | 
					
						
							|  |  |  | 			var uids = []; | 
					
						
							|  |  |  | 			async.waterfall([ | 
					
						
							|  |  |  | 				function (next) { | 
					
						
							|  |  |  | 					db.getSortedSetRange('pid:' + pid + ':replies', 0, -1, next); | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				function (_replyPids, next) { | 
					
						
							|  |  |  | 					replyPids = _replyPids; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					var count = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					async.until(function () { | 
					
						
							|  |  |  | 						return count === replyPids.length || uids.length === 6; | 
					
						
							|  |  |  | 					}, function (next) { | 
					
						
							|  |  |  | 						async.waterfall([ | 
					
						
							|  |  |  | 							function (next) { | 
					
						
							|  |  |  | 								posts.getPostField(replyPids[count], 'uid', next); | 
					
						
							|  |  |  | 							}, | 
					
						
							|  |  |  | 							function (uid, next) { | 
					
						
							|  |  |  | 								uid = parseInt(uid, 10); | 
					
						
							|  |  |  | 								if (uids.indexOf(uid) === -1) { | 
					
						
							|  |  |  | 									uids.push(uid); | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 								count += 1; | 
					
						
							|  |  |  | 								next(); | 
					
						
							|  |  |  | 							}, | 
					
						
							|  |  |  | 						], next); | 
					
						
							|  |  |  | 					}, next); | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				function (next) { | 
					
						
							| 
									
										
										
										
											2017-03-15 18:56:12 -04:00
										 |  |  | 					async.parallel({ | 
					
						
							| 
									
										
										
										
											2017-03-17 13:35:24 -04:00
										 |  |  | 						users: function (next) { | 
					
						
							| 
									
										
										
										
											2017-03-15 18:56:12 -04:00
										 |  |  | 							user.getUsersWithFields(uids, ['uid', 'username', 'userslug', 'picture'], callerUid, next); | 
					
						
							|  |  |  | 						}, | 
					
						
							| 
									
										
										
										
											2017-03-17 13:35:24 -04:00
										 |  |  | 						timestampISO: function (next) { | 
					
						
							| 
									
										
										
										
											2017-03-15 18:56:12 -04:00
										 |  |  | 							posts.getPostField(replyPids[0], 'timestamp', function (err, timestamp) { | 
					
						
							|  |  |  | 								next(err, utils.toISOString(timestamp)); | 
					
						
							|  |  |  | 							}); | 
					
						
							|  |  |  | 						}, | 
					
						
							| 
									
										
										
										
											2017-05-19 17:14:46 -04:00
										 |  |  | 					}, next); | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				function (replies, next) { | 
					
						
							|  |  |  | 					if (replies.users.length > 5) { | 
					
						
							|  |  |  | 						replies.users.shift(); | 
					
						
							|  |  |  | 						replies.hasMore = true; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-03-15 18:56:12 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 17:14:46 -04:00
										 |  |  | 					replies.count = replyPids.length; | 
					
						
							|  |  |  | 					replies.text = replies.count > 1 ? '[[topic:replies_to_this_post, ' + replies.count + ']]' : '[[topic:one_reply_to_this_post]]'; | 
					
						
							|  |  |  | 					next(null, replies); | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			], next); | 
					
						
							| 
									
										
										
										
											2017-03-15 18:56:12 -04:00
										 |  |  | 		}, callback); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-03-21 17:04:15 -04:00
										 |  |  | }; |