Files
NodeBB/src/categories/update.js

144 lines
4.6 KiB
JavaScript
Raw Normal View History

2014-02-28 15:25:50 -05:00
'use strict';
const async = require('async');
2016-12-09 18:53:08 +03:00
const db = require('../database');
const meta = require('../meta');
const utils = require('../utils');
const slugify = require('../slugify');
const translator = require('../translator');
const plugins = require('../plugins');
const cache = require('../cache');
2013-05-24 11:18:41 -04:00
module.exports = function (Categories) {
2019-07-16 00:41:42 -04:00
Categories.update = async function (modified) {
const cids = Object.keys(modified);
2019-07-16 00:41:42 -04:00
await Promise.all(cids.map(cid => updateCategory(cid, modified[cid])));
return cids;
2015-09-28 16:09:33 -04:00
};
2015-01-18 14:31:37 -05:00
2019-07-16 00:41:42 -04:00
async function updateCategory(cid, modifiedFields) {
const exists = await Categories.exists(cid);
if (!exists) {
return;
}
2015-07-05 08:31:21 +03:00
2019-07-16 00:41:42 -04:00
if (modifiedFields.hasOwnProperty('name')) {
const translated = await translator.translate(modifiedFields.name);
2021-02-03 23:59:08 -07:00
modifiedFields.slug = `${cid}/${slugify(translated)}`;
2019-07-16 00:41:42 -04:00
}
const result = await plugins.hooks.fire('filter:category.update', { cid: cid, category: modifiedFields });
2015-09-28 16:09:33 -04:00
2019-07-16 00:41:42 -04:00
const category = result.category;
var fields = Object.keys(category);
// move parent to front, so its updated first
var parentCidIndex = fields.indexOf('parentCid');
if (parentCidIndex !== -1 && fields.length > 1) {
fields.splice(0, 0, fields.splice(parentCidIndex, 1)[0]);
}
2021-02-04 00:01:39 -07:00
await async.eachSeries(fields, async (key) => {
2019-07-16 00:41:42 -04:00
await updateCategoryField(cid, key, category[key]);
});
plugins.hooks.fire('action:category.update', { cid: cid, modified: category });
2015-09-28 16:09:33 -04:00
}
2013-05-24 11:18:41 -04:00
2019-07-16 00:41:42 -04:00
async function updateCategoryField(cid, key, value) {
if (key === 'parentCid') {
2019-07-16 00:41:42 -04:00
return await updateParent(cid, value);
2016-12-09 18:53:08 +03:00
} else if (key === 'tagWhitelist') {
2019-07-16 00:41:42 -04:00
return await updateTagWhitelist(cid, value);
} else if (key === 'name') {
return await updateName(cid, value);
Categories refactor (#9257) * feat: wip categories pagination * feat: add subCategoriesPerPage setting * feat: add load more sub categories button to category page * fix: openapi spec * feat: show sub categories left on category page hide button when no more categories left * breaking: rename categories to allCategories on /search categories contains the search results * fix: spec * refactor: remove cidsPerPage * fix: tests * feat: use component for subcategories * fix: prevent negative subCategoriesLeft * feat: new category filter/search WIP * feat: remove categories from /tag * fix: dont load all categories when showing move modal * feat: allow adding custom categories to list * breaking: dont load entire category tree on post queue removed unused code add hooks to filter/selector add options to filter/selector * feat: make selector modal work again * feat: replace old search module * fix: topic move selector * feat: dont load all categories on create category modal * fix: fix more categorySelectors * feat: dont load entire category tree on group details page * feat: dont load all categories on home page and user settings page * feat: add pagination to /user/:userslug/categories * fix: update schemas * fix: more tests * fix: test * feat: flags page, dont return entire category tree * fix: flag test * feat: categories manage page dont load all categories allow changing root category clear caches properly * fix: spec * feat: admins&mods page dont load all categories * fix: spec * fix: dont load all children when opening dropdown * fix: on search results dont return all children * refactor: pass all options, rename options.cids to options.selectedCids * fix: #9266 * fix: index 0 * fix: spec * feat: #9265, add setObjectBulk * refactor: shoter updateOrder * feat: selectors on categories/category * fix: tests and search filter * fix: category update test * feat: pagination on acp categories page show order in set order modal * fix: allow drag&drop on pages > 1 in /admin/manage/categories * fix: teasers for deep nested categories fix sub category display on /category page * fix: spec * refactor: use eslint-disable-next-line * refactor: shorter
2021-02-07 15:09:52 -05:00
} else if (key === 'order') {
return await updateOrder(cid, value);
2019-07-16 00:41:42 -04:00
}
2021-02-03 23:59:08 -07:00
await db.setObjectField(`category:${cid}`, key, value);
Categories refactor (#9257) * feat: wip categories pagination * feat: add subCategoriesPerPage setting * feat: add load more sub categories button to category page * fix: openapi spec * feat: show sub categories left on category page hide button when no more categories left * breaking: rename categories to allCategories on /search categories contains the search results * fix: spec * refactor: remove cidsPerPage * fix: tests * feat: use component for subcategories * fix: prevent negative subCategoriesLeft * feat: new category filter/search WIP * feat: remove categories from /tag * fix: dont load all categories when showing move modal * feat: allow adding custom categories to list * breaking: dont load entire category tree on post queue removed unused code add hooks to filter/selector add options to filter/selector * feat: make selector modal work again * feat: replace old search module * fix: topic move selector * feat: dont load all categories on create category modal * fix: fix more categorySelectors * feat: dont load entire category tree on group details page * feat: dont load all categories on home page and user settings page * feat: add pagination to /user/:userslug/categories * fix: update schemas * fix: more tests * fix: test * feat: flags page, dont return entire category tree * fix: flag test * feat: categories manage page dont load all categories allow changing root category clear caches properly * fix: spec * feat: admins&mods page dont load all categories * fix: spec * fix: dont load all children when opening dropdown * fix: on search results dont return all children * refactor: pass all options, rename options.cids to options.selectedCids * fix: #9266 * fix: index 0 * fix: spec * feat: #9265, add setObjectBulk * refactor: shoter updateOrder * feat: selectors on categories/category * fix: tests and search filter * fix: category update test * feat: pagination on acp categories page show order in set order modal * fix: allow drag&drop on pages > 1 in /admin/manage/categories * fix: teasers for deep nested categories fix sub category display on /category page * fix: spec * refactor: use eslint-disable-next-line * refactor: shorter
2021-02-07 15:09:52 -05:00
if (key === 'description') {
2019-07-16 00:41:42 -04:00
await Categories.parseDescription(cid, value);
}
}
2019-07-16 00:41:42 -04:00
async function updateParent(cid, newParent) {
newParent = parseInt(newParent, 10) || 0;
if (parseInt(cid, 10) === newParent) {
throw new Error('[[error:cant-set-self-as-parent]]');
2015-09-15 12:58:19 -04:00
}
2019-07-16 00:41:42 -04:00
const childrenCids = await Categories.getChildrenCids(cid);
if (childrenCids.includes(newParent)) {
throw new Error('[[error:cant-set-child-as-parent]]');
}
const oldParent = await Categories.getCategoryField(cid, 'parentCid');
await Promise.all([
2021-02-03 23:59:08 -07:00
db.sortedSetRemove(`cid:${oldParent}:children`, cid),
db.sortedSetAdd(`cid:${newParent}:children`, cid, cid),
db.setObjectField(`category:${cid}`, 'parentCid', newParent),
2019-07-16 00:41:42 -04:00
]);
Categories refactor (#9257) * feat: wip categories pagination * feat: add subCategoriesPerPage setting * feat: add load more sub categories button to category page * fix: openapi spec * feat: show sub categories left on category page hide button when no more categories left * breaking: rename categories to allCategories on /search categories contains the search results * fix: spec * refactor: remove cidsPerPage * fix: tests * feat: use component for subcategories * fix: prevent negative subCategoriesLeft * feat: new category filter/search WIP * feat: remove categories from /tag * fix: dont load all categories when showing move modal * feat: allow adding custom categories to list * breaking: dont load entire category tree on post queue removed unused code add hooks to filter/selector add options to filter/selector * feat: make selector modal work again * feat: replace old search module * fix: topic move selector * feat: dont load all categories on create category modal * fix: fix more categorySelectors * feat: dont load entire category tree on group details page * feat: dont load all categories on home page and user settings page * feat: add pagination to /user/:userslug/categories * fix: update schemas * fix: more tests * fix: test * feat: flags page, dont return entire category tree * fix: flag test * feat: categories manage page dont load all categories allow changing root category clear caches properly * fix: spec * feat: admins&mods page dont load all categories * fix: spec * fix: dont load all children when opening dropdown * fix: on search results dont return all children * refactor: pass all options, rename options.cids to options.selectedCids * fix: #9266 * fix: index 0 * fix: spec * feat: #9265, add setObjectBulk * refactor: shoter updateOrder * feat: selectors on categories/category * fix: tests and search filter * fix: category update test * feat: pagination on acp categories page show order in set order modal * fix: allow drag&drop on pages > 1 in /admin/manage/categories * fix: teasers for deep nested categories fix sub category display on /category page * fix: spec * refactor: use eslint-disable-next-line * refactor: shorter
2021-02-07 15:09:52 -05:00
cache.del([
2021-02-03 23:59:08 -07:00
`cid:${oldParent}:children`,
`cid:${newParent}:children`,
`cid:${oldParent}:children:all`,
`cid:${newParent}:children:all`,
Categories refactor (#9257) * feat: wip categories pagination * feat: add subCategoriesPerPage setting * feat: add load more sub categories button to category page * fix: openapi spec * feat: show sub categories left on category page hide button when no more categories left * breaking: rename categories to allCategories on /search categories contains the search results * fix: spec * refactor: remove cidsPerPage * fix: tests * feat: use component for subcategories * fix: prevent negative subCategoriesLeft * feat: new category filter/search WIP * feat: remove categories from /tag * fix: dont load all categories when showing move modal * feat: allow adding custom categories to list * breaking: dont load entire category tree on post queue removed unused code add hooks to filter/selector add options to filter/selector * feat: make selector modal work again * feat: replace old search module * fix: topic move selector * feat: dont load all categories on create category modal * fix: fix more categorySelectors * feat: dont load entire category tree on group details page * feat: dont load all categories on home page and user settings page * feat: add pagination to /user/:userslug/categories * fix: update schemas * fix: more tests * fix: test * feat: flags page, dont return entire category tree * fix: flag test * feat: categories manage page dont load all categories allow changing root category clear caches properly * fix: spec * feat: admins&mods page dont load all categories * fix: spec * fix: dont load all children when opening dropdown * fix: on search results dont return all children * refactor: pass all options, rename options.cids to options.selectedCids * fix: #9266 * fix: index 0 * fix: spec * feat: #9265, add setObjectBulk * refactor: shoter updateOrder * feat: selectors on categories/category * fix: tests and search filter * fix: category update test * feat: pagination on acp categories page show order in set order modal * fix: allow drag&drop on pages > 1 in /admin/manage/categories * fix: teasers for deep nested categories fix sub category display on /category page * fix: spec * refactor: use eslint-disable-next-line * refactor: shorter
2021-02-07 15:09:52 -05:00
]);
2019-07-16 00:41:42 -04:00
}
2016-12-09 18:53:08 +03:00
2019-07-16 00:41:42 -04:00
async function updateTagWhitelist(cid, tags) {
tags = tags.split(',').map(tag => utils.cleanUpTag(tag, meta.config.maximumTagLength))
.filter(Boolean);
2021-02-03 23:59:08 -07:00
await db.delete(`cid:${cid}:tag:whitelist`);
2019-07-16 00:41:42 -04:00
const scores = tags.map((tag, index) => index);
2021-02-03 23:59:08 -07:00
await db.sortedSetAdd(`cid:${cid}:tag:whitelist`, scores, tags);
cache.del(`cid:${cid}:tag:whitelist`);
2016-12-09 18:53:08 +03:00
}
2019-07-16 00:41:42 -04:00
async function updateOrder(cid, order) {
const parentCid = await Categories.getCategoryField(cid, 'parentCid');
Categories refactor (#9257) * feat: wip categories pagination * feat: add subCategoriesPerPage setting * feat: add load more sub categories button to category page * fix: openapi spec * feat: show sub categories left on category page hide button when no more categories left * breaking: rename categories to allCategories on /search categories contains the search results * fix: spec * refactor: remove cidsPerPage * fix: tests * feat: use component for subcategories * fix: prevent negative subCategoriesLeft * feat: new category filter/search WIP * feat: remove categories from /tag * fix: dont load all categories when showing move modal * feat: allow adding custom categories to list * breaking: dont load entire category tree on post queue removed unused code add hooks to filter/selector add options to filter/selector * feat: make selector modal work again * feat: replace old search module * fix: topic move selector * feat: dont load all categories on create category modal * fix: fix more categorySelectors * feat: dont load entire category tree on group details page * feat: dont load all categories on home page and user settings page * feat: add pagination to /user/:userslug/categories * fix: update schemas * fix: more tests * fix: test * feat: flags page, dont return entire category tree * fix: flag test * feat: categories manage page dont load all categories allow changing root category clear caches properly * fix: spec * feat: admins&mods page dont load all categories * fix: spec * fix: dont load all children when opening dropdown * fix: on search results dont return all children * refactor: pass all options, rename options.cids to options.selectedCids * fix: #9266 * fix: index 0 * fix: spec * feat: #9265, add setObjectBulk * refactor: shoter updateOrder * feat: selectors on categories/category * fix: tests and search filter * fix: category update test * feat: pagination on acp categories page show order in set order modal * fix: allow drag&drop on pages > 1 in /admin/manage/categories * fix: teasers for deep nested categories fix sub category display on /category page * fix: spec * refactor: use eslint-disable-next-line * refactor: shorter
2021-02-07 15:09:52 -05:00
await db.sortedSetsAdd('categories:cid', order, cid);
const childrenCids = await db.getSortedSetRange(
2021-02-03 23:59:08 -07:00
`cid:${parentCid}:children`, 0, -1
Categories refactor (#9257) * feat: wip categories pagination * feat: add subCategoriesPerPage setting * feat: add load more sub categories button to category page * fix: openapi spec * feat: show sub categories left on category page hide button when no more categories left * breaking: rename categories to allCategories on /search categories contains the search results * fix: spec * refactor: remove cidsPerPage * fix: tests * feat: use component for subcategories * fix: prevent negative subCategoriesLeft * feat: new category filter/search WIP * feat: remove categories from /tag * fix: dont load all categories when showing move modal * feat: allow adding custom categories to list * breaking: dont load entire category tree on post queue removed unused code add hooks to filter/selector add options to filter/selector * feat: make selector modal work again * feat: replace old search module * fix: topic move selector * feat: dont load all categories on create category modal * fix: fix more categorySelectors * feat: dont load entire category tree on group details page * feat: dont load all categories on home page and user settings page * feat: add pagination to /user/:userslug/categories * fix: update schemas * fix: more tests * fix: test * feat: flags page, dont return entire category tree * fix: flag test * feat: categories manage page dont load all categories allow changing root category clear caches properly * fix: spec * feat: admins&mods page dont load all categories * fix: spec * fix: dont load all children when opening dropdown * fix: on search results dont return all children * refactor: pass all options, rename options.cids to options.selectedCids * fix: #9266 * fix: index 0 * fix: spec * feat: #9265, add setObjectBulk * refactor: shoter updateOrder * feat: selectors on categories/category * fix: tests and search filter * fix: category update test * feat: pagination on acp categories page show order in set order modal * fix: allow drag&drop on pages > 1 in /admin/manage/categories * fix: teasers for deep nested categories fix sub category display on /category page * fix: spec * refactor: use eslint-disable-next-line * refactor: shorter
2021-02-07 15:09:52 -05:00
);
const currentIndex = childrenCids.indexOf(String(cid));
if (currentIndex === -1) {
throw new Error('[[error:no-category]]');
}
// moves cid to index order-1 in the array
if (childrenCids.length > 1) {
childrenCids.splice(Math.max(0, order - 1), 0, childrenCids.splice(currentIndex, 1)[0]);
}
// recalculate orders from array indices
await db.sortedSetAdd(
2021-02-03 23:59:08 -07:00
`cid:${parentCid}:children`,
Categories refactor (#9257) * feat: wip categories pagination * feat: add subCategoriesPerPage setting * feat: add load more sub categories button to category page * fix: openapi spec * feat: show sub categories left on category page hide button when no more categories left * breaking: rename categories to allCategories on /search categories contains the search results * fix: spec * refactor: remove cidsPerPage * fix: tests * feat: use component for subcategories * fix: prevent negative subCategoriesLeft * feat: new category filter/search WIP * feat: remove categories from /tag * fix: dont load all categories when showing move modal * feat: allow adding custom categories to list * breaking: dont load entire category tree on post queue removed unused code add hooks to filter/selector add options to filter/selector * feat: make selector modal work again * feat: replace old search module * fix: topic move selector * feat: dont load all categories on create category modal * fix: fix more categorySelectors * feat: dont load entire category tree on group details page * feat: dont load all categories on home page and user settings page * feat: add pagination to /user/:userslug/categories * fix: update schemas * fix: more tests * fix: test * feat: flags page, dont return entire category tree * fix: flag test * feat: categories manage page dont load all categories allow changing root category clear caches properly * fix: spec * feat: admins&mods page dont load all categories * fix: spec * fix: dont load all children when opening dropdown * fix: on search results dont return all children * refactor: pass all options, rename options.cids to options.selectedCids * fix: #9266 * fix: index 0 * fix: spec * feat: #9265, add setObjectBulk * refactor: shoter updateOrder * feat: selectors on categories/category * fix: tests and search filter * fix: category update test * feat: pagination on acp categories page show order in set order modal * fix: allow drag&drop on pages > 1 in /admin/manage/categories * fix: teasers for deep nested categories fix sub category display on /category page * fix: spec * refactor: use eslint-disable-next-line * refactor: shorter
2021-02-07 15:09:52 -05:00
childrenCids.map((cid, index) => index + 1),
childrenCids
);
await db.setObjectBulk(
2021-02-03 23:59:08 -07:00
childrenCids.map(cid => `category:${cid}`),
Categories refactor (#9257) * feat: wip categories pagination * feat: add subCategoriesPerPage setting * feat: add load more sub categories button to category page * fix: openapi spec * feat: show sub categories left on category page hide button when no more categories left * breaking: rename categories to allCategories on /search categories contains the search results * fix: spec * refactor: remove cidsPerPage * fix: tests * feat: use component for subcategories * fix: prevent negative subCategoriesLeft * feat: new category filter/search WIP * feat: remove categories from /tag * fix: dont load all categories when showing move modal * feat: allow adding custom categories to list * breaking: dont load entire category tree on post queue removed unused code add hooks to filter/selector add options to filter/selector * feat: make selector modal work again * feat: replace old search module * fix: topic move selector * feat: dont load all categories on create category modal * fix: fix more categorySelectors * feat: dont load entire category tree on group details page * feat: dont load all categories on home page and user settings page * feat: add pagination to /user/:userslug/categories * fix: update schemas * fix: more tests * fix: test * feat: flags page, dont return entire category tree * fix: flag test * feat: categories manage page dont load all categories allow changing root category clear caches properly * fix: spec * feat: admins&mods page dont load all categories * fix: spec * fix: dont load all children when opening dropdown * fix: on search results dont return all children * refactor: pass all options, rename options.cids to options.selectedCids * fix: #9266 * fix: index 0 * fix: spec * feat: #9265, add setObjectBulk * refactor: shoter updateOrder * feat: selectors on categories/category * fix: tests and search filter * fix: category update test * feat: pagination on acp categories page show order in set order modal * fix: allow drag&drop on pages > 1 in /admin/manage/categories * fix: teasers for deep nested categories fix sub category display on /category page * fix: spec * refactor: use eslint-disable-next-line * refactor: shorter
2021-02-07 15:09:52 -05:00
childrenCids.map((cid, index) => ({ order: index + 1 }))
);
cache.del([
'categories:cid',
2021-02-03 23:59:08 -07:00
`cid:${parentCid}:children`,
`cid:${parentCid}:children:all`,
Categories refactor (#9257) * feat: wip categories pagination * feat: add subCategoriesPerPage setting * feat: add load more sub categories button to category page * fix: openapi spec * feat: show sub categories left on category page hide button when no more categories left * breaking: rename categories to allCategories on /search categories contains the search results * fix: spec * refactor: remove cidsPerPage * fix: tests * feat: use component for subcategories * fix: prevent negative subCategoriesLeft * feat: new category filter/search WIP * feat: remove categories from /tag * fix: dont load all categories when showing move modal * feat: allow adding custom categories to list * breaking: dont load entire category tree on post queue removed unused code add hooks to filter/selector add options to filter/selector * feat: make selector modal work again * feat: replace old search module * fix: topic move selector * feat: dont load all categories on create category modal * fix: fix more categorySelectors * feat: dont load entire category tree on group details page * feat: dont load all categories on home page and user settings page * feat: add pagination to /user/:userslug/categories * fix: update schemas * fix: more tests * fix: test * feat: flags page, dont return entire category tree * fix: flag test * feat: categories manage page dont load all categories allow changing root category clear caches properly * fix: spec * feat: admins&mods page dont load all categories * fix: spec * fix: dont load all children when opening dropdown * fix: on search results dont return all children * refactor: pass all options, rename options.cids to options.selectedCids * fix: #9266 * fix: index 0 * fix: spec * feat: #9265, add setObjectBulk * refactor: shoter updateOrder * feat: selectors on categories/category * fix: tests and search filter * fix: category update test * feat: pagination on acp categories page show order in set order modal * fix: allow drag&drop on pages > 1 in /admin/manage/categories * fix: teasers for deep nested categories fix sub category display on /category page * fix: spec * refactor: use eslint-disable-next-line * refactor: shorter
2021-02-07 15:09:52 -05:00
]);
}
2019-07-16 00:41:42 -04:00
Categories.parseDescription = async function (cid, description) {
const parsedDescription = await plugins.hooks.fire('filter:parse.raw', description);
2019-07-16 00:41:42 -04:00
await Categories.setCategoryField(cid, 'descriptionParsed', parsedDescription);
2016-03-15 15:38:16 +02:00
};
async function updateName(cid, newName) {
const oldName = await Categories.getCategoryField(cid, 'name');
2021-02-03 23:59:08 -07:00
await db.sortedSetRemove('categories:name', `${oldName.substr(0, 200).toLowerCase()}:${cid}`);
await db.sortedSetAdd('categories:name', 0, `${newName.substr(0, 200).toLowerCase()}:${cid}`);
await db.setObjectField(`category:${cid}`, 'name', newName);
}
2014-04-10 20:31:57 +01:00
};