- added paged results lib methods

- cleanup for blogs, comments and discussions API
- deleting a forum reply post now changes the content to "removed" instead of deleting the node
- fix for comment deletion and archive filter in client side javascript

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@9612 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Michael Ru
2008-07-01 13:44:33 +00:00
parent 0c4683657d
commit 310d127f36
32 changed files with 984 additions and 1134 deletions

View File

@@ -1,8 +1,10 @@
/** Name of the blog details aspect. */
const BLOG_DETAILS_ASPECT = "blg:blogDetails"; const BLOG_DETAILS_ASPECT = "blg:blogDetails";
/** /**
* Fetches the blog properties from the json object and adds them to the array. * Fetches the blog properties from the json object and adds them to an array
* using the correct property names as indexes.
*/ */
function getBlogPropertiesArray() function getBlogPropertiesArray()
{ {
@@ -39,50 +41,9 @@ function getBlogPropertiesArray()
} }
/** /**
* Returns the data of a blog post. * Returns the data object of a blog node.
*/ */
function getBlogData(node) function getBlogData(node)
{ {
return node; return node;
} }
/**
* Returns an array containing all topics found in the passed array.
* Filters out non-fm:topic nodes.
*/
function getBlogListData(nodes, index, count)
{
var items = new Array();
var i;
var added = 0;
for (i = index; i < nodes.length && added < count; i++)
{
items.push(getBlogData(nodes[i]));
added++;
}
return ({
"total" : nodes.length,
"pageSize" : count,
"startIndex" : index,
"itemCount" : items.length,
"items": items
});
}
/**
* Returns a list of topics, as returned by the lucene query
*/
function getBlogsListByLuceneQuery(node, luceneQuery, sortAttribute, ascending, index, count)
{
var nodes = null;
if (sortAttribute != null)
{
nodes = search.luceneSearch(node.nodeRef.storeRef.toString(), luceneQuery, sortAttribute, ascending);
}
else
{
nodes = search.luceneSearch(luceneQuery);
}
return getBlogListData(nodes, index, count);
}

View File

@@ -9,9 +9,7 @@ function main()
return; return;
} }
model.item = node; model.item = getBlogData(node);
// process additional parameters
} }
main(); main();

View File

@@ -34,10 +34,10 @@ function main()
return; return;
} }
// update // update blog
updateBlog(node); updateBlog(node);
model.item = node; model.item = getBlogData(node);
} }
main(); main();

View File

@@ -1,34 +1,4 @@
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/comments/comments.lib.js">
const DRAFT_FOLDER_NAME = "Drafts";
/**
* Returns the draft folder.
*/
function getOrCreateDraftsFolder(node)
{
var draftFolder = node.childByNamePath(DRAFT_FOLDER_NAME);
if (draftFolder == null)
{
draftFolder = node.createNode(DRAFT_FOLDER_NAME, "cm:folder");
}
return draftFolder;
}
function getCommentsCount(node)
{
// check whether there are comments
// PENDING: this should use the comments API
if (node.hasAspect("fm:discussable"))
{
var forumNode = node.childAssocs["fm:discussion"][0];
var topicNode = forumNode.childAssocs["cm:contains"][0];
return topicNode.childAssocs["cm:contains"].length
}
else
{
return 0;
}
}
/** /**
* Returns the data of a blog post. * Returns the data of a blog post.
@@ -64,53 +34,3 @@ function getBlogPostData(node)
return data; return data;
} }
/**
* Returns the data of a blog post.
*/
/*function getBlogPostData(node)
{
return node;
}*/
/**
* Returns an array containing all topics found in the passed array.
* Filters out non-fm:topic nodes.
*/
function getBlogPostListData(nodes, index, count)
{
var items = new Array();
var i;
var added = 0;
for (i = index; i < nodes.length && added < count; i++)
{
items.push(getBlogPostData(nodes[i]));
added++;
}
return ({
"total" : nodes.length,
"pageSize" : count,
"startIndex" : index,
"itemCount" : items.length,
"items": items
});
}
/**
* Returns a list of topics, as returned by the lucene query
*/
function getBlogPostListByLuceneQuery(node, luceneQuery, sortAttribute, ascending, index, count)
{
var nodes = null;
if (sortAttribute != null)
{
nodes = search.luceneSearch(node.nodeRef.storeRef.toString(), luceneQuery, sortAttribute, ascending);
}
else
{
nodes = search.luceneSearch(luceneQuery);
}
return getBlogPostListData(nodes, index, count);
}

View File

@@ -1,22 +1,24 @@
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/requestutils.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/requestutils.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/blogs/blogpost.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/blogs/blogpost.lib.js">
var POST_ACTION = "publish"; const POST_ACTION = "publish";
var UPDATE_ACTION = "update"; const UPDATE_ACTION = "update";
var REMOVE_ACTION = "unpublish"; const REMOVE_ACTION = "unpublish";
function executeAction(node, action) /**
* Validates the action to execute.
* @return the action name to be used for the blog-post action or null if the specified action is invalid
*/
function validateAction(node, action)
{ {
var blogAction = ""; var blogAction = null;
var isPublished = false; var isPublished = false;
if ((node.hasAspect("blg:blogPost")) && (node.properties["blg:published"] == true)) if ((node.hasAspect("blg:blogPost")) && (node.properties["blg:published"] == true))
{ {
isPublished = true; isPublished = true;
} }
// make sure we have a real JavaScript object, otherwise switch won't work correctly
// make sure we have a real JavaScript object,
// otherwise switch won't work correctly
action = "" + action; action = "" + action;
switch (action) switch (action)
{ {
@@ -31,19 +33,34 @@ function executeAction(node, action)
break; break;
} }
if (blogAction != "") if (blogAction === null)
{
// set an error status
status.setCode(status.STATUS_BAD_REQUEST, "Invalid action specified (node in wrong state?)");
return null;
}
else
{
return blogAction;
}
}
/**
* Publishe, update or removes the blog from/to the external blog
*/
function executeAction(node, action)
{
// get the blog action to call (the names differ from the constants defined above)
var blogAction = validateAction(node, action);
if (blogAction != null)
{ {
var blog = actions.create("blog-post"); var blog = actions.create("blog-post");
blog.parameters.action = blogAction; blog.parameters.action = blogAction;
blog.execute(node); blog.execute(node);
result = blog.parameters["result"];
logger.log("Blog action result: " + result);
model.message = result;
/* Check whether action succeeded
if (result != "sfsdf")
{
}*/ // PENDING: how do we know that the action succeeded?
model.result = blog.parameters["result"];
logger.log("Blog action result: " + result);
} }
} }
@@ -59,6 +76,8 @@ function main()
// fetch and execute the action // fetch and execute the action
var action = json.get("action"); var action = json.get("action");
executeAction(node, action); executeAction(node, action);
// get the updated data for the blog post
model.item = getBlogPostData(node); model.item = getBlogPostData(node);
} }

View File

@@ -1,21 +1,19 @@
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/requestutils.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/requestutils.lib.js">
/** /**
* Deletes a topic node. * Deletes a blog post node.
*/ */
function deletePost(postNode) function deleteBlogPost(postNode)
{ {
// we simply delete the topic // delete the node
var qnamePath = postNode.qnamePath; var nodeRef = postNode.nodeRef;
logger.log("Deleting node " + qnamePath);
var isDeleted = postNode.remove(); var isDeleted = postNode.remove();
logger.log("Node deleted: " + isDeleted);
if (! isDeleted) if (! isDeleted)
{ {
status.setCode(status.STATUS_INTERNAL_SERVER_ERROR, "Unable to delete node: " + qnamePath); status.setCode(status.STATUS_INTERNAL_SERVER_ERROR, "Unable to delete node: " + nodeRef);
return; return;
} }
model.message = "Node " + qnamePath + " deleted"; model.message = "Node " + nodeRef + " deleted";
} }
function main() function main()
@@ -27,7 +25,7 @@ function main()
return; return;
} }
deletePost(node); deleteBlogPost(node);
} }
main(); main();

View File

@@ -10,11 +10,8 @@ function main()
return; return;
} }
// PENDING: type check?
// assign data // assign data
model.item = getBlogPostData(node); model.item = getBlogPostData(node);
model.contentFormat = (args["contentFormat"] != undefined) ? args["contentFormat"] : "full"; model.contentFormat = (args["contentFormat"] != undefined) ? args["contentFormat"] : "full";
} }

View File

@@ -2,15 +2,11 @@
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/blogs/blogpost.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/blogs/blogpost.lib.js">
/** /**
* Creates a post inside the passed forum node. * Updates a blog post node
*/ */
function updatePost(postNode) function updateBlogPost(postNode)
{ {
/*var name = ""; // fetch the new data
if (json.has("name"))
{
title = json.get("name");
}*/
var title = ""; var title = "";
if (json.has("title")) if (json.has("title"))
{ {
@@ -18,23 +14,18 @@ function updatePost(postNode)
} }
var content = json.get("content"); var content = json.get("content");
// update the topic title // update the node
postNode.properties.title = title; postNode.properties.title = title;
postNode.mimetype = "text/html"; postNode.mimetype = "text/html";
postNode.content = content; postNode.content = content;
postNode.save(); postNode.save();
// PENDING:
// check whether it is draft mode // check whether it is draft mode
/*if (postNode.hasAspect("cm:workingcopy") && json.get("draft") == "false") /*if (postNode.hasAspect("cm:workingcopy") && json.get("draft") == "false")
{ {
postNode.removeAspect("cm:workingcopy"); postNode.removeAspect("cm:workingcopy");
}*/ }*/
// try to change the file name
/*if (name.length > 0)
{
postNode.name = name;
}*/
} }
function main() function main()
@@ -46,8 +37,8 @@ function main()
return; return;
} }
// update // update blog post
updatePost(node); updateBlogPost(node);
model.item = getBlogPostData(node); model.item = getBlogPostData(node);
} }

View File

