blacklight 8.11.0 → 9.0.0.beta2

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 (288) hide show
  1. checksums.yaml +4 -4
  2. data/.env +3 -3
  3. data/.github/matrix.json +11 -42
  4. data/.github/pull_request_template.md +7 -0
  5. data/.github/workflows/main.yml +0 -2
  6. data/.github/workflows/release_7_x_scheduled.yml +39 -0
  7. data/.github/workflows/release_8_x_scheduled.yml +39 -0
  8. data/.github/workflows/test.yml +0 -5
  9. data/.rubocop.yml +71 -3
  10. data/.rubocop_todo.yml +43 -76
  11. data/.solr_wrapper.yml +2 -0
  12. data/README.md +30 -8
  13. data/VERSION +1 -1
  14. data/app/assets/builds/blacklight.css +452 -0
  15. data/app/assets/javascripts/blacklight/blacklight.esm.js +6 -76
  16. data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -1
  17. data/app/assets/javascripts/blacklight/blacklight.js +6 -76
  18. data/app/assets/javascripts/blacklight/blacklight.js.map +1 -1
  19. data/app/assets/stylesheets/blacklight/_balanced_list.scss +1 -4
  20. data/app/assets/stylesheets/blacklight/_blacklight_base.scss +1 -3
  21. data/app/assets/stylesheets/blacklight/_bookmark.scss +44 -41
  22. data/app/assets/stylesheets/blacklight/_bootstrap_overrides.scss +0 -25
  23. data/app/assets/stylesheets/blacklight/_constraints.scss +15 -24
  24. data/app/assets/stylesheets/blacklight/_controls.scss +2 -18
  25. data/app/assets/stylesheets/blacklight/_facets.scss +17 -84
  26. data/app/assets/stylesheets/blacklight/_group.scss +2 -5
  27. data/app/assets/stylesheets/blacklight/_header.scss +8 -11
  28. data/app/assets/stylesheets/blacklight/_icons.scss +0 -8
  29. data/app/assets/stylesheets/blacklight/_modal.scss +1 -1
  30. data/app/assets/stylesheets/blacklight/_pagination.scss +0 -4
  31. data/app/assets/stylesheets/blacklight/_search_form.scss +0 -1
  32. data/app/assets/stylesheets/blacklight/_search_history.scss +0 -8
  33. data/app/assets/stylesheets/blacklight/_search_results.scss +1 -15
  34. data/app/assets/stylesheets/blacklight/blacklight_defaults.scss +9 -14
  35. data/app/assets/stylesheets/blacklight/build.scss +4 -0
  36. data/app/components/blacklight/advanced_search_form_component.rb +3 -3
  37. data/app/components/blacklight/constraint_component.rb +1 -1
  38. data/app/components/blacklight/constraint_layout_component.html.erb +2 -2
  39. data/app/components/blacklight/constraints_component.html.erb +2 -2
  40. data/app/components/blacklight/constraints_component.rb +3 -3
  41. data/app/components/blacklight/document/bookmark_component.html.erb +3 -3
  42. data/app/components/blacklight/document/bookmark_component.rb +2 -2
  43. data/app/components/blacklight/document/group_component.html.erb +1 -1
  44. data/app/components/blacklight/document/more_like_this_component.rb +2 -2
  45. data/app/components/blacklight/document/page_header_component.rb +1 -1
  46. data/app/components/blacklight/document/sidebar_component.rb +5 -5
  47. data/app/components/blacklight/document/thumbnail_component.html.erb +3 -7
  48. data/app/components/blacklight/document/thumbnail_component.rb +7 -6
  49. data/app/components/blacklight/document_component.rb +12 -16
  50. data/app/components/blacklight/document_title_component.rb +5 -11
  51. data/app/components/blacklight/facet_field_checkboxes_component.rb +2 -20
  52. data/app/components/blacklight/facet_field_component.rb +2 -17
  53. data/app/components/blacklight/facet_field_filter_component.rb +2 -21
  54. data/app/components/blacklight/facet_field_inclusive_constraint_component.rb +4 -25
  55. data/app/components/blacklight/facet_field_list_component.rb +2 -50
  56. data/app/components/blacklight/facet_field_no_layout_component.rb +2 -10
  57. data/app/components/blacklight/facet_item_component.rb +2 -74
  58. data/app/components/blacklight/facet_item_pivot_component.rb +3 -3
  59. data/app/components/blacklight/facets/checkboxes_component.rb +26 -0
  60. data/app/components/blacklight/facets/count_component.rb +23 -0
  61. data/app/components/blacklight/{facet_field_component.html.erb → facets/field_component.html.erb} +4 -4
  62. data/app/components/blacklight/facets/field_component.rb +23 -0
  63. data/app/components/blacklight/facets/filters_component.html.erb +4 -0
  64. data/app/components/blacklight/facets/filters_component.rb +27 -0
  65. data/app/components/blacklight/{facet_field_inclusive_constraint_component.html.erb → facets/inclusive_constraint_component.html.erb} +1 -1
  66. data/app/components/blacklight/facets/inclusive_constraint_component.rb +31 -0
  67. data/app/components/blacklight/{facet_field_filter_component.html.erb → facets/index_navigation_component.html.erb} +1 -1
  68. data/app/components/blacklight/facets/index_navigation_component.rb +32 -0
  69. data/app/components/blacklight/facets/item_component.rb +73 -0
  70. data/app/components/blacklight/facets/list_component.html.erb +11 -0
  71. data/app/components/blacklight/facets/list_component.rb +38 -0
  72. data/app/components/blacklight/facets/no_layout_component.rb +16 -0
  73. data/app/components/blacklight/facets/selected_value_component.rb +29 -0
  74. data/app/components/blacklight/facets/suggest_component.html.erb +12 -0
  75. data/app/components/blacklight/facets/suggest_component.rb +22 -0
  76. data/app/components/blacklight/metadata_field_plain_text_layout_component.rb +2 -2
  77. data/app/components/blacklight/response/facet_group_component.html.erb +3 -18
  78. data/app/components/blacklight/response/facet_group_component.rb +11 -23
  79. data/app/components/blacklight/response/facet_toggle_button_component.html.erb +16 -0
  80. data/app/components/blacklight/response/facet_toggle_button_component.rb +14 -0
  81. data/app/components/blacklight/response/pagination_component.html.erb +1 -1
  82. data/app/components/blacklight/response/pagination_component.rb +2 -1
  83. data/app/components/blacklight/response/sort_component.rb +1 -0
  84. data/app/components/blacklight/response/view_type_button_component.html.erb +1 -1
  85. data/app/components/blacklight/response/view_type_component.html.erb +1 -1
  86. data/app/components/blacklight/search/per_page_component.html.erb +1 -1
  87. data/app/components/blacklight/search/per_page_component.rb +1 -0
  88. data/app/components/blacklight/search/sidebar_component.html.erb +1 -1
  89. data/app/components/blacklight/search/sidebar_component.rb +1 -1
  90. data/app/components/blacklight/search_bar_component.html.erb +3 -3
  91. data/app/components/blacklight/search_bar_component.rb +2 -2
  92. data/app/components/blacklight/search_button_component.rb +2 -2
  93. data/app/components/blacklight/search_context/server_applied_params_component.html.erb +2 -2
  94. data/app/components/blacklight/search_context/server_applied_params_component.rb +9 -0
  95. data/app/components/blacklight/skip_link_component.html.erb +1 -1
  96. data/app/components/blacklight/skip_link_component.rb +2 -1
  97. data/app/components/blacklight/top_navbar_component.html.erb +2 -2
  98. data/app/controllers/concerns/blacklight/bookmarks.rb +3 -3
  99. data/app/controllers/concerns/blacklight/catalog.rb +9 -23
  100. data/app/controllers/concerns/blacklight/controller.rb +1 -1
  101. data/app/controllers/concerns/blacklight/facetable.rb +34 -0
  102. data/app/controllers/concerns/blacklight/search_context.rb +0 -12
  103. data/app/controllers/concerns/blacklight/searchable.rb +1 -1
  104. data/app/helpers/blacklight/blacklight_helper_behavior.rb +0 -6
  105. data/app/helpers/blacklight/catalog_helper_behavior.rb +0 -10
  106. data/app/helpers/blacklight/configuration_helper_behavior.rb +2 -14
  107. data/app/helpers/blacklight/document_helper_behavior.rb +3 -27
  108. data/app/helpers/blacklight/facets_helper_behavior.rb +9 -0
  109. data/app/helpers/blacklight/icon_helper_behavior.rb +3 -11
  110. data/app/helpers/blacklight/layout_helper_behavior.rb +2 -2
  111. data/app/helpers/blacklight/render_partials_helper_behavior.rb +0 -14
  112. data/app/helpers/blacklight/url_helper_behavior.rb +1 -1
  113. data/app/javascript/{blacklight → blacklight-frontend}/bookmark_toggle.js +1 -1
  114. data/app/javascript/{blacklight → blacklight-frontend}/checkbox_submit.js +3 -0
  115. data/app/javascript/{blacklight → blacklight-frontend}/core.js +2 -10
  116. data/app/javascript/{blacklight → blacklight-frontend}/facet_suggest.js +1 -3
  117. data/app/javascript/blacklight-frontend/index.js +16 -0
  118. data/app/javascript/{blacklight → blacklight-frontend}/modal.js +1 -5
  119. data/app/models/concerns/blacklight/document.rb +0 -11
  120. data/app/models/concerns/blacklight/user.rb +1 -1
  121. data/app/models/facet_search_builder.rb +5 -0
  122. data/app/presenters/blacklight/facet_field_presenter.rb +3 -3
  123. data/app/presenters/blacklight/rendering/helper_method.rb +4 -4
  124. data/app/presenters/blacklight/rendering/join.rb +2 -2
  125. data/app/services/blacklight/facet_search_service.rb +44 -0
  126. data/app/services/blacklight/field_retriever.rb +1 -1
  127. data/app/services/blacklight/search_params_yaml_coder.rb +0 -2
  128. data/app/services/blacklight/search_service.rb +6 -6
  129. data/app/values/blacklight/types.rb +2 -2
  130. data/app/views/bookmarks/_clear_bookmarks_widget.html.erb +0 -2
  131. data/app/views/bookmarks/index.html.erb +1 -1
  132. data/app/views/catalog/_facet_pivot.html.erb +1 -1
  133. data/app/views/catalog/_home_text.html.erb +2 -2
  134. data/app/views/catalog/_results_pagination.html.erb +2 -5
  135. data/app/views/catalog/_search_results.html.erb +3 -3
  136. data/app/views/catalog/_search_results_header.html.erb +1 -1
  137. data/app/views/catalog/_sort_and_per_page.html.erb +1 -1
  138. data/app/views/catalog/_sort_widget.html.erb +1 -0
  139. data/app/views/catalog/facet.html.erb +4 -6
  140. data/app/views/catalog/show.html.erb +2 -3
  141. data/app/views/kaminari/blacklight/_paginator.html.erb +1 -2
  142. data/app/views/layouts/blacklight/base.html.erb +3 -7
  143. data/app/views/search_history/index.html.erb +0 -2
  144. data/blacklight.gemspec +4 -4
  145. data/config/importmap.rb +1 -1
  146. data/config/locales/blacklight.ar.yml +2 -2
  147. data/config/locales/blacklight.ca.yml +124 -124
  148. data/config/locales/blacklight.de.yml +2 -2
  149. data/config/locales/blacklight.en.yml +14 -14
  150. data/config/locales/blacklight.es.yml +2 -2
  151. data/config/locales/blacklight.fr.yml +2 -2
  152. data/config/locales/blacklight.hu.yml +2 -2
  153. data/config/locales/blacklight.it.yml +1 -1
  154. data/config/locales/blacklight.nl.yml +2 -2
  155. data/config/locales/blacklight.pt-BR.yml +1 -1
  156. data/config/locales/blacklight.sq.yml +2 -2
  157. data/config/locales/blacklight.zh.yml +2 -2
  158. data/lib/blacklight/abstract_repository.rb +2 -2
  159. data/lib/blacklight/abstract_search_builder.rb +154 -0
  160. data/lib/blacklight/configuration/context.rb +3 -3
  161. data/lib/blacklight/configuration/display_field.rb +1 -1
  162. data/lib/blacklight/configuration/facet_field.rb +6 -6
  163. data/lib/blacklight/configuration/field.rb +4 -4
  164. data/lib/blacklight/configuration/fields.rb +3 -4
  165. data/lib/blacklight/configuration/search_field.rb +1 -1
  166. data/lib/blacklight/configuration/view_config.rb +2 -4
  167. data/lib/blacklight/configuration.rb +11 -18
  168. data/lib/blacklight/engine.rb +0 -6
  169. data/lib/blacklight/facet_search_builder.rb +18 -0
  170. data/lib/blacklight/nested_open_struct_with_hash_access.rb +1 -1
  171. data/lib/blacklight/open_struct_with_hash_access.rb +5 -5
  172. data/lib/blacklight/search_builder.rb +1 -159
  173. data/lib/blacklight/search_state/filter_field.rb +2 -2
  174. data/lib/blacklight/search_state/pivot_filter_field.rb +4 -4
  175. data/lib/blacklight/solr/abstract_filter_query_builder.rb +77 -0
  176. data/lib/blacklight/solr/default_filter_query_builder.rb +20 -0
  177. data/lib/blacklight/solr/facet_search_builder_behavior.rb +62 -0
  178. data/lib/blacklight/solr/repository.rb +8 -9
  179. data/lib/blacklight/solr/request.rb +1 -7
  180. data/lib/blacklight/solr/response/facets.rb +2 -2
  181. data/lib/blacklight/solr/response/group_response.rb +2 -2
  182. data/lib/blacklight/solr/response/params.rb +0 -4
  183. data/lib/blacklight/solr/response.rb +5 -1
  184. data/lib/blacklight/solr/search_builder_behavior.rb +17 -132
  185. data/lib/blacklight.rb +2 -2
  186. data/lib/generators/blacklight/assets/importmap_generator.rb +6 -24
  187. data/lib/generators/blacklight/assets/propshaft_generator.rb +1 -1
  188. data/lib/generators/blacklight/assets_generator.rb +3 -3
  189. data/lib/generators/blacklight/controller_generator.rb +3 -3
  190. data/lib/generators/blacklight/search_builder_generator.rb +1 -1
  191. data/lib/generators/blacklight/templates/.solr_wrapper.yml +2 -0
  192. data/lib/generators/blacklight/templates/catalog_controller.rb +3 -1
  193. data/lib/generators/blacklight/templates/solr/conf/solrconfig.xml +0 -4
  194. data/lib/generators/blacklight/user_generator.rb +9 -10
  195. data/package.json +15 -5
  196. data/rollup.config.js +1 -1
  197. data/spec/components/blacklight/advanced_search_form_component_spec.rb +18 -22
  198. data/spec/components/blacklight/constraint_layout_component_spec.rb +8 -8
  199. data/spec/components/blacklight/constraints_component_spec.rb +11 -11
  200. data/spec/components/blacklight/document/action_component_spec.rb +21 -17
  201. data/spec/components/blacklight/document/group_component_spec.rb +10 -15
  202. data/spec/components/blacklight/document/page_header_component_spec.rb +35 -28
  203. data/spec/components/blacklight/document/sidebar_component_spec.rb +9 -30
  204. data/spec/components/blacklight/document_component_spec.rb +98 -65
  205. data/spec/components/blacklight/facet_component_spec.rb +12 -8
  206. data/spec/components/blacklight/facet_item_pivot_component_spec.rb +12 -12
  207. data/spec/components/blacklight/{facet_field_checkboxes_component_spec.rb → facets/checkboxes_component_spec.rb} +14 -14
  208. data/spec/components/blacklight/facets/filters_component_spec.rb +36 -0
  209. data/spec/components/blacklight/facets/index_navigation_component_spec.rb +40 -0
  210. data/spec/components/blacklight/{facet_item_component_spec.rb → facets/item_component_spec.rb} +10 -10
  211. data/spec/components/blacklight/{facet_field_list_component_spec.rb → facets/list_component_spec.rb} +24 -24
  212. data/spec/components/blacklight/facets/suggest_component_spec.rb +68 -0
  213. data/spec/components/blacklight/header_component_spec.rb +2 -4
  214. data/spec/components/blacklight/hidden_search_state_component_spec.rb +7 -7
  215. data/spec/components/blacklight/metadata_field_component_spec.rb +17 -15
  216. data/spec/components/blacklight/response/facet_group_component_spec.rb +37 -0
  217. data/spec/components/blacklight/response/pagination_component_spec.rb +1 -1
  218. data/spec/components/blacklight/response/spellcheck_component_spec.rb +1 -1
  219. data/spec/components/blacklight/search_bar_component_spec.rb +5 -5
  220. data/spec/components/blacklight/search_context/server_applied_params_component_spec.rb +2 -2
  221. data/spec/components/blacklight/search_context/server_item_pagination_component_spec.rb +3 -5
  222. data/spec/components/blacklight/skip_link_component_spec.rb +8 -11
  223. data/spec/components/blacklight/start_over_button_component_spec.rb +4 -4
  224. data/spec/components/blacklight/system/flash_message_component_spec.rb +7 -11
  225. data/spec/controllers/catalog_controller_spec.rb +11 -19
  226. data/spec/features/axe_spec.rb +6 -11
  227. data/spec/features/bookmarks_spec.rb +48 -11
  228. data/spec/features/facets_spec.rb +58 -63
  229. data/spec/features/search_context_spec.rb +1 -2
  230. data/spec/features/search_filters_spec.rb +6 -6
  231. data/spec/helpers/blacklight/configuration_helper_behavior_spec.rb +0 -9
  232. data/spec/helpers/blacklight/facets_helper_behavior_spec.rb +10 -0
  233. data/spec/helpers/blacklight/render_partials_helper_behavior_spec.rb +1 -1
  234. data/spec/lib/blacklight/configuration/facet_field_spec.rb +2 -2
  235. data/spec/models/blacklight/configuration_spec.rb +32 -28
  236. data/spec/models/blacklight/facet_search_builder_spec.rb +19 -0
  237. data/spec/models/blacklight/search_builder_spec.rb +1 -11
  238. data/spec/models/blacklight/solr/default_filter_query_builder_spec.rb +72 -0
  239. data/spec/models/blacklight/solr/document_spec.rb +0 -4
  240. data/spec/models/blacklight/solr/facet_search_builder_behavior_spec.rb +929 -0
  241. data/spec/models/blacklight/solr/repository_spec.rb +31 -29
  242. data/spec/models/blacklight/solr/request_spec.rb +7 -0
  243. data/spec/models/blacklight/solr/response/facets_spec.rb +86 -40
  244. data/spec/models/blacklight/solr/response/group_response_spec.rb +8 -5
  245. data/spec/models/blacklight/solr/response/group_spec.rb +9 -5
  246. data/spec/models/blacklight/solr/response_spec.rb +96 -64
  247. data/spec/models/blacklight/solr/search_builder_behavior_spec.rb +2 -227
  248. data/spec/models/solr_document_spec.rb +5 -1
  249. data/spec/services/blacklight/search_service_spec.rb +5 -26
  250. data/spec/spec_helper.rb +0 -1
  251. data/spec/support/view_component_test_helpers.rb +0 -18
  252. data/spec/views/catalog/facet.html.erb_spec.rb +10 -11
  253. data/spec/views/catalog/index.atom.builder_spec.rb +6 -3
  254. data/spec/views/catalog/index.html.erb_spec.rb +8 -3
  255. data/spec/views/catalog/show.html.erb_spec.rb +1 -0
  256. data/tasks/blacklight.rake +8 -5
  257. metadata +76 -81
  258. data/app/assets/stylesheets/blacklight/_autocomplete.scss +0 -25
  259. data/app/assets/stylesheets/blacklight/_mixins.scss +0 -20
  260. data/app/components/blacklight/facet_field_list_component.html.erb +0 -19
  261. data/app/components/blacklight/icons/legacy_icon_component.rb +0 -30
  262. data/app/components/blacklight/search/facet_suggest_input.html.erb +0 -12
  263. data/app/components/blacklight/search/facet_suggest_input.rb +0 -20
  264. data/app/javascript/blacklight/index.js +0 -18
  265. data/app/javascript/blacklight/modalForm.js +0 -60
  266. data/app/views/catalog/_constraints.html.erb +0 -1
  267. data/app/views/catalog/_facet_index_navigation.html.erb +0 -1
  268. data/app/views/catalog/_facet_layout.html.erb +0 -8
  269. data/app/views/catalog/_facet_pagination.html.erb +0 -1
  270. data/app/views/catalog/_facets.html.erb +0 -5
  271. data/app/views/catalog/_search_form.html.erb +0 -7
  272. data/app/views/catalog/_search_header.html.erb +0 -1
  273. data/app/views/catalog/_show_sidebar.html.erb +0 -3
  274. data/app/views/catalog/_show_tools.html.erb +0 -2
  275. data/app/views/catalog/_start_over.html.erb +0 -1
  276. data/app/views/shared/_header_navbar.html.erb +0 -1
  277. data/lib/generators/blacklight/assets/sprockets_generator.rb +0 -68
  278. data/spec/components/blacklight/document_metadata_component_spec.rb +0 -0
  279. data/spec/components/blacklight/search/facet_suggest_input_spec.rb +0 -57
  280. data/spec/views/catalog/_facet_index_navigation.html.erb_spec.rb +0 -43
  281. data/spec/views/catalog/_facet_layout.html.erb_spec.rb +0 -41
  282. data/spec/views/catalog/_search_header.erb_spec.rb +0 -14
  283. data/spec/views/catalog/_show_sidebar.erb_spec.rb +0 -24
  284. data/spec/views/catalog/_show_tools.html.erb_spec.rb +0 -37
  285. /data/app/components/blacklight/{facet_field_checkboxes_component.html.erb → facets/checkboxes_component.html.erb} +0 -0
  286. /data/app/javascript/{blacklight → blacklight-frontend}/button_focus.js +0 -0
  287. /data/app/javascript/{blacklight → blacklight-frontend}/debounce.js +0 -0
  288. /data/app/javascript/{blacklight → blacklight-frontend}/search_context.js +0 -0
