會員註冊 / 登入  |  電腦版  |  Jump to bottom of page

Integration Forum » Create a Topic and Navigate to Topic programatically

發表人: deepacific
10 年 前
Hi

Is there any way to create a new Topic from another application and get back the URL or some info. Also, I want to be able to navigate to that topic from external application.

This is the use case I am trying to solve.
1. JForum Admin sets up some forums for users.
2. From an external application, I want to start a new topic in a specific forum. So I need to find the right forum by looking up its id or name or something unique. May be get a list of forums along with forum Ids.
3. When user clicks on new Topic, user must select a forum from the list and after selection, User enters basic Topic information e.g Name , Description etc and clicking ok creates a new topic in selected forum. It returns the topic id or some unique identifier.
4. I can bind the unique topic Id with that user in my application and construct a URL that will point to that topic.

Thank you.

deepacific

發表人: andowson
10 年 前
Check if this can help:
http://jforum.andowson.com/posts/list/17.page

發表人: deepacific
10 年 前
Hi andowson

I did check that link and it was really helpful. I actually wanted to wrap some more calls, like
posting a reply on a topic
getting total number of posts in a topic
getting an event every time there is a new post in a topic


Are there any plans in near future for a full API for doing all this?

發表人: andowson
10 年 前
Dear deepacific,
In short, no.

Currently I don't have any plan for this. If you need this, I guess you must have more specific knowledge about the full API, how about you do the plan first and contribute it back?

Andowson

發表人: deepacific
10 年 前
Hi andowson

I already made some changes in PostRest that allows me to:

1. Post replies on a topic - I basically added another parameter topicId and then set the topic id on the post object.
2. Return total number of posts in a topic - once again I modified the PostRest to return the numOfPosts as a header in the response object. I am getting this number from PostRepository.
3. For the event/notification, I know what needs to be done. Basically we need methods to register listeners for the different updates and then fire an event based on update type. Then people can just implement that interface and do whatever they wish to do in their application. I just wanted to make sure that if these changes are acceptable and will become part of the next release. I want to avoid synchronizing my changes with every new release of JForum.


I am more than happy to put the code here if you want.

Best

Deepacific

發表人: andowson
10 年 前
Dear deepacific,
I'm glad to hear about this. You can upload the code here as an attachment and I'll commit it back to the SVN later or if you'd like to join the team, I'll add you as a committer then you can commit it back to the SVN yourself.

發表人: deepacific
10 年 前
Hi andowsen

Here is the code for changed PostRes.java. This handles posting replies and returning the number of posts. I still have to figure out what is the best place to add a hook for firing the event , when a new post is added

/*
* Copyright (c) JForum Team
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* 1) Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
* 2) Redistributions in binary form must reproduce the
* above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* 3) Neither the name of "Rafael Steil" nor
* the names of its contributors may be used to endorse
* or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
* HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
*
* Created on 01/10/2011 14:32:22
* The JForum Project
* http://www.jforum.net
*/
package net.jforum.api.rest;

import java.util.Date;

import net.jforum.Command;
import net.jforum.JForumExecutionContext;
import net.jforum.SessionFacade;
import net.jforum.context.RequestContext;
import net.jforum.context.ResponseContext;
import net.jforum.dao.DataAccessDriver;
import net.jforum.dao.UserDAO;
import net.jforum.entities.Post;
import net.jforum.entities.Topic;
import net.jforum.entities.User;
import net.jforum.entities.UserSession;
import net.jforum.exceptions.APIException;
import net.jforum.util.I18n;
import net.jforum.util.preferences.ConfigKeys;
import net.jforum.util.preferences.SystemGlobals;
import net.jforum.util.preferences.TemplateKeys;
import net.jforum.view.forum.PostAction;

import org.apache.commons.lang3.StringUtils;

import freemarker.template.SimpleHash;
import freemarker.template.Template;
import net.jforum.repository.PostRepository;