@@ -1,25 +1,27 @@
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/requestutils.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/requestutils.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/blogs/blogpost.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/blogs/blogpost.lib.js">
/**
* Returns the date representing the begin of a month (the first day at 00:00:00)
*/
function getBeginOfMonthDate(date) function getBeginOfMonthDate(date)
{ {
return new Date(date.getFullYear(), date.getMonth(), 1); return new Date(date.getFullYear(), date.getMonth(), 1);
} }
/**
* Returns the date representing the last second of a month (23:59:59)
*/
function getEndOfMonthDate(date) function getEndOfMonthDate(date)
{ {
var year = date.getFullYear(); var year = date.getFullYear();
var month = date.getMonth(); var month = date.getMonth();
var beginOfNextMonth = new Date(year, month + 1, 1); // will increment year by 1 if month > 11 var beginOfNextMonth = new Date(year, month + 1, 1); // will increment year if month > 11
return new Date(beginOfNextMonth.getTime() - 1); return new Date(beginOfNextMonth.getTime() - 1); // one less to get the last millisecond of the previous day
} }
/** /**
* Creates an object containing information about the month. * Create an object containing information about the month specified by date.
* This object holds all the data returned.
*/ */
function getMonthDataObject(date) function getMonthDataObject(date)
{ {
@@ -28,15 +30,15 @@ function getMonthDataObject(date)
data.month = date.getMonth(); data.month = date.getMonth();
data.firstPostInMonth = date; data.firstPostInMonth = date;
data.beginOfMonth = getBeginOfMonthDate(date); data.beginOfMonth = getBeginOfMonthDate(date);
data.beginOfMonthMillis = data.beginOfMonth.getTime();
data.endOfMonth = getEndOfMonthDate(date); data.endOfMonth = getEndOfMonthDate(date);
data.endOfMonthMillis = data.endOfMonth.getTime();
data.count = 1; data.count = 1;
return data; return data;
} }
/** /**
* Fetches all posts found in the forum. * Fetches data for each month for which posts exist, plus the count of each.
* Note: If no posts could be found, this method will return the current month
* but with a count of posts equals zero.
*/ */
function getBlogPostMonths(node) function getBlogPostMonths(node)
{ {
@@ -46,31 +48,41 @@ function getBlogPostMonths(node)
var sortAttribute = "@{http://www.alfresco.org/model/content/1.0}created"; var sortAttribute = "@{http://www.alfresco.org/model/content/1.0}created";
nodes = search.luceneSearch(node.nodeRef.storeRef.toString(), luceneQuery, sortAttribute, true); nodes = search.luceneSearch(node.nodeRef.storeRef.toString(), luceneQuery, sortAttribute, true);
// fetch all dates with different month and year. Throw away doubles. // will hold the months information
var data = new Array(); var data = new Array();
if (nodes.length > 0) { // do we have posts?
var curr = nodes[0].properties["cm:created"]; if (nodes.length > 0)
var currData = getMonthDataObject(curr); {
data.push(currData); var currYear = -1;
var currMonth = -1;
for (var x=1; x < nodes.length; x++) var currData = null;
for (var x=0; x < nodes.length; x++)
{ {
var date = nodes[x].properties["cm:created"]; var date = nodes[x].properties["cm:created"];
// check whether we are in a new month
if (curr.getFullYear() != date.getFullYear() || curr.getMonth() != date.getMonth()) // is this a new month?
if (currYear != date.getFullYear() || currMonth != date.getMonth())
{ {
curr = node; currYear = date.getFullYear();
currData = getMonthDataObject(curr); currMonth = date.getMonth();
currData = getMonthDataObject(date);
data.push(currData); data.push(currData);
} }
// or still the same one // otherwise just increment the counter
else else
{ {
currData.count += 1; currData.count += 1;
} }
} }
} }
// if not, add the current month with count = 0
else
{
var emptyData = getMonthdataObject(new Date());
emptyData.count = 0;
data.push(emptyData);
}
return data; return data;
} }

View File

@@ -1,9 +1,10 @@
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/requestutils.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/requestutils.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/searchutils.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/searchutils.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/generic-paged-results.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/blogs/blogpost.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/blogs/blogpost.lib.js">
/** /**
* Fetches all posts found in the forum. * Fetches all posts of the given blog
*/ */
function getBlogPostList(node, fromDate, toDate, index, count) function getBlogPostList(node, fromDate, toDate, index, count)
{ {
@@ -19,7 +20,7 @@ function getBlogPostList(node, fromDate, toDate, index, count)
var sortAttribute = "@{http://www.alfresco.org/model/content/1.0}created"; var sortAttribute = "@{http://www.alfresco.org/model/content/1.0}created";
// get the data // get the data
return getBlogPostListByLuceneQuery(node, luceneQuery, sortAttribute, false, index, count); return getPagedResultsDataByLuceneQuery(node, luceneQuery, sortAttribute, false, index, count, getBlogPostData);
} }
function main() function main()
@@ -55,8 +56,8 @@ function main()
} }
} }
// fetch and assign the data
model.data = getBlogPostList(node, fromDate, toDate, index, count); model.data = getBlogPostList(node, fromDate, toDate, index, count);
model.contentFormat = (args["contentFormat"] != undefined) ? args["contentFormat"] : "full"; model.contentFormat = (args["contentFormat"] != undefined) ? args["contentFormat"] : "full";
} }

View File

@@ -3,14 +3,13 @@
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/blogs/blogpost.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/blogs/blogpost.lib.js">
/** /**
* Creates a post inside the passed forum node. * Creates a blog post
*/ */
function createBlogPost(blogNode) function createBlogPost(blogNode)
{ {
// fetch the data required to create a topic // fetch the data required to create the post
var title = json.get("title"); var title = json.get("title");
var content = json.get("content"); var content = json.get("content");
logger.log("Creating new blog post " + title + " with text " + content);
// get a unique name // get a unique name
var name = getUniqueChildName(blogNode, "post"); var name = getUniqueChildName(blogNode, "post");

View File

@@ -2,25 +2,20 @@
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/comments/comments.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/comments/comments.lib.js">
/** /**
* Deletes a topic node. * Delete a comment.
*/ */
function deleteComment(node) function deleteComment(node)
{ {
// we simply delete the topic // we simply delete the topic
var qnamePath = node.qnamePath; var nodeRef = node.nodeRef;
logger.log("Deleting node " + qnamePath);
var isDeleted = node.remove(); var isDeleted = node.remove();
logger.log("Node deleted: " + isDeleted);
if (! isDeleted) if (! isDeleted)
{ {
status.setCode(status.STATUS_INTERNAL_SERVER_ERROR, "Unable to delete node: " + qnamePath); status.setCode(status.STATUS_INTERNAL_SERVER_ERROR, "Unable to delete node: " + nodeRef);
return; return;
} }
// also remove the discussable aspect if there are no more comments model.message = "Node " + nodeRef + " deleted";
deleteCommentsFolder(node);
model.message = "Node " + qnamePath + " deleted";
} }
function main() function main()

View File

@@ -10,9 +10,7 @@ function main()
return; return;
} }
model.item = node; model.item = getCommentData(node);
// process additional parameters
} }
main(); main();

View File

@@ -2,19 +2,19 @@
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/comments/comments.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/comments/comments.lib.js">
/** /**
* Creates a post inside the passed forum node. * Update a comment
*/ */
function updateComment(node) function updateComment(node)
{ {
/*var title = ""; var title = "";
if (json.has("title")) if (json.has("title"))
{ {
title = json.get("title"); title = json.get("title");
}*/ }
var content = json.get("content"); var content = json.get("content");
// update the topic title // update the topic title
//postNode.properties.title = title; node.properties.title = title;
node.mimetype = "text/html"; node.mimetype = "text/html";
node.content = content; node.content = content;
node.save(); node.save();
@@ -29,10 +29,10 @@ function main()
return; return;
} }
// update // update comment
updateComment(node); updateComment(node);
model.item = node; model.item = getCommentData(node);
} }
main(); main();