@@ -5,45 +5,7 @@ module Blacklight
5
5
  # Blacklight's SearchBuilder converts blacklight request parameters into
6
6
  # query parameters appropriate for search index. It does so by evaluating a
7
7
  # chain of processing methods to populate a result hash (see {#to_hash}).
8
- class SearchBuilder
9
- class_attribute :default_processor_chain
10
- self.default_processor_chain = []
11
-
12
- attr_reader :processor_chain, :search_state, :blacklight_params
13
-
14
- # @overload initialize(scope)
15
- # @param [Object] scope scope the scope where the filter methods reside in.
16
- # @overload initialize(processor_chain, scope)
17
- # @param [List<Symbol>,TrueClass] processor_chain options a list of filter methods to run or true, to use the default methods
18
- # @param [Object] scope the scope where the filter methods reside in.
19
- def initialize(*options)
20
- case options.size
21
- when 1
22
- @processor_chain = default_processor_chain.dup
23
- @scope = options.first
24
- when 2
25
- @processor_chain, @scope = options
26
- else
27
- raise ArgumentError, "wrong number of arguments. (#{options.size} for 1..2)"
28
- end
29
-
30
- @blacklight_params = {}
31
- search_state_class = @scope.try(:search_state_class) || Blacklight::SearchState
32
- @search_state = search_state_class.new(@blacklight_params, @scope&.blacklight_config, @scope)
33
- @additional_filters = {}
34
- @merged_params = {}
35
- @reverse_merged_params = {}
36
- end
37
-
38
- ##
39
- # Set the parameters to pass through the processor chain
40
- def with(blacklight_params_or_search_state = {})
41
- params_will_change!
42
- @search_state = blacklight_params_or_search_state.is_a?(Blacklight::SearchState) ? blacklight_params_or_search_state : @search_state.reset(blacklight_params_or_search_state)
43
- @blacklight_params = @search_state.params.dup
44
- self
45
- end
46
-
8
+ class SearchBuilder < AbstractSearchBuilder
47
9
  ##
