Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions app/models/range_limit_search_builder.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Used for building the search for the range_limit route
# You may completely override this class in the host application if you want to customize the search behavior.
class RangeLimitSearchBuilder < SearchBuilder
include BlacklightRangeLimit::RangeLimitSearchBuilderBehavior
end
1 change: 1 addition & 0 deletions lib/blacklight_range_limit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module BlacklightRangeLimit
require 'blacklight_range_limit/facet_field_config_override'
require 'blacklight_range_limit/range_limit_builder'
require 'blacklight_range_limit/controller_override'
require 'blacklight_range_limit/range_limit_search_builder_behavior'

require 'blacklight_range_limit/version'
require 'blacklight_range_limit/engine'
Expand Down
27 changes: 15 additions & 12 deletions lib/blacklight_range_limit/controller_override.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module BlacklightRangeLimit
module ControllerOverride
extend ActiveSupport::Concern

RANGE_LIMIT_FIELDS = [:range_end, :range_field, :range_start].freeze
RANGE_LIMIT_FIELDS = %i[range_end range_field range_start].freeze

included do
# have to do this in before_action so it's done before any application level
Expand All @@ -22,19 +22,14 @@ def range_limit
@facet = blacklight_config.facet_fields[params[:range_field]]
raise ActionController::RoutingError, 'Not Found' unless @facet&.range

# We need to swap out the add_range_limit_params search param filter,
# and instead add in our fetch_specific_range_limit filter,
# to fetch only the range limit segments for only specific
# field (with start/end params) mentioned in query params
# range_field, range_start, and range_end
@response, = range_limit_search_service.search_results

@response, _ = search_service.search_results do |search_builder|
search_builder.except(:add_range_limit_params).append(:fetch_specific_range_limit)
end

display_facet = @response.aggregations[@facet.field] || Blacklight::Solr::Response::Facets::FacetField.new(@facet.key, [], response: @response)
display_facet = @response.aggregations[@facet.field] || Blacklight::Solr::Response::Facets::FacetField.new(
@facet.key, [], response: @response
)

@presenter = (@facet.presenter || BlacklightRangeLimit::FacetFieldPresenter).new(@facet, display_facet, view_context)
@presenter = (@facet.presenter || BlacklightRangeLimit::FacetFieldPresenter).new(@facet, display_facet,
view_context)

render BlacklightRangeLimit::RangeSegmentsComponent.new(facet_field: @presenter), layout: !request.xhr?
end
Expand All @@ -47,6 +42,14 @@ def _range_limit_add_search_state_fields
blacklight_config.search_state_fields.concat(missing_keys)
end

# @return [Blacklight::SearchService]
def range_limit_search_service
search_service_class.new(config: blacklight_config,
search_state: search_state,
search_builder_class: RangeLimitSearchBuilder,
**search_service_context)
end

class_methods do
def default_range_config
BlacklightRangeLimit.default_range_config
Expand Down
79 changes: 23 additions & 56 deletions lib/blacklight_range_limit/range_limit_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ def add_range_limit_params(solr_params)
ranged_facet_configs = blacklight_config.facet_fields.select { |_key, config| config.range }
return solr_params unless ranged_facet_configs.any?

solr_params["stats"] = "true"
solr_params["stats.field"] ||= []
solr_params['stats'] = 'true'
solr_params['stats.field'] ||= []

ranged_facet_configs.each do |field_key, config|
solr_params["stats.field"] << config.field
solr_params['stats.field'] << config.field

range_config = config.range_config
next unless range_config[:chart_js] || range_config[:textual_facets]
Expand All @@ -29,55 +29,20 @@ def add_range_limit_params(solr_params)
range = bl_create_selected_range_value(selected_value, config)

# If we have both ends of a range
add_range_segments_to_solr!(solr_params, field_key, range.begin, range.end) if range && range.count != Float::INFINITY
if range && range.count != Float::INFINITY
add_range_segments_to_solr!(solr_params, field_key, range.begin, range.end)
end
end

solr_params
end


# Another processing method, this one is NOT included in default processing chain,
# it is specifically swapped in *instead of* add_range_limit_params for
# certain ajax requests that only want to fetch range limit segments for
# ONE field.
#
# It turns off facetting and sets rows to 0 as well, only results for
# single specified field are needed.
#
# Specified field and parameters are specified in incoming parameters
# range_field, range_start, range_end
def fetch_specific_range_limit(solr_params)
field_key = blacklight_params[:range_field] # what field to fetch for

unless blacklight_params[:range_start].present? && blacklight_params[:range_start].kind_of?(String) &&
blacklight_params[:range_end].present? && blacklight_params[:range_end].kind_of?(String)
raise BlacklightRangeLimit::InvalidRange
end