/**
* @author Andowson Chang
*
*/
public class PostREST extends Command {

/* (non-Javadoc)
* @see net.jforum.Command#list()
*/
@Override
public void list() {
try {
this.authenticate();
// do nothing here
// TODO: add implementation
}
catch (Exception e) {
this.setTemplateName(TemplateKeys.API_ERROR);
this.context.put("exception", e);
}
}

/**
* Creates a new post.
* Required parameters are "email", "forum_id", "subject" and "message".
*/
public void insert()
{
try {
this.authenticate();

final String email = this.requiredRequestParameter("email");
final String forumId = this.requiredRequestParameter("forum_id");
final String subject = this.requiredRequestParameter("subject");
final String message = this.requiredRequestParameter("message");
final String topicId = this.request.getParameter("topicId");


final UserDAO dao = DataAccessDriver.getInstance().newUserDAO();
User user = dao.findByEmail(email);
// If user's email not exists, use anonymous instead
if (user == null) {
user = new User();
user.setId(SystemGlobals.getIntValue(ConfigKeys.ANONYMOUS_USER_ID));
user.setUsername(I18n.getMessage("Guest"));
}
// OK, time to insert the post
final UserSession userSession = SessionFacade.getUserSession();
userSession.setUserId(user.getId());
userSession.setUsername(user.getUsername());
String sessionId = userSession.getSessionId();
userSession.setStartTime(new Date(System.currentTimeMillis()));
SessionFacade.makeLogged();

SessionFacade.removeAttribute(ConfigKeys.LAST_POST_TIME);
SessionFacade.setAttribute(ConfigKeys.REQUEST_IGNORE_CAPTCHA, "1");

final Post post = new Post();
post.setForumId(Integer.valueOf(forumId));
post.setSubject(subject);
post.setText(message);

// check if it is a reply to a post and if topic Id is not 0
if(topicId != null && !topicId.equalsIgnoreCase("")){
try{
post.setTopicId(Integer.valueOf(topicId));
}catch(Exception e){
// do nothing here
}
}
this.insertMessage(user, post);

// new start
String postLink = JForumExecutionContext.getRedirectTo();
JForumExecutionContext.setRedirect(null);
if(postLink == null || postLink.equals("")){
postLink = "Error";
}
JForumExecutionContext.getResponse().addHeader("postLink", postLink);
this.setTemplateName("api.post.insert");
// add a header to the response for the post link
this.context.put("postLink", postLink);
int numOfPosts = PostRepository.size(post.getTopicId());
if(numOfPosts == 0){
// not loaded in cache yet, load in cache
PostRepository.selectAllByTopicByLimit(post.getTopicId(), 0, 1);
// get the number of posts
numOfPosts = PostRepository.size(post.getTopicId());
}
// add a header for the number of posts
JForumExecutionContext.getResponse().addHeader("numOfPosts", String.valueOf(numOfPosts));
this.context.put("numOfPosts", String.valueOf(numOfPosts));

// new end

SessionFacade.makeUnlogged();
SessionFacade.remove(sessionId);
}
catch (Exception e) {
this.setTemplateName(TemplateKeys.API_ERROR);
this.context.put("exception", e);
}
}

/**
* Calls {@link PostAction#insertSave()}
* @param post the post
* @param user the user who's doing the post
*/
private void insertMessage(final User user, final Post post)
{
this.addDataToRequest(user, post);

final PostAction postAction = new PostAction(JForumExecutionContext.getRequest(), new SimpleHash());
postAction.insertSave();
}

/**
* Extracts information from a mail message and adds it to the request context
* @param post the post
* @param user the user who's doing the post
*/
private void addDataToRequest(final User user, final Post post)
{
final RequestContext request = JForumExecutionContext.getRequest();

request.addParameter("topic_type", Integer.toString(Topic.TYPE_NORMAL));
request.addParameter("quick", "1");

final int topicId = post.getTopicId();
if (topicId > 0) {
request.addParameter("topic_id", Integer.toString(topicId));
}

if (!user.isBbCodeEnabled()) {
request.addParameter("disable_bbcode", "on");
}

if (!user.isSmiliesEnabled()) {
request.addParameter("disable_smilies", "on");
}

if (!user.isHtmlEnabled()) {
request.addParameter("disable_html", "on");
}
}

/**
* Retrieves a parameter from the request and ensures it exists
* @param paramName the parameter name to retrieve its value
* @return the parameter value
* @throws APIException if the parameter is not found or its value is empty
*/
private String requiredRequestParameter(final String paramName)
{
final String value = this.request.getParameter(paramName);

if (StringUtils.isBlank(value)) {
throw new APIException("The parameter '" + paramName + "' was not found");
}

return value;
}

/**
* Tries to authenticate the user accessing the API
* @throws APIException if the authentication fails
*/
private void authenticate()
{
final String apiKey = this.requiredRequestParameter("api_key");

final RESTAuthentication auth = new RESTAuthentication();

if (!auth.validateApiKey(apiKey)) {
throw new APIException("The provided API authentication information is not valid");
}
}

public Template process(final RequestContext request, final ResponseContext response, final SimpleHash context)
{
JForumExecutionContext.setContentType("text/xml");
return super.process(request, response, context);
}
}

發表人: andowson
10 年 前
Thank you for sharing this. I just added code tags to make it easy to read.




會員註冊 / 登入  |  電腦版  |  Jump to top of page