sheercms
Version:
Sheer Cliff CMS is a simple and powerful content management system (CMS) for Node JS.
549 lines (500 loc) • 19 kB
JavaScript
var logger = require('../logger');
var models = require('./types-models');
var api = require('../api');
var mongoose = require('mongoose');
var S = require('string');
var util = require('../utilities');
var contentModels = require('../content/content-models');
var _contentTypes = [];
/*
callback: (err)
*/
module.exports.loadContentTypes = function(callback) {
models.ContentType.find().sort({name:1}).lean().exec(function (err, types) {
if (err) {
if (callback) callback(err);
}
else {
try {
if (types) {
_contentTypes = mapContentTypes(types, true);
for (var i = 0; i < _contentTypes.length; i++) {
var t = _contentTypes[i];
buildContentType(t);
}
if (callback) callback(null);
}
else {
var e = new Error("No content types were found.");
logger.error(e);
if (callback) callback(e);
}
} catch(e) {
logger.error(e);
if (callback) callback(e);
}
}
});
};
function mapContentTypes(list, allProps) {
var arr = [];
for(var i = 0; i < list.length; i++) {
var t = list[i];
arr.push(mapContentType(t, allProps));
}
return arr;
}
function mapContentType(t, allProps) {
var obj = {
id: t._id.toString(),
_id: t._id.toString(),
name: t.name,
desc: t.desc,
created: t.created,
modified: t.modified,
createdBy: t.createdBy,
modifiedBy: t.modifiedBy,
icon: t.icon,
controller: t.controller,
abstract: t.abstract,
built: false,
mediaExt: t.mediaExt,
mediaType: t.mediaType,
tabText: t.tabText,
tabDesc: t.tabDesc,
defaultTemplateId: t.defaultTemplateId,
mime: t.mime
};
//map the inherit types array
if (t.inheritTypes)
obj.inheritTypes = util.objectIdArrayToString(t.inheritTypes);
//map the templates array
if (t.templates)
obj.templates = util.objectIdArrayToString(t.templates);
if (allProps) {
obj.fields = t.fields;
}
return obj;
}
function mapObjectIdArray(objIds) {
var arr = [];
for (var i = 0; i < objIds.length; i++) {
arr.push(util.toObjectId(objIds[i]));
}
return arr;
}
function buildContentType(t) {
var name, desc;
logger.info("Building content type fields: " + t.name);
t.groups = [];
if (t.fields && t.fields.length > 0) {
name = S(t.tabText).isEmpty() ? t.name : t.tabText;
desc = S(t.tabDesc).isEmpty() ? t.desc : t.tabDesc;
t.groups.push(new FieldGroup(name, desc, t.fields));
}
if (t.inheritTypes && t.inheritTypes.length > 0) {
for (var i = 0; i < t.inheritTypes.length; i++) {
var id = t.inheritTypes[i];
var ct = getContentType(id);
if (ct) {
name = S(ct.tabText).isEmpty() ? ct.name : ct.tabText;
desc = S(ct.tabDesc).isEmpty() ? ct.desc : ct.tabDesc;
t.groups.push(new FieldGroup(name, desc, ct.fields));
}
}
}
t.built = true;
}
function FieldGroup(name, desc, fields) {
var self = this;
self.name = name;
self.desc = desc;
self.fields = fields;
};
/*
callback: function(err, contentType);
*/
module.exports.getContentType = function(id, callback) {
if (callback) {
if (_contentTypes) {
for (var i = 0; i < _contentTypes.length; i++) {
if (_contentTypes[i]._id == id) {
callback(null, _contentTypes[i]);
return;
}
}
callback(null, null);
}
else
callback(null, null);
}
}
module.exports.getContentTypeSync = function(id) {
return getContentType(id);
}
function getContentType(id) {
for(var i = 0; i < _contentTypes.length; i++) {
if (_contentTypes[i].id == id)
return _contentTypes[i];
}
return null;
}
/*
callback: (err, contentType)
*/
module.exports.createContentType = function(contentType, username, callback) {
try {
//first make sure there isn't already one with this name
models.ContentType.findOne({ name: contentType.name}, function (err, result) {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else if (result) {
var e = new Error("A content type with this key already exists: " + contentType.name);
logger.warn(e);
if (callback) callback(e);
}
else {
if (S(contentType.icon).isEmpty())
contentType.icon = '/cms/static/images/icons/32/page_white.png';
//new content type
var t = new models.ContentType({
name: contentType.name,
created: new Date(),
createdBy: username,
desc: contentType.desc,
icon: contentType.icon,
controller: contentType.controller,
abstract: contentType.abstract || false,
fields: contentType.fields,
mediaExt: contentType.mediaExt,
mediaType: contentType.mediaType,
tabText: contentType.tabText,
tabDesc: contentType.tabDesc,
inheritTypes: util.stringArrayToObjectIds(contentType.inheritTypes),
templates: util.stringArrayToObjectIds(contentType.templates),
defaultTemplateId: util.toObjectId(contentType.defaultTemplateId),
mime: contentType.mime
});
try {
t.save(function (err) {
try {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else {
//reload all of the types
module.exports.loadContentTypes(function (err) {
try {
if (err) {
if (callback) callback(err);
}
else {
if (callback) callback(null, mapContentType(t, true));
}
}
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);
}
}
});
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
};
/*
callback: (err, contentType)
*/
module.exports.updateContentType = function(contentType, username, callback) {
try {
if (contentType._id) {
//existing item
tId = util.toObjectId(contentType._id);
models.ContentType.findById(tId, function (err, result) {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else if (result == null) {
var e = new Error("Content Type not found: " + contentType._id);
logger.error(e);
if (callback) callback(e);
}
else {
if (S(contentType.icon).isEmpty())
contentType.icon = '/cms/static/images/icons/32/page_white.png';
//update the properties
result.name = contentType.name;
result.modified = new Date();
result.modifiedBy = username,
result.desc = contentType.desc;
result.icon = contentType.icon;
result.controller = contentType.controller;
result.abstract = contentType.abstract;
result.fields = contentType.fields;
result.mediaExt = contentType.mediaExt;
result.mediaType = contentType.mediaType;
result.tabText = contentType.tabText;
result.tabDesc = contentType.tabDesc;
result.inheritTypes = util.stringArrayToObjectIds(contentType.inheritTypes);
result.templates = util.stringArrayToObjectIds(contentType.templates);
result.defaultTemplateId = util.toObjectId(contentType.defaultTemplateId);
result.mime = contentType.mime;
result.markModified('fields');
try {
result.save(function (err) {
try {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else {
module.exports.loadContentTypes(function (err) {
try {
if (err) {
if (callback) callback(err);
}
else {
if (callback) callback(null, mapContentType(result, true));
}
}
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);
}
}
});
}
else
throw new Error('contentType._id is null');
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
};
/*
reload: if true, the content types list is reloaded
callback: (err, contentType)
*/
module.exports.importContentType = function(contentType, username, reload, callback) {
try {
//the template should have an ID
if (!contentType._id) {
var e = new Error('The _id property is required during import.');
logger.error(e);
if (callback) callback(e);
return;
}
logger.info("Importing content type: " + contentType._id);
var id = util.toObjectId(contentType._id);
models.ContentType.findById(id, function(err, doc) {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else {
if (!doc) {
doc = new models.ContentType();
doc._id = contentType._id;
doc.created = new Date();
doc.createdBy = username;
}
//update the properties
doc.name = contentType.name;
doc.modified = new Date();
doc.modifiedBy = username,
doc.desc = contentType.desc;
doc.icon = contentType.icon;
doc.controller = contentType.controller;
doc.abstract = contentType.abstract;
doc.fields = contentType.fields;
doc.mediaExt = contentType.mediaExt;
doc.mediaType = contentType.mediaType;
doc.tabText = contentType.tabText;
doc.tabDesc = contentType.tabDesc;
doc.inheritTypes = util.stringArrayToObjectIds(contentType.inheritTypes);
doc.templates = util.stringArrayToObjectIds(contentType.templates);
doc.defaultTemplateId = util.toObjectId(contentType.defaultTemplateId);
doc.mime = contentType.mime;
doc.markModified('fields');
try {
doc.save(function (err) {
try {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else {
if (reload === true) {
module.exports.loadContentTypes(function (err) {
if (err) {
if (callback) callback(err);
}
else {
if (callback) callback(null, mapContentType(doc, true));
}
});
}
else {
if (callback) callback(null, mapContentType(doc, true));
}
}
}
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);
}
}
/*
callback: (err, contentTypes)
*/
module.exports.getContentTypes = function(allProps, callback) {
if (callback) {
try {
if (allProps)
callback(null, _contentTypes);
else
callback(null, mapContentTypes(_contentTypes, false));
}
catch (e) {
logger.error(e);
callback(e);
}
}
};
/*
callback: (err)
*/
module.exports.delete = function(typeId, callback) {
try {
var id = util.toObjectId(typeId);
//first make sure there are no items using the content type
contentModels.Draft.find({typeId: id}).count(function (err, count) {
try {
if (err) {
if (callback) callback(err);
}
else if (count === 0) {
models.ContentType.findByIdAndRemove(id, function (err) {
try {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else {
//rebuilt the content types cache
module.exports.loadContentTypes(function (err) {
if (err) {
if (callback) callback(err);
}
else {
if (callback) callback(null);
}
});
}
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
});
}
else {
var e = new Error('This content type cannot be deleted because there are items using it.');
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);
}
};
/*
returns the content type for this extension
*/
module.exports.getMediaContentType = function(typeIds, ext) {
var types = getContentTypes(typeIds);
if (ext && ext.length > 0) {
var extNoDot = ext.replace(".", "").toLowerCase();
for(var i = 0; i < types.length; i++) {
var t = types[i];
if (t.mediaExt && t.mediaExt.length > 0) {
var extArr = t.mediaExt.split(',');
if (extArr && extArr.length > 0) {
for(var j = 0; j < extArr.length; j++) {
if (extArr[j].toLowerCase() == extNoDot) {
return t;
}
}
}
}
}
}
return null;
}
function getContentTypes(typeIds) {
var types = [];
if (typeIds) {
for (var i = 0; i < typeIds.length; i++) {
var id = typeIds[i];
for (var j = 0; j < _contentTypes.length; j++) {
if (_contentTypes[j]._id == id) {
types.push(_contentTypes[j]);
break;
}
}
}
}
return types;
}