lib/zen/package/comments/lib/comments/controller/comments.rb in zen-0.2.8 vs lib/zen/package/comments/lib/comments/controller/comments.rb in zen-0.3b

- old
+ new

@@ -1,116 +1,178 @@ -#:nodoc: +## +# Package that allows users to manage and submit comments. +# +# ## Controllers +# +# * {Comments::Controller::Comments} +# * {Comments::Controller::CommentsForm} +# +# ## Helpers +# +# * {Ramaze::Helper::Comment} +# * {Ramaze::Helper::CommentFrontend} +# +# ## Models +# +# * {Comments::Model::Comment} +# * {Comments::Model::CommentStatus} +# +# ## Generic Modules & Classes +# +# * {Comments::AntiSpam} +# +# @since 0.1 +# module Comments #:nodoc: module Controller ## - # Controller used for managing comments. Administrations can't actually - # add new comments using the backend controller but can edit or delete them. - # Comments can be submitted to any section entry as long as the section - # allows it. When submitting a comment the user data such as the name and - # email will be retrieved from either the users table (if the user is logged - # in) or from the form that was submitted. + # Controller for managing existing comments. When logged in a user can not + # add a comment, for that they'd have to use the frontend. # - # @author Yorick Peterse - # @since 0.1 + # Depending on the settings of a section the comments belong to (via a + # section entry) users may have to meet certain requirements in order to be + # able to post a comment. For example, a section might require users to be + # logged in in order to post comments. If this is the case and the user + # tries to submit a comment a message will be displayed and the HTTP status + # code is changed to 403. See {Comments::Controller::CommentsForm} for more + # information. # + # In order to manage existing comments you'll have to navigate to + # ``/admin/comments``. This page will show an overview of all existing + # comments (or a message if no comments were found). + # + # ![Comments](../../_static/comments/comments.png) + # + # Comments can be edited by clicking on their name. Deleting comments can be + # done by checking the checkboxes in each row followed by clicking the + # "Delete selected comments" button. + # + # ## Editing Comments + # + # ![Edit Comment](../../_static/comments/edit_comment.png) + # + # When editing a comment you can specify/update the following fields: + # + # * **Name**: the name of the author. This field can only be changed if the + # comment was posted by somebody that wasn't logged in. + # * **Website**: the website of the author that posted the comment. + # * **Email**: the Email address of the author. If the comment was posted by + # a user that wasn't logged in then this field is required. + # * **Status**: the status of a comment, can be "Open", "Closed" or "Spam". + # If the status is something other than "Open" it will be hidden when the + # comments plugin is used. + # * **Comment** (required): the actual comment. Based on a section's + # settings these are formatted using Markdown, Textile or any of the other + # available markup processors. + # + # Note that if a comment was posted by a user that was logged in you won't + # be able to change the name of the author. + # + # ## Used Permissions + # + # This controller uses the following permissions: + # + # * show_comment + # * edit_comment + # * new_comment + # * delete_comment + # + # ## Events + # + # All events called in this controller receive an instance of + # {Comments::Model::Comment}. However, just like all other controllers the + # ``delete_comment`` receives an instance of this model that has already + # been destroyed. + # + # An example of using one of these events is to notify a user when his + # comment has been marked as spam: + # + # require 'mail' + # + # Zen::Event.call(:after_edit_comment) do |comment| + # email = comment.user.email + # spam = Comments::Model::CommentStatus[:name => 'spam'] + # + # if comment.comment_status_id == spam.id + # Mail.deliver do + # from 'example@domain.tld' + # to email + # subject 'Your comment has been marked as spam' + # body "Dear #{comment.user.name}, your comment has been " \ + # "marked as spam" + # end + # end + # end + # + # @since 0.1 + # @map /admin/comments + # @event before_edit_comment + # @event after_edit_comment + # @event beore_delete_comment + # @event after_delete_comment + # class Comments < Zen::Controller::AdminController - include ::Comments::Model - - map '/admin/comments' + map '/admin/comments' helper :comment + title 'comments.titles.%s' - before_all do - csrf_protection(:save, :delete) do - respond(lang('zen_general.errors.csrf'), 403) - end - end + csrf_protection :save, :delete ## - # Constructor method that pre-loads several variables and language files. - # The following language files are loaded: + # Shows an overview of all existing comments and allows the user to edit + # or remove these comments. # - # * comments + # @since 0.1 + # @permission show_comment # - # @author Yorick Peterse - # @since 0.1 - # - def initialize - super + def index + authorize_user!(:show_comment) - Zen::Language.load('comments') + set_breadcrumbs(lang('comments.titles.index')) - # Set the page title - if !action.method.nil? - method = action.method.to_s - @page_title = lang("comments.titles.#{method}") rescue nil + @comments = search do |query| + ::Comments::Model::Comment.search(query).order(:comments__id.asc) end - end - ## - # Shows an overview of all posted comments along with their status, - # author and so on. - # - # This method requires the following permissions: - # - # * read - # - # @author Yorick Peterse - # @since 0.1 - # - def index - require_permissions(:read) + @comments ||= ::Comments::Model::Comment \ + .eager(:comment_status, :user) \ + .order(:id.asc) - set_breadcrumbs(lang('comments.titles.index')) - - @comments = paginate(Comment.eager(:comment_status)) + @comments = paginate(@comments) end ## - # Edits an existing comment based on the ID. + # Allows a user to edit an existing comment. # - # This method requires the following permissions: + # @param [Fixnum] id The ID of the comment to edit. + # @since 0.1 + # @permission edit_comment # - # * read - # * update - # - # @author Yorick Peterse - # @param [Integer] id The ID of the comment to retrieve so that we can - # edit it. - # @since 0.1 - # def edit(id) - require_permissions(:read, :update) + authorize_user!(:edit_comment) set_breadcrumbs( Comments.a(lang('comments.titles.index'), :index), @page_title ) - if flash[:form_data] - @comment = flash[:form_data] - else - @comment = validate_comment(id) - end + @comment = flash[:form_data] || validate_comment(id) render_view(:form) end ## - # Saves a comment based on the current POST data. Note that this - # method won't create a new comment as this can't be done using the - # backend. + # Saves the changes made to an existing comment. # - # This method requires the following permissions: + # @since 0.1 + # @permission edit_comment + # @event before_edit_comment + # @event after_edit_comment # - # * update - # - # @author Yorick Peterse - # @since 0.1 - # def save - require_permissions(:update) + authorize_user!(:edit_comment) # Copy the POST data so we can work with it without messing things up post = request.subset( :id, :user_id, @@ -125,63 +187,68 @@ comment = validate_comment(post['id']) post.delete('id') begin - comment.update(post) - message(:success, lang('comments.success.save')) + post.each { |k, v| comment.send("#{k}=", v) } + Zen::Event.call(:before_edit_comment, comment) + + comment.save rescue => e Ramaze::Log.error(e.inspect) message(:error, lang('comments.errors.save')) flash[:form_errors] = comment.errors flash[:form_data] = comment redirect_referrer end - # Redirect the user to the proper page. - if comment.id - redirect(Comments.r(:edit, comment.id)) - else - redirect_referrer - end + Zen::Event.call(:after_edit_comment, comment) + + message(:success, lang('comments.success.save')) + redirect(Comments.r(:edit, comment.id)) end ## - # Deletes a number of comments based on the comment IDs specified - # in the POST array "comment_ids". + # Deletes a number of comments. The IDs of these comments should be + # specified in the POSt array "comment_ids". # - # This method requires the following permissions: + # @since 0.1 + # @permission delete_comment + # @event before_delete_comment + # @event after_delete_comment # - # * delete - # - # @author Yorick Peterse - # @since 0.1 - # def delete - require_permissions(:delete) + authorize_user!(:delete_comment) # Obviously we'll require some IDs if !request.params['comment_ids'] \ or request.params['comment_ids'].empty? message(:error, lang('comments.errors.no_delete')) redirect_referrer end # Delete each section request.params['comment_ids'].each do |id| + comment = ::Comments::Model::Comment[id] + + next if comment.nil? + Zen::Event.call(:before_delete_comment, comment) + begin - Comment[id].destroy - message(:success, lang('comments.success.delete')) + comment.destroy rescue => e Ramaze::Log.error(e.inspect) message(:error, lang('comments.errors.delete') % id) redirect_referrer end + + Zen::Event.call(:after_delete_comment, comment) end + message(:success, lang('comments.success.delete')) redirect_referrer end end # Comments end # Controller end # Comments