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, '\1') rescue "" end if filter index = content.index '' 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