View File

@@ -1,23 +1,15 @@
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/requestutils.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/requestutils.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/generic-paged-results.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/comments/comments.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/comments/comments.lib.js">
/** /**
* Fetches all posts found in the forum. * Get all comments for a node
*/ */
function getCommentsList(node, index, count) function getCommentsList(node, index, count)
{ {
var nodes = new Array(); var nodes = getComments(node);
// comments are added through a custom child association ("cm:comments") that links to a cm:folder that holds all the comment files return getPagedResultsData(nodes, index, count, getCommentData);
var commentFolder = getCommentsFolder(node);
if (commentFolder != null)
{
nodes = commentFolder.childAssocs["cm:contains"];
}
return getCommentListData(nodes, index, count);
} }
function main() function main()

View File

@@ -1,17 +1,38 @@
/** Name used for the topic that contains all comments. */
const COMMENTS_TOPIC_NAME = "Comments";
/**
* Returns all comment nodes for a given node.
* @return an array of comments.
*/
function getComments(node)
{
var commentsFolder = getCommentsFolder(node);
if (commentsFolder != null)
{
var elems = commentsFolder.childAssocs["cm:contains"];
if (elems != null)
{
return elems;
}
}
// no comments found, return an empty array
return new Array();
}
/** /**
* Returns the folder that contains all the comments. * Returns the folder that contains all the comments.
* We currently use the forum model for testing purpose *
* PENDING: use a proper model! * We currently use the fm:discussable aspect where we
* add a "Comments" topic to it.
*/ */
function getCommentsFolder(node) function getCommentsFolder(node)
{ {
if (node.hasAspect("fm:discussable")) if (node.hasAspect("fm:discussable"))
{ {
var forumFolder = node.childAssocs["fm:discussion"][0]; var forumFolder = node.childAssocs["fm:discussion"][0];
// we simply take the first topic folder in it var topicFolder = forumFolder.childByNamePath(COMMENTS_TOPIC_NAME);
// PENDING: this is error prone!
var topicFolder = forumFolder.childAssocs["cm:contains"][0];
return topicFolder; return topicFolder;
} }
else else
@@ -31,69 +52,25 @@ function getOrCreateCommentsFolder(node)
return commentsFolder; return commentsFolder;
} }
// add the aspect and create the forum as well as the comments topic
node.addAspect("fm:discussable"); node.addAspect("fm:discussable");
var forumNode = node.createNode("Comments Forum", "fm:forum", "fm:discussion"); var forumNode = node.createNode("Forum", "fm:forum", "fm:discussion");
commentsFolder = forumNode.createNode("Comments", "fm:topic", "cm:contains"); commentsFolder = forumNode.createNode(COMMENTS_TOPIC_NAME, "fm:topic", "cm:contains");
return commentsFolder; return commentsFolder;
} }
/** /**
* Deletes the comments folder for a node if there are no comments in it. * Returns the data object for a comment node
*/ */
function deleteCommentsFolder(node)
{
var commentsFolder = getCommentFolder(node);
if (commentsFolder != null && commentsFolder.childAssocs["cm:contains"] == 0)
{
var forumFolder = node.childAssocs["fm:discussion"][0];
node.removeNode(forumNode);
node.removeAspect("fm:discussable");
}
}
function getCommentData(node) function getCommentData(node)
{ {
return node; return node;
} }
/** /**
* Returns an array containing all topics found in the passed array. * Returns the count of comments for a node.
* Filters out non-fm:topic nodes.
*/ */
function getCommentListData(nodes, index, count) function getCommentsCount(node)
{ {
var items = new Array(); return getComments(node).length;
var i;
var added = 0;
for (i = index; i < nodes.length && added < count; i++)
{
items.push(getCommentData(nodes[i]));
added++;
}
return ({
"total" : nodes.length,
"pageSize" : count,
"startIndex" : index,
"itemCount" : items.length,
"items": items
});
} }
/**
* Returns a list of topics, as returned by the lucene query
*/
/*function getBlogsListByLuceneQuery(node, luceneQuery, sortAttribute, ascending, index, count)
{
var nodes = null;
if (sortAttribute != null)
{
nodes = search.luceneSearch(node.nodeRef.storeRef.toString(), luceneQuery, sortAttribute, ascending);
}
else
{
nodes = search.luceneSearch(luceneQuery);
}
return getBlogListData(nodes, index, count);
}*/

View File

@@ -8,19 +8,23 @@
function addComment(node) function addComment(node)
{ {
// fetch the data required to create a comment // fetch the data required to create a comment
//var title = json.get("title"); var title = "";
if (json.has("title"))
{
title = json.get("title");
}
var content = json.get("content"); var content = json.get("content");
logger.log("Creating new comment with text " + content);
// fetch the parent to add the node to
var commentsFolder = getOrCreateCommentsFolder(node); var commentsFolder = getOrCreateCommentsFolder(node);
// get a unique name // get a unique name
var name = getUniqueChildName(commentsFolder, "comment"); var name = getUniqueChildName(commentsFolder, "comment");
// we simply create a new file inside the blog folder // create the comment
var commentNode = commentsFolder.createNode(name, "fm:post"); var commentNode = commentsFolder.createNode(name, "fm:post");
commentNode.mimetype = "text/html"; commentNode.mimetype = "text/html";
//commentNode.properties.title = title; commentNode.properties.title = title;
commentNode.content = content; commentNode.content = content;
commentNode.save(); commentNode.save();
@@ -37,7 +41,7 @@ function main()
} }
var comment = addComment(node); var comment = addComment(node);
model.item = comment; model.item = getCommentData(comment);
} }
main(); main();

View File

@@ -1,69 +1,83 @@
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/requestutils.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/requestutils.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/generic-paged-results.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/discussions/topicpost.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/discussions/topicpost.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/discussions/forum/forum-posts.lib.js">
/** var MAX_NUM_OF_PROCESSED_POSTS = 20;
* Prepends a number with zeros to make it a 4numgth string
*/
function toFourDigitString(num)
{
if (num < 10) return "000" + num;
if (num < 100) return "00" + num;
if (num < 1000) return "0" + num;
return "" + num;
}
/** /**
* Fetches the hot topics found in the forum. * Fetches the hot topics found in the forum.
* Hot topics are the one with the most replies recently. * Hot topics are topics with the most replies over the last x days.
* *
* We implement this follows: We fetch all posts in the forum, ordered by inverse * The current implementation fetches all posts in the forum ordered by inverse
* creation date and fetch the nodes for the first 20 posts * creation date. It then analyzes the last x posts and fetches the topics thereof,
* keeping track of the number of posts for each.
*
* Note: We only look at topics with replies, the others will therefore not show up
* in that list.
*/ */
function getHotTopicPostList(node, index, count) function getHotTopicPostList(node, index, count)
{ {
// get the posts to check
var luceneQuery = " +TYPE:\"{http://www.alfresco.org/model/forum/1.0}post\"" + var luceneQuery = " +TYPE:\"{http://www.alfresco.org/model/forum/1.0}post\"" +
" +PATH:\"" + node.qnamePath + "/*/*\"" + " +PATH:\"" + node.qnamePath + "/*/*\"" +
" +ASPECT:\"cm:referencing\""; " +ASPECT:\"cm:referencing\"";
var sortAttribute = "@{http://www.alfresco.org/model/content/1.0}created"; var sortAttribute = "@{http://www.alfresco.org/model/content/1.0}created";
posts = search.luceneSearch(node.nodeRef.storeRef.toString(), luceneQuery, sortAttribute, false); var posts = search.luceneSearch(node.nodeRef.storeRef.toString(), luceneQuery, sortAttribute, false);
/** Implement sort and order logic to show the node with most replies first. */ // check how many posts we check in the result set
// PENDING: quick and dirty version, works but needs cleanup! var max = MAX_NUM_OF_PROCESSED_POSTS;
var max = 20; // only process so many posts if (posts.length < max)
if (posts.length < max) max = posts.length; {
max = posts.length;
var idToNode = new Array(); }
var idToCount = new Array();
// get for each the topic, keeping track of the number of replies and the first occurance
// of the post.
var idToData = {};
for (var x=0; x < max; x++) for (var x=0; x < max; x++)
{ {
// get the topic node (which is the direct parent of the post)
var parent = posts[x].parent; var parent = posts[x].parent;
var id = parent.nodeRef.id; var id = parent.nodeRef.id;
if (idToCount[id] != null) { if (idToData[id] != null) {
idToCount[id] = idToCount[id] + 1; idToData[id].count += 1;
} else { } else {
idToNode[id] = parent; idToData[id] = { count: 1, pos: x, node: parent};
idToCount[id] = 1;
} }
} }
// get the list sorted by number of replies // copy the elements to an array as we will have to sort it
var tmp = new Array(); // afterwards
for (var id in idToCount) { var dataArr = new Array();
tmp.push(toFourDigitString(idToCount[id]) + id); for (n in idToData)
}
tmp.sort();
tmp.reverse();
var nodes = Array();
for (var x=0; x < tmp.length; x++)
{ {
nodes.push(idToNode[tmp[x].substring(4)]); dataArr.push(idToData[n]);
} }
// get the data // sort the elements by number of replies, then by the position
return getTopicPostListData(nodes, index, count); var sorter = function(a, b)
{
if (a.count != b.count)
{
// more replies first
return b.count - a.count
}
else {
// lower pos first
return a.pos - b.pos;
}
}
dataArr.sort(sorter);
// extract now the nodes
var nodes = Array();
for (var x=0; x < dataArr.length; x++)
{
nodes.push(dataArr[x].node);
}
// get the paginated data
return getPagedResultsData(nodes, index, count, getTopicPostData);
} }
function main() function main()

View File

@@ -1,32 +1,17 @@
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/requestutils.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/requestutils.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/generic-paged-results.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/discussions/topicpost.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/discussions/topicpost.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/discussions/forum/forum-posts.lib.js">
function getLatestAddedPostData(node)
function getLatestAddedPostsListData(nodes, index, count)
{ {
var items = new Array();
var i;
var added = 0;
for (i = index; i < nodes.length && added < count; i++)
{
// fetch the topic post data and then add the node as reply. // fetch the topic post data and then add the node as reply.
// in case of a new topicpost, the reply and the post will be the // in case of a new topic post, the reply and the post will be the
// same, otherwise they differ. The topic post will be used to fetch // same, otherwise they differ. The topic post will be used to fetch
// the topic title, while the reply will be used to show the text // the topic title, while the reply will be used to show the text
var data = getTopicPostData(nodes[i].parent); var data = getTopicPostData(node.parent);
data.reply = nodes[i]; data.reply = node;
items.push(data); data.isRootPost = data.post.nodeRef == data.reply.nodeRef;
added++; return data;
}
return ({
"total" : nodes.length,
"pageSize" : count,
"startIndex" : index,
"itemCount" : items.length,
"items": items
});
} }
/** /**
@@ -37,10 +22,9 @@ function getLatestAddedPosts(node, index, count)
var luceneQuery = " +TYPE:\"{http://www.alfresco.org/model/forum/1.0}post\"" + var luceneQuery = " +TYPE:\"{http://www.alfresco.org/model/forum/1.0}post\"" +
" +PATH:\"" + node.qnamePath + "/*/*\""; " +PATH:\"" + node.qnamePath + "/*/*\"";
var sortAttribute = "@{http://www.alfresco.org/model/content/1.0}created"; var sortAttribute = "@{http://www.alfresco.org/model/content/1.0}created";
nodes = search.luceneSearch(node.nodeRef.storeRef.toString(), luceneQuery, sortAttribute, false);
// get the data // get the data
return getLatestAddedPostsListData(nodes, index, count); return getPagedResultsDataByLuceneQuery(node, luceneQuery, sortAttribute, false, index, count, getLatestAddedPostData);
} }
function main() function main()
@@ -63,4 +47,3 @@ function main()
} }
main(); main();
var x = 0;

