blacklight 5.11.3 → 5.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/app/helpers/blacklight/blacklight_helper_behavior.rb +2 -2
  4. data/app/helpers/blacklight/catalog_helper_behavior.rb +2 -4
  5. data/app/helpers/blacklight/facets_helper_behavior.rb +10 -6
  6. data/app/helpers/blacklight/url_helper_behavior.rb +1 -1
  7. data/app/views/bookmarks/_clear_bookmarks_widget.html.erb +1 -0
  8. data/app/views/bookmarks/index.html.erb +0 -1
  9. data/blacklight.gemspec +1 -1
  10. data/config/locales/blacklight.en.yml +1 -0
  11. data/lib/blacklight.rb +2 -1
  12. data/lib/blacklight/bookmarks.rb +2 -0
  13. data/lib/blacklight/catalog.rb +1 -1
  14. data/lib/blacklight/configuration.rb +8 -1
  15. data/lib/blacklight/configuration/fields.rb +20 -10
  16. data/lib/blacklight/document.rb +43 -13
  17. data/lib/blacklight/document_presenter.rb +8 -4
  18. data/lib/blacklight/facet.rb +6 -54
  19. data/lib/blacklight/request_builders.rb +2 -2
  20. data/lib/blacklight/search_builder.rb +48 -18
  21. data/lib/blacklight/search_helper.rb +10 -10
  22. data/lib/blacklight/solr.rb +1 -1
  23. data/lib/blacklight/solr/search_builder.rb +2 -265
  24. data/lib/blacklight/solr/search_builder_behavior.rb +274 -0
  25. data/lib/blacklight/solr_repository.rb +1 -1
  26. data/lib/blacklight/solr_response.rb +8 -16
  27. data/lib/blacklight/solr_response/facets.rb +133 -25
  28. data/lib/blacklight/solr_response/group_response.rb +1 -1
  29. data/lib/blacklight/solr_response/pagination_methods.rb +0 -17
  30. data/lib/generators/blacklight/install_generator.rb +6 -1
  31. data/lib/generators/blacklight/search_builder_generator.rb +20 -0
  32. data/lib/generators/blacklight/templates/search_builder.rb +3 -0
  33. data/lib/railties/blacklight.rake +1 -1
  34. data/spec/controllers/catalog_controller_spec.rb +9 -9
  35. data/spec/helpers/blacklight_helper_spec.rb +29 -179
  36. data/spec/helpers/facets_helper_spec.rb +37 -75
  37. data/spec/helpers/url_helper_spec.rb +1 -1
  38. data/spec/lib/blacklight/configuration_spec.rb +18 -1
  39. data/spec/lib/blacklight/document_spec.rb +62 -0
  40. data/spec/lib/blacklight/search_builder_spec.rb +15 -13
  41. data/spec/lib/blacklight/search_helper_spec.rb +15 -16
  42. data/spec/lib/blacklight/solr/document_spec.rb +5 -3
  43. data/spec/lib/blacklight/solr/search_builder_spec.rb +0 -5
  44. data/spec/lib/blacklight/solr_response/facets_spec.rb +144 -10
  45. data/spec/lib/blacklight/solr_response_spec.rb +5 -13
  46. data/spec/lib/document_presenter_spec.rb +23 -27
  47. data/spec/views/catalog/_facets.html.erb_spec.rb +1 -1
  48. data/spec/views/catalog/_index_default.erb_spec.rb +2 -13
  49. data/spec/views/catalog/_show_default.erb_spec.rb +1 -13
  50. metadata +10 -4
@@ -98,8 +98,11 @@ module Blacklight::SearchHelper
98
98
  # @param [List<Symbol] processor_chain a list of filter methods to run
99
99
  # @return [Blacklight::SolrResponse] the solr response object
100
100
  def search_results(user_params, search_params_logic)
101
- query = search_builder(search_params_logic).with(user_params).query
102
- response = repository.search(query)
101
+ builder = search_builder(search_params_logic).with(user_params)
102
+ builder.page(user_params[:page]) if user_params[:page]
103
+ builder.rows(user_params[:per_page] || user_params[:rows]) if user_params[:per_page] or user_params[:rows]
104
+
105
+ response = repository.search(builder.query)
103
106
 
104
107
  case
105
108
  when (response.grouped? && grouped_key_for_results)
@@ -173,7 +176,7 @@ module Blacklight::SearchHelper
173
176
  # NOTE: The sniffing of the proper sort from the solr response is not
174
177
  # currently tested for, tricky to figure out how to test, since the
175
178
  # default setup we test against doesn't use this feature.
176
- Blacklight::Solr::FacetPaginator.new(response.facets.first.items,
179
+ Blacklight::Solr::FacetPaginator.new(response.aggregations[facet_field].items,
177
180
  :offset => response.params[:"f.#{facet_field}.facet.offset"],
178
181
  :limit => limit,
179
182
  :sort => response.params[:"f.#{facet_field}.facet.sort"] || response.params["facet.sort"]
@@ -188,12 +191,8 @@ module Blacklight::SearchHelper
188
191
  # the Blacklight app-level request params that define the search.
189
192
  # @return [Blacklight::SolrDocument, nil] the found document or nil if not found
190
193
  def get_single_doc_via_search(index, request_params)
191
- request_params = search_builder.with(request_params).processed_parameters
192
-
193
- request_params[:start] = (index - 1) # start at 0 to get 1st doc, 1 to get 2nd.
194
- request_params[:rows] = 1
195
- request_params[:fl] = '*'
196
- response = repository.search(request_params)
194
+ query = search_builder.with(request_params).start(index - 1).rows(1).query(fl: "*")
195
+ response = repository.search(query)
197
196
  response.documents.first
198
197
  end
199
198
  deprecation_deprecate :get_single_doc_via_search
@@ -201,8 +200,9 @@ module Blacklight::SearchHelper
201
200
  # Get the previous and next document from a search result
202
201
  # @return [Blacklight::SolrResponse, Array<Blacklight::SolrDocument>] the solr response and a list of the first and last document
203
202
  def get_previous_and_next_documents_for_search(index, request_params, extra_controller_params={})
203
+ p = previous_and_next_document_params(index)
204
204
 
205
- query = search_builder.with(request_params).query(extra_controller_params.merge(previous_and_next_document_params(index)))
205
+ query = search_builder.with(request_params).start(p.delete(:start)).rows(p.delete(:rows)).query(extra_controller_params.merge(p))
206
206
  response = repository.search(query)
207
207
 
208
208
  document_list = response.documents
@@ -6,5 +6,5 @@ module Blacklight::Solr
6
6
  autoload :Document, 'blacklight/solr/document'
7
7
  autoload :Request, 'blacklight/solr/request'
8
8
  autoload :SearchBuilder, 'blacklight/solr/search_builder'
9
-
9
+ autoload :SearchBuilderBehavior, 'blacklight/solr/search_builder_behavior'
10
10
  end
@@ -1,269 +1,6 @@
1
1
  module Blacklight::Solr
2
+ # @deprecated
2
3
  class SearchBuilder < Blacklight::SearchBuilder
3
-
4
- self.default_processor_chain = [:default_solr_parameters, :add_query_to_solr, :add_facet_fq_to_solr, :add_facetting_to_solr, :add_solr_fields_to_query, :add_paging_to_solr, :add_sorting_to_solr, :add_group_config_to_solr ]
5
-
6
- ####
7
- # Start with general defaults from BL config. Need to use custom
8
- # merge to dup values, to avoid later mutating the original by mistake.
9
- def default_solr_parameters(solr_parameters)
10
- blacklight_config.default_solr_params.each do |key, value|
11
- solr_parameters[key] = if value.respond_to? :deep_dup
12
- value.deep_dup
13
- elsif value.respond_to? :dup and value.duplicable?
14
- value.dup
15
- else
16
- value
17
- end
18
- end
19
- end
20
-
21
- ##
22
- # Take the user-entered query, and put it in the solr params,
23
- # including config's "search field" params for current search field.
24
- # also include setting spellcheck.q.
25
- def add_query_to_solr(solr_parameters)
26
- ###
27
- # Merge in search field configured values, if present, over-writing general
28
- # defaults
29
- ###
30
- # legacy behavior of user param :qt is passed through, but over-ridden
31
- # by actual search field config if present. We might want to remove
32
- # this legacy behavior at some point. It does not seem to be currently
33
- # rspec'd.
34
- solr_parameters[:qt] = blacklight_params[:qt] if blacklight_params[:qt]
35
-
36
- if search_field
37
- solr_parameters[:qt] = search_field.qt
38
- solr_parameters.merge!( search_field.solr_parameters) if search_field.solr_parameters
39
- end
40
-
41
- ##
42
- # Create Solr 'q' including the user-entered q, prefixed by any
43
- # solr LocalParams in config, using solr LocalParams syntax.
44
- # http://wiki.apache.org/solr/LocalParams
45
- ##
46
- if (search_field && hash = search_field.solr_local_parameters)
47
- local_params = hash.collect do |key, val|
48
- key.to_s + "=" + solr_param_quote(val, :quote => "'")
49
- end.join(" ")
50
- solr_parameters[:q] = "{!#{local_params}}#{blacklight_params[:q]}"
51
-
52
- ##
53
- # Set Solr spellcheck.q to be original user-entered query, without
54
- # our local params, otherwise it'll try and spellcheck the local
55
- # params!
56
- solr_parameters["spellcheck.q"] ||= blacklight_params[:q]
57
- elsif blacklight_params[:q].is_a? Hash
58
- q = blacklight_params[:q]
59
- solr_parameters[:q] = if q.values.any?(&:blank?)
60
- # if any field parameters are empty, exclude _all_ results
61
- "{!lucene}NOT *:*"
62
- else
63
- "{!lucene}" + q.map do |field, values|
64
- "#{field}:(#{ Array(values).map { |x| solr_param_quote(x) }.join(" OR ")})"
65
- end.join(" AND ")
66
- end
67
-
68
- solr_parameters[:spellcheck] = 'false'
69
- elsif blacklight_params[:q]
70
- solr_parameters[:q] = blacklight_params[:q]
71
- end
72
- end
73
-
74
- ##
75
- # Add any existing facet limits, stored in app-level HTTP query
76
- # as :f, to solr as appropriate :fq query.
77
- def add_facet_fq_to_solr(solr_parameters)
78
-
79
- # convert a String value into an Array
80
- if solr_parameters[:fq].is_a? String
81
- solr_parameters[:fq] = [solr_parameters[:fq]]
82
- end
83
-
84
- # :fq, map from :f.
85
- if ( blacklight_params[:f])
86
- f_request_params = blacklight_params[:f]
87
-
88
- f_request_params.each_pair do |facet_field, value_list|
89
- Array(value_list).each do |value|
90
- next if value.blank? # skip empty strings
91
- solr_parameters.append_filter_query facet_value_to_fq_string(facet_field, value)
92
- end
93
- end
94
- end
95
- end
96
-
97
- ##
98
- # Add appropriate Solr facetting directives in, including
99
- # taking account of our facet paging/'more'. This is not
100
- # about solr 'fq', this is about solr facet.* params.
101
- def add_facetting_to_solr(solr_parameters)
102
- # While not used by BL core behavior, legacy behavior seemed to be
103
- # to accept incoming params as "facet.field" or "facets", and add them
104
- # on to any existing facet.field sent to Solr. Legacy behavior seemed
105
- # to be accepting these incoming params as arrays (in Rails URL with []
106
- # on end), or single values. At least one of these is used by
107
- # Stanford for "faux hieararchial facets".
108
- if blacklight_params.has_key?("facet.field") || blacklight_params.has_key?("facets")
109
- solr_parameters[:"facet.field"].concat( [blacklight_params["facet.field"], blacklight_params["facets"]].flatten.compact ).uniq!
110
- end
111
-
112
- blacklight_config.facet_fields.select { |field_name,facet|
113
- facet.include_in_request || (facet.include_in_request.nil? && blacklight_config.add_facet_fields_to_solr_request)
114
- }.each do |field_name, facet|
115
- solr_parameters[:facet] ||= true
116
-
117
- case
118
- when facet.pivot
119
- solr_parameters.append_facet_pivot with_ex_local_param(facet.ex, facet.pivot.join(","))
120
- when facet.query
121
- solr_parameters.append_facet_query facet.query.map { |k, x| with_ex_local_param(facet.ex, x[:fq]) }
122
- else
123
- solr_parameters.append_facet_fields with_ex_local_param(facet.ex, facet.field)
124
- end
125
-
126
- if facet.sort
127
- solr_parameters[:"f.#{facet.field}.facet.sort"] = facet.sort
128
- end
129
-
130
- if facet.solr_params
131
- facet.solr_params.each do |k, v|
132
- solr_parameters[:"f.#{facet.field}.#{k}"] = v
133
- end
134
- end
135
-
136
- # Support facet paging and 'more'
137
- # links, by sending a facet.limit one more than what we
138
- # want to page at, according to configured facet limits.
139
- solr_parameters[:"f.#{facet.field}.facet.limit"] = (facet_limit_for(field_name) + 1) if facet_limit_for(field_name)
140
- end
141
- end
142
-
143
- def add_solr_fields_to_query solr_parameters
144
- blacklight_config.show_fields.select(&method(:should_add_field_to_request?)).each do |field_name, field|
145
- if field.solr_params
146
- field.solr_params.each do |k, v|
147
- solr_parameters[:"f.#{field.field}.#{k}"] = v
148
- end
149
- end
150
- end
151
-
152
- blacklight_config.index_fields.select(&method(:should_add_field_to_request?)).each do |field_name, field|
153
- if field.highlight
154
- solr_parameters[:hl] = true
155
- solr_parameters.append_highlight_field field.field
156
- end
157
-
158
- if field.solr_params
159
- field.solr_params.each do |k, v|
160
- solr_parameters[:"f.#{field.field}.#{k}"] = v
161
- end
162
- end
163
- end
164
- end
165
-
166
- ###
167
- # copy paging params from BL app over to solr, changing
168
- # app level per_page and page to Solr rows and start.
169
- def add_paging_to_solr(solr_params)
170
- # user-provided parameters should override any default row
171
- solr_params[:rows] = rows(solr_params[:rows])
172
- if page > 1
173
- solr_params[:start] = solr_params[:rows].to_i * (page - 1)
174
- end
175
- end
176
-
177
- ###
178
- # copy sorting params from BL app over to solr
179
- def add_sorting_to_solr(solr_parameters)
180
- solr_parameters[:sort] = sort unless sort.blank?
181
- end
182
-
183
- # Remove the group parameter if we've faceted on the group field (e.g. for the full results for a group)
184
- def add_group_config_to_solr solr_parameters
185
- if blacklight_params[:f] and blacklight_params[:f][grouped_key_for_results]
186
- solr_parameters[:group] = false
187
- end
188
- end
189
-
190
- def with_ex_local_param(ex, value)
191
- if ex
192
- "{!ex=#{ex}}#{value}"
193
- else
194
- value
195
- end
196
- end
197
-
198
- # Look up facet limit for given facet_field. Will look at config, and
199
- # if config is 'true' will look up from Solr @response if available. If
200
- # no limit is avaialble, returns nil. Used from #add_facetting_to_solr
201
- # to supply f.fieldname.facet.limit values in solr request (no @response
202
- # available), and used in display (with @response available) to create
203
- # a facet paginator with the right limit.
204
- def facet_limit_for(facet_field)
205
- facet = blacklight_config.facet_fields[facet_field]
206
- return if facet.blank?
207
-
208
- if facet.limit
209
- facet.limit == true ? blacklight_config.default_facet_limit : facet.limit
210
- end
211
- end
212
-
213
- ##
214
- # A helper method used for generating solr LocalParams, put quotes
215
- # around the term unless it's a bare-word. Escape internal quotes
216
- # if needed.
217
- def solr_param_quote(val, options = {})
218
- options[:quote] ||= '"'
219
- unless val =~ /^[a-zA-Z0-9$_\-\^]+$/
220
- val = options[:quote] +
221
- # Yes, we need crazy escaping here, to deal with regexp esc too!
222
- val.gsub("'", "\\\\\'").gsub('"', "\\\\\"") +
223
- options[:quote]
224
- end
225
- return val
226
- end
227
-
228
- private
229
-
230
- ##
231
- # Convert a facet/value pair into a solr fq parameter
232
- def facet_value_to_fq_string(facet_field, value)
233
- facet_config = blacklight_config.facet_fields[facet_field]
234
-
235
- solr_field = facet_config.field if facet_config and not facet_config.query
236
- solr_field ||= facet_field
237
-
238
- local_params = []
239
- local_params << "tag=#{facet_config.tag}" if facet_config and facet_config.tag
240
-
241
- prefix = ""
242
- prefix = "{!#{local_params.join(" ")}}" unless local_params.empty?
243
-
244
- fq = case
245
- when (facet_config and facet_config.query)
246
- facet_config.query[value][:fq]
247
- when (facet_config and facet_config.date)
248
- # in solr 3.2+, this could be replaced by a !term query
249
- "#{prefix}#{solr_field}:#{RSolr.solr_escape(value)}"
250
- when (value.is_a?(DateTime) or value.is_a?(Date) or value.is_a?(Time))
251
- "#{prefix}#{solr_field}:#{RSolr.solr_escape(value.to_time.utc.strftime("%Y-%m-%dT%H:%M:%SZ"))}"
252
- when (value.is_a?(TrueClass) or value.is_a?(FalseClass) or value == 'true' or value == 'false'),
253
- (value.is_a?(Integer) or (value.to_i.to_s == value if value.respond_to? :to_i)),
254
- (value.is_a?(Float) or (value.to_f.to_s == value if value.respond_to? :to_f))
255
- "#{prefix}#{solr_field}:#{RSolr.solr_escape(value.to_s)}"
256
- when value.is_a?(Range)
257
- "#{prefix}#{solr_field}:[#{value.first} TO #{value.last}]"
258
- else
259
- "{!raw f=#{solr_field}#{(" " + local_params.join(" ")) unless local_params.empty?}}#{value}"
260
- end
261
- end
262
-
263
- ##
264
- # The key to use to retrieve the grouped field to display
265
- def grouped_key_for_results
266
- blacklight_config.index.group
267
- end
4
+ include Blacklight::Solr::SearchBuilderBehavior
268
5
  end
269
6
  end
@@ -0,0 +1,274 @@
1
+ module Blacklight::Solr
2
+ module SearchBuilderBehavior
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ self.default_processor_chain = [:default_solr_parameters, :add_query_to_solr, :add_facet_fq_to_solr, :add_facetting_to_solr, :add_solr_fields_to_query, :add_paging_to_solr, :add_sorting_to_solr, :add_group_config_to_solr ]
7
+ end
8
+
9
+ ####
10
+ # Start with general defaults from BL config. Need to use custom
11
+ # merge to dup values, to avoid later mutating the original by mistake.
12
+ def default_solr_parameters(solr_parameters)
13
+ blacklight_config.default_solr_params.each do |key, value|
14
+ solr_parameters[key] = if value.respond_to? :deep_dup
15
+ value.deep_dup
16
+ elsif value.respond_to? :dup and value.duplicable?
17
+ value.dup
18
+ else
19
+ value
20
+ end
21
+ end
22
+ end
23
+
24
+ ##
25
+ # Take the user-entered query, and put it in the solr params,
26
+ # including config's "search field" params for current search field.
27
+ # also include setting spellcheck.q.
28
+ def add_query_to_solr(solr_parameters)
29
+ ###
30
+ # Merge in search field configured values, if present, over-writing general
31
+ # defaults
32
+ ###
33
+ # legacy behavior of user param :qt is passed through, but over-ridden
34
+ # by actual search field config if present. We might want to remove
35
+ # this legacy behavior at some point. It does not seem to be currently
36
+ # rspec'd.
37
+ solr_parameters[:qt] = blacklight_params[:qt] if blacklight_params[:qt]
38
+
39
+ if search_field
40
+ solr_parameters[:qt] = search_field.qt
41
+ solr_parameters.merge!( search_field.solr_parameters) if search_field.solr_parameters
42
+ end
43
+
44
+ ##
45
+ # Create Solr 'q' including the user-entered q, prefixed by any
46
+ # solr LocalParams in config, using solr LocalParams syntax.
47
+ # http://wiki.apache.org/solr/LocalParams
48
+ ##
49
+ if (search_field && hash = search_field.solr_local_parameters)
50
+ local_params = hash.collect do |key, val|
51
+ key.to_s + "=" + solr_param_quote(val, :quote => "'")
52
+ end.join(" ")
53
+ solr_parameters[:q] = "{!#{local_params}}#{blacklight_params[:q]}"
54
+
55
+ ##
56
+ # Set Solr spellcheck.q to be original user-entered query, without
57
+ # our local params, otherwise it'll try and spellcheck the local
58
+ # params!
59
+ solr_parameters["spellcheck.q"] ||= blacklight_params[:q]
60
+ elsif blacklight_params[:q].is_a? Hash
61
+ q = blacklight_params[:q]
62
+ solr_parameters[:q] = if q.values.any?(&:blank?)
63
+ # if any field parameters are empty, exclude _all_ results
64
+ "{!lucene}NOT *:*"
65
+ else
66
+ "{!lucene}" + q.map do |field, values|
67
+ "#{field}:(#{ Array(values).map { |x| solr_param_quote(x) }.join(" OR ")})"
68
+ end.join(" AND ")
69
+ end
70
+
71
+ solr_parameters[:spellcheck] = 'false'
72
+ elsif blacklight_params[:q]
73
+ solr_parameters[:q] = blacklight_params[:q]
74
+ end
75
+ end
76
+
77
+ ##
78
+ # Add any existing facet limits, stored in app-level HTTP query
79
+ # as :f, to solr as appropriate :fq query.
80
+ def add_facet_fq_to_solr(solr_parameters)
81
+
82
+ # convert a String value into an Array
83
+ if solr_parameters[:fq].is_a? String
84
+ solr_parameters[:fq] = [solr_parameters[:fq]]
85
+ end
86
+
87
+ # :fq, map from :f.
88
+ if ( blacklight_params[:f])
89
+ f_request_params = blacklight_params[:f]
90
+
91
+ f_request_params.each_pair do |facet_field, value_list|
92
+ Array(value_list).each do |value|
93
+ next if value.blank? # skip empty strings
94
+ solr_parameters.append_filter_query facet_value_to_fq_string(facet_field, value)
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ ##
101
+ # Add appropriate Solr facetting directives in, including
102
+ # taking account of our facet paging/'more'. This is not
103
+ # about solr 'fq', this is about solr facet.* params.
104
+ def add_facetting_to_solr(solr_parameters)
105
+ # While not used by BL core behavior, legacy behavior seemed to be
106
+ # to accept incoming params as "facet.field" or "facets", and add them
107
+ # on to any existing facet.field sent to Solr. Legacy behavior seemed
108
+ # to be accepting these incoming params as arrays (in Rails URL with []
109
+ # on end), or single values. At least one of these is used by
110
+ # Stanford for "faux hieararchial facets".
111
+ if blacklight_params.has_key?("facet.field") || blacklight_params.has_key?("facets")
112
+ solr_parameters[:"facet.field"].concat( [blacklight_params["facet.field"], blacklight_params["facets"]].flatten.compact ).uniq!
113
+ end
114
+
115
+ blacklight_config.facet_fields.select { |field_name,facet|
116
+ facet.include_in_request || (facet.include_in_request.nil? && blacklight_config.add_facet_fields_to_solr_request)
117
+ }.each do |field_name, facet|
118
+ solr_parameters[:facet] ||= true
119
+
120
+ case
121
+ when facet.pivot
122
+ solr_parameters.append_facet_pivot with_ex_local_param(facet.ex, facet.pivot.join(","))
123
+ when facet.query
124
+ solr_parameters.append_facet_query facet.query.map { |k, x| with_ex_local_param(facet.ex, x[:fq]) }
125
+ else
126
+ solr_parameters.append_facet_fields with_ex_local_param(facet.ex, facet.field)
127
+ end
128
+
129
+ if facet.sort
130
+ solr_parameters[:"f.#{facet.field}.facet.sort"] = facet.sort
131
+ end
132
+
133
+ if facet.solr_params
134
+ facet.solr_params.each do |k, v|
135
+ solr_parameters[:"f.#{facet.field}.#{k}"] = v
136
+ end
137
+ end
138
+
139
+ # Support facet paging and 'more'
140
+ # links, by sending a facet.limit one more than what we
141
+ # want to page at, according to configured facet limits.
142
+ solr_parameters[:"f.#{facet.field}.facet.limit"] = (facet_limit_for(field_name) + 1) if facet_limit_for(field_name)
143
+ end
144
+ end
145
+
146
+ def add_solr_fields_to_query solr_parameters
147
+ blacklight_config.show_fields.select(&method(:should_add_field_to_request?)).each do |field_name, field|
148
+ if field.solr_params
149
+ field.solr_params.each do |k, v|
150
+ solr_parameters[:"f.#{field.field}.#{k}"] = v
151
+ end
152
+ end
153
+ end
154
+
155
+ blacklight_config.index_fields.select(&method(:should_add_field_to_request?)).each do |field_name, field|
156
+ if field.highlight
157
+ solr_parameters[:hl] = true
158
+ solr_parameters.append_highlight_field field.field
159
+ end
160
+
161
+ if field.solr_params
162
+ field.solr_params.each do |k, v|
163
+ solr_parameters[:"f.#{field.field}.#{k}"] = v
164
+ end
165
+ end
166
+ end
167
+ end
168
+
169
+ ###
170
+ # copy paging params from BL app over to solr, changing
171
+ # app level per_page and page to Solr rows and start.
172
+ def add_paging_to_solr(solr_params)
173
+ rows(solr_params[:rows] || 10) if rows.nil?
174
+
175
+ solr_params[:rows] = rows
176
+
177
+ if start != 0
178
+ solr_params[:start] = start
179
+ end
180
+ end
181
+
182
+ ###
183
+ # copy sorting params from BL app over to solr
184
+ def add_sorting_to_solr(solr_parameters)
185
+ solr_parameters[:sort] = sort unless sort.blank?
186
+ end
187
+
188
+ # Remove the group parameter if we've faceted on the group field (e.g. for the full results for a group)
189
+ def add_group_config_to_solr solr_parameters
190
+ if blacklight_params[:f] and blacklight_params[:f][grouped_key_for_results]
191
+ solr_parameters[:group] = false
192
+ end
193
+ end
194
+
195
+ def with_ex_local_param(ex, value)
196
+ if ex
197
+ "{!ex=#{ex}}#{value}"
198
+ else
199
+ value
200
+ end
201
+ end
202
+
203
+ # Look up facet limit for given facet_field. Will look at config, and
204
+ # if config is 'true' will look up from Solr @response if available. If
205
+ # no limit is avaialble, returns nil. Used from #add_facetting_to_solr
206
+ # to supply f.fieldname.facet.limit values in solr request (no @response
207
+ # available), and used in display (with @response available) to create
208
+ # a facet paginator with the right limit.
209
+ def facet_limit_for(facet_field)
210
+ facet = blacklight_config.facet_fields[facet_field]
211
+ return if facet.blank?
212
+
213
+ if facet.limit
214
+ facet.limit == true ? blacklight_config.default_facet_limit : facet.limit
215
+ end
216
+ end
217
+
218
+ ##
219
+ # A helper method used for generating solr LocalParams, put quotes
220
+ # around the term unless it's a bare-word. Escape internal quotes
221
+ # if needed.
222
+ def solr_param_quote(val, options = {})
223
+ options[:quote] ||= '"'
224
+ unless val =~ /^[a-zA-Z0-9$_\-\^]+$/
225
+ val = options[:quote] +
226
+ # Yes, we need crazy escaping here, to deal with regexp esc too!
227
+ val.gsub("'", "\\\\\'").gsub('"', "\\\\\"") +
228
+ options[:quote]
229
+ end
230
+ return val
231
+ end
232
+
233
+ private
234
+
235
+ ##
236
+ # Convert a facet/value pair into a solr fq parameter
237
+ def facet_value_to_fq_string(facet_field, value)
238
+ facet_config = blacklight_config.facet_fields[facet_field]
239
+
240
+ solr_field = facet_config.field if facet_config and not facet_config.query
241
+ solr_field ||= facet_field
242
+
243
+ local_params = []
244
+ local_params << "tag=#{facet_config.tag}" if facet_config and facet_config.tag
245
+
246
+ prefix = ""
247
+ prefix = "{!#{local_params.join(" ")}}" unless local_params.empty?
248
+
249
+ fq = case
250
+ when (facet_config and facet_config.query)
251
+ facet_config.query[value][:fq]
252
+ when (facet_config and facet_config.date)
253
+ # in solr 3.2+, this could be replaced by a !term query
254
+ "#{prefix}#{solr_field}:#{RSolr.solr_escape(value)}"
255
+ when (value.is_a?(DateTime) or value.is_a?(Date) or value.is_a?(Time))
256
+ "#{prefix}#{solr_field}:#{RSolr.solr_escape(value.to_time.utc.strftime("%Y-%m-%dT%H:%M:%SZ"))}"
257
+ when (value.is_a?(TrueClass) or value.is_a?(FalseClass) or value == 'true' or value == 'false'),
258
+ (value.is_a?(Integer) or (value.to_i.to_s == value if value.respond_to? :to_i)),
259
+ (value.is_a?(Float) or (value.to_f.to_s == value if value.respond_to? :to_f))
260
+ "#{prefix}#{solr_field}:#{RSolr.solr_escape(value.to_s)}"
261
+ when value.is_a?(Range)
262
+ "#{prefix}#{solr_field}:[#{value.first} TO #{value.last}]"
263
+ else
264
+ "{!raw f=#{solr_field}#{(" " + local_params.join(" ")) unless local_params.empty?}}#{value}"
265
+ end
266
+ end
267
+
268
+ ##
269
+ # The key to use to retrieve the grouped field to display
270
+ def grouped_key_for_results
271
+ blacklight_config.index.group
272
+ end
273
+ end
274
+ end