start = blacklight_params[:range_start].to_i
finish = blacklight_params[:range_end].to_i

add_range_segments_to_solr!(solr_params, field_key, start, finish )

# Remove all field faceting for efficiency, we won't be using it.
solr_params.delete("facet.field")
solr_params.delete("facet.field".to_sym)

# We don't need any actual rows either
solr_params[:rows] = 0

return solr_params
rescue BlacklightRangeLimit::InvalidRange
# This will make Rails return a 400
raise ActionController::BadRequest, "invalid range_start (#{blacklight_params[:range_start]}) or range_end (#{blacklight_params[:range_end]})"
end

# hacky polyfill for new Blacklight behavior we need, if we don't have it yet
#
# https://github.com/projectblacklight/blacklight/pull/3213
# https://github.com/projectblacklight/blacklight/pull/3443
bl_version = Gem.loaded_specs["blacklight"]&.version
if bl_version && (bl_version <= Gem::Version.new("8.6.1"))
bl_version = Gem.loaded_specs['blacklight']&.version
if bl_version && (bl_version <= Gem::Version.new('8.6.1'))
def facet_value_to_fq_string(facet_field, value, use_local_params: true)
facet_config = blacklight_config.facet_fields[facet_field]

Expand All @@ -94,7 +59,7 @@ def facet_value_to_fq_string(facet_field, value, use_local_params: true)

prefix = "{!#{local_params.join(' ')}}" unless local_params.empty?

"#{prefix}#{solr_field}:[#{value.begin || "*"} TO #{value.end || "*"}]"
"#{prefix}#{solr_field}:[#{value.begin || '*'} TO #{value.end || '*'}]"
else
super
end
Expand All @@ -108,23 +73,25 @@ def bl_create_selected_range_value(selected_value, field_config)
range_config = field_config.range_config

range = if selected_value.is_a? Range
selected_value
elsif range_config[:assumed_boundaries].is_a?(Range)
range_config[:assumed_boundaries]
elsif range_config[:assumed_boundaries] # Array of two things please
Range.new(*range_config[:assumed_boundaries])
else
nil
end
selected_value
elsif range_config[:assumed_boundaries].is_a?(Range)
range_config[:assumed_boundaries]
elsif range_config[:assumed_boundaries] # Array of two things please
Range.new(*range_config[:assumed_boundaries])
else
nil
end

# clamp between config'd min and max
min = range_config[:min_value]
max = range_config[:max_value]

range = Range.new(
(range.begin.clamp(min, max) if range.begin),
(range.end.clamp(min, max) if range.end),
) if range
if range
range = Range.new(
(range.begin.clamp(min, max) if range.begin),
(range.end.clamp(min, max) if range.end)
)
end

range
end
Expand Down
53 changes: 53 additions & 0 deletions lib/blacklight_range_limit/range_limit_search_builder_behavior.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Used for building the search for the range_limit route
module BlacklightRangeLimit
module RangeLimitSearchBuilderBehavior
extend ActiveSupport::Concern

included do
# We need to swap out the add_range_limit_params search param filter,
# and instead add in our fetch_specific_range_limit filter,
# to fetch only the range limit segments for only specific
# field (with start/end params) mentioned in query params
# range_field, range_start, and range_end
self.default_processor_chain += %i[fetch_specific_range_limit]
self.default_processor_chain -= %i[add_range_limit_params]
end

# Another processing method, this one is NOT included in default processing chain,
# it is specifically swapped in *instead of* add_range_limit_params for
# certain ajax requests that only want to fetch range limit segments for
# ONE field.
#
# It turns off facetting and sets rows to 0 as well, only results for
# single specified field are needed.
#
# Specified field and parameters are specified in incoming parameters
# range_field, range_start, range_end
def fetch_specific_range_limit(solr_params)
field_key = blacklight_params[:range_field] # what field to fetch for

unless blacklight_params[:range_start].present? && blacklight_params[:range_start].is_a?(String) &&
blacklight_params[:range_end].present? && blacklight_params[:range_end].is_a?(String)
raise BlacklightRangeLimit::InvalidRange
end

start = blacklight_params[:range_start].to_i
finish = blacklight_params[:range_end].to_i

add_range_segments_to_solr!(solr_params, field_key, start, finish)

# Remove all field faceting for efficiency, we won't be using it.
solr_params.delete('facet.field')
solr_params.delete('facet.field'.to_sym)

# We don't need any actual rows either
solr_params[:rows] = 0

solr_params
rescue BlacklightRangeLimit::InvalidRange
# This will make Rails return a 400
raise ActionController::BadRequest,
"invalid range_start (#{blacklight_params[:range_start]}) or range_end (#{blacklight_params[:range_end]})"
end
end
end