Class: Blacklight::SearchState::FilterField

Inherits:
Object
  • Object
show all
Defined in:
lib/blacklight/search_state/filter_field.rb

Overview

Modeling access to filter query parameters

Constant Summary collapse

MISSING =
{ missing: true }.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config, search_state) ⇒ FilterField

Returns a new instance of FilterField.



30
31
32
33
34
35
# File 'lib/blacklight/search_state/filter_field.rb', line 30

def initialize(config, search_state)
  @config = config
  @search_state = search_state
  @filters_key = :f
  @inclusive_filters_key = :f_inclusive
end

Instance Attribute Details

#configObject

Returns the value of attribute config.



11
12
13
# File 'lib/blacklight/search_state/filter_field.rb', line 11

def config
  @config
end

#filters_keyObject (readonly)

Returns the value of attribute filters_key.



19
20
21
# File 'lib/blacklight/search_state/filter_field.rb', line 19

def filters_key
  @filters_key
end

#inclusive_filters_keyObject (readonly)

Returns the value of attribute inclusive_filters_key.



23
24
25
# File 'lib/blacklight/search_state/filter_field.rb', line 23

def inclusive_filters_key
  @inclusive_filters_key
end

#inclusive_paramString, Symbol

Returns:

  • (String, Symbol)


23
# File 'lib/blacklight/search_state/filter_field.rb', line 23

attr_reader :inclusive_filters_key

#paramString, Symbol

Returns:

  • (String, Symbol)


19
# File 'lib/blacklight/search_state/filter_field.rb', line 19

attr_reader :filters_key

#search_stateObject

Returns the value of attribute search_state.



15
16
17
# File 'lib/blacklight/search_state/filter_field.rb', line 15

def search_state
  @search_state
end

Instance Method Details

#add(item) ⇒ Blacklight::SearchState

Returns new state.

Parameters:

  • item (String, #value)

    a filter item to add to the url

Returns:



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
# File 'lib/blacklight/search_state/filter_field.rb', line 39

def add(item)
  new_state = search_state.reset_search

  if item.try(:missing)
    # if this is a 'missing' facet value, the :fq is only for backwards compatibility
  elsif item.respond_to?(:fq)
    Array(item.fq).each do |f, v|
      new_state = new_state.filter(f).add(v)
    end
  end

  if item.respond_to?(:field) && item.field != key
    return new_state.filter(item.field).add(item)
  end

  url_key = key
  params = new_state.params
  param = filters_key
  value = as_url_parameter(item)

  if value == Blacklight::SearchState::FilterField::MISSING
    url_key = "-#{key}"
    value = Blacklight::Engine.config.blacklight.facet_missing_param
  end

  param = inclusive_filters_key if value.is_a?(Array)

  # value could be a string
  params[param] = (params[param] || {}).dup

  if value.is_a? Array
    params[param][url_key] = value
  elsif config.single
    params[param][url_key] = [value]
  else
    params[param][url_key] = Array(params[param][url_key] || []).dup
    params[param][url_key].push(value)
  end

  new_state.reset(params)
end

#each_value(except: [], &block) ⇒ Object

Appease rubocop rules by implementing #each_value



139
140
141
# File 'lib/blacklight/search_state/filter_field.rb', line 139

def each_value(except: [], &block)
  values(except: except).each(&block)
end

#include?(item) ⇒ Boolean

Returns whether the provided filter is currently applied/selected.

Parameters:

  • item (String, #value)

    a filter to remove from the url

Returns:

  • (Boolean)

    whether the provided filter is currently applied/selected



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/blacklight/search_state/filter_field.rb', line 145

def include?(item)
  if item.respond_to?(:field) && item.field != key
    return search_state.filter(item.field).selected?(item)
  end

  value = as_url_parameter(item)
  params = search_state.params

  if value.is_a?(Array)
    (params.dig(inclusive_filters_key, key) || []).to_set == value.to_set
  elsif value == Blacklight::SearchState::FilterField::MISSING
    (params.dig(filters_key, "-#{key}") || []).include?(Blacklight::Engine.config.blacklight.facet_missing_param)
  else
    (params.dig(filters_key, key) || []).include?(value)
  end
end

#keyString, Symbol

Returns:

  • (String, Symbol)


26
# File 'lib/blacklight/search_state/filter_field.rb', line 26

delegate :key, to: :config

#permitted_paramsObject



162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/blacklight/search_state/filter_field.rb', line 162

def permitted_params
  if config.pivot
    {
      filters_key => config.pivot.each_with_object({}) { |key, filter| filter.merge(key => [], "-#{key}" => []) },
      inclusive_filters_key => config.pivot.each_with_object({}) { |key, filter| filter.merge(key => []) }
    }
  else
    {
      filters_key => { config.key => [], "-#{config.key}" => [] },
      inclusive_filters_key => { config.key => [] }
    }
  end
end

#remove(item) ⇒ Blacklight::SearchState

Returns new state.

Parameters:

  • item (String, #value)

    a filter to remove from the url

Returns:



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
# File 'lib/blacklight/search_state/filter_field.rb', line 83

def remove(item)
  new_state = search_state.reset_search
  if item.respond_to?(:field) && item.field != key
    return new_state.filter(item.field).remove(item)
  end

  url_key = config.key
  params = new_state.params

  param = filters_key
  value = as_url_parameter(item)

  if value == Blacklight::SearchState::FilterField::MISSING
    url_key = "-#{key}"
    value = Blacklight::Engine.config.blacklight.facet_missing_param
  end

  param = inclusive_filters_key if value.is_a?(Array)

  # need to dup the facet values too,
  # if the values aren't dup'd, then the values
  # from the session will get remove in the show view...
  params[param] = (params[param] || {}).dup
  params[param][url_key] = (params[param][url_key] || []).dup

  collection = params[param][url_key]
  # collection should be an array, because we link to ?f[key][]=value,
  # however, Facebook (and maybe some other PHP tools) tranform that parameters
  # into ?f[key][0]=value, which Rails interprets as a Hash.
  if collection.is_a? Hash
    Deprecation.warn(self, 'Normalizing parameters in FilterField#remove is deprecated')
    collection = collection.values
  end

  params[param][url_key] = collection - Array(value)
  params[param].delete(url_key) if params[param][url_key].empty?
  params.delete(param) if params[param].empty?

  new_state.reset(params)
end

#values(except: []) ⇒ Array

Returns an array of applied filters.

Returns:

  • (Array)

    an array of applied filters



125
126
127
128
129
130
131
132
133
134
135
# File 'lib/blacklight/search_state/filter_field.rb', line 125

def values(except: [])
  params = search_state.params
  return [] if params.blank?

  f = except.include?(:filters) ? [] : [params.dig(filters_key, key)].flatten.compact
  f_inclusive = [params.dig(:f_inclusive, key)] unless params.dig(inclusive_filters_key, key).blank? || except.include?(:inclusive_filters)
  f_missing = [Blacklight::SearchState::FilterField::MISSING] if params.dig(filters_key, "-#{key}")&.any? { |v| v == Blacklight::Engine.config.blacklight.facet_missing_param }
  f_missing = [] if except.include?(:missing)

  f + (f_inclusive || []) + (f_missing || [])
end