• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pulibrary / orangelight / 00dbc10b-d747-4ad7-b211-7b26d753abbb

14 Aug 2025 01:25PM UTC coverage: 0.483% (-94.9%) from 95.343%
00dbc10b-d747-4ad7-b211-7b26d753abbb

push

circleci

web-flow
Merge pull request #5181 from pulibrary/dependabot/bundler/activestorage-7.2.2.2

Bump activestorage from 7.2.2.1 to 7.2.2.2

47 of 9721 relevant lines covered (0.48%)

0.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/app/models/search_builder.rb
1
# frozen_string_literal: true
2

3
class SearchBuilder < Blacklight::SearchBuilder
×
4
  include Blacklight::Solr::SearchBuilderBehavior
×
5
  include BlacklightRangeLimit::RangeLimitBuilder
×
6
  include BlacklightHelper
×
7

8
  default_processor_chain.unshift(:conditionally_configure_json_query_dsl)
×
9

10
  self.default_processor_chain += %i[parslet_trick cleanup_boolean_operators
×
11
                                     cjk_mm wildcard_char_strip
×
12
                                     only_home_facets prepare_left_anchor_search
×
13
                                     series_title_results pul_holdings html_facets
×
14
                                     numismatics_advanced
×
15
                                     adjust_mm remove_unneeded_facets]
×
16

17
  # mutate the solr_parameters to remove words that are
18
  # boolean operators, but not intended as such.
19
  def cleanup_boolean_operators(solr_parameters)
×
20
    transform_queries!(solr_parameters) { |query| cleaned_query(query) }
×
21
  end
×
22

23
  # Blacklight uses Parslet https://rubygems.org/gems/parslet/versions/2.0.0 to parse the user query
24
  # and unfortunately Parslet gets confused when the user's query ends with "()". Here we tweak the
25
  # query to prevent the error and let the query to be parsed as if the ending "()" was not present.
26
  # Notice that we must update the value in `blacklight_params[:q]`
27
  def parslet_trick(_solr_parameters)
×
28
    return unless blacklight_params[:q].is_a?(String)
×
29
    return unless blacklight_params[:q].strip.end_with?("()")
×
30
    blacklight_params[:q] = blacklight_params[:q].strip.gsub("()", "")
×
31
  end
×
32

33
  # Only search for coin records when querying with the numismatics advanced search
34
  def numismatics_advanced(solr_parameters)
×
35
    return unless blacklight_params[:advanced_type] == 'numismatics'
×
36
    solr_parameters[:fq] ||= []
×
37
    solr_parameters[:fq] << "format:Coin"
×
38
  end
×
39

40
  def only_home_facets(solr_parameters)
×
41
    return if search_parameters? || advanced_search?
×
42
    solr_parameters['facet.field'] = blacklight_config.facet_fields.select { |_, v| v[:home] }.keys
×
43
    solr_parameters['facet.pivot'] = []
×
44
  end
×
45

46
  ##
47
  # Check if we are on an advanced search page
48
  # @return [Boolean]
49
  def advanced_search?
×
50
    blacklight_params[:advanced_type] == 'advanced' ||
×
51
      search_state.controller.try(:params).try(:[], :action) == 'advanced_search' ||
×
52
      blacklight_params[:advanced_type] == 'numismatics' ||
×
53
      # The next two are required for the advanced search gem
54
      blacklight_params[:search_field] == 'advanced' ||
×
55
      blacklight_params[:action] == 'numismatics'
×
56
  end
×
57

58
  ##
59
  # Check if any search parameters have been set
60
  # @return [Boolean]
61
  def search_parameters?
×
62
    search_query_present? || facet_query_present?
×
63
  end
×
64

65
  def conditionally_configure_json_query_dsl(_solr_parameters)
×
66
    advanced_fields = %w[all_fields title author subject left_anchor publisher in_series notes series_title isbn issn]
×
67
    add_edismax(advanced_fields:)
×
68
  end
×
69

70
  def adjust_mm(solr_parameters)
×
71
    # If the user is attempting a boolean OR query,
72
    # for example: activism OR "social justice"
73
    # don't want to cancel out the boolean OR with
74
    # an mm configuration that requires all the clauses
75
    # to be in the document
76
    return unless includes_written_boolean?
×
77
    solr_parameters['mm'] = 0
×
78
  end
×
79

80
  def includes_written_boolean?
×
81
    if advanced_search? && search_query_present?
×
82
      json_query_dsl_clauses&.any? { |clause| clause&.dig('query')&.include?('OR') }
×
83
    else
×
84
      blacklight_params[:q].to_s.split.include? 'OR'
×
85
    end
×
86
  end
×
87

88
  # When the user is viewing the values of a specific facet
89
  # by clicking the "more" link in a facet, solr doesn't
90
  # need to perform expensive calculations related to other
91
  # facets that the user is not displaying
92
  # :reek:FeatureEnvy
93
  def remove_unneeded_facets(solr_parameters)
×
94
    return unless facet
×
95
    remove_unneeded_stats(solr_parameters)
×
96
    solr_parameters.delete('facet.pivot') unless solr_parameters['facet.pivot']&.split(',')&.include? facet
×
97
    solr_parameters.delete('facet.query') unless solr_parameters['facet.query']&.any? { |query| query.partition(':').first == facet }
×
98
  end
×
99

100
  def wildcard_char_strip(solr_parameters)
×
101
    transform_queries!(solr_parameters) { |query| query.delete('?') }
×
102
  end
×
103

104
  private
×
105

106
    def search_query_present?
×
107
      !blacklight_params[:q].nil? || json_query_dsl_clauses&.any? { |clause| clause.dig('query')&.present? }
×
108
    end
×
109

110
    def facet_query_present?
×
111
      blacklight_params[:f].present? || blacklight_params[:action] == 'facet'
×
112
    end
×
113

114
    def json_query_dsl_clauses
×
115
      blacklight_params.dig('clause')&.values
×
116
    end
×
117

118
    def add_edismax(advanced_fields:)
×
119
      advanced_fields.each do |field|
×
120
        solr_params = blacklight_config.search_fields[field]['solr_parameters']
×
121
        edismax = solr_params.present? ? solr_params.dup : {}
×
122
        blacklight_config.search_fields[field]['clause_params'] = { edismax: }
×
123
      end
×
124
    end
×
125

126
    # :reek:FeatureEnvy
127
    def remove_unneeded_stats(solr_parameters)
×
128
      return if solr_parameters['stats.field'].to_a.include? facet
×
129
      solr_parameters.delete('stats')
×
130
      solr_parameters.delete('stats.field')
×
131
    end
×
132

133
    # :reek:DuplicateMethodCall
134
    # :reek:MissingSafeMethod
135
    # :reek:UtilityFunction
136
    def transform_queries!(solr_parameters)
×
137
      solr_parameters[:q] = yield solr_parameters[:q] if solr_parameters[:q]
×
138
      solr_parameters.dig('json', 'query', 'bool', 'must')&.map! do |search_element|
×
139
        search_element[:edismax][:query] = yield search_element[:edismax][:query]
×
140
        search_element
×
141
      end
×
142
    end
×
143

144
    def cleaned_query(query)
×
145
      return query if query.nil?
×
146
      query.gsub(/([A-Z]) (NOT|OR|AND) ([A-Z])/) do
×
147
        "#{Regexp.last_match(1)} #{Regexp.last_match(2).downcase} #{Regexp.last_match(3)}"
×
148
      end
×
149
    end
×
150
end
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc