class SiteSearchController < ApplicationController include ActionView::Helpers::TextHelper 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 rescue nil next if title.nil? and context.nil? context = context.gsub(/<\/?[^>]*>/, "").gsub(/ /i,"") rescue "" title_matches = title.match(regex) context_matches = context.match(regex) if title_matches or context_matches tmp = {} tmp[:id] = page.id tmp[:module] = "page" tmp[:url] = "/"+page.path tmp[:title] = title tmp[:content] = context 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.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 = eval("r.#{f}").gsub(/<\/?[^>]*>/, "").gsub(/ /i,"") rescue "" if f=="title" or f=="name" tmp[:title] = value else tmp[:content] << value end end result.push(tmp) end end end result.each do |res| res[:matches] = 0 res[:matches] += res[:title].match(/(#{key_string})/i) ? 100 : 0 rescue 0 res[:matches] += res[:content].match(/(#{key_string})/i) ? 100 : 0 rescue 0 keywords.each do |k| res[:matches] += res[:title].scan(/(#{k})/i).size + res[:content].scan(/(#{k})/i).size res[:title].gsub!(/(#{k})/i, '\1') rescue "" res[:content].gsub!(/(#{k})/i, '\1') rescue "" end if res[:matches]==0 result = result - [res] next end res[:content] = truncate(res[:content], length: 150) end result = result.sort_by { |k| k[:matches] }.reverse rescue [] render :json => { "results" => result, "time"=> ((Time.now-startTime)*1000).to_i , "keywords"=>keywords} end end