search_controller.rb
7.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
class SearchController < ApplicationController
helper TagsHelper
before_filter :load_category
before_filter :prepare_filter
before_filter :check_search_whole_site
before_filter :load_search_assets
before_filter :check_valid_assets, :only => [ :assets, :directory ]
no_design_blocks
protected
def load_search_assets
@search_in = SEARCH_IN
@searching = {}
@search_in.each do |key, name|
@searching[key] = (params[:asset].blank? && (params[:find_in].nil? || params[:find_in].empty? || params[:find_in].include?(key.to_s))) || (params[:asset] == key.to_s)
end
end
def prepare_filter
if @category
@finder = CategoryFinder.new(@category)
else
@finder = EnvironmentFinder.new(@environment)
end
end
def check_search_whole_site
if params[:search_whole_site_yes] or params[:search_whole_site] == 'yes'
redirect_to params.merge(:category_path => [], :search_whole_site => nil, :search_whole_site_yes => nil)
end
end
def check_valid_assets
@asset = params[:asset].to_sym
if !SEARCH_IN.map(&:first).include?(@asset)
render :text => 'go away', :status => 403
return
end
end
def events
@events = @results[:events]
@calendar = Event.date_range(params[:year], params[:month]).map do |date|
[
# the day itself
date,
# list of events of that day
@events.select do |event|
event.date_range.include?(date)
end,
# is this date in the current month?
true
]
end
# pad with days before
while @calendar.first.first.wday != 0
@calendar.unshift([@calendar.first.first - 1.day, [], false])
end
# pad with days after (until Saturday)
while @calendar.last.first.wday != 6
@calendar << [@calendar.last.first + 1.day, [], false]
end
end
def people
#nothing, just to enable
end
def enterprises
#nothing, just to enable
end
def communities
#nothing, just to enable
end
def articles
#nothins, just to enable
end
public
include SearchHelper
######################################################
SEARCH_IN = [
[ :articles, N_('Articles') ],
[ :enterprises, N_('Enterprises') ],
[ :people, N_('People') ],
[ :communities, N_('Communities') ],
[ :products, N_('Products') ],
[ :events, N_('Events') ]
]
# TODO don't hardcode like this >:-(
LIST_LIMIT = 10
def complete_region
# FIXME this logic should be in the model
@regions = Region.find(:all, :conditions => [ '(name like ? or name like ?) and lat is not null and lng is not null', '%' + params[:region][:name] + '%', '%' + params[:region][:name].capitalize + '%' ])
render :action => 'complete_region', :layout => false
end
def index
@query = params[:query] || ''
@filtered_query = remove_stop_words(@query)
@product_category = ProductCategory.find(params[:product_category]) if params[:product_category]
# FIXME name is not unique
@region = Region.find_by_name(params[:region][:name]) if params[:region]
# how many assets we are searching for?
number_of_result_assets = @searching.values.select{|v| v}.size
# apply limit when searching for only one type of asset
limit = (number_of_result_assets == 1) ? LIST_LIMIT : nil
@results = {}
@names = {}
SEARCH_IN.each do |key, description|
if @searching[key]
if [:enterprises, :people].include?(key) && @region
@results[key] = @finder.find(key, @filtered_query, :within => params[:radius], :region => @region.id, :product_category => @product_category, :limit => limit)
else
@results[key] = @finder.find(key, @filtered_query, :product_category => @product_category, :limit => limit)
end
end
@names[key] = gettext(description)
end
if @results.keys.size == 1
specific_action = @results.keys.first
if respond_to?(specific_action)
@asset_name = gettext(@names[@results.keys.first])
send(specific_action)
render :action => specific_action
return
end
end
render :action => 'index'
end
def products
@results[:products].uniq!
if !(@category || @product_category || @region || (!@query.blank?))
# not searching, no menu
return
end
@categories = @results[:products].map(&:product_category).compact
@counts = @categories.uniq.inject({}) do |h, cat|
h[cat.id] = [cat, 0]
h
end
@categories.each do |cat|
cat.hierarchy.each do |each_cat|
@counts[each_cat.id][1] += 1 if @counts[each_cat.id]
end
end
@found_product_categories = @counts.values.sort_by{|v|v[0].full_name}
end
alias :assets :index
#######################################################
# view the summary of one category
def category_index
@results = {}
@names = {}
[
[ :people, _('Recently registered people'), @finder.recent('people') ],
[ :communities, _('Recently created communities'), @finder.recent('communities') ],
[ :articles, _('Recent articles'), @finder.recent('articles') ],
[ :most_commented_articles, _('Most commented articles'), @finder.most_commented_articles ],
[ :enterprises, _('Recently created enterprises'), @finder.recent('enterprises') ],
[ :events, _('Recently added events'), @finder.current_events(params[:year], params[:month]) ]
].each do |key, name, list|
@results[key] = list
@names[key] = name
end
end
attr_reader :category
def directory
@results = { @asset => @finder.find_by_initial(@asset, params[:initial]) }
@asset_name = gettext(SEARCH_IN.find { |entry| entry.first == @asset }[1])
@names = { @asset => @asset_name }
render :action => @asset
end
def tags
@tags = Tag.find(:all).inject({}) do |memo,tag|
memo[tag.name] = tag.taggings.count
memo
end
end
def tag
@tag = Tag.find_by_name(params[:tag])
@tagged = @tag.taggings.map(&:taggable)
end
def sellers
# FIXME use a better select for category
@categories = ProductCategory.find(:all)
@regions = Region.find(:all).select{|r|r.lat && r.lng}
@product_category = ProductCategory.find(params[:category]) if params[:category]
@region = Region.find(params[:region]) if params[:region]
options = {}
options.merge! :origin => [params[:lat].to_f, params[:long].to_f], :within => params[:radius] if !params[:lat].blank? && !params[:long].blank? && !params[:radius].blank?
options.merge! :origin => [@region.lat, @region.lng], :within => params[:radius] if !params[:region].blank? && !params[:radius].blank?
if @product_category
finder = CategoryFinder.new(@product_category)
product_ids = finder.find('products',nil)
options.merge! :include => :products, :conditions => ['products.id IN ?', product_ids ]
end
@enterprises = Enterprise.find(:all, options)
end
#######################################################
def popup
@regions = Region.find(:all).select{|r|r.lat && r.lng}
render :action => 'popup', :layout => false
end
end