mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 11:05:54 +01:00 
			
		
		
		
	posts.js refactor pt1
This commit is contained in:
		
							
								
								
									
										412
									
								
								src/posts.js
									
									
									
									
									
								
							
							
						
						
									
										412
									
								
								src/posts.js
									
									
									
									
									
								
							| @@ -1,107 +1,25 @@ | ||||
| 'use strict'; | ||||
|  | ||||
| var async = require('async'), | ||||
| 	path = require('path'), | ||||
| 	fs = require('fs'), | ||||
| 	nconf = require('nconf'), | ||||
| 	_ = require('underscore'), | ||||
| 	validator = require('validator'), | ||||
| 	winston = require('winston'), | ||||
| 	gravatar = require('gravatar'), | ||||
| 	S = require('string'), | ||||
|  | ||||
|  | ||||
| 	db = require('./database'), | ||||
| 	utils = require('../public/src/utils'), | ||||
| 	user = require('./user'), | ||||
| 	groups = require('./groups'), | ||||
| 	topics = require('./topics'), | ||||
| 	favourites = require('./favourites'), | ||||
| 	postTools = require('./postTools'), | ||||
| 	privileges = require('./privileges'), | ||||
| 	categories = require('./categories'), | ||||
| 	plugins = require('./plugins'), | ||||
| 	meta = require('./meta'), | ||||
| 	emitter = require('./emitter'), | ||||
| 	websockets = require('./socket.io'); | ||||
| 	plugins = require('./plugins'); | ||||
|  | ||||
| (function(Posts) { | ||||
| 	require('./posts/recent')(Posts); | ||||
|  | ||||
| 	require('./posts/create')(Posts); | ||||
| 	require('./posts/delete')(Posts); | ||||
| 	require('./posts/user')(Posts); | ||||
| 	require('./posts/category')(Posts); | ||||
| 	require('./posts/summary')(Posts); | ||||
| 	require('./posts/recent')(Posts); | ||||
| 	require('./posts/flags')(Posts); | ||||
|  | ||||
| 	Posts.create = function(data, callback) { | ||||
| 		var uid = data.uid, | ||||
| 			tid = data.tid, | ||||
| 			content = data.content, | ||||
| 			timestamp = data.timestamp || Date.now(); | ||||
|  | ||||
|  | ||||
| 		if (uid === null) { | ||||
| 			return callback(new Error('[[error:invalid-uid]]')); | ||||
| 		} | ||||
|  | ||||
| 		var postData; | ||||
|  | ||||
| 		async.waterfall([ | ||||
| 			function(next) { | ||||
| 				db.incrObjectField('global', 'nextPid', next); | ||||
| 			}, | ||||
| 			function(pid, next) { | ||||
|  | ||||
| 				postData = { | ||||
| 					'pid': pid, | ||||
| 					'uid': uid, | ||||
| 					'tid': tid, | ||||
| 					'content': content, | ||||
| 					'timestamp': timestamp, | ||||
| 					'reputation': 0, | ||||
| 					'votes': 0, | ||||
| 					'editor': '', | ||||
| 					'edited': 0, | ||||
| 					'deleted': 0 | ||||
| 				}; | ||||
|  | ||||
| 				if (data.toPid) { | ||||
| 					postData.toPid = data.toPid; | ||||
| 				} | ||||
|  | ||||
| 				plugins.fireHook('filter:post.save', postData, next); | ||||
| 			}, | ||||
| 			function(postData, next) { | ||||
| 				db.setObject('post:' + postData.pid, postData, next); | ||||
| 			}, | ||||
| 			function(next) { | ||||
| 				async.parallel([ | ||||
| 					function(next) { | ||||
| 						user.onNewPostMade(postData, next); | ||||
| 					}, | ||||
| 					function(next) { | ||||
| 						topics.onNewPostMade(postData, next); | ||||
| 					}, | ||||
| 					function(next) { | ||||
| 						categories.onNewPostMade(postData, next); | ||||
| 					}, | ||||
| 					function(next) { | ||||
| 						db.sortedSetAdd('posts:pid', timestamp, postData.pid, next); | ||||
| 					}, | ||||
| 					function(next) { | ||||
| 						db.incrObjectField('global', 'postCount', next); | ||||
| 					} | ||||
| 				], function(err) { | ||||
| 					if (err) { | ||||
| 						return next(err); | ||||
| 					} | ||||
| 					plugins.fireHook('filter:post.get', postData, next); | ||||
| 				}); | ||||
| 			}, | ||||
| 			function(postData, next) { | ||||
| 				plugins.fireHook('action:post.save', postData); | ||||
| 				next(null, postData); | ||||
| 			} | ||||
| 		], callback); | ||||
| 	}; | ||||
|  | ||||
| 	Posts.exists = function(pid, callback) { | ||||
| 		db.isSortedSetMember('posts:pid', pid, callback); | ||||
| 	}; | ||||
| @@ -167,184 +85,6 @@ var async = require('async'), | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	Posts.getUserInfoForPosts = function(uids, uid, callback) { | ||||
| 		async.parallel({ | ||||
| 			groups: function(next) { | ||||
| 				groups.getUserGroups(uids, next); | ||||
| 			}, | ||||
| 			userData: function(next) { | ||||
| 				user.getMultipleUserFields(uids, ['uid', 'username', 'userslug', 'reputation', 'postcount', 'picture', 'signature', 'banned', 'status'], next); | ||||
| 			}, | ||||
| 			online: function(next) { | ||||
| 				websockets.isUsersOnline(uids, next); | ||||
| 			} | ||||
| 		}, function(err, results) { | ||||
| 			if (err) { | ||||
| 				return callback(err); | ||||
| 			} | ||||
|  | ||||
| 			var userData = results.userData; | ||||
| 			for(var i=0; i<userData.length; ++i) { | ||||
| 				userData[i].groups = results.groups[i]; | ||||
| 				userData[i].status = results.online[i] ? (userData[i].status || 'online') : 'offline'; | ||||
| 			} | ||||
|  | ||||
| 			async.map(userData, function(userData, next) { | ||||
| 				userData.uid = userData.uid || 0; | ||||
| 				userData.username = userData.username || '[[global:guest]]'; | ||||
| 				userData.userslug = userData.userslug || ''; | ||||
| 				userData.reputation = userData.reputation || 0; | ||||
| 				userData.postcount = userData.postcount || 0; | ||||
| 				userData.banned = parseInt(userData.banned, 10) === 1; | ||||
| 				userData.picture = userData.picture || user.createGravatarURLFromEmail(''); | ||||
|  | ||||
| 				async.parallel({ | ||||
| 					signature: function(next) { | ||||
| 						if (parseInt(meta.config.disableSignatures, 10) === 1) { | ||||
| 							userData.signature = ''; | ||||
| 							return next(); | ||||
| 						} | ||||
| 						postTools.parseSignature(userData, uid, next); | ||||
| 					}, | ||||
| 					customProfileInfo: function(next) { | ||||
| 						plugins.fireHook('filter:posts.custom_profile_info', {profile: [], uid: userData.uid}, next); | ||||
| 					} | ||||
| 				}, function(err, results) { | ||||
| 					if (err) { | ||||
| 						return next(err); | ||||
| 					} | ||||
|  | ||||
| 					userData.custom_profile_info = results.customProfileInfo.profile; | ||||
|  | ||||
| 					plugins.fireHook('filter:posts.modifyUserInfo', userData, next); | ||||
| 				}); | ||||
| 			}, callback); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	Posts.getPostSummaryByPids = function(pids, uid, options, callback) { | ||||
| 		options.stripTags = options.hasOwnProperty('stripTags') ? options.stripTags : false; | ||||
| 		options.parse = options.hasOwnProperty('parse') ? options.parse : true; | ||||
| 		options.extraFields = options.hasOwnProperty('extraFields') ? options.extraFields : []; | ||||
|  | ||||
| 		if (!Array.isArray(pids) || !pids.length) { | ||||
| 			return callback(null, []); | ||||
| 		} | ||||
|  | ||||
| 		var keys = pids.map(function(pid) { | ||||
| 			return 'post:' + pid; | ||||
| 		}); | ||||
|  | ||||
| 		var fields = ['pid', 'tid', 'content', 'uid', 'timestamp', 'deleted'].concat(options.extraFields); | ||||
|  | ||||
| 		db.getObjectsFields(keys, fields, function(err, posts) { | ||||
| 			if (err) { | ||||
| 				return callback(err); | ||||
| 			} | ||||
|  | ||||
| 			posts = posts.filter(function(p) { | ||||
| 				return !!p && parseInt(p.deleted, 10) !== 1; | ||||
| 			}); | ||||
|  | ||||
| 			var uids = [], tids = []; | ||||
| 			for(var i=0; i<posts.length; ++i) { | ||||
| 				if (uids.indexOf(posts[i].uid) === -1) { | ||||
| 					uids.push(posts[i].uid); | ||||
| 				} | ||||
| 				if (tids.indexOf('topic:' + posts[i].tid) === -1) { | ||||
| 					tids.push('topic:' + posts[i].tid); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			async.parallel({ | ||||
| 				users: function(next) { | ||||
| 					user.getMultipleUserFields(uids, ['uid', 'username', 'userslug', 'picture'], next); | ||||
| 				}, | ||||
| 				topicsAndCategories: function(next) { | ||||
| 					db.getObjectsFields(tids, ['uid', 'tid', 'title', 'cid', 'slug', 'deleted'], function(err, topics) { | ||||
| 						if (err) { | ||||
| 							return next(err); | ||||
| 						} | ||||
|  | ||||
| 						var cids = topics.map(function(topic) { | ||||
| 							if (topic) { | ||||
| 								topic.title = validator.escape(topic.title); | ||||
| 							} | ||||
| 							return topic && topic.cid; | ||||
| 						}).filter(function(value, index, array) { | ||||
| 							return value && array.indexOf(value) === index; | ||||
| 						}); | ||||
|  | ||||
| 						categories.getMultipleCategoryFields(cids, ['cid', 'name', 'icon', 'slug'], function(err, categories) { | ||||
| 							next(err, {topics: topics, categories: categories}); | ||||
| 						}); | ||||
| 					}); | ||||
| 				}, | ||||
| 				indices: function(next) { | ||||
| 					Posts.getPostIndices(posts, uid, next); | ||||
| 				} | ||||
| 			}, function(err, results) { | ||||
| 				function toObject(key, data) { | ||||
| 					var obj = {}; | ||||
| 					for(var i=0; i<data.length; ++i) { | ||||
| 						obj[data[i][key]] = data[i]; | ||||
| 					} | ||||
| 					return obj; | ||||
| 				} | ||||
|  | ||||
| 				function stripTags(content) { | ||||
| 					if (options.stripTags && content) { | ||||
| 						var s = S(content); | ||||
| 						return s.stripTags.apply(s, utils.stripTags).s; | ||||
| 					} | ||||
| 					return content; | ||||
| 				} | ||||
|  | ||||
| 				if (err) { | ||||
| 					return callback(err); | ||||
| 				} | ||||
|  | ||||
| 				results.users = toObject('uid', results.users); | ||||
| 				results.topics = toObject('tid', results.topicsAndCategories.topics); | ||||
| 				results.categories = toObject('cid', results.topicsAndCategories.categories); | ||||
|  | ||||
| 				for (var i=0; i<posts.length; ++i) { | ||||
| 					posts[i].index = utils.isNumber(results.indices[i]) ? parseInt(results.indices[i], 10) + 1 : 1; | ||||
| 				} | ||||
|  | ||||
| 				posts = posts.filter(function(post) { | ||||
| 					return results.topics[post.tid] && parseInt(results.topics[post.tid].deleted, 10) !== 1; | ||||
| 				}); | ||||
|  | ||||
| 				async.map(posts, function(post, next) { | ||||
| 					post.user = results.users[post.uid]; | ||||
| 					post.topic = results.topics[post.tid]; | ||||
| 					post.category = results.categories[post.topic.cid]; | ||||
| 					post.relativeTime = utils.toISOString(post.timestamp); | ||||
|  | ||||
| 					if (!post.content || !options.parse) { | ||||
| 						post.content = stripTags(post.content); | ||||
| 						return next(null, post); | ||||
| 					} | ||||
|  | ||||
| 					postTools.parsePost(post, uid, function(err, post) { | ||||
| 						if (err) { | ||||
| 							return next(err); | ||||
| 						} | ||||
|  | ||||
| 						post.content = stripTags(post.content); | ||||
|  | ||||
| 						next(null, post); | ||||
| 					}); | ||||
| 				}, function(err, posts) { | ||||
| 					plugins.fireHook('filter:post.getPostSummaryByPids', {posts: posts, uid: uid}, function(err, postData) { | ||||
| 						callback(err, postData.posts); | ||||
| 					}); | ||||
| 				}); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	Posts.getPostData = function(pid, callback) { | ||||
| 		db.getObject('post:' + pid, function(err, data) { | ||||
| 			if(err) { | ||||
| @@ -405,107 +145,6 @@ var async = require('async'), | ||||
| 		db.setObject('post:' + pid, data, callback); | ||||
| 	}; | ||||
|  | ||||
| 	Posts.getCidByPid = function(pid, callback) { | ||||
| 		Posts.getPostField(pid, 'tid', function(err, tid) { | ||||
| 			if(err) { | ||||
| 				return callback(err); | ||||
| 			} | ||||
|  | ||||
| 			topics.getTopicField(tid, 'cid', function(err, cid) { | ||||
| 				if(err || !cid) { | ||||
| 					return callback(err || new Error('[[error:invalid-cid]]')); | ||||
| 				} | ||||
| 				callback(null, cid); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	Posts.getCidsByPids = function(pids, callback) { | ||||
| 		Posts.getPostsFields(pids, ['tid'], function(err, posts) { | ||||
| 			if (err) { | ||||
| 				return callback(err); | ||||
| 			} | ||||
|  | ||||
| 			var tids = posts.map(function(post) { | ||||
| 				return post.tid; | ||||
| 			}).filter(function(tid, index, array) { | ||||
| 				return tid && array.indexOf(tid) === index; | ||||
| 			}); | ||||
|  | ||||
| 			topics.getTopicsFields(tids, ['cid'], function(err, topics) { | ||||
| 				if (err) { | ||||
| 					return callback(err); | ||||
| 				} | ||||
|  | ||||
| 				var map = {}; | ||||
| 				topics.forEach(function(topic, index) { | ||||
| 					if (topic) { | ||||
| 						map[tids[index]] = topic.cid; | ||||
| 					} | ||||
| 				}); | ||||
|  | ||||
| 				var cids = posts.map(function(post) { | ||||
| 					return map[post.tid]; | ||||
| 				}); | ||||
|  | ||||
| 				callback(null, cids); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	Posts.getPostsByUid = function(callerUid, uid, start, end, callback) { | ||||
| 		user.getPostIds(uid, start, end, function(err, pids) { | ||||
| 			if (err) { | ||||
| 				return callback(err); | ||||
| 			} | ||||
|  | ||||
| 			privileges.posts.filter('read', pids, callerUid, function(err, pids) { | ||||
| 				if (err) { | ||||
| 					return callback(err); | ||||
| 				} | ||||
| 				getPosts(pids, callerUid, function(err, posts) { | ||||
| 					if (err) { | ||||
| 						return callback(err); | ||||
| 					} | ||||
| 					callback(null, {posts: posts, nextStart: end + 1}); | ||||
| 				}); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	Posts.getFavourites = function(uid, start, end, callback) { | ||||
| 		db.getSortedSetRevRange('uid:' + uid + ':favourites', start, end, function(err, pids) { | ||||
| 			if (err) { | ||||
| 				return callback(err); | ||||
| 			} | ||||
|  | ||||
| 			getPosts(pids, uid, function(err, posts) { | ||||
| 				if (err) { | ||||
| 					return callback(err); | ||||
| 				} | ||||
| 				callback(null, {posts: posts, nextStart: end + 1}); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	function getPosts(pids, uid, callback) { | ||||
| 		if (!Array.isArray(pids) || !pids.length) { | ||||
| 			return callback(null, []); | ||||
| 		} | ||||
|  | ||||
| 		Posts.getPostSummaryByPids(pids, uid, {stripTags: false}, function(err, posts) { | ||||
| 			if (err) { | ||||
| 				return callback(err); | ||||
| 			} | ||||
|  | ||||
| 			if (!Array.isArray(posts) || !posts.length) { | ||||
| 				return callback(null, []); | ||||
| 			} | ||||
|  | ||||
| 			callback(null, posts); | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	Posts.getPidIndex = function(pid, uid, callback) { | ||||
| 		async.parallel({ | ||||
| 			settings: function(next) { | ||||
| @@ -568,43 +207,6 @@ var async = require('async'), | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	Posts.isOwner = function(pid, uid, callback) { | ||||
| 		uid = parseInt(uid, 10); | ||||
| 		if (Array.isArray(pid)) { | ||||
| 			if (!uid) { | ||||
| 				return callback(null, pid.map(function() {return false;})); | ||||
| 			} | ||||
| 			Posts.getPostsFields(pid, ['uid'], function(err, posts) { | ||||
| 				if (err) { | ||||
| 					return callback(err); | ||||
| 				} | ||||
| 				posts = posts.map(function(post) { | ||||
| 					return post && parseInt(post.uid, 10) === uid; | ||||
| 				}); | ||||
| 				callback(null, posts); | ||||
| 			}); | ||||
| 		} else { | ||||
| 			if (!uid) { | ||||
| 				return callback(null, false); | ||||
| 			} | ||||
| 			Posts.getPostField(pid, 'uid', function(err, author) { | ||||
| 				callback(err, parseInt(author, 10) === uid); | ||||
| 			}); | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	Posts.isModerator = function(pids, uid, callback) { | ||||
| 		if (!parseInt(uid, 10)) { | ||||
| 			return callback(null, pids.map(function() {return false;})); | ||||
| 		} | ||||
| 		Posts.getCidsByPids(pids, function(err, cids) { | ||||
| 			if (err) { | ||||
| 				return callback(err); | ||||
| 			} | ||||
| 			user.isModerator(uid, cids, callback); | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	Posts.isMain = function(pid, callback) { | ||||
| 		Posts.getPostField(pid, 'tid', function(err, tid) { | ||||
| 			if (err) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user