module Comments #:nodoc: module Model ## # Model for managing and retrieving comments. # # ## Events # # All events called in this model receive an instance of # {Comments::Model::Comment}. However, just like all other models the # ``delete_comment`` event 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 # @event before\_new\_comment # @event after\_new\_comment # @event before\_edit\_comment # @event after\_edit\_comment # @event beore\_delete\_comment # @event after\_delete\_comment # class Comment < Sequel::Model include Zen::Model::Helper ## # Array containing all the columns that can be set by the user. # # @since 2012-02-17 # COLUMNS = [ :user_id, :name, :website, :email, :comment, :comment_status_id, :section_entry_id ] many_to_one :section_entry, :class => 'Sections::Model::SectionEntry', :eager => [:section] many_to_one :user, :class => 'Users::Model::User' many_to_one :comment_status, :class => 'Comments::Model::CommentStatus' plugin :timestamps, :create => :created_at, :update => :updated_at plugin :events, :before_create => :before_new_comment, :after_create => :after_new_comment, :before_update => :before_edit_comment, :after_update => :after_edit_comment, :before_destroy => :before_delete_comment, :after_destroy => :after_delete_comment ## # Searches for a number of comments based on the given search query. The # following fields can be searched: # # * comments.comment # * comments.email # * comments.name # * users.email # * users.name # # @since 2011-10-16 # @param [String] query The search query. # @return [Array] # def self.search(query) return select_all(:comments) \ .filter( search_column(:comment, query) | search_column(:users__email, query) | search_column(:comments__email, query) | search_column(:comments__name, query) | search_column(:users__name, query) ) \ .eager(:user, :comment_status) \ .left_join(:users, :comments__user_id => :users__id) end ## # Returns a hash containing all available statuses for each comment. # # @example # Comments::Model::Comment.status_hash # # @since 0.2 # @return [Hash] # def self.status_hash statuses = {} ::Comments::Model::CommentStatus.all.each do |status| statuses[status.id] = Zen::Language.lang( "comments.labels.#{status.name}" ) end return statuses end ## # Specify the validation rules for each comment. # # @since 0.1 # def validate validates_presence([:comment, :section_entry_id]) validates_integer([:comment_status_id, :section_entry_id]) validates_max_length(255, [:name, :email, :website]) if user_id.nil? validates_presence([:name, :email]) end end ## # Hook run before saving an existing comment. # # @since 0.2.6 # def before_save sanitize_fields([:name, :website, :email, :comment], true) # Get the default status of a comment if self.comment_status_id.nil? self.comment_status_id = ::Comments::Model::CommentStatus[ :name => 'closed' ].id end super end ## # Gets the name of the author of the comment. This name is either # retrieved from the current comment row or from an associated user # object. # # @since 2011-10-16 # @return [String] # def user_name if user.nil? return name else return user.name end end ## # Gets the Email address of the author of the comment. # # @since 2011-10-16 # @return [String] # def user_email if user.nil? return email else return user.email end end ## # Gets the website of the author of the comment and optionally creates an # anchor tag for it. # # @since 2011-10-16 # @param [TrueClass|FalseClass] with_link When set to true the website # will be returned as an ```` tag. # @param [String] text The alternative text to use for the link tag. # @return [String] # def user_website(with_link = false, text = nil) if user.nil? website = website else website = user.website end if !website.nil? and !website.empty? and with_link == true link_text = text || website website = '%s' % [ website, website, link_text ] end return website end ## # Returns the first 15 characters of a comment, optionally wrapped in a # link that points to the form to edit the comment. # # @since 2011-10-17 # @param [TrueClass|FalseClass] with_link When set to true the comment # will be wrapped in an ```` tag. # @return [String] # def summary(with_link = false) _comment = comment || '' _comment = _comment[0, 15] + '...' if with_link == true return '%s' % [ Comments::Controller::Comments.r(:edit, id), _comment ] else return _comment end end ## # Returns the text of the comment in HTML based on the markup engine used # by the section that the comment belongs to. # # @since 0.3 # @return [String] # def html return Zen::Markup.convert( section_entry.section.comment_format, comment ) end ## # Returns the name of the comment status. # # @since 2011-10-17 # @return [String] # def status_name return lang("comments.labels.#{comment_status.name}") end end # Comment end # Model end # Comments