mirror of
https://github.com/discourse/discourse.git
synced 2024-11-24 22:26:29 +08:00
b772d96f7a
Optionally allow admins to apply regex based normalization to permalinks prior to matching. This allows us to drop query string, or cleanly ignore slugs, etc.
102 lines
1.9 KiB
Ruby
102 lines
1.9 KiB
Ruby
class Permalink < ActiveRecord::Base
|
|
belongs_to :topic
|
|
belongs_to :post
|
|
belongs_to :category
|
|
|
|
before_validation :normalize_url
|
|
|
|
class Normalizer
|
|
attr_reader :source
|
|
|
|
def initialize(source)
|
|
@source = source
|
|
if source.present?
|
|
@rules = source.split("|").map do |rule|
|
|
parse_rule(rule)
|
|
end.compact
|
|
end
|
|
end
|
|
|
|
def parse_rule(rule)
|
|
return unless rule =~ /\/.*\//
|
|
|
|
escaping = false
|
|
regex = ""
|
|
sub = ""
|
|
c = 0
|
|
|
|
rule.chars.each do |l|
|
|
c += 1 if !escaping && l == "/"
|
|
escaping = l == "\\"
|
|
|
|
if c > 1
|
|
sub << l
|
|
else
|
|
regex << l
|
|
end
|
|
end
|
|
|
|
if regex.length > 1
|
|
[Regexp.new(regex[1..-1]), sub[1..-1] || ""] rescue nil
|
|
end
|
|
|
|
end
|
|
|
|
def normalize(url)
|
|
return url unless @rules
|
|
@rules.each do |(regex,sub)|
|
|
url = url.sub(regex,sub)
|
|
end
|
|
|
|
url
|
|
end
|
|
|
|
end
|
|
|
|
def self.normalize_url(url)
|
|
if url
|
|
url = url.strip
|
|
url = url[1..-1] if url[0,1] == '/'
|
|
end
|
|
|
|
normalizations = SiteSetting.permalink_normalizations
|
|
|
|
@normalizer = Normalizer.new(normalizations) unless @normalizer && @normalizer.source == normalizations
|
|
@normalizer.normalize(url)
|
|
end
|
|
|
|
def self.find_by_url(url)
|
|
find_by(url: normalize_url(url))
|
|
end
|
|
|
|
def normalize_url
|
|
self.url = Permalink.normalize_url(url) if url
|
|
end
|
|
|
|
def target_url
|
|
return external_url if external_url
|
|
return post.url if post
|
|
return topic.relative_url if topic
|
|
return category.url if category
|
|
nil
|
|
end
|
|
end
|
|
|
|
# == Schema Information
|
|
#
|
|
# Table name: permalinks
|
|
#
|
|
# id :integer not null, primary key
|
|
# url :string(1000) not null
|
|
# topic_id :integer
|
|
# post_id :integer
|
|
# category_id :integer
|
|
# created_at :datetime
|
|
# updated_at :datetime
|
|
# external_url :string(1000)
|
|
#
|
|
# Indexes
|
|
#
|
|
# index_permalinks_on_url (url) UNIQUE
|
|
#
|