Commit e7b5205f7980aa300dd7daf7fc8bd27d9aef9738

Authored by Rodrigo Souto
2 parents 8195b993 82423ba6

Merge branch 'pluginize-solr' into merge-solr

Showing 662 changed files with 125601 additions and 108485 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 662 files displayed.

INSTALL
... ... @@ -33,7 +33,7 @@ You need to install some packages Noosfero depends on. On Debian GNU/Linux or
33 33 Debian-based systems, all of these packages are available through the Debian
34 34 archive. You can install them with the following command:
35 35  
36   - # apt-get install ruby rake po4a libgettext-ruby-util libgettext-ruby1.8 libsqlite3-ruby rcov librmagick-ruby libredcloth-ruby libwill-paginate-ruby iso-codes libfeedparser-ruby openjdk-6-jre libdaemons-ruby thin tango-icon-theme libhpricot-ruby
  36 + # apt-get install ruby rake po4a libgettext-ruby-util libgettext-ruby1.8 libsqlite3-ruby rcov librmagick-ruby libredcloth-ruby libwill-paginate-ruby iso-codes libfeedparser-ruby libdaemons-ruby thin tango-icon-theme libhpricot-ruby
37 37  
38 38 On other systems, they may or may not be available through your regular package
39 39 management system. Below are the links to their homepages.
... ... @@ -43,7 +43,6 @@ management system. Below are the links to their homepages.
43 43 * po4a: http://po4a.alioth.debian.org/
44 44 * Ruby-sqlite3: http://rubyforge.org/projects/sqlite-ruby
45 45 * rcov: http://eigenclass.org/hiki/rcov
46   -* Solr: http://lucene.apache.org/solr
47 46 * RMagick: http://rmagick.rubyforge.org/
48 47 * RedCloth: http://redcloth.org/
49 48 * will_paginate: http://github.com/mislav/will_paginate/wikis
... ... @@ -111,9 +110,6 @@ $ tar -zxvf noosfero-0.39.0.tar.gz
111 110 $ ln -s noosfero-0.39.0 current
112 111 $ cd current
113 112  
114   -Copy config/solr.yml.dist to config/solr.yml. You will
115   -probably not need to customize this configuration, but have a look at it.
116   -
117 113 Create the thin configuration file:
118 114  
119 115 $ thin -C config/thin.yml -e production config
... ... @@ -195,10 +191,6 @@ Compile the translations:
195 191  
196 192 $ RAILS_ENV=production rake noosfero:translations:compile
197 193  
198   -Run Solr:
199   -
200   -$ rake solr:start
201   -
202 194 Now we must create some initial data. To create your default environment
203 195 (the first one), run the command below:
204 196  
... ...
Rakefile
... ... @@ -7,6 +7,10 @@ require 'rake'
7 7 require 'rake/testtask'
8 8 require 'rake/rdoctask'
9 9  
10   -ACTS_AS_SEARCHABLE_ENABLED = false if Rake.application.top_level_tasks.detect{|t| t == 'db:data:minimal'}
11   -
  10 +# rails tasks
12 11 require 'tasks/rails'
  12 +
  13 +# plugins' tasks
  14 +plugins_tasks = Dir.glob("config/plugins/*/{tasks,lib/tasks,rails/tasks}/**/*.rake").sort +
  15 + Dir.glob("config/plugins/*/vendor/plugins/*/{tasks,lib/tasks,rails/tasks}/**/*.rake").sort
  16 +plugins_tasks.each{ |ext| load ext }
... ...
app/controllers/admin/region_validators_controller.rb
... ... @@ -33,7 +33,7 @@ class RegionValidatorsController < AdminController
33 33 def load_region_and_search
34 34 @region = environment.regions.find(params[:id])
35 35 if params[:search]
36   - @search = @region.search_possible_validators(params[:search])
  36 + @search = find_by_contents(:organizations, Organization, params[:search])[:results].reject {|item| @region.validator_ids.include?(item.id) }
37 37 end
38 38 end
39 39  
... ...
app/controllers/application_controller.rb
... ... @@ -154,4 +154,18 @@ class ApplicationController < ActionController::Base
154 154 end
155 155 end
156 156  
  157 + def find_by_contents(asset, scope, query, paginate_options={:page => 1}, options={})
  158 + scope = scope.send(options[:filter]) if options[:filter]
  159 +
  160 + @plugins.first(:find_by_contents, asset, scope, query, paginate_options, options) ||
  161 + fallback_find_by_contents(asset, scope, query, paginate_options, options)
  162 + end
  163 +
  164 + private
  165 +
  166 + def fallback_find_by_contents(asset, scope, query, paginate_options, options)
  167 + return {:results => scope.paginate(paginate_options)} if query.blank?
  168 + {:results => scope.like_search(query).paginate(paginate_options)}
  169 + end
  170 +
157 171 end
... ...
app/controllers/my_profile/cms_controller.rb
... ... @@ -270,7 +270,7 @@ class CmsController < MyProfileController
270 270  
271 271 def search
272 272 query = params[:q]
273   - results = profile.files.published.find_by_contents(query)[:results]
  273 + results = find_by_contents(:uploaded_files, profile.files.published, query)[:results]
274 274 render :text => article_list_to_json(results), :content_type => 'application/json'
275 275 end
276 276  
... ...
app/controllers/public/profile_search_controller.rb
... ... @@ -11,7 +11,7 @@ class ProfileSearchController < PublicController
11 11 if params[:where] == 'environment'
12 12 redirect_to :controller => 'search', :query => @q
13 13 else
14   - @results = profile.articles.published.find_by_contents(@q, {:per_page => 10, :page => params[:page]})[:results]
  14 + @results = find_by_contents(:articles, profile.articles.published, @q, {:per_page => 10, :page => params[:page]})[:results]
15 15 end
16 16 end
17 17 end
... ...
app/controllers/public/search_controller.rb
... ... @@ -4,10 +4,11 @@ class SearchController < PublicController
4 4 include SearchHelper
5 5 include ActionView::Helpers::NumberHelper
6 6  
7   - before_filter :redirect_asset_param, :except => [:facets_browse, :assets]
  7 + before_filter :redirect_asset_param, :except => :assets
8 8 before_filter :load_category
9 9 before_filter :load_search_assets
10 10 before_filter :load_query
  11 + before_filter :load_filter
11 12  
12 13 # Backwards compatibility with old URLs
13 14 def redirect_asset_param
... ... @@ -17,25 +18,51 @@ class SearchController < PublicController
17 18  
18 19 no_design_blocks
19 20  
20   - def facets_browse
21   - @asset = params[:asset]
22   - @asset_class = asset_class(@asset)
  21 + def index
  22 + @searches = {}
  23 + @order = []
  24 + @names = {}
  25 + @results_only = true
23 26  
24   - @facets_only = true
25   - send(@asset)
  27 + @enabled_searches.select { |key,description| @searching[key] }.each do |key, description|
  28 + load_query
  29 + @asset = key
  30 + send(key)
  31 + @order << key
  32 + @names[key] = getterm(description)
  33 + end
  34 + @asset = nil
26 35  
27   - @facet = @asset_class.map_facets_for(environment).find { |facet| facet[:id] == params[:facet_id] }
28   - raise 'Facet not found' if @facet.nil?
  36 + if @searches.keys.size == 1
  37 + @asset = @searches.keys.first
  38 + render :action => @asset
  39 + end
  40 + end
29 41  
30   - render :layout => false
  42 + # view the summary of one category
  43 + def category_index
  44 + @searches = {}
  45 + @order = []
  46 + @names = {}
  47 + limit = MULTIPLE_SEARCH_LIMIT
  48 + [
  49 + [ :people, _('People'), :recent_people ],
  50 + [ :enterprises, _('Enterprises'), :recent_enterprises ],
  51 + [ :products, _('Products'), :recent_products ],
  52 + [ :events, _('Upcoming events'), :upcoming_events ],
  53 + [ :communities, _('Communities'), :recent_communities ],
  54 + [ :articles, _('Contents'), :recent_articles ]
  55 + ].each do |asset, name, filter|
  56 + @order << asset
  57 + @searches[asset]= {:results => @category.send(filter, limit)}
  58 + raise "No total_entries for: #{asset}" unless @searches[asset][:results].respond_to?(:total_entries)
  59 + @names[asset] = name
  60 + end
31 61 end
32 62  
33 63 def articles
34   - if !@empty_query
35   - full_text_search ['public:true']
36   - else
37   - @results[@asset] = @environment.articles.public.send(@filter).paginate(paginate_options)
38   - end
  64 + @scope = @environment.articles.public
  65 + full_text_search
39 66 end
40 67  
41 68 def contents
... ... @@ -43,49 +70,23 @@ class SearchController &lt; PublicController
43 70 end
44 71  
45 72 def people
46   - if !@empty_query
47   - full_text_search ['public:true']
48   - else
49   - @results[@asset] = visible_profiles(Person).send(@filter).paginate(paginate_options)
50   - end
  73 + @scope = visible_profiles(Person)
  74 + full_text_search
51 75 end
52 76  
53 77 def products
54   - public_filters = ['public:true', 'enabled:true']
55   - if !@empty_query
56   - full_text_search public_filters
57   - else
58   - @one_page = true
59   - @geosearch = logged_in? && current_user.person.lat && current_user.person.lng
60   -
61   - extra_limit = LIST_SEARCH_LIMIT*5
62   - sql_options = {:limit => LIST_SEARCH_LIMIT, :order => 'random()'}
63   - if @geosearch
64   - full_text_search public_filters, :sql_options => sql_options, :extra_limit => extra_limit,
65   - :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   - else
68   - full_text_search public_filters, :sql_options => sql_options, :extra_limit => extra_limit,
69   - :boost_functions => ['recip(ms(NOW/HOUR,updated_at),1.3e-10,1,1)']
70   - end
71   - end
  78 + @scope = @environment.products
  79 + full_text_search
72 80 end
73 81  
74 82 def enterprises
75   - if !@empty_query
76   - full_text_search ['public:true']
77   - else
78   - @filter_title = _('Enterprises from network')
79   - @results[@asset] = visible_profiles(Enterprise, [{:products => :product_category}]).paginate(paginate_options)
80   - end
  83 + @scope = visible_profiles(Enterprise, [{:products => :product_category}])
  84 + full_text_search
81 85 end
82 86  
83 87 def communities
84   - if !@empty_query
85   - full_text_search ['public:true']
86   - else
87   - @results[@asset] = visible_profiles(Community).send(@filter).paginate(paginate_options)
88   - end
  88 + @scope = visible_profiles(Community)
  89 + full_text_search
89 90 end
90 91  
91 92 def events
... ... @@ -93,7 +94,7 @@ class SearchController &lt; PublicController
93 94 month = (params[:month] ? params[:month].to_i : Date.today.month)
94 95 day = (params[:day] ? params[:day].to_i : Date.today.day)
95 96 date = build_date(params[:year], params[:month], params[:day])
96   - date_range = (date - 1.month)..(date + 1.month).at_end_of_month
  97 + date_range = (date - 1.month).at_beginning_of_month..(date + 1.month).at_end_of_month
97 98  
98 99 @selected_day = nil
99 100 @events_of_the_day = []
... ... @@ -104,64 +105,21 @@ class SearchController &lt; PublicController
104 105 environment.events.by_day(@selected_day)
105 106 end
106 107  
107   - if !@empty_query
108   - full_text_search
109   - else
110   - @results[@asset] = date_range ? environment.events.by_range(date_range) : environment.events
111   - end
  108 + @scope = date_range ? environment.events.by_range(date_range) : environment.events
  109 + full_text_search
112 110  
113   - events = @results[@asset]
  111 + events = @searches[@asset][:results]
114 112 @calendar = populate_calendar(date, events)
115 113 @previous_calendar = populate_calendar(date - 1.month, events)
116 114 @next_calendar = populate_calendar(date + 1.month, events)
117 115 end
118 116  
119   - def index
120   - @results = {}
121   - @order = []
122   - @names = {}
123   - @results_only = true
124   -
125   - @enabled_searches.select { |key,description| @searching[key] }.each do |key, description|
126   - load_query
127   - @asset = key
128   - send(key)
129   - @order << key
130   - @names[key] = getterm(description)
131   - end
132   - @asset = nil
133   - @facets = {}
134   -
135   - render :action => @results.keys.first if @results.keys.size == 1
136   - end
137   -
138 117 # keep old URLs workings
139 118 def assets
140 119 params[:action] = params[:asset].is_a?(Array) ? :index : params.delete(:asset)
141 120 redirect_to params
142 121 end
143 122  
144   - # view the summary of one category
145   - def category_index
146   - @results = {}
147   - @order = []
148   - @names = {}
149   - limit = MULTIPLE_SEARCH_LIMIT
150   - [
151   - [ :people, _('People'), :recent_people ],
152   - [ :enterprises, _('Enterprises'), :recent_enterprises ],
153   - [ :products, _('Products'), :recent_products ],
154   - [ :events, _('Upcoming events'), :upcoming_events ],
155   - [ :communities, _('Communities'), :recent_communities ],
156   - [ :articles, _('Contents'), :recent_articles ]
157   - ].each do |asset, name, filter|
158   - @order << asset
159   - @results[asset] = @category.send(filter, limit)
160   - raise "No total_entries for: #{asset}" unless @results[asset].respond_to?(:total_entries)
161   - @names[asset] = name
162   - end
163   - end
164   -
165 123 def tags
166 124 @tags_cache_key = "tags_env_#{environment.id.to_s}"
167 125 if is_cache_expired?(@tags_cache_key)
... ... @@ -173,7 +131,7 @@ class SearchController &lt; PublicController
173 131 @tag = params[:tag]
174 132 @tag_cache_key = "tag_#{CGI.escape(@tag.to_s)}_env_#{environment.id.to_s}_page_#{params[:npage]}"
175 133 if is_cache_expired?(@tag_cache_key)
176   - @results[@asset] = environment.articles.find_tagged_with(@tag).paginate(paginate_options)
  134 + @searches[@asset] = {:results => environment.articles.find_tagged_with(@tag).paginate(paginate_options)}
177 135 end
178 136 end
179 137  
... ... @@ -187,11 +145,9 @@ class SearchController &lt; PublicController
187 145 protected
188 146  
189 147 def load_query
190   - @asset = params[:action].to_sym
  148 + @asset = (params[:asset] || params[:action]).to_sym
191 149 @order ||= [@asset]
192   - @results ||= {}
193   - @filter = filter
194   - @filter_title = filter_description(@asset, @filter)
  150 + @searches ||= {}
195 151  
196 152 @query = params[:query] || ''
197 153 @empty_query = @category.nil? && @query.blank?
... ... @@ -211,42 +167,13 @@ class SearchController &lt; PublicController
211 167 end
212 168 end
213 169  
214   - FILTERS = %w(
215   - more_recent
216   - more_active
217   - more_popular
218   - more_comments
219   - )
220   - def filter
221   - if FILTERS.include?(params[:filter])
222   - params[:filter]
223   - else
224   - 'more_recent'
225   - end
226   - end
227   -
228   - def filter_description(asset, filter)
229   - {
230   - 'articles_more_recent' => _('More recent contents from network'),
231   - 'articles_more_popular' => _('More viewed contents from network'),
232   - 'articles_more_comments' => _('Most commented contents from network'),
233   - 'people_more_recent' => _('More recent people from network'),
234   - 'people_more_active' => _('More active people from network'),
235   - 'people_more_popular' => _('More popular people from network'),
236   - 'communities_more_recent' => _('More recent communities from network'),
237   - 'communities_more_active' => _('More active communities from network'),
238   - 'communities_more_popular' => _('More popular communities from network'),
239   - 'products_more_recent' => _('Highlights'),
240   - }[asset.to_s + '_' + filter]
241   - end
242   -
243 170 def load_search_assets
244   - if Searches.keys.include?(params[:action].to_sym) and environment.enabled?("disable_asset_#{params[:action]}")
  171 + if SEARCHES.keys.include?(params[:action].to_sym) && environment.enabled?("disable_asset_#{params[:action]}")
245 172 render_not_found
246 173 return
247 174 end
248 175  
249   - @enabled_searches = Searches.select {|key, name| environment.disabled?("disable_asset_#{params[:action]}") }
  176 + @enabled_searches = SEARCHES.select {|key, name| environment.disabled?("disable_asset_#{key}") }
250 177 @searching = {}
251 178 @titles = {}
252 179 @enabled_searches.each do |key, name|
... ... @@ -256,13 +183,19 @@ class SearchController &lt; PublicController
256 183 @names = @titles if @names.nil?
257 184 end
258 185  
  186 + def load_filter
  187 + @filter = 'more_recent'
  188 + if SEARCHES.keys.include?(@asset.to_sym)
  189 + available_filters = asset_class(@asset)::SEARCH_FILTERS
  190 + @filter = params[:filter] if available_filters.include?(params[:filter])
  191 + end
  192 + end
  193 +
259 194 def limit
260   - if map_search?
  195 + if map_search?(@searches)
