UNPKG

sheercms

Version:

Sheer Cliff CMS is a simple and powerful content management system (CMS) for Node JS.

549 lines (500 loc) 19 kB
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; }