View File

@@ -4,6 +4,7 @@
<#macro latestPostJSON item> <#macro latestPostJSON item>
{ {
"topicTitle" : "${item.post.properties.title?js_string}", "topicTitle" : "${item.post.properties.title?js_string}",
"isRootPost" : ${item.isRootPost?string},
<@postLib.postDataJSON refNode=item.topic post=item.reply /> <@postLib.postDataJSON refNode=item.topic post=item.reply />
} }
</#macro> </#macro>

View File

@@ -1,11 +1,12 @@
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/requestutils.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/requestutils.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/searchutils.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/searchutils.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/generic-paged-results.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/discussions/topicpost.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/discussions/topicpost.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/discussions/forum/forum-posts.lib.js">
const DEFAULT_NUM_DAYS = 30;
/** /**
* Returns the date object for the NOW - numdays days in the past * Returns the date object for the date "numdays" ago
*/ */
function getTodayMinusXDays(numdays) function getTodayMinusXDays(numdays)
{ {
@@ -17,7 +18,7 @@ function getTodayMinusXDays(numdays)
} }
/** /**
* Fetches all posts found in the forum. * Fetches all posts added to the forum in the last numdays days
*/ */
function getTopicPostList(node, numdays, index, count) function getTopicPostList(node, numdays, index, count)
{ {
@@ -30,7 +31,7 @@ function getTopicPostList(node, numdays, index, count)
var sortAttribute = "@{http://www.alfresco.org/model/content/1.0}created"; var sortAttribute = "@{http://www.alfresco.org/model/content/1.0}created";
// get the data // get the data
return getTopicPostListByLuceneQuery(node, luceneQuery, sortAttribute, false, index, count); return getPagedResultsDataByLuceneQuery(node, luceneQuery, sortAttribute, false, index, count, getTopicPostData);
} }
function main() function main()
@@ -45,8 +46,6 @@ function main()
// process additional parameters // process additional parameters
var index = args["startIndex"] != undefined ? parseInt(args["startIndex"]) : 0; var index = args["startIndex"] != undefined ? parseInt(args["startIndex"]) : 0;
var count = args["pageSize"] != undefined ? parseInt(args["pageSize"]) : 10; var count = args["pageSize"] != undefined ? parseInt(args["pageSize"]) : 10;
var DEFAULT_NUM_DAYS = 30;
var numdays = args["numdays"] != undefined ? parseInt(args["numdays"]) : DEFAULT_NUM_DAYS; var numdays = args["numdays"] != undefined ? parseInt(args["numdays"]) : DEFAULT_NUM_DAYS;
// fetch the data and assign it to the model // fetch the data and assign it to the model

View File

@@ -1,6 +1,6 @@
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/requestutils.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/requestutils.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/generic-paged-results.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/discussions/topicpost.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/discussions/topicpost.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/discussions/forum/forum-posts.lib.js">
/** /**
* Fetches all posts found in the forum. * Fetches all posts found in the forum.
@@ -13,7 +13,7 @@ function getTopicPostList(node, index, count)
var sortAttribute = "@{http://www.alfresco.org/model/content/1.0}created"; var sortAttribute = "@{http://www.alfresco.org/model/content/1.0}created";
// get the data // get the data
return getTopicPostListByLuceneQuery(node, luceneQuery, sortAttribute, false, index, count); return getPagedResultsDataByLuceneQuery(node, luceneQuery, sortAttribute, false, index, count, getTopicPostData);
} }
function main() function main()

View File

@@ -1,42 +0,0 @@
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/discussions/topicpost.lib.js">
/**
* Returns an array containing all topics found in the passed array.
* Filters out non-fm:topic nodes.
*/
function getTopicPostListData(nodes, index, count)
{
var items = new Array();
var i;
var added = 0;
for (i = index; i < nodes.length && added < count; i++)
{
items.push(getTopicPostData(nodes[i]));
added++;
}
return ({
"total" : nodes.length,
"pageSize" : count,
"startIndex" : index,
"itemCount" : items.length,
"items": items
});
}
/**
* Returns a list of topics, as returned by the lucene query
*/
function getTopicPostListByLuceneQuery(node, luceneQuery, sortAttribute, ascending, index, count)
{
var nodes = null;
if (sortAttribute != null)
{
nodes = search.luceneSearch(node.nodeRef.storeRef.toString(), luceneQuery, sortAttribute, ascending);
}
else
{
nodes = search.luceneSearch(luceneQuery);
}
return getTopicPostListData(nodes, index, count);
}

View File

@@ -3,17 +3,18 @@
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/discussions/topicpost.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/discussions/topicpost.lib.js">
/** /**
* Creates a post inside the passed forum node. * Adds a post to the passed forum node.
*/ */
function createPost(forumNode) function createPost(forumNode)
{ {
// fetch the data required to create a topic // fetch the data required to create a topic
var title = json.get("title"); var title = json.get("title");
var content = json.get("content"); var content = json.get("content");
logger.log("Creating New post " + title + " with text " + content);
// create the topic node, and add the first child node representing the topic text // create the topic node, and add the first child node representing the topic text
// NOTE: this is a change from the old web client, where the topic title was used as name for the node // NOTE: this is a change from the old web client, where the topic title was used as name
// for the topic node. We will use generated names to make sure we won't have naming
// clashes.
var name = getUniqueChildName(forumNode, "post"); var name = getUniqueChildName(forumNode, "post");
var topicNode = forumNode.createNode(name, "fm:topic"); var topicNode = forumNode.createNode(name, "fm:topic");
@@ -37,6 +38,7 @@ function main()
} }
var topicPost = createPost(node); var topicPost = createPost(node);
model.topicpost = getTopicPostData(topicPost); model.topicpost = getTopicPostData(topicPost);
} }

