package controllers; import controllers.Navigation.Level; import managers.AccountManager; import managers.GroupManager; import managers.PostBookmarkManager; import managers.PostManager; import models.Account; import models.Group; import models.Post; import models.PostBookmark; import models.services.NotificationService; import play.Configuration; import play.Logger; import play.api.i18n.Lang; import play.api.mvc.Call; import play.data.Form; import play.data.FormFactory; import play.db.jpa.Transactional; import play.i18n.MessagesApi; import play.mvc.Result; import play.mvc.Security; import views.html.Post.view; import javax.inject.Inject; import java.util.List; @Security.Authenticated(Secured.class) public class PostController extends BaseController { final Logger.ALogger LOG = Logger.of(PostController.class); GroupManager groupManager; PostManager postManager; PostBookmarkManager postBookmarkManager; AccountManager accountManager; Configuration configuration; FormFactory formFactory; NotificationService notificationService; MessagesApi messagesApi; @Inject public PostController(GroupManager groupManager, PostManager postManager, PostBookmarkManager postBookmarkManager, AccountManager accountManager, Configuration configuration, FormFactory formFactory, NotificationService notificationService, MessagesApi messagesApi) { this.groupManager = groupManager; this.postManager = postManager; this.postBookmarkManager = postBookmarkManager; this.accountManager = accountManager; this.configuration = configuration; this.formFactory = formFactory; this.notificationService = notificationService; this.messagesApi = messagesApi; this.postForm = formFactory.form(Post.class); } Form<Post> postForm; static final int PAGE = 1; static final String STREAM_FILTER = "all"; public Result view(Long id) { Post post = postManager.findById(id); if (post == null) { return redirect(controllers.routes.Application.error()); } if (post.parent != null) { return redirect(controllers.routes.Application.error()); } if (!Secured.viewPost(post)) { return redirect(controllers.routes.Application.index()); } if (postManager.belongsToGroup(post)) { Navigation.set(Level.GROUPS, "Post", post.group.title, controllers.routes.GroupController.stream(post.group.id, PAGE, false)); } if (post.belongsToAccount()) { Navigation.set(Level.FRIENDS, "Post", post.account.name, controllers.routes.ProfileController.stream(post.account.id, PAGE, false)); } return ok(view.render(post, postForm)); } /** * Adds a post. * * @param anyId can be a accountId or groupId * @param target define target stream: profile-stream, group-stream * @return Result */ @Transactional public Result addPost(Long anyId, String target) { Account account = Component.currentAccount(); Form<Post> filledForm = postForm.bindFromRequest(); if (target.equals(Post.GROUP)) { Group group = groupManager.findById(anyId); if (Secured.isMemberOfGroup(group, account)) { if (filledForm.hasErrors()) { flash("error", messagesApi.get(Lang.defaultLang(), "post.try_with_content")); } else { Post post = filledForm.get(); post.owner = Component.currentAccount(); post.group = group; postManager.create(post); notificationService.createNotification(post, Post.GROUP); LOG.info("New post from " + post.owner.id + " in " + group.title); } } else { flash("info", messagesApi.get(Lang.defaultLang(), "post.join_group_first")); } return redirect(controllers.routes.GroupController.stream(group.id, PAGE, false)); } if (target.equals(Post.PROFILE)) { Account profile = accountManager.findById(anyId); if (Secured.isNotNull(profile) && (Secured.isFriend(profile) || profile.equals(account) || Secured.isAdmin())) { if (filledForm.hasErrors()) { flash("error", messagesApi.get(Lang.defaultLang(), "post.try_with_content")); } else { Post post = filledForm.get(); post.account = profile; post.owner = account; postManager.create(post); if (!account.equals(profile)) { notificationService.createNotification(post, Post.PROFILE); } } return redirect(controllers.routes.ProfileController.stream(anyId, PAGE, false)); } flash("info", messagesApi.get(Lang.defaultLang(), "post.post_on_stream_only")); return redirect(controllers.routes.ProfileController.stream(anyId, PAGE, false)); } if (target.equals(Post.STREAM)) { Account profile = accountManager.findById(anyId); if (Secured.isNotNull(profile) && profile.equals(account)) { if (filledForm.hasErrors()) { flash("error", messagesApi.get(Lang.defaultLang(), "post.try_with_content")); } else { Post post = filledForm.get(); post.account = profile; post.owner = account; postManager.create(post); } return redirect(controllers.routes.Application.stream(STREAM_FILTER, PAGE, false)); } flash("info", messagesApi.get(Lang.defaultLang(), "post.post_on_stream_only")); return redirect(controllers.routes.Application.stream(STREAM_FILTER, PAGE, false)); } return redirect(controllers.routes.Application.index()); } @Transactional public Result addComment(long postId) { final Post parent = postManager.findById(postId); final Account account = Component.currentAccount(); if (!Secured.addComment(parent)) { return badRequest(); } final Form<Post> filledForm = postForm.bindFromRequest(); if (filledForm.hasErrors()) { return badRequest(); } else { final Post post = filledForm.get(); post.owner = account; post.parent = parent; postManager.create(post); // update parent to move it to the top postManager.update(parent); if (postManager.belongsToGroup(parent)) { // this is a comment in a group post notificationService.createNotification(post, Post.COMMENT_GROUP); } if (postManager.belongsToAccount(parent)) { if (!account.equals(parent.owner) && !parent.account.equals(parent.owner)) { // this is a comment on a news stream post from another person notificationService.createNotification(post, Post.COMMENT_OWN_PROFILE); } else if (!account.equals(parent.account)) { // this is a comment on a foreign news stream post notificationService.createNotification(post, Post.COMMENT_PROFILE); } } LOG.info("New comment from " + post.owner.id + " for post " + post.parent.id); return ok(views.html.snippets.postComment.render(post)); } } public Result getEditForm(Long postId) { Post post = postManager.findById(postId); Account account = Component.currentAccount(); if (!Secured.isPostStillEditable(post, account)) { return badRequest(); } return ok(views.html.snippets.editPost.render(post, postForm.fill(post))); } @Transactional public Result updatePost(Long postId) { Post post = postManager.findById(postId); Account account = Component.currentAccount(); if (!Secured.isPostStillEditableWithTolerance(post, account)) { return badRequest(); } else { Form<Post> filledForm = postForm.bindFromRequest(); if (filledForm.hasErrors()) { return badRequest(); } else { Post newPost = filledForm.get(); post.content = newPost.content; postManager.create(post); // updates elasticsearch stuff postManager.update(post); return ok(post.content); } } } @Transactional public static List<Post> getComments(Long id, int limit) { //int max = Integer.parseInt(Play.application().configuration().getString("htwplus.comments.init")); int offset = 0; if (limit != 0) { offset = PostManager.countCommentsForPost2(id) - limit; } return PostManager.getCommentsForPost2(id, limit, offset); } @Transactional public Result getOlderComments(Long id, Integer current) { Post parent = postManager.findById(id); if (!Secured.viewComments(parent)) { return badRequest(); } String result = ""; // subtract already displayed comments int limit = postManager.countCommentsForPost(id) - Integer.parseInt(configuration.getString("htwplus.comments.init")); List<Post> comments; comments = postManager.getCommentsForPost(id, limit, 0); for (Post post : comments) { result = result.concat(views.html.snippets.postComment.render(post).toString()); } return ok(result); } @Transactional public Result deletePost(Long postId) { Post post = postManager.findById(postId); Account account = Component.currentAccount(); Call routesTo = null; if (Secured.isAllowedToDeletePost(post, account)) { //verify redirect if (post.group != null) { routesTo = controllers.routes.GroupController.stream(post.group.id, PAGE, false); } if (post.account != null) { routesTo = controllers.routes.Application.index(); } if (post.parent != null) { if (post.parent.group != null) { routesTo = controllers.routes.GroupController.stream(post.parent.group.id, PAGE, false); } else if (post.parent.account != null) { routesTo = controllers.routes.Application.index(); } } postManager.delete(post); flash("success", "Gelöscht!"); } else { flash("error", "Konnte nicht gelöscht werden!"); } if (routesTo == null) { routesTo = controllers.routes.Application.index(); } return redirect(routesTo); } public Result bookmarkPost(Long postId) { Account account = Component.currentAccount(); Post post = postManager.findById(postId); String returnStatement = ""; if (Secured.viewPost(post)) { PostBookmark possibleBookmark = postBookmarkManager.findByAccountAndPost(account, post); if (possibleBookmark == null) { postBookmarkManager.create(new PostBookmark(account, post)); returnStatement = "setBookmark"; } else { postBookmarkManager.delete(possibleBookmark); returnStatement = "removeBookmark"; } } return ok(returnStatement); } }