Commit 6e82bdc7062af8f0447fff19593054948cbeb5e5

Authored by Rodrigo Souto
1 parent 144d5783

[otw] products action... =/

app/controllers/public/search_controller.rb
@@ -8,6 +8,7 @@ class SearchController < PublicController @@ -8,6 +8,7 @@ class SearchController < PublicController
8 before_filter :load_category 8 before_filter :load_category
9 before_filter :load_search_assets 9 before_filter :load_search_assets
10 before_filter :load_query 10 before_filter :load_query
  11 + before_filter :load_search_engine
11 12
12 # Backwards compatibility with old URLs 13 # Backwards compatibility with old URLs
13 def redirect_asset_param 14 def redirect_asset_param
@@ -18,7 +19,7 @@ class SearchController < PublicController @@ -18,7 +19,7 @@ class SearchController < PublicController
18 no_design_blocks 19 no_design_blocks
19 20
20 def facets_browse 21 def facets_browse
21 - @asset = params[:asset] 22 + @asset = params[:asset].to_sym
22 @asset_class = asset_class(@asset) 23 @asset_class = asset_class(@asset)
23 24
24 @facets_only = true 25 @facets_only = true
@@ -31,11 +32,12 @@ class SearchController < PublicController @@ -31,11 +32,12 @@ class SearchController < PublicController
31 end 32 end
32 33
33 def articles 34 def articles
34 - if !@empty_query  
35 - full_text_search ['public:true'] 35 + if @search_engine && !@empty_query
  36 + full_text_search
36 else 37 else
37 @results[@asset] = @environment.articles.public.send(@filter).paginate(paginate_options) 38 @results[@asset] = @environment.articles.public.send(@filter).paginate(paginate_options)
38 end 39 end
  40 + render :template => 'search/search_page'
39 end 41 end
40 42
41 def contents 43 def contents
@@ -43,49 +45,51 @@ class SearchController < PublicController @@ -43,49 +45,51 @@ class SearchController < PublicController
43 end 45 end
44 46
45 def people 47 def people
46 - if !@empty_query  
47 - full_text_search ['public:true'] 48 + if @search_engine && !@empty_query
  49 + full_text_search
48 else 50 else
49 @results[@asset] = visible_profiles(Person).send(@filter).paginate(paginate_options) 51 @results[@asset] = visible_profiles(Person).send(@filter).paginate(paginate_options)
50 end 52 end
  53 + render :template => 'search/search_page'
51 end 54 end
52 55
53 def products 56 def products
54 - public_filters = ['public:true', 'enabled:true']  
55 - if !@empty_query  
56 - full_text_search public_filters 57 + if @search_engine && !@empty_query
  58 + full_text_search
57 else 59 else
58 - @one_page = true  
59 @geosearch = logged_in? && current_user.person.lat && current_user.person.lng 60 @geosearch = logged_in? && current_user.person.lat && current_user.person.lng
60 61
61 extra_limit = LIST_SEARCH_LIMIT*5 62 extra_limit = LIST_SEARCH_LIMIT*5
62 sql_options = {:limit => LIST_SEARCH_LIMIT, :order => 'random()'} 63 sql_options = {:limit => LIST_SEARCH_LIMIT, :order => 'random()'}
63 if @geosearch 64 if @geosearch
64 - full_text_search public_filters, :sql_options => sql_options, :extra_limit => extra_limit, 65 + full_text_search :sql_options => sql_options, :extra_limit => extra_limit,
65 :alternate_query => "{!boost b=recip(geodist(),#{"%e" % (1.to_f/DistBoost)},1,1)}", 66 :alternate_query => "{!boost b=recip(geodist(),#{"%e" % (1.to_f/DistBoost)},1,1)}",
66 :radius => DistFilt, :latitude => current_user.person.lat, :longitude => current_user.person.lng 67 :radius => DistFilt, :latitude => current_user.person.lat, :longitude => current_user.person.lng
67 else 68 else
68 - full_text_search public_filters, :sql_options => sql_options, :extra_limit => extra_limit, 69 + full_text_search :sql_options => sql_options, :extra_limit => extra_limit,
69 :boost_functions => ['recip(ms(NOW/HOUR,updated_at),1.3e-10,1,1)'] 70 :boost_functions => ['recip(ms(NOW/HOUR,updated_at),1.3e-10,1,1)']
70 end 71 end
71 end 72 end
  73 + render :template => 'search/search_page'
72 end 74 end
73 75
74 def enterprises 76 def enterprises
75 - if !@empty_query  
76 - full_text_search ['public:true'] 77 + if @search_engine && !@empty_query
  78 + full_text_search
77 else 79 else
78 @filter_title = _('Enterprises from network') 80 @filter_title = _('Enterprises from network')
79 @results[@asset] = visible_profiles(Enterprise, [{:products => :product_category}]).paginate(paginate_options) 81 @results[@asset] = visible_profiles(Enterprise, [{:products => :product_category}]).paginate(paginate_options)
80 end 82 end
  83 + render :template => 'search/search_page'
81 end 84 end
82 85
83 def communities 86 def communities
84 - if !@empty_query  
85 - full_text_search ['public:true'] 87 + if @search_engine && !@empty_query
  88 + full_text_search
86 else 89 else
87 @results[@asset] = visible_profiles(Community).send(@filter).paginate(paginate_options) 90 @results[@asset] = visible_profiles(Community).send(@filter).paginate(paginate_options)
88 end 91 end
  92 + render :template => 'search/search_page'
89 end 93 end
90 94
91 def events 95 def events
@@ -104,7 +108,7 @@ class SearchController < PublicController @@ -104,7 +108,7 @@ class SearchController < PublicController
104 environment.events.by_day(@selected_day) 108 environment.events.by_day(@selected_day)
105 end 109 end
106 110
107 - if !@empty_query 111 + if @search_engine && !@empty_query
108 full_text_search 112 full_text_search
109 else 113 else
110 @results[@asset] = date_range ? environment.events.by_range(date_range) : environment.events 114 @results[@asset] = date_range ? environment.events.by_range(date_range) : environment.events
@@ -189,6 +193,7 @@ class SearchController < PublicController @@ -189,6 +193,7 @@ class SearchController < PublicController
189 def load_query 193 def load_query
190 @asset = params[:action].to_sym 194 @asset = params[:action].to_sym
191 @order ||= [@asset] 195 @order ||= [@asset]
  196 + params[:display] ||= 'list'
192 @results ||= {} 197 @results ||= {}
193 @filter = filter 198 @filter = filter
194 @filter_title = filter_description(@asset, @filter) 199 @filter_title = filter_description(@asset, @filter)
@@ -211,6 +216,10 @@ class SearchController < PublicController @@ -211,6 +216,10 @@ class SearchController < PublicController
211 end 216 end
212 end 217 end
213 218
  219 + def load_search_engine
  220 + @search_engine = @plugins.first_plugin(:search_engine?)
  221 + end
  222 +
214 FILTERS = %w( 223 FILTERS = %w(
215 more_recent 224 more_recent
216 more_active 225 more_active
@@ -260,9 +269,7 @@ class SearchController < PublicController @@ -260,9 +269,7 @@ class SearchController < PublicController
260 if map_search? 269 if map_search?
261 MAP_SEARCH_LIMIT 270 MAP_SEARCH_LIMIT
262 elsif !multiple_search? 271 elsif !multiple_search?
263 - if [:people, :communities].include? @asset  
264 - BLOCKS_SEARCH_LIMIT  
265 - elsif @asset == :enterprises and @empty_query 272 + if [:people, :communities, :enterprises].include? @asset
266 BLOCKS_SEARCH_LIMIT 273 BLOCKS_SEARCH_LIMIT
267 else 274 else
268 LIST_SEARCH_LIMIT 275 LIST_SEARCH_LIMIT
@@ -273,41 +280,12 @@ class SearchController < PublicController @@ -273,41 +280,12 @@ class SearchController < PublicController
273 end 280 end
274 281
275 def paginate_options(page = params[:page]) 282 def paginate_options(page = params[:page])
276 - page = 1 if multiple_search? or params[:display] == 'map' 283 + page = 1 if multiple_search? or @display == 'map'
277 { :per_page => limit, :page => page } 284 { :per_page => limit, :page => page }
278 end 285 end
279 286
280 - def full_text_search(filters = [], options = {})  
281 - paginate_options = paginate_options(params[:page])  
282 - asset_class = asset_class(@asset)  
283 - solr_options = options  
284 - pg_options = paginate_options(params[:page])  
285 -  
286 - if !multiple_search?  
287 - if !@results_only and asset_class.respond_to? :facets  
288 - solr_options.merge! asset_class.facets_find_options(params[:facet])  
289 - solr_options[:all_facets] = true  
290 - end  
291 - solr_options[:filter_queries] ||= []  
292 - solr_options[:filter_queries] += filters  
293 - solr_options[:filter_queries] << "environment_id:#{environment.id}"  
294 - solr_options[:filter_queries] << asset_class.facet_category_query.call(@category) if @category  
295 -  
296 - solr_options[:boost_functions] ||= []  
297 - params[:order_by] = nil if params[:order_by] == 'none'  
298 - if params[:order_by]  
299 - order = SortOptions[@asset][params[:order_by].to_sym]  
300 - raise "Unknown order by" if order.nil?  
301 - order[:solr_opts].each do |opt, value|  
302 - solr_options[opt] = value.is_a?(Proc) ? instance_eval(&value) : value  
303 - end  
304 - end  
305 - end  
306 -  
307 - ret = asset_class.find_by_contents(@query, paginate_options, solr_options)  
308 - @results[@asset] = ret[:results]  
309 - @facets = ret[:facets]  
310 - @all_facets = ret[:all_facets] 287 + def full_text_search(options = {})
  288 + @results[@asset] = @plugins.first(:full_text_search, @asset, @query, @category, paginate_options(params[:page]))
311 end 289 end
312 290
313 private 291 private
app/helpers/search_helper.rb
@@ -2,7 +2,7 @@ module SearchHelper @@ -2,7 +2,7 @@ module SearchHelper
2 2
3 MAP_SEARCH_LIMIT = 2000 3 MAP_SEARCH_LIMIT = 2000
4 LIST_SEARCH_LIMIT = 20 4 LIST_SEARCH_LIMIT = 20
5 - BLOCKS_SEARCH_LIMIT = 18 5 + BLOCKS_SEARCH_LIMIT = 24
6 MULTIPLE_SEARCH_LIMIT = 8 6 MULTIPLE_SEARCH_LIMIT = 8
7 DistFilt = 200 7 DistFilt = 200
8 DistBoost = 50 8 DistBoost = 50
@@ -50,7 +50,7 @@ module SearchHelper @@ -50,7 +50,7 @@ module SearchHelper
50 end 50 end
51 51
52 def map_search? 52 def map_search?
53 - !@empty_query and !multiple_search? and params[:display] == 'map' 53 + !multiple_search? and params[:display] == 'map'
54 end 54 end
55 55
56 def search_page_title(title, category = nil) 56 def search_page_title(title, category = nil)
@@ -66,8 +66,12 @@ module SearchHelper @@ -66,8 +66,12 @@ module SearchHelper
66 :align => 'center', :class => 'search-category-context') if category 66 :align => 'center', :class => 'search-category-context') if category
67 end 67 end
68 68
69 - def display_results(map_capable = false)  
70 - if map_capable and map_search? 69 + def map_capable?(asset)
  70 + [:enterprises, :products].include?(asset)
  71 + end
  72 +
  73 + def display_results(asset)
  74 + if map_capable?(asset) and map_search?
71 partial = 'google_maps' 75 partial = 'google_maps'
72 klass = 'map' 76 klass = 'map'
73 else 77 else
@@ -78,12 +82,6 @@ module SearchHelper @@ -78,12 +82,6 @@ module SearchHelper
78 content_tag('div', render(:partial => partial), :class => "map-or-list-search-results #{klass}") 82 content_tag('div', render(:partial => partial), :class => "map-or-list-search-results #{klass}")
79 end 83 end
80 84
81 - def display_map_list_button  
82 - button(:search, params[:display] == 'map' ? _('Display in list') : _('Display in map'),  
83 - params.merge(:display => (params[:display] == 'map' ? 'list' : 'map')),  
84 - :class => "map-toggle-button" )  
85 - end  
86 -  
87 def city_with_state(city) 85 def city_with_state(city)
88 if city and city.kind_of?(City) 86 if city and city.kind_of?(City)
89 s = city.parent 87 s = city.parent
@@ -97,17 +95,6 @@ module SearchHelper @@ -97,17 +95,6 @@ module SearchHelper
97 end 95 end
98 end 96 end
99 97
100 - def facets_menu(asset, _facets)  
101 - @asset_class = asset_class(asset)  
102 - @facets = _facets  
103 - render(:partial => 'facets_menu')  
104 - end  
105 -  
106 - def facets_unselect_menu(asset)  
107 - @asset_class = asset_class(asset)  
108 - render(:partial => 'facets_unselect_menu')  
109 - end  
110 -  
111 def facet_javascript(input_id, facet, array) 98 def facet_javascript(input_id, facet, array)
112 array = [] if array.nil? 99 array = [] if array.nil?
113 hintText = _('Type in an option') 100 hintText = _('Type in an option')
@@ -117,94 +104,6 @@ module SearchHelper @@ -117,94 +104,6 @@ module SearchHelper
117 #{jquery_token_input_messages_json(hintText)}});") 104 #{jquery_token_input_messages_json(hintText)}});")
118 end 105 end
119 106
120 - def facet_link_html(facet, params, value, label, count)  
121 - params = params ? params.dup : {}  
122 - has_extra = label.kind_of?(Array)  
123 - link_label = has_extra ? label[0] : label  
124 - id = facet[:solr_field].to_s  
125 - params[:facet] ||= {}  
126 - params[:facet][id] ||= {}  
127 - params[:page] = {} if params[:page]  
128 -  
129 - selected = facet[:label_id].nil? ? params[:facet][id] == value : params[:facet][id][facet[:label_id]].to_a.include?(value)  
130 -  
131 - if count > 0  
132 - url = params.merge(:facet => params[:facet].merge(  
133 - id => facet[:label_id].nil? ? value : params[:facet][id].merge( facet[:label_id] => params[:facet][id][facet[:label_id]].to_a | [value] )  
134 - ))  
135 - else  
136 - # preserve others filters and change this filter  
137 - url = params.merge(:facet => params[:facet].merge(  
138 - id => facet[:label_id].nil? ? value : { facet[:label_id] => value }  
139 - ))  
140 - end  
141 -  
142 - content_tag 'div', link_to(link_label, url, :class => 'facet-result-link-label') +  
143 - content_tag('span', (has_extra ? label[1] : ''), :class => 'facet-result-extra-label') +  
144 - (count > 0 ? content_tag('span', " (#{count})", :class => 'facet-result-count') : ''),  
145 - :class => 'facet-menu-item' + (selected ? ' facet-result-link-selected' : '')  
146 - end  
147 -  
148 - def facet_selecteds_html_for(environment, klass, params)  
149 - def name_with_extra(klass, facet, value)  
150 - name = klass.facet_result_name(facet, value)  
151 - name = name[0] + name[1] if name.kind_of?(Array)  
152 - name  
153 - end  
154 -  
155 - ret = []  
156 - params = params.dup  
157 - params[:facet].each do |id, value|  
158 - facet = klass.facet_by_id(id.to_sym)  
159 - next unless facet  
160 - if value.kind_of?(Hash)  
161 - label_hash = facet[:label].call(environment)  
162 - value.each do |label_id, value|  
163 - facet[:label_id] = label_id  
164 - facet[:label] = label_hash[label_id]  
165 - value.to_a.each do |value|  
166 - ret << [facet[:label], name_with_extra(klass, facet, value),  
167 - params.merge(:facet => params[:facet].merge(id => params[:facet][id].merge(label_id => params[:facet][id][label_id].to_a.reject{ |v| v == value })))]  
168 - end  
169 - end  
170 - else  
171 - ret << [klass.facet_label(facet), name_with_extra(klass, facet, value),  
172 - params.merge(:facet => params[:facet].reject{ |k,v| k == id })]  
173 - end  
174 - end  
175 -  
176 - ret.map do |label, name, url|  
177 - content_tag('div', content_tag('span', label, :class => 'facet-selected-label') +  
178 - content_tag('span', name, :class => 'facet-selected-name') +  
179 - link_to('', url, :class => 'facet-selected-remove', :title => 'remove facet'), :class => 'facet-selected')  
180 - end.join  
181 - end  
182 -  
183 - def order_by(asset)  
184 - options = SortOptions[asset].map do |name, options|  
185 - next if options[:if] and ! instance_eval(&options[:if])  
186 - [_(options[:label]), name.to_s]  
187 - end.compact  
188 -  
189 - content_tag('div', _('Sort results by ') +  
190 - select_tag(asset.to_s + '[order]', options_for_select(options, params[:order_by] || 'none'),  
191 - {:onchange => "window.location = jQuery.param.querystring(window.location.href, { 'order_by' : this.options[this.selectedIndex].value})"}),  
192 - :class => "search-ordering")  
193 - end  
194 -  
195 - def label_total_found(asset, total_found)  
196 - labels = {  
197 - :products => _("%s products offers found"),  
198 - :articles => _("%s articles found"),  
199 - :events => _("%s events found"),  
200 - :people => _("%s people found"),  
201 - :enterprises => _("%s enterprises found"),  
202 - :communities => _("%s communities found"),  
203 - }  
204 - content_tag('span', labels[asset] % total_found,  
205 - :class => "total-pages-found") if labels[asset]  
206 - end  
207 -  
208 def asset_class(asset) 107 def asset_class(asset)
209 asset.to_s.singularize.camelize.constantize 108 asset.to_s.singularize.camelize.constantize
210 end 109 end
@@ -213,4 +112,19 @@ module SearchHelper @@ -213,4 +112,19 @@ module SearchHelper
213 asset_class(asset).table_name 112 asset_class(asset).table_name
214 end 113 end
215 114
  115 + def display_filter(asset, display, float = 'right')
  116 + if map_capable?(asset)
  117 + list_link = display == 'list' ? _('List') : link_to(_('List'), params.merge(:display => 'list'))
  118 + map_link = display == 'map' ? _('Map') : link_to(_('Map'), params.merge(:display => 'map'))
  119 + content_tag('div',
  120 + content_tag('strong', _('Display')) + ': ' +
  121 + list_link +
  122 + ' | ' +
  123 + map_link,
  124 + :id => 'search-display-filter',
  125 + :style => "float: #{float}"
  126 + )
  127 + end
  128 + end
  129 +
216 end 130 end
app/views/search/_display_results.rhtml
1 <div id="search-results" class="<%= !multiple_search? ? 'only-one-result-box' : 'multiple-results-boxes' %>"> 1 <div id="search-results" class="<%= !multiple_search? ? 'only-one-result-box' : 'multiple-results-boxes' %>">
2 <% @order.each do |name| %> 2 <% @order.each do |name| %>
3 <% results = @results[name] %> 3 <% results = @results[name] %>
4 - <% empty = results.nil? || results.empty? %>  
5 4
6 - <div class="search-results-<%= name %> search-results-box <%= "search-results-empty" if empty %>">  
7 - <% if not empty %> 5 + <div class="search-results-<%= name %> search-results-box <%= "search-results-empty" if results.blank? %>">
  6 + <% if !results.blank? %>
8 <% partial = partial_for_class(results.first.class.class_name.constantize) %> 7 <% partial = partial_for_class(results.first.class.class_name.constantize) %>
9 8
10 <% if multiple_search? %> 9 <% if multiple_search? %>
app/views/search/_facets_menu.rhtml
@@ -1,36 +0,0 @@ @@ -1,36 +0,0 @@
1 -<% less_options_limit = 8 %>  
2 -  
3 -<div id="facets-menu">  
4 - <% @asset_class.map_facets_for(environment).each do |facet| %>  
5 -  
6 - <div id="facet-menu-<%= facet[:id].to_s %>" class="facet-menu">  
7 - <div class="facet-menu-label">  
8 - <%= @asset_class.facet_label(facet) %>  
9 - </div>  
10 -  
11 - <% results = @asset_class.map_facet_results(facet, params[:facet], @facets, @all_facets, :limit => less_options_limit) %>  
12 - <% facet_count = results.total_entries %>  
13 -  
14 - <% if facet_count > 0 %>  
15 - <div class="facet-menu-options facet-menu-more-options" style="display: none">  
16 - </div>  
17 -  
18 - <div class="facet-menu-options facet-menu-less-options">  
19 - <% results.each do |id, label, count| %>  
20 - <%= facet_link_html(facet, params, id, label, count) %><br />  
21 - <% end %>  
22 - </div> <br />  
23 -  
24 - <% if facet_count > less_options_limit %>  
25 - <%= link_to_function _("Options"),  
26 - "facet_options_toggle('#{facet[:id].to_s}', '#{url_for(params.merge(:action => 'facets_browse', :facet_id => facet[:id], :asset => @asset, :escape => false))}'); " +  
27 - "jQuery(this).toggleClass('facet-less-options')", :class => "facet-options-toggle" %>  
28 - <br />  
29 - <% end %>  
30 -  
31 - <% else %>  
32 - <span class="facet-any-result-found"><%= _("No filter available") %></span>  
33 - <% end %>  
34 - </div>  
35 - <% end %>  
36 -</div>  
app/views/search/_profile.rhtml
1 <li class="search-profile-item"> 1 <li class="search-profile-item">
2 -<% if @empty_query or multiple_search? or !profile.enterprise? %> 2 +<% if @empty_query || multiple_search? || !profile.enterprise? || !@search_engine %>
3 <%= profile_image_link profile, :portrait, 'div', 3 <%= profile_image_link profile, :portrait, 'div',
4 @filter == 'more_recent' ? profile.send(@filter + '_label') + show_date(profile.created_at) : profile.send(@filter + '_label') %> 4 @filter == 'more_recent' ? profile.send(@filter + '_label') + show_date(profile.created_at) : profile.send(@filter + '_label') %>
5 <% else %> 5 <% else %>
app/views/search/_results_header.rhtml
1 <div class="search-results-header <%= "search-no-results" if @results[@asset].nil? or @results[@asset].length == 0 %>"> 1 <div class="search-results-header <%= "search-no-results" if @results[@asset].nil? or @results[@asset].length == 0 %>">
2 - <% if !@empty_query %>  
3 - <div class="search-results-header-information">  
4 - <% if @results[@asset].total_entries > 0 %>  
5 - <%= label_total_found(@asset, @results[@asset].total_entries) %>  
6 - <% if params[:display] != 'map' %>  
7 - <span class="current-page"><%= _("Showing page %s of %s") % [@results[@asset].current_page, @results[@asset].total_pages] %></span>  
8 - <% end %>  
9 - <% end %>  
10 - </div>  
11 -  
12 - <div class="search-results-header-facets-order-by">  
13 - <%= facets_unselect_menu(@asset) %>  
14 - <%= order_by(@asset) if params[:display] != 'map' %>  
15 - </div>  
16 - <% else %>  
17 - <div id='search-filter-title'><%= @filter_title if @filter_title %></div>  
18 - <% end %>  
19 - 2 + <div id='search-filter-title'><%= @filter_title if @filter_title %></div>
  3 + <%= display_filter(@asset, params[:display]) if map_capable?(@asset) %>
20 <div style="clear: both"></div> 4 <div style="clear: both"></div>
21 </div> 5 </div>
app/views/search/articles.rhtml
@@ -1,17 +0,0 @@ @@ -1,17 +0,0 @@
1 -<%= search_page_title( @titles[:articles], @category ) %>  
2 -  
3 -<div id="search-column-left">  
4 - <% if !@empty_query %>  
5 - <%= facets_menu(:articles, @facets) %>  
6 - <% end %>  
7 -</div>  
8 -  
9 -<div id="search-column-right">  
10 - <%= render :partial => 'search_form', :locals => { :hint => _('Type the title, author or content desired') } %>  
11 - <%= render :partial => 'results_header' %>  
12 -  
13 - <%= display_results %>  
14 - <%= pagination_links @results[:articles] %>  
15 -</div>  
16 -  
17 -<div style="clear: both"></div>  
app/views/search/communities.rhtml
@@ -1,25 +0,0 @@ @@ -1,25 +0,0 @@
1 -<%= search_page_title( @titles[:communities], @category ) %>  
2 -  
3 -<div id='search-column-left'>  
4 - <% if logged_in? %>  
5 - <% button_bar do %>  
6 - <%# FIXME shouldn't the user create the community in the current environment instead of going to its home environment? %>  
7 - <%= button(:add, __('New community'), user.url.merge(:controller => 'memberships', :action => 'new_community', :profile => user.identifier)) %>  
8 - <% end %>  
9 - <% end %>  
10 -  
11 - <% if !@empty_query %>  
12 - <%= facets_menu(:communities, @facets) %>  
13 - <% end %>  
14 -</div>  
15 -  
16 -<div id='search-column-right'>  
17 - <%= render :partial => 'search_form', :locals => { :hint => _("Type words about the community you're looking for") } %>  
18 - <%= render :partial => 'results_header' %>  
19 -  
20 - <%= display_results %>  
21 - <%= pagination_links @results.values.first %>  
22 -</div>  
23 -  
24 -<div style="clear: both"></div>  
25 -  
app/views/search/contents.rhtml
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -articles.rhtml  
2 \ No newline at end of file 0 \ No newline at end of file
app/views/search/enterprises.rhtml
@@ -1,28 +0,0 @@ @@ -1,28 +0,0 @@
1 -<%= search_page_title( @titles[:enterprises], @category ) %>  
2 -  
3 -<div id="search-column-left">  
4 - <% if logged_in? && environment.enabled?('enterprise_registration') %>  
5 - <% button_bar do %>  
6 - <%= button(:add, __('New enterprise'), {:controller => 'enterprise_registration'}) %>  
7 - <% end %>  
8 - <% end %>  
9 -  
10 - <% if !@empty_query %>  
11 - <% button_bar do %>  
12 - <%= display_map_list_button %>  
13 - <% end %>  
14 - <%= facets_menu(:enterprises, @facets) %>  
15 - <% end %>  
16 -</div>  
17 -  
18 -<div id="search-column-right">  
19 - <%= render :partial => 'search_form', :locals => { :hint => _("Type words about the enterprise you're looking for") } %>  
20 - <%= render :partial => 'results_header' %>  
21 -  
22 - <%= display_results(true) %>  
23 - <% if params[:display] != 'map' %>  
24 - <%= pagination_links @results[:enterprises] %>  
25 - <% end %>  
26 -</div>  
27 -  
28 -<div style="clear: both"></div>  
app/views/search/events.html.erb 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= render :partial => 'events/agenda' %>
app/views/search/events.rhtml
@@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
1 -<%= search_page_title( Environment.default.name + "'s " + @titles[:events], @category ) %>  
2 -  
3 -<%= render :partial => 'events/agenda' %>  
app/views/search/index.rhtml
@@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
7 <%= search_page_title(_('Search Results'), @category) %> 7 <%= search_page_title(_('Search Results'), @category) %>
8 <%= render :partial => 'search_form', :locals => { :hint => '' } %> 8 <%= render :partial => 'search_form', :locals => { :hint => '' } %>
9 <%= category_context(@category, params) %> 9 <%= category_context(@category, params) %>
10 - <%= display_results %> 10 + <%= display_results(@asset) %>
11 11
12 <div id="category-childs"> 12 <div id="category-childs">
13 <% if @category %> 13 <% if @category %>
app/views/search/people.rhtml
@@ -1,19 +0,0 @@ @@ -1,19 +0,0 @@
1 -<%= search_page_title( @titles[:people], @category ) %>  
2 -  
3 -<div id='search-column-left'>  
4 - <% if !@empty_query %>  
5 - <%= facets_menu(:people, @facets) %>  
6 - <% end %>  
7 -</div>  
8 -  
9 -<div id='search-column-right'>  
10 - <%= render :partial => 'search_form', :locals => { :hint => _("Type words about the person you're looking for") } %>  
11 - <%= render :partial => 'results_header' %>  
12 -  
13 - <%= display_results %>  
14 - <% if params[:display] != 'map' %>  
15 - <%= pagination_links @results.values.first %>  
16 - <% end %>  
17 -</div>  
18 -  
19 -<div style="clear: both"></div>  
app/views/search/products.rhtml
@@ -1,26 +0,0 @@ @@ -1,26 +0,0 @@
1 -<%= search_page_title( @titles[:products], @category ) %>  
2 -  
3 -<div id="search-column-left">  
4 - <% if !@empty_query %>  
5 - <% button_bar do %>  
6 - <%= display_map_list_button %>  
7 -<% end %>  
8 - <%= facets_menu(:products, @facets) %>  
9 -<% end %>  
10 -</div>  
11 -  
12 -<div id="search-column-right">  
13 - <%= render :partial => 'search_form', :locals => { :hint => _('Type the product, service, city or qualifier desired') } %>  
14 - <%= render :partial => 'results_header' %>  
15 -  
16 - <%= display_results(true) %>  
17 - <% if !@one_page and params[:display] != 'map' %>  
18 - <%= pagination_links @results[:products] %>  
19 -<% end %>  
20 -</div>  
21 -  
22 -<% javascript_tag do %>  
23 - jQuery('.search-product-price-details').altBeautify();  
24 -<% end %>  
25 -  
26 -<div style="clear: both"></div>  
app/views/search/search_page.html.erb 0 → 100644
@@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
  1 +<%= search_page_title( @titles[@asset], @category ) %>
  2 +
  3 +<%= render :partial => 'results_header' %>
  4 +
  5 +<%= display_results(@asset) %>
  6 +<% if params[:display] != 'map' %>
  7 + <%= pagination_links @results[@asset] %>
  8 +<% end %>
  9 +
  10 +<div style="clear: both"></div>
  11 +
  12 +<% if @asset == :product %>
  13 + <% javascript_tag do %>
  14 + jQuery('.search-product-price-details').altBeautify();
  15 + <% end %>
  16 +<% end %>
lib/noosfero/plugin.rb
@@ -351,6 +351,17 @@ class Noosfero::Plugin @@ -351,6 +351,17 @@ class Noosfero::Plugin
351 nil 351 nil
352 end 352 end
353 353
  354 + # -> Specifies plugin that works as a search engine
  355 + # returns = true/false
  356 + def search_engine?
  357 + false
  358 + end
  359 +
  360 + # -> Realizes a full text search
  361 + # returns = whatever the plugin needs to render the view
  362 + def full_text_search(asset, query, category, paginate_options)
  363 + end
  364 +
354 def method_missing(method, *args, &block) 365 def method_missing(method, *args, &block)
355 # This is a generic hotspot for all controllers on Noosfero. 366 # This is a generic hotspot for all controllers on Noosfero.
356 # If any plugin wants to define filters to run on any controller, the name of 367 # If any plugin wants to define filters to run on any controller, the name of
plugins/solr/dependencies.rb 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +require 'active_record'
  2 +require 'acts_as_searchable'
  3 +require 'acts_as_faceted'
plugins/solr/lib/solr_plugin.rb
  1 +require_dependency 'solr_plugin/search_helper'
  2 +
1 class SolrPlugin < Noosfero::Plugin 3 class SolrPlugin < Noosfero::Plugin
2 4
  5 + include SolrPlugin::SearchHelper
  6 +
3 def self.plugin_name 7 def self.plugin_name
4 "Solr" 8 "Solr"
5 end 9 end
@@ -8,6 +12,16 @@ class SolrPlugin &lt; Noosfero::Plugin @@ -8,6 +12,16 @@ class SolrPlugin &lt; Noosfero::Plugin
8 _("Uses Solr as search engine.") 12 _("Uses Solr as search engine.")
9 end 13 end
10 14
  15 + def search_engine?
  16 + true
  17 + end
  18 +
  19 + def full_text_search(asset, query, category, paginate_options)
  20 + asset_class = asset_class(asset)
  21 + solr_options = solr_options(asset, category)
  22 + asset_class.find_by_contents(query, paginate_options, solr_options)
  23 + end
  24 +
11 end 25 end
12 26
13 Dir[File.join(SolrPlugin.root_path, 'lib', 'ext', '*.rb')].each {|file| require_dependency file } 27 Dir[File.join(SolrPlugin.root_path, 'lib', 'ext', '*.rb')].each {|file| require_dependency file }
plugins/solr/lib/solr_plugin/results_helper.rb 0 → 100644
@@ -0,0 +1,113 @@ @@ -0,0 +1,113 @@
  1 +class SolrPlugin < Noosfero::Plugin
  2 + module ResultsHelper
  3 + def set_results_variables
  4 + if @results[@asset].kind_of?(Hash)
  5 + ret = @results[@asset]
  6 + @results[@asset] = ret[:results]
  7 + @facets = ret[:facets]
  8 + @all_facets = ret[:all_facets]
  9 + end
  10 + end
  11 +
  12 + def order_by(asset)
  13 + options = SolrPlugin::SortOptions[asset].map do |name, options|
  14 + next if options[:if] && !instance_eval(&options[:if])
  15 + [_(options[:label]), name.to_s]
  16 + end.compact
  17 +
  18 + content_tag('div', _('Sort results by ') +
  19 + select_tag(asset.to_s + '[order]', options_for_select(options, params[:order_by] || 'none'),
  20 + {:onchange => "window.location = jQuery.param.querystring(window.location.href, { 'order_by' : this.options[this.selectedIndex].value})"}
  21 + ),
  22 + :class => "search-ordering"
  23 + )
  24 + end
  25 +
  26 + def label_total_found(asset, total_found)
  27 + labels = {
  28 + :products => _("%s products offers found"),
  29 + :articles => _("%s articles found"),
  30 + :events => _("%s events found"),
  31 + :people => _("%s people found"),
  32 + :enterprises => _("%s enterprises found"),
  33 + :communities => _("%s communities found"),
  34 + }
  35 + content_tag('span', labels[asset] % total_found,
  36 + :class => "total-pages-found") if labels[asset]
  37 + end
  38 +
  39 + def facets_menu(asset, _facets)
  40 + @asset_class = asset_class(asset)
  41 + @facets = _facets
  42 + render(:partial => 'facets_menu')
  43 + end
  44 +
  45 + def facets_unselect_menu(asset)
  46 + @asset_class = asset_class(asset)
  47 + render(:partial => 'facets_unselect_menu')
  48 + end
  49 +
  50 + def facet_selecteds_html_for(environment, klass, params)
  51 + def name_with_extra(klass, facet, value)
  52 + name = klass.facet_result_name(facet, value)
  53 + name = name[0] + name[1] if name.kind_of?(Array)
  54 + name
  55 + end
  56 +
  57 + ret = []
  58 + params = params.dup
  59 + params[:facet].each do |id, value|
  60 + facet = klass.facet_by_id(id.to_sym)
  61 + next unless facet
  62 + if value.kind_of?(Hash)
  63 + label_hash = facet[:label].call(environment)
  64 + value.each do |label_id, value|
  65 + facet[:label_id] = label_id
  66 + facet[:label] = label_hash[label_id]
  67 + value.to_a.each do |value|
  68 + ret << [facet[:label], name_with_extra(klass, facet, value),
  69 + params.merge(:facet => params[:facet].merge(id => params[:facet][id].merge(label_id => params[:facet][id][label_id].to_a.reject{ |v| v == value })))]
  70 + end
  71 + end
  72 + else
  73 + ret << [klass.facet_label(facet), name_with_extra(klass, facet, value),
  74 + params.merge(:facet => params[:facet].reject{ |k,v| k == id })]
  75 + end
  76 + end
  77 +
  78 + ret.map do |label, name, url|
  79 + content_tag('div', content_tag('span', label, :class => 'facet-selected-label') +
  80 + content_tag('span', name, :class => 'facet-selected-name') +
  81 + link_to('', url, :class => 'facet-selected-remove', :title => 'remove facet'), :class => 'facet-selected')
  82 + end.join
  83 + end
  84 +
  85 + def facet_link_html(facet, params, value, label, count)
  86 + params = params ? params.dup : {}
  87 + has_extra = label.kind_of?(Array)
  88 + link_label = has_extra ? label[0] : label
  89 + id = facet[:solr_field].to_s
  90 + params[:facet] ||= {}
  91 + params[:facet][id] ||= {}
  92 + params[:page] = {} if params[:page]
  93 +
  94 + selected = facet[:label_id].nil? ? params[:facet][id] == value : params[:facet][id][facet[:label_id]].to_a.include?(value)
  95 +
  96 + if count > 0
  97 + url = params.merge(:facet => params[:facet].merge(
  98 + id => facet[:label_id].nil? ? value : params[:facet][id].merge( facet[:label_id] => params[:facet][id][facet[:label_id]].to_a | [value] )
  99 + ))
  100 + else
  101 + # preserve others filters and change this filter
  102 + url = params.merge(:facet => params[:facet].merge(
  103 + id => facet[:label_id].nil? ? value : { facet[:label_id] => value }
  104 + ))
  105 + end
  106 +
  107 + content_tag 'div', link_to(link_label, url, :class => 'facet-result-link-label') +
  108 + content_tag('span', (has_extra ? label[1] : ''), :class => 'facet-result-extra-label') +
  109 + (count > 0 ? content_tag('span', " (#{count})", :class => 'facet-result-count') : ''),
  110 + :class => 'facet-menu-item' + (selected ? ' facet-result-link-selected' : '')
  111 + end
  112 + end
  113 +end
plugins/solr/lib/solr_plugin/search_helper.rb 0 → 100644
@@ -0,0 +1,83 @@ @@ -0,0 +1,83 @@
  1 +class SolrPlugin < Noosfero::Plugin
  2 +
  3 + SortOptions = {
  4 + :products => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},
  5 + :more_recent, {:label => _('More recent'), :solr_opts => {:sort => 'updated_at desc, score desc'}},
  6 + :name, {:label => _('Name'), :solr_opts => {:sort => 'solr_plugin_name_sortable asc'}},
  7 + :closest, {:label => _('Closest to me'), :if => proc{ logged_in? && (profile=current_user.person).lat && profile.lng },
  8 + :solr_opts => {:sort => "geodist() asc",
  9 + :latitude => proc{ current_user.person.lat }, :longitude => proc{ current_user.person.lng }}},
  10 + ],
  11 + :events => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},
  12 + :name, {:label => _('Name'), :solr_opts => {:sort => 'solr_plugin_name_sortable asc'}},
  13 + ],
  14 + :articles => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},
  15 + :name, {:label => _('Name'), :solr_opts => {:sort => 'solr_plugin_name_sortable asc'}},
  16 + :more_recent, {:label => _('More recent'), :solr_opts => {:sort => 'updated_at desc, score desc'}},
  17 + ],
  18 + :enterprises => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},
  19 + :name, {:label => _('Name'), :solr_opts => {:sort => 'solr_plugin_name_sortable asc'}},
  20 + ],
  21 + :people => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},
  22 + :name, {:label => _('Name'), :solr_opts => {:sort => 'solr_plugin_name_sortable asc'}},
  23 + ],
  24 + :communities => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},
  25 + :name, {:label => _('Name'), :solr_opts => {:sort => 'solr_plugin_name_sortable asc'}},
  26 + ],
  27 + }
  28 +
  29 + module SearchHelper
  30 + def asset_class(asset)
  31 + asset.to_s.singularize.camelize.constantize
  32 + end
  33 +
  34 + def asset_table(asset)
  35 + asset_class(asset).table_name
  36 + end
  37 +
  38 + def multiple_search?
  39 + ['index', 'category_index'].include?(context.params[:action])
  40 + end
  41 +
  42 + def filters(asset)
  43 + case asset
  44 + when :products
  45 + ['solr_plugin_public:true']
  46 + when :events
  47 + []
  48 + else
  49 + ['solr_plugin_public:true']
  50 + end
  51 + end
  52 +
  53 + def results_only?
  54 + context.params[:action] == 'index'
  55 + end
  56 +
  57 + def solr_options(asset, category)
  58 + asset_class = asset_class(asset)
  59 + solr_options = {}
  60 + if !multiple_search?
  61 + if !results_only? and asset_class.respond_to? :facets
  62 + solr_options.merge! asset_class.facets_find_options(context.params[:facet])
  63 + solr_options[:all_facets] = true
  64 + end
  65 + solr_options[:filter_queries] ||= []
  66 + solr_options[:filter_queries] += filters(asset)
  67 + solr_options[:filter_queries] << "environment_id:#{context.environment.id}"
  68 + solr_options[:filter_queries] << asset_class.facet_category_query.call(category) if category
  69 +
  70 + solr_options[:boost_functions] ||= []
  71 + context.params[:order_by] = nil if context.params[:order_by] == 'none'
  72 + if context.params[:order_by]
  73 + order = SolrPlugin::SortOptions[asset][context.params[:order_by].to_sym]
  74 + raise "Unknown order by" if order.nil?
  75 + order[:solr_opts].each do |opt, value|
  76 + solr_options[opt] = value.is_a?(Proc) ? instance_eval(&value) : value
  77 + end
  78 + end
  79 + end
  80 + solr_options
  81 + end
  82 + end
  83 +end
plugins/solr/test/unit/article_test.rb 0 → 100644
@@ -0,0 +1,115 @@ @@ -0,0 +1,115 @@
  1 +require 'test_helper'
  2 +
  3 +class ArticleTest < ActiveSupport::TestCase
  4 + def setup
  5 + @environment = Environment.default
  6 + @environment.enable_plugin(SolrPlugin)
  7 + @profile = create_user('testing').person
  8 + end
  9 +
  10 + attr_accessor :environment, :profile
  11 +
  12 + should 'act as faceted' do
  13 + person = fast_create(Person)
  14 + cat = Category.create!(:name => 'hardcore', :environment_id => Environment.default.id)
  15 + a = Article.create!(:name => 'black flag review', :profile_id => person.id)
  16 + a.add_category(cat, true)
  17 + a.save!
  18 + assert_equal Article.type_name, Article.facet_by_id(:solr_plugin_f_type)[:proc].call(a.send(:solr_plugin_f_type))
  19 + assert_equal Person.type_name, Article.facet_by_id(:solr_plugin_f_profile_type)[:proc].call(a.send(:solr_plugin_f_profile_type))
  20 + assert_equal a.published_at, a.send(:solr_plugin_f_published_at)
  21 + assert_equal ['hardcore'], a.send(:solr_plugin_f_category)
  22 + assert_equal "solr_plugin_category_filter:\"#{cat.id}\"", Article.facet_category_query.call(cat)
  23 + end
  24 +
  25 + should 'act as searchable' do
  26 + TestSolr.enable
  27 + person = fast_create(Person, :name => "Hiro", :address => 'U-Stor-It @ Inglewood, California',
  28 + :nickname => 'Protagonist')
  29 + person2 = fast_create(Person, :name => "Raven")
  30 + category = fast_create(Category, :name => "science fiction", :acronym => "sf", :abbreviation => "sci-fi")
  31 + a = Article.create!(:name => 'a searchable article about bananas', :profile_id => person.id,
  32 + :body => 'the body talks about mosquitos', :abstract => 'and the abstract is about beer',
  33 + :filename => 'not_a_virus.exe')
  34 + a.add_category(category)
  35 + c = a.comments.build(:title => 'snow crash', :author => person2, :body => 'wanna try some?')
  36 + c.save!
  37 +
  38 + # fields
  39 + assert_includes Article.find_by_contents('bananas')[:results].docs, a
  40 + assert_includes Article.find_by_contents('mosquitos')[:results].docs, a
  41 + assert_includes Article.find_by_contents('beer')[:results].docs, a
  42 + assert_includes Article.find_by_contents('not_a_virus.exe')[:results].docs, a
  43 + # filters
  44 + assert_includes Article.find_by_contents('bananas', {}, {:filter_queries => ["solr_plugin_public:true"]})[:results].docs, a
  45 + assert_not_includes Article.find_by_contents('bananas', {}, {:filter_queries => ["solr_plugin_public:false"]})[:results].docs, a
  46 + assert_includes Article.find_by_contents('bananas', {}, {:filter_queries => ["environment_id:\"#{Environment.default.id}\""]})[:results].docs, a
  47 + assert_includes Article.find_by_contents('bananas', {}, {:filter_queries => ["profile_id:\"#{person.id}\""]})[:results].docs, a
  48 + # includes
  49 + assert_includes Article.find_by_contents('Hiro')[:results].docs, a
  50 + assert_includes Article.find_by_contents("person-#{person.id}")[:results].docs, a
  51 + assert_includes Article.find_by_contents("California")[:results].docs, a
  52 + assert_includes Article.find_by_contents("Protagonist")[:results].docs, a
  53 +# FIXME: After merging with AI1826, searching on comments is not working
  54 +# assert_includes Article.find_by_contents("snow")[:results].docs, a
  55 +# assert_includes Article.find_by_contents("try some")[:results].docs, a
  56 +# assert_includes Article.find_by_contents("Raven")[:results].docs, a
  57 +#
  58 +# FIXME: After merging with AI1826, searching on categories is not working
  59 +# assert_includes Article.find_by_contents("science")[:results].docs, a
  60 +# assert_includes Article.find_by_contents(category.slug)[:results].docs, a
  61 +# assert_includes Article.find_by_contents("sf")[:results].docs, a
  62 +# assert_includes Article.find_by_contents("sci-fi")[:results].docs, a
  63 + end
  64 +
  65 + should 'boost name matches' do
  66 + TestSolr.enable
  67 + person = fast_create(Person)
  68 + in_body = Article.create!(:name => 'something', :profile_id => person.id, :body => 'bananas in the body!')
  69 + in_name = Article.create!(:name => 'bananas in the name!', :profile_id => person.id)
  70 + assert_equal [in_name, in_body], Article.find_by_contents('bananas')[:results].docs
  71 + end
  72 +
  73 + should 'boost if profile is enabled' do
  74 + TestSolr.enable
  75 + person2 = fast_create(Person, :enabled => false)
  76 + art_profile_disabled = Article.create!(:name => 'profile disabled', :profile_id => person2.id)
  77 + person1 = fast_create(Person, :enabled => true)
  78 + art_profile_enabled = Article.create!(:name => 'profile enabled', :profile_id => person1.id)
  79 + assert_equal [art_profile_enabled, art_profile_disabled], Article.find_by_contents('profile')[:results].docs
  80 + end
  81 +
  82 + should 'index comments body together with article' do
  83 + TestSolr.enable
  84 + owner = create_user('testuser').person
  85 + art = fast_create(TinyMceArticle, :profile_id => owner.id, :name => 'ytest')
  86 + c1 = Comment.create(:title => 'test comment', :body => 'anything', :author => owner, :source => art); c1.save!
  87 +
  88 + assert_includes Article.find_by_contents('anything')[:results], art
  89 + end
  90 +
  91 + should 'index by schema name when database is postgresql' do
  92 + TestSolr.enable
  93 + uses_postgresql 'schema_one'
  94 + art1 = Article.create!(:name => 'some thing', :profile_id => @profile.id)
  95 + assert_equal [art1], Article.find_by_contents('thing')[:results].docs
  96 + uses_postgresql 'schema_two'
  97 + art2 = Article.create!(:name => 'another thing', :profile_id => @profile.id)
  98 + assert_not_includes Article.find_by_contents('thing')[:results], art1
  99 + assert_includes Article.find_by_contents('thing')[:results], art2
  100 + uses_postgresql 'schema_one'
  101 + assert_includes Article.find_by_contents('thing')[:results], art1
  102 + assert_not_includes Article.find_by_contents('thing')[:results], art2
  103 + uses_sqlite
  104 + end
  105 +
  106 + should 'not index by schema name when database is not postgresql' do
  107 + TestSolr.enable
  108 + uses_sqlite
  109 + art1 = Article.create!(:name => 'some thing', :profile_id => @profile.id)
  110 + assert_equal [art1], Article.find_by_contents('thing')[:results].docs
  111 + art2 = Article.create!(:name => 'another thing', :profile_id => @profile.id)
  112 + assert_includes Article.find_by_contents('thing')[:results], art1
  113 + assert_includes Article.find_by_contents('thing')[:results], art2
  114 + end
  115 +end
plugins/solr/test/unit/environment_test.rb 0 → 100644
@@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
  1 +require 'test_helper'
  2 +
  3 +class EnvironmentTest < ActiveSupport::TestCase
  4 + def setup
  5 + @environment = Environment.default
  6 + @environment.enable_plugin(SolrPlugin)
  7 + end
  8 +
  9 + attr_accessor :environment
  10 +
  11 + should 'find by contents from articles' do
  12 + TestSolr.enable
  13 + env = fast_create(Environment)
  14 + env.enable_plugin(SolrPlugin)
  15 + assert_nothing_raised do
  16 + env.articles.find_by_contents('')[:results]
  17 + end
  18 + end
  19 +
  20 + should 'return more than 10 enterprises by contents' do
  21 + TestSolr.enable
  22 + Enterprise.destroy_all
  23 + ('1'..'20').each do |n|
  24 + Enterprise.create!(:name => 'test ' + n, :identifier => 'test_' + n)
  25 + end
  26 +
  27 + assert_equal 20, environment.enterprises.find_by_contents('test')[:results].total_entries
  28 + end
  29 +end
plugins/solr/test/unit/event_test.rb 0 → 100644
@@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
  1 +require 'test_helper'
  2 +
  3 +class EventTest < ActiveSupport::TestCase
  4 + def setup
  5 + @environment = Environment.default
  6 + @environment.enable_plugin(SolrPlugin)
  7 + @profile = create_user('testing').person
  8 + end
  9 +
  10 + attr_accessor :environment, :profile
  11 +
  12 + should 'be indexed by title' do
  13 + TestSolr.enable
  14 + e = Event.create!(:name => 'my surprisingly nice event', :start_date => Date.new(2008, 06, 06), :profile => profile)
  15 + assert_includes Event.find_by_contents('surprisingly')[:results], e
  16 + end
  17 +
  18 + should 'be indexed by body' do
  19 + TestSolr.enable
  20 + e = Event.create!(:name => 'bli', :start_date => Date.new(2008, 06, 06), :profile => profile, :body => 'my surprisingly long description about my freaking nice event')
  21 + assert_includes Event.find_by_contents('surprisingly')[:results], e
  22 + end
  23 +end
plugins/solr/test/unit/text_article_test.rb 0 → 100644
@@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
  1 +require 'test_helper'
  2 +
  3 +class TextArticleTest < ActiveSupport::TestCase
  4 + def setup
  5 + @environment = Environment.default
  6 + @environment.enable_plugin(SolrPlugin)
  7 + end
  8 +
  9 + attr_accessor :environment
  10 +
  11 + should 'found TextileArticle by TextArticle indexes' do
  12 + TestSolr.enable
  13 + person = create_user('testuser').person
  14 + article = TextileArticle.create!(:name => 'found article test', :profile => person)
  15 + assert_equal TextileArticle.find_by_contents('found')[:results].docs, TextArticle.find_by_contents('found')[:results].docs
  16 + end
  17 +end