View File

@@ -2,7 +2,7 @@
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/discussions/topicpost.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/discussions/topicpost.lib.js">
/** /**
* Fetches the nodes that are children of post * Returns all reply nodes to a post
*/ */
function getRepliesForPost(post) function getRepliesForPost(post)
{ {
@@ -18,8 +18,9 @@ function getRepliesForPost(post)
} }
/** /**
* Fetches the reply node and the child count. * Returns a data object containing the passed post,
* Fetches the children in addition if levels > 1. * the number of replies to the post, as well as
* the replies themselves if levels > 1
*/ */
function getReplyDataRecursive(post, levels) function getReplyDataRecursive(post, levels)
{ {
@@ -40,6 +41,10 @@ function getReplyDataRecursive(post, levels)
return data; return data;
} }
/**
* Returns a data object containing all replies of a post.
* @return data object with "children" property that contains an array of reply data objects
*/
function getRepliesImpl(post, levels) function getRepliesImpl(post, levels)
{ {
var data = getReplyDataRecursive(post, levels + 1); var data = getReplyDataRecursive(post, levels + 1);
@@ -58,12 +63,13 @@ function getReplies(node, levels)
// we have to differentiate here whether this is a top-level post or a reply // we have to differentiate here whether this is a top-level post or a reply
if (node.type == "{http://www.alfresco.org/model/forum/1.0}topic") if (node.type == "{http://www.alfresco.org/model/forum/1.0}topic")
{ {
// find the primary post node // find the primary post node.
var data = getTopicPostData(node); // PENDING: couldn't this be done in a more performant way? var data = getTopicPostData(node);
return getRepliesImpl(data.post, levels); return getRepliesImpl(data.post, levels);
} }
else if (node.type == "{http://www.alfresco.org/model/forum/1.0}post") else if (node.type == "{http://www.alfresco.org/model/forum/1.0}post")
{ {
// the node is already a post
return getRepliesImpl(node, levels); return getRepliesImpl(node, levels);
} }
else else

View File

@@ -5,7 +5,7 @@
/** /**
* Creates a post inside the passed forum node. * Creates a post inside the passed forum node.
*/ */
function createReplyPost(topicNode, parentPostNode) function createPostReplyImpl(topicNode, parentPostNode)
{ {
// fetch the data required to create a topic // fetch the data required to create a topic
var title = ""; var title = "";
@@ -14,12 +14,9 @@ function createReplyPost(topicNode, parentPostNode)
title = json.get("title"); title = json.get("title");
} }
var content = json.get("content"); var content = json.get("content");
logger.log("Creating new post with title " + title + " and text " + content);
// create the topic node, and add the first child node representing the topic text // create the post node using a unique name
// NOTE: this is a change from the old web client, where the topic title was used as name for the node
var name = getUniqueChildName(topicNode, "post"); var name = getUniqueChildName(topicNode, "post");
var postNode = topicNode.createNode(name, "fm:post"); var postNode = topicNode.createNode(name, "fm:post");
postNode.mimetype = "text/html"; postNode.mimetype = "text/html";
postNode.properties.title = title; postNode.properties.title = title;
@@ -34,27 +31,31 @@ function createReplyPost(topicNode, parentPostNode)
return postNode; return postNode;
} }
/**
* Creates a reply to a post.
* @param node The parent post node
*/
function createPostReply(node) function createPostReply(node)
{ {
// we have to differentiate here whether this is a top-level post or a reply // we have to differentiate here whether this is a top-level post or a reply
if (node.type == "{http://www.alfresco.org/model/forum/1.0}topic") if (node.type == "{http://www.alfresco.org/model/forum/1.0}topic")
{ {
// find the primary post node // find the primary post node
var data = getTopicPostData(node); var topic = node;
var topic = data.topic; var post = findPostNode(node);
var post = data.post; return createPostReplyImpl(topic, post);
return createReplyPost(topic, post);
} }
else if (node.type == "{http://www.alfresco.org/model/forum/1.0}post") else if (node.type == "{http://www.alfresco.org/model/forum/1.0}post")
{ {
// the forum is the paren of the node // the forum is the parent of the node
var topic = node.parent; var topic = node.parent;
var post = node; var post = node;
return createReplyPost(topic, post); return createPostReplyImpl(topic, post);
} }
else else
{ {
status.setCode(STATUS_BAD_REQUEST, "Incompatible node type. Required either fm:topic or fm:post. Received: " + node.type); status.setCode(STATUS_BAD_REQUEST, "Incompatible node type. Required either fm:topic or fm:post. Received: " + node.type);
return null;
} }
} }

View File