48
10
  # Update the :q (query) parameter
49
11
  # @param [Hash<Symbol,Object>] conditions the field and values to query on
@@ -93,68 +55,6 @@ module Blacklight
93
55
  builder
94
56
  end
95
57
 
96
- ##
97
- # Merge additional, repository-specific parameters
98
- def merge(extra_params, &block)
99
- if extra_params
100
- params_will_change!
101
- @merged_params.merge!(extra_params.to_hash, &block)
102
- end
103
- self
104
- end
105
-
106
- ##
107
- # "Reverse merge" additional, repository-specific parameters
108
- def reverse_merge(extra_params, &block)
109
- if extra_params
110
- params_will_change!
111
- @reverse_merged_params.reverse_merge!(extra_params.to_hash, &block)
112
- end
113
- self
114
- end
115
-
116
- delegate :[], :key?, to: :to_hash
117
-
118
- # a solr query method
119
- # @return [Blacklight::Solr::Response] the solr response object
120
- def to_hash
121
- return @params unless params_need_update?
122
-
123
- @params = processed_parameters
124
- .reverse_merge(@reverse_merged_params)
125
- .merge(@merged_params)
126
- .tap { clear_changes }
127
- end
128
-
129
- alias_method :query, :to_hash
130
- alias_method :to_h, :to_hash
131
-
132
- # The CatalogController #index action uses this.
133
- # Solr parameters can come from a number of places. From lowest
134
- # precedence to highest:
135
- # 1. General defaults in blacklight config (are trumped by)
136
- # 2. defaults for the particular search field identified by params[:search_field] (are trumped by)
137
- # 3. certain parameters directly on input HTTP query params
138
- # * not just any parameter is grabbed willy nilly, only certain ones are allowed by HTTP input)
139
- # * for legacy reasons, qt in http query does not over-ride qt in search field definition default.
140
- # 4. extra parameters passed in as argument.
141
- #
142
- # spellcheck.q will be supplied with the [:q] value unless specifically
143
- # specified otherwise.
144
- #
145
- # Incoming parameter :f is mapped to :fq solr parameter.
146
- #
147
- # @return a params hash for searching solr.
148
- def processed_parameters
149
- request.tap do |request_parameters|
150
- processor_chain.each do |method_name|
151
- send(method_name, request_parameters)
152
- end
153
- end
154
- end
155
-
156
- delegate :blacklight_config, to: :scope
157
-
158
58
  def start=(value)
159
59
  params_will_change!
160
60
  @start = value.to_i
@@ -209,34 +109,6 @@ module Blacklight
209
109
 
210
110
  alias per rows
211
111
 
212
- # sets the facet that this query pertains to, for the purpose of facet pagination
213
- def facet=(value)
214
- params_will_change!
215
- @facet = value
216
- end
217
-
218
- # @param [Object] value
219
- def facet(value = nil)
220
- if value
221
- self.facet = value
222
- return self
223
- end
224
- @facet
225
- end
226
-
227
- def facet_suggestion_query=(value)
228
- params_will_change!
229
- @facet_suggestion_query = value
230
- end
231
-
232
- def facet_suggestion_query(value = nil)
233
- if value
234
- self.facet_suggestion_query = value
235
- return self
236
- end
237
- @facet_suggestion_query
238
- end
239
-
240
112
  # Decode the user provided 'sort' parameter into a sort string that can be
241
113
  # passed to the search. This sanitizes the input by ensuring only
242
114
  # configured search values are passed through to the search.
@@ -244,35 +116,5 @@ module Blacklight
244
116
  def sort
245
117
  search_state.sort_field&.sort
246
118
  end
247
-
248
- delegate :search_field, to: :search_state
249
-
250
- private
251
-
252
- def request
253
- Blacklight::Solr::Request.new
254
- end
255
-
256
- def should_add_field_to_request? _field_name, field
257
- field.include_in_request || (field.include_in_request.nil? && blacklight_config.add_field_configuration_to_solr_request)
258
- end
259
-
260
- attr_reader :scope
261
-
262
- def params_will_change!
263
- @dirty = true
264
- end
265
-
266
- def params_changed?
267
- !!@dirty
268
- end
269
-
270
- def params_need_update?
271
- params_changed? || @params.nil?
272
- end
273
-
274
- def clear_changes
275
- @dirty = false
276
- end
277
119
  end
278
120
  end
@@ -120,8 +120,8 @@ module Blacklight
120
120
  delegate :any?, to: :values
121
121
 
122
122
  # Appease rubocop rules by implementing #each_value
123
- def each_value(except: [], &block)
124
- values(except: except).each(&block)
123
+ def each_value(except: [], &)
124
+ values(except: except).each(&)
125
125
  end
126
126
 
127
127
  # @param [String,#value] item a filter to remove from the url
@@ -89,16 +89,16 @@ module Blacklight
89
89
  end
90
90
  end
91
91
 
92
- class QueryBuilder
92
+ class QueryBuilder < Solr::AbstractFilterQueryBuilder
93
93
  # @return [Array] filter_query, subqueries
94
- def self.call(search_builder, filter, solr_parameters)
94
+ def call(filter, solr_parameters)
95
95
  existing = solr_parameters['fq']&.dup || []
96
96
  queries = []
97
97
  filter.values.compact_blank.each do |value|
98
- queries << search_builder.send(:facet_value_to_fq_string, filter.pivot.first, value.value)
98
+ queries << facet_value_to_fq_string(filter.pivot.first, value.value)
99
99
  value.fq.each do |entry|
100
100
  k, v = entry
101
- queries << search_builder.send(:facet_value_to_fq_string, k, v) if v
101
+ queries << facet_value_to_fq_string(k, v) if v
102
102
  end
