antville/code/Story/objectFunctions.js

299 lines
9.2 KiB
JavaScript

/**
* check if story is ok; if true, save changed story
* @param Obj Object containing the properties needed for creating a new story
* @param Obj User-Object modifying this story
* @return Obj Object containing two properties:
* - error (boolean): true if error happened, false if everything went fine
* - message (String): containing a message to user
*/
function evalStory(param,modifier) {
// loop through param and collect content properties
var majorUpdate = false;
var contentIsCool = false;
var cont = this.getContent();
for (var i in param) {
if (i.indexOf ("content_") == 0) {
var part = i.substring(8);
// check if there's a difference between old and
// new text of more than 50 characters:
if (!majorUpdate) {
var len1 = cont[part] ? cont[part].length : 0;
var len2 = 0;
if (param[i])
var len2 = param[i].length;
majorUpdate = Math.abs(len1 - len2) >= 50;
}
cont[part] = param[i].trim();
if (!contentIsCool && param[i])
contentIsCool = true;
}
}
// if all story parts are null, return with error-message
if (!contentIsCool)
return (getError("textMissing"));
// check if the createtime is set in param
if (param.createtime) {
var ctime = tryEval("parseTimestamp(param.createtime, \"yyyy-MM-dd HH:mm\")");
if (ctime.error)
return (getError("timestampParse",param.createtime));
}
// check name of topic (if specified)
var topicName = null;
if (param.topic)
topicName = param.topic;
else if (!isNaN(parseInt(param.topicidx,10)))
topicName = this.site.topics.get(parseInt(param.topicidx,10)).groupname;
if (topicName && !isCleanForURL(topicName)) {
// name of topic contains forbidden characters, so return immediatly
return (getError("topicNoSpecialChars"));
}
// check new online-status of story
var newStatus = parseInt(param.online,10);
if ((param.publish || param.submit == "publish") && isNaN(newStatus))
newStatus = parseInt(param.onlinedefault,10);
else if (param.save || param.submit == "save")
newStatus = 0;
if (isNaN(newStatus))
return (getError("storyPublish"));
if (newStatus == 1 && !topicName)
return (getError("storyTopicMissing"));
// since we came down here we store the new values of the story
if (newStatus > 0 && (!this.online || majorUpdate))
this.site.lastupdate = new Date();
this.online = newStatus;
if (majorUpdate)
this.modifytime = new Date();
this.setContent (cont);
// let's keep the title property
this.title = param.content_title;
if (ctime && ctime.value != this.createtime) {
this.createtime = ctime.value;
// create day of story with respect to site-timezone
this.day = formatTimestamp(this.createtime,"yyyyMMdd");
}
if (modifier == this.creator)
this.editableby = !isNaN(param.editableby) ? parseInt(param.editableby,10) : null;
this.discussions = (param.discussions_array || param.discussions == null ? 1 : 0);
this.modifier = modifier;
this.ipaddress = param.http_remotehost;
this.topic = topicName;
this.cache.modifytime = new Date();
var result = getConfirm("storyUpdate");
result.url = this.online > 0 ? this.href() : this.site.stories.href();
return (result);
}
/**
* function sets story either online or offline
*/
function toggleOnline(newStatus) {
if (newStatus == "online") {
this.online = 2;
this.site.lastupdate = new Date();
} else if (newStatus == "offline")
this.online = 0;
return true;
}
/**
* function evaluates comment and adds it if ok
* @param Obj Object containing properties needed for creation of comment
* @param Obj Story-Object
* @param Obj User-Object (creator of comment)
* @return Obj Object containing two properties:
* - error (boolean): true if error happened, false if everything went fine
* - message (String): containing a message to user
*/
function evalComment(param,story,creator) {
var result;
if (!param.content_text) {
result = getError("textMissing");
} else {
var c = new comment();
var cont = new HopObject ();
for (var i in param) {
if (i.indexOf ("content_") == 0)
cont[i.substring(8)] = param[i].trim();
}
c.setContent (cont);
// let's keep the title property:
c.title = param.content_title;
c.site = this.site;
c.story = story;
c.createtime = c.modifytime = new Date();
c.creator = creator;
c.online = 1;
c.editableby = null;
c.ipaddress = param.http_remotehost;
this.add(c);
// also add to story.comments since it has
// cachemode set to aggressive and wouldn't refetch
// its child collection index otherwise
if (this._prototype == "story")
this.comments.add(c);
else
this.story.comments.add(c);
this.site.lastupdate = new Date();
result = getConfirm("commentCreate");
}
return (result);
}
/**
* function deletes a whole thread
* @param Obj Comment-Object that should be deleted
* @return String Message indicating success/failure
*/
function deleteComment(currComment) {
for (var i=currComment.size();i>0;i--)
this.deleteComment(currComment.get(i-1));
// also remove from comment's parent since it has
// cachemode set to aggressive and wouldn't refetch
// its child collection index otherwise
var p = currComment.parent;
if (p == null)
p = currComment.story;
if (p.remove(currComment) && this.comments.remove(currComment))
return(getMessage("confirm","commentDelete"));
else
return(getMessage("error","commentDelete"));
}
/**
* function checks if the text of the story was already cached
* and if it's still valid
* if false, it caches it again
* @return String cached text of story
*/
function getRenderedContentPart (name) {
var partLastRendered = this.cache["lastRendered_"+name];
if (partLastRendered <= this.modifytime ||
partLastRendered <= this.cache.modifytime) {
// enable caching; some macros (eg. poll, storylist)
// will set this to false to prevent caching of a contentpart
// containing them [rg]
req.data.cachePart = true;
// cached version of text is too old, so we cache it again
var part = this.getContentPart (name);
if (!part)
return "";
var s = createSkin(format(part));
this.allowTextMacros(s);
this.cache["rendered_"+name] = activateLinks(this.renderSkinAsString(s));
if (req.data.cachePart)
this.cache["lastRendered_"+name] = new Date();
}
return (this.cache["rendered_"+name]);
}
/**
* Get a content part by name.
*/
function getContentPart (name) {
// check if this is a story with the old property layout. If so, convert to new.
if (this.text && !this.content) {
this.convertContentToXML();
}
var cnt = this.getContent();
return cnt[name];
}
/**
* Set a content part to a new value.
*/
function setContentPart (name, value) {
var cnt = this.getContent();
cnt[name] = value.trim();
this.setContent (cnt);
}
/**
* Return the content parsed into a HopObject.
*/
function getContent () {
if (!this.content)
return new HopObject ();
return Xml.readFromString (this.content);
}
/**
* Set the content of this story object.
*/
function setContent (cnt) {
this.content = Xml.writeToString (cnt);
var raw = new java.lang.StringBuffer();
for (var i in cnt) {
raw.append(cnt[i]);
raw.append(" ");
}
this.rawcontent = raw.toString().toLowerCase();
}
/**
* function deletes all childobjects of a story (recursive!)
*/
function deleteAll() {
for (var i=this.comments.size();i>0;i--) {
var c = this.comments.get(i-1);
this.comments.remove(c);
}
return true;
}
/**
* Function to convert old story content to new XML encoded format.
*/
function convertContentToXML () {
var cnt = new HopObject();
var raw = "";
if (this.title) {
cnt.title = this.title;
raw += this.title+" ";
}
if (this.text) {
cnt.text = this.text;
raw += this.text;
}
this.content = Xml.writeToString (cnt);
this.rawcontent = raw;
}
/**
* function records the access to a story-object
* by incrementing the counter of the Object representing
* this story in app.data.readLog which will be stored
* in database by scheduler
*/
function incrementReadCounter() {
// check if app.data.readLog already contains
// an Object representing this story
if (!app.data.readLog.containsKey(String(this._id))) {
var logObj = new Object();
logObj.site = this.site.alias;
logObj.story = this._id;
logObj.reads = this.reads + 1;
app.data.readLog.put(String(this._id),logObj);
} else
app.data.readLog.get(String(this._id)).reads++;
return;
}
/**
* Return either the title of the story or
* the id prefixed with standard display name
* to be used in the global linkedpath macro
* @see hopobject.getNavigationName()
*/
function getNavigationName () {
if (this.title)
return this.title;
return (DISPLAY["story"] + " " + this._id);
}