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