94 lines
3.6 KiB
Ruby
94 lines
3.6 KiB
Ruby
|
class SiteSearchController < ApplicationController
|
||
|
|
||
|
def search
|
||
|
startTime = Time.now
|
||
|
if params[:keywords].present?
|
||
|
modules = [
|
||
|
{:key=>"announcement", :model=>"Bulletin", :fields=>["title","subtitle","text"], :url=>"/panel/announcement/front_end/bulletin/"}
|
||
|
]
|
||
|
|
||
|
key_string = params[:keywords]
|
||
|
keywords = key_string.split(/\s+(?=(?:[^"]*"[^"]*")*[^"]*$)/)
|
||
|
regex = Regexp.union(keywords.map{|word| Regexp.new(".*"+word+".*", "i")})
|
||
|
|
||
|
result = []
|
||
|
|
||
|
# Search Pages
|
||
|
Item.where(:app_frontend_url=>"page_contexts", :is_published=>true).each do |page|
|
||
|
title = page.title
|
||
|
context = PageContext.where(:page_id=>page.id).first.context
|
||
|
context = ActionController::Base.helpers.strip_tags(context).gsub(/ /i," ") rescue ""
|
||
|
title_matches = title.scan(regex).size
|
||
|
context_matches = context.scan(regex).size rescue 0
|
||
|
if title_matches > 0 or context_matches > 0
|
||
|
tmp = {}
|
||
|
tmp[:id] = page.id
|
||
|
tmp[:module] = "page"
|
||
|
tmp[:url] = "/"+page.path
|
||
|
tmp[:title] = hight_light(keywords, title)
|
||
|
tmp[:content] = hight_light(keywords, context, true)
|
||
|
tmp[:matches] = title_matches+context_matches
|
||
|
tmp[:matches] += title.scan(Regexp.new(".*"+key_string+".*", "i")).size > 0 ? 20 : 0 rescue 0
|
||
|
tmp[:matches] += context.scan(Regexp.new(".*"+key_string+".*", "i")).size > 0 ? 20 : 0 rescue 0
|
||
|
result.push(tmp)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
# Search Modules
|
||
|
modules.each do |mod|
|
||
|
query = mod[:fields].map{|f| {f.to_sym => regex} }
|
||
|
res = Kernel.const_get(mod[:model]).any_of(query)
|
||
|
res.all.each do |r|
|
||
|
tmp = {}
|
||
|
tmp[:id] = r.id
|
||
|
tmp[:module] = mod[:key]
|
||
|
tmp[:url] = mod[:url]+r.id.to_s
|
||
|
tmp[:content] = ""
|
||
|
tmp[:matches] = 0
|
||
|
mod[:fields].each do |f|
|
||
|
value = ActionController::Base.helpers.strip_tags(eval("r.#{f}")).gsub(/ /i,"")
|
||
|
|
||
|
if f=="title" or f=="name"
|
||
|
tmp[:title] = value
|
||
|
else
|
||
|
tmp[:content] << value
|
||
|
end
|
||
|
end
|
||
|
|
||
|
tmp[:matches] = tmp[:content].scan(regex).size + tmp[:title].scan(regex).size
|
||
|
tmp[:matches] += tmp[:title].scan(Regexp.new(".*"+key_string+".*", "i")).size > 0 ? 20 : 0 rescue 0
|
||
|
tmp[:matches] += tmp[:content].scan(Regexp.new(".*"+key_string+".*", "i")).size > 0 ? 20 : 0 rescue 0
|
||
|
|
||
|
tmp[:title] = hight_light(keywords, tmp[:title])
|
||
|
tmp[:content] = hight_light(keywords, tmp[:content], true)
|
||
|
|
||
|
result.push(tmp) unless tmp[:matches]==0
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
result = result.sort_by { |k| k[:matches] }.reverse rescue []
|
||
|
render :json => { "results" => result, "time"=> ((Time.now-startTime)*1000).to_i , "keywords"=>keywords}
|
||
|
end
|
||
|
|
||
|
def hight_light(keywords, content, filter=false)
|
||
|
matches = 0
|
||
|
keywords.each do |k|
|
||
|
matches += content.scan(/(#{k})/i).size
|
||
|
content.gsub!(/(#{k})/i, '<strong>\1</strong>') rescue ""
|
||
|
end
|
||
|
|
||
|
if filter
|
||
|
index = content.index '<strong>'
|
||
|
unless index.nil?
|
||
|
index = index>50 ? index-50 : 0
|
||
|
deadline = 150
|
||
|
content = content[index, deadline]
|
||
|
else
|
||
|
content = content[0, 100]
|
||
|
end
|
||
|
end
|
||
|
|
||
|
return content
|
||
|
end
|
||
|
|
||
|
end
|