class TopicController < ApplicationController helper :forum # Use HubSsoLib for permissions management, as a layer on top of # the provision within RForum. @@hubssolib_permissions = HubSsoLib::Permissions.new({ :new => [ :admin, :webmaster, :privileged, :normal ], :subscribe => [ :admin, :webmaster, :privileged, :normal ], :unsubscribe => [ :admin, :webmaster, :privileged, :normal ], :delete_post => [ :admin, :webmaster, :privileged, :normal ], :move => [ :admin, :webmaster, :privileged ], :undelete_post => [ :admin, :webmaster, :privileged ] }) def TopicController.hubssolib_permissions @@hubssolib_permissions end # Display a topic. If reply_to parameter is included, handle the post editing form, too def show begin @topic = Topic.find(@params['id']) rescue ActiveRecord::RecordNotFound render_text "Topic not found", 404 return end @title = @topic.subject @forum = @topic.forum return if redirect_if_site_doesnt_match raise RForum::SecurityError if @topic.hidden? && !@user.can_view_deleted_posts?(@topic) # Get the time of the last visit @last_read_at = @user.last_read_time(@topic) || Time.at(0) unless @user.guest? @user.update_read_time(@topic).updated_at unless @user.guest? @posts = @topic.posts_with_user_data(include_hidden = @user.can_view_deleted_posts?(@topic)) if @params['post'] begin if not @params['post']['id'].to_s.empty? # Edit post; check permission and update text and subject raise RForum::SecurityError unless @user.can_edit?(Post.find(@params['post']['id'])) post = Post.update(@params['post']['id'], {'subject' => @params['post']['subject'], 'text' => @params['post']['text']}) else # Create reply raise RForum::SecurityError unless @user.can_reply? post = prepare_post_from_params(@params['post']) post.parent_id = @params['post']['parent_id'] parent = Post.find(@params['post']['parent_id']) if parent.topic.forum.readonly == 1 render_text 'This forum does not allow posts.' end parent.add_reply(post) end display_post(post) # on error, re-render the same topic with the form again rescue RForum::ValidationError => e @post = e.entity end # if reply_to parameter specified, prepare template inputs for a post editing form elsif @params['reply_to'] if @forum.readonly == 1 render_text 'This forum does not allow posts.' end raise RForum::SecurityError unless @user.can_post? @no_robots = true @post = prepare_reply_for_form(@params['reply_to']) elsif @params['edit'] @no_robots = true @post = Post.find(@params['edit']) raise RForum::SecurityError unless @user.can_edit?(@post) end end # If this action is called via a hyperlink, it displays a form # Submit button on the same form reinvokes the same action, but also puts the form data # into @params['post'], and in that case the action creates the form. # If form creation fails due to validation errors, the form is re-displayed; otherwise # user is redirected to the post in the topic def new raise RForum::SecurityError unless @user.can_post? @no_robots = true @forum = Forum.find(@params['forum_id']) rescue Forum.find_first @title = "New post in forum '#{@forum.name}'" if @forum.readonly == 1 render_text 'This forum does not allow posts.' return end if @params['post'] # Form submitted new_post = prepare_post_from_params(@params['post']) begin saved_post = @forum.add_post(new_post) display_post(saved_post) rescue RForum::ValidationError => e # on error, re-render the form again @post = e.entity end else return if redirect_if_site_doesnt_match @post = Post.new @post.author = @user end end def move topic = Topic.find(@params['id']) raise RForum::SecurityError unless @user.can_move?(topic) @title = l(:move_topic_title) if @params['to'] new_forum = Forum.find(@params['to']) topic.forum = new_forum topic.save redirect_to :action => 'show', :id => topic.id else @topic = topic end end # Delete a topic or a single post def delete_post post = Post.find(@params['id']) raise RForum::SecurityError unless @user.can_delete?(post) recursive = @user.can_delete_recursive?(post) && (@params['recursive'].to_i == 1) if post.root? Post.transaction do post.topic.hide end redirect_to :controller => 'forum', :action => 'forum', :id => post.topic.forum_id else Post.transaction do post.hide(recursive) end redirect_to :controller => 'topic', :action => 'show', :id => post.topic_id end end # Undelete a single post def undelete_post post = Post.find(@params['id']) raise RForum::SecurityError unless @user.can_undelete?(post) recursive = @user.can_undelete_recursive?(post) && (@params['recursive'].to_i == 1) if post.root? Post.transaction do post.topic.unhide(recursive) end redirect_to :controller => 'topic', :action => 'show', :id => post.topic_id else Post.transaction do post.unhide(recursive) end redirect_to :controller => 'topic', :action => 'show', :id => post.topic_id, :anchor => post.id end end # Subscribe to receive notification about new posts in this topic. def subscribe @topic = Topic.find(@params['id']) unless @user.guest? @user.subscribe_topic(@topic) end flash[:attention] = 'Email notification for new posts in this topic is now enabled.' redirect_to :controller => 'topic', :action => 'show', :id => @topic.id end def unsubscribe @topic = Topic.find(@params['id']) unless @user.guest? # Ignore errors; if the user wasn't subscribed anyway, there's no need # to moan about it. @user.unsubscribe_topic(@topic) end flash[:attention] = 'Email notification for new posts in this topic is now disabled.' redirect_to :controller => 'topic', :action => 'show', :id => @topic.id end private def display_post(post) redirect_to :controller => 'topic', :action => 'show', :id => post.topic_id, :anchor => post.id end def prepare_reply_for_form(reply_to_id) reply_to = Post.find_with_user_data(reply_to_id) post = Post.new( 'topic_id' => reply_to.topic_id, 'parent_id' => reply_to.id, 'subject' => reply_to.reply_subject, 'text' => "#{reply_to.get_display_name} wrote:\n#{reply_to.quoted_text}\n\n") post.author = @user return post end # prepare a Post object from a form, update @user with guest_name and guest_email def prepare_post_from_params(form_attributes) new_post = Post.new if form_attributes['new_attachment'] && form_attributes['new_attachment'].size > 0 new_post.new_attachment = form_attributes['new_attachment'] end new_post.subject = form_attributes['subject'] new_post.text = form_attributes['text'] if @user.guest? @user.guest_name = form_attributes['guest_name'] @user.guest_email = form_attributes['guest_email'] end new_post.author = @user new_post.author_host = @request.remote_ip return new_post end end