feat: #7743 finish groups
parent
a39ca51e06
commit
72def7dfa6
@ -1,118 +1,85 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var async = require('async');
|
const user = require('../user');
|
||||||
|
const db = require('./../database');
|
||||||
var user = require('../user');
|
|
||||||
var db = require('./../database');
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = function (Groups) {
|
module.exports = function (Groups) {
|
||||||
Groups.search = function (query, options, callback) {
|
Groups.search = async function (query, options) {
|
||||||
if (!query) {
|
if (!query) {
|
||||||
return callback(null, []);
|
return [];
|
||||||
|
}
|
||||||
|
query = String(query).toLowerCase();
|
||||||
|
let groupNames = await db.getSortedSetRange('groups:createtime', 0, -1);
|
||||||
|
if (!options.hideEphemeralGroups) {
|
||||||
|
groupNames = Groups.ephemeralGroups.concat(groupNames);
|
||||||
}
|
}
|
||||||
query = query.toLowerCase();
|
groupNames = groupNames.filter(name => name.toLowerCase().includes(query) && name !== 'administrators' && !Groups.isPrivilegeGroup(name));
|
||||||
async.waterfall([
|
groupNames = groupNames.slice(0, 100);
|
||||||
async.apply(db.getSortedSetRange, 'groups:createtime', 0, -1),
|
|
||||||
function (groupNames, next) {
|
|
||||||
if (!options.hideEphemeralGroups) {
|
|
||||||
groupNames = Groups.ephemeralGroups.concat(groupNames);
|
|
||||||
}
|
|
||||||
groupNames = groupNames.filter(function (name) {
|
|
||||||
return name.toLowerCase().includes(query) && name !== 'administrators' && !Groups.isPrivilegeGroup(name);
|
|
||||||
});
|
|
||||||
groupNames = groupNames.slice(0, 100);
|
|
||||||
if (options.showMembers) {
|
|
||||||
Groups.getGroupsAndMembers(groupNames, next);
|
|
||||||
} else {
|
|
||||||
Groups.getGroupsData(groupNames, next);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
function (groupsData, next) {
|
|
||||||
groupsData = groupsData.filter(Boolean);
|
|
||||||
if (options.filterHidden) {
|
|
||||||
groupsData = groupsData.filter(group => !group.hidden);
|
|
||||||
}
|
|
||||||
|
|
||||||
Groups.sort(options.sort, groupsData, next);
|
let groupsData;
|
||||||
},
|
if (options.showMembers) {
|
||||||
], callback);
|
groupsData = await Groups.getGroupsAndMembers(groupNames);
|
||||||
|
} else {
|
||||||
|
groupsData = await Groups.getGroupsData(groupNames);
|
||||||
|
}
|
||||||
|
groupsData = groupsData.filter(Boolean);
|
||||||
|
if (options.filterHidden) {
|
||||||
|
groupsData = groupsData.filter(group => !group.hidden);
|
||||||
|
}
|
||||||
|
return Groups.sort(options.sort, groupsData);
|
||||||
};
|
};
|
||||||
|
|
||||||
Groups.sort = function (strategy, groups, next) {
|
Groups.sort = function (strategy, groups) {
|
||||||
switch (strategy) {
|
switch (strategy) {
|
||||||
case 'count':
|
case 'count':
|
||||||
groups = groups.sort(function (a, b) {
|
groups.sort((a, b) => a.slug > b.slug)
|
||||||
return a.slug > b.slug;
|
.sort((a, b) => b.memberCount - a.memberCount);
|
||||||
}).sort(function (a, b) {
|
|
||||||
return b.memberCount - a.memberCount;
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'date':
|
case 'date':
|
||||||
groups = groups.sort(function (a, b) {
|
groups.sort((a, b) => b.createtime - a.createtime);
|
||||||
return b.createtime - a.createtime;
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'alpha': // intentional fall-through
|
case 'alpha': // intentional fall-through
|
||||||
default:
|
default:
|
||||||
groups = groups.sort(function (a, b) {
|
groups.sort((a, b) => (a.slug > b.slug ? 1 : -1));
|
||||||
return a.slug > b.slug ? 1 : -1;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
next(null, groups);
|
return groups;
|
||||||
};
|
};
|
||||||
|
|
||||||
Groups.searchMembers = function (data, callback) {
|
Groups.searchMembers = async function (data) {
|
||||||
if (!data.query) {
|
if (!data.query) {
|
||||||
Groups.getOwnersAndMembers(data.groupName, data.uid, 0, 19, function (err, users) {
|
const users = await Groups.getOwnersAndMembers(data.groupName, data.uid, 0, 19);
|
||||||
callback(err, { users: users });
|
return { users: users };
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var results;
|
|
||||||
async.waterfall([
|
|
||||||
function (next) {
|
|
||||||
data.paginate = false;
|
|
||||||
user.search(data, next);
|
|
||||||
},
|
|
||||||
function (_results, next) {
|
|
||||||
results = _results;
|
|
||||||
var uids = results.users.map(function (user) {
|
|
||||||
return user && user.uid;
|
|
||||||
});
|
|
||||||
|
|
||||||
Groups.isMembers(uids, data.groupName, next);
|
data.paginate = false;
|
||||||
},
|
const results = await user.search(data);
|
||||||
function (isMembers, next) {
|
|
||||||
results.users = results.users.filter(function (user, index) {
|
let uids = results.users.map(user => user && user.uid);
|
||||||
return isMembers[index];
|
const isMembers = await Groups.isMembers(uids, data.groupName);
|
||||||
});
|
|
||||||
var uids = results.users.map(function (user) {
|
results.users = results.users.filter((user, index) => isMembers[index]);
|
||||||
return user && user.uid;
|
|
||||||
});
|
uids = results.users.map(user => user && user.uid);
|
||||||
Groups.ownership.isOwners(uids, data.groupName, next);
|
const isOwners = await Groups.ownership.isOwners(uids, data.groupName);
|
||||||
},
|
|
||||||
function (isOwners, next) {
|
results.users.forEach(function (user, index) {
|
||||||
results.users.forEach(function (user, index) {
|
if (user) {
|
||||||
if (user) {
|
user.isOwner = isOwners[index];
|
||||||
user.isOwner = isOwners[index];
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
results.users.sort(function (a, b) {
|
results.users.sort(function (a, b) {
|
||||||
if (a.isOwner && !b.isOwner) {
|
if (a.isOwner && !b.isOwner) {
|
||||||
return -1;
|
return -1;
|
||||||
} else if (!a.isOwner && b.isOwner) {
|
} else if (!a.isOwner && b.isOwner) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
next(null, results);
|
return results;
|
||||||
},
|
|
||||||
], callback);
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,337 +1,244 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var async = require('async');
|
const winston = require('winston');
|
||||||
var winston = require('winston');
|
|
||||||
|
|
||||||
var plugins = require('../plugins');
|
const plugins = require('../plugins');
|
||||||
var utils = require('../utils');
|
const utils = require('../utils');
|
||||||
var db = require('../database');
|
const db = require('../database');
|
||||||
var user = require('../user');
|
const user = require('../user');
|
||||||
|
const batch = require('../batch');
|
||||||
|
|
||||||
|
|
||||||
module.exports = function (Groups) {
|
module.exports = function (Groups) {
|
||||||
Groups.update = function (groupName, values, callback) {
|
Groups.update = async function (groupName, values) {
|
||||||
callback = callback || function () {};
|
const exists = await db.exists('group:' + groupName);
|
||||||
|
if (!exists) {
|
||||||
async.waterfall([
|
throw new Error('[[error:no-group]]');
|
||||||
function (next) {
|
}
|
||||||
db.exists('group:' + groupName, next);
|
|
||||||
},
|
|
||||||
function (exists, next) {
|
|
||||||
if (!exists) {
|
|
||||||
return next(new Error('[[error:no-group]]'));
|
|
||||||
}
|
|
||||||
plugins.fireHook('filter:group.update', {
|
|
||||||
groupName: groupName,
|
|
||||||
values: values,
|
|
||||||
}, next);
|
|
||||||
},
|
|
||||||
function (result, next) {
|
|
||||||
values = result.values;
|
|
||||||
|
|
||||||
var payload = {
|
|
||||||
description: values.description || '',
|
|
||||||
icon: values.icon || '',
|
|
||||||
labelColor: values.labelColor || '#000000',
|
|
||||||
textColor: values.textColor || '#ffffff',
|
|
||||||
};
|
|
||||||
|
|
||||||
if (values.hasOwnProperty('userTitle')) {
|
|
||||||
payload.userTitle = values.userTitle || '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (values.hasOwnProperty('userTitleEnabled')) {
|
const result = await plugins.fireHook('filter:group.update', {
|
||||||
payload.userTitleEnabled = values.userTitleEnabled ? '1' : '0';
|
groupName: groupName,
|
||||||
}
|
values: values,
|
||||||
|
});
|
||||||
|
values = result.values;
|
||||||
|
|
||||||
if (values.hasOwnProperty('hidden')) {
|
const payload = {
|
||||||
payload.hidden = values.hidden ? '1' : '0';
|
description: values.description || '',
|
||||||
}
|
icon: values.icon || '',
|
||||||
|
labelColor: values.labelColor || '#000000',
|
||||||
|
textColor: values.textColor || '#ffffff',
|
||||||
|
};
|
||||||
|
|
||||||
if (values.hasOwnProperty('private')) {
|
if (values.hasOwnProperty('userTitle')) {
|
||||||
payload.private = values.private ? '1' : '0';
|
payload.userTitle = values.userTitle || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (values.hasOwnProperty('disableJoinRequests')) {
|
if (values.hasOwnProperty('userTitleEnabled')) {
|
||||||
payload.disableJoinRequests = values.disableJoinRequests ? '1' : '0';
|
payload.userTitleEnabled = values.userTitleEnabled ? '1' : '0';
|
||||||
}
|
}
|
||||||
async.series([
|
|
||||||
async.apply(checkNameChange, groupName, values.name),
|
if (values.hasOwnProperty('hidden')) {
|
||||||
function (next) {
|
payload.hidden = values.hidden ? '1' : '0';
|
||||||
if (values.hasOwnProperty('private')) {
|
}
|
||||||
updatePrivacy(groupName, values.private, next);
|
|
||||||
} else {
|
if (values.hasOwnProperty('private')) {
|
||||||
next();
|
payload.private = values.private ? '1' : '0';
|
||||||
}
|
}
|
||||||
},
|
|
||||||
function (next) {
|
if (values.hasOwnProperty('disableJoinRequests')) {
|
||||||
if (values.hasOwnProperty('hidden')) {
|
payload.disableJoinRequests = values.disableJoinRequests ? '1' : '0';
|
||||||
updateVisibility(groupName, values.hidden, next);
|
}
|
||||||
} else {
|
|
||||||
next();
|
await checkNameChange(groupName, values.name);
|
||||||
}
|
if (values.hasOwnProperty('private')) {
|
||||||
},
|
await updatePrivacy(groupName, values.private);
|
||||||
async.apply(db.setObject, 'group:' + groupName, payload),
|
}
|
||||||
async.apply(Groups.renameGroup, groupName, values.name),
|
|
||||||
], next);
|
if (values.hasOwnProperty('hidden')) {
|
||||||
},
|
await updateVisibility(groupName, values.hidden);
|
||||||
function (result, next) {
|
}
|
||||||
plugins.fireHook('action:group.update', {
|
await db.setObject('group:' + groupName, payload);
|
||||||
name: groupName,
|
await Groups.renameGroup(groupName, values.name);
|
||||||
values: values,
|
|
||||||
});
|
plugins.fireHook('action:group.update', {
|
||||||
next();
|
name: groupName,
|
||||||
},
|
values: values,
|
||||||
], callback);
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function updateVisibility(groupName, hidden, callback) {
|
async function updateVisibility(groupName, hidden) {
|
||||||
if (hidden) {
|
if (hidden) {
|
||||||
async.parallel([
|
await db.sortedSetRemoveBulk([
|
||||||
async.apply(db.sortedSetsRemove, ['groups:visible:createtime', 'groups:visible:memberCount'], groupName),
|
['groups:visible:createtime', groupName],
|
||||||
async.apply(db.sortedSetRemove, 'groups:visible:name', groupName.toLowerCase() + ':' + groupName),
|
['groups:visible:memberCount', groupName],
|
||||||
], callback);
|
['groups:visible:name', groupName.toLowerCase() + ':' + groupName],
|
||||||
} else {
|
]);
|
||||||
async.waterfall([
|
return;
|
||||||
function (next) {
|
|
||||||
db.getObjectFields('group:' + groupName, ['createtime', 'memberCount'], next);
|
|
||||||
},
|
|
||||||
function (groupData, next) {
|
|
||||||
db.sortedSetAddBulk([
|
|
||||||
['groups:visible:createtime', groupData.createtime, groupName],
|
|
||||||
['groups:visible:memberCount', groupData.memberCount, groupName],
|
|
||||||
['groups:visible:name', 0, groupName.toLowerCase() + ':' + groupName],
|
|
||||||
], next);
|
|
||||||
},
|
|
||||||
], callback);
|
|
||||||
}
|
}
|
||||||
|
const groupData = await db.getObjectFields('group:' + groupName, ['createtime', 'memberCount']);
|
||||||
|
await db.sortedSetAddBulk([
|
||||||
|
['groups:visible:createtime', groupData.createtime, groupName],
|
||||||
|
['groups:visible:memberCount', groupData.memberCount, groupName],
|
||||||
|
['groups:visible:name', 0, groupName.toLowerCase() + ':' + groupName],
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Groups.hide = function (groupName, callback) {
|
Groups.hide = async function (groupName) {
|
||||||
showHide(groupName, 'hidden', callback);
|
await showHide(groupName, 'hidden');
|
||||||
};
|
};
|
||||||
|
|
||||||
Groups.show = function (groupName, callback) {
|
Groups.show = async function (groupName) {
|
||||||
showHide(groupName, 'show', callback);
|
await showHide(groupName, 'show');
|
||||||
};
|
};
|
||||||
|
|
||||||
function showHide(groupName, hidden, callback) {
|
async function showHide(groupName, hidden) {
|
||||||
hidden = hidden === 'hidden';
|
hidden = hidden === 'hidden';
|
||||||
callback = callback || function () {};
|
await Promise.all([
|
||||||
async.parallel([
|
db.setObjectField('group:' + groupName, 'hidden', hidden ? 1 : 0),
|
||||||
async.apply(db.setObjectField, 'group:' + groupName, 'hidden', hidden ? 1 : 0),
|
updateVisibility(groupName, hidden),
|
||||||
async.apply(updateVisibility, groupName, hidden),
|
]);
|
||||||
], function (err) {
|
|
||||||
callback(err);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePrivacy(groupName, isPrivate, callback) {
|
async function updatePrivacy(groupName, isPrivate) {
|
||||||
async.waterfall([
|
const groupData = await Groups.getGroupFields(groupName, ['private']);
|
||||||
function (next) {
|
const currentlyPrivate = groupData.private === 1;
|
||||||
Groups.getGroupFields(groupName, ['private'], next);
|
if (!currentlyPrivate || currentlyPrivate === isPrivate) {
|
||||||
},
|
return;
|
||||||
function (currentValue, next) {
|
}
|
||||||
var currentlyPrivate = currentValue.private === 1;
|
const pendingUids = await db.getSetMembers('group:' + groupName + ':pending');
|
||||||
if (!currentlyPrivate || currentlyPrivate === isPrivate) {
|
if (!pendingUids.length) {
|
||||||
return callback();
|
return;
|
||||||
}
|
}
|
||||||
db.getSetMembers('group:' + groupName + ':pending', next);
|
|
||||||
},
|
|
||||||
function (uids, next) {
|
|
||||||
if (!uids.length) {
|
|
||||||
return callback();
|
|
||||||
}
|
|
||||||
var now = Date.now();
|
|
||||||
winston.verbose('[groups.update] Group is now public, automatically adding ' + uids.length + ' new members, who were pending prior.');
|
|
||||||
async.series([
|
|
||||||
async.apply(db.sortedSetAdd, 'group:' + groupName + ':members', uids.map(() => now), uids),
|
|
||||||
async.apply(db.delete, 'group:' + groupName + ':pending'),
|
|
||||||
], next);
|
|
||||||
},
|
|
||||||
], function (err) {
|
|
||||||
callback(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkNameChange(currentName, newName, callback) {
|
winston.verbose('[groups.update] Group is now public, automatically adding ' + pendingUids.length + ' new members, who were pending prior.');
|
||||||
if (currentName === newName) {
|
|
||||||
return setImmediate(callback);
|
for (const uid of pendingUids) {
|
||||||
|
/* eslint-disable no-await-in-loop */
|
||||||
|
await Groups.join(groupName, uid);
|
||||||
}
|
}
|
||||||
var currentSlug = utils.slugify(currentName);
|
await db.delete('group:' + groupName + ':pending');
|
||||||
var newSlug = utils.slugify(newName);
|
}
|
||||||
if (currentSlug === newSlug) {
|
|
||||||
return setImmediate(callback);
|
async function checkNameChange(currentName, newName) {
|
||||||
|
const currentSlug = utils.slugify(currentName);
|
||||||
|
const newSlug = utils.slugify(newName);
|
||||||
|
if (currentName === newName || currentSlug === newSlug) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
async.waterfall([
|
const [group, exists] = await Promise.all([
|
||||||
function (next) {
|
Groups.getGroupData(currentName),
|
||||||
async.parallel({
|
Groups.existsBySlug(newSlug),
|
||||||
group: function (next) {
|
]);
|
||||||
Groups.getGroupData(currentName, next);
|
|
||||||
},
|
|
||||||
exists: function (next) {
|
|
||||||
Groups.existsBySlug(newSlug, next);
|
|
||||||
},
|
|
||||||
}, next);
|
|
||||||
},
|
|
||||||
function (results, next) {
|
|
||||||
if (results.exists) {
|
|
||||||
return next(new Error('[[error:group-already-exists]]'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!results.group) {
|
if (exists) {
|
||||||
return next(new Error('[[error:no-group]]'));
|
throw new Error('[[error:group-already-exists]]');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (results.group.system) {
|
if (!group) {
|
||||||
return next(new Error('[[error:not-allowed-to-rename-system-group]]'));
|
throw new Error('[[error:no-group]]');
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
if (group.system) {
|
||||||
},
|
throw new Error('[[error:not-allowed-to-rename-system-group]]');
|
||||||
], callback);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Groups.renameGroup = function (oldName, newName, callback) {
|
Groups.renameGroup = async function (oldName, newName) {
|
||||||
if (oldName === newName || !newName || newName.length === 0) {
|
if (oldName === newName || !newName || String(newName).length === 0) {
|
||||||
return setImmediate(callback);
|
return;
|
||||||
|
}
|
||||||
|
const group = await db.getObject('group:' + oldName);
|
||||||
|
if (!group) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
var group;
|
|
||||||
async.waterfall([
|
|
||||||
function (next) {
|
|
||||||
db.getObject('group:' + oldName, next);
|
|
||||||
},
|
|
||||||
function (_group, next) {
|
|
||||||
group = _group;
|
|
||||||
if (!group) {
|
|
||||||
return callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
Groups.exists(newName, next);
|
const exists = await Groups.exists(newName);
|
||||||
},
|
if (exists) {
|
||||||
function (exists, next) {
|
throw new Error('[[error:group-already-exists]]');
|
||||||
if (exists) {
|
}
|
||||||
return callback(new Error('[[error:group-already-exists]]'));
|
|
||||||
}
|
await updateMemberGroupTitles(oldName, newName);
|
||||||
async.series([
|
await updateNavigationItems(oldName, newName);
|
||||||
async.apply(updateMemberGroupTitles, oldName, newName),
|
await updateWidgets(oldName, newName);
|
||||||
async.apply(updateNavigationItems, oldName, newName),
|
await db.setObject('group:' + oldName, { name: newName, slug: utils.slugify(newName) });
|
||||||
async.apply(updateWidgets, oldName, newName),
|
await db.deleteObjectField('groupslug:groupname', group.slug);
|
||||||
async.apply(db.setObjectField, 'group:' + oldName, 'name', newName),
|
await db.setObjectField('groupslug:groupname', utils.slugify(newName), newName);
|
||||||
async.apply(db.setObjectField, 'group:' + oldName, 'slug', utils.slugify(newName)),
|
|
||||||
async.apply(db.deleteObjectField, 'groupslug:groupname', group.slug),
|
const allGroups = await db.getSortedSetRange('groups:createtime', 0, -1);
|
||||||
async.apply(db.setObjectField, 'groupslug:groupname', utils.slugify(newName), newName),
|
const keys = allGroups.map(group => 'group:' + group + ':members');
|
||||||
function (next) {
|
await renameGroupsMember(keys, oldName, newName);
|
||||||
db.getSortedSetRange('groups:createtime', 0, -1, function (err, groups) {
|
|
||||||
if (err) {
|
await db.rename('group:' + oldName, 'group:' + newName);
|
||||||
return next(err);
|
await db.rename('group:' + oldName + ':members', 'group:' + newName + ':members');
|
||||||
}
|
await db.rename('group:' + oldName + ':owners', 'group:' + newName + ':owners');
|
||||||
const keys = groups.map(group => 'group:' + group + ':members');
|
await db.rename('group:' + oldName + ':pending', 'group:' + newName + ':pending');
|
||||||
renameGroupsMember(keys, oldName, newName, next);
|
await db.rename('group:' + oldName + ':invited', 'group:' + newName + ':invited');
|
||||||
});
|
await db.rename('group:' + oldName + ':member:pids', 'group:' + newName + ':member:pids');
|
||||||
},
|
|
||||||
async.apply(db.rename, 'group:' + oldName, 'group:' + newName),
|
await renameGroupsMember(['groups:createtime', 'groups:visible:createtime', 'groups:visible:memberCount'], oldName, newName);
|
||||||
async.apply(db.rename, 'group:' + oldName + ':members', 'group:' + newName + ':members'),
|
await renameGroupsMember(['groups:visible:name'], oldName.toLowerCase() + ':' + oldName, newName.toLowerCase() + ':' + newName);
|
||||||
async.apply(db.rename, 'group:' + oldName + ':owners', 'group:' + newName + ':owners'),
|
|
||||||
async.apply(db.rename, 'group:' + oldName + ':pending', 'group:' + newName + ':pending'),
|
plugins.fireHook('action:group.rename', {
|
||||||
async.apply(db.rename, 'group:' + oldName + ':invited', 'group:' + newName + ':invited'),
|
old: oldName,
|
||||||
async.apply(db.rename, 'group:' + oldName + ':member:pids', 'group:' + newName + ':member:pids'),
|
new: newName,
|
||||||
|
|
||||||
async.apply(renameGroupsMember, ['groups:createtime', 'groups:visible:createtime', 'groups:visible:memberCount'], oldName, newName),
|
|
||||||
async.apply(renameGroupsMember, ['groups:visible:name'], oldName.toLowerCase() + ':' + oldName, newName.toLowerCase() + ':' + newName),
|
|
||||||
function (next) {
|
|
||||||
plugins.fireHook('action:group.rename', {
|
|
||||||
old: oldName,
|
|
||||||
new: newName,
|
|
||||||
});
|
|
||||||
Groups.resetCache();
|
|
||||||
next();
|
|
||||||
},
|
|
||||||
], next);
|
|
||||||
},
|
|
||||||
], function (err) {
|
|
||||||
callback(err);
|
|
||||||
});
|
});
|
||||||
|
Groups.resetCache();
|
||||||
};
|
};
|
||||||
|
|
||||||
function updateMemberGroupTitles(oldName, newName, callback) {
|
async function updateMemberGroupTitles(oldName, newName) {
|
||||||
const batch = require('../batch');
|
await batch.processSortedSet('group:' + oldName + ':members', async function (uids) {
|
||||||
batch.processSortedSet('group:' + oldName + ':members', function (uids, next) {
|
let usersData = await user.getUsersData(uids);
|
||||||
async.waterfall([
|
usersData = usersData.filter(userData => userData && userData.groupTitleArray.includes(oldName));
|
||||||
function (next) {
|
|
||||||
user.getUsersData(uids, next);
|
usersData.forEach(function (userData) {
|
||||||
},
|
userData.newTitleArray = userData.groupTitleArray.map(oldTitle => (oldTitle === oldName ? newName : oldTitle));
|
||||||
function (usersData, next) {
|
});
|
||||||
usersData = usersData.filter(userData => userData && userData.groupTitleArray.includes(oldName));
|
|
||||||
async.each(usersData, function (userData, next) {
|
await Promise.all(usersData.map(u => user.setUserField(u.uid, 'groupTitle', JSON.stringify(u.newTitleArray))));
|
||||||
const newTitleArray = userData.groupTitleArray.map(oldTitle => (oldTitle === oldName ? newName : oldTitle));
|
}, {});
|
||||||
user.setUserField(userData.uid, 'groupTitle', JSON.stringify(newTitleArray), next);
|
|
||||||
}, next);
|
|
||||||
},
|
|
||||||
], next);
|
|
||||||
}, callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function renameGroupsMember(keys, oldName, newName, callback) {
|
async function renameGroupsMember(keys, oldName, newName) {
|
||||||
var scores;
|
const isMembers = await db.isMemberOfSortedSets(keys, oldName);
|
||||||
async.waterfall([
|
keys = keys.filter((key, index) => isMembers[index]);
|
||||||
function (next) {
|
if (!keys.length) {
|
||||||
db.isMemberOfSortedSets(keys, oldName, next);
|
return;
|
||||||
},
|
}
|
||||||
function (isMembers, next) {
|
const scores = await db.sortedSetsScore(keys, oldName);
|
||||||
keys = keys.filter((key, index) => isMembers[index]);
|
await db.sortedSetsRemove(keys, oldName);
|
||||||
if (!keys.length) {
|
await db.sortedSetsAdd(keys, scores, newName);
|
||||||
return callback();
|
|
||||||
}
|
|
||||||
db.sortedSetsScore(keys, oldName, next);
|
|
||||||
},
|
|
||||||
function (_scores, next) {
|
|
||||||
scores = _scores;
|
|
||||||
db.sortedSetsRemove(keys, oldName, next);
|
|
||||||
},
|
|
||||||
function (next) {
|
|
||||||
db.sortedSetsAdd(keys, scores, newName, next);
|
|
||||||
},
|
|
||||||
], callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateNavigationItems(oldName, newName, callback) {
|
async function updateNavigationItems(oldName, newName) {
|
||||||
const navigation = require('../navigation/admin');
|
const navigation = require('../navigation/admin');
|
||||||
|
const navItems = await navigation.get();
|
||||||
|
navItems.forEach(function (navItem) {
|
||||||
|
if (navItem && Array.isArray(navItem.groups) && navItem.groups.includes(oldName)) {
|
||||||
|
navItem.groups.splice(navItem.groups.indexOf(oldName), 1, newName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
async.waterfall([
|
await navigation.save(navItems);
|
||||||
navigation.get,
|
|
||||||
function (navItems, next) {
|
|
||||||
navItems.forEach(function (navItem) {
|
|
||||||
if (navItem && Array.isArray(navItem.groups) && navItem.groups.includes(oldName)) {
|
|
||||||
navItem.groups.splice(navItem.groups.indexOf(oldName), 1, newName);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
navigation.save(navItems, next);
|
|
||||||
},
|
|
||||||
], callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateWidgets(oldName, newName, callback) {
|
async function updateWidgets(oldName, newName) {
|
||||||
const admin = require('../widgets/admin');
|
const admin = require('../widgets/admin');
|
||||||
const widgets = require('../widgets');
|
const widgets = require('../widgets');
|
||||||
async.waterfall([
|
|
||||||
admin.get,
|
const data = await admin.get();
|
||||||
function (data, next) {
|
|
||||||
async.eachSeries(data.areas, function (area, next) {
|
data.areas.forEach(function (area) {
|
||||||
if (!area.data.length) {
|
area.widgets = area.data;
|
||||||
return setImmediate(next);
|
area.widgets.forEach(function (widget) {
|
||||||
}
|
if (widget && widget.data && Array.isArray(widget.data.groups) && widget.data.groups.includes(oldName)) {
|
||||||
area.widgets = area.data;
|
widget.data.groups.splice(widget.data.groups.indexOf(oldName), 1, newName);
|
||||||
area.widgets.forEach(function (widget) {
|
}
|
||||||
if (widget && widget.data && Array.isArray(widget.data.groups) && widget.data.groups.includes(oldName)) {
|
});
|
||||||
widget.data.groups.splice(widget.data.groups.indexOf(oldName), 1, newName);
|
});
|
||||||
}
|
for (const area of data.areas) {
|
||||||
});
|
if (area.data.length) {
|
||||||
|
await widgets.setArea(area);
|
||||||
widgets.setArea(area, next);
|
}
|
||||||
}, next);
|
}
|
||||||
},
|
|
||||||
], callback);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue