You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
3.8 KiB
JavaScript
143 lines
3.8 KiB
JavaScript
'use strict';
|
|
|
|
const validator = require('validator');
|
|
|
|
const db = require('../database');
|
|
const categories = require('../categories');
|
|
const utils = require('../utils');
|
|
const translator = require('../translator');
|
|
const plugins = require('../plugins');
|
|
|
|
const intFields = [
|
|
'tid', 'cid', 'uid', 'mainPid', 'postcount',
|
|
'viewcount', 'postercount', 'deleted', 'locked', 'pinned',
|
|
'pinExpiry', 'timestamp', 'upvotes', 'downvotes', 'lastposttime',
|
|
'deleterUid',
|
|
];
|
|
|
|
module.exports = function (Topics) {
|
|
Topics.getTopicsFields = async function (tids, fields) {
|
|
if (!Array.isArray(tids) || !tids.length) {
|
|
return [];
|
|
}
|
|
|
|
// "scheduled" is derived from "timestamp"
|
|
if (fields.includes('scheduled') && !fields.includes('timestamp')) {
|
|
fields.push('timestamp');
|
|
}
|
|
|
|
const keys = tids.map(tid => `topic:${tid}`);
|
|
const topics = await db.getObjects(keys, fields);
|
|
const result = await plugins.hooks.fire('filter:topic.getFields', {
|
|
tids: tids,
|
|
topics: topics,
|
|
fields: fields,
|
|
keys: keys,
|
|
});
|
|
result.topics.forEach(topic => modifyTopic(topic, fields));
|
|
return result.topics;
|
|
};
|
|
|
|
Topics.getTopicField = async function (tid, field) {
|
|
const topic = await Topics.getTopicFields(tid, [field]);
|
|
return topic ? topic[field] : null;
|
|
};
|
|
|
|
Topics.getTopicFields = async function (tid, fields) {
|
|
const topics = await Topics.getTopicsFields([tid], fields);
|
|
return topics ? topics[0] : null;
|
|
};
|
|
|
|
Topics.getTopicData = async function (tid) {
|
|
const topics = await Topics.getTopicsFields([tid], []);
|
|
return topics && topics.length ? topics[0] : null;
|
|
};
|
|
|
|
Topics.getTopicsData = async function (tids) {
|
|
return await Topics.getTopicsFields(tids, []);
|
|
};
|
|
|
|
Topics.getCategoryData = async function (tid) {
|
|
const cid = await Topics.getTopicField(tid, 'cid');
|
|
return await categories.getCategoryData(cid);
|
|
};
|
|
|
|
Topics.setTopicField = async function (tid, field, value) {
|
|
await db.setObjectField(`topic:${tid}`, field, value);
|
|
};
|
|
|
|
Topics.setTopicFields = async function (tid, data) {
|
|
await db.setObject(`topic:${tid}`, data);
|
|
};
|
|
|
|
Topics.deleteTopicField = async function (tid, field) {
|
|
await db.deleteObjectField(`topic:${tid}`, field);
|
|
};
|
|
|
|
Topics.deleteTopicFields = async function (tid, fields) {
|
|
await db.deleteObjectFields(`topic:${tid}`, fields);
|
|
};
|
|
};
|
|
|
|
function escapeTitle(topicData) {
|
|
if (topicData) {
|
|
if (topicData.title) {
|
|
topicData.title = translator.escape(validator.escape(topicData.title));
|
|
}
|
|
if (topicData.titleRaw) {
|
|
topicData.titleRaw = translator.escape(topicData.titleRaw);
|
|
}
|
|
}
|
|
}
|
|
|
|
function modifyTopic(topic, fields) {
|
|
if (!topic) {
|
|
return;
|
|
}
|
|
|
|
db.parseIntFields(topic, intFields, fields);
|
|
|
|
if (topic.hasOwnProperty('title')) {
|
|
topic.titleRaw = topic.title;
|
|
topic.title = String(topic.title);
|
|
}
|
|
|
|
escapeTitle(topic);
|
|
|
|
if (topic.hasOwnProperty('timestamp')) {
|
|
topic.timestampISO = utils.toISOString(topic.timestamp);
|
|
if (!fields.length || fields.includes('scheduled')) {
|
|
topic.scheduled = topic.timestamp > Date.now();
|
|
}
|
|
}
|
|
|
|
if (topic.hasOwnProperty('lastposttime')) {
|
|
topic.lastposttimeISO = utils.toISOString(topic.lastposttime);
|
|
}
|
|
|
|
if (topic.hasOwnProperty('pinExpiry')) {
|
|
topic.pinExpiryISO = utils.toISOString(topic.pinExpiry);
|
|
}
|
|
|
|
if (topic.hasOwnProperty('upvotes') && topic.hasOwnProperty('downvotes')) {
|
|
topic.votes = topic.upvotes - topic.downvotes;
|
|
}
|
|
|
|
if (fields.includes('teaserPid') || !fields.length) {
|
|
topic.teaserPid = topic.teaserPid || null;
|
|
}
|
|
|
|
if (fields.includes('tags') || !fields.length) {
|
|
const tags = String(topic.tags || '');
|
|
topic.tags = tags.split(',').filter(Boolean).map((tag) => {
|
|
const escaped = validator.escape(String(tag));
|
|
return {
|
|
value: tag,
|
|
valueEscaped: escaped,
|
|
valueEncoded: encodeURIComponent(escaped),
|
|
class: escaped.replace(/\s/g, '-'),
|
|
};
|
|
});
|
|
}
|
|
}
|