261 196 MAP_SEARCH_LIMIT
262 197 elsif !multiple_search?
263   - if [:people, :communities].include? @asset
264   - BLOCKS_SEARCH_LIMIT
265   - elsif @asset == :enterprises and @empty_query
  198 + if [:people, :communities, :enterprises].include? @asset
266 199 BLOCKS_SEARCH_LIMIT
267 200 else
268 201 LIST_SEARCH_LIMIT
... ... @@ -273,41 +206,12 @@ class SearchController &lt; PublicController
273 206 end
274 207  
275 208 def paginate_options(page = params[:page])
276   - page = 1 if multiple_search? or params[:display] == 'map'
  209 + page = 1 if multiple_search?(@searches) || params[:display] == 'map'
277 210 { :per_page => limit, :page => page }
278 211 end
279 212  
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]
  213 + def full_text_search
  214 + @searches[@asset] = find_by_contents(@asset, @scope, @query, paginate_options, {:category => @category, :filter => @filter})
311 215 end
312 216  
313 217 private
... ...
app/helpers/application_helper.rb
... ... @@ -274,9 +274,9 @@ module ApplicationHelper
274 274  
275 275 VIEW_EXTENSIONS = %w[.rhtml .html.erb]
276 276  
277   - def partial_for_class_in_view_path(klass, view_path, suffix = nil)
  277 + def partial_for_class_in_view_path(klass, view_path, prefix = nil, suffix = nil)
278 278 return nil if klass.nil?
279   - name = [klass.name.underscore, suffix].compact.map(&:to_s).join('_')
  279 + name = [prefix, klass.name.underscore, suffix].compact.map(&:to_s).join('_')
280 280  
281 281 search_name = String.new(name)
282 282 if search_name.include?("/")
... ... @@ -291,14 +291,14 @@ module ApplicationHelper
291 291 return name if File.exists?(File.join(path))
292 292 end
293 293  
294   - partial_for_class_in_view_path(klass.superclass, view_path, suffix)
  294 + partial_for_class_in_view_path(klass.superclass, view_path, prefix, suffix)
295 295 end
296 296  
297   - def partial_for_class(klass, suffix=nil)
  297 + def partial_for_class(klass, prefix=nil, suffix=nil)
298 298 raise ArgumentError, 'No partial for object. Is there a partial for any class in the inheritance hierarchy?' if klass.nil?
299 299 name = klass.name.underscore
300 300 @controller.view_paths.each do |view_path|
301   - partial = partial_for_class_in_view_path(klass, view_path, suffix)
  301 + partial = partial_for_class_in_view_path(klass, view_path, prefix, suffix)
302 302 return partial if partial
303 303 end
304 304  
... ...
app/helpers/search_helper.rb
... ... @@ -2,12 +2,10 @@ module SearchHelper
2 2  
3 3 MAP_SEARCH_LIMIT = 2000
4 4 LIST_SEARCH_LIMIT = 20
5   - BLOCKS_SEARCH_LIMIT = 18
  5 + BLOCKS_SEARCH_LIMIT = 24
6 6 MULTIPLE_SEARCH_LIMIT = 8
7   - DistFilt = 200
8   - DistBoost = 50
9 7  
10   - Searches = ActiveSupport::OrderedHash[
  8 + SEARCHES = ActiveSupport::OrderedHash[
11 9 :articles, _('Contents'),
12 10 :enterprises, _('Enterprises'),
13 11 :people, _('People'),
... ... @@ -16,46 +14,31 @@ module SearchHelper
16 14 :events, _('Events'),
17 15 ]
18 16  
19   - SortOptions = {
20   - :products => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},
21   - :more_recent, {:label => _('More recent'), :solr_opts => {:sort => 'updated_at desc, score desc'}},
22   - :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}},
23   - :closest, {:label => _('Closest to me'), :if => proc{ logged_in? && (profile=current_user.person).lat && profile.lng },
24   - :solr_opts => {:sort => "geodist() asc",
25   - :latitude => proc{ current_user.person.lat }, :longitude => proc{ current_user.person.lng }}},
26   - ],
27   - :events => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},
28   - :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}},
29   - ],
30   - :articles => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},
31   - :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}},
32   - :more_recent, {:label => _('More recent'), :solr_opts => {:sort => 'updated_at desc, score desc'}},
33   - ],
34   - :enterprises => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},
35   - :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}},
36   - ],
37   - :people => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},
38   - :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}},
39   - ],
40   - :communities => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},
41   - :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}},
42   - ],
  17 + FILTER_TRANSLATION = {
  18 + 'more_popular' => _('More popular'),
  19 + 'more_active' => _('More active'),
  20 + 'more_recent' => _('More recent'),
  21 + 'more_comments' => _('More comments')
43 22 }
44 23  
45 24 # FIXME remove it after search_controler refactored
46 25 include EventsHelper
47 26  
48   - def multiple_search?
49   - ['index', 'category_index'].include?(params[:action]) or @results.size > 1
  27 + def multiple_search?(searches=nil)
  28 + ['index', 'category_index'].include?(params[:action]) || (searches && searches.size > 1)
50 29 end
51 30  
52   - def map_search?
53   - !@empty_query and !multiple_search? and params[:display] == 'map'
  31 + def map_search?(searches=nil)
  32 + !multiple_search?(searches) && params[:display] == 'map'
  33 + end
  34 +
  35 + def asset_class(asset)
  36 + asset.to_s.singularize.camelize.constantize
54 37 end
55 38  
56 39 def search_page_title(title, category = nil)
57 40 title = "<h1>" + title
58   - title += '<small>' + category.name + '</small>' if category
  41 + title += ' - <small>' + category.name + '</small>' if category
59 42 title + "</h1>"
60 43 end
61 44  
... ... @@ -66,8 +49,12 @@ module SearchHelper
66 49 :align => 'center', :class => 'search-category-context') if category
67 50 end
68 51  
69   - def display_results(map_capable = false)
70   - if map_capable and map_search?
  52 + def display?(asset, mode)
  53 + defined?(asset_class(asset)::SEARCH_DISPLAYS) && asset_class(asset)::SEARCH_DISPLAYS.include?(mode.to_s)
  54 + end
  55 +
  56 + def display_results(searches=nil, asset=nil)
  57 + if display?(asset, :map) && map_search?(searches)
71 58 partial = 'google_maps'
72 59 klass = 'map'
73 60 else
... ... @@ -78,10 +65,13 @@ module SearchHelper
78 65 content_tag('div', render(:partial => partial), :class => "map-or-list-search-results #{klass}")
79 66 end
80 67  
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" )
  68 + def display_filter(asset, display)
  69 + asset = :articles if asset == :tag
  70 + if display?(asset, display)
  71 + display
  72 + else
  73 + asset_class(asset).default_search_display
  74 + end
85 75 end
86 76  
87 77 def city_with_state(city)
... ... @@ -97,120 +87,50 @@ module SearchHelper
97 87 end
98 88 end
99 89  
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)
112   - array = [] if array.nil?
113   - hintText = _('Type in an option')
114   - text_field_tag('facet['+input_id+']', '', :id => input_id) +
115   - javascript_tag("jQuery.TokenList(jQuery('##{input_id}'), #{array.to_json},
116   - {searchDelay: 0, permanentDropdown: true, theme: 'facet', dontAdd: true, preventDuplicates: true,
117   - #{jquery_token_input_messages_json(hintText)}});")
118   - end
119   -
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   - ))
  90 + def display_selector(asset, display, float = 'right')
  91 + display = nil if display.blank?
  92 + display ||= asset_class(asset).default_search_display
  93 + if [display?(asset, :map), display?(asset, :compact), display?(asset, :full)].select {|option| option}.count > 1
  94 + compact_link = display?(asset, :compact) ? (display == 'compact' ? _('Compact') : link_to(_('Compact'), params.merge(:display => 'compact'))) : nil
  95 + map_link = display?(asset, :map) ? (display == 'map' ? _('Map') : link_to(_('Map'), params.merge(:display => 'map'))) : nil
  96 + full_link = display?(asset, :full) ? (display == 'full' ? _('Full') : link_to(_('Full'), params.merge(:display => 'full'))) : nil
  97 + content_tag('div',
  98 + content_tag('strong', _('Display')) + ': ' + [compact_link, map_link, full_link].compact.join(' | ').html_safe,
  99 + :class => 'search-customize-options'
  100 + )
140 101 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 102 end
147 103  
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
  104 + def filter_selector(asset, filter, float = 'right')
  105 + klass = asset_class(asset)
  106 + if klass::SEARCH_FILTERS.count > 1
  107 + options = options_for_select(klass::SEARCH_FILTERS.map {|f| [FILTER_TRANSLATION[f], f]}, filter)
  108 + url_params = url_for(params.merge(:filter => 'FILTER'))
  109 + onchange = "document.location.href = '#{url_params}'.replace('FILTER', this.value)"
  110 + select_field = select_tag(:filter, options, :onchange => onchange)
  111 + content_tag('div',
  112 + content_tag('strong', _('Filter')) + ': ' + select_field,
  113 + :class => "search-customize-options"
  114 + )
174 115 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)
209   - asset.to_s.singularize.camelize.constantize
210 116 end
211 117  
212   - def asset_table(asset)
213   - asset_class(asset).table_name
  118 + def filter_title(asset, filter)
  119 + {
  120 + 'articles_more_recent' => _('More recent contents from network'),
  121 + 'articles_more_popular' => _('More viewed contents from network'),
  122 + 'articles_more_comments' => _('Most commented contents from network'),
  123 + 'people_more_recent' => _('More recent people from network'),
  124 + 'people_more_active' => _('More active people from network'),
  125 + 'people_more_popular' => _('More popular people from network'),
  126 + 'communities_more_recent' => _('More recent communities from network'),
  127 + 'communities_more_active' => _('More active communities from network'),
  128 + 'communities_more_popular' => _('More popular communities from network'),
  129 + 'enterprises_more_recent' => _('More recent enterprises from network'),
  130 + 'enterprises_more_active' => _('More active enterprises from network'),
  131 + 'enterprises_more_popular' => _('More popular enterprises from network'),
  132 + 'products_more_recent' => _('Highlights'),
  133 + }[asset.to_s + '_' + filter].to_s
214 134 end
215 135  
216 136 end
... ...
app/models/article.rb
... ... @@ -2,6 +2,26 @@ require &#39;hpricot&#39;
2 2  
3 3 class Article < ActiveRecord::Base
4 4  
  5 + SEARCHABLE_FIELDS = {
  6 + :name => 10,
  7 + :abstract => 3,
  8 + :body => 2,
  9 + :slug => 1,
  10 + :filename => 1,
  11 + }
  12 +
  13 + SEARCH_FILTERS = %w[
  14 + more_recent
  15 + more_popular
  16 + more_comments
  17 + ]
  18 +
  19 + SEARCH_DISPLAYS = %w[full]
  20 +
  21 + def self.default_search_display
  22 + 'full'
  23 + end
  24 +
5 25 #FIXME This is necessary because html is being generated on the model...
6 26 include ActionView::Helpers::TagHelper
7 27  
... ... @@ -147,7 +167,6 @@ class Article &lt; ActiveRecord::Base
147 167 else
148 168 ArticleCategorization.add_category_to_article(c, self)
149 169 self.categories(reload)
150   - self.solr_save
151 170 end
152 171 end
153 172  
... ... @@ -165,7 +184,6 @@ class Article &lt; ActiveRecord::Base
165 184 ArticleCategorization.add_category_to_article(item, self)
166 185 end
167 186 self.categories(true)
168   - self.solr_save
169 187 pending_categorizations.clear
170 188 end
171 189  
... ... @@ -201,20 +219,12 @@ class Article &lt; ActiveRecord::Base
201 219 named_scope :public,
202 220 :conditions => [ "advertise = ? AND published = ? AND profiles.visible = ? AND profiles.public_profile = ?", true, true, true, true ]
203 221  
204   - named_scope :more_recent,
205   - :conditions => [ "advertise = ? AND published = ? AND profiles.visible = ? AND profiles.public_profile = ? AND
206   - ((articles.type != ?) OR articles.type is NULL)",
207   - true, true, true, true, 'RssFeed'
208   - ],
209   - :order => 'articles.published_at desc, articles.id desc'
210   -
211 222 # retrives the most commented articles, sorted by the comment count (largest
212 223 # first)
213 224 def self.most_commented(limit)
214 225 paginate(:order => 'comments_count DESC', :page => 1, :per_page => limit)
215 226 end
216 227  
217   - named_scope :more_popular, :order => 'hits DESC'
218 228 named_scope :relevant_as_recent, :conditions => ["(articles.type != 'UploadedFile' and articles.type != 'RssFeed' and articles.type != 'Blog') OR articles.type is NULL"]
219 229  
220 230 def self.recent(limit = nil, extra_conditions = {}, pagination = true)
... ... @@ -426,8 +436,8 @@ class Article &lt; ActiveRecord::Base
426 436 named_scope :images, :conditions => { :is_image => true }
427 437 named_scope :text_articles, :conditions => [ 'articles.type IN (?)', text_article_types ]
428 438  
  439 + named_scope :more_popular, :order => 'hits DESC'
429 440 named_scope :more_comments, :order => "comments_count DESC"
430   - named_scope :more_views, :order => "hits DESC"
431 441 named_scope :more_recent, :order => "created_at DESC"
432 442  
433 443 def self.display_filter(user, profile)
... ... @@ -479,10 +489,6 @@ class Article &lt; ActiveRecord::Base
479 489 allow_post_content?(user) || user && allow_members_to_edit && user.is_member_of?(profile)
480 490 end
481 491  
482   - def comments_updated
483   - solr_save
484   - end
485   -
486 492 def accept_category?(cat)
487 493 !cat.is_a?(ProductCategory)
488 494 end
... ... @@ -620,7 +626,7 @@ class Article &lt; ActiveRecord::Base
620 626  
621 627 end
622 628  
623   - def more_views_label
  629 + def more_popular_label
624 630 amount = self.hits
625 631 {
626 632 0 => _('no views'),
... ... @@ -648,98 +654,7 @@ class Article &lt; ActiveRecord::Base
648 654 img.nil? ? '' : img.attributes['src']
649 655 end
650 656  
651   - private
652   -
653   - # FIXME: workaround for development env.
654   - # Subclasses aren't (re)loaded, and acts_as_solr
655   - # depends on subclasses method to search
656   - # see http://stackoverflow.com/questions/4138957/activerecordsubclassnotfound-error-when-using-sti-in-rails/4139245
657   - UploadedFile
658   - TextArticle
659   - TinyMceArticle
660   - TextileArticle
661   - Folder
662   - EnterpriseHomepage
663   - Gallery
664   - Blog
665   - Forum
666   - Event
667   -
668   - def self.f_type_proc(klass)
669   - klass.constantize.type_name
670   - end
671   -
672   - def self.f_profile_type_proc(klass)
673   - klass.constantize.type_name
674   - end
675   -
676   - def f_type
677   - #join common types
678   - case self.class.name
679   - when 'TinyMceArticle', 'TextileArticle'
680   - TextArticle.name
681   - else
682   - self.class.name
683   - end
684   - end
685   -
686   - def f_profile_type
687   - self.profile.class.name
688   - end
689   -
690   - def f_published_at
691   - self.published_at
692   - end
693   -
694   - def f_category
695   - self.categories.collect(&:name)
696   - end
697   -
698 657 delegate :region, :region_id, :environment, :environment_id, :to => :profile, :allow_nil => true
699   - def name_sortable # give a different name for solr
700   - name
701   - end
702   -
703   - def public
704   - self.public?
705   - end
706   -
707   - def category_filter
708   - categories_including_virtual_ids
709   - end
710   -
711   - public
712   -
713   - acts_as_faceted :fields => {
714   - :f_type => {:label => _('Type'), :proc => proc{|klass| f_type_proc(klass)}},
715   - :f_published_at => {:type => :date, :label => _('Published date'), :queries => {'[* TO NOW-1YEARS/DAY]' => _("Older than one year"),
716   - '[NOW-1YEARS TO NOW/DAY]' => _("In the last year"), '[NOW-1MONTHS TO NOW/DAY]' => _("In the last month"), '[NOW-7DAYS TO NOW/DAY]' => _("In the last week"), '[NOW-1DAYS TO NOW/DAY]' => _("In the last day")},
717   - :queries_order => ['[NOW-1DAYS TO NOW/DAY]', '[NOW-7DAYS TO NOW/DAY]', '[NOW-1MONTHS TO NOW/DAY]', '[NOW-1YEARS TO NOW/DAY]', '[* TO NOW-1YEARS/DAY]']},
718   - :f_profile_type => {:label => _('Profile'), :proc => proc{|klass| f_profile_type_proc(klass)}},
719   - :f_category => {:label => _('Categories')},
720   - }, :category_query => proc { |c| "category_filter:\"#{c.id}\"" },
721   - :order => [:f_type, :f_published_at, :f_profile_type, :f_category]
722   -
723   - acts_as_searchable :fields => facets_fields_for_solr + [
724   - # searched fields
725   - {:name => {:type => :text, :boost => 2.0}},
726   - {:slug => :text}, {:body => :text},
727   - {:abstract => :text}, {:filename => :text},
728   - # filtered fields
729   - {:public => :boolean}, {:environment_id => :integer},
730   - {:profile_id => :integer}, :language,
731   - {:category_filter => :integer},
732   - # ordered/query-boosted fields
733   - {:name_sortable => :string}, :last_changed_by_id, :published_at, :is_image,
734   - :updated_at, :created_at,
735   - ], :include => [
736   - {:profile => {:fields => [:name, :identifier, :address, :nickname, :region_id, :lat, :lng]}},
737   - {:comments => {:fields => [:title, :body, :author_name, :author_email]}},
738   - {:categories => {:fields => [:name, :path, :slug, :lat, :lng, :acronym, :abbreviation]}},
739   - ], :facets => facets_option_for_solr,
740   - :boost => proc { |a| 10 if a.profile && a.profile.enabled },
741   - :if => proc{ |a| ! ['RssFeed'].include?(a.class.name) }
742   - handle_asynchronously :solr_save
743 658  
744 659 private
745 660  
... ...
app/models/category.rb
1 1 class Category < ActiveRecord::Base
2 2  
  3 + SEARCHABLE_FIELDS = {
  4 + :name => 10,
  5 + :acronym => 5,
  6 + :abbreviation => 5,
  7 + :slug => 1,
  8 + }
  9 +
3 10 validates_exclusion_of :slug, :in => [ 'index' ], :message => N_('%{fn} cannot be like that.').fix_i18n
4 11 validates_presence_of :name, :environment_id
5 12 validates_uniqueness_of :slug,:scope => [ :environment_id, :parent_id ], :message => N_('%{fn} is already being used by another category.').fix_i18n
... ... @@ -100,23 +107,4 @@ class Category &lt; ActiveRecord::Base
100 107 self.children.find(:all, :conditions => {:display_in_menu => true}).empty?
101 108 end
102 109  
103   - private
104   - def name_sortable # give a different name for solr
105   - name
106   - end
107   - public
108   -
109   - acts_as_searchable :fields => [
110   - # searched fields
111   - {:name => {:type => :text, :boost => 2.0}},
112   - {:path => :text}, {:slug => :text},
113   - {:abbreviation => :text}, {:acronym => :text},
114   - # filtered fields
115   - :parent_id,
116   - # ordered/query-boosted fields
117   - {:name_sortable => :string},
118   - ]
119   - after_save_reindex [:articles, :profiles], :with => :delayed_job
120   - handle_asynchronously :solr_save
121   -
122 110 end
... ...
app/models/certifier.rb
1 1 class Certifier < ActiveRecord::Base
2 2  
  3 + SEARCHABLE_FIELDS = {
  4 + :name => 10,
  5 + :description => 3,
  6 + :link => 1,
  7 + }
  8 +
3 9 belongs_to :environment
4 10  
5 11 has_many :qualifier_certifiers, :dependent => :destroy
... ... @@ -24,6 +30,4 @@ class Certifier &lt; ActiveRecord::Base
24 30 self.name.downcase.transliterate <=> b.name.downcase.transliterate
25 31 end
26 32  
27   - after_save_reindex [:products], :with => :delayed_job
28   -
29 33 end
... ...
app/models/comment.rb
1 1 class Comment < ActiveRecord::Base
2 2  
  3 + SEARCHABLE_FIELDS = {
  4 + :title => 10,
  5 + :name => 4,
  6 + :body => 2,
  7 + }
  8 +
3 9 validates_presence_of :body
4 10  
5 11 belongs_to :source, :counter_cache => true, :polymorphic => true
... ... @@ -78,12 +84,6 @@ class Comment &lt; ActiveRecord::Base
78 84 self.article.profile.notification_emails - [self.author_email || self.email]
79 85 end
80 86  
81   - after_save :notify_article
82   - after_destroy :notify_article
83   - def notify_article
84   - article.comments_updated if article.kind_of?(Article)
85   - end
86   -
87 87 after_create :new_follower
88 88 def new_follower
89 89 if source.kind_of?(Article)
... ...
app/models/enterprise.rb
... ... @@ -2,6 +2,8 @@
2 2 # only enterprises can offer products and services.
3 3 class Enterprise < Organization
4 4  
  5 + SEARCH_DISPLAYS += %w[map full]
  6 +
5 7 def self.type_name
6 8 _('Enterprise')
7 9 end
... ... @@ -14,8 +16,6 @@ class Enterprise &lt; Organization
14 16  
15 17 has_and_belongs_to_many :fans, :class_name => 'Person', :join_table => 'favorite_enteprises_people'
16 18  
17   - after_save_reindex [:products], :with => :delayed_job
18   - extra_data_for_index :product_categories
19 19 def product_categories
20 20 products.includes(:product_category).map{|p| p.category_full_name}.compact
21 21 end
... ... @@ -189,4 +189,8 @@ class Enterprise &lt; Organization
189 189 { :profile => identifier, :controller => 'catalog'}
190 190 end
191 191  
  192 + def more_recent_label
  193 + ''
  194 + end
  195 +
192 196 end
... ...
app/models/environment.rb
... ... @@ -268,8 +268,6 @@ class Environment &lt; ActiveRecord::Base
268 268  
269 269 settings_items :search_hints, :type => Hash, :default => {}
270 270  
271   - settings_items :top_level_category_as_facet_ids, :type => Array, :default => []
272   -
273 271 def news_amount_by_folder=(amount)
274 272 settings[:news_amount_by_folder] = amount.to_i
275 273 end
... ...
app/models/license.rb
1 1 class License < ActiveRecord::Base
  2 +
  3 + SEARCHABLE_FIELDS = {
  4 + :name => 10,
  5 + :url => 5,
  6 + }
  7 +
2 8 belongs_to :environment
3 9 has_many :content, :class_name => 'Article', :foreign_key => 'license_id'
4 10  
... ...
app/models/national_region.rb
1 1 class NationalRegion < ActiveRecord::Base
2 2  
  3 + SEARCHABLE_FIELDS = {
  4 + :name => 1,
  5 + :national_region_code => 1,
  6 + }
  7 +
3 8 def self.search_city(city_name, like = false, state = nil)
4 9  
5 10 operator = "="
... ...
app/models/organization.rb
1 1 # Represents any organization of the system
2 2 class Organization < Profile
3 3  
  4 + SEARCH_FILTERS += %w[
  5 + more_popular
  6 + more_active
  7 + ]
  8 +
4 9 settings_items :closed, :type => :boolean, :default => false
5 10 def closed?
6 11 closed
... ...
app/models/person.rb
1 1 # A person is the profile of an user holding all relationships with the rest of the system
2 2 class Person < Profile
3 3  
  4 + SEARCH_FILTERS += %w[
  5 + more_popular
  6 + more_active
  7 + ]
  8 +
4 9 def self.type_name
5 10 _('Person')
6 11 end
... ...
app/models/product.rb
1 1 class Product < ActiveRecord::Base
2 2  
  3 + SEARCHABLE_FIELDS = {
  4 + :name => 10,
  5 + :description => 1,
  6 + }
  7 +
  8 + SEARCH_FILTERS = %w[
  9 + more_recent
  10 + ]
  11 +
  12 + SEARCH_DISPLAYS = %w[map full]
  13 +
  14 + def self.default_search_display
  15 + 'full'
  16 + end
  17 +
3 18 belongs_to :enterprise
4 19 has_one :region, :through => :enterprise
5 20 validates_presence_of :enterprise
... ... @@ -173,7 +188,7 @@ class Product &lt; ActiveRecord::Base
173 188  
174 189 def price_described?
175 190 return false if price.blank? or price == 0
176   - (price - total_production_cost).zero?
  191 + (price - total_production_cost.to_f).zero?
177 192 end
178 193  
179 194 def update_price_details(price_details)
... ... @@ -215,89 +230,6 @@ class Product &lt; ActiveRecord::Base
215 230 end
216 231 end
217 232  
218   - private
219   - def f_category
220   - self.product_category.name
221   - end
222   - def f_region
223   - self.enterprise.region.id if self.enterprise.region
224   - end
225   - def self.f_region_proc(id)
226   - c = Region.find(id)
227   - s = c.parent
228   - if c and c.kind_of?(City) and s and s.kind_of?(State) and s.acronym
229   - [c.name, ', ' + s.acronym]
230   - else
231   - c.name
232   - end
233   - end
234   - def self.f_qualifier_proc(ids)
235   - array = ids.split
236   - qualifier = Qualifier.find_by_id array[0]
237   - certifier = Certifier.find_by_id array[1]
238   - certifier ? [qualifier.name, _(' cert. ') + certifier.name] : qualifier.name
239   - end
240   - def f_qualifier
241   - product_qualifiers.map do |pq|
242   - "#{pq.qualifier_id} #{pq.certifier_id}"
243   - end
244   - end
245   -
246   - alias_method :name_sortable, :name
247 233 delegate :enabled, :region, :region_id, :environment, :environment_id, :to => :enterprise
248   - def name_sortable # give a different name for solr
249   - name
250   - end
251   - def public
252   - self.public?
253   - end
254   - def price_sortable
255   - (price.nil? or price.zero?) ? nil : price
256   - end
257   - def category_filter
258   - enterprise.categories_including_virtual_ids << product_category_id
259   - end
260   - public
261   -
262   - acts_as_faceted :fields => {
263   - :f_category => {:label => _('Related products')},
264   - :f_region => {:label => _('City'), :proc => proc { |id| f_region_proc(id) }},
265   - :f_qualifier => {:label => _('Qualifiers'), :proc => proc { |id| f_qualifier_proc(id) }},
266   - }, :category_query => proc { |c| "category_filter:#{c.id}" },
267   - :order => [:f_category, :f_region, :f_qualifier]
268   -
269   - Boosts = [
270   - [:image, 0.55, proc{ |p| p.image ? 1 : 0}],
271   - [:qualifiers, 0.45, proc{ |p| p.product_qualifiers.count > 0 ? 1 : 0}],
272   - [:open_price, 0.45, proc{ |p| p.price_described? ? 1 : 0}],
273   - [:solidarity, 0.45, proc{ |p| p.percentage_from_solidarity_economy[0].to_f/100 }],
274   - [:available, 0.35, proc{ |p| p.available ? 1 : 0}],
275   - [:price, 0.35, proc{ |p| (!p.price.nil? and p.price > 0) ? 1 : 0}],
276   - [:new_product, 0.35, proc{ |p| (p.updated_at.to_i - p.created_at.to_i) < 24*3600 ? 1 : 0}],
277   - [:description, 0.3, proc{ |p| !p.description.blank? ? 1 : 0}],
278   - [:enabled, 0.2, proc{ |p| p.enterprise.enabled ? 1 : 0}],
279   - ]
280   -
281   - acts_as_searchable :fields => facets_fields_for_solr + [
282   - # searched fields
283   - {:name => {:type => :text, :boost => 2.0}},
284   - {:description => :text}, {:category_full_name => :text},
285   - # filtered fields
286   - {:public => :boolean}, {:environment_id => :integer},
287   - {:enabled => :boolean}, {:category_filter => :integer},
288   - # ordered/query-boosted fields
289   - {:price_sortable => :decimal}, {:name_sortable => :string},
290   - {:lat => :float}, {:lng => :float},
291   - :updated_at, :created_at,
292   - ], :include => [
293   - {:product_category => {:fields => [:name, :path, :slug, :lat, :lng, :acronym, :abbreviation]}},
294   - {:region => {:fields => [:name, :path, :slug, :lat, :lng]}},
295   - {:enterprise => {:fields => [:name, :identifier, :address, :nickname, :lat, :lng]}},
296   - {:qualifiers => {:fields => [:name]}},
297   - {:certifiers => {:fields => [:name]}},
298   - ], :facets => facets_option_for_solr,
299   - :boost => proc{ |p| boost = 1; Boosts.each{ |b| boost = boost * (1 - ((1 - b[2].call(p)) * b[1])) }; boost}
300   - handle_asynchronously :solr_save
301   - after_save_reindex [:enterprise], :with => :delayed_job
302 234  
303 235 end
... ...
app/models/product_category.rb
... ... @@ -11,6 +11,4 @@ class ProductCategory &lt; Category
11 11 top_category ? top_category.children : top_level_for(env).select{|c|c.kind_of?(ProductCategory)}
12 12 end
13 13  
14   - after_save_reindex [:products], :with => :delayed_job
15   -
16 14 end
... ...
app/models/profile.rb
... ... @@ -3,10 +3,20 @@
3 3 # which by default is the one returned by Environment:default.
4 4 class Profile < ActiveRecord::Base
5 5  
6   - # use for internationalizable human type names in search facets
7   - # reimplement on subclasses
8   - def self.type_name
9   - _('Profile')
  6 + SEARCHABLE_FIELDS = {
  7 + :name => 10,
  8 + :identifier => 5,
  9 + :nickname => 2,
  10 + }
  11 +
  12 + SEARCH_FILTERS = %w[
  13 + more_recent
  14 + ]
  15 +
  16 + SEARCH_DISPLAYS = %w[compact]
  17 +
  18 + def self.default_search_display
  19 + 'compact'
10 20 end
11 21  
12 22 module Roles
... ... @@ -127,18 +137,6 @@ class Profile &lt; ActiveRecord::Base
127 137 scrap.nil? ? Scrap.all_scraps(self) : Scrap.all_scraps(self).find(scrap)
128 138 end
129 139  
130   - class_inheritable_accessor :extra_index_methods
131   - self.extra_index_methods = []
132   -
133   - def extra_data_for_index
134   - self.class.extra_index_methods.map { |meth| meth.to_proc.call(self) }.flatten
135   - end
136   -
137   - def self.extra_data_for_index(sym = nil, &block)
138   - self.extra_index_methods.push(sym) if sym
139   - self.extra_index_methods.push(block) if block_given?
140   - end
141   -
142 140 acts_as_having_settings :field => :data
143 141  
144 142 def settings
... ... @@ -262,7 +260,6 @@ class Profile &lt; ActiveRecord::Base
262 260 else
263 261 ProfileCategorization.add_category_to_profile(c, self)
264 262 self.categories(true)
265   - self.solr_save
266 263 end
267 264 self.categories(reload)
268 265 end
... ... @@ -894,86 +891,6 @@ private :generate_url, :url_options
894 891 self.active_fields
895 892 end
896 893  
897   - private
898   - def self.f_categories_label_proc(environment)
899   - ids = environment.top_level_category_as_facet_ids
900   - r = Category.find(ids)
901   - map = {}
902   - ids.map{ |id| map[id.to_s] = r.detect{|c| c.id == id}.name }
903   - map
904   - end
905   - def self.f_categories_proc(facet, id)
906   - id = id.to_i
907   - return if id.zero?
908   - c = Category.find(id)
909   - c.name if c.top_ancestor.id == facet[:label_id].to_i or facet[:label_id] == 0
910   - end
911   - def f_categories
912   - category_ids - [region_id]
913   - end
914   -
915   - def f_region
916   - self.region_id
917   - end
918   - def self.f_region_proc(id)
919   - c = Region.find(id)
920   - s = c.parent
921   - if c and c.kind_of?(City) and s and s.kind_of?(State) and s.acronym
922   - [c.name, ', ' + s.acronym]
923   - else
924   - c.name
925   - end
926   - end
927   -
928   - def self.f_enabled_proc(enabled)
929   - enabled = enabled == "true" ? true : false
930   - enabled ? s_('facets|Enabled') : s_('facets|Not enabled')
931   - end
932   - def f_enabled
933   - self.enabled
934   - end
935   -
936   - def name_sortable # give a different name for solr
937   - name
938   - end
939   - def public
940   - self.public?
941   - end
942   - def category_filter
943   - categories_including_virtual_ids
944   - end
945   - public
946   -
947   - acts_as_faceted :fields => {
948   - :f_enabled => {:label => _('Situation'), :type_if => proc { |klass| klass.kind_of?(Enterprise) },
949   - :proc => proc { |id| f_enabled_proc(id) }},
950   - :f_region => {:label => _('City'), :proc => proc { |id| f_region_proc(id) }},
951   - :f_categories => {:multi => true, :proc => proc {|facet, id| f_categories_proc(facet, id)},
952   - :label => proc { |env| f_categories_label_proc(env) }, :label_abbrev => proc{ |env| f_categories_label_abbrev_proc(env) }},
953   - }, :category_query => proc { |c| "category_filter:#{c.id}" },
954   - :order => [:f_region, :f_categories, :f_enabled]
955   -
956   - acts_as_searchable :fields => facets_fields_for_solr + [:extra_data_for_index,
957   - # searched fields
958   - {:name => {:type => :text, :boost => 2.0}},
959   - {:identifier => :text}, {:nickname => :text},
960   - # filtered fields
961   - {:public => :boolean}, {:environment_id => :integer},
962   - {:category_filter => :integer},
963   - # ordered/query-boosted fields
964   - {:name_sortable => :string}, {:user_id => :integer},
965   - :enabled, :active, :validated, :public_profile,
966   - {:lat => :float}, {:lng => :float},
967   - :updated_at, :created_at,
968   - ],
969   - :include => [
970   - {:region => {:fields => [:name, :path, :slug, :lat, :lng]}},
971   - {:categories => {:fields => [:name, :path, :slug, :lat, :lng, :acronym, :abbreviation]}},
972   - ], :facets => facets_option_for_solr,
973   - :boost => proc{ |p| 10 if p.enabled }
974   - after_save_reindex [:articles], :with => :delayed_job
975   - handle_asynchronously :solr_save
976   -
977 894 def control_panel_settings_button
978 895 {:title => _('Profile Info and settings'), :icon => 'edit-profile'}
979 896 end
... ...
app/models/qualifier.rb
1 1 class Qualifier < ActiveRecord::Base
2 2  
  3 + SEARCHABLE_FIELDS = {
  4 + :name => 1,
  5 + }
  6 +
3 7 belongs_to :environment
4 8  
5 9 has_many :qualifier_certifiers, :dependent => :destroy
... ... @@ -15,6 +19,4 @@ class Qualifier &lt; ActiveRecord::Base
15 19 self.name.downcase.transliterate <=> b.name.downcase.transliterate
16 20 end
17 21  
18   - after_save_reindex [:products], :with => :delayed_job
19   -
20 22 end
... ...
app/models/region.rb
... ... @@ -4,12 +4,6 @@ class Region &lt; Category
4 4  
5 5 require_dependency 'enterprise' # enterprises can also be validators
6 6  
7   - # searches for organizations that could become validators for this region.
8   - # <tt>search</tt> is passed as is to find_by_contents on Organization.
9   - def search_possible_validators(search)
10   - Organization.find_by_contents(search)[:results].docs.reject {|item| self.validator_ids.include?(item.id) }
11   - end
12   -
13 7 def has_validator?
14 8 validators.count > 0
15 9 end
... ...
app/models/scrap.rb
1 1 class Scrap < ActiveRecord::Base
  2 + SEARCHABLE_FIELDS = {
  3 + :content => 1,
  4 + }
2 5 validates_presence_of :content
3 6 validates_presence_of :sender_id, :receiver_id
4 7  
... ...
app/views/layouts/application-ng.rhtml
... ... @@ -33,7 +33,6 @@
33 33 </div>
34 34 <div id="wrap-2">
35 35 <%= render :partial => 'layouts/user' %>
36   -
37 36 <h1 id="site-title">
38 37 <%= theme_site_title %>
39 38 </h1>
... ...
app/views/map_balloon/product.rhtml
1 1 <div id="balloon">
2   - <%= render :partial => 'search/product', :locals => {:product => @product} %>
  2 + <%= render :partial => 'search/full_product', :locals => {:product => @product} %>
3 3 </div>
... ...
app/views/search/_article.rhtml
... ... @@ -1,12 +0,0 @@
1   -<li class="search-article-item article-item">
2   - <%= link_to(article.title, article.url, :class => "search-result-title") %>
3   - <div class="search-content-first-column">
4   - <%= render :partial => 'image', :object => article %>
5   - </div>
6   - <table class="noborder search-content-second-column">
7   - <%= render :partial => 'article_common', :object => article %>
8   - </table>
9   - <%= render :partial => 'article_last_change', :object => article %>
10   -
11   - <div style="clear:both"></div>
12   -</li>
app/views/search/_blog.rhtml
... ... @@ -1,24 +0,0 @@
1   -<li class="search-blog article-item">
2   - <%= link_to blog.title, blog.view_url, :class => 'search-result-title' %>
3   - <div class="search-content-first-column">
4   - <%= render :partial => 'image', :object => blog %>
5   - </div>
6   - <table class="noborder search-content-second-column">
7   - <tr class="search-blog-items">
8   - <td class="search-field-label"><%= _("Last posts") %></td>
9   -
10   - <% r = blog.children.find(:all, :order => :updated_at, :conditions => ['type != ?', 'RssFeed']).last(3) %>
11   - <td class="<%= "search-field-none" if r.empty? %>">
12   - <% r.each do |a| %>
13   - <%= link_to a.title, a.view_url, :class => 'search-blog-sample-item '+icon_for_article(a) %>
14   - <% end %>
15   - <%= _('None') if r.empty? %>
16   - </td>
17   - </tr>
18   -
19   - <%= render :partial => 'article_common', :object => blog %>
20   - </table>
21   - <%= render :partial => 'article_last_change', :object => blog %>
22   -
23   - <div style="clear: both;"/></div>
24   -</li>
app/views/search/_compact_profile.html.erb 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +<% filter_label = profile.send(@filter + '_label') %>
  2 +<% filter_label += show_date(profile.created_at) if @filter == 'more_recent' %>
  3 +<li class="search-profile-item">
  4 + <%= profile_image_link profile, :portrait, 'div', filter_label %>
  5 +</li>
... ...
app/views/search/_content.rhtml
... ... @@ -1 +0,0 @@
1   -_article.rhtml
2 0 \ No newline at end of file
app/views/search/_display_results.rhtml
1 1 <div id="search-results" class="<%= !multiple_search? ? 'only-one-result-box' : 'multiple-results-boxes' %>">
2 2 <% @order.each do |name| %>
3   - <% results = @results[name] %>
4   - <% empty = results.nil? || results.empty? %>
  3 + <% search = @searches[name] %>
5 4  
6   - <div class="search-results-<%= name %> search-results-box <%= "search-results-empty" if empty %>">
7   - <% if not empty %>
8   - <% partial = partial_for_class(results.first.class.class_name.constantize) %>
  5 + <div class="search-results-<%= name %> search-results-box <%= "search-results-empty" if search[:results].blank? %>">
  6 + <% if !search[:results].blank? %>
9 7  
10   - <% if multiple_search? %>
  8 + <% if multiple_search?(@searches) %>
11 9 <h3><%= @names[name] %></h3>
12   - <% if results.total_entries > SearchController::MULTIPLE_SEARCH_LIMIT %>
13   - <%= link_to(_('see all (%d)') % results.total_entries, params.merge(:action => name), :class => 'see-more' ) %>
  10 + <% if search[:results].total_entries > SearchController::MULTIPLE_SEARCH_LIMIT %>
  11 + <%= link_to(_('see all (%d)') % search[:results].total_entries, params.merge(:action => name), :class => 'see-more' ) %>
14 12 <% end %>
15 13 <% end %>
16 14  
17   - <div class="search-results-innerbox search-results-type-<%= partial %> <%= 'common-profile-list-block' if partial == 'profile' %>">
  15 + <% display = display_filter(name, params[:display]) %>
  16 +
  17 + <div class="search-results-innerbox search-results-type-<%= name.to_s.singularize %> <%= 'common-profile-list-block' if [:enterprises, :people, :communities].include?(name) %>">
18 18 <ul>
19   - <% results.each do |hit| %>
20   - <%= render :partial => partial_for_class(hit.class), :object => hit %>
21   - <% end %>
  19 + <% search[:results].each do |hit| %>
  20 + <% partial = partial_for_class(hit.class, display) %>
  21 + <% variable_name = partial.gsub("#{display}_", '').to_sym %>
  22 + <%= render :partial => partial, :locals => {variable_name => hit} %>
  23 + <% end %>
22 24 </ul>
23 25 </div>
24 26 <% else %>
... ...
app/views/search/_event.rhtml
... ... @@ -1,25 +0,0 @@
1   -<li class="search-event-item article-item">
2   -<%= link_to(event.title, event.url, :class => "search-result-title") %>
3   -<div class="search-content-first-column">
4   - <%= render :partial => 'image', :object => event %>
5   -</div>
6   -<table class="noborder search-content-second-column">
7   - <% if event.start_date %>
8   - <tr class="search-article-event-date">
9   - <td class="search-field-label"><%= _('Start date') %></td>
10   - <td class="article-item-date"><%= event.start_date %></td>
11   - </tr>
12   - <% end %>
13   - <% if event.end_date %>
14   - <tr class="search-article-event-date">
15   - <td class="search-field-label"><%= _('End date') %></td>
16   - <td class="article-item-date"><%= event.end_date %></td>
17   - </tr>
18   - <% end %>
19   -
20   - <%= render :partial => 'article_common', :object => event %>
21   -</table>
22   -<%= render :partial => 'article_last_change', :object => event %>
23   -
24   -<div style="clear: both"></div>
25   -</li>
app/views/search/_facets_menu.rhtml
... ... @@ -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/_facets_unselect_menu.rhtml
... ... @@ -1,6 +0,0 @@
1   -<div class="facets-applied">
2   - <% if params[:facet] and params[:facet].count > 0 %>
3   - <span class="facets-applied-label"><%= _("Applied filters") %> </span>
4   - <%= facet_selecteds_html_for(environment, asset_class(@asset), params) %>
5   - <% end %>
6   -</div>
app/views/search/_folder.rhtml
... ... @@ -1,24 +0,0 @@
1   -<li class="search-folder-item article-item">
2   - <%= link_to folder.title, folder.view_url, :class => 'search-result-title' %>
3   - <div class="search-content-first-column">
4   - <%= render :partial => 'image', :object => folder %>
5   - </div>
6   - <table class="noborder search-content-second-column">
7   - <tr class="search-folder-items">
8   - <td class="search-field-label"><%= _("Last items") %></td>
9   -
10   - <% r = folder.children.last(3) %>
11   - <td class="<%= "search-field-none" if r.empty? %>">
12   - <% r.each do |a| %>
13   - <%= link_to a.title, a.view_url, :class => 'search-folder-sample-item '+icon_for_article(a) %>
14   - <% end %>
15   - <%= _('None') if r.empty? %>
16   - </td>
17   - </tr>
18   -
19   - <%= render :partial => 'article_common', :object => folder %>
20   - </table>
21   - <%= render :partial => 'article_last_change', :object => folder %>
22   -
23   - <div style="clear:both"></div>
24   -</li>
app/views/search/_forum.rhtml
... ... @@ -1,24 +0,0 @@
1   -<li class="search-forum-item article-item">
2   - <%= link_to forum.title, forum.view_url, :class => 'search-result-title' %>
3   - <div class="search-content-first-column">
4   - <%= render :partial => 'image', :object => forum %>
5   - </div>
6   - <table class="noborder search-content-second-column">
7   - <tr class="search-forum-items">
8   - <td class="search-field-label"><%= _("Last topics") %></td>
9   -
10   - <% r = forum.children.find(:all, :order => :updated_at, :conditions => ['type != ?', 'RssFeed']).last(3) %>
11   - <td class="<%= "search-field-none" if r.empty? %>">
12   - <% r.each do |a| %>
13   - <%= link_to a.title, a.view_url, :class => 'search-forum-sample-item '+icon_for_article(a) %>
14   - <% end %>
15   - <%= _('None') if r.empty? %>
16   - </td>
17   - </tr>
18   -
19   - <%= render :partial => 'article_common', :object => forum %>
20   - </table>
21   - <%= render :partial => 'article_last_change', :object => forum %>
22   -
23   - <div style="clear:both"></div>
24   -</li>
app/views/search/_full_article.html.erb 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +<li class="search-article-item article-item">
  2 + <%= link_to(article.title, article.url, :class => "search-result-title") %>
  3 + <div class="search-content-first-column">
  4 + <%= render :partial => 'image', :object => article %>
  5 + </div>
  6 + <table class="noborder search-content-second-column">
  7 + <%= render :partial => 'article_common', :object => article %>
  8 + </table>
  9 + <%= render :partial => 'article_last_change', :object => article %>
  10 +
  11 + <div style="clear:both"></div>
  12 +</li>
... ...
app/views/search/_full_blog.html.erb 0 → 100644
... ... @@ -0,0 +1,24 @@
  1 +<li class="search-blog article-item">
  2 + <%= link_to blog.title, blog.view_url, :class => 'search-result-title' %>
  3 + <div class="search-content-first-column">
  4 + <%= render :partial => 'image', :object => blog %>
  5 + </div>
  6 + <table class="noborder search-content-second-column">
  7 + <tr class="search-blog-items">
  8 + <td class="search-field-label"><%= _("Last posts") %></td>
  9 +
  10 + <% r = blog.children.find(:all, :order => :updated_at, :conditions => ['type != ?', 'RssFeed']).last(3) %>
  11 + <td class="<%= "search-field-none" if r.empty? %>">
  12 + <% r.each do |a| %>
  13 + <%= link_to a.title, a.view_url, :class => 'search-blog-sample-item '+icon_for_article(a) %>
  14 + <% end %>
  15 + <%= _('None') if r.empty? %>
  16 + </td>
  17 + </tr>
  18 +
  19 + <%= render :partial => 'article_common', :object => blog %>
  20 + </table>
  21 + <%= render :partial => 'article_last_change', :object => blog %>
  22 +
  23 + <div style="clear: both;"/></div>
  24 +</li>
... ...
app/views/search/_full_enterprise.html.erb 0 → 100644
... ... @@ -0,0 +1,38 @@
  1 +<li class="search-profile-item">
  2 + <div class="search-enterprise-item">
  3 + <div class="search-enterprise-item-column-left">
  4 + <%= profile_image_link enterprise, :portrait, 'div',
  5 + @filter == 'more_recent' ? enterprise.send(@filter + '_label') + show_date(enterprise.created_at) : enterprise.send(@filter + '_label') %>
  6 + </div>
  7 + <div class="search-enterprise-item-column-right">
  8 + <%= link_to_homepage(enterprise.name, enterprise.identifier, :class => "search-result-title") %>
  9 + <div class="search-enterprise-description">
  10 + <% if enterprise.description %>
  11 + <% body_stripped = strip_tags(enterprise.description) %>
  12 + <% elsif enterprise.home_page and enterprise.home_page.body %>
  13 + <% body_stripped = strip_tags(enterprise.home_page.body) %>
  14 + <% end %>
  15 + <%= excerpt(body_stripped, body_stripped.first(3), 200) if body_stripped %>
  16 + </div>
  17 + <div class="search-enterprise-region">
  18 + <span class="search-enterprise-region-label"><%= _("City") %></span>
  19 + <% if enterprise.region %>
  20 + <span class="search-enterprise-region-name"><%= city_with_state(enterprise.region) %></span>
  21 + <% end %>
  22 + </div>
  23 +
  24 + <div class="search-enterprise-categorization">
  25 + <% enterprise.top_level_categorization.each do |parent, children| %>
  26 + <div class="search-enterprise-category-<%=parent.id%> search-enterprise-category">
  27 + <span class="search-enterprise-categorization-parent"><%= parent.name %></span>
  28 + <span class="search-enterprise-categorization-children">
  29 + <%= children.collect(&:name).join(', ') %>
  30 + </span>
  31 + </div>
  32 + <% end %>
  33 + </div>
  34 + </div>
  35 +
  36 + <hr class="clearfix" />
  37 + </div>
  38 +</li>
... ...
app/views/search/_full_event.html.erb 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +<li class="search-event-item article-item">
  2 +<%= link_to(event.title, event.url, :class => "search-result-title") %>
  3 +<div class="search-content-first-column">
  4 + <%= render :partial => 'image', :object => event %>
  5 +</div>
  6 +<table class="noborder search-content-second-column">
  7 + <% if event.start_date %>
  8 + <tr class="search-article-event-date">
  9 + <td class="search-field-label"><%= _('Start date') %></td>
  10 + <td class="article-item-date"><%= event.start_date %></td>
  11 + </tr>
  12 + <% end %>
  13 + <% if event.end_date %>
  14 + <tr class="search-article-event-date">
  15 + <td class="search-field-label"><%= _('End date') %></td>
  16 + <td class="article-item-date"><%= event.end_date %></td>
  17 + </tr>
  18 + <% end %>
  19 +
  20 + <%= render :partial => 'article_common', :object => event %>
  21 +</table>
  22 +<%= render :partial => 'article_last_change', :object => event %>
  23 +
  24 +<div style="clear: both"></div>
  25 +</li>
... ...
app/views/search/_full_folder.html.erb 0 → 100644
... ... @@ -0,0 +1,24 @@
  1 +<li class="search-folder-item article-item">
  2 + <%= link_to folder.title, folder.view_url, :class => 'search-result-title' %>
  3 + <div class="search-content-first-column">
  4 + <%= render :partial => 'image', :object => folder %>
  5 + </div>
  6 + <table class="noborder search-content-second-column">
  7 + <tr class="search-folder-items">
  8 + <td class="search-field-label"><%= _("Last items") %></td>
  9 +
  10 + <% r = folder.children.last(3) %>
  11 + <td class="<%= "search-field-none" if r.empty? %>">
  12 + <% r.each do |a| %>
  13 + <%= link_to a.title, a.view_url, :class => 'search-folder-sample-item '+icon_for_article(a) %>
  14 + <% end %>
  15 + <%= _('None') if r.empty? %>
  16 + </td>
  17 + </tr>
  18 +
  19 + <%= render :partial => 'article_common', :object => folder %>
  20 + </table>
  21 + <%= render :partial => 'article_last_change', :object => folder %>
  22 +
  23 + <div style="clear:both"></div>
  24 +</li>
... ...
app/views/search/_full_forum.html.erb 0 → 100644
... ... @@ -0,0 +1,24 @@
  1 +<li class="search-forum-item article-item">
  2 + <%= link_to forum.title, forum.view_url, :class => 'search-result-title' %>
  3 + <div class="search-content-first-column">
  4 + <%= render :partial => 'image', :object => forum %>
  5 + </div>
  6 + <table class="noborder search-content-second-column">
  7 + <tr class="search-forum-items">
  8 + <td class="search-field-label"><%= _("Last topics") %></td>
  9 +
  10 + <% r = forum.children.find(:all, :order => :updated_at, :conditions => ['type != ?', 'RssFeed']).last(3) %>
  11 + <td class="<%= "search-field-none" if r.empty? %>">
  12 + <% r.each do |a| %>
  13 + <%= link_to a.title, a.view_url, :class => 'search-forum-sample-item '+icon_for_article(a) %>
  14 + <% end %>
  15 + <%= _('None') if r.empty? %>
  16 + </td>
  17 + </tr>
  18 +
  19 + <%= render :partial => 'article_common', :object => forum %>
  20 + </table>
  21 + <%= render :partial => 'article_last_change', :object => forum %>
  22 +
  23 + <div style="clear:both"></div>
  24 +</li>
... ...
app/views/search/_full_gallery.html.erb 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +<li class="search-gallery article-item">
  2 + <%= link_to gallery.title, gallery.view_url, :class => 'search-result-title' %>
  3 + <div class="search-content-first-column">
  4 + <%= render :partial => 'image', :object => gallery %>
  5 + </div>
  6 + <table class="noborder search-content-second-column">
  7 + <%= render :partial => 'article_common', :object => gallery %>
  8 + </table>
  9 + <%= render :partial => 'article_last_change', :object => gallery %>
  10 +
  11 + <div style="clear: both"></div>
  12 +</li>
  13 +
... ...
app/views/search/_full_product.rhtml 0 → 100644
... ... @@ -0,0 +1,85 @@
  1 +<% extra_content = @plugins.dispatch(:asset_product_extras, product).collect { |content| instance_eval(&content) } %>
  2 +<% extra_properties = @plugins.dispatch(:asset_product_properties, product)%>
  3 +
  4 +<li class="search-product-item <%= 'highlighted' if product.highlighted? %>">
  5 +
  6 + <div class="search-product-item-first-column">
  7 + <%= render :partial => 'search/image', :object => product %>
  8 +
  9 + <% if product.available %>
  10 + <% if product.price && product.price > 0 %>
  11 + <% has_discount = product.discount && product.discount > 0 %>
  12 + <% if product.price %>
  13 + <span class="search-product-price-textid"><%=_("from") if has_discount %></span><%= price_span(product.price, :class => "search-product-price " + (has_discount ? 'with-discount' : '')) %>
  14 + <% if has_discount %>
  15 + <span class="search-product-price-textid"><%=_("by")%></span><%= price_span(product.price_with_discount, :class => "search-product-price") %>
  16 + <% end %>
  17 + <% if product.unit %>
  18 + <span class="search-product-unit">&nbsp;<%= _('/') %>&nbsp;<%= product.unit.name %></span>
  19 + <% end %>
  20 + <% end %>
  21 + <div class="search-product-inputs-info">
  22 + <% if p = product.percentage_from_solidarity_economy %>
  23 + <div class="search-product-percentage-from-solidarity-economy search-product-ecosol-percentage-icon-<%= p[0].to_s %>"
  24 + title="<%=_('Percentage of inputs from solidarity economy')%>">
  25 + <%= p[1] %>
  26 + </div>
  27 + <% end %>
  28 +
  29 + <% if product.price_described? %>
  30 + <% title = (product.inputs.relevant_to_price + product.price_details).map{ |i|
  31 + '<div class="search-product-input-dots-to-price">' +
  32 + '<div class="search-product-input-name">' + i.name + '</div>' +
  33 + price_span(i.price, :class => 'search-product-input-price') +
  34 + '</div>' }.join('') %>
  35 + <%= link_to_function _("Open Price"), '', :title => title, :class => "search-product-price-details" %>
  36 + <% end %>
  37 + </div>
  38 + <% end %>
  39 + <% else %>
  40 + <span class="product-not-available"><%= _('Not available') %></div>
  41 + <% end %>
  42 +
  43 + </div>
  44 + <div class="search-product-item-second-column">
  45 + <%= link_to_product product, :class => 'search-result-title' %>
  46 + <div class="search-product-supplier">
  47 + <span class="search-field-label"><%= _('Supplier') %> </span><%= link_to_homepage(product.enterprise.name, product.enterprise.identifier) %>
  48 + </div>
  49 + <div class="search-product-description">
  50 + <% if product.description %>
  51 + <% desc_stripped = strip_tags(product.description) %>
  52 + <span class="search-field-label"><%= _('Description') %> </span><%= excerpt(desc_stripped, desc_stripped.first(3), 300) %>
  53 + <% end %>
  54 + </div>
  55 + </div>
  56 + <div class="search-product-item-third-column">
  57 + <div class="search-product-region">
  58 + <% if product.enterprise.region %>
  59 + <span class="search-field-label"><%= _('City') %></span>
  60 + <br /><%= city_with_state(product.enterprise.region) %>
  61 + <% end %>
  62 + </div>
  63 + <div class="search-product-qualifiers">
  64 + <% if product.product_qualifiers.count > 0 %>
  65 + <span class="search-field-label"><%= _('Qualifiers') %></span>
  66 + <% product.product_qualifiers.each do |pq| %>
  67 + <% if pq.qualifier %>
  68 + <span class="search-product-qualifier"><%= pq.qualifier.name + (pq.certifier.nil? ? _(";") : '') %></span>
  69 + <% end %>
  70 + <% if pq.certifier %>
  71 + <span class="search-product-certifier">&nbsp;<%= _('cert. ') + pq.certifier.name + _(";") %></span>
  72 + <% end %>
  73 + <% end %>
  74 + <% end %>
  75 + </div>
  76 + </div>
  77 +
  78 + <div style="clear: both"></div>
  79 +
  80 + <%= extra_content.join('\n') %>
  81 + <% extra_properties.each do |property| %>
  82 + <div><%= property[:name] + ': ' + instance_eval(&property[:content]) %></div>
  83 + <% end %>
  84 +
  85 +</li>
... ...
app/views/search/_full_text_article.html.erb 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +<li class="search-text-article-item article-item">
  2 + <%= link_to(text_article.title, text_article.url, :class => "search-result-title") %>
  3 +
  4 + <div class="search-content-first-column">
  5 + <%= render :partial => 'image', :object => text_article %>
  6 + </div>
  7 + <table class="noborder search-content-second-column">
  8 + <%= render :partial => 'article_common', :object => text_article %>
  9 + </table>
  10 + <%= render :partial => 'article_last_change', :object => text_article %>
  11 +
  12 + <div style="clear: both"></div>
  13 +</li>
... ...
app/views/search/_full_uploaded_file.html.erb 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +<li class="search-uploaded-file-item article-item">
  2 + <%= link_to uploaded_file.filename, uploaded_file.view_url, :class => 'search-result-title' %>
  3 +
  4 + <div class="search-content-first-column">
  5 + <%= render :partial => 'image', :object => uploaded_file %>
  6 + </div>
  7 +
  8 + <table class="noborder search-content-second-column">
  9 + <%= render :partial => 'article_author', :object => uploaded_file %>
  10 + <%= render :partial => 'article_description', :object => uploaded_file %>
  11 +
  12 + <% if uploaded_file.parent and uploaded_file.parent.published? %>
  13 + <tr class="search-uploaded-file-parent">
  14 + <td class="search-field-label"><%= uploaded_file.parent.gallery? ? _("Gallery") : _("Folder") %></td>
  15 + <td><%= link_to uploaded_file.parent.name, uploaded_file.parent.url %></td>
  16 + </tr>
  17 + <% end %>
  18 +
  19 + <%= render :partial => 'article_tags', :object => uploaded_file.tags %>
  20 + <%= render :partial => 'article_categories', :object => uploaded_file.categories %>
  21 + </table>
  22 + <%= render :partial => 'article_last_change', :object => uploaded_file %>
  23 +
  24 + <div style="clear:both"></div>
  25 +</li>
... ...
app/views/search/_gallery.rhtml
... ... @@ -1,13 +0,0 @@
1   -<li class="search-gallery article-item">
2   - <%= link_to gallery.title, gallery.view_url, :class => 'search-result-title' %>
3   - <div class="search-content-first-column">
4   - <%= render :partial => 'image', :object => gallery %>
5   - </div>
6   - <table class="noborder search-content-second-column">
7   - <%= render :partial => 'article_common', :object => gallery %>
8   - </table>
9   - <%= render :partial => 'article_last_change', :object => gallery %>
10   -
11   - <div style="clear: both"></div>
12   -</li>
13   -
app/views/search/_google_maps.rhtml
... ... @@ -13,8 +13,8 @@
13 13 <script type='text/javascript'>
14 14 mapLoad(<%= GoogleMaps.initial_zoom.to_json %>);
15 15  
16   - <% @results.each do |name,results| %>
17   - <% results.each do |item| %>
  16 + <% @searches.each do |name,search| %>
  17 + <% search[:results].each do |item| %>
18 18 <% if item.lat && item.lng %>
19 19 mapPutMarker(<%= item.lat.to_json %>, <%= item.lng.to_json %>, <%= item.name.to_json %>, '<%= icon %>',
20 20 '<%= url_for(:controller => :map_balloon, :action => name.to_s.singularize, :id => item.id) %>');
... ...
app/views/search/_image.html.erb 0 → 100644
... ... @@ -0,0 +1,53 @@
  1 +<div class="search-image-container">
  2 +
  3 + <% if image.is_a? UploadedFile and image.filename %>
  4 + <% extension = image.extension %>
  5 + <% if ['jpg', 'jpeg', 'gif', 'png', 'tiff', 'svg'].include? extension %>
  6 + <%= link_to '', image.view_url, :class => "search-image-pic", :style => 'background-image: url(%s)'% image.public_filename(:thumb) %>
  7 + <% if image.width && image.height %>
  8 + <% javascript_tag do %>
  9 + image = jQuery('script').last().parent().find('.search-image-pic');
  10 + des_width = parseInt(image.css('width'));
  11 + des_height = parseInt(image.css('height'));
  12 +
  13 + width = <%= image.width %>;
  14 + height = <%= image.height %>;
  15 + scale_factor = width > height ? des_width/width : des_height/height;
  16 +
  17 + image.css({'width' : scale_factor*width +'px', 'height' : scale_factor*height+'px'});
  18 + <% end %>
  19 + <% end %>
  20 + <% elsif ['pdf'].include? extension %>
  21 + <%= link_to '', image.view_url, :class => 'search-image-pic icon-application-pdf' %>
  22 + <% elsif ['doc', 'docx', 'odt', 'rtf', 'txt', 'html', 'htm'].include? extension %>
  23 + <%= link_to '', image.view_url, :class => 'search-image-pic icon-application-vnd-oasis-opendocument-text' %>
  24 + <% elsif ['xls', 'xlsx', 'ods', 'csv', 'tsv', 'tab'].include? extension %>
  25 + <%= link_to '', image.view_url, :class => 'search-image-pic icon-application-vnd-oasis-opendocument-spreadsheet' %>
  26 + <% end %>
  27 + <% elsif image.is_a? Gallery %>
  28 + <div class="search-gallery-items">
  29 + <% r = image.children.find(:all, :order => :updated_at, :conditions => ['type = ?', 'UploadedFile']).last(3) %>
  30 + <% if r.length > 0 %>
  31 + <% r.each_index do |i| img = r[i] %>
  32 + <%= link_to '', img.view_url, :class => "search-image-pic pic-num#{i+1}",
  33 + :style => 'background-image: url(%s)'% img.public_filename(:thumb) %>
  34 + <% end %>
  35 + <% else %>
  36 + <div class="search-no-image"><span><%= _('No image') %></span></div>
  37 + <% end %>
  38 + </div>
  39 + <% elsif image.is_a? Product %>
  40 + <% if image.image %>
  41 + <div class="zoomable-image">
  42 + <%= link_to '', product_path(image), :class => "search-image-pic",
  43 + :style => 'background-image: url(%s)'% image.default_image(:thumb) %>
  44 + <%= link_to content_tag(:span, _('Zoom in')), image.image.public_filename,
  45 + :class => 'zoomify-image' %>
  46 + </div>
  47 + <% else %>
  48 + <div class="search-no-image"><span><%= _('No image') %></span></div>
  49 + <% end %>
  50 + <% else %>
  51 + <div class="search-content-type-icon icon-content-<%=image.class.to_s.underscore.dasherize%>"></div>
  52 + <% end %>
  53 +</div>
... ...
app/views/search/_image.rhtml
... ... @@ -1,53 +0,0 @@
1   -<div class="search-image-container">
2   -
3   - <% if image.is_a? UploadedFile and image.filename %>
4   - <% extension = image.extension %>
5   - <% if ['jpg', 'jpeg', 'gif', 'png', 'tiff', 'svg'].include? extension %>
6   - <%= link_to '', image.view_url, :class => "search-image-pic", :style => 'background-image: url(%s)'% image.public_filename(:thumb) %>
7   - <% if image.width && image.height %>
8   - <% javascript_tag do %>
9   - image = jQuery('script').last().parent().find('.search-image-pic');
10   - des_width = parseInt(image.css('width'));
11   - des_height = parseInt(image.css('height'));
12   -
13   - width = <%= image.width %>;
14   - height = <%= image.height %>;
15   - scale_factor = width > height ? des_width/width : des_height/height;
16   -
17   - image.css({'width' : scale_factor*width +'px', 'height' : scale_factor*height+'px'});
18   - <% end %>
19   - <% end %>
20   - <% elsif ['pdf'].include? extension %>
21   - <%= link_to '', image.view_url, :class => 'search-image-pic icon-application-pdf' %>
22   - <% elsif ['doc', 'docx', 'odt', 'rtf', 'txt', 'html', 'htm'].include? extension %>
23   - <%= link_to '', image.view_url, :class => 'search-image-pic icon-application-vnd-oasis-opendocument-text' %>
24   - <% elsif ['xls', 'xlsx', 'ods', 'csv', 'tsv', 'tab'].include? extension %>
25   - <%= link_to '', image.view_url, :class => 'search-image-pic icon-application-vnd-oasis-opendocument-spreadsheet' %>
26   - <% end %>
27   - <% elsif image.is_a? Gallery %>
28   - <div class="search-gallery-items">
29   - <% r = image.children.find(:all, :order => :updated_at, :conditions => ['type = ?', 'UploadedFile']).last(3) %>
30   - <% if r.length > 0 %>
31   - <% r.each_index do |i| img = r[i] %>
32   - <%= link_to '', img.view_url, :class => "search-image-pic pic-num#{i+1}",
33   - :style => 'background-image: url(%s)'% img.public_filename(:thumb) %>
34   - <% end %>
35   - <% else %>
36   - <div class="search-no-image"><span><%= _('No image') %></span></div>
37   - <% end %>
38   - </div>
39   - <% elsif image.is_a? Product %>
40   - <% if image.image %>
41   - <div class="zoomable-image">
42   - <%= link_to '', product_path(image), :class => "search-image-pic",
43   - :style => 'background-image: url(%s)'% image.default_image(:thumb) %>
44   - <%= link_to content_tag(:span, _('Zoom in')), image.image.public_filename,
45   - :class => 'zoomify-image' %>
46   - </div>
47   - <% else %>
48   - <div class="search-no-image"><span><%= _('No image') %></span></div>
49   - <% end %>
50   - <% else %>
51   - <div class="search-content-type-icon icon-content-<%=image.class.to_s.underscore.dasherize%>"></div>
52   - <% end %>
53   -</div>
app/views/search/_product.rhtml
... ... @@ -1,85 +0,0 @@
1   -<% extra_content = @plugins.dispatch(:asset_product_extras, product).collect { |content| instance_eval(&content) } %>
2   -<% extra_properties = @plugins.dispatch(:asset_product_properties, product)%>
3   -
4   -<li class="search-product-item <%= 'highlighted' if product.highlighted? %>">
5   -
6   - <div class="search-product-item-first-column">
7   - <%= render :partial => 'search/image', :object => product %>
8   -
9   - <% if product.available %>
10   - <% if product.price && product.price > 0 %>
11   - <% has_discount = product.discount && product.discount > 0 %>
12   - <% if product.price %>
13   - <span class="search-product-price-textid"><%=_("from") if has_discount %></span><%= price_span(product.price, :class => "search-product-price " + (has_discount ? 'with-discount' : '')) %>
14   - <% if has_discount %>
15   - <span class="search-product-price-textid"><%=_("by")%></span><%= price_span(product.price_with_discount, :class => "search-product-price") %>
16   - <% end %>
17   - <% if product.unit %>
18   - <span class="search-product-unit">&nbsp;<%= _('/') %>&nbsp;<%= product.unit.name %></span>
19   - <% end %>
20   - <% end %>
21   - <div class="search-product-inputs-info">
22   - <% if p = product.percentage_from_solidarity_economy %>
23   - <div class="search-product-percentage-from-solidarity-economy search-product-ecosol-percentage-icon-<%= p[0].to_s %>"
24   - title="<%=_('Percentage of inputs from solidarity economy')%>">
25   - <%= p[1] %>
26   - </div>
27   - <% end %>
28   -
29   - <% if product.price_described? %>
30   - <% title = (product.inputs.relevant_to_price + product.price_details).map{ |i|
31   - '<div class="search-product-input-dots-to-price">' +
32   - '<div class="search-product-input-name">' + i.name + '</div>' +
33   - price_span(i.price, :class => 'search-product-input-price') +
34   - '</div>' }.join('') %>
35   - <%= link_to_function _("Open Price"), '', :title => title, :class => "search-product-price-details" %>
36   - <% end %>
37   - </div>
38   - <% end %>
39   - <% else %>
40   - <span class="product-not-available"><%= _('Not available') %></div>
41   - <% end %>
42   -
43   - </div>
44   - <div class="search-product-item-second-column">
45   - <%= link_to_product product, :class => 'search-result-title' %>
46   - <div class="search-product-supplier">
47   - <span class="search-field-label"><%= _('Supplier') %> </span><%= link_to_homepage(product.enterprise.name, product.enterprise.identifier) %>
48   - </div>
49   - <div class="search-product-description">
50   - <% if product.description %>
51   - <% desc_stripped = strip_tags(product.description) %>
52   - <span class="search-field-label"><%= _('Description') %> </span><%= excerpt(desc_stripped, desc_stripped.first(3), 300) %>
53   - <% end %>
54   - </div>
55   - </div>
56   - <div class="search-product-item-third-column">
57   - <div class="search-product-region">
58   - <% if product.enterprise.region %>
59   - <span class="search-field-label"><%= _('City') %></span>
60   - <br /><%= city_with_state(product.enterprise.region) %>
61   - <% end %>
62   - </div>
63   - <div class="search-product-qualifiers">
64   - <% if product.product_qualifiers.count > 0 %>
65   - <span class="search-field-label"><%= _('Qualifiers') %></span>
66   - <% product.product_qualifiers.each do |pq| %>
67   - <% if pq.qualifier %>
68   - <span class="search-product-qualifier"><%= pq.qualifier.name + (pq.certifier.nil? ? _(";") : '') %></span>
69   - <% end %>
70   - <% if pq.certifier %>
71   - <span class="search-product-certifier">&nbsp;<%= _('cert. ') + pq.certifier.name + _(";") %></span>
72   - <% end %>
73   - <% end %>
74   - <% end %>
75   - </div>
76   - </div>
77   -
78   - <div style="clear: both"></div>
79   -
80   - <%= extra_content.join('\n') %>
81   - <% extra_properties.each do |property| %>
82   - <div><%= property[:name] + ': ' + instance_eval(&property[:content]) %></div>
83   - <% end %>
84   -
85   -</li>
app/views/search/_profile.rhtml
... ... @@ -1,42 +0,0 @@
1   -<li class="search-profile-item">
2   -<% if @empty_query or multiple_search? or !profile.enterprise? %>
3   - <%= profile_image_link profile, :portrait, 'div',
4   - @filter == 'more_recent' ? profile.send(@filter + '_label') + show_date(profile.created_at) : profile.send(@filter + '_label') %>
5   -<% else %>
6   - <div class="search-enterprise-item">
7   - <div class="search-enterprise-item-column-left">
8   - <%= profile_image_link profile, :portrait, 'div' %>
9   - </div>
10   - <div class="search-enterprise-item-column-right">
11   - <%= link_to_homepage(profile.name, profile.identifier, :class => "search-result-title") %>
12   - <div class="search-enterprise-description">
13   - <% if profile.description %>
14   - <% body_stripped = strip_tags(profile.description) %>
15   - <% elsif profile.home_page and profile.home_page.body %>
16   - <% body_stripped = strip_tags(profile.home_page.body) %>
17   - <% end %>
18   - <%= excerpt(body_stripped, body_stripped.first(3), 200) if body_stripped %>
19   - </div>
20   - <div class="search-enterprise-region">
21   - <span class="search-enterprise-region-label"><%= _("City") %></span>
22   - <% if profile.region %>
23   - <span class="search-enterprise-region-name"><%= city_with_state(profile.region) %></span>
24   - <% end %>
25   - </div>
26   -
27   - <div class="search-enterprise-categorization">
28   - <% profile.top_level_categorization.each do |parent, children| %>
29   - <div class="search-enterprise-category-<%=parent.id%> search-enterprise-category">
30   - <span class="search-enterprise-categorization-parent"><%= parent.name %></span>
31   - <span class="search-enterprise-categorization-children">
32   - <%= children.collect(&:name).join(', ') %>
33   - </span>
34   - </div>
35   - <% end %>
36   - </div>
37   - </div>
38   -
39   - <hr class="clearfix" />
40   - </div>
41   -<% end %>
42   -</li>
app/views/search/_results_header.rhtml
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   -
  1 +<div class="search-results-header <%= "search-no-results" if @searches[@asset].nil? or @searches[@asset].length == 0 %>">
  2 + <div id='search-filter-title'><%= filter_title(@asset, @filter) %></div>
  3 + <%= display_selector(@asset, params[:display]) %>
  4 + <%= filter_selector(@asset, @filter) %>
20 5 <div style="clear: both"></div>
21 6 </div>
... ...
app/views/search/_search_form.rhtml
... ... @@ -4,16 +4,7 @@
4 4 :method => 'get', :class => 'search_form' ) do %>
5 5  
6 6 <%= hidden_field_tag :display, params[:display] %>
7   -
8   - <% params_uri = CGI::unescape(request.request_uri) %>
9   - <% if params_uri.index('?') %>
10   - <% params_uri[(params_uri.index('?')+1)..-1].to_s.split("&").each do |part| %>
11   - <% if part.start_with? "facet" %>
12   - <% name_value = part.split("=") %>
13   - <%= hidden_field_tag name_value[0], name_value[1] %>
14   - <% end %>
15   - <% end %>
16   - <% end %>
  7 + <%= hidden_field_tag :filter, params[:filter] %>
17 8  
18 9 <div class="search-field">
19 10 <span class="formfield">
... ... @@ -24,6 +15,8 @@
24 15 <%= submit_button(:search, _('Search')) %>
25 16 </div>
26 17  
  18 + <%= render :partial => 'search_form_extra_fields' %>
  19 +
27 20 <% end %>
28 21  
29 22 <% if @empty_query %>
... ...
app/views/search/_search_form_extra_fields.html.erb 0 → 100644
... ... @@ -0,0 +1,6 @@
  1 +<%#
  2 + This partial serves the search engine plugins to fill in any extra
  3 + fields they need in the search form. The search engine plugin must define a
  4 + partial named like this one and the plugin's view path will override the
  5 + default view path which will render the plugin file instead of this one.
  6 +%>
... ...
app/views/search/_text_article.rhtml
... ... @@ -1,13 +0,0 @@
1   -<li class="search-text-article-item article-item">
2   - <%= link_to(text_article.title, text_article.url, :class => "search-result-title") %>
3   -
4   - <div class="search-content-first-column">
5   - <%= render :partial => 'image', :object => text_article %>
6   - </div>
7   - <table class="noborder search-content-second-column">
8   - <%= render :partial => 'article_common', :object => text_article %>
9   - </table>
10   - <%= render :partial => 'article_last_change', :object => text_article %>
11   -
12   - <div style="clear: both"></div>
13   -</li>
app/views/search/_uploaded_file.rhtml
... ... @@ -1,25 +0,0 @@
1   -<li class="search-uploaded-file-item article-item">
2   - <%= link_to uploaded_file.filename, uploaded_file.view_url, :class => 'search-result-title' %>
3   -
4   - <div class="search-content-first-column">
5   - <%= render :partial => 'image', :object => uploaded_file %>
6   - </div>
7   -
8   - <table class="noborder search-content-second-column">
9   - <%= render :partial => 'article_author', :object => uploaded_file %>
10   - <%= render :partial => 'article_description', :object => uploaded_file %>
11   -
12   - <% if uploaded_file.parent and uploaded_file.parent.published? %>
13   - <tr class="search-uploaded-file-parent">
14   - <td class="search-field-label"><%= uploaded_file.parent.gallery? ? _("Gallery") : _("Folder") %></td>
15   - <td><%= link_to uploaded_file.parent.name, uploaded_file.parent.url %></td>
16   - </tr>
17   - <% end %>
18   -
19   - <%= render :partial => 'article_tags', :object => uploaded_file.tags %>
20   - <%= render :partial => 'article_categories', :object => uploaded_file.categories %>
21   - </table>
22   - <%= render :partial => 'article_last_change', :object => uploaded_file %>
23   -
24   - <div style="clear:both"></div>
25   -</li>
app/views/search/articles.html.erb 0 → 120000
... ... @@ -0,0 +1 @@
  1 +search_page.html.erb
