end\r
\r
def search\r
- @token = params[:token]\r
+ @question = params[:q] || ""\r
+ @question.strip!\r
+ @all_words = params[:all_words] || (params[:submit] ? false : true)\r
@scope = params[:scope] || (params[:submit] ? [] : %w(issues news documents) )\r
-\r
- if @token and @token.length > 2\r
- @token.strip!\r
- like_token = "%#{@token}%"\r
+ if !@question.empty?\r
+ # tokens must be at least 3 character long\r
+ @tokens = @question.split.uniq.select {|w| w.length > 2 }\r
+ # no more than 5 tokens to search for\r
+ @tokens.slice! 5..-1 if @tokens.size > 5\r
+ # strings used in sql like statement\r
+ like_tokens = @tokens.collect {|w| "%#{w}%"}\r
+ operator = @all_words ? " AND " : " OR "\r
+ limit = 10\r
@results = []\r
- @results += @project.issues.find(:all, :include => :author, :conditions => ["issues.subject like ? or issues.description like ?", like_token, like_token] ) if @scope.include? 'issues'\r
- @results += @project.news.find(:all, :conditions => ["news.title like ? or news.description like ?", like_token, like_token], :include => :author ) if @scope.include? 'news'\r
- @results += @project.documents.find(:all, :conditions => ["title like ? or description like ?", like_token, like_token] ) if @scope.include? 'documents'\r
+ @results += @project.issues.find(:all, :limit => limit, :include => :author, :conditions => [ (["(LOWER(issues.subject) like ? OR LOWER(issues.description) like ?)"] * like_tokens.size).join(operator), * (like_tokens * 2).sort] ) if @scope.include? 'issues'\r
+ @results += @project.news.find(:all, :limit => limit, :conditions => [ (["(LOWER(news.title) like ? OR LOWER(news.description) like ?)"] * like_tokens.size).join(operator), * (like_tokens * 2).sort], :include => :author ) if @scope.include? 'news'\r
+ @results += @project.documents.find(:all, :limit => limit, :conditions => [ (["(LOWER(title) like ? OR LOWER(description) like ?)"] * like_tokens.size).join(operator), * (like_tokens * 2).sort] ) if @scope.include? 'documents'\r
+ @question = @tokens.join(" ")\r
end\r
end\r
\r
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
\r
module ProjectsHelper\r
- def result_overview(text, token)\r
- match = excerpt(text, token)\r
- match ? highlight(match, token) : truncate(text, 150)\r
+\r
+ def highlight_tokens(text, tokens)\r
+ return text unless tokens && !tokens.empty?\r
+ regexp = Regexp.new "(#{tokens.join('|')})", Regexp::IGNORECASE \r
+ result = ''\r
+ text.split(regexp).each_with_index do |words, i|\r
+ result << (i.even? ? (words.length > 100 ? "#{words[0..44]} ... #{words[-45..-1]}" : words) : content_tag('span', words, :class => 'highlight'))\r
+ end\r
+ result\r
end
end
\r
<div class="box">\r
<% form_tag({:action => 'search', :id => @project}, :method => :get) do %>\r
-<p><%= text_field_tag 'token', @token, :size => 30 %>\r
+<p><%= text_field_tag 'q', @question, :size => 30 %>\r
<%= check_box_tag 'scope[]', 'issues', (@scope.include? 'issues') %> <label><%= l(:label_issue_plural) %></label>\r
<%= check_box_tag 'scope[]', 'news', (@scope.include? 'news') %> <label><%= l(:label_news_plural) %></label>\r
-<%= check_box_tag 'scope[]', 'documents', (@scope.include? 'documents') %> <label><%= l(:label_document_plural) %></label></p>\r
+<%= check_box_tag 'scope[]', 'documents', (@scope.include? 'documents') %> <label><%= l(:label_document_plural) %></label><br />\r
+<%= check_box_tag 'all_words', 1, @all_words %> <%= l(:label_all_words) %></p>\r
<%= submit_tag l(:button_submit), :name => 'submit' %>\r
<% end %>\r
</div>\r
<% @results.each do |e| %>\r
<li><p>\r
<% if e.is_a? Issue %>\r
- <%= link_to "#{e.tracker.name} ##{e.id}", :controller => 'issues', :action => 'show', :id => e %>: <%= highlight(h(e.subject), @token) %><br />\r
- <%= result_overview(e.description, @token) %><br />\r
+ <%= link_to "#{e.tracker.name} ##{e.id}", :controller => 'issues', :action => 'show', :id => e %>: <%= highlight_tokens(h(e.subject), @tokens) %><br />\r
+ <%= highlight_tokens(e.description, @tokens) %><br />\r
<i><%= e.author.name %>, <%= format_time(e.created_on) %></i>\r
<% elsif e.is_a? News %>\r
- <%=l(:label_news)%>: <%= link_to highlight(h(e.title), @token), :controller => 'news', :action => 'show', :id => e %><br />\r
- <%= result_overview(e.description, @token) %><br />\r
+ <%=l(:label_news)%>: <%= link_to highlight_tokens(h(e.title), @tokens), :controller => 'news', :action => 'show', :id => e %><br />\r
+ <%= highlight_tokens(e.description, @tokens) %><br />\r
<i><%= e.author.name %>, <%= format_time(e.created_on) %></i>\r
<% elsif e.is_a? Document %>\r
- <%=l(:label_document)%>: <%= link_to highlight(h(e.title), @token), :controller => 'documents', :action => 'show', :id => e %><br />\r
- <%= result_overview(e.description, @token) %><br />\r
+ <%=l(:label_document)%>: <%= link_to highlight_tokens(h(e.title), @tokens), :controller => 'documents', :action => 'show', :id => e %><br />\r
+ <%= highlight_tokens(e.description, @tokens) %><br />\r
<i><%= format_time(e.created_on) %></i>\r
<% end %>\r
</p></li> \r
label_search: Suche\r
label_result: %d Resultat\r
label_result_plural: %d Resultate\r
+label_all_words: Alle Wörter\r
\r
button_login: Einloggen\r
button_submit: Einreichen\r
label_search: Search\r
label_result: %d result\r
label_result_plural: %d results\r
+label_all_words: All words\r
\r
button_login: Login\r
button_submit: Submit\r
label_search: Búsqueda\r
label_result: %d resultado\r
label_result_plural: %d resultados\r
+label_all_words: Todas las palabras\r
\r
button_login: Conexión\r
button_submit: Someter\r
label_search: Recherche\r
label_result: %d résultat\r
label_result_plural: %d résultats\r
+label_all_words: Tous les mots\r
\r
button_login: Connexion\r
button_submit: Soumettre\r
label_search: 検索\r
label_result: %d 件の結果\r
label_result_plural: %d 件の結果\r
+label_all_words: すべての単語\r
\r
button_login: ログイン\r
button_submit: 変更\r
hr { border:0; border-top: dotted 1px #fff; border-bottom: dotted 1px #c0c0c0; }\r
table p {margin:0; padding:0;}\r
\r
-strong.highlight { background-color: #FCFD8D;}\r
+.highlight { background-color: #FCFD8D;}\r
\r
div.square {\r
border: 1px solid #999;\r