sheercms
Version:
Sheer Cliff CMS is a simple and powerful content management system (CMS) for Node JS.
613 lines (577 loc) • 21.4 kB
JavaScript
var logger = require('../logger');
var models = require('./groups-models');
var api = require('../api');
var mongoose = require('mongoose');
var S = require('string');
var util = require('../utilities');
var async = require('async');
var contentModels = require('../content/content-models');
/*
callback: err, group
*/
module.exports.createGroup = function(group, callback) {
try {
var g = new models.Group({
parentId: group.parentId,
name: group.name,
desc: group.desc,
branch: group.branch,
icon: (group.icon && group.icon.length > 0) ? group.icon : '/cms/static/images/icons/32/page_white_stack.png',
itemCount: 0,
childCount: 0,
contentTypes: [],
perms: null,
urlPattern: null,
views: ['list'], //list, gallery, calendar
sortBy: null,
sortDir: null,
position: 9999,
created: new Date()
});
if (group.mediaSettings) {
g.mediaSettings = {
imageWidth: group.mediaSettings.imageWidth,
imageHeight: group.mediaSettings.imageHeight,
resizeMode: group.mediaSettings.resizeMode,
imageQuality: group.mediaSettings.imageQuality
}
}
if (group.categories)
g.categories = group.categories;
g.save(function (err) {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else {
logger.info("Group created: " + g._id);
if (callback) callback(null, mapGroup(g));
}
});
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
};
/*
callback: err, group
*/
module.exports.updateGroup = function(group, callback) {
try {
var id = util.toObjectId(group._id);
models.Group.findById(id, function (err, result) {
try {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else if (result === null) {
var e = new Error("Group not found: " + group._id);
logger.error(e);
if (callback) callback(e);
}
else {
//update the properties
result.name = group.name;
result.desc = group.desc;
result.icon = (group.icon && group.icon.length > 0) ? group.icon : '/cms/static/images/icons/32/page_white_stack.png';
result.contentTypes = util.stringArrayToObjectIds(group.contentTypes);
result.perms = group.perms;
result.urlPattern = group.urlPattern;
result.views = group.views;
result.sortBy = group.sortBy;
result.sortDir = group.sortDir;
result.position = group.position;
result.modified = new Date();
result.categories = group.categories;
if (group.mediaSettings) {
if (!result.mediaSettings)
result.mediaSettings = {};
result.mediaSettings.imageWidth = group.mediaSettings.imageWidth;
result.mediaSettings.imageHeight = group.mediaSettings.imageHeight;
result.mediaSettings.resizeMode = group.mediaSettings.resizeMode;
result.mediaSettings.imageQuality = group.mediaSettings.imageQuality;
}
result.markModified('perms');
result.save(function (err) {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else {
logger.info("Group updated: " + result._id);
if (callback) callback(null, mapGroup(result));
}
});
}
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
});
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
};
/*
callback: err, group
*/
module.exports.importGroup = function(group, callback) {
try {
var id = util.toObjectId(group._id);
models.Group.findById(id, function (err, result) {
try {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else {
if (result == null) {
result = new models.Group();
result._id = id;
result.created = new Date();
}
//update the properties
result.branch = group.branch;
result.parentId = group.parentId;
result.name = group.name;
result.desc = group.desc;
result.icon = (group.icon && group.icon.length > 0) ? group.icon : '/cms/static/images/icons/32/page_white_stack.png';
result.contentTypes = util.stringArrayToObjectIds(group.contentTypes);
result.perms = group.perms;
result.urlPattern = group.urlPattern;
result.views = group.views;
result.sortBy = group.sortBy;
result.sortDir = group.sortDir;
result.position = group.position;
result.modified = new Date();
result.categories = group.categories;
if (group.mediaSettings) {
if (!result.mediaSettings)
result.mediaSettings = {};
result.mediaSettings.imageWidth = group.mediaSettings.imageWidth;
result.mediaSettings.imageHeight = group.mediaSettings.imageHeight;
result.mediaSettings.resizeMode = group.mediaSettings.resizeMode;
result.mediaSettings.imageQuality = group.mediaSettings.imageQuality;
}
result.markModified('perms');
result.save(function (err) {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else {
logger.info("Group imported: " + result._id);
module.exports.recalculateCount(result._id, function(err, count) {
if (callback) callback(err, mapGroup(result));
});
}
});
}
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
});
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
};
/*
increment can be + or - integer
callback: err, newCount
*/
module.exports.updateItemCount = function(groupId, increment, callback) {
try {
var id = util.toObjectId(groupId);
var update = {$inc: {"itemCount": increment}};
var options = {new: true};
models.Group.findByIdAndUpdate(id, update, options, function (err, result) {
try {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else if (result === null) {
var e = new Error("Group not found: " + groupId);
logger.error(e);
if (callback) callback(e);
}
else {
if (callback) callback(null, result.itemCount); //successful
}
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
});
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
};
/*
recalculates the item count on all groups in the CMS.
callback: err
*/
module.exports.recalculateAllGroups = function(callback) {
try {
models.Group.find().lean().exec(function (err, groups) {
try {
if (err) {
if (callback) callback(err);
}
else {
if (groups && groups.length > 0) {
async.eachSeries(groups, function (group, done) {
module.exports.recalculateCount(group._id, function(err, count) {
done(err);
});
}, function (err) {
if (callback) callback(err);
});
}
else {
if (callback) callback(null);
}
}
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
});
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
};
/*
callback: err, newCount
*/
module.exports.recalculateCount = function(groupId, callback) {
try {
var id = util.toObjectId(groupId);
//count all of the items with this group ID
contentModels.Draft.find({groupId: id}).count(function (err, count) {
try {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else {
var update = {"itemCount": count};
var options = {new: true};
models.Group.findByIdAndUpdate(id, update, options, function (err, result) {
try {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else if (result === null) {
var e = new Error("Group not found: " + groupId);
logger.error(e);
if (callback) callback(e);
}
else {
if (callback) callback(null, result.itemCount); //successful
}
}
catch (e) {
logger.error(e);
if (callback) callback(e);
}
});
}
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
});
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
};
/*
positions: [{groupId, position}]
callback: err
*/
module.exports.reorderGroups = function(positions, callback) {
try {
//map the positions to ObjectIds
var ids = positions.map(function(pos) { return util.toObjectId(pos.groupId); });
models.Group.find({_id: {$in: ids}}, function (err, results) {
try {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else if (results === null) {
var e = new Error("Groups not found: " + JSON.stringify(positions));
logger.error(e);
if (callback) callback(e);
}
else {
//put the positions in a hash
var hash = {};
for(var i = 0; i < positions.length; i++) {
var pos = positions[i];
hash[pos.groupId] = pos.position;
}
//update each group found
async.eachSeries(results, function (group, done) {
try {
var pos = hash[group._id.toString()];
if (pos) {
group.position = pos;
group.save(function (err) {
if (err) {
logger.error(err);
done(err);
}
else {
logger.info("Group position updated: " + group._id + " to " + pos);
done();
}
});
}
else {
var e = new Error("Position not found in the hash for group: " + group._id);
logger.error(e);
done(e);
}
}
catch(e) {
logger.error(e);
done(e);
}
}, function (err) {
if (callback) callback(err);
});
}
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
});
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
};
/*
callback: err
*/
module.exports.deleteGroup = function(groupId, callback) {
try {
var id = util.toObjectId(groupId);
models.Group.findById(id, function (err, result) {
try {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else if (result === null) {
var e = new Error('Group cannot be deleted because it does not exist: ' + groupId);
logger.error(e);
if (callback) callback(e);
}
else {
//make sure there are not child groups or items
if (result.itemCount > 0) {
var e = new Error('Group cannot be deleted because it contains items: ' + result.name + ' (' + groupId + ')');
logger.error(e);
if (callback) callback(e);
}
else if (result.childCount > 0) {
var e = new Error('Group cannot be deleted because it contains child groups: ' + result.name + ' (' + groupId + ')');
logger.error(e);
if (callback) callback(e);
}
else {
//delete this group
logger.info('Deleting group: ' + result.name + ' (' + groupId + ')');
models.Group.findByIdAndRemove(id, function (err) {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else {
logger.info('Group deleted successfully: ' + result.name + ' (' + groupId + ')');
if (callback) callback(null);
}
});
}
}
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
});
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
};
/*
username: if not null, it will be used to calculate the permissions on the group
callback: err, groups
*/
module.exports.getGroups = function(branch, parentId, username, callback) {
try {
if (callback) {
var pId = util.toObjectId(parentId);
if (!branch)
throw new Error('branch parameter is null.');
models.Group.find({ branch: branch, parentId: pId }).sort("position name").lean().exec(function (err, result) {
try {
if (err) {
logger.error(err);
callback(err);
}
else {
if (result && result.length > 0 && username && username.length > 0) {
//calculate the permissions for this user on the groups
api.users.getUser(username, function (err, user) {
try {
if (err) {
callback(err);
}
else if (user) {
for(var i = 0; i < result.length; i++) {
var g = result[i];
g.rights = module.exports.getGroupRights(g, user);
}
callback(null, result);
}
else {
var e = new Error("User not found: " + username);
logger.error(e);
callback(e);
}
}
catch (e) {
logger.error(e);
callback(e);
}
});
}
else
callback(err, result);
}
}
catch(e) {
logger.error(e);
callback(e);
}
});
}
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
};
module.exports.getGroupRights = function(group, user) {
if (api.users.isAdmin(user)) {
return new AccessRight(true, true, true, true, true);
}
else if (group && group.perms && group.perms.length && user && user.roles && user.roles.length > 0) {
var right = new AccessRight(false, false, false, false, false);
//put the roles in an object hash
var roles = {};
for(var i = 0; i < user.roles.length; i++)
roles[user.roles[i]] = true;
//loop through each permission on this group
for(var i = 0; i < group.perms.length; i++) {
var p = group.perms[i];
if (roles[p.role] == true) {
if (p.create == true)
right.create = true;
if (p.read == true)
right.read = true;
if (p.update == true)
right.update = true;
if (p.delete == true)
right.delete = true;
if (p.publish == true)
right.publish = true;
}
}
return right;
}
else {
return new AccessRight(false, false, false, false, false);
}
};
function AccessRight(create, read, update, del, pub) {
var self = this;
self.create = create;
self.read = read;
self.update = update;
self.delete = del;
self.publish = pub;
}
/*
callback: err, group
*/
module.exports.getGroup = function(groupId, callback) {
try {
if (callback) {
var id = util.toObjectId(groupId);
models.Group.findOne({_id: id}).lean().exec(function (err, result) {
if (err) {
logger.error(err);
callback(err);
}
else
callback(err, result);
});
}
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
};
function mapGroup(group) {
var g = {
_id: group._id,
parentId: group.parentId,
name: group.name,
desc: group.desc,
branch: group.branch,
icon: group.icon,
itemCount: group.itemCount,
childCount: group.childCount,
contentTypes: util.objectIdArrayToString(group.contentTypes),
perms: group.perms,
urlPattern: group.urlPattern,
views: group.views,
sortBy: group.sortBy,
sortDir: group.sortDir,
position: group.position,
created: group.created,
modified: group.modified,
mediaSettings: group.mediaSettings,
categories: group.categories
};
return g;
}