0 2 \ No newline at end of file
... ...
app/views/search/articles.rhtml
... ... @@ -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/category_index.rhtml
... ... @@ -1 +0,0 @@
1   -index.rhtml
2 0 \ No newline at end of file
app/views/search/category_index.rhtml 0 → 100644
... ... @@ -0,0 +1,28 @@
  1 +<div id="search-page" class="<%= "view-category" if @category %>">
  2 +
  3 + <% if @category %>
  4 + <div id="category-image"><%= image_tag(@category.image.public_filename(:thumb), :id => 'category-image') if @category.image %></div>
  5 + <% end %>
  6 +
  7 + <h1><%= _("Category Index") %></h1>
  8 + <%= category_context(@category, params) %>
  9 + <%= display_results @searches %>
  10 +
  11 + <div id="category-childs">
  12 + <% if @category %>
  13 + <h2> <%= _('Sub-categories') %> </h2>
  14 + <% if @category.children.empty? %>
  15 + <strong id="cat-no-child"><%= _('No sub-categories') %></strong>
  16 + <% else %>
  17 + <ul>
  18 + <% @category.children.each do |c| %>
  19 + <li> <%= link_to_category c, false %> </li>
  20 + <% end %>
  21 + </ul>
  22 + <% end %>
  23 + <% end %>
  24 + </div>
  25 +
  26 +</div>
  27 +
  28 +<div style="clear: both"></div>
