UNPKG

cody

Version:
559 lines (462 loc) 16.5 kB
// // Johan Coppieters - jan 2013 - jWorks // // console.log("loading " + module.id); var cody = require("./../index.js"); function Page(basis, app) { // copy from basis for (var a in basis) { if (basis.hasOwnProperty(a)) { this[a] = basis[a]; } } if (typeof this.item !== "undefined") { // replace 'item' (an id) by the real object and add 'itemId' this.itemId = this.item; this.item = app.getItem(this.itemId); if (typeof this.item === "undefined") { app.err("Application.fetchPages", "did not find item for page " + this.itemId + " / " + this.title); } } this.prefix = app.prefix; } module.exports = Page; Page.addDefaults = function(basis, item) { if (typeof item === "undefined") { item = {}; } basis.item = basis.item || item.id; basis.language = basis.language || cody.Application.kDefaultLanguage; basis.title = basis.title || item.name || cody.Item.kDefaultName; basis.created = basis.created || new Date(); basis.updated = basis.updated || new Date(); basis.link = basis.link || ""; basis.keywords = basis.keywords || ""; basis.description = basis.description || ""; basis.active = basis.active || "Y"; basis.content = basis.content || []; return basis; }; Page.loadPages = function(connection, store) { connection.query('select * from pages', [], function(err, result) { if (err) { console.log(err); throw(new Error("Page.loadPages failed with sql errors")); } store(result); }); }; Page.loadLanguages = function(connection, store) { connection.query('select * from languages order by sortorder', [], function(err, result) { if (err) { console.log(err); throw(new Error("Page.loadLanguages failed with sql errors")); } store(result); }); }; Page.prototype.addTo = function(app) { // add to the list of all pages app.pages.push(this); // build url with its unique id (no check needed) and store in the hashmap this.url = this.language + "/" + this.itemId; app.urls[this.url] = this; if (! this.setLink(this.link, app, true) ) { throw new Error("Application.fetchPages - double link: " + this.url); } }; Page.prototype.setLink = function(link, app, isNew) { // if we have a user defined link, store it in the url field as well in the app's url hashmap // delete the current link from the app's hashmap if (isNew !== true) { if ((typeof this.link !== "undefined") && (this.link !== "")) { delete app.urls[this.language + "/" + this.link]; } } if (link !== '') { // check if this link is not already used if (isNew === true) { if (app.urls[this.language + "/" + link]) { console.log("Page.setLink -> " + this.language + "/" + link + " already used"); return false; } } // replace the page its url by something better (than "language/id") var url = this.language + "/" + link; app.urls[url] = this; this.url = url; } this.link = link; return true; }; Page.prototype.addRoot = function() { var self = this; function goUp(aPage) { //console.log("goUp: " + aPage.item.id + " -> " + aPage.item.parentId); if (aPage.parent && (aPage.parent.item.parentId > 0)) { goUp(aPage.parent); } else { self.top = aPage; self.root = aPage.parent; //console.log("goUp: assigned for " + self.item.id + " -> top = " +self.top.item.id // ", root: " + ((self.root) ? self.root.item.id : "no root")); } } //console.log("AddRoot: " + this.itemId); goUp(this); }; Page.prototype.addChildren = function(list) { // loop through all pages and find pages having my parent id and language this.children = []; for (var i = 0; i < list.length; i++) { if ((list[i].item.parentId === this.itemId) && (list[i].language === this.language)) { // parent and language match -> add to my children this.children.push(list[i]); // this is done more than once... better solution? list[i].parent = this; } } if (this.children.length > 1) { this.sortChildren(this.item.orderby); // console.log("Page.addChildren -> sorted children of " + this.title + " -> " + this.item.orderby); // for(var i in this.children) console.log(" " + this.children[i].item.sortorder + ". " + this.children[i].title); } }; Page.prototype.sortChildren = function(order) { var kEqual = 0; // kBefore = -1, kAfter = 1; this.children.sort( function(a, b) { if (a === b) { return kEqual; } if (order === cody.Item.kAlphabetical) { return a.title.localeCompare(b.title); } if (order === cody.Item.kDate) { return b.item.dated.getTime() - a.item.dated.getTime(); } if (order === cody.Item.kManual) { return a.item.sortorder - b.item.sortorder; } console.log("Page.sortChildren -> We should't be here... orderby = " + order); return kEqual; }); }; Page.prototype.getController = function(context) { return (typeof this.item.template === "undefined") ? new Controller(context) : this.item.template.getController(context); }; Page.prototype.getView = function() { return (typeof this.item.template === "undefined") ? "index.ejs" : this.item.template.getView(); }; Page.prototype.getDisplay = function() { // check if this page is marked as: "show first subitem" if ((this.item.showcontent === cody.Item.kSubItem) && (this.children.length > 0)) { return this.children[0].getDisplay(); } else { return this; } }; Page.prototype.getLink = function() { // to be used for making URL when changing languages... /[language]/getLink() return (this.link != "") ? this.link : this.item.id; }; Page.prototype.getURL = function(language) { var prefix = this.prefix ? "/" + this.prefix : ""; // if the language is different from this page its language, // we actually return the url of another page (with the same item) if (typeof language !== "undefined") { return prefix + language + "/" + this.getLink(); } else { return prefix + this.url; } }; Page.prototype.shortString = function() { return this.title + " ("+ this.item.id + "/" + this.item.parentId + "), order = " + this.item.orderby + ", content = " + this.nrContent() + ", size = " + this.contentLength() + " bytes"; }; Page.prototype.needsLogin = function() { return (this.item) && (this.item.needslogin === "Y"); }; // // Tree interface requirements // Page.prototype.getAllowedDomains = function() { return this.item.getAllowedDomains(); }; Page.prototype.hasChildren = function() { return (this.children.length > 0); }; Page.prototype.isActive = function() { return (this.active === 'Y'); }; Page.prototype.isVisible = function() { var now = new Date(); return (this.active === 'Y') && (this.item.validfrom <= now) && (this.item.validto >= now); }; Page.prototype.hasBelow = function(p) { if (this === p) return true; for (var iP in this.children) { if (this.children[iP].hasBelow(p)) return true; } return false; } Page.prototype.getChildren = function() { return this.children; }; Page.prototype.getSortOrder = function() { return this.item.sortorder; }; Page.prototype.setSortOrder = function(nr) { this.item.sortorder = nr; }; Page.prototype.getName = function() { return this.title; }; Page.prototype.setName = function(name) { this.title = name; }; Page.prototype.getId = function() { return this.item.id; }; Page.prototype.getKind = function(kind) { var result = []; for (var ic in this.content) { if (this.content[ic].kind === kind) { result.push(this.content[ic]); } } return result; }; /* Page utilities */ Page.prototype.scrapeFrom = function(controller) { var self = this; // get all page info from the controller self.title = controller.getParam("title", self.title); self.active = controller.getParam("active", "N"); self.keywords = controller.getParam("keywords", ""); self.description = controller.getParam("description", ""); self.setLink(controller.getParam("link"), controller.app, false); // missing: updated (automatically on doUpdate), created (invariable), language (invariable) }; Page.prototype.doUpdate = function(controller, next, isNew) { var self = this; var values = [self.title, self.link, self.active, self.keywords, self.description, self.itemId, self.language]; // new or existing record? if (isNew) { // console.log("Page.doUpdate -> insert page " + self.title); controller.query("insert into pages (title, link, active, keywords, description , updated, created, item, language) " + "values (?, ?, ?, ?, ?, now(), now(), ?, ?)", values, function(err, result) { if (err) { console.log("Page.doUpdate -> error inserting page: " + self.language + "/" + self.itemId); console.log(err); } else { console.log("Page.doUpdate -> inserted page: " + self.language + "/" + self.itemId); self.created = self.updated = new Date(); } if (typeof next === "function") { next(); } }); } else { // console.log("Page.doUpdate -> update page " + self.itemId + " - " + self.title); controller.query("update pages set title = ?, link = ?, active = ?, keywords = ?, description = ?, updated = now() " + " where item = ? and language = ?", values, function(err) { if (err) { console.log("Page.doUpdate -> error updating page: " + self.language + "/" + self.itemId); console.log(err); } else { console.log("Page.doUpdate -> updated page: " + self.language + "/" + self.itemId); self.updated = new Date(); } if (typeof next === "function") { next(); } }); } }; Page.prototype.doDelete = function(controller, next) { var self = this; // should NOT be used !! console.log("ERROR: should not be used -- delete page " + self.language + "/" + this.item.id + " - " + this.title); controller.query("delete from pages where item = ? and language = ?", [self.itemId, self.language], function(err) { if (err) { console.log(err); } else { console.log("Page.doDelete -> deleted page: " + self.language + "/" + self.itemId); } if (typeof next === "function") { next(); } }); }; Page.prototype.doDeactivate = function(controller, next) { var self = this; console.log("Page.doDeactivate -> deactive page " + self.language + "/" + self.itemId + " - " + self.title); this.active = 'N'; controller.query("update pages set active = 'N' where item = ? and language = ?", [self.itemId, self.language], function(err) { if (err) { console.log(err); } else { console.log("Page.doDeactivate -> deactived page: " + self.language + "/" + self.itemId); } if (typeof next === "function") { next(); } }); }; /* Content stuff */ Page.prototype.render = function(params) { console.log("ERROR ** this seems to be so wrong??"); return this.content.render(params); } Page.prototype.getContent = function(id) { var i = -1; if (typeof id === "string") { i = this.getContentByName(id); } else { i = this.getContentIndex(id); } if (i >= 0) { return this.content[i]; } return undefined; }; Page.prototype.getContentByName = function(name) { for (var ic = 0; ic < this.content.length; ic++) { if (this.content[ic].name === name) { return ic; } } return -1; }; Page.prototype.getContentIndex = function(id) { for (var ic = 0; ic < this.content.length; ic++) { if (this.content[ic].id == id) { return ic; } } return -1; }; Page.prototype.nrContent = function() { return (typeof this.content !== "undefined") ? 0 : this.content.length; }; Page.prototype.contentLength = function() { if (typeof this.content === "undefined") { return 0; } var total = 0; this.content.forEach( function (c) { total += c.contentLength(); }); return total; }; Page.prototype.sortContent = function() { this.content.sort( function(a, b) { if (a.intro === b.intro) { return (a.sortorder - b.sortorder); } else if (a.intro === 'Y') { return -1; } else { return 1; } }); }; Page.prototype.loadContent = function(app, next) { this.fetchContent(app, this.language, this.itemId, next); }; Page.prototype.deleteContentById = function( controller, theId, next ) { var self = this; var i = self.getContentIndex(theId); if (i >= 0) { controller.query("delete from content where id=?", [theId], function(err) { if (err) { console.log(err); } else { self.content.splice(i, 1); console.log("Page.deleteContentById -> deleted content " + theId + ", on: " + i + ", of: " + self.language + "/" + self.itemId); } if (typeof next === "function") { next(); } }); } else { console.log("Page.deleteContentById: " + theId + " not found on " + self.language + "/" + self.itemId); if (typeof next === "function") { next(); } } }; Page.prototype.deleteContent = function( controller, next ) { var self = this; controller.query("delete from content where item=? and language=?", [self.itemId, self.language], function(err) { if (err) { console.log(err); } else { self.content = []; console.log("Page.deleteContent -> deleted all content of: " + self.language + "/" + self.itemId); if (typeof next === "function") { next(); } } }); }; Page.prototype.fetchContent = function( app, language, itemId, next ) { var self = this; var nrC = 1; var nrI = 1; app.connection.query( "select * from content where item = ? and language = ? order by intro desc, sortorder asc", [itemId, language], function(err, result) { if (err) { console.log(err); throw(new Error("Page.fetchContent failed with sql errors")); } self.content = []; console.log("Page.fetchContent, found " + result.length + " content blocks"); for (var i = 0; i < result.length; i++) { self.content[i] = new cody.Content(result[i], app); self.content[i].attachTo(self, itemId, language); if (self.content[i].name === "") { if (self.content[i].isIntro()) { self.content[i].name = ("Intro"+nrI); nrI++; } else { self.content[i].name = ("Content"+nrC); nrC++; } } console.log(" " + self.content[i].name + " = " + self.content[i].data.length + " bytes"); } if (typeof next === "function") { next(); } }); }; Page.prototype.updateContent = function( controller, finish ) { var self = this; cody.Application.each(self.content, function(next) { var aContent = this; aContent.scrapeFromWithId(controller); aContent.doUpdate(controller, false, next); }, function(err){ self.sortContent(); finish(); }); }; Page.prototype.adjustContent = function( controller, finish ) { var self = this; console.log("Page.adjustContent: add correct Content for " + self.itemId + " on template: " + (-1 * self.item.templateId)); var dummy = new Page({}, controller.app); dummy.fetchContent( controller.app, "*", -1 * self.item.templateId, function() { // used to be self.language instead of * // but then I decided that templates were language independent cody.Application.each(dummy.content, function(next) { var aContent = this; // only attach when no content block with this name exists if (self.getContent(aContent.name) === undefined) { self.content.push(aContent); aContent.attachTo(self, self.itemId, self.language); aContent.doUpdate(controller, true, next); } else { next(); } }, function(err){ self.sortContent(); finish(); }); }); }; Page.prototype.addContent = function( controller, theKind, finish ) { var self = this; console.log("Page.addContent: add " + theKind + " content for " + self.itemId); var aName = cody.Content.kindName(theKind); var aContent = new cody.Content({kind: theKind, name: aName}, controller.app); aContent.attachTo(self, self.itemId, self.language); self.content.push( aContent ); aContent.doUpdate(controller, true, function() { console.log("Page.addContent: added content id = " + aContent.id); finish(aContent.id); }); };