'use strict'; const async = require('async'); const plugins = require('../plugins'); module.exports = function (Topics) { Topics.merge = async function (tids, uid, options) { options = options || {}; const topicsData = await Topics.getTopicsFields(tids, ['scheduled']); if (topicsData.some(t => t.scheduled)) { throw new Error('[[error:cant-merge-scheduled]]'); } const oldestTid = findOldestTopic(tids); let mergeIntoTid = oldestTid; if (options.mainTid) { mergeIntoTid = options.mainTid; } else if (options.newTopicTitle) { mergeIntoTid = await createNewTopic(options.newTopicTitle, oldestTid); } const otherTids = tids.sort((a, b) => a - b) .filter(tid => tid && parseInt(tid, 10) !== parseInt(mergeIntoTid, 10)); await async.eachSeries(otherTids, async (tid) => { const pids = await Topics.getPids(tid); await async.eachSeries(pids, (pid, next) => { Topics.movePostToTopic(uid, pid, mergeIntoTid, next); }); await Topics.setTopicField(tid, 'mainPid', 0); await Topics.delete(tid, uid); await Topics.setTopicFields(tid, { mergeIntoTid: mergeIntoTid, mergerUid: uid, mergedTimestamp: Date.now(), }); }); await updateViewCount(mergeIntoTid, tids); plugins.hooks.fire('action:topic.merge', { uid: uid, tids: tids, mergeIntoTid: mergeIntoTid, otherTids: otherTids, }); return mergeIntoTid; }; async function createNewTopic(title, oldestTid) { const topicData = await Topics.getTopicFields(oldestTid, ['uid', 'cid']); const params = { uid: topicData.uid, cid: topicData.cid, title: title, }; const result = await plugins.hooks.fire('filter:topic.mergeCreateNewTopic', { oldestTid: oldestTid, params: params, }); const tid = await Topics.create(result.params); return tid; } async function updateViewCount(mergeIntoTid, tids) { const topicData = await Topics.getTopicsFields(tids, ['viewcount']); const totalViewCount = topicData.reduce( (count, topic) => count + parseInt(topic.viewcount, 10), 0 ); await Topics.setTopicField(mergeIntoTid, 'viewcount', totalViewCount); } function findOldestTopic(tids) { return Math.min.apply(null, tids); } };