... ...
app/views/search/communities.html.erb 0 → 120000
... ... @@ -0,0 +1 @@
  1 +search_page.html.erb
0 2 \ No newline at end of file
... ...
app/views/search/communities.rhtml
... ... @@ -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   -articles.rhtml
2 0 \ No newline at end of file
app/views/search/enterprises.html.erb 0 → 120000
... ... @@ -0,0 +1 @@
  1 +search_page.html.erb
0 2 \ No newline at end of file
... ...
app/views/search/enterprises.rhtml
... ... @@ -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 @@
  1 +<%= render :partial => 'events/agenda' %>
... ...
app/views/search/events.rhtml
... ... @@ -1,3 +0,0 @@
1   -<%= search_page_title( Environment.default.name + "'s " + @titles[:events], @category ) %>
2   -
3   -<%= render :partial => 'events/agenda' %>
app/views/search/facets_browse.rhtml
... ... @@ -1,8 +0,0 @@
1   -<% results = @asset_class.map_facet_results(@facet, params[:facet], @facets, @all_facets) %>
2   -
3   -<% array = [] %>
4   -<% @asset_class.facet_result_sort(@facet, results, :alphabetically).each do |id, label, count| %>
5   - <% array << {:id => id, :name => facet_link_html(@facet, params.merge(:controller => 'search', :action => @asset), id, label, count)} %>
6   -<% end %>
7   -
8   -<%= facet_javascript('facet-input-'+@facet[:id].to_s, @facet, array) %>
app/views/search/index.rhtml
... ... @@ -7,7 +7,7 @@
7 7 <%= search_page_title(_('Search Results'), @category) %>
8 8 <%= render :partial => 'search_form', :locals => { :hint => '' } %>
9 9 <%= category_context(@category, params) %>
10   - <%= display_results %>
  10 + <%= display_results(@searches, @asset) %>
11 11  
12 12 <div id="category-childs">
13 13 <% if @category %>
... ...
app/views/search/people.html.erb 0 → 120000
... ... @@ -0,0 +1 @@
  1 +search_page.html.erb
0 2 \ No newline at end of file
... ...
app/views/search/people.rhtml
... ... @@ -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.html.erb 0 → 120000
... ... @@ -0,0 +1 @@
  1 +search_page.html.erb
0 2 \ No newline at end of file
... ...
app/views/search/products.rhtml
... ... @@ -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,17 @@
  1 +<%= search_page_title( @titles[@asset], @category ) %>
  2 +
  3 +<%= render :partial => 'search_form', :locals => { :hint => _("Type words about the %s you're looking for") % @asset.to_s.singularize } %>
  4 +<%= render :partial => 'results_header' %>
  5 +
  6 +<%= display_results(@searches, @asset) %>
  7 +<% if params[:display] != 'map' %>
  8 + <%= pagination_links @searches[@asset][:results] %>
  9 +<% end %>
  10 +
  11 +<div style="clear: both"></div>
  12 +
  13 +<% if @asset == :product %>
  14 + <% javascript_tag do %>
  15 + jQuery('.search-product-price-details').altBeautify();
  16 + <% end %>
  17 +<% end %>
... ...
app/views/search/tag.rhtml
... ... @@ -7,7 +7,7 @@
7 7 <% end %>
8 8  
9 9 <% cache_timeout(@tag_cache_key, 4.hour) do %>
10   - <%= display_results %>
  10 + <%= display_results @searches %>
11 11  
12 12 <div style="clear: both"></div>
13 13 <% end %>
... ...
app/views/tasks/_task.rhtml
... ... @@ -50,13 +50,13 @@
50 50 <% fields_for "tasks[#{task.id}][task]", task do |f| %>
51 51 <% if task.accept_details %>
52 52 <div id="on-accept-information-<%=task.id%>" style="display: none">
53   - <%= render :partial => partial_for_class(task.class, :accept_details), :locals => {:task => task, :f => f} %>
  53 + <%= render :partial => partial_for_class(task.class, nil, :accept_details), :locals => {:task => task, :f => f} %>
54 54 </div>
55 55 <% end %>
56 56  
57 57 <% if task.reject_details %>
58 58 <div id="on-reject-information-<%=task.id%>" style="display: none">
59   - <%= render :partial => partial_for_class(task.class, :reject_details), :locals => {:task => task, :f => f} %>
  59 + <%= render :partial => partial_for_class(task.class, nil, :reject_details), :locals => {:task => task, :f => f} %>
