require 'uri'
class Comment < Content
validates_presence_of :author, :author_ip, :article_id, :body
validates_format_of :author_email, :with => Format::EMAIL
before_validation :clean_up_author_email
before_validation :clean_up_author_url
after_validation_on_create :snag_article_attributes
before_create :check_comment_expiration
before_create :sanitize_attributes
before_save :update_counter_cache
before_destroy :decrement_counter_cache
belongs_to :article
has_one :event, :dependent => :destroy
before_create :check_if_previewing
attr_accessible :article, :article_id, :user_id, :user, :excerpt, :body, :author, :author_url, :author_email, :author_ip, :updater_id, :updater, :comment_age, :user_agent, :referrer, :preview
attr_accessor :preview
class Previewing < StandardError; end
# If the view sends the "preview" accessor, we raise this
# error so the controller can simply rescue
def check_if_previewing
raise Comment::Previewing if preview
end
def self.find_all_by_section(section, options = {})
find :all, options.update(:conditions => ['contents.approved = ? and assigned_sections.section_id = ?', true, section.id],
:select => 'contents.*', :joins => 'INNER JOIN assigned_sections ON assigned_sections.article_id = contents.article_id',
:order => 'contents.created_at DESC')
end
def to_liquid
CommentDrop.new self
end
def approved=(value)
@old_approved ||= approved? ? :true : :false
write_attribute :approved, value
end
def clean_up_author_email
if value = read_attribute(:author_email) then
write_attribute :author_email, value.strip
end
end
def clean_up_author_url
if value = read_attribute(:author_url) then
value.strip!
value = 'http://' + value unless value.blank? || value[0..0] == '/' || URI::parse(value).scheme
write_attribute :author_url, value
end
rescue URI::InvalidURIError
write_attribute :author_url, nil
end
def article_referenced_cache_key
"[#{article_id}:Article]"
end
def check_approval(site, request, options={})
options.reverse_merge!(:authenticated => false)
self.approved = site.approve_comments? || spam_engine(site).ham?(article.permalink_url(site, request), self, :authenticated => options[:authenticated])
end
def mark_as_spam(site, request)
spam_engine(site).mark_as_spam(article.permalink_url(site, request), self)
end
def mark_as_ham(site, request)
spam_engine(site).mark_as_ham(article.permalink_url(site, request), self)
end
def spam_engine_info
spam_engine(site).info(self)
end
def spam_engine_classes
spam_engine(self.site).classes(self)
end
protected
def spam_engine(site)
site.spam_engine
end
def sanitize_attributes
[:author, :author_url, :author_email, :author_ip, :user_agent, :referrer].each do |a|
self.send("#{a}=", CGI::escapeHTML(self.send(a).to_s))
end
end
def snag_article_attributes
self.filter ||= article.site.filter
[:site, :title, :published_at, :permalink].each { |a| self.send("#{a}=", article.send(a)) }
end
def check_comment_expiration
raise Article::CommentNotAllowed, "#{article.status} does not allow comments" unless article.accept_comments?
end
def update_counter_cache
Article.increment_counter 'comments_count', article_id if approved? && @old_approved == :false
Article.decrement_counter 'comments_count', article_id if !approved? && @old_approved == :true
end
def decrement_counter_cache
Article.decrement_counter 'comments_count', article_id if approved?
end
end