@@ -1,61 +1,40 @@
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/requestutils.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/requestutils.lib.js">
const DELETED_REPLY_POST_MARKER = "[[deleted]]";
/** /**
* Deletes a topic node. * Deletes a topic node.
*/ */
function deleteTopicPost(topicNode) function deleteTopicPost(topicNode)
{ {
// we simply delete the topic // we simply delete the complete topic
var qnamePath = topicNode.qnamePath; var nodeRef = topicNode.nodeRef;
logger.log("Deleting node " + qnamePath);
var isDeleted = topicNode.remove(); var isDeleted = topicNode.remove();
logger.log("Node deleted: " + isDeleted);
if (! isDeleted) if (! isDeleted)
{ {
status.setCode(status.STATUS_INTERNAL_SERVER_ERROR, "Unable to delete node: " + qnamePath); status.setCode(status.STATUS_INTERNAL_SERVER_ERROR, "Unable to delete node: " + nodeRef);
return; return;
} }
model.message = "Node " + qnamePath + " deleted"; model.message = "Node " + nodeRef + " deleted";
}
function addRepliesOfPostRecursive(node, arr)
{
var replies = node.sourceAssocs["cm:references"];
if (replies != null)
{
var x;
for (x = 0; x < replies.length; x++)
{
addRepliesOfPostRecursive(replies[x], arr);
arr.push(replies[x]);
}
}
} }
/** /**
* Deletes a reply post. * Delete a reply post.
* Note: Because posts are recursive, we can't simply delete the node.
* For now we set a marker text [[delete]] as title and content.
*/ */
function deleteReplyPost(postNode) function deleteReplyPost(node)
{ {
// we have to delete the node as well as all replies var title = DELETED_REPLY_POST_MARKER;
// PENDING: what happens if the user has the right to delete its node var content = DELETED_REPLY_POST_MARKER;
// but not the replies to it?
var nodes = new Array();
addRepliesOfPostRecursive(postNode, nodes);
nodes.push(postNode);
var qnamePath = postNode.qnamePath // update the topic title
var isDeleted = false; node.properties.title = title;
for (x = 0; x < nodes.length; x++) node.mimetype = "text/html";
{ node.content = content;
isDeleted = nodes[x].remove(); node.save();
if (! isDeleted)
{ model.message = "Node " + node.nodeRef + " marked as removed";
status.setCode(status.STATUS_INTERNAL_SERVER_ERROR, "Unable to delete node: " + nodes[x].nodeRef);
return;
}
}
model.message = "Node " + qnamePath + " deleted";
} }
/** /**

View File

@@ -2,37 +2,9 @@
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/discussions/topicpost.lib.js"> <import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/discussions/topicpost.lib.js">
/** /**
* Returns the correct post node to update- * Updates the passed forum post node.
* This function makes sure that a post is returned in case the passed node is a topic.
*/ */
function findPostNode(node) function updatePost(node)
{
if (node.type == "{http://www.alfresco.org/model/forum/1.0}post")
{
return node;
}
else if (node.type == "{http://www.alfresco.org/model/forum/1.0}topic")
{
var nodes = getOrderedPosts(node);
if (nodes.length > 0)
{
return nodes[0];
}
else
{
status.setCode(status.STATUS_INTERNAL_SERVER_ERROR, "First post of topic node" + node.nodeRef + " missing");
}
}
else
{
status.setCode(STATUS_BAD_REQUEST, "Incompatible node type. Required either fm:topic or fm:post. Received: " + node.type);
}
}
/**
* Creates a post inside the passed forum node.
*/
function updatePost(postNode)
{ {
var title = ""; var title = "";
if (json.has("title")) if (json.has("title"))
@@ -42,10 +14,10 @@ function updatePost(postNode)
var content = json.get("content"); var content = json.get("content");
// update the topic title // update the topic title
postNode.properties.title = title; node.properties.title = title;
postNode.mimetype = "text/html"; node.mimetype = "text/html";
postNode.content = content; node.content = content;
postNode.save(); node.save();
} }
function main() function main()
@@ -100,6 +72,7 @@ function main()
} }
else else
{ {
// See above, use getTopicPostDataFromTopicAndPosts instead of getTopicPostData
//model.topicpost = getTopicPostData(node); //model.topicpost = getTopicPostData(node);
model.topicpost = getTopicPostDataFromTopicAndPosts(node, nodes); model.topicpost = getTopicPostDataFromTopicAndPosts(node, nodes);
} }

View File

@@ -1,12 +1,33 @@
/** /**
* This library contains functions to work with topics (aka top level posts). * Returns the fm:post node given a fm:topic or fm:post node.
* *
* Top-level posts are different from post that act as replies in that * This function makes sure that a post is returned in case the passed node is a topic.
* they have some additional data available:
* lastReplyOn:
* lastReplyFrom:
* totalReplyCount:
*/ */
function findPostNode(node)
{
if (node.type == "{http://www.alfresco.org/model/forum/1.0}post")
{
return node;
}
else if (node.type == "{http://www.alfresco.org/model/forum/1.0}topic")
{
var nodes = getOrderedPosts(node);
if (nodes.length > 0)
{
return nodes[0];
}
else
{
status.setCode(status.STATUS_INTERNAL_SERVER_ERROR, "First post of topic node" + node.nodeRef + " missing");
}
}
else
{
status.setCode(STATUS_BAD_REQUEST, "Incompatible node type. Required either fm:topic or fm:post. Received: " + node.type);
return null;
}
}
/** Returns the topic posts for a topic, ordered by creation date. /** Returns the topic posts for a topic, ordered by creation date.

View File

@@ -0,0 +1,51 @@
/**
* Returns a data object that can be passed to the paged results template
* for rendering.
*
* @param nodes: The complete result set nodes
* @param index: the start index from which results should be returned
* @param count: the number of elements that should be returned
* @param extractDataFn: The function that extracts the data to be returned
* for each node in the final data set.
* The functions signature is name(index, node).
*
* Returns an array containing all topics found in the passed array.
* Filters out non-fm:topic nodes.
*/
function getPagedResultsData(nodes, index, count, extractDataFn)
{
var items = new Array();
var i;
var added = 0;
for (i = index; i < nodes.length && added < count; i++)
{
items.push(extractDataFn(nodes[i]));
added++;
}
return ({
"total" : nodes.length,
"pageSize" : count,
"startIndex" : index,
"itemCount" : items.length,
"items": items
});
}
/**
* Returns a list of topics, as returned by the lucene query
*/
function getPagedResultsDataByLuceneQuery(node, luceneQuery, sortAttribute, ascending, index, count, extractDataFn)
{
var nodes = null;
if (sortAttribute != null)
{
nodes = search.luceneSearch(node.nodeRef.storeRef.toString(), luceneQuery, sortAttribute, ascending);
}
else
{
nodes = search.luceneSearch(luceneQuery);
}
return getPagedResultsData(nodes, index, count, extractDataFn);
}

View File

@@ -34,7 +34,7 @@ function findNodeInSite()
} }
// try to fetch the the path is there is any // try to fetch the the path is there is any
if ((path !== null) && (path != "")) if ((path !== null) && (path.length > 0))
{ {
node = node.childByNamePath(path); node = node.childByNamePath(path);
if (node === null) if (node === null)