0001: /*
0002: * Copyright (c) JForum Team
0003: * All rights reserved.
0004: *
0005: * Redistribution and use in source and binary forms,
0006: * with or without modification, are permitted provided
0007: * that the following conditions are met:
0008: *
0009: * 1) Redistributions of source code must retain the above
0010: * copyright notice, this list of conditions and the
0011: * following disclaimer.
0012: * 2) Redistributions in binary form must reproduce the
0013: * above copyright notice, this list of conditions and
0014: * the following disclaimer in the documentation and/or
0015: * other materials provided with the distribution.
0016: * 3) Neither the name of "Rafael Steil" nor
0017: * the names of its contributors may be used to endorse
0018: * or promote products derived from this software without
0019: * specific prior written permission.
0020: *
0021: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
0022: * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
0023: * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
0024: * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
0025: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR
0026: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
0027: * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
0028: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0029: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES
0030: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0031: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
0032: * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
0033: * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
0034: * IN CONTRACT, STRICT LIABILITY, OR TORT
0035: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
0036: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
0037: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
0038: *
0039: * This file creation date: May 3, 2003 / 5:05:18 PM
0040: * The JForum Project
0041: * http://www.jforum.net
0042: */
0043: package net.jforum.view.forum;
0044:
0045: import java.io.File;
0046: import java.io.FileInputStream;
0047: import java.io.IOException;
0048: import java.io.OutputStream;
0049: import java.text.SimpleDateFormat;
0050: import java.util.Collections;
0051: import java.util.Date;
0052: import java.util.HashMap;
0053: import java.util.Iterator;
0054: import java.util.List;
0055: import java.util.Map;
0056:
0057: import net.jforum.Command;
0058: import net.jforum.JForumExecutionContext;
0059: import net.jforum.SessionFacade;
0060: import net.jforum.context.RequestContext;
0061: import net.jforum.dao.AttachmentDAO;
0062: import net.jforum.dao.DataAccessDriver;
0063: import net.jforum.dao.ForumDAO;
0064: import net.jforum.dao.KarmaDAO;
0065: import net.jforum.dao.PollDAO;
0066: import net.jforum.dao.PostDAO;
0067: import net.jforum.dao.TopicDAO;
0068: import net.jforum.dao.UserDAO;
0069: import net.jforum.entities.Attachment;
0070: import net.jforum.entities.Forum;
0071: import net.jforum.entities.ModerationLog;
0072: import net.jforum.entities.Poll;
0073: import net.jforum.entities.PollChanges;
0074: import net.jforum.entities.Post;
0075: import net.jforum.entities.QuotaLimit;
0076: import net.jforum.entities.Topic;
0077: import net.jforum.entities.User;
0078: import net.jforum.entities.UserSession;
0079: import net.jforum.exceptions.AttachmentException;
0080: import net.jforum.exceptions.ForumException;
0081: import net.jforum.repository.ForumRepository;
0082: import net.jforum.repository.PostRepository;
0083: import net.jforum.repository.RankingRepository;
0084: import net.jforum.repository.SecurityRepository;
0085: import net.jforum.repository.SmiliesRepository;
0086: import net.jforum.repository.TopicRepository;
0087: import net.jforum.security.PermissionControl;
0088: import net.jforum.security.SecurityConstants;
0089: import net.jforum.util.I18n;
0090: import net.jforum.util.preferences.ConfigKeys;
0091: import net.jforum.util.preferences.SystemGlobals;
0092: import net.jforum.util.preferences.TemplateKeys;
0093: import net.jforum.view.forum.common.AttachmentCommon;
0094: import net.jforum.view.forum.common.ForumCommon;
0095: import net.jforum.view.forum.common.PollCommon;
0096: import net.jforum.view.forum.common.PostCommon;
0097: import net.jforum.view.forum.common.TopicsCommon;
0098: import net.jforum.view.forum.common.ViewCommon;
0099:
0100: import org.apache.commons.lang.StringUtils;
0101:
0102: import freemarker.template.SimpleHash;
0103:
0104: /**
0105: * @author Rafael Steil
0106: * @version $Id: PostAction.java,v 1.198 2007/09/27 04:47:19 rafaelsteil Exp $
0107: */
0108: public class PostAction extends Command {
0109: public PostAction() {
0110: }
0111:
0112: public PostAction(RequestContext request, SimpleHash templateContext) {
0113: super .context = templateContext;
0114: super .request = request;
0115: }
0116:
0117: public void list() {
0118: PostDAO postDao = DataAccessDriver.getInstance().newPostDAO();
0119: PollDAO pollDao = DataAccessDriver.getInstance().newPollDAO();
0120:
0121: TopicDAO topicDao = DataAccessDriver.getInstance()
0122: .newTopicDAO();
0123:
0124: UserSession us = SessionFacade.getUserSession();
0125: int anonymousUser = SystemGlobals
0126: .getIntValue(ConfigKeys.ANONYMOUS_USER_ID);
0127: boolean logged = SessionFacade.isLogged();
0128:
0129: int topicId = this .request.getIntParameter("topic_id");
0130:
0131: Topic topic = TopicRepository.getTopic(new Topic(topicId));
0132:
0133: if (topic == null) {
0134: topic = topicDao.selectById(topicId);
0135: }
0136:
0137: // The topic exists?
0138: if (topic.getId() == 0) {
0139: this .topicNotFound();
0140: return;
0141: }
0142:
0143: // Shall we proceed?
0144: Forum forum = ForumRepository.getForum(topic.getForumId());
0145:
0146: if (!logged) {
0147: if (forum == null
0148: || !ForumRepository.isCategoryAccessible(forum
0149: .getCategoryId())) {
0150: this .setTemplateName(ViewCommon.contextToLogin());
0151: return;
0152: }
0153: } else if (!TopicsCommon.isTopicAccessible(topic.getForumId())) {
0154: return;
0155: }
0156:
0157: int count = SystemGlobals
0158: .getIntValue(ConfigKeys.POSTS_PER_PAGE);
0159: int start = ViewCommon.getStartPage();
0160:
0161: PermissionControl pc = SecurityRepository.get(us.getUserId());
0162:
0163: boolean moderatorCanEdit = false;
0164: if (pc.canAccess(SecurityConstants.PERM_MODERATION_POST_EDIT)) {
0165: moderatorCanEdit = true;
0166: }
0167:
0168: List helperList = PostCommon.topicPosts(postDao,
0169: moderatorCanEdit, us.getUserId(), topic.getId(), start,
0170: count);
0171:
0172: // Ugly assumption:
0173: // Is moderation pending for the topic?
0174: if (topic.isModerated() && helperList.size() == 0) {
0175: this .notModeratedYet();
0176: return;
0177: }
0178:
0179: // Set the topic status as read
0180: if (logged) {
0181: topicDao.updateReadStatus(topic.getId(), us.getUserId(),
0182: true);
0183: }
0184:
0185: boolean canVoteOnPoll = logged
0186: && SecurityRepository
0187: .canAccess(SecurityConstants.PERM_VOTE);
0188: Poll poll = null;
0189:
0190: if (topic.isVote()) {
0191: // It has a poll associated with the topic
0192: poll = pollDao.selectById(topic.getVoteId());
0193:
0194: if (canVoteOnPoll) {
0195: canVoteOnPoll = !pollDao.hasUserVotedOnPoll(topic
0196: .getVoteId(), us.getUserId());
0197: }
0198: }
0199:
0200: topicDao.incrementTotalViews(topic.getId());
0201: topic.setTotalViews(topic.getTotalViews() + 1);
0202:
0203: if (us.getUserId() != anonymousUser) {
0204: SessionFacade.getTopicsReadTime().put(
0205: new Integer(topic.getId()),
0206: new Long(System.currentTimeMillis()));
0207: }
0208:
0209: boolean karmaEnabled = SecurityRepository
0210: .canAccess(SecurityConstants.PERM_KARMA_ENABLED);
0211: Map userVotes = new HashMap();
0212:
0213: if (logged && karmaEnabled) {
0214: userVotes = DataAccessDriver.getInstance().newKarmaDAO()
0215: .getUserVotes(topic.getId(), us.getUserId());
0216: }
0217:
0218: this .setTemplateName(TemplateKeys.POSTS_LIST);
0219: this .context.put("attachmentsEnabled", pc.canAccess(
0220: SecurityConstants.PERM_ATTACHMENTS_ENABLED, Integer
0221: .toString(topic.getForumId())));
0222: this .context
0223: .put(
0224: "canDownloadAttachments",
0225: pc
0226: .canAccess(SecurityConstants.PERM_ATTACHMENTS_DOWNLOAD));
0227: this .context
0228: .put(
0229: "thumbShowBox",
0230: SystemGlobals
0231: .getBoolValue(ConfigKeys.ATTACHMENTS_IMAGES_THUMB_BOX_SHOW));
0232: this .context.put("am", new AttachmentCommon(this .request, topic
0233: .getForumId()));
0234: this .context.put("karmaVotes", userVotes);
0235: this .context.put("rssEnabled", SystemGlobals
0236: .getBoolValue(ConfigKeys.RSS_ENABLED));
0237: this .context
0238: .put(
0239: "canRemove",
0240: pc
0241: .canAccess(SecurityConstants.PERM_MODERATION_POST_REMOVE));
0242: this .context.put("moderatorCanEdit", moderatorCanEdit);
0243: this .context.put("allCategories", ForumCommon
0244: .getAllCategoriesAndForums(false));
0245: this .context.put("topic", topic);
0246: this .context.put("poll", poll);
0247: this .context.put("canVoteOnPoll", canVoteOnPoll);
0248: this .context.put("rank", new RankingRepository());
0249: this .context.put("posts", helperList);
0250: this .context.put("forum", forum);
0251: this .context.put("karmaMin", new Integer(SystemGlobals
0252: .getValue(ConfigKeys.KARMA_MIN_POINTS)));
0253: this .context.put("karmaMax", new Integer(SystemGlobals
0254: .getValue(ConfigKeys.KARMA_MAX_POINTS)));
0255: this .context.put("avatarAllowExternalUrl", SystemGlobals
0256: .getBoolValue(ConfigKeys.AVATAR_ALLOW_EXTERNAL_URL));
0257: this .context.put("moderationLoggingEnabled", SystemGlobals
0258: .getBoolValue(ConfigKeys.MODERATION_LOGGING_ENABLED));
0259: this .context.put("needCaptcha", SystemGlobals
0260: .getBoolValue(ConfigKeys.CAPTCHA_POSTS));
0261:
0262: Map topicPosters = topicDao.topicPosters(topic.getId());
0263:
0264: for (Iterator iter = topicPosters.values().iterator(); iter
0265: .hasNext();) {
0266: ViewCommon.prepareUserSignature((User) iter.next());
0267: }
0268:
0269: this .context.put("users", topicPosters);
0270: this .context.put("anonymousPosts", pc.canAccess(
0271: SecurityConstants.PERM_ANONYMOUS_POST, Integer
0272: .toString(topic.getForumId())));
0273: this .context.put("watching", topicDao.isUserSubscribed(topicId,
0274: SessionFacade.getUserSession().getUserId()));
0275: this .context.put("pageTitle", topic.getTitle());
0276: this .context.put("isAdmin", pc
0277: .canAccess(SecurityConstants.PERM_ADMINISTRATION));
0278: this .context.put("readonly", !pc.canAccess(
0279: SecurityConstants.PERM_READ_ONLY_FORUMS, Integer
0280: .toString(topic.getForumId())));
0281: this .context.put("replyOnly", !pc.canAccess(
0282: SecurityConstants.PERM_REPLY_ONLY, Integer
0283: .toString(topic.getForumId())));
0284:
0285: this .context.put("isModerator", us.isModerator(topic
0286: .getForumId()));
0287:
0288: ViewCommon.contextToPagination(start,
0289: topic.getTotalReplies() + 1, count);
0290:
0291: TopicsCommon.topicListingBase();
0292: TopicRepository.updateTopic(topic);
0293: }
0294:
0295: /**
0296: * Given a postId, sends the user to the right page
0297: */
0298: public void preList() {
0299: int postId = this .request.getIntParameter("post_id");
0300:
0301: PostDAO dao = DataAccessDriver.getInstance().newPostDAO();
0302:
0303: int count = dao.countPreviousPosts(postId);
0304: int postsPerPage = SystemGlobals
0305: .getIntValue(ConfigKeys.POSTS_PER_PAGE);
0306:
0307: int topicId = 0;
0308:
0309: if (this .request.getParameter("topic_id") != null) {
0310: topicId = this .request.getIntParameter("topic_id");
0311: }
0312:
0313: if (topicId == 0) {
0314: Post post = dao.selectById(postId);
0315: topicId = post.getTopicId();
0316: }
0317:
0318: String page = "";
0319:
0320: if (count > postsPerPage) {
0321: page = Integer.toString(postsPerPage
0322: * ((count - 1) / postsPerPage))
0323: + "/";
0324: }
0325:
0326: JForumExecutionContext.setRedirect(this .request
0327: .getContextPath()
0328: + "/posts/list/"
0329: + page
0330: + topicId
0331: + SystemGlobals.getValue(ConfigKeys.SERVLET_EXTENSION)
0332: + "#" + postId);
0333: }
0334:
0335: /**
0336: * Votes on a poll.
0337: */
0338: public void vote() {
0339: int pollId = this .request.getIntParameter("poll_id");
0340: int topicId = this .request.getIntParameter("topic_id");
0341:
0342: if (SessionFacade.isLogged()
0343: && this .request.getParameter("poll_option") != null) {
0344: Topic topic = TopicRepository.getTopic(new Topic(topicId));
0345:
0346: if (topic == null) {
0347: topic = DataAccessDriver.getInstance().newTopicDAO()
0348: .selectRaw(topicId);
0349: }
0350:
0351: if (topic.getStatus() == Topic.STATUS_LOCKED) {
0352: this .topicLocked();
0353: return;
0354: }
0355:
0356: // They voted, save the value
0357: int optionId = this .request.getIntParameter("poll_option");
0358:
0359: PollDAO dao = DataAccessDriver.getInstance().newPollDAO();
0360:
0361: //vote on the poll
0362: UserSession user = SessionFacade.getUserSession();
0363: dao.voteOnPoll(pollId, optionId, user.getUserId(), request
0364: .getRemoteAddr());
0365: }
0366:
0367: JForumExecutionContext.setRedirect(this .request
0368: .getContextPath()
0369: + "/posts/list/"
0370: + topicId
0371: + SystemGlobals.getValue(ConfigKeys.SERVLET_EXTENSION));
0372: }
0373:
0374: public void listByUser() {
0375: PostDAO pm = DataAccessDriver.getInstance().newPostDAO();
0376: UserDAO um = DataAccessDriver.getInstance().newUserDAO();
0377: TopicDAO tm = DataAccessDriver.getInstance().newTopicDAO();
0378:
0379: User u = um.selectById(this .request.getIntParameter("user_id"));
0380:
0381: if (u.getId() == 0) {
0382: this .context.put("message", I18n
0383: .getMessage("User.notFound"));
0384: this .setTemplateName(TemplateKeys.USER_NOT_FOUND);
0385: return;
0386: }
0387:
0388: int count = SystemGlobals
0389: .getIntValue(ConfigKeys.POSTS_PER_PAGE);
0390: int start = ViewCommon.getStartPage();
0391: int postsPerPage = SystemGlobals
0392: .getIntValue(ConfigKeys.POSTS_PER_PAGE);
0393:
0394: List posts = pm.selectByUserByLimit(u.getId(), start,
0395: postsPerPage);
0396: int totalMessages = pm.countUserPosts(u.getId());
0397:
0398: // get list of forums
0399: Map topics = new HashMap();
0400: Map forums = new HashMap();
0401:
0402: for (Iterator iter = posts.iterator(); iter.hasNext();) {
0403: Post p = (Post) iter.next();
0404:
0405: if (!topics.containsKey(new Integer(p.getTopicId()))) {
0406: Topic t = TopicRepository.getTopic(new Topic(p
0407: .getTopicId()));
0408:
0409: if (t == null) {
0410: t = tm.selectRaw(p.getTopicId());
0411: }
0412:
0413: this .context
0414: .put(
0415: "attachmentsEnabled",
0416: SecurityRepository
0417: .canAccess(
0418: SecurityConstants.PERM_ATTACHMENTS_ENABLED,
0419: Integer.toString(t
0420: .getForumId())));
0421: this .context.put("am", new AttachmentCommon(
0422: this .request, t.getForumId()));
0423:
0424: topics.put(new Integer(t.getId()), t);
0425: }
0426:
0427: if (!forums.containsKey(new Integer(p.getForumId()))) {
0428: Forum f = ForumRepository.getForum(p.getForumId());
0429:
0430: if (f == null) {
0431: // Ok, probably the user does not have permission to see this forum
0432: iter.remove();
0433: totalMessages--;
0434: continue;
0435: }
0436:
0437: forums.put(new Integer(f.getId()), f);
0438: }
0439:
0440: PostCommon.preparePostForDisplay(p);
0441: }
0442:
0443: this .setTemplateName(TemplateKeys.POSTS_USER_POSTS_LIST);
0444:
0445: this .context
0446: .put(
0447: "canDownloadAttachments",
0448: SecurityRepository
0449: .canAccess(SecurityConstants.PERM_ATTACHMENTS_DOWNLOAD));
0450: this .context.put("rssEnabled", SystemGlobals
0451: .getBoolValue(ConfigKeys.RSS_ENABLED));
0452: this .context.put("allCategories", ForumCommon
0453: .getAllCategoriesAndForums(false));
0454: this .context.put("posts", posts);
0455: this .context.put("topics", topics);
0456: this .context.put("forums", forums);
0457: this .context.put("u", u);
0458: this .context.put("pageTitle", I18n
0459: .getMessage("PostShow.userPosts")
0460: + " " + u.getUsername());
0461: this .context.put("karmaMin", new Integer(SystemGlobals
0462: .getValue(ConfigKeys.KARMA_MIN_POINTS)));
0463: this .context.put("karmaMax", new Integer(SystemGlobals
0464: .getValue(ConfigKeys.KARMA_MAX_POINTS)));
0465:
0466: ViewCommon.contextToPagination(start, totalMessages, count);
0467: }
0468:
0469: public void review() {
0470: PostDAO postDao = DataAccessDriver.getInstance().newPostDAO();
0471: TopicDAO topicDao = DataAccessDriver.getInstance()
0472: .newTopicDAO();
0473:
0474: int userId = SessionFacade.getUserSession().getUserId();
0475: int topicId = this .request.getIntParameter("topic_id");
0476:
0477: Topic topic = TopicRepository.getTopic(new Topic(topicId));
0478:
0479: if (topic == null) {
0480: topic = topicDao.selectById(topicId);
0481: }
0482:
0483: if (!TopicsCommon.isTopicAccessible(topic.getForumId())) {
0484: return;
0485: }
0486:
0487: int count = SystemGlobals
0488: .getIntValue(ConfigKeys.POSTS_PER_PAGE);
0489: int start = ViewCommon.getStartPage();
0490:
0491: Map usersMap = topicDao.topicPosters(topic.getId());
0492: List helperList = PostCommon.topicPosts(postDao, false, userId,
0493: topic.getId(), start, count);
0494: Collections.reverse(helperList);
0495:
0496: this .setTemplateName(SystemGlobals
0497: .getValue(ConfigKeys.TEMPLATE_DIR)
0498: + "/empty.htm");
0499:
0500: this .setTemplateName(TemplateKeys.POSTS_REVIEW);
0501: this .context.put("posts", helperList);
0502: this .context.put("users", usersMap);
0503: }
0504:
0505: private void topicNotFound() {
0506: this .setTemplateName(TemplateKeys.POSTS_TOPIC_NOT_FOUND);
0507: this .context.put("message", I18n
0508: .getMessage("PostShow.TopicNotFound"));
0509: }
0510:
0511: private void postNotFound() {
0512: this .setTemplateName(TemplateKeys.POSTS_POST_NOT_FOUND);
0513: this .context.put("message", I18n
0514: .getMessage("PostShow.PostNotFound"));
0515: }
0516:
0517: private void replyOnly() {
0518: this .setTemplateName(TemplateKeys.POSTS_REPLY_ONLY);
0519: this .context.put("message", I18n
0520: .getMessage("PostShow.replyOnly"));
0521: }
0522:
0523: private boolean isReplyOnly(int forumId) {
0524: return !SecurityRepository.canAccess(
0525: SecurityConstants.PERM_REPLY_ONLY, Integer
0526: .toString(forumId));
0527: }
0528:
0529: public void reply() {
0530: this .insert();
0531: }
0532:
0533: public void insert() {
0534: int forumId;
0535:
0536: // If we have a topic_id, then it should be a reply
0537: if (this .request.getParameter("topic_id") != null) {
0538: int topicId = this .request.getIntParameter("topic_id");
0539:
0540: Topic t = TopicRepository.getTopic(new Topic(topicId));
0541:
0542: if (t == null) {
0543: t = DataAccessDriver.getInstance().newTopicDAO()
0544: .selectRaw(topicId);
0545:
0546: if (t == null) {
0547: throw new ForumException(
0548: "Could not find a topic with id #"
0549: + topicId);
0550: }
0551: }
0552:
0553: forumId = t.getForumId();
0554:
0555: if (!TopicsCommon.isTopicAccessible(t.getForumId())) {
0556: return;
0557: }
0558:
0559: if (t.getStatus() == Topic.STATUS_LOCKED) {
0560: this .topicLocked();
0561: return;
0562: }
0563:
0564: this .context.put("topic", t);
0565: this .context.put("setType", false);
0566: this .context.put("pageTitle", I18n
0567: .getMessage("PostForm.reply")
0568: + " " + t.getTitle());
0569: } else {
0570: forumId = this .request.getIntParameter("forum_id");
0571:
0572: if (this .isReplyOnly(forumId)) {
0573: this .replyOnly();
0574: return;
0575: }
0576: this .context.put("setType", true);
0577: this .context.put("pageTitle", I18n
0578: .getMessage("PostForm.title"));
0579: }
0580:
0581: Forum forum = ForumRepository.getForum(forumId);
0582:
0583: if (forum == null) {
0584: throw new ForumException("Could not find a forum with id #"
0585: + forumId);
0586: }
0587:
0588: if (!TopicsCommon.isTopicAccessible(forumId)) {
0589: return;
0590: }
0591:
0592: if (!this .anonymousPost(forumId)
0593: || this .isForumReadonly(forumId, this .request
0594: .getParameter("topic_id") != null)) {
0595: return;
0596: }
0597:
0598: int userId = SessionFacade.getUserSession().getUserId();
0599:
0600: this .setTemplateName(TemplateKeys.POSTS_INSERT);
0601:
0602: // Attachments
0603: boolean attachmentsEnabled = SecurityRepository.canAccess(
0604: SecurityConstants.PERM_ATTACHMENTS_ENABLED, Integer
0605: .toString(forumId));
0606:
0607: if (attachmentsEnabled
0608: && !SessionFacade.isLogged()
0609: && !SystemGlobals
0610: .getBoolValue(ConfigKeys.ATTACHMENTS_ANONYMOUS)) {
0611: attachmentsEnabled = false;
0612: }
0613:
0614: this .context.put("attachmentsEnabled", attachmentsEnabled);
0615:
0616: if (attachmentsEnabled) {
0617: QuotaLimit ql = new AttachmentCommon(this .request, forumId)
0618: .getQuotaLimit(userId);
0619: this .context.put("maxAttachmentsSize", new Long(
0620: ql != null ? ql.getSizeInBytes() : 1));
0621: this .context.put("maxAttachments", SystemGlobals
0622: .getValue(ConfigKeys.ATTACHMENTS_MAX_POST));
0623: }
0624:
0625: boolean needCaptcha = SystemGlobals
0626: .getBoolValue(ConfigKeys.CAPTCHA_POSTS);
0627:
0628: this .context.put("moderationLoggingEnabled", SystemGlobals
0629: .getBoolValue(ConfigKeys.MODERATION_LOGGING_ENABLED));
0630: this .context.put("smilies", SmiliesRepository.getSmilies());
0631: this .context.put("forum", forum);
0632: this .context.put("action", "insertSave");
0633: this .context.put("start", this .request.getParameter("start"));
0634: this .context.put("isNewPost", true);
0635: this .context.put("needCaptcha", needCaptcha);
0636: this .context.put("htmlAllowed", SecurityRepository.canAccess(
0637: SecurityConstants.PERM_HTML_DISABLED, Integer
0638: .toString(forumId)));
0639: this .context
0640: .put(
0641: "canCreateStickyOrAnnouncementTopics",
0642: SecurityRepository
0643: .canAccess(SecurityConstants.PERM_CREATE_STICKY_ANNOUNCEMENT_TOPICS));
0644: this .context.put("canCreatePolls", SecurityRepository
0645: .canAccess(SecurityConstants.PERM_CREATE_POLL));
0646:
0647: User user = DataAccessDriver.getInstance().newUserDAO()
0648: .selectById(userId);
0649:
0650: ViewCommon.prepareUserSignature(user);
0651:
0652: if (this .request.getParameter("preview") != null) {
0653: user.setNotifyOnMessagesEnabled(this .request
0654: .getParameter("notify") != null);
0655: }
0656:
0657: this .context.put("user", user);
0658: }
0659:
0660: public void edit() {
0661: this .edit(false, null);
0662: }
0663:
0664: private void edit(boolean preview, Post p) {
0665: int userId = SessionFacade.getUserSession().getUserId();
0666:
0667: if (!preview) {
0668: PostDAO pm = DataAccessDriver.getInstance().newPostDAO();
0669: p = pm.selectById(this .request.getIntParameter("post_id"));
0670:
0671: // The post exist?
0672: if (p.getId() == 0) {
0673: this .postNotFound();
0674: return;
0675: }
0676: }
0677:
0678: boolean isModerator = SecurityRepository
0679: .canAccess(SecurityConstants.PERM_MODERATION_POST_EDIT);
0680: boolean canEdit = SessionFacade.isLogged()
0681: && (isModerator || p.getUserId() == userId);
0682:
0683: if (!canEdit) {
0684: this .setTemplateName(TemplateKeys.POSTS_EDIT_CANNOTEDIT);
0685: this .context.put("message", I18n
0686: .getMessage("CannotEditPost"));
0687: } else {
0688: Topic topic = TopicRepository.getTopic(new Topic(p
0689: .getTopicId()));
0690:
0691: if (topic == null) {
0692: topic = DataAccessDriver.getInstance().newTopicDAO()
0693: .selectRaw(p.getTopicId());
0694: }
0695:
0696: if (!TopicsCommon.isTopicAccessible(topic.getForumId())) {
0697: return;
0698: }
0699:
0700: if (topic.getStatus() == Topic.STATUS_LOCKED
0701: && !isModerator) {
0702: this .topicLocked();
0703: return;
0704: }
0705:
0706: if (preview
0707: && this .request.getParameter("topic_type") != null) {
0708: topic.setType(this .request
0709: .getIntParameter("topic_type"));
0710: }
0711:
0712: if (p.hasAttachments()) {
0713: this .context.put("attachments", DataAccessDriver
0714: .getInstance().newAttachmentDAO()
0715: .selectAttachments(p.getId()));
0716: }
0717:
0718: Poll poll = null;
0719:
0720: if (topic.isVote() && topic.getFirstPostId() == p.getId()) {
0721: // It has a poll associated with the topic
0722: PollDAO poolDao = DataAccessDriver.getInstance()
0723: .newPollDAO();
0724: poll = poolDao.selectById(topic.getVoteId());
0725: }
0726:
0727: this .setTemplateName(TemplateKeys.POSTS_EDIT);
0728:
0729: this .context.put("attachmentsEnabled", SecurityRepository
0730: .canAccess(
0731: SecurityConstants.PERM_ATTACHMENTS_ENABLED,
0732: Integer.toString(p.getForumId())));
0733:
0734: this .context
0735: .put(
0736: "moderationLoggingEnabled",
0737: SystemGlobals
0738: .getBoolValue(ConfigKeys.MODERATION_LOGGING_ENABLED));
0739:
0740: QuotaLimit ql = new AttachmentCommon(this .request, p
0741: .getForumId()).getQuotaLimit(userId);
0742: this .context.put("maxAttachmentsSize", new Long(
0743: ql != null ? ql.getSizeInBytes() : 1));
0744: this .context.put("isEdit", true);
0745: this .context.put("maxAttachments", SystemGlobals
0746: .getValue(ConfigKeys.ATTACHMENTS_MAX_POST));
0747: this .context.put("smilies", SmiliesRepository.getSmilies());
0748: this .context.put("forum", ForumRepository.getForum(p
0749: .getForumId()));
0750: this .context.put("action", "editSave");
0751: this .context.put("post", p);
0752: this .context.put("setType", p.getId() == topic
0753: .getFirstPostId());
0754: this .context.put("topic", topic);
0755: this .context.put("poll", poll);
0756: this .context.put("pageTitle", I18n
0757: .getMessage("PostShow.messageTitle")
0758: + " " + p.getSubject());
0759: this .context.put("isModerator", isModerator);
0760: this .context.put("start", this .request
0761: .getParameter("start"));
0762: this .context.put("htmlAllowed", SecurityRepository
0763: .canAccess(SecurityConstants.PERM_HTML_DISABLED,
0764: Integer.toString(topic.getForumId())));
0765: this .context
0766: .put(
0767: "canCreateStickyOrAnnouncementTopics",
0768: SecurityRepository
0769: .canAccess(SecurityConstants.PERM_CREATE_STICKY_ANNOUNCEMENT_TOPICS));
0770: this .context.put("canCreatePolls", SecurityRepository
0771: .canAccess(SecurityConstants.PERM_CREATE_POLL));
0772: }
0773:
0774: UserDAO udao = DataAccessDriver.getInstance().newUserDAO();
0775: User u = udao.selectById(userId);
0776: ViewCommon.prepareUserSignature(u);
0777:
0778: if (preview) {
0779: u.setNotifyOnMessagesEnabled(this .request
0780: .getParameter("notify") != null);
0781:
0782: if (u.getId() != p.getUserId()) {
0783: // Probably a moderator is editing the message
0784: User previewUser = udao.selectById(p.getUserId());
0785: ViewCommon.prepareUserSignature(previewUser);
0786: this .context.put("previewUser", previewUser);
0787: }
0788: }
0789:
0790: this .context.put("user", u);
0791: }
0792:
0793: public void quote() {
0794: PostDAO pm = DataAccessDriver.getInstance().newPostDAO();
0795: Post p = pm.selectById(this .request.getIntParameter("post_id"));
0796:
0797: if (p.getId() == 0) {
0798: this .postNotFound();
0799: return;
0800: }
0801:
0802: if (p.isModerationNeeded()) {
0803: this .notModeratedYet();
0804: return;
0805: }
0806:
0807: if (!this .anonymousPost(p.getForumId())) {
0808: return;
0809: }
0810:
0811: Topic topic = TopicRepository
0812: .getTopic(new Topic(p.getTopicId()));
0813:
0814: if (topic == null) {
0815: topic = DataAccessDriver.getInstance().newTopicDAO()
0816: .selectRaw(p.getTopicId());
0817: }
0818:
0819: if (!TopicsCommon.isTopicAccessible(topic.getForumId())) {
0820: return;
0821: }
0822:
0823: if (topic.getStatus() == Topic.STATUS_LOCKED) {
0824: this .topicLocked();
0825: return;
0826: }
0827:
0828: this .setTemplateName(TemplateKeys.POSTS_QUOTE);
0829:
0830: this .context.put("forum", ForumRepository.getForum(p
0831: .getForumId()));
0832: this .context.put("action", "insertSave");
0833: this .context.put("post", p);
0834:
0835: UserDAO um = DataAccessDriver.getInstance().newUserDAO();
0836: User u = um.selectById(p.getUserId());
0837:
0838: int userId = SessionFacade.getUserSession().getUserId();
0839:
0840: this .context.put("attachmentsEnabled", SecurityRepository
0841: .canAccess(SecurityConstants.PERM_ATTACHMENTS_ENABLED,
0842: Integer.toString(topic.getForumId())));
0843:
0844: QuotaLimit ql = new AttachmentCommon(this .request, topic
0845: .getForumId()).getQuotaLimit(userId);
0846: this .context.put("maxAttachmentsSize", new Long(ql != null ? ql
0847: .getSizeInBytes() : 1));
0848:
0849: this .context.put("moderationLoggingEnabled", SystemGlobals
0850: .getBoolValue(ConfigKeys.MODERATION_LOGGING_ENABLED));
0851: this .context.put("maxAttachments", SystemGlobals
0852: .getValue(ConfigKeys.ATTACHMENTS_MAX_POST));
0853: this .context.put("isNewPost", true);
0854: this .context.put("topic", topic);
0855: this .context.put("quote", "true");
0856: this .context.put("quoteUser", u.getUsername());
0857: this .context.put("setType", false);
0858: this .context.put("htmlAllowed", SecurityRepository.canAccess(
0859: SecurityConstants.PERM_HTML_DISABLED, Integer
0860: .toString(topic.getForumId())));
0861: this .context.put("start", this .request.getParameter("start"));
0862: this .context.put("user", DataAccessDriver.getInstance()
0863: .newUserDAO().selectById(userId));
0864: this .context.put("pageTitle", I18n.getMessage("PostForm.reply")
0865: + " " + topic.getTitle());
0866: this .context.put("smilies", SmiliesRepository.getSmilies());
0867:
0868: boolean needCaptcha = SystemGlobals
0869: .getBoolValue(ConfigKeys.CAPTCHA_POSTS);
0870:
0871: if (needCaptcha) {
0872: SessionFacade.getUserSession().createNewCaptcha();
0873: }
0874:
0875: this .context.put("needCaptcha", needCaptcha);
0876: }
0877:
0878: public void editSave() {
0879: PostDAO postDao = DataAccessDriver.getInstance().newPostDAO();
0880: PollDAO pollDao = DataAccessDriver.getInstance().newPollDAO();
0881: TopicDAO topicDao = DataAccessDriver.getInstance()
0882: .newTopicDAO();
0883:
0884: Post post = postDao.selectById(this .request
0885: .getIntParameter("post_id"));
0886:
0887: if (!PostCommon.canEditPost(post)) {
0888: this .cannotEdit();
0889: return;
0890: }
0891:
0892: boolean isModerator = SecurityRepository
0893: .canAccess(SecurityConstants.PERM_MODERATION_POST_EDIT);
0894:
0895: String originalMessage = post.getText();
0896:
0897: post = PostCommon.fillPostFromRequest(post, true);
0898:
0899: // The user wants to preview the message before posting it?
0900: if ("1".equals(this .request.getParameter("preview"))) {
0901: this .context.put("preview", true);
0902:
0903: Post postPreview = new Post(post);
0904: this .context.put("postPreview", PostCommon
0905: .preparePostForDisplay(postPreview));
0906:
0907: this .edit(true, post);
0908: } else {
0909: AttachmentCommon attachments = new AttachmentCommon(
0910: this .request, post.getForumId());
0911:
0912: try {
0913: attachments.preProcess();
0914: } catch (AttachmentException e) {
0915: JForumExecutionContext.enableRollback();
0916: post.setText(this .request.getParameter("message"));
0917: this .context.put("errorMessage", e.getMessage());
0918: this .context.put("post", post);
0919: this .edit(false, post);
0920: return;
0921: }
0922:
0923: Topic t = TopicRepository.getTopic(new Topic(post
0924: .getTopicId()));
0925:
0926: if (t == null) {
0927: t = topicDao.selectById(post.getTopicId());
0928: }
0929:
0930: if (!TopicsCommon.isTopicAccessible(t.getForumId())) {
0931: return;
0932: }
0933:
0934: if (t.getStatus() == Topic.STATUS_LOCKED
0935: && !SecurityRepository
0936: .canAccess(SecurityConstants.PERM_MODERATION_POST_EDIT)) {
0937: this .topicLocked();
0938: return;
0939: }
0940:
0941: postDao.update(post);
0942:
0943: // Attachments
0944: attachments
0945: .editAttachments(post.getId(), post.getForumId());
0946: attachments.insertAttachments(post);
0947:
0948: // The first message (the one which originated the topic) was changed
0949: if (t.getFirstPostId() == post.getId()) {
0950: t.setTitle(post.getSubject());
0951:
0952: int newType = this .request
0953: .getIntParameter("topic_type");
0954: boolean changeType = SecurityRepository
0955: .canAccess(SecurityConstants.PERM_CREATE_STICKY_ANNOUNCEMENT_TOPICS)
0956: && newType != t.getType();
0957:
0958: if (changeType) {
0959: t.setType(newType);
0960: }
0961:
0962: // Poll
0963: Poll poll = PollCommon.fillPollFromRequest();
0964:
0965: if (poll != null && !t.isVote()) {
0966: // They added a poll
0967: poll.setTopicId(t.getId());
0968:
0969: if (!this .ensurePollMinimumOptions(post, poll)) {
0970: return;
0971: }
0972:
0973: pollDao.addNew(poll);
0974: t.setVoteId(poll.getId());
0975:
0976: } else if (poll != null) {
0977: if (!this .ensurePollMinimumOptions(post, poll)) {
0978: return;
0979: }
0980:
0981: // They edited the poll in the topic
0982: Poll existing = pollDao.selectById(t.getVoteId());
0983: PollChanges changes = new PollChanges(existing,
0984: poll);
0985:
0986: if (changes.hasChanges()) {
0987: poll.setId(existing.getId());
0988: poll.setChanges(changes);
0989: pollDao.update(poll);
0990: }
0991:
0992: } else if (t.isVote()) {
0993: // They deleted the poll from the topic
0994: pollDao.delete(t.getVoteId());
0995: t.setVoteId(0);
0996: }
0997:
0998: topicDao.update(t);
0999:
1000: if (changeType) {
1001: TopicRepository.addTopic(t);
1002: } else {
1003: TopicRepository.updateTopic(t);
1004: }
1005: }
1006:
1007: if (SystemGlobals
1008: .getBoolValue(ConfigKeys.MODERATION_LOGGING_ENABLED)
1009: && isModerator
1010: && post.getUserId() != SessionFacade
1011: .getUserSession().getUserId()) {
1012: ModerationHelper helper = new ModerationHelper();
1013: this .request.addParameter("log_original_message",
1014: originalMessage);
1015: ModerationLog log = helper
1016: .buildModerationLogFromRequest();
1017: log.getPosterUser().setId(post.getUserId());
1018: helper.saveModerationLog(log);
1019: }
1020:
1021: if (this .request.getParameter("notify") == null) {
1022: topicDao.removeSubscription(post.getTopicId(),
1023: SessionFacade.getUserSession().getUserId());
1024: }
1025:
1026: String path = this .request.getContextPath()
1027: + "/posts/list/";
1028: int start = ViewCommon.getStartPage();
1029:
1030: if (start > 0) {
1031: path += start + "/";
1032: }
1033:
1034: path += post.getTopicId()
1035: + SystemGlobals
1036: .getValue(ConfigKeys.SERVLET_EXTENSION)
1037: + "#" + post.getId();
1038: JForumExecutionContext.setRedirect(path);
1039:
1040: if (SystemGlobals
1041: .getBoolValue(ConfigKeys.POSTS_CACHE_ENABLED)) {
1042: PostRepository.update(post.getTopicId(), PostCommon
1043: .preparePostForDisplay(post));
1044: }
1045: }
1046: }
1047:
1048: private boolean ensurePollMinimumOptions(Post p, Poll poll) {
1049: if (poll.getOptions().size() < 2) {
1050: // It is not a valid poll, cancel the post
1051: JForumExecutionContext.enableRollback();
1052: p.setText(this .request.getParameter("message"));
1053: p.setId(0);
1054: this .context.put("errorMessage", I18n
1055: .getMessage("PostForm.needMorePollOptions"));
1056: this .context.put("post", p);
1057: this .context.put("poll", poll);
1058: this .edit();
1059: return false;
1060: }
1061:
1062: return true;
1063: }
1064:
1065: public void waitingModeration() {
1066: this .setTemplateName(TemplateKeys.POSTS_WAITING);
1067:
1068: int topicId = this .request.getIntParameter("topic_id");
1069: String path = this .request.getContextPath();
1070:
1071: if (topicId == 0) {
1072: path += "/forums/show/"
1073: + this .request.getParameter("forum_id");
1074: } else {
1075: path += "/posts/list/" + topicId;
1076: }
1077:
1078: this .context
1079: .put(
1080: "message",
1081: I18n
1082: .getMessage(
1083: "PostShow.waitingModeration",
1084: new String[] { path
1085: + SystemGlobals
1086: .getValue(ConfigKeys.SERVLET_EXTENSION) }));
1087: }
1088:
1089: private void notModeratedYet() {
1090: this .setTemplateName(TemplateKeys.POSTS_NOT_MODERATED);
1091: this .context.put("message", I18n
1092: .getMessage("PostShow.notModeratedYet"));
1093: }
1094:
1095: public void insertSave() {
1096: int forumId = this .request.getIntParameter("forum_id");
1097: boolean firstPost = false;
1098:
1099: if (!this .anonymousPost(forumId)) {
1100: return;
1101: }
1102:
1103: Topic t = new Topic(-1);
1104: t.setForumId(forumId);
1105:
1106: boolean newTopic = (this .request.getParameter("topic_id") == null);
1107:
1108: if (!TopicsCommon.isTopicAccessible(t.getForumId())
1109: || this .isForumReadonly(t.getForumId(), newTopic)) {
1110: return;
1111: }
1112:
1113: TopicDAO topicDao = DataAccessDriver.getInstance()
1114: .newTopicDAO();
1115: PostDAO postDao = DataAccessDriver.getInstance().newPostDAO();
1116: PollDAO poolDao = DataAccessDriver.getInstance().newPollDAO();
1117: ForumDAO forumDao = DataAccessDriver.getInstance()
1118: .newForumDAO();
1119:
1120: if (!newTopic) {
1121: int topicId = this .request.getIntParameter("topic_id");
1122:
1123: t = TopicRepository.getTopic(new Topic(topicId));
1124:
1125: if (t == null) {
1126: t = topicDao.selectById(topicId);
1127: }
1128:
1129: // Could not find the topic. The topicId sent was invalid
1130: if (t == null || t.getId() == 0) {
1131: newTopic = true;
1132: } else {
1133: if (!TopicsCommon.isTopicAccessible(t.getForumId())) {
1134: return;
1135: }
1136:
1137: // Cannot insert new messages on locked topics
1138: if (t.getStatus() == Topic.STATUS_LOCKED) {
1139: this .topicLocked();
1140: return;
1141: }
1142: }
1143: }
1144:
1145: // We don't use "else if" here because there is a possibility of the
1146: // checking above set the newTopic var to true
1147: if (newTopic) {
1148: if (this .isReplyOnly(forumId)) {
1149: this .replyOnly();
1150: return;
1151: }
1152:
1153: if (this .request.getParameter("topic_type") != null) {
1154: t.setType(this .request.getIntParameter("topic_type"));
1155:
1156: if (t.getType() != Topic.TYPE_NORMAL
1157: && !SecurityRepository
1158: .canAccess(SecurityConstants.PERM_CREATE_STICKY_ANNOUNCEMENT_TOPICS)) {
1159: t.setType(Topic.TYPE_NORMAL);
1160: }
1161: }
1162: }
1163:
1164: UserSession us = SessionFacade.getUserSession();
1165: User u = DataAccessDriver.getInstance().newUserDAO()
1166: .selectById(us.getUserId());
1167:
1168: if ("1".equals(this .request.getParameter("quick"))
1169: && SessionFacade.isLogged()) {
1170: this .request.addParameter("notify", u
1171: .isNotifyOnMessagesEnabled() ? "1" : null);
1172: this .request.addParameter("attach_sig", u
1173: .getAttachSignatureEnabled() ? "1" : "0");
1174: } else {
1175: u.setId(us.getUserId());
1176: u.setUsername(us.getUsername());
1177: }
1178:
1179: // Set the Post
1180: Post p = PostCommon.fillPostFromRequest();
1181:
1182: if (p.getText() == null || p.getText().trim().equals("")) {
1183: this .insert();
1184: return;
1185: }
1186:
1187: // Check the elapsed time since the last post from the user
1188: int delay = SystemGlobals
1189: .getIntValue(ConfigKeys.POSTS_NEW_DELAY);
1190:
1191: if (delay > 0) {
1192: Long lastPostTime = (Long) SessionFacade
1193: .getAttribute(ConfigKeys.LAST_POST_TIME);
1194:
1195: if (lastPostTime != null) {
1196: if (System.currentTimeMillis() < (lastPostTime
1197: .longValue() + delay)) {
1198: this .context.put("post", p);
1199: this .context.put("start", this .request
1200: .getParameter("start"));
1201: this .context.put("error", I18n
1202: .getMessage("PostForm.tooSoon"));
1203: this .insert();
1204: return;
1205: }
1206: }
1207: }
1208:
1209: p.setForumId(this .request.getIntParameter("forum_id"));
1210:
1211: if (StringUtils.isBlank(p.getSubject())) {
1212: p.setSubject(t.getTitle());
1213: }
1214:
1215: boolean needCaptcha = SystemGlobals
1216: .getBoolValue(ConfigKeys.CAPTCHA_POSTS)
1217: && request.getSessionContext().getAttribute(
1218: ConfigKeys.REQUEST_IGNORE_CAPTCHA) == null;
1219:
1220: if (needCaptcha) {
1221: if (!us.validateCaptchaResponse(this .request
1222: .getParameter("captcha_anwser"))) {
1223: this .context.put("post", p);
1224: this .context.put("start", this .request
1225: .getParameter("start"));
1226: this .context.put("error", I18n
1227: .getMessage("CaptchaResponseFails"));
1228:
1229: this .insert();
1230:
1231: return;
1232: }
1233: }
1234:
1235: boolean preview = "1".equals(this .request
1236: .getParameter("preview"));
1237:
1238: if (!preview) {
1239: AttachmentCommon attachments = new AttachmentCommon(
1240: this .request, forumId);
1241:
1242: try {
1243: attachments.preProcess();
1244: } catch (AttachmentException e) {
1245: JForumExecutionContext.enableRollback();
1246: p.setText(this .request.getParameter("message"));
1247: p.setId(0);
1248: this .context.put("errorMessage", e.getMessage());
1249: this .context.put("post", p);
1250: this .insert();
1251: return;
1252: }
1253:
1254: Forum forum = ForumRepository.getForum(forumId);
1255: PermissionControl pc = SecurityRepository.get(us
1256: .getUserId());
1257:
1258: // Moderators and admins don't need to have their messages moderated
1259: boolean moderate = (forum.isModerated()
1260: && !pc.canAccess(SecurityConstants.PERM_MODERATION) && !pc
1261: .canAccess(SecurityConstants.PERM_ADMINISTRATION));
1262:
1263: if (newTopic) {
1264: t.setTime(new Date());
1265: t.setTitle(this .request.getParameter("subject"));
1266: t.setModerated(moderate);
1267: t.setPostedBy(u);
1268: t.setFirstPostTime(ViewCommon.formatDate(t.getTime()));
1269:
1270: int topicId = topicDao.addNew(t);
1271: t.setId(topicId);
1272: firstPost = true;
1273: }
1274:
1275: if (!firstPost
1276: && pc
1277: .canAccess(
1278: SecurityConstants.PERM_REPLY_WITHOUT_MODERATION,
1279: Integer.toString(t.getForumId()))) {
1280: moderate = false;
1281: }
1282:
1283: // Topic watch
1284: if (this .request.getParameter("notify") != null) {
1285: this .watch(topicDao, t.getId(), u.getId());
1286: }
1287:
1288: p.setTopicId(t.getId());
1289:
1290: // add a poll
1291: Poll poll = PollCommon.fillPollFromRequest();
1292:
1293: if (poll != null && newTopic) {
1294: poll.setTopicId(t.getId());
1295:
1296: if (poll.getOptions().size() < 2) {
1297: //it is not a valid poll, cancel the post
1298: JForumExecutionContext.enableRollback();
1299: p.setText(this .request.getParameter("message"));
1300: p.setId(0);
1301: this .context
1302: .put(
1303: "errorMessage",
1304: I18n
1305: .getMessage("PostForm.needMorePollOptions"));
1306: this .context.put("post", p);
1307: this .context.put("poll", poll);
1308: this .insert();
1309: return;
1310: }
1311:
1312: poolDao.addNew(poll);
1313: t.setVoteId(poll.getId());
1314: }
1315:
1316: // Save the remaining stuff
1317: p.setModerate(moderate);
1318: int postId = postDao.addNew(p);
1319:
1320: if (newTopic) {
1321: t.setFirstPostId(postId);
1322: }
1323:
1324: if (!moderate) {
1325: t.setLastPostId(postId);
1326: t.setLastPostBy(u);
1327: t.setLastPostDate(p.getTime());
1328: t.setLastPostTime(p.getFormatedTime());
1329: }
1330:
1331: topicDao.update(t);
1332:
1333: attachments.insertAttachments(p);
1334:
1335: if (!moderate) {
1336: StringBuffer path = new StringBuffer(512);
1337: path.append(this .request.getContextPath()).append(
1338: "/posts/list/");
1339:
1340: int start = ViewCommon.getStartPage();
1341:
1342: path
1343: .append(this .startPage(t, start))
1344: .append("/")
1345: .append(t.getId())
1346: .append(
1347: SystemGlobals
1348: .getValue(ConfigKeys.SERVLET_EXTENSION))
1349: .append('#').append(postId);
1350:
1351: JForumExecutionContext.setRedirect(path.toString());
1352:
1353: if (newTopic) {
1354: // Notify "forum new topic" users
1355: ForumCommon.notifyUsers(forum, t, p);
1356: } else {
1357: t.setTotalReplies(t.getTotalReplies() + 1);
1358: TopicsCommon.notifyUsers(t, p);
1359: }
1360:
1361: // Update forum stats, cache and etc
1362: t.setTotalViews(t.getTotalViews() + 1);
1363:
1364: DataAccessDriver.getInstance().newUserDAO()
1365: .incrementPosts(p.getUserId());
1366:
1367: TopicsCommon.updateBoardStatus(t, postId, firstPost,
1368: topicDao, forumDao);
1369: ForumRepository.updateForumStats(t, u, p);
1370:
1371: int anonymousUser = SystemGlobals
1372: .getIntValue(ConfigKeys.ANONYMOUS_USER_ID);
1373:
1374: if (u.getId() != anonymousUser) {
1375: SessionFacade.getTopicsReadTime().put(
1376: new Integer(t.getId()),
1377: new Long(p.getTime().getTime()));
1378: }
1379:
1380: if (SystemGlobals
1381: .getBoolValue(ConfigKeys.POSTS_CACHE_ENABLED)) {
1382: SimpleDateFormat df = new SimpleDateFormat(
1383: SystemGlobals
1384: .getValue(ConfigKeys.DATE_TIME_FORMAT));
1385: p.setFormatedTime(df.format(p.getTime()));
1386:
1387: PostRepository.append(p.getTopicId(), PostCommon
1388: .preparePostForDisplay(p));
1389: }
1390: } else {
1391: JForumExecutionContext
1392: .setRedirect(this .request.getContextPath()
1393: + "/posts/waitingModeration/"
1394: + (firstPost ? 0 : t.getId())
1395: + "/"
1396: + t.getForumId()
1397: + SystemGlobals
1398: .getValue(ConfigKeys.SERVLET_EXTENSION));
1399: }
1400:
1401: if (delay > 0) {
1402: SessionFacade.setAttribute(ConfigKeys.LAST_POST_TIME,
1403: new Long(System.currentTimeMillis()));
1404: }
1405: } else {
1406: this .context.put("preview", true);
1407: this .context.put("post", p);
1408: this .context.put("start", this .request
1409: .getParameter("start"));
1410:
1411: Post postPreview = new Post(p);
1412: this .context.put("postPreview", PostCommon
1413: .preparePostForDisplay(postPreview));
1414:
1415: this .insert();
1416: }
1417: }
1418:
1419: private int startPage(Topic t, int currentStart) {
1420: int postsPerPage = SystemGlobals
1421: .getIntValue(ConfigKeys.POSTS_PER_PAGE);
1422:
1423: int newStart = (t.getTotalReplies() + 1) / postsPerPage
1424: * postsPerPage;
1425:
1426: return (newStart > currentStart) ? newStart : currentStart;
1427: }
1428:
1429: public void delete() {
1430: if (!SecurityRepository
1431: .canAccess(SecurityConstants.PERM_MODERATION_POST_REMOVE)) {
1432: this .setTemplateName(TemplateKeys.POSTS_CANNOT_DELETE);
1433: this .context.put("message", I18n
1434: .getMessage("CannotRemovePost"));
1435:
1436: return;
1437: }
1438:
1439: // Post
1440: PostDAO postDao = DataAccessDriver.getInstance().newPostDAO();
1441: Post p = postDao.selectById(this .request
1442: .getIntParameter("post_id"));
1443:
1444: if (p.getId() == 0) {
1445: this .postNotFound();
1446: return;
1447: }
1448:
1449: TopicDAO topicDao = DataAccessDriver.getInstance()
1450: .newTopicDAO();
1451: Topic t = topicDao.selectRaw(p.getTopicId());
1452:
1453: if (!TopicsCommon.isTopicAccessible(t.getForumId())) {
1454: return;
1455: }
1456:
1457: postDao.delete(p);
1458: DataAccessDriver.getInstance().newUserDAO().decrementPosts(
1459: p.getUserId());
1460:
1461: // Karma
1462: KarmaDAO karmaDao = DataAccessDriver.getInstance()
1463: .newKarmaDAO();
1464: karmaDao.updateUserKarma(p.getUserId());
1465:
1466: // Attachments
1467: new AttachmentCommon(this .request, p.getForumId())
1468: .deleteAttachments(p.getId(), p.getForumId());
1469:
1470: // It was the last remaining post in the topic?
1471: int totalPosts = topicDao.getTotalPosts(p.getTopicId());
1472:
1473: if (totalPosts > 0) {
1474: // Topic
1475: topicDao.decrementTotalReplies(p.getTopicId());
1476:
1477: int maxPostId = topicDao.getMaxPostId(p.getTopicId());
1478: if (maxPostId > -1) {
1479: topicDao.setLastPostId(p.getTopicId(), maxPostId);
1480: }
1481:
1482: int minPostId = topicDao.getMinPostId(p.getTopicId());
1483: if (minPostId > -1) {
1484: topicDao.setFirstPostId(p.getTopicId(), minPostId);
1485: }
1486:
1487: // Forum
1488: ForumDAO fm = DataAccessDriver.getInstance().newForumDAO();
1489:
1490: maxPostId = fm.getMaxPostId(p.getForumId());
1491: if (maxPostId > -1) {
1492: fm.setLastPost(p.getForumId(), maxPostId);
1493: }
1494:
1495: String returnPath = this .request.getContextPath()
1496: + "/posts/list/";
1497:
1498: int page = ViewCommon.getStartPage();
1499:
1500: if (page > 0) {
1501: int postsPerPage = SystemGlobals
1502: .getIntValue(ConfigKeys.POSTS_PER_PAGE);
1503:
1504: if (totalPosts % postsPerPage == 0) {
1505: page -= postsPerPage;
1506: }
1507:
1508: returnPath += page + "/";
1509: }
1510:
1511: JForumExecutionContext.setRedirect(returnPath
1512: + p.getTopicId()
1513: + SystemGlobals
1514: .getValue(ConfigKeys.SERVLET_EXTENSION));
1515:
1516: // Update the cache
1517: if (TopicRepository.isTopicCached(t)) {
1518: t = topicDao.selectById(t.getId());
1519: TopicRepository.updateTopic(t);
1520: }
1521: } else {
1522: // Ok, all posts were removed. Time to say goodbye
1523: TopicsCommon.deleteTopic(p.getTopicId(), p.getForumId(),
1524: false);
1525:
1526: JForumExecutionContext.setRedirect(this .request
1527: .getContextPath()
1528: + "/forums/show/"
1529: + p.getForumId()
1530: + SystemGlobals
1531: .getValue(ConfigKeys.SERVLET_EXTENSION));
1532: }
1533:
1534: this .request.addOrReplaceParameter("log_original_message", p
1535: .getText());
1536: ModerationHelper moderationHelper = new ModerationHelper();
1537: ModerationLog moderationLog = moderationHelper
1538: .buildModerationLogFromRequest();
1539: moderationLog.getPosterUser().setId(p.getUserId());
1540: moderationHelper.saveModerationLog(moderationLog);
1541:
1542: PostRepository.remove(t.getId(), p.getId());
1543: TopicRepository.loadMostRecentTopics();
1544: TopicRepository.loadHottestTopics();
1545: ForumRepository.reloadForum(p.getForumId());
1546: }
1547:
1548: private void watch(TopicDAO tm, int topicId, int userId) {
1549: if (!tm.isUserSubscribed(topicId, userId)) {
1550: tm.subscribeUser(topicId, userId);
1551: }
1552: }
1553:
1554: public void watch() {
1555: int topicId = this .request.getIntParameter("topic_id");
1556: int userId = SessionFacade.getUserSession().getUserId();
1557:
1558: this .watch(DataAccessDriver.getInstance().newTopicDAO(),
1559: topicId, userId);
1560: this .list();
1561: }
1562:
1563: public void unwatch() {
1564: if (!SessionFacade.isLogged()) {
1565: this .setTemplateName(ViewCommon.contextToLogin());
1566: } else {
1567: int topicId = this .request.getIntParameter("topic_id");
1568: int userId = SessionFacade.getUserSession().getUserId();
1569: int start = ViewCommon.getStartPage();
1570:
1571: DataAccessDriver.getInstance().newTopicDAO()
1572: .removeSubscription(topicId, userId);
1573:
1574: String returnPath = this .request.getContextPath()
1575: + "/posts/list/";
1576:
1577: if (start > 0) {
1578: returnPath += start + "/";
1579: }
1580:
1581: returnPath += topicId
1582: + SystemGlobals
1583: .getValue(ConfigKeys.SERVLET_EXTENSION);
1584:
1585: this .setTemplateName(TemplateKeys.POSTS_UNWATCH);
1586: this .context.put("pageTitle", I18n
1587: .getMessage("PostShow.unwatch"));
1588: this .context
1589: .put("message", I18n.getMessage(
1590: "ForumBase.unwatched",
1591: new String[] { returnPath }));
1592: }
1593: }
1594:
1595: public void downloadAttach() {
1596: int id = this .request.getIntParameter("attach_id");
1597:
1598: if (!SessionFacade.isLogged()
1599: && !SystemGlobals
1600: .getBoolValue(ConfigKeys.ATTACHMENTS_ANONYMOUS)) {
1601: String referer = this .request.getHeader("Referer");
1602:
1603: if (referer != null) {
1604: this
1605: .setTemplateName(ViewCommon
1606: .contextToLogin(referer));
1607: } else {
1608: this .setTemplateName(ViewCommon.contextToLogin());
1609: }
1610:
1611: return;
1612: }
1613:
1614: AttachmentDAO am = DataAccessDriver.getInstance()
1615: .newAttachmentDAO();
1616: Attachment a = am.selectAttachmentById(id);
1617:
1618: PostDAO postDao = DataAccessDriver.getInstance().newPostDAO();
1619: Post post = postDao.selectById(a.getPostId());
1620:
1621: String forumId = Integer.toString(post.getForumId());
1622:
1623: boolean attachmentsEnabled = SecurityRepository.canAccess(
1624: SecurityConstants.PERM_ATTACHMENTS_ENABLED, forumId);
1625: boolean attachmentsDownload = SecurityRepository.canAccess(
1626: SecurityConstants.PERM_ATTACHMENTS_DOWNLOAD, forumId);
1627:
1628: if (!attachmentsEnabled && !attachmentsDownload) {
1629: this .setTemplateName(TemplateKeys.POSTS_CANNOT_DOWNLOAD);
1630: this .context.put("message", I18n
1631: .getMessage("Attachments.featureDisabled"));
1632: return;
1633: }
1634:
1635: String filename = SystemGlobals
1636: .getValue(ConfigKeys.ATTACHMENTS_STORE_DIR)
1637: + "/" + a.getInfo().getPhysicalFilename();
1638:
1639: if (!new File(filename).exists()) {
1640: this .setTemplateName(TemplateKeys.POSTS_ATTACH_NOTFOUND);
1641: this .context.put("message", I18n
1642: .getMessage("Attachments.notFound"));
1643: return;
1644: }
1645:
1646: FileInputStream fis = null;
1647: OutputStream os = null;
1648:
1649: try {
1650: a.getInfo().setDownloadCount(
1651: a.getInfo().getDownloadCount() + 1);
1652: am.updateAttachment(a);
1653:
1654: fis = new FileInputStream(filename);
1655: os = response.getOutputStream();
1656:
1657: if (am.isPhysicalDownloadMode(a.getInfo().getExtension()
1658: .getExtensionGroupId())) {
1659: this .response
1660: .setContentType("application/octet-stream");
1661: } else {
1662: this .response.setContentType(a.getInfo().getMimetype());
1663: }
1664:
1665: if (this .request.getHeader("User-Agent").indexOf("Firefox") != -1) {
1666: this .response
1667: .setHeader(
1668: "Content-Disposition",
1669: "attachment; filename=\""
1670: + new String(
1671: a
1672: .getInfo()
1673: .getRealFilename()
1674: .getBytes(
1675: SystemGlobals
1676: .getValue(ConfigKeys.ENCODING)),
1677: SystemGlobals
1678: .getValue(ConfigKeys.DEFAULT_CONTAINER_ENCODING))
1679: + "\";");
1680: } else {
1681: this .response.setHeader("Content-Disposition",
1682: "attachment; filename=\""
1683: + ViewCommon.toUtf8String(a.getInfo()
1684: .getRealFilename()) + "\";");
1685: }
1686:
1687: this .response.setContentLength((int) a.getInfo()
1688: .getFilesize());
1689:
1690: int c;
1691: byte[] b = new byte[4096];
1692: while ((c = fis.read(b)) != -1) {
1693: os.write(b, 0, c);
1694: }
1695:
1696: JForumExecutionContext.enableCustomContent(true);
1697: } catch (IOException e) {
1698: throw new ForumException(e);
1699: } finally {
1700: if (fis != null) {
1701: try {
1702: fis.close();
1703: } catch (Exception e) {
1704: }
1705: }
1706:
1707: if (os != null) {
1708: try {
1709: os.close();
1710: } catch (Exception e) {
1711: }
1712: }
1713: }
1714: }
1715:
1716: private void cannotEdit() {
1717: this .setTemplateName(TemplateKeys.POSTS_EDIT_CANNOTEDIT);
1718: this .context.put("message", I18n.getMessage("CannotEditPost"));
1719: }
1720:
1721: private void topicLocked() {
1722: this .setTemplateName(TemplateKeys.POSTS_TOPIC_LOCKED);
1723: this .context.put("message", I18n
1724: .getMessage("PostShow.topicLocked"));
1725: }
1726:
1727: public void listSmilies() {
1728: this .setTemplateName(SystemGlobals
1729: .getValue(ConfigKeys.TEMPLATE_DIR)
1730: + "/empty.htm");
1731: this .setTemplateName(TemplateKeys.POSTS_LIST_SMILIES);
1732: this .context.put("smilies", SmiliesRepository.getSmilies());
1733: }
1734:
1735: private boolean isForumReadonly(int forumId, boolean isReply) {
1736: if (!SecurityRepository.canAccess(
1737: SecurityConstants.PERM_READ_ONLY_FORUMS, Integer
1738: .toString(forumId))) {
1739: if (isReply) {
1740: this .list();
1741: } else {
1742: JForumExecutionContext
1743: .setRedirect(this .request.getContextPath()
1744: + "/forums/show/"
1745: + forumId
1746: + SystemGlobals
1747: .getValue(ConfigKeys.SERVLET_EXTENSION));
1748: }
1749:
1750: return true;
1751: }
1752:
1753: return false;
1754: }
1755:
1756: private boolean anonymousPost(int forumId) {
1757: // Check if anonymous posts are allowed
1758: if (!SessionFacade.isLogged()
1759: && !SecurityRepository.canAccess(
1760: SecurityConstants.PERM_ANONYMOUS_POST, Integer
1761: .toString(forumId))) {
1762: this .setTemplateName(ViewCommon.contextToLogin());
1763:
1764: return false;
1765: }
1766:
1767: return true;
1768: }
1769: }
|