plugins/solr/test/unit/tiny_mce_article_test.rb 0 → 100644
@@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
  1 +require 'test_helper'
  2 +
  3 +class TinyMceArticleTest < ActiveSupport::TestCase
  4 + def setup
  5 + @environment = Environment.default
  6 + @environment.enable_plugin(SolrPlugin)
  7 + @profile = create_user('testing').person
  8 + end
  9 +
  10 + attr_accessor :environment, :profile
  11 +
  12 + should 'be found when searching for articles by query' do
  13 + TestSolr.enable
  14 + tma = TinyMceArticle.create!(:name => 'test tinymce article', :body => '---', :profile => profile)
  15 + assert_includes TinyMceArticle.find_by_contents('article')[:results], tma
  16 + assert_includes Article.find_by_contents('article')[:results], tma
  17 + end
  18 +end
plugins/solr/views/search/.communities.rhtml.swp 0 → 100644
No preview for this file type
plugins/solr/views/search/.people.rhtml.swp 0 → 100644
No preview for this file type
plugins/solr/views/search/_facets.html.erb 0 → 100644
@@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
  1 +<% if logged_in? %>
  2 + <% button_bar do %>
  3 + <%# FIXME shouldn't the user create the community in the current environment instead of going to its home environment? %>
  4 + <%= button(:add, __('New community'), user.url.merge(:controller => 'memberships', :action => 'new_community', :profile => user.identifier)) if @asset == :communities %>
  5 + <%= button(:add, __('New enterprise'), {:controller => 'enterprise_registration'}) if @asset == :enterprises && environment.enabled?('enterprise_registration') %>
  6 + <% end %>
  7 +<% end %>
  8 +<% if !@empty_query %>
  9 + <%= facets_menu(@asset, @facets) %>
  10 +<% end %>
plugins/solr/views/search/_facets_menu.html.erb 0 → 100644
@@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
  1 +<% less_options_limit = 8 %>
  2 +
  3 +<div id="facets-menu">
  4 + <% @asset_class.map_facets_for(environment).each do |facet| %>
  5 +
  6 + <div id="facet-menu-<%= facet[:id].to_s %>" class="facet-menu">
  7 + <div class="facet-menu-label">
  8 + <%= @asset_class.facet_label(facet) %>
  9 + </div>
  10 +
  11 + <% results = @asset_class.map_facet_results(facet, params[:facet], @facets, @all_facets, :limit => less_options_limit) %>
  12 + <% facet_count = results.total_entries %>
  13 +
  14 + <% if facet_count > 0 %>
  15 + <div class="facet-menu-options facet-menu-more-options" style="display: none">
  16 + </div>
  17 +
  18 + <div class="facet-menu-options facet-menu-less-options">
  19 + <% results.each do |id, label, count| %>
  20 + <%= facet_link_html(facet, params, id, label, count) %><br />
  21 + <% end %>
  22 + </div> <br />
  23 +
  24 + <% if facet_count > less_options_limit %>
  25 + <%= link_to_function _("Options"),
  26 + "facet_options_toggle('#{facet[:id].to_s}', '#{url_for(params.merge(:action => 'facets_browse', :facet_id => facet[:id], :asset => @asset, :escape => false))}'); " +
  27 + "jQuery(this).toggleClass('facet-less-options')", :class => "facet-options-toggle" %>
  28 + <br />
  29 + <% end %>
  30 +
  31 + <% else %>
  32 + <span class="facet-any-result-found"><%= _("No filter available") %></span>
  33 + <% end %>
  34 + </div>
  35 + <% end %>
  36 +</div>
plugins/solr/views/search/_results.html.erb 0 → 100644
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +<%= render :partial => 'search_form', :locals => { :hint => _("Type words about the %s you're looking for") % @asset.to_s.singularize } %>
  2 +<%= render :partial => 'results_header' %>
  3 +
  4 +<%= display_results(@asset) %>
  5 +<% if params[:display] != 'map' %>
  6 + <%= pagination_links @results[@asset] %>
  7 +<% end %>
plugins/solr/views/search/_results_header.html.erb 0 → 100644
@@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
  1 +<div class="search-results-header <%= "search-no-results" if @results[@asset].nil? or @results[@asset].length == 0 %>">
  2 + <% if !@empty_query %>
  3 + <div class="search-results-header-information">
  4 + <% if @results[@asset].total_entries > 0 %>
  5 + <%= label_total_found(@asset, @results[@asset].total_entries) %>
  6 + <% if params[:display] != 'map' %>
  7 + <span class="current-page"><%= _("Showing page %s of %s") % [@results[@asset].current_page, @results[@asset].total_pages] %></span>
  8 + <% end %>
  9 + <% end %>
  10 + </div>
  11 +
  12 + <div class="search-results-header-facets-order-by">
  13 + <%= facets_unselect_menu(@asset) %>
  14 + <%= order_by(@asset) if params[:display] != 'map' %>
  15 + </div>
  16 + <% else %>
  17 + <div id='search-filter-title'><%= @filter_title if @filter_title %></div>
  18 + <% end %>
  19 + <% float = !@empty_query && params[:display] == 'list' ? 'left' : 'right' %>
  20 + <%= display_filter(@asset, params[:display], float) if map_capable?(@asset) %>
  21 + <div style="clear: both"></div>
  22 +</div>
plugins/solr/views/search/search_page.html.erb 0 → 100644
@@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
  1 +<% extend SolrPlugin::ResultsHelper %>
  2 +<% set_results_variables %>
  3 +
  4 +<%= search_page_title( @titles[@asset], @category ) %>
  5 +
  6 +<% if !@empty_query %>
  7 + <div id='search-column-left'>
  8 + <%= render :partial => 'facets' %>
  9 + </div>
  10 +
  11 + <div id='search-column-right'>
  12 + <%= render :partial => 'results' %>
  13 + </div>
  14 +<% else %>
  15 + <%= render :partial => 'results' %>
  16 +<% end %>
  17 +
  18 +<div style="clear: both"></div>
  19 +
  20 +<% if @asset == :products %>
  21 + <% javascript_tag do %>
  22 + jQuery('.search-product-price-details').altBeautify();
  23 + <% end %>
  24 +<% end %>
public/stylesheets/search.css
@@ -647,6 +647,7 @@ li.search-product-item hr { @@ -647,6 +647,7 @@ li.search-product-item hr {
647 font-weight: bold; 647 font-weight: bold;
648 font-size: 130%; 648 font-size: 130%;
649 line-height: 35px; 649 line-height: 35px;
  650 + float: left;
650 } 651 }
651 .search-results-header.search-no-results { 652 .search-results-header.search-no-results {
652 border-bottom: 0px; 653 border-bottom: 0px;
@@ -665,6 +666,9 @@ li.search-product-item hr { @@ -665,6 +666,9 @@ li.search-product-item hr {
665 color: #ff0000 666 color: #ff0000
666 } 667 }
667 668
  669 +#search-display-filter {
  670 + margin-top: 20px;
  671 +}
668 672
669 /* Search field and button */ 673 /* Search field and button */
670 674