60 60 </div>
61 61 <% end %>
62 62 <% end %>
... ...
config/initializers/dependencies.rb
1 1 # locally-developed modules
2   -require 'acts_as_faceted'
3 2 require 'acts_as_filesystem'
4 3 require 'acts_as_having_settings'
5   -require 'acts_as_searchable'
6 4 require 'acts_as_having_boxes'
7 5 require 'acts_as_having_image'
8 6 require 'acts_as_having_posts'
... ...
config/solr.yml.dist
... ... @@ -1,25 +0,0 @@
1   -# Config file for the acts_as_solr plugin.
2   -#
3   -# If you change the host or port number here, make sure you update
4   -# them in your Solr config file
5   -
6   -# No change is needed to support multitenancy. Only one solr environment will be used.
7   -# Just remember to use 'rake multitenancy:reindex' for reindexation.
8   -
9   -production:
10   - url: http://127.0.0.1:8983/solr
11   - jvm_options: -server -Xmx192M -Xms64M
12   - timeout: 0
13   -
14   -development:
15   - url: http://0.0.0.0:8982/solr
16   - jvm_options: -server -Xmx128M -Xms16M
17   - timeout: 0
18   -
19   -test: &TEST
20   - url: http://0.0.0.0:8981/solr
21   - jvm_options: -server -Xmx128M -Xms16M
22   - timeout: 0
23   -
24   -cucumber:
25   - <<: *TEST
debian/noosfero.install
... ... @@ -28,7 +28,6 @@ public usr/share/noosfero
28 28  
29 29 debian/default/noosfero etc/default
30 30 etc/init.d/noosfero etc/init.d
31   -debian/solr.yml etc/noosfero
32 31 debian/thin.yml etc/noosfero
33 32 etc/logrotate.d/noosfero etc/logrotate.d
34 33 debian/noosfero.yml etc/noosfero
... ...
debian/noosfero.links
... ... @@ -2,7 +2,6 @@ usr/share/rails-ruby1.8 usr/share/noosfero/vendor/ra
2 2 var/tmp/noosfero usr/share/noosfero/tmp
3 3 var/log/noosfero usr/share/noosfero/log
4 4 etc/noosfero/database.yml usr/share/noosfero/config/database.yml
5   -etc/noosfero/solr.yml usr/share/noosfero/config/solr.yml
6 5 etc/noosfero/thin.yml usr/share/noosfero/config/thin.yml
7 6 etc/noosfero/plugins usr/share/noosfero/config/plugins
8 7 etc/noosfero/noosfero.yml usr/share/noosfero/config/noosfero.yml
... ...
debian/solr.yml
... ... @@ -1,22 +0,0 @@
1   -# Config file for the acts_as_solr plugin.
2   -#
3   -# If you change the host or port number here, make sure you update
4   -# them in your Solr config file
5   -
6   -development:
7   - url: http://0.0.0.0:8982/solr
8   - jvm_options: -server -Xmx128M -Xms16M
9   - timeout: 0
10   -
11   -production:
12   - url: http://127.0.0.1:8983/solr
13   - jvm_options: -server -Xmx192M -Xms64M
14   - timeout: 0
15   -
16   -test: &TEST
17   - url: http://0.0.0.0:8981/solr
18   - jvm_options: -server -Xmx128M -Xms16M
19   - timeout: 0
20   -
21   -cucumber:
22   - <<: *TEST
etc/init.d/noosfero
... ... @@ -45,14 +45,13 @@ if [ -z &quot;$NOOSFERO_DIR&quot; ] || [ -z &quot;$NOOSFERO_USER&quot; ]; then
45 45 fi
46 46  
47 47 ######################
48   -SOLR_PID_FILE=$NOOSFERO_DIR/tmp/pids/solr.production.pid
49 48  
50 49 main_script() {
51 50 cd $NOOSFERO_DIR
52 51 if [ "$NOOSFERO_USER" != "$USER" ]; then
53   - su $NOOSFERO_USER -l -c "SOLR_DATA_PATH=/var/lib/noosfero-data/index ./script/production $1"
  52 + su $NOOSFERO_USER -l -c "./script/production $1"
54 53 else
55   - SOLR_DATA_PATH=/var/lib/noosfero-data/index ./script/production $1
  54 + ./script/production $1
56 55 fi
57 56 }
58 57  
... ... @@ -78,13 +77,6 @@ do_setup() {
78 77 chmod 750 /var/tmp/noosfero
79 78 fi
80 79  
81   - # Solr directory
82   - if [ ! -d /var/tmp/noosfero/solr ]; then
83   - mkdir -p /var/tmp/noosfero/solr
84   - chown $NOOSFERO_USER:root /var/tmp/noosfero/solr
85   - chmod 750 /var/tmp/noosfero/solr
86   - fi
87   -
88 80 # symlink the directories into Noosfero directory
89 81 if [ ! -e $NOOSFERO_DIR/tmp ]; then
90 82 ln -s /var/tmp/noosfero $NOOSFERO_DIR/tmp
... ... @@ -98,28 +90,21 @@ do_setup() {
98 90 }
99 91  
100 92 do_start() {
101   -
102   - # FIXME should not test for solr only
103   - if [ -e $SOLR_PID_FILE ]; then
104   - echo 'noosfero already running, cannot start.'
105   - exit 2
  93 + if ! running; then
  94 + do_setup
  95 + # actually start the service
  96 + main_script start
  97 + else
  98 + echo 'Noosfero is already running, nothing to do...'
106 99 fi
107   -
108   - do_setup
109   -
110   - # actually start the service
111   - main_script start
112 100 }
113 101  
114 102 do_stop() {
115   -
116   - # FIXME should not test for solr only
117   - if [ ! -e $SOLR_PID_FILE ]; then
118   - echo 'noosfero not running, cannot stop'
119   - exit 2
  103 + if running; then
  104 + main_script stop
  105 + else
  106 + echo 'Noosfero is already stopped, nothing to do...'
120 107 fi
121   -
122   - main_script stop
123 108 }
124 109  
125 110 do_restart() {
... ... @@ -127,6 +112,10 @@ do_restart() {
127 112 do_start
128 113 }
129 114  
  115 +running(){
  116 + pgrep -u noosfero -f server > /dev/null
  117 +}
  118 +
130 119 case "$1" in
131 120 start|stop|restart|setup)
132 121 do_$1
... ...
features/support/env.rb
... ... @@ -5,8 +5,6 @@
5 5 # files.
6 6  
7 7 ENV["RAILS_ENV"] ||= "cucumber"
8   -abort unless system 'rake -s solr:start'
9   -at_exit { system 'rake -s solr:stop' }
10 8  
11 9 require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
12 10  
... ...
gitignore.example
... ... @@ -8,7 +8,6 @@ config/database.yml
8 8 config/session.secret
9 9 config/noosfero.yml
10 10 config/mongrel_cluster.yml
11   -config/solr.yml
12 11 config/plugins
13 12 config/thin.yml
14 13 config/local.rb
... ... @@ -32,7 +31,6 @@ doc/noosfero/*.xhtml
32 31 doc/noosfero/*/*.xhtml
33 32 tags
34 33 pkg
35   -solr
36 34 *~
37 35 *.swp
38 36 debian/*.log
... ...
lib/acts_as_faceted.rb
... ... @@ -1,222 +0,0 @@
1   -module ActsAsFaceted
2   -
3   - module ClassMethods
4   - end
5   -
6   - module ActsMethods
7   - # Example:
8   - #
9   - #acts_as_faceted :fields => {
10   - # :f_type => {:label => _('Type'), :proc => proc{|klass| f_type_proc(klass)}},
11   - # :f_published_at => {:type => :date, :label => _('Published date'), :queries => {'[* TO NOW-1YEARS/DAY]' => _("Older than one year"),
12   - # '[NOW-1YEARS TO NOW/DAY]' => _("Last year"), '[NOW-1MONTHS TO NOW/DAY]' => _("Last month"), '[NOW-7DAYS TO NOW/DAY]' => _("Last week"), '[NOW-1DAYS TO NOW/DAY]' => _("Last day")}},
13   - # :f_profile_type => {:label => _('Author'), :proc => proc{|klass| f_profile_type_proc(klass)}},
14   - # :f_category => {:label => _('Categories')}},
15   - # :order => [:f_type, :f_published_at, :f_profile_type, :f_category]
16   - #
17   - #acts_as_searchable :additional_fields => [ {:name => {:type => :string, :as => :name_sort, :boost => 5.0}} ] + facets_fields_for_solr,
18   - # :exclude_fields => [:setting],
19   - # :include => [:profile],
20   - # :facets => facets_option_for_solr,
21   - # :if => proc{|a| ! ['RssFeed'].include?(a.class.name)}
22   - def acts_as_faceted(options)
23   - extend ClassMethods
24   - extend ActsAsSolr::CommonMethods
25   -
26   - cattr_accessor :facets
27   - cattr_accessor :facets_order
28   - cattr_accessor :to_solr_fields_names
29   - cattr_accessor :facets_results_containers
30   - cattr_accessor :solr_fields_names
31   - cattr_accessor :facets_option_for_solr
32   - cattr_accessor :facets_fields_for_solr
33   - cattr_accessor :facet_category_query
34   -
35   - self.facets = options[:fields]
36   - self.facets_order = options[:order] || self.facets.keys
37   - self.facets_results_containers = {:fields => 'facet_fields', :queries => 'facet_queries', :ranges => 'facet_ranges'}
38   - self.facets_option_for_solr = Hash[facets.select{ |id,data| ! data.has_key?(:queries) }].keys
39   - self.facets_fields_for_solr = facets.map{ |id,data| {id => data[:type] || :facet} }
40   - self.solr_fields_names = facets.map{ |id,data| id.to_s + '_' + get_solr_field_type(data[:type] || :facet) }
41   - self.facet_category_query = options[:category_query]
42   -
43   - # A hash to retrieve the field key for the solr facet string returned
44   - # :field_name => "field_name_facet"
45   - self.to_solr_fields_names = Hash[facets.keys.zip(solr_fields_names)]
46   -
47   - def facet_by_id(id)
48   - {:id => id}.merge(facets[id]) if facets[id]
49   - end
50   -
51   - def map_facets_for(environment)
52   - facets_order.map do |id|
53   - facet = facet_by_id(id)
54   - next if facet[:type_if] and !facet[:type_if].call(self.new)
55   -
56   - if facet[:multi]
57   - facet[:label].call(environment).map do |label_id, label|
58   - facet.merge({:id => facet[:id].to_s+'_'+label_id.to_s, :solr_field => facet[:id], :label_id => label_id, :label => label})
59   - end
60   - else
61   - facet.merge(:id => facet[:id].to_s, :solr_field => facet[:id])
62   - end
63   - end.compact.flatten
64   - end
65   -
66   - def map_facet_results(facet, facet_params, facets_data, unfiltered_facets_data = {}, options = {})
67   - raise 'Use map_facets_for before this method' if facet[:solr_field].nil?
68   - facets_data = {} if facets_data.blank? # could be empty array
69   - solr_facet = to_solr_fields_names[facet[:solr_field]]
70   - unfiltered_facets_data ||= {}
71   -
72   - if facet[:queries]
73   - container = facets_data[facets_results_containers[:queries]]
74   - facet_data = (container.nil? or container.empty?) ? [] : container.select{ |k,v| k.starts_with? solr_facet }
75   - container = unfiltered_facets_data[facets_results_containers[:queries]]
76   - unfiltered_facet_data = (container.nil? or container.empty?) ? [] : container.select{ |k,v| k.starts_with? solr_facet }
77   - else
78   - container = facets_data[facets_results_containers[:fields]]
79   - facet_data = (container.nil? or container.empty?) ? [] : container[solr_facet] || []
80   - container = unfiltered_facets_data[facets_results_containers[:fields]]
81   - unfiltered_facet_data = (container.nil? or container.empty?) ? [] : container[solr_facet] || []
82   - end
83   -
84   - if !unfiltered_facets_data.blank? and !facet_params.blank?
85   - f = Hash[Array(facet_data)]
86   - zeros = []
87   - facet_data = unfiltered_facet_data.map do |id, count|
88   - count = f[id]
89   - if count.nil?
90   - zeros.push [id, 0]
91   - nil
92   - else
93   - [id, count]
94   - end
95   - end.compact + zeros
96   - end
97   -
98   - facet_count = facet_data.length
99   -
100   - if facet[:queries]
101   - result = facet_data.map do |id, count|
102   - q = id[id.index(':')+1,id.length]
103   - label = facet_result_name(facet, q)
104   - [q, label, count] if count > 0
105   - end.compact
106   - result = facet[:queries_order].map{ |id| result.detect{ |rid, label, count| rid == id } }.compact if facet[:queries_order]
107   - elsif facet[:proc]
108   - if facet[:label_id]
109   - result = facet_data.map do |id, count|
110   - name = facet_result_name(facet, id)
111   - [id, name, count] if name
112   - end.compact
113   - # FIXME limit is NOT improving performance in this case :(
114   - facet_count = result.length
115   - result = result.first(options[:limit]) if options[:limit]
116   - else
117   - facet_data = facet_data.first(options[:limit]) if options[:limit]
118   - result = facet_data.map { |id, count| [id, facet_result_name(facet, id), count] }
119   - end
120   - else
121   - facet_data = facet_data.first(options[:limit]) if options[:limit]
122   - result = facet_data.map { |id, count| [id, facet_result_name(facet, id), count] }
123   - end
124   -
125   - sorted = facet_result_sort(facet, result, options[:sort])
126   -
127   - # length can't be used if limit option is given;
128   - # total_entries comes to help
129   - sorted.class.send(:define_method, :total_entries, proc { facet_count })
130   -
131   - sorted
132   - end
133   -
134   - def facet_result_sort(facet, facets_data, sort_by = nil)
135   - if facet[:queries_order]
136   - facets_data
137   - elsif sort_by == :alphabetically
138   - facets_data.sort{ |a,b| Array(a[1])[0] <=> Array(b[1])[0] }
139   - elsif sort_by == :count
140   - facets_data.sort{ |a,b| -1*(a[2] <=> b[2]) }
141   - else
142   - facets_data
143   - end
144   - end
145   -
146   - def facet_result_name(facet, data)
147   - if facet[:queries]
148   - gettext(facet[:queries][data])
149   - elsif facet[:proc]
150   - if facet[:multi]
151   - facet[:label_id] ||= 0
152   - facet[:proc].call(facet, data)
153   - else
154   - gettext(facet[:proc].call(data))
155   - end
156   - else
157   - data
158   - end
159   - end
160   -
161   - def facet_label(facet)
162   - return nil unless facet
163   - _(facet[:label])
164   - end
165   -
166   - def facets_find_options(facets_selected = {}, options = {})
167   - browses = []
168   - facets_selected ||= {}
169   - facets_selected.map do |id, value|
170   - next unless facets[id.to_sym]
171   - if value.kind_of?(Hash)
172   - value.map do |label_id, value|
173   - value.to_a.each do |value|
174   - browses << id.to_s + ':' + (facets[id.to_sym][:queries] ? value : '"'+value.to_s+'"')
175   - end
176   - end
177   - else
178   - browses << id.to_s + ':' + (facets[id.to_sym][:queries] ? value : '"'+value.to_s+'"')
179   - end
180   - end.flatten
181   -
182   - {:facets => {:zeros => false, :sort => :count,
183   - :fields => facets_option_for_solr,
184   - :browse => browses,
185   - :query => facets.map { |f, options| options[:queries].keys.map { |q| f.to_s + ':' + q } if options[:queries] }.compact.flatten,
186   - }
187   - }
188   - end
189   - end
190   - end
191   -
192   -end
193   -
194   -ActiveRecord::Base.extend ActsAsFaceted::ActsMethods
195   -
196   -# from https://github.com/rubyworks/facets/blob/master/lib/core/facets/enumerable/graph.rb
197   -module Enumerable
198   - def graph(&yld)
199   - if yld
200   - h = {}
201   - each do |*kv|
202   - r = yld[*kv]
203   - case r
204   - when Hash
205   - nk, nv = *r.to_a[0]
206   - when Range
207   - nk, nv = r.first, r.last
208   - else
209   - nk, nv = *r
210   - end
211   - h[nk] = nv
212   - end
213   - h
214   - else
215   - Enumerator.new(self,:graph)
216   - end
217   - end
218   -
219   - # Alias for #graph, which stands for "map hash".
220   - alias_method :mash, :graph
221   -end
222   -
lib/acts_as_searchable.rb
... ... @@ -1,87 +0,0 @@
1   -module ActsAsSearchable
2   -
3   - module ClassMethods
4   - ACTS_AS_SEARCHABLE_ENABLED = true unless defined? ACTS_AS_SEARCHABLE_ENABLED
5   -
6   - def acts_as_searchable(options = {})
7   - return if !ACTS_AS_SEARCHABLE_ENABLED
8   -
9   - if options[:fields]
10   - options[:fields] << {:schema_name => :string}
11   - else
12   - options[:additional_fields] ||= []
13   - options[:additional_fields] << {:schema_name => :string}
14   - end
15   -
16   - acts_as_solr options
17   - extend FindByContents
18   - send :include, InstanceMethods
19   - end
20   -
21   - module InstanceMethods
22   - def schema_name
23   - self.class.schema_name
24   - end
25   -
26   - # replace solr_id from vendor/plugins/acts_as_solr_reloaded/lib/acts_as_solr/instance_methods.rb
27   - # to include schema_name
28   - def solr_id
29   - id = "#{self.class.name}:#{record_id(self)}"
30   - id.insert(0, "#{schema_name}:") unless schema_name.blank?
31   - id
32   - end
33   - end
34   -
35   - module FindByContents
36   -
37   - def schema_name
38   - (Noosfero::MultiTenancy.on? and ActiveRecord::Base.postgresql?) ? ActiveRecord::Base.connection.schema_search_path : ''
39   - end
40   -
41   - def find_by_contents(query, pg_options = {}, options = {}, db_options = {})
42   - pg_options[:page] ||= 1
43   - pg_options[:per_page] ||= 20
44   - options[:page] = pg_options[:page].to_i
45   - options[:per_page] = pg_options[:per_page].to_i
46   - options[:scores] ||= true
47   - options[:filter_queries] ||= []
48   - options[:filter_queries] << "schema_name:\"#{schema_name}\"" unless schema_name.blank?
49   - all_facets_enabled = options.delete(:all_facets)
50   - options[:per_page] = options.delete(:extra_limit) if options[:extra_limit]
51   - results = []
52   - facets = all_facets = {}
53   -
54   - solr_result = find_by_solr(query, options)
55   - if all_facets_enabled
56   - options[:facets][:browse] = nil
57   - all_facets = find_by_solr(query, options.merge(:per_page => 0)).facets
58   - end
59   -
60   - if !solr_result.nil?
61   - facets = options.include?(:facets) ? solr_result.facets : []
62   -
63   - if db_options.empty?
64   - results = solr_result
65   - else
66   - ids = solr_result.results.map{ |r| r[:id].to_i }
67   - if ids.empty?
68   - ids << -1
69   - end
70   -
71   - if db_options[:conditions]
72   - db_options[:conditions] = sanitize_sql_for_conditions(db_options[:conditions]) + " and #{table_name}.id in (#{ids.join(', ')})"
73   - else
74   - db_options[:conditions] = "#{table_name}.id in (#{ids.join(', ')})"
75   - end
76   -
77   - results = find(:all, db_options)
78   - end
79   - end
80   -
81   - {:results => results, :facets => facets, :all_facets => all_facets}
82   - end
83   - end
84   - end
85   -end
86   -
87   -ActiveRecord::Base.send(:extend, ActsAsSearchable::ClassMethods)
lib/noosfero/core_ext/active_record.rb
... ... @@ -13,4 +13,17 @@ class ActiveRecord::Base
13 13 key.join('/')
14 14 end
15 15  
  16 + def self.like_search(query)
  17 + if defined?(self::SEARCHABLE_FIELDS)
  18 + fields = self::SEARCHABLE_FIELDS.keys.map(&:to_s) & column_names
  19 + query = query.downcase.strip
  20 + conditions = fields.map do |field|
  21 + "lower(#{table_name}.#{field}) LIKE '%#{query}%'"
  22 + end.join(' OR ')
  23 + where(conditions)
  24 + else
  25 + raise "No searchable fields defined for #{self.name}"
  26 + end
  27 + end
  28 +
16 29 end
... ...
lib/noosfero/plugin.rb
... ... @@ -16,38 +16,52 @@ class Noosfero::Plugin
16 16 if Rails.env.test? && !enabled_plugins.include?(File.join(Rails.root, 'config', 'plugins', 'foo'))
17 17 enabled_plugins << File.join(Rails.root, 'plugins', 'foo')
18 18 end
  19 +
19 20 enabled_plugins.select do |entry|
20 21 File.directory?(entry)
21 22 end.each do |dir|
22   - plugin_name = File.basename(dir)
23   -
24   - plugin_dependencies_ok = true
25   - plugin_dependencies_file = File.join(dir, 'dependencies.rb')
26   - if File.exists?(plugin_dependencies_file)
27   - begin
28   - require plugin_dependencies_file
29   - rescue LoadError => ex
30   - plugin_dependencies_ok = false
31   - $stderr.puts "W: Noosfero plugin #{plugin_name} failed to load (#{ex})"
32   - end
33   - end
  23 + load_plugin dir
  24 + end
  25 + end
34 26  
35   - if plugin_dependencies_ok
36   - Rails.configuration.controller_paths << File.join(dir, 'controllers')
37   - ActiveSupport::Dependencies.load_paths << File.join(dir, 'controllers')
38   - controllers_folders = %w[public profile myprofile admin]
39   - controllers_folders.each do |folder|
40   - Rails.configuration.controller_paths << File.join(dir, 'controllers', folder)
41   - ActiveSupport::Dependencies.load_paths << File.join(dir, 'controllers', folder)
42   - end
43   - [ ActiveSupport::Dependencies.load_paths, $:].each do |path|
44   - path << File.join(dir, 'models')
45   - path << File.join(dir, 'lib')
46   - end
47   -
48   - klass(plugin_name)
  27 + def load_plugin dir
  28 + plugin_name = File.basename(dir)
  29 +
  30 + plugin_dependencies_ok = true
  31 + plugin_dependencies_file = File.join(dir, 'dependencies.rb')
  32 + if File.exists?(plugin_dependencies_file)
  33 + begin
  34 + require plugin_dependencies_file
  35 + rescue LoadError => ex
  36 + plugin_dependencies_ok = false
  37 + $stderr.puts "W: Noosfero plugin #{plugin_name} failed to load (#{ex})"
49 38 end
50 39 end
  40 +
  41 + return unless plugin_dependencies_ok
  42 +
  43 + # add load paths
  44 + Rails.configuration.controller_paths << File.join(dir, 'controllers')
  45 + ActiveSupport::Dependencies.load_paths << File.join(dir, 'controllers')
  46 + controllers_folders = %w[public profile myprofile admin]
  47 + controllers_folders.each do |folder|
  48 + Rails.configuration.controller_paths << File.join(dir, 'controllers', folder)
  49 + ActiveSupport::Dependencies.load_paths << File.join(dir, 'controllers', folder)
  50 + end
  51 + [ ActiveSupport::Dependencies.load_paths, $:].each do |path|
  52 + path << File.join(dir, 'models')
  53 + path << File.join(dir, 'lib')
  54 + end
  55 +
  56 + # load vendor/plugins
  57 + Dir.glob(File.join(dir, '/vendor/plugins/*')).each do |vendor_plugin|
  58 + [ ActiveSupport::Dependencies.load_paths, $:].each{ |path| path << "#{vendor_plugin}/lib" }
  59 + init = "#{vendor_plugin}/init.rb"
  60 + require init.gsub(/.rb$/, '') if File.file? init
  61 + end
  62 +
  63 + # load class
  64 + klass(plugin_name)
51 65 end
52 66  
53 67 def all
... ... @@ -380,6 +394,13 @@ class Noosfero::Plugin
380 394 nil
381 395 end
382 396  
  397 + # -> Finds objects by their contents
  398 + # returns = {:results => [a, b, c, ...], ...}
  399 + # P.S.: The plugin might add other informations on the return hash for its
  400 + # own use in specific views
  401 + def find_by_contents(asset, scope, query, paginate_options={}, options={})
  402 + end
  403 +
383 404 # -> Adds additional blocks to profiles and environments.
384 405 # Your plugin must implements a class method called 'extra_blocks'
385 406 # that returns a hash with the following syntax.
... ...
lib/noosfero/plugin/manager.rb
... ... @@ -23,12 +23,36 @@ class Noosfero::Plugin::Manager
23 23 dispatch_without_flatten(event, *args).flatten
24 24 end
25 25  
  26 + def dispatch_plugins(event, *args)
  27 + map { |plugin| plugin.class if plugin.send(event, *args) }.compact.flatten
  28 + end
  29 +
26 30 def dispatch_without_flatten(event, *args)
27 31 map { |plugin| plugin.send(event, *args) }.compact
28 32 end
29 33  
30 34 alias :dispatch_scopes :dispatch_without_flatten
31 35  
  36 + def first(event, *args)
  37 + result = nil
  38 + each do |plugin|
  39 + result = plugin.send(event, *args)
  40 + break if result.present?
  41 + end
  42 + result
  43 + end
  44 +
  45 + def first_plugin(event, *args)
  46 + result = nil
  47 + each do |plugin|
  48 + if plugin.send(event, *args)
  49 + result = plugin.class
  50 + break
  51 + end
  52 + end
  53 + result
  54 + end
  55 +
32 56 def enabled_plugins
33 57 @enabled_plugins ||= (Noosfero::Plugin.all & environment.enabled_plugins).map do |plugin|
34 58 p = plugin.constantize.new
... ...
lib/set_profile_region_from_city_state.rb
... ... @@ -11,6 +11,7 @@ module SetProfileRegionFromCityState
11 11 end
12 12  
13 13 module InstanceMethods
  14 + include Noosfero::Plugin::HotSpot
14 15  
15 16 def city_with_region=(value)
16 17 self.city_without_region = value
... ... @@ -24,16 +25,20 @@ module SetProfileRegionFromCityState
24 25  
25 26 def region_from_city_and_state
26 27 if @change_region
27   - s = State.find_by_contents(self.state)[:results].first
28   - if s
29   - c = City.find_by_contents(self.city, {}, :filter_queries => ["parent_id:#{s.id}"])[:results].first
30   - self.region = c
31   - else
32   - self.region = nil
33   - end
  28 + self.region = nil
  29 + state = search_region(State, self.state)
  30 + self.region = search_region(City.where(:parent_id => state.id), self.city) if state
34 31 end
35 32 end
36 33  
  34 + private
  35 +
  36 + def search_region(scope, query)
  37 + return nil if !query
  38 + query = query.downcase.strip
  39 + scope.where(['lower(name)=? OR lower(abbreviation)=? OR lower(acronym)=?', query, query, query]).first
  40 + end
  41 +
37 42 end
38 43  
39 44 end
... ...
lib/tasks/multitenancy.rake
... ... @@ -14,22 +14,6 @@ namespace :multitenancy do
14 14 (file_envs - db_envs.map{ |e| e + '.rb' }).each { |env| safe_unlink env }
15 15 end
16 16  
17   - task :reindex => :environment do
18   - # enable output from rebuild_index
19   - logger = ActiveRecord::Base.logger = Logger.new(STDOUT)
20   - logger.level = ActiveSupport::BufferedLogger::INFO
21   -
22   - db_envs = ActiveRecord::Base.configurations.keys.select{ |k| k.match(/_#{RAILS_ENV}$/) }
23   - db_envs.each do |e|
24   - puts "Rebuilding index for environment #{e}"
25   - ActiveRecord::Base.connection.schema_search_path = ActiveRecord::Base.configurations[e]['schema_search_path']
26   - $solr_indexed_models.each do |m|
27   - puts "Rebuilding index for model #{m}"
28   - m.rebuild_index
29   - end
30   - end
31   - end
32   -
33 17 end
34 18  
35 19 namespace :db do
... ...
lib/tasks/release.rake
1 1 namespace :noosfero do
2 2  
  3 + def pendencies_on_authors
  4 + sh "git status | grep 'AUTHORS'" do |ok, res|
  5 + return {:ok => ok, :res => res}
  6 + end
  7 + end
  8 +
  9 + def pendencies_on_repo
  10 + sh "git status | grep 'nothing.*commit'" do |ok, res|
  11 + return {:ok => ok, :res => res}
  12 + end
  13 + end
  14 +
3 15 desc 'checks if there are uncommitted changes in the repo'
4 16 task :check_repo do
5   - sh "git status | grep 'nothing.*commit'" do |ok, res|
6   - if !ok
7   - raise "******** There are uncommited changes in the repository, cannot continue"
8   - end
  17 + if !pendencies_on_repo[:ok]
  18 + raise "******** There are uncommited changes in the repository, cannot continue"
9 19 end
10 20 end
11 21  
... ... @@ -85,6 +95,80 @@ EOF
85 95 rm_f 'AUTHORS'
86 96 raise e
87 97 end
  98 + if pendencies_on_authors[:res]
  99 + puts 'The AUTHORS file was updated!'
  100 + sh 'git diff AUTHORS'
  101 + if confirm('Do you want to commit this changes to the author file')
  102 + default_message = 'Updating AUTHORS file'
  103 + message = ask("Commit message [#{default_message}]:")
  104 + message = message.present? ? message : default_message
  105 + sh 'git add AUTHORS'
  106 + sh "git commit -m '#{message}'"
  107 + end
  108 + end
  109 + end
  110 +
  111 + def ask(message)
  112 + print message
  113 + STDIN.gets.chomp
  114 + end
  115 +
  116 + def confirm(message, default=true)
  117 + choice_message = default ? ' [Y/n]? ' : ' [y/N]? '
  118 + choice = nil
  119 + while choice.nil?
  120 + answer = ask(message + choice_message)
  121 + if answer.blank?
  122 + choice = default
  123 + elsif ['y', 'yes'].include?(answer.downcase)
  124 + choice = true
  125 + elsif ['n', 'no'].include?(answer.downcase)
  126 + choice = false
  127 + end
  128 + end
  129 + choice
  130 + end
  131 +
  132 + desc 'sets the new version on apropriate files'
  133 + task :set_version, :release_kind do |t, args|
  134 + next if File.exist?("tmp/pending-release")
  135 + release_kind = args[:release_kind] || 'stable'
  136 +
  137 + if release_kind == 'test'
  138 + version_question = "Release candidate of which version: "
  139 + distribution = 'squeeze-test'
  140 + else
  141 + version_question = "Version that is being released: "
  142 + distribution = 'unstable'
  143 + end
  144 +
  145 + version_name = new_version = ask(version_question)
  146 +
  147 + if release_kind == 'test'
  148 + timestamp = Time.now.strftime('%Y%m%d%H%M%S')
  149 + version_name += "~rc#{timestamp}"
  150 + end
  151 + release_message = ask("Release message: ")
  152 +
  153 + sh 'git checkout debian/changelog lib/noosfero.rb'
  154 + sh "sed -i \"s/VERSION = '[^']*'/VERSION = '#{version_name}'/\" lib/noosfero.rb"
  155 + sh "dch --newversion #{version_name} --distribution #{distribution} --force-distribution '#{release_message}'"
  156 +
  157 + puts
  158 + if confirm("Commit version bump to #{version_name} on #{distribution} distribution")
  159 + sh 'git add debian/changelog lib/noosfero.rb'
  160 + sh "git commit -m 'Bumping version #{version_name}'"
  161 + sh "touch tmp/pending-release"
  162 + else
  163 + sh 'git checkout debian/changelog lib/noosfero.rb'
  164 + abort 'Version update not confirmed. Reverting changes and exiting...'
  165 + end
  166 + end
  167 +
  168 + desc "uploads the packages to the repository"
  169 + task :upload_packages, :release_kind do |t, args|
  170 + release_kind = args[:release_kind] || 'stable'
  171 + sh "dput --unchecked #{release_kind} #{Dir['pkg/*.changes'].first}"
88 172 end
89 173  
90 174 def ask(message)
... ... @@ -179,8 +263,6 @@ EOF
179 263 mkdir "#{target}/tmp"
180 264 ln_s '../../../vendor/rails', "#{target}/vendor/rails"
181 265 cp "#{target}/config/database.yml.sqlite3", "#{target}/config/database.yml"
182   - # solr inclusion
183   - Dir.chdir(target) { sh "rake solr:download" }
184 266  
185 267 sh "cd #{target} && dpkg-buildpackage -us -uc -b"
186 268 end
... ...
plugins/mezuro/script/install/install-rvm.sh
... ... @@ -100,7 +100,6 @@ cd mezuro
100 100 git checkout mezuro-dev
101 101 rvm use ruby-1.8.7-p302@mezuro
102 102 cp config/database.yml.sqlite3 config/database.yml
103   -cp config/solr.yml.dist config/solr.yml
104 103 cp plugins/mezuro/service.yml.example plugins/mezuro/service.yml
105 104 cp plugins/mezuro/licenses.yml.example plugins/mezuro/licenses.yml
106 105 mkdir tmp
... ... @@ -116,5 +115,4 @@ ln -s mezuro-theme/ default
116 115 cd ../../../
117 116  
118 117 #Prepare Mezuro for running functional and unit tests
119   -rake solr:download
120   -rake db:test:prepare
121 118 \ No newline at end of file
  119 +rake db:test:prepare
... ...
plugins/mezuro/test/functional/myprofile/mezuro_plugin_metric_configuration_controller_test.rb
... ... @@ -23,7 +23,6 @@ class MezuroPluginMetricConfigurationControllerTest &lt; ActionController::TestCase
23 23 @configuration_content = MezuroPlugin::ConfigurationContent.new(:profile => @profile, :name => @configuration.name, :configuration_id => 42)
24 24 @configuration_content.expects(:send_configuration_to_service).returns(nil)
25 25 @configuration_content.expects(:validate_configuration_name).returns(true)
26   - @configuration_content.stubs(:solr_save)
27 26 @configuration_content.save
28 27  
29 28 @base_tool = BaseToolFixtures.base_tool
... ...
plugins/mezuro/test/functional/myprofile/mezuro_plugin_range_controller_test.rb
... ... @@ -21,7 +21,6 @@ class MezuroPluginRangeControllerTest &lt; ActionController::TestCase
21 21 @content = MezuroPlugin::ConfigurationContent.new(:profile => @profile, :name => @configuration.name, :configuration_id => 42)
22 22 @content.expects(:send_configuration_to_service).returns(nil)
23 23 @content.expects(:validate_configuration_name).returns(true)
24   - @content.stubs(:solr_save)
25 24 @content.save
26 25  
27 26 @created_range = RangeFixtures.created_range
... ...
plugins/mezuro/test/functional/myprofile/mezuro_plugin_reading_controller_test.rb
... ... @@ -16,7 +16,6 @@ class MezuroPluginReadingControllerTest &lt; ActionController::TestCase
16 16 @reading_hash = ReadingFixtures.hash
17 17 @content = MezuroPlugin::ReadingGroupContent.new(:profile => @profile, :name => name)
18 18 @content.expects(:send_reading_group_to_service).returns(nil)
19   - @content.stubs(:solr_save)
20 19 @content.save
21 20 end
22 21  
... ...
plugins/mezuro/test/functional/profile/mezuro_plugin_repository_controller_test.rb
... ... @@ -21,7 +21,6 @@ class MezuroPluginRepositoryControllerTest &lt; ActionController::TestCase
21 21 @repository_hash = RepositoryFixtures.hash
22 22 @content = MezuroPlugin::ProjectContent.new(:profile => @profile, :name => name)
23 23 @content.expects(:send_project_to_service).returns(nil)
24   - @content.stubs(:solr_save)
25 24 @content.save
26 25 end
27 26  
... ...
plugins/mezuro/test/unit/mezuro_plugin/configuration_content_test.rb
... ... @@ -48,7 +48,6 @@ class ConfigurationContentTest &lt; ActiveSupport::TestCase
48 48  
49 49 should 'send configuration to service after saving' do
50 50 @content.expects :send_configuration_to_service
51   - @content.stubs(:solr_save)
52 51 @content.run_callbacks :before_save
53 52 end
54 53  
... ...