discourse/app/models/incoming_link.rb
Sam f9e33ec6b8 store ip address and current user with incoming links
make links long an readable in share dialog
2013-04-26 16:18:55 +10:00

88 lines
2.3 KiB
Ruby

class IncomingLink < ActiveRecord::Base
belongs_to :topic
validates :url, presence: true
validate :referer_valid
before_validation :extract_domain
before_validation :extract_topic_and_post
after_create :update_link_counts
def self.add(request,current_user=nil)
user_id, host, referer = nil
if request['u']
u = User.select(:id).where(username_lower: request['u'].downcase).first
user_id = u.id if u
end
if request.referer.present?
host = URI.parse(request.referer).host
referer = request.referer[0..999]
end
if host != request.host && (user_id || referer)
cid = current_user.id if current_user
unless cid && cid == user_id
IncomingLink.create(url: request.url,
referer: referer,
user_id: user_id,
current_user_id: cid,
ip_address: request.remote_ip)
end
end
end
# Internal: Extract the domain from link.
def extract_domain
if referer.present?
self.domain = URI.parse(referer).host
end
end
# Internal: If link is internal and points to topic/post, extract their IDs.
def extract_topic_and_post
if url.present?
parsed = URI.parse(url)
begin
params = Rails.application.routes.recognize_path(parsed.path)
self.topic_id = params[:topic_id]
self.post_number = params[:post_number]
rescue ActionController::RoutingError
# If we can't route to the url, that's OK. Don't save those two fields.
end
end
end
# Internal: Update appropriate link counts.
def update_link_counts
if topic_id.present?
exec_sql("UPDATE topics
SET incoming_link_count = incoming_link_count + 1
WHERE id = ?", topic_id)
if post_number.present?
exec_sql("UPDATE posts
SET incoming_link_count = incoming_link_count + 1
WHERE topic_id = ? and post_number = ?", topic_id, post_number)
end
end
end
protected
def referer_valid
return true unless referer
if (referer.length < 3 || referer.length > 100) || (domain.length < 1 || domain.length > 100)
# internal, no need to localize
errors.add(:referer, 'referer is invalid')
false
else
true
end
end
end