103
103
  queries.uniq!
104
104
  end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight::Solr
4
+ class AbstractFilterQueryBuilder
5
+ def initialize(blacklight_config:)
6
+ @blacklight_config = blacklight_config
7
+ end
8
+
9
+ attr_reader :blacklight_config
10
+
11
+ private
12
+
13
+ def facet_inclusive_value_to_fq_string(facet_field, values)
14
+ return if values.blank?
15
+
16
+ return facet_value_to_fq_string(facet_field, values.first) if values.length == 1
17
+
18
+ facet_config = blacklight_config.facet_fields[facet_field]
19
+
20
+ local_params = []
21
+ local_params << "tag=#{facet_config.tag}" if facet_config&.tag
22
+
23
+ solr_filters = values.each_with_object({}).with_index do |(v, h), index|
24
+ h["f_inclusive.#{facet_field}.#{index}"] = facet_value_to_fq_string(facet_field, v, use_local_params: false)
25
+ end
26
+
27
+ filter_query = solr_filters.keys.map do |k|
28
+ "{!query v=$#{k}}"
29
+ end.join(' OR ')
30
+
31
+ ["{!lucene#{" #{local_params.join(' ')}" unless local_params.empty?}}#{filter_query}", solr_filters]
32
+ end
33
+
34
+ ##
35
+ # Convert a facet/value pair into a solr fq parameter
36
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
37
+ def facet_value_to_fq_string(facet_field, value, use_local_params: true)
38
+ facet_config = blacklight_config.facet_fields[facet_field]
39
+
40
+ solr_field = facet_config.field if facet_config && !facet_config.query
41
+ solr_field ||= facet_field
42
+
43
+ local_params = []
44
+ local_params << "tag=#{facet_config.tag}" if use_local_params && facet_config&.tag
45
+
46
+ if facet_config&.query
47
+ if facet_config.query[value]
48
+ facet_config.query[value][:fq]
49
+ else
50
+ # exclude all documents if the custom facet key specified was not found
51
+ '-*:*'
52
+ end
53
+ elsif value.is_a?(Range)
54
+ prefix = "{!#{local_params.join(' ')}}" unless local_params.empty?
55
+ start = value.begin || '*'
56
+ finish = value.end || '*'
57
+ "#{prefix}#{solr_field}:[#{start} TO #{finish}]"
58
+ elsif value == Blacklight::SearchState::FilterField::MISSING
59
+ "-#{solr_field}:[* TO *]"
60
+ else
61
+ "{!term f=#{solr_field}#{" #{local_params.join(' ')}" unless local_params.empty?}}#{convert_to_term_value(value)}"
62
+ end
63
+ end
64
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
65
+
66
+ def convert_to_term_value(value)
67
+ case value
68
+ when DateTime, Time
69
+ value.utc.strftime("%Y-%m-%dT%H:%M:%SZ")
70
+ when Date
71
+ value.to_time(:local).strftime("%Y-%m-%dT%H:%M:%SZ")
72
+ else
73
+ value.to_s
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight::Solr
4
+ class DefaultFilterQueryBuilder < AbstractFilterQueryBuilder
5
+ def call(filter, _solr_parameters)
6
+ filter_queries = []
7
+ all_subqueries = {}
8
+ filter.values.compact_blank.each do |value|
9
+ filter_query, subqueries = if value.is_a?(Array)
10
+ facet_inclusive_value_to_fq_string(filter.key, value.compact_blank)
11
+ else
12
+ facet_value_to_fq_string(filter.config.key, value)
13
+ end
14
+ filter_queries << filter_query
15
+ all_subqueries.merge!(subqueries) if subqueries
16
+ end
17
+ [filter_queries, all_subqueries]
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight::Solr
4
+ module FacetSearchBuilderBehavior
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ include Blacklight::Solr::SearchBuilderBehavior
9
+ self.default_processor_chain = [:default_solr_parameters,
10
+ :add_search_field_default_parameters,
11
+ :add_query_to_solr,
12
+ :add_facet_fq_to_solr,
13
+ :add_facetting_to_solr,
14
+ :add_solr_fields_to_query,
15
+ :add_additional_filters,
16
+ :add_facet_paging_to_solr,
17
+ :add_facet_suggestion_parameters]
18
+ end
19
+
20
+ def add_facet_paging_to_solr(solr_params)
21
+ return if facet.blank?
22
+
23
+ facet_config = blacklight_config.facet_fields[facet]
24
+
25
+ solr_params[:rows] = 0
26
+
27
+ limit = if solr_params["facet.limit"]
28
+ solr_params["facet.limit"].to_i
29
+ else
30
+ facet_config.fetch(:more_limit, blacklight_config.default_more_limit)
31
+ end
32
+
33
+ page = search_state.facet_page
34
+ sort = search_state.facet_sort
35
+ prefix = search_state.facet_prefix
36
+ offset = (page - 1) * limit
37
+
38
+ if facet_config.json
39
+ add_solr_facet_json_params(solr_parameters, facet, facet_config, limit: limit + 1, offset: offset, sort: sort, prefix: prefix)
40
+ return
41
+ end
42
+
43
+ # Now override with our specific things for fetching facet values
44
+ facet_ex = facet_config.respond_to?(:ex) ? facet_config.ex : nil
45
+ solr_params[:'facet.field'] = with_ex_local_param(facet_ex, facet_config.field)
46
+
47
+ # Need to set as f.facet_field.facet.* to make sure we
48
+ # override any field-specific default in the solr request handler.
49
+ solr_params[:"f.#{facet_config.field}.facet.limit"] = limit + 1
50
+ solr_params[:"f.#{facet_config.field}.facet.offset"] = offset
51
+ solr_params[:"f.#{facet_config.field}.facet.sort"] = sort if sort
52
+ solr_params[:"f.#{facet_config.field}.facet.prefix"] = prefix if prefix
53
+ end
54
+
55
+ def add_facet_suggestion_parameters(solr_params)
56
+ return if facet.blank? || facet_suggestion_query.blank?
57
+
58
+ solr_params[:'facet.contains'] = facet_suggestion_query[0..50]
59
+ solr_params[:'facet.contains.ignoreCase'] = true
60
+ end
61
+ end
62
+ end
@@ -8,7 +8,6 @@ module Blacklight::Solr
8
8
  # @param [Hash] params additional solr query parameters
9
9
  def find id, params = {}
10
10
  doc_params = params.reverse_merge(blacklight_config.default_document_solr_params)
11
- .reverse_merge(qt: blacklight_config.document_solr_request_handler)
12
11
  .merge(blacklight_config.document_unique_id_param => id)
13
12
 
14
13
  solr_response = send_and_receive blacklight_config.document_solr_path || blacklight_config.solr_path, doc_params
@@ -27,7 +26,11 @@ module Blacklight::Solr
27
26
  # Execute a search query against solr
28
27
  # @param [Hash] params solr query parameters
29
28
  # @param [String] path solr request handler path
30
- def search pos_params = {}, path: nil, params: nil, **kwargs
29
+ def search pos_params = nil, path: nil, params: nil, **kwargs
30
+ if pos_params
31
+ Blacklight.deprecation.warn("Passing positional arguments to search() is deprecated. Use the params kwarg instead.")
32
+ end
33
+
31
34
  request_params = (params || pos_params).reverse_merge(kwargs).reverse_merge({ qt: blacklight_config.qt })
32
35
 
33
36
  send_and_receive(path || default_search_path(request_params), request_params)
@@ -56,15 +59,11 @@ module Blacklight::Solr
56
59
  end
57
60
 
58
61
  ##
59
- # Execute a solr query
62
+ # Execute a solr query at the given path with the parameters
60
63
  # TODO: Make this private after we have a way to abstract admin/luke and ping
61
64
  # @see [RSolr::Client#send_and_receive]
62
- # @overload find(solr_path, params)
63
- # Execute a solr query at the given path with the parameters
64
- # @param [String] solr path (defaults to blacklight_config.solr_path)
65
- # @param [Hash] parameters for RSolr::Client#send_and_receive
66
- # @overload find(params)
67
- # @param [Hash] parameters for RSolr::Client#send_and_receive
65
+ # @param [String] path solr path (defaults to blacklight_config.solr_path)
66
+ # @param [Hash, Blacklight::SearchBuilder] solr_params parameters for RSolr::Client#send_and_receive
68
67
  # @return [Blacklight::Solr::Response] the solr response object
69
68
  def send_and_receive(path, solr_params = {})
70
69
  benchmark("Solr fetch", level: :debug) do
@@ -3,12 +3,6 @@
3
3
  class Blacklight::Solr::InvalidParameter < ArgumentError; end
4
4
 
5
5
  class Blacklight::Solr::Request < ActiveSupport::HashWithIndifferentAccess
6
- # @deprecated
7
- SINGULAR_KEYS = %w(facet fl q qt rows start spellcheck spellcheck.q sort per_page wt hl group defType)
8
-
9
- # @deprecated
10
- ARRAY_KEYS = %w(facet.field facet.query facet.pivot fq hl.fl)
11
-
12
6
  def initialize(constructor = {})
13
7
  if constructor.is_a?(Hash)
14
8
  super()
@@ -42,7 +36,7 @@ class Blacklight::Solr::Request < ActiveSupport::HashWithIndifferentAccess
42
36
  self[:json][:query] ||= { bool: { bool_operator => [] } }
43
37
  self[:json][:query][:bool][bool_operator] ||= []
44
38
 
45
- if self['q']
39
+ if self['q'].present?
46
40
  self[:json][:query][:bool][:must] ||= []
47
41
  self[:json][:query][:bool][:must] << self['q']
48
42
  delete 'q'
@@ -229,7 +229,7 @@ module Blacklight::Solr::Response::Facets
229
229
 
230
230
  blacklight_config.facet_fields.select { |_k, v| v.query }.each_with_object({}) do |(field_name, facet_field), hash|
231
231
  salient_facet_queries = facet_field.query.map { |_k, x| x[:fq] }
232
- items = facet_queries.select { |k, _v| salient_facet_queries.include?(k) }.reject { |_value, hits| hits.zero? }.map do |value, hits|
232
+ items = facet_queries.slice(*salient_facet_queries).reject { |_value, hits| hits.zero? }.map do |value, hits|
233
233
  salient_fields = facet_field.query.select { |_key, val| val[:fq] == value }
234
234
  key = ((salient_fields.keys if salient_fields.respond_to? :keys) || salient_fields.first).first
235
235
  Blacklight::Solr::Response::Facets::FacetItem.new(value: key, hits: hits, label: facet_field.query[key][:label])
@@ -250,7 +250,7 @@ module Blacklight::Solr::Response::Facets
250
250
 
251
251
  salient_facet_queries = facet_field.query.map { |_k, x| x[:fq] }
252
252
 
253
- relevant_facet_data = self['facets'].select { |k, _v| salient_facet_queries.include?(k) }.reject { |_key, data| data['count'].zero? }
253
+ relevant_facet_data = self['facets'].slice(*salient_facet_queries).reject { |_key, data| data['count'].zero? }
254
254
 
255
255
  relevant_facet_data.map do |key, data|
256
256
  salient_fields = facet_field.query.select { |_key, val| val[:fq] == key }
@@ -51,9 +51,9 @@ class Blacklight::Solr::Response::GroupResponse
51
51
  )
52
52
  end
53
53
 
54
- def method_missing meth, *args, &block
54
+ def method_missing(meth, *args, &)
55
55
  if response.respond_to? meth
56
- response.send(meth, *args, &block)
56
+ response.send(meth, *args, &)
57
57
  else
58
58
  super
59
59
  end
@@ -52,10 +52,6 @@ module Blacklight::Solr::Response::Params
52
52
 
53
53
  private
54
54
 
55
- def search_builder
56
- request_params if request_params.is_a?(Blacklight::SearchBuilder)
57
- end
58
-
59
55
  # Extract JSON Request API parameters from the response header or the request itself
60
56
  def json_params
61
57
  encoded_json_params = header&.dig('params', 'json')
@@ -8,12 +8,16 @@ class Blacklight::Solr::Response < ActiveSupport::HashWithIndifferentAccess
8
8
  include MoreLikeThis
9
9
  include Params
10
10
 
11
- attr_reader :request_params
11
+ attr_reader :request_params, :search_builder
12
12
  attr_accessor :blacklight_config, :options
13
13
 
14
14
  delegate :document_factory, to: :blacklight_config
15
15
 
16
+ # @param [Hash] data
17
+ # @param [Hash, Blacklight::SearchBuilder] request_params a SearchBuilder or a Hash of parameters
16
18
  def initialize(data, request_params, options = {})
19
+ @search_builder = request_params if request_params.is_a?(Blacklight::SearchBuilder)
20
+
17
21
  super(force_to_utf8(ActiveSupport::HashWithIndifferentAccess.new(data)))
18
22
  @request_params = ActiveSupport::HashWithIndifferentAccess.new(request_params)
19
23
  self.blacklight_config = options[:blacklight_config]