feat: #7743, posts module

v1.18.x
Barış Soner Uşaklı 6 years ago
parent 930ffd074f
commit 1b2b308a7e

@ -1,99 +1,68 @@
'use strict';
var async = require('async');
var db = require('../database');
var plugins = require('../plugins');
const db = require('../database');
const plugins = require('../plugins');
module.exports = function (Posts) {
Posts.bookmark = function (pid, uid, callback) {
toggleBookmark('bookmark', pid, uid, callback);
Posts.bookmark = async function (pid, uid) {
return await toggleBookmark('bookmark', pid, uid);
};
Posts.unbookmark = function (pid, uid, callback) {
toggleBookmark('unbookmark', pid, uid, callback);
Posts.unbookmark = async function (pid, uid) {
return await toggleBookmark('unbookmark', pid, uid);
};
function toggleBookmark(type, pid, uid, callback) {
async function toggleBookmark(type, pid, uid) {
if (parseInt(uid, 10) <= 0) {
return callback(new Error('[[error:not-logged-in]]'));
throw new Error('[[error:not-logged-in]]');
}
var isBookmarking = type === 'bookmark';
var postData;
var hasBookmarked;
var owner;
async.waterfall([
function (next) {
async.parallel({
owner: function (next) {
Posts.getPostField(pid, 'uid', next);
},
postData: function (next) {
Posts.getPostFields(pid, ['pid', 'uid'], next);
},
hasBookmarked: function (next) {
Posts.hasBookmarked(pid, uid, next);
},
}, next);
},
function (results, next) {
owner = results.owner;
postData = results.postData;
hasBookmarked = results.hasBookmarked;
const isBookmarking = type === 'bookmark';
const [postData, hasBookmarked] = await Promise.all([
Posts.getPostFields(pid, ['pid', 'uid']),
Posts.hasBookmarked(pid, uid),
]);
if (isBookmarking && hasBookmarked) {
return callback(new Error('[[error:already-bookmarked]]'));
throw new Error('[[error:already-bookmarked]]');
}
if (!isBookmarking && !hasBookmarked) {
return callback(new Error('[[error:already-unbookmarked]]'));
throw new Error('[[error:already-unbookmarked]]');
}
if (isBookmarking) {
db.sortedSetAdd('uid:' + uid + ':bookmarks', Date.now(), pid, next);
await db.sortedSetAdd('uid:' + uid + ':bookmarks', Date.now(), pid);
} else {
db.sortedSetRemove('uid:' + uid + ':bookmarks', pid, next);
await db.sortedSetRemove('uid:' + uid + ':bookmarks', pid);
}
},
function (next) {
db[isBookmarking ? 'setAdd' : 'setRemove']('pid:' + pid + ':users_bookmarked', uid, next);
},
function (next) {
db.setCount('pid:' + pid + ':users_bookmarked', next);
},
function (count, next) {
postData.bookmarks = count;
Posts.setPostField(pid, 'bookmarks', count, next);
},
function (next) {
var current = hasBookmarked ? 'bookmarked' : 'unbookmarked';
await db[isBookmarking ? 'setAdd' : 'setRemove']('pid:' + pid + ':users_bookmarked', uid);
postData.bookmarks = await db.setCount('pid:' + pid + ':users_bookmarked');
await Posts.setPostField(pid, 'bookmarks', postData.bookmarks);
plugins.fireHook('action:post.' + type, {
pid: pid,
uid: uid,
owner: owner,
current: current,
owner: postData.uid,
current: hasBookmarked ? 'bookmarked' : 'unbookmarked',
});
next(null, {
return {
post: postData,
isBookmarked: isBookmarking,
});
},
], callback);
};
}
Posts.hasBookmarked = function (pid, uid, callback) {
Posts.hasBookmarked = async function (pid, uid) {
if (parseInt(uid, 10) <= 0) {
return callback(null, Array.isArray(pid) ? pid.map(() => false) : false);
return Array.isArray(pid) ? pid.map(() => false) : false;
}
if (Array.isArray(pid)) {
var sets = pid.map(pid => 'pid:' + pid + ':users_bookmarked');
db.isMemberOfSets(sets, uid, callback);
} else {
db.isSetMember('pid:' + pid + ':users_bookmarked', uid, callback);
const sets = pid.map(pid => 'pid:' + pid + ':users_bookmarked');
return await db.isMemberOfSets(sets, uid);
}
return await db.isSetMember('pid:' + pid + ':users_bookmarked', uid);
};
};

@ -1,83 +1,41 @@
'use strict';
var async = require('async');
var _ = require('lodash');
var db = require('../database');
var topics = require('../topics');
const _ = require('lodash');
const db = require('../database');
const topics = require('../topics');
module.exports = function (Posts) {
Posts.getCidByPid = function (pid, callback) {
async.waterfall([
function (next) {
Posts.getPostField(pid, 'tid', next);
},
function (tid, next) {
topics.getTopicField(tid, 'cid', next);
},
], callback);
Posts.getCidByPid = async function (pid) {
const tid = await Posts.getPostField(pid, 'tid');
return await topics.getTopicField(tid, 'cid');
};
Posts.getCidsByPids = function (pids, callback) {
var tids;
var postData;
async.waterfall([
function (next) {
Posts.getPostsFields(pids, ['tid'], next);
},
function (_postData, next) {
postData = _postData;
tids = _.uniq(postData.map(post => post && post.tid).filter(Boolean));
topics.getTopicsFields(tids, ['cid'], next);
},
function (topicData, next) {
var map = {};
topicData.forEach(function (topic, index) {
if (topic) {
map[tids[index]] = topic.cid;
}
});
var cids = postData.map(post => map[post.tid]);
next(null, cids);
},
], callback);
Posts.getCidsByPids = async function (pids) {
const postData = await Posts.getPostsFields(pids, ['tid']);
const tids = _.uniq(postData.map(post => post && post.tid).filter(Boolean));
const topicData = await topics.getTopicsFields(tids, ['cid']);
const tidToTopic = _.zipObject(tids, topicData);
const cids = postData.map(post => tidToTopic[post.tid].cid);
return cids;
};
Posts.filterPidsByCid = function (pids, cid, callback) {
Posts.filterPidsByCid = async function (pids, cid) {
if (!cid) {
return setImmediate(callback, null, pids);
return pids;
}
if (!Array.isArray(cid) || cid.length === 1) {
return filterPidsBySingleCid(pids, cid, callback);
return await filterPidsBySingleCid(pids, cid);
}
async.waterfall([
function (next) {
async.map(cid, function (cid, next) {
Posts.filterPidsByCid(pids, cid, next);
}, next);
},
function (pidsArr, next) {
next(null, _.union.apply(_, pidsArr));
},
], callback);
const pidsArr = await Promise.all(cid.map(c => Posts.filterPidsByCid(pids, c)));
return _.union.apply(_, pidsArr);
};
function filterPidsBySingleCid(pids, cid, callback) {
async.waterfall([
function (next) {
db.isSortedSetMembers('cid:' + parseInt(cid, 10) + ':pids', pids, next);
},
function (isMembers, next) {
pids = pids.filter(function (pid, index) {
return pid && isMembers[index];
});
next(null, pids);
},
], callback);
async function filterPidsBySingleCid(pids, cid) {
const isMembers = await db.isSortedSetMembers('cid:' + parseInt(cid, 10) + ':pids', pids);
return pids.filter((pid, index) => pid && isMembers[index]);
}
};

@ -1,6 +1,5 @@
'use strict';
var async = require('async');
var _ = require('lodash');
var meta = require('../meta');
@ -13,30 +12,24 @@ var groups = require('../groups');
var utils = require('../utils');
module.exports = function (Posts) {
Posts.create = function (data, callback) {
Posts.create = async function (data) {
// This is an internal method, consider using Topics.reply instead
var uid = data.uid;
var tid = data.tid;
var content = data.content.toString();
var timestamp = data.timestamp || Date.now();
var isMain = data.isMain || false;
const uid = data.uid;
const tid = data.tid;
const content = data.content.toString();
const timestamp = data.timestamp || Date.now();
const isMain = data.isMain || false;
if (!uid && parseInt(uid, 10) !== 0) {
return callback(new Error('[[error:invalid-uid]]'));
throw new Error('[[error:invalid-uid]]');
}
if (data.toPid && !utils.isNumber(data.toPid)) {
return callback(new Error('[[error:invalid-pid]]'));
throw new Error('[[error:invalid-pid]]');
}
var postData;
async.waterfall([
function (next) {
db.incrObjectField('global', 'nextPid', next);
},
function (pid, next) {
postData = {
const pid = await db.incrObjectField('global', 'nextPid');
let postData = {
pid: pid,
uid: uid,
tid: tid,
@ -48,67 +41,44 @@ module.exports = function (Posts) {
if (data.toPid) {
postData.toPid = data.toPid;
}
if (data.ip && meta.config.trackIpPerPost) {
postData.ip = data.ip;
}
if (data.handle && !parseInt(uid, 10)) {
postData.handle = data.handle;
}
plugins.fireHook('filter:post.create', { post: postData, data: data }, next);
},
function (data, next) {
postData = data.post;
db.setObject('post:' + postData.pid, postData, next);
},
function (next) {
topics.getTopicFields(tid, ['cid', 'pinned'], next);
},
function (topicData, next) {
let result = await plugins.fireHook('filter:post.create', { post: postData, data: data });
postData = result.post;
await db.setObject('post:' + postData.pid, postData);
const topicData = await topics.getTopicFields(tid, ['cid', 'pinned']);
postData.cid = topicData.cid;
async.parallel([
function (next) {
user.onNewPostMade(postData, next);
},
function (next) {
topics.onNewPostMade(postData, next);
},
function (next) {
categories.onNewPostMade(topicData.cid, topicData.pinned, postData, next);
},
function (next) {
groups.onNewPostMade(postData, next);
},
function (next) {
db.sortedSetAdd('posts:pid', timestamp, postData.pid, next);
},
function (next) {
await Promise.all([
db.sortedSetAdd('posts:pid', timestamp, postData.pid),
db.incrObjectField('global', 'postCount'),
user.onNewPostMade(postData),
topics.onNewPostMade(postData),
categories.onNewPostMade(topicData.cid, topicData.pinned, postData),
groups.onNewPostMade(postData),
addReplyTo(postData, timestamp),
Posts.uploads.sync(postData.pid),
]);
result = await plugins.fireHook('filter:post.get', { post: postData, uid: data.uid });
result.post.isMain = isMain;
plugins.fireHook('action:post.save', { post: _.clone(result.post) });
return result.post;
};
async function addReplyTo(postData, timestamp) {
if (!postData.toPid) {
return next(null);
return;
}
await Promise.all([
db.sortedSetAdd('pid:' + postData.toPid + ':replies', timestamp, postData.pid),
db.incrObjectField('post:' + postData.toPid, 'replies'),
]);
}
async.parallel([
async.apply(db.sortedSetAdd, 'pid:' + postData.toPid + ':replies', timestamp, postData.pid),
async.apply(db.incrObjectField, 'post:' + postData.toPid, 'replies'),
], next);
},
function (next) {
db.incrObjectField('global', 'postCount', next);
},
async.apply(Posts.uploads.sync, postData.pid),
], function (err) {
next(err);
});
},
function (next) {
plugins.fireHook('filter:post.get', { post: postData, uid: data.uid }, next);
},
function (data, next) {
data.post.isMain = isMain;
plugins.fireHook('action:post.save', { post: _.clone(data.post) });
next(null, data.post);
},
], callback);
};
};

@ -1,10 +1,8 @@
'use strict';
var async = require('async');
var db = require('../database');
var plugins = require('../plugins');
var utils = require('../utils');
const db = require('../database');
const plugins = require('../plugins');
const utils = require('../utils');
const intFields = [
'uid', 'pid', 'tid', 'deleted', 'timestamp',
@ -12,67 +10,49 @@ const intFields = [
];
module.exports = function (Posts) {
Posts.getPostsFields = function (pids, fields, callback) {
Posts.getPostsFields = async function (pids, fields) {
if (!Array.isArray(pids) || !pids.length) {
return callback(null, []);
return [];
}
async.waterfall([
function (next) {
const keys = pids.map(pid => 'post:' + pid);
let postData;
if (fields.length) {
db.getObjectsFields(keys, fields, next);
postData = await db.getObjectsFields(keys, fields);
} else {
db.getObjects(keys, next);
postData = await db.getObjects(keys);
}
},
function (posts, next) {
plugins.fireHook('filter:post.getFields', { posts: posts, fields: fields }, next);
},
function (data, next) {
data.posts.forEach(post => modifyPost(post, fields));
next(null, Array.isArray(data.posts) ? data.posts : null);
},
], callback);
const result = await plugins.fireHook('filter:post.getFields', { posts: postData, fields: fields });
result.posts.forEach(post => modifyPost(post, fields));
return Array.isArray(result.posts) ? result.posts : null;
};
Posts.getPostData = function (pid, callback) {
Posts.getPostsFields([pid], [], function (err, posts) {
callback(err, posts && posts.length ? posts[0] : null);
});
Posts.getPostData = async function (pid) {
const posts = await Posts.getPostsFields([pid], []);
return posts && posts.length ? posts[0] : null;
};
Posts.getPostsData = function (pids, callback) {
Posts.getPostsFields(pids, [], callback);
Posts.getPostsData = async function (pids) {
return await Posts.getPostsFields(pids, []);
};
Posts.getPostField = function (pid, field, callback) {
Posts.getPostFields(pid, [field], function (err, post) {
callback(err, post ? post[field] : null);
});
Posts.getPostField = async function (pid, field) {
const post = await Posts.getPostFields(pid, [field]);
return post ? post[field] : null;
};
Posts.getPostFields = function (pid, fields, callback) {
Posts.getPostsFields([pid], fields, function (err, posts) {
callback(err, posts ? posts[0] : null);
});
Posts.getPostFields = async function (pid, fields) {
const posts = await Posts.getPostsFields([pid], fields);
return posts ? posts[0] : null;
};
Posts.setPostField = function (pid, field, value, callback) {
Posts.setPostFields(pid, { [field]: value }, callback);
Posts.setPostField = async function (pid, field, value) {
await Posts.setPostFields(pid, { [field]: value });
};
Posts.setPostFields = function (pid, data, callback) {
async.waterfall([
function (next) {
db.setObject('post:' + pid, data, next);
},
function (next) {
Posts.setPostFields = async function (pid, data) {
await db.setObject('post:' + pid, data);
data.pid = pid;
plugins.fireHook('action:post.setFields', { data: data });
next();
},
], callback);
};
};

@ -1,212 +1,132 @@
'use strict';
var async = require('async');
var _ = require('lodash');
const _ = require('lodash');
var db = require('../database');
var topics = require('../topics');
var user = require('../user');
var groups = require('../groups');
var notifications = require('../notifications');
var plugins = require('../plugins');
const db = require('../database');
const topics = require('../topics');
const categories = require('../categories');
const user = require('../user');
const groups = require('../groups');
const notifications = require('../notifications');
const plugins = require('../plugins');
module.exports = function (Posts) {
Posts.delete = function (pid, uid, callback) {
deleteOrRestore('delete', pid, uid, callback);
Posts.delete = async function (pid, uid) {
return await deleteOrRestore('delete', pid, uid);
};
Posts.restore = function (pid, uid, callback) {
deleteOrRestore('restore', pid, uid, callback);
Posts.restore = async function (pid, uid) {
return await deleteOrRestore('restore', pid, uid);
};
function deleteOrRestore(type, pid, uid, callback) {
var postData;
async function deleteOrRestore(type, pid, uid) {
const isDeleting = type === 'delete';
async.waterfall([
function (next) {
plugins.fireHook('filter:post.' + type, { pid: pid, uid: uid }, next);
},
function (data, next) {
Posts.setPostFields(pid, {
await plugins.fireHook('filter:post.' + type, { pid: pid, uid: uid });
await Posts.setPostFields(pid, {
deleted: isDeleting ? 1 : 0,
deleterUid: isDeleting ? uid : 0,
}, next);
},
function (next) {
Posts.getPostFields(pid, ['pid', 'tid', 'uid', 'content', 'timestamp'], next);
},
function (_post, next) {
postData = _post;
topics.getTopicFields(_post.tid, ['tid', 'cid', 'pinned'], next);
},
function (topicData, next) {
});
const postData = await Posts.getPostFields(pid, ['pid', 'tid', 'uid', 'content', 'timestamp']);
const topicData = await topics.getTopicFields(postData.tid, ['tid', 'cid', 'pinned']);
postData.cid = topicData.cid;
async.parallel([
function (next) {
topics.updateLastPostTimeFromLastPid(postData.tid, next);
},
function (next) {
if (isDeleting) {
db.sortedSetRemove('cid:' + topicData.cid + ':pids', pid, next);
} else {
db.sortedSetAdd('cid:' + topicData.cid + ':pids', postData.timestamp, pid, next);
}
},
function (next) {
topics.updateTeaser(postData.tid, next);
},
], next);
},
function (results, next) {
await Promise.all([
topics.updateLastPostTimeFromLastPid(postData.tid),
topics.updateTeaser(postData.tid),
isDeleting ?
db.sortedSetRemove('cid:' + topicData.cid + ':pids', pid) :
db.sortedSetAdd('cid:' + topicData.cid + ':pids', postData.timestamp, pid),
]);
plugins.fireHook('action:post.' + type, { post: _.clone(postData), uid: uid });
next(null, postData);
},
], callback);
return postData;
}
Posts.purge = function (pid, uid, callback) {
let postData;
async.waterfall([
function (next) {
Posts.getPostData(pid, next);
},
function (_postData, next) {
postData = _postData;
Posts.purge = async function (pid, uid) {
const postData = await Posts.getPostData(pid);
if (!postData) {
return callback();
return;
}
plugins.fireHook('filter:post.purge', { post: postData, pid: pid, uid: uid }, next);
},
function (data, next) {
async.parallel([
async.apply(deletePostFromTopicUserNotification, postData),
async.apply(deletePostFromCategoryRecentPosts, pid),
async.apply(deletePostFromUsersBookmarks, pid),
async.apply(deletePostFromUsersVotes, pid),
async.apply(deletePostFromReplies, postData),
async.apply(deletePostFromGroups, postData),
async.apply(db.sortedSetsRemove, ['posts:pid', 'posts:votes', 'posts:flagged'], pid),
], err => next(err));
},
function (next) {
await plugins.fireHook('filter:post.purge', { post: postData, pid: pid, uid: uid });
await Promise.all([
deletePostFromTopicUserNotification(postData),
deletePostFromCategoryRecentPosts(pid),
deletePostFromUsersBookmarks(pid),
deletePostFromUsersVotes(pid),
deletePostFromReplies(postData),
deletePostFromGroups(postData),
db.sortedSetsRemove(['posts:pid', 'posts:votes', 'posts:flagged'], pid),
]);
plugins.fireHook('action:post.purge', { post: postData, uid: uid });
db.delete('post:' + pid, next);
},
], callback);
await db.delete('post:' + pid);
};
function deletePostFromTopicUserNotification(postData, callback) {
async.waterfall([
function (next) {
db.sortedSetsRemove([
async function deletePostFromTopicUserNotification(postData) {
await db.sortedSetsRemove([
'tid:' + postData.tid + ':posts',
'tid:' + postData.tid + ':posts:votes',
'uid:' + postData.uid + ':posts',
], postData.pid, next);
},
function (next) {
topics.getTopicFields(postData.tid, ['tid', 'cid', 'pinned'], next);
},
function (topicData, next) {
], postData.pid);
const topicData = await topics.getTopicFields(postData.tid, ['tid', 'cid', 'pinned']);
const tasks = [
async.apply(db.decrObjectField, 'global', 'postCount'),
async.apply(db.decrObjectField, 'category:' + topicData.cid, 'post_count'),
async.apply(db.sortedSetRemove, 'cid:' + topicData.cid + ':uid:' + postData.uid + ':pids', postData.pid),
async.apply(db.sortedSetRemove, 'cid:' + topicData.cid + ':uid:' + postData.uid + ':pids:votes', postData.pid),
async.apply(topics.decreasePostCount, postData.tid),
async.apply(topics.updateTeaser, postData.tid),
async.apply(topics.updateLastPostTimeFromLastPid, postData.tid),
async.apply(db.sortedSetIncrBy, 'tid:' + postData.tid + ':posters', -1, postData.uid),
async.apply(user.incrementUserPostCountBy, postData.uid, -1),
async.apply(notifications.rescind, 'new_post:tid:' + postData.tid + ':pid:' + postData.pid + ':uid:' + postData.uid),
db.decrObjectField('global', 'postCount'),
db.decrObjectField('category:' + topicData.cid, 'post_count'),
db.sortedSetRemove('cid:' + topicData.cid + ':uid:' + postData.uid + ':pids', postData.pid),
db.sortedSetRemove('cid:' + topicData.cid + ':uid:' + postData.uid + ':pids:votes', postData.pid),
topics.decreasePostCount(postData.tid),
topics.updateTeaser(postData.tid),
topics.updateLastPostTimeFromLastPid(postData.tid),
db.sortedSetIncrBy('tid:' + postData.tid + ':posters', -1, postData.uid),
user.incrementUserPostCountBy(postData.uid, -1),
notifications.rescind('new_post:tid:' + postData.tid + ':pid:' + postData.pid + ':uid:' + postData.uid),
];
if (!topicData.pinned) {
tasks.push(async.apply(db.sortedSetIncrBy, 'cid:' + topicData.cid + ':tids:posts', -1, postData.tid));
tasks.push(db.sortedSetIncrBy, 'cid:' + topicData.cid + ':tids:posts', -1, postData.tid);
}
async.parallel(tasks, next);
},
], function (err) {
callback(err);
});
await Promise.all(tasks);
}
function deletePostFromCategoryRecentPosts(pid, callback) {
async.waterfall([
function (next) {
db.getSortedSetRange('categories:cid', 0, -1, next);
},
function (cids, next) {
async function deletePostFromCategoryRecentPosts(pid) {
const cids = await categories.getAllCidsFromSet('categories:cid');
const sets = cids.map(cid => 'cid:' + cid + ':pids');
db.sortedSetsRemove(sets, pid, next);
},
], callback);
await db.sortedSetsRemove(sets, pid);
}
function deletePostFromUsersBookmarks(pid, callback) {
async.waterfall([
function (next) {
db.getSetMembers('pid:' + pid + ':users_bookmarked', next);
},
function (uids, next) {
async function deletePostFromUsersBookmarks(pid) {
const uids = await db.getSetMembers('pid:' + pid + ':users_bookmarked');
const sets = uids.map(uid => 'uid:' + uid + ':bookmarks');
db.sortedSetsRemove(sets, pid, next);
},
function (next) {
db.delete('pid:' + pid + ':users_bookmarked', next);
},
], callback);
await db.sortedSetsRemove(sets, pid);
await db.delete('pid:' + pid + ':users_bookmarked');
}
function deletePostFromUsersVotes(pid, callback) {
async.waterfall([
function (next) {
async.parallel({
upvoters: function (next) {
db.getSetMembers('pid:' + pid + ':upvote', next);
},
downvoters: function (next) {
db.getSetMembers('pid:' + pid + ':downvote', next);
},
}, next);
},
function (results, next) {
async.parallel([
function (next) {
const upvoterSets = results.upvoters.map(uid => 'uid:' + uid + ':upvote');
const downvoterSets = results.downvoters.map(uid => 'uid:' + uid + ':downvote');
db.sortedSetsRemove(upvoterSets.concat(downvoterSets), pid, next);
},
function (next) {
db.deleteAll(['pid:' + pid + ':upvote', 'pid:' + pid + ':downvote'], next);
},
], next);
},
], callback);
async function deletePostFromUsersVotes(pid) {
const [upvoters, downvoters] = await Promise.all([
db.getSetMembers('pid:' + pid + ':upvote'),
db.getSetMembers('pid:' + pid + ':downvote'),
]);
const upvoterSets = upvoters.map(uid => 'uid:' + uid + ':upvote');
const downvoterSets = downvoters.map(uid => 'uid:' + uid + ':downvote');
await Promise.all([
db.sortedSetsRemove(upvoterSets.concat(downvoterSets), pid),
db.deleteAll(['pid:' + pid + ':upvote', 'pid:' + pid + ':downvote']),
]);
}
function deletePostFromReplies(postData, callback) {
async function deletePostFromReplies(postData) {
if (!parseInt(postData.toPid, 10)) {
return setImmediate(callback);
return;
}
async.parallel([
async.apply(db.sortedSetRemove, 'pid:' + postData.toPid + ':replies', postData.pid),
async.apply(db.decrObjectField, 'post:' + postData.toPid, 'replies'),
], callback);
await Promise.all([
db.sortedSetRemove('pid:' + postData.toPid + ':replies', postData.pid),
db.decrObjectField('post:' + postData.toPid, 'replies'),
]);
}
function deletePostFromGroups(postData, callback) {
async function deletePostFromGroups(postData) {
if (!parseInt(postData.uid, 10)) {
return setImmediate(callback);
return;
}
async.waterfall([
function (next) {
groups.getUserGroupMembership('groups:visible:createtime', [postData.uid], next);
},
function (groupNames, next) {
groupNames = groupNames[0];
const keys = groupNames.map(groupName => 'group:' + groupName + ':member:pids');
db.sortedSetsRemove(keys, postData.pid, next);
},
], callback);
const groupNames = await groups.getUserGroupMembership('groups:visible:createtime', [postData.uid]);
const keys = groupNames[0].map(groupName => 'group:' + groupName + ':member:pids');
await db.sortedSetsRemove(keys, postData.pid);
}
};

@ -901,6 +901,14 @@ describe('Post\'s', function () {
done();
});
});
it('should filter pids by multiple cids', function (done) {
posts.filterPidsByCid([postData.pid, 100, 101], [cid], function (err, pids) {
assert.ifError(err);
assert.deepEqual([postData.pid], pids);
done();
});
});
});
it('should error if user does not exist', function (done) {

Loading…
Cancel
Save