blacklight 3.6.1.1 → 3.7.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.
- data/VERSION +1 -1
- data/app/controllers/bookmarks_controller.rb +28 -46
- data/app/helpers/blacklight/blacklight_helper_behavior.rb +4 -11
- data/app/helpers/blacklight/facets_helper_behavior.rb +57 -4
- data/app/helpers/blacklight/render_constraints_helper_behavior.rb +4 -1
- data/app/helpers/blacklight/search_history_constraints_helper_behavior.rb +5 -3
- data/app/views/_user_util_links.html.erb +8 -7
- data/app/views/bookmarks/index.html.erb +1 -1
- data/app/views/catalog/_bookmark_control.html.erb +2 -2
- data/lib/blacklight/configuration.rb +14 -1
- data/lib/blacklight/configuration/facet_field.rb +14 -0
- data/lib/blacklight/controller.rb +44 -7
- data/lib/blacklight/routes.rb +1 -10
- data/lib/blacklight/solr_helper.rb +60 -17
- data/lib/generators/blacklight/blacklight_generator.rb +1 -0
- data/lib/generators/blacklight/templates/catalog_controller.rb +11 -6
- data/test_support/bin/test.sh +1 -0
- data/test_support/features/bookmarks.feature +9 -19
- data/test_support/spec/controllers/application_controller_spec.rb +1 -0
- data/test_support/spec/controllers/bookmarks_controller_spec.rb +48 -0
- data/test_support/spec/controllers/catalog_controller_spec.rb +2 -1
- data/test_support/spec/controllers/search_history_controller_spec.rb +2 -0
- data/test_support/spec/helpers/blacklight_helper_spec.rb +1 -2
- data/test_support/spec/helpers/facets_helper_spec.rb +91 -4
- data/test_support/spec/helpers/search_history_constraints_helper_spec.rb +3 -0
- data/test_support/spec/lib/solr_helper_spec.rb +56 -8
- metadata +6 -9
- data/app/controllers/folder_controller.rb +0 -54
- data/app/views/catalog/_folder_control.html.erb +0 -12
- data/test_support/features/folder.feature +0 -67
- data/test_support/features/step_definitions/folder_steps.rb +0 -27
- data/test_support/spec/controllers/folder_controller_spec.rb +0 -47
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.7.0
|
@@ -3,40 +3,14 @@
|
|
3
3
|
# take the Solr document ID as the :id, NOT the id of the actual Bookmark action.
|
4
4
|
class BookmarksController < ApplicationController
|
5
5
|
|
6
|
-
before_filter :require_user_authentication_provider
|
7
6
|
before_filter :verify_user
|
8
|
-
|
9
|
-
# Beware, :id is the Solr document_id, not the actual Bookmark id.
|
10
|
-
# idempotent, as PUT is supposed to be.
|
11
|
-
# you can also send a bookmark[title] param, which will be used for simplest case
|
12
|
-
# or fall through display of Bookmark in list.
|
13
|
-
def update
|
14
|
-
bookmark = current_user.existing_bookmark_for(params[:id])
|
15
|
-
if bookmark
|
16
|
-
#update existing one with new values if present
|
17
|
-
bookmark.attributes = params[:bookmark] if params[:bookmark]
|
18
|
-
else
|
19
|
-
# create new one with values and document_id
|
20
|
-
bookmark = current_user.bookmarks.build(params[:bookmark].merge(:document_id => params[:id]))
|
21
|
-
end
|
22
|
-
|
23
|
-
success = bookmark.save
|
24
|
-
|
25
|
-
unless request.xhr?
|
26
|
-
if success
|
27
|
-
flash[:notice] = I18n.t('blacklight.bookmarks.add.success')
|
28
|
-
else
|
29
|
-
flash[:error] = I18n.t('blacklight.bookmarks.add.failure')
|
30
|
-
end
|
31
|
-
redirect_to :back
|
32
|
-
else
|
33
|
-
#ajaxy request doesn't need a redirect and shouldn't have flash set
|
34
|
-
render :text => "", :status => (success ? "200" : "500" )
|
35
|
-
end
|
36
|
-
end
|
37
7
|
|
38
8
|
def index
|
39
|
-
@bookmarks =
|
9
|
+
@bookmarks = current_or_guest_user.bookmarks.page(params[:page])
|
10
|
+
end
|
11
|
+
|
12
|
+
def update
|
13
|
+
create
|
40
14
|
end
|
41
15
|
|
42
16
|
# For adding a single bookmark, suggest use PUT/#update to
|
@@ -49,27 +23,35 @@ class BookmarksController < ApplicationController
|
|
49
23
|
# is simpler.
|
50
24
|
def create
|
51
25
|
@bookmarks = params[:bookmarks] || []
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
26
|
+
|
27
|
+
if params[:bookmark]
|
28
|
+
params[:bookmark][:document_id] ||= params[:id]
|
29
|
+
@bookmarks << params[:bookmark] if params[:bookmark]
|
30
|
+
end
|
31
|
+
|
32
|
+
success = @bookmarks.all? do |bookmark|
|
33
|
+
current_or_guest_user.bookmarks.create(bookmark) unless current_or_guest_user.existing_bookmark_for(bookmark[:document_id])
|
57
34
|
end
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
35
|
+
|
36
|
+
if request.xhr?
|
37
|
+
render :text => "", :status => (success ? "200" : "500" )
|
38
|
+
else
|
39
|
+
if @bookmarks.length > 0 && success
|
40
|
+
flash[:notice] = I18n.t('blacklight.bookmarks.add.success', :count => @bookmarks.length)
|
41
|
+
elsif @bookmarks.length > 0
|
42
|
+
flash[:error] = I18n.t('blacklight.bookmarks.add.failure', :count => @bookmarks.length)
|
43
|
+
end
|
44
|
+
|
45
|
+
redirect_to :back
|
62
46
|
end
|
63
|
-
|
64
|
-
redirect_to :back
|
65
47
|
end
|
66
48
|
|
67
49
|
# Beware, :id is the Solr document_id, not the actual Bookmark id.
|
68
50
|
# idempotent, as DELETE is supposed to be.
|
69
51
|
def destroy
|
70
|
-
bookmark =
|
52
|
+
bookmark = current_or_guest_user.existing_bookmark_for(params[:id])
|
71
53
|
|
72
|
-
success = (!bookmark) ||
|
54
|
+
success = (!bookmark) || current_or_guest_user.bookmarks.delete(bookmark)
|
73
55
|
|
74
56
|
unless request.xhr?
|
75
57
|
if success
|
@@ -85,7 +67,7 @@ class BookmarksController < ApplicationController
|
|
85
67
|
end
|
86
68
|
|
87
69
|
def clear
|
88
|
-
if
|
70
|
+
if current_or_guest_user.bookmarks.clear
|
89
71
|
flash[:notice] = I18n.t('blacklight.bookmarks.clear.success')
|
90
72
|
else
|
91
73
|
flash[:error] = I18n.t('blacklight.bookmarks.clear.failure')
|
@@ -95,6 +77,6 @@ class BookmarksController < ApplicationController
|
|
95
77
|
|
96
78
|
protected
|
97
79
|
def verify_user
|
98
|
-
flash[:notice] = I18n.t('blacklight.bookmarks.need_login') and raise Blacklight::Exceptions::AccessDenied unless
|
80
|
+
flash[:notice] = I18n.t('blacklight.bookmarks.need_login') and raise Blacklight::Exceptions::AccessDenied unless current_or_guest_user
|
99
81
|
end
|
100
82
|
end
|
@@ -73,21 +73,19 @@ module Blacklight::BlacklightHelperBehavior
|
|
73
73
|
end
|
74
74
|
|
75
75
|
# Save function area for search results 'index' view, normally
|
76
|
-
# renders next to title.
|
76
|
+
# renders next to title.
|
77
77
|
def render_index_doc_actions(document, options={})
|
78
78
|
content = []
|
79
|
-
content << render(:partial => 'catalog/bookmark_control', :locals => {:document=> document}.merge(options)) if has_user_authentication_provider? and
|
80
|
-
content << render(:partial => 'catalog/folder_control', :locals => {:document=> document}.merge(options))
|
79
|
+
content << render(:partial => 'catalog/bookmark_control', :locals => {:document=> document}.merge(options)) if has_user_authentication_provider? and current_or_guest_user
|
81
80
|
|
82
81
|
content_tag("div", content.join("\n").html_safe, :class=>"documentFunctions")
|
83
82
|
end
|
84
83
|
|
85
84
|
# Save function area for item detail 'show' view, normally
|
86
|
-
# renders next to title. By default includes '
|
85
|
+
# renders next to title. By default includes 'Bookmarks'
|
87
86
|
def render_show_doc_actions(document=@document, options={})
|
88
87
|
content = []
|
89
|
-
content << render(:partial => 'catalog/bookmark_control', :locals => {:document=> document}.merge(options)) if has_user_authentication_provider? and
|
90
|
-
content << render(:partial => 'catalog/folder_control', :locals => {:document=> document}.merge(options))
|
88
|
+
content << render(:partial => 'catalog/bookmark_control', :locals => {:document=> document}.merge(options)) if has_user_authentication_provider? and current_or_guest_user
|
91
89
|
|
92
90
|
content_tag("div", content.join("\n").html_safe, :class=>"documentFunctions")
|
93
91
|
end
|
@@ -344,11 +342,6 @@ module Blacklight::BlacklightHelperBehavior
|
|
344
342
|
return result
|
345
343
|
end
|
346
344
|
|
347
|
-
# determines if the given document id is in the folder
|
348
|
-
def item_in_folder?(doc_id)
|
349
|
-
session[:folder_document_ids] && session[:folder_document_ids].include?(doc_id) ? true : false
|
350
|
-
end
|
351
|
-
|
352
345
|
# puts together a collection of documents into one refworks export string
|
353
346
|
def render_refworks_texts(documents)
|
354
347
|
val = ''
|
@@ -32,14 +32,15 @@ module Blacklight::FacetsHelperBehavior
|
|
32
32
|
def facet_by_field_name solr_field
|
33
33
|
case solr_field
|
34
34
|
when String, Symbol
|
35
|
-
|
35
|
+
extract_solr_facet_by_field_name(solr_field)
|
36
36
|
when Blacklight::Configuration::FacetField
|
37
|
-
|
37
|
+
extract_solr_facet_by_field_name(solr_field.field)
|
38
38
|
else
|
39
39
|
solr_field
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
+
|
43
44
|
# used in the catalog/_facets partial and elsewhere
|
44
45
|
# Renders a single section for facet limit with a specified
|
45
46
|
# solr field used for faceting. Can be over-ridden for custom
|
@@ -95,7 +96,7 @@ module Blacklight::FacetsHelperBehavior
|
|
95
96
|
# options consist of:
|
96
97
|
# :suppress_link => true # do not make it a link, used for an already selected value for instance
|
97
98
|
def render_facet_value(facet_solr_field, item, options ={})
|
98
|
-
(link_to_unless(options[:suppress_link], item.value, add_facet_params_and_redirect(facet_solr_field, item.value), :class=>"facet_select label") + " " + render_facet_count(item.hits)).html_safe
|
99
|
+
(link_to_unless(options[:suppress_link], ((item.label if item.respond_to?(:label)) || item.value), add_facet_params_and_redirect(facet_solr_field, item.value), :class=>"facet_select label") + " " + render_facet_count(item.hits)).html_safe
|
99
100
|
end
|
100
101
|
|
101
102
|
# Standard display of a SELECTED facet value, no link, special span
|
@@ -117,9 +118,18 @@ module Blacklight::FacetsHelperBehavior
|
|
117
118
|
# is suitable for a redirect. See
|
118
119
|
# add_facet_params_and_redirect
|
119
120
|
def add_facet_params(field, value)
|
121
|
+
facet_config = facet_configuration_for_field(field)
|
122
|
+
|
123
|
+
|
124
|
+
|
120
125
|
p = params.dup
|
121
126
|
p[:f] = (p[:f] || {}).dup # the command above is not deep in rails3, !@#$!@#$
|
122
127
|
p[:f][field] = (p[:f][field] || []).dup
|
128
|
+
|
129
|
+
if facet_config.single and not p[:f][field].empty?
|
130
|
+
p[:f][field] = []
|
131
|
+
end
|
132
|
+
|
123
133
|
p[:f][field].push(value)
|
124
134
|
p
|
125
135
|
end
|
@@ -172,5 +182,48 @@ module Blacklight::FacetsHelperBehavior
|
|
172
182
|
def facet_in_params?(field, value)
|
173
183
|
params[:f] and params[:f][field] and params[:f][field].include?(value)
|
174
184
|
end
|
175
|
-
|
185
|
+
|
186
|
+
def facet_display_value field, value
|
187
|
+
|
188
|
+
facet_config = facet_configuration_for_field(field)
|
189
|
+
|
190
|
+
display_label = value
|
191
|
+
|
192
|
+
if facet_config.query and facet_config.query[value]
|
193
|
+
display_label = facet_config.query[value][:label]
|
194
|
+
end
|
195
|
+
|
196
|
+
if facet_config.date
|
197
|
+
localization_options = {}
|
198
|
+
localization_options = facet_config.date unless facet_config.date === true
|
199
|
+
display_label = l(value.to_datetime, localization_options)
|
200
|
+
end
|
201
|
+
|
202
|
+
display_label
|
203
|
+
end
|
204
|
+
|
205
|
+
private
|
206
|
+
|
207
|
+
# Get the solr response for the solr field :field
|
208
|
+
def extract_solr_facet_by_field_name facet_name
|
209
|
+
facet_field = facet_configuration_for_field(facet_name)
|
210
|
+
case
|
211
|
+
when facet_field.query
|
212
|
+
create_rsolr_facet_field_response_for_query_facet_field facet_name, facet_field
|
213
|
+
else
|
214
|
+
@response.facet_by_field_name(facet_name)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def create_rsolr_facet_field_response_for_query_facet_field facet_name, facet_field
|
219
|
+
salient_facet_queries = facet_field.query.map { |k, x| x[:fq] }
|
220
|
+
items = []
|
221
|
+
@response.facet_queries.select { |k,v| salient_facet_queries.include?(k) }.reject { |value, hits| hits == 0 }.map do |value,hits|
|
222
|
+
salient_fields = facet_field.query.select { |key, val| val[:fq] == value }
|
223
|
+
key = ((salient_fields.keys if salient_fields.respond_to? :keys) || salient_fields.first).first
|
224
|
+
items << OpenStruct.new(:value => key, :hits => hits, :label => facet_field.query[key][:label])
|
225
|
+
end
|
226
|
+
|
227
|
+
RSolr::Ext::Response::Facets::FacetField.new facet_name, items
|
228
|
+
end
|
176
229
|
end
|
@@ -43,9 +43,12 @@ module Blacklight::RenderConstraintsHelperBehavior
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def render_filter_element(facet, values, localized_params)
|
46
|
+
facet_config = facet_configuration_for_field(facet)
|
47
|
+
|
46
48
|
values.map do |val|
|
49
|
+
|
47
50
|
render_constraint_element( facet_field_labels[facet],
|
48
|
-
val,
|
51
|
+
facet_display_value(facet, val),
|
49
52
|
:remove => url_for(remove_facet_params(facet, val, localized_params)),
|
50
53
|
:classes => ["filter", "filter-" + facet.parameterize]
|
51
54
|
) + "\n"
|
@@ -41,7 +41,7 @@ module Blacklight::SearchHistoryConstraintsHelperBehavior
|
|
41
41
|
# 'and'. Pass in option :escape_value => false to pass in pre-rendered
|
42
42
|
# html for value. key with escape_key if needed.
|
43
43
|
def render_search_to_s_element(key, value, options = {})
|
44
|
-
content_tag(:span, render_filter_name(key) + render_filter_value(value), :class => 'constraint')
|
44
|
+
content_tag(:span, render_filter_name(key) + render_filter_value(value, key), :class => 'constraint')
|
45
45
|
end
|
46
46
|
|
47
47
|
def render_filter_name name
|
@@ -49,8 +49,10 @@ module Blacklight::SearchHistoryConstraintsHelperBehavior
|
|
49
49
|
content_tag(:span, t('blacklight.search.filters.label', :label => name), :class => 'filterName')
|
50
50
|
end
|
51
51
|
|
52
|
-
def render_filter_value value
|
53
|
-
|
52
|
+
def render_filter_value value, key = nil
|
53
|
+
display_value = value
|
54
|
+
display_value = facet_display_value(key, value) if key
|
55
|
+
content_tag(:span, h(display_value), :class => 'filterValue')
|
54
56
|
end
|
55
57
|
|
56
58
|
end
|
@@ -1,15 +1,16 @@
|
|
1
1
|
<% if has_user_authentication_provider? %>
|
2
|
-
|
2
|
+
<% if current_user %>
|
3
3
|
<%= link_to t('blacklight.header_links.logout'), destroy_user_session_path %> [<%= link_to current_user, edit_user_registration_path %>]
|
4
|
+
<% else %>
|
5
|
+
<%= link_to t('blacklight.header_links.login'), new_user_session_path %>
|
6
|
+
<% end %>
|
4
7
|
|
|
8
|
+
<% end %>
|
5
9
|
<%= link_to t('blacklight.header_links.bookmarks'), bookmarks_path %>
|
10
|
+
<% if current_user %>
|
6
11
|
|
|
7
12
|
<%= link_to t('blacklight.header_links.saved_searches'), saved_searches_path %>
|
8
|
-
<% else %>
|
9
|
-
<%= link_to t('blacklight.header_links.login'), new_user_session_path %>
|
10
13
|
<% end %>
|
11
|
-
|
|
12
|
-
<% end %>
|
13
|
-
<%= link_to t('blacklight.header_links.selected_items'), folder_index_path %> (<span id="folder_number"><%= "#{session[:folder_document_ids] ? session[:folder_document_ids].length : 0}" %></span>)
|
14
|
-
|
|
14
|
+
|
|
15
15
|
<%= link_to t('blacklight.header_links.search_history'), search_history_path %>
|
16
|
+
|
@@ -1,5 +1,5 @@
|
|
1
|
-
<% if has_user_authentication_provider? and
|
2
|
-
<%- existing_bookmark =
|
1
|
+
<% if has_user_authentication_provider? and current_or_guest_user %>
|
2
|
+
<%- existing_bookmark = current_or_guest_user.existing_bookmark_for(document.id) -%>
|
3
3
|
<%-
|
4
4
|
# Note these two forms are pretty similar but for different :methods, classes, and labels.
|
5
5
|
# but it was simpler to leave them seperate instead of DRYing them, got confusing trying that.
|
@@ -15,7 +15,8 @@ module Blacklight
|
|
15
15
|
:show => OpenStructWithHashAccess.new(:html_title => SolrDocument.unique_key, :heading => SolrDocument.unique_key),
|
16
16
|
:index => OpenStructWithHashAccess.new(:show_link => SolrDocument.unique_key),
|
17
17
|
:spell_max => 5,
|
18
|
-
:max_per_page => 100
|
18
|
+
:max_per_page => 100,
|
19
|
+
:add_facet_fields_to_solr_request => false
|
19
20
|
}
|
20
21
|
|
21
22
|
|
@@ -23,6 +24,7 @@ module Blacklight
|
|
23
24
|
require 'blacklight/configuration/fields'
|
24
25
|
require 'blacklight/configuration/solr_field'
|
25
26
|
require 'blacklight/configuration/search_field'
|
27
|
+
require 'blacklight/configuration/facet_field'
|
26
28
|
require 'blacklight/configuration/sort_field'
|
27
29
|
include Fields
|
28
30
|
|
@@ -68,6 +70,17 @@ module Blacklight
|
|
68
70
|
field
|
69
71
|
end
|
70
72
|
|
73
|
+
# Add any configured facet fields to the default solr parameters hash
|
74
|
+
def add_facet_fields_to_solr_request!
|
75
|
+
self.add_facet_fields_to_solr_request = true
|
76
|
+
end
|
77
|
+
|
78
|
+
def facet_fields_to_add_to_solr
|
79
|
+
return facet_fields.reject { |k,v| v[:query] }.map { |k,v| v.field } if self.add_facet_fields_to_solr_request
|
80
|
+
|
81
|
+
[]
|
82
|
+
end
|
83
|
+
|
71
84
|
##
|
72
85
|
# Provide a 'deep copy' of Blacklight::Configuration that can be modifyed without affecting
|
73
86
|
# the original Blacklight::Configuration instance.
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Blacklight
|
2
|
+
class Configuration::FacetField < Blacklight::Configuration::SolrField
|
3
|
+
def normalize! blacklight_config
|
4
|
+
self.query.stringify_keys! if self.query
|
5
|
+
|
6
|
+
if self.single and self.tag.blank? and self.ex.blank?
|
7
|
+
self.tag = "#{self.field}_single"
|
8
|
+
self.ex = "#{self.field}_single"
|
9
|
+
end
|
10
|
+
super
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
@@ -25,6 +25,22 @@ module Blacklight::Controller
|
|
25
25
|
base.send :helper_method, :stylesheet_links
|
26
26
|
base.send :helper_method, :javascript_includes
|
27
27
|
base.send :helper_method, :has_user_authentication_provider?
|
28
|
+
|
29
|
+
|
30
|
+
# This callback runs when a user first logs in
|
31
|
+
base.set_callback :logging_in_user, :before, :transfer_guest_user_actions_to_current_user rescue nil
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
def method_missing(meth, *args, &block)
|
36
|
+
if meth.to_s == "current_or_guest_user"
|
37
|
+
# Add the method
|
38
|
+
define_method(meth) { blacklight_current_or_guest_user }
|
39
|
+
|
40
|
+
blacklight_current_or_guest_user
|
41
|
+
else
|
42
|
+
super
|
43
|
+
end
|
28
44
|
end
|
29
45
|
|
30
46
|
# test for exception notifier plugin
|
@@ -96,15 +112,17 @@ module Blacklight::Controller
|
|
96
112
|
'blacklight'
|
97
113
|
end
|
98
114
|
|
99
|
-
|
100
|
-
puts "DEPRICATED: Please use Devise, Authlogic or other authentication system."
|
101
|
-
user_session # method provided by devise
|
102
|
-
end
|
103
|
-
|
104
|
-
# Should be provided by devise
|
115
|
+
# Should be provided by authentication provider
|
105
116
|
# def current_user
|
106
117
|
# end
|
107
|
-
|
118
|
+
# def current_or_guest_user
|
119
|
+
# end
|
120
|
+
|
121
|
+
# Here's a stub implementation we'll add if it isn't provided for us
|
122
|
+
def blacklight_current_or_guest_user
|
123
|
+
current_user if has_user_authentication_provider?
|
124
|
+
end
|
125
|
+
|
108
126
|
##
|
109
127
|
# We discard flash messages generated by the xhr requests to avoid
|
110
128
|
# confusing UX.
|
@@ -122,6 +140,25 @@ module Blacklight::Controller
|
|
122
140
|
def require_user_authentication_provider
|
123
141
|
raise ActionController::RoutingError.new('Not Found') unless has_user_authentication_provider?
|
124
142
|
end
|
143
|
+
|
144
|
+
##
|
145
|
+
# When a user logs in, transfer any saved searches or bookmarks to the current_user
|
146
|
+
def transfer_guest_user_actions_to_current_user
|
147
|
+
return unless respond_to? :current_user and respond_to? :guest_user and current_user and guest_user
|
148
|
+
current_user_searches = current_user.searches.all.collect(&:query_params)
|
149
|
+
current_user_bookmarks = current_user.bookmarks.all.collect(&:document_id)
|
150
|
+
|
151
|
+
guest_user.searches.all.reject { |s| current_user_searches.include?(s.query_params)}.each do |s|
|
152
|
+
s.user_id = current_user.id
|
153
|
+
s.save
|
154
|
+
end
|
155
|
+
|
156
|
+
guest_user.bookmarks.all.reject { |b| current_user_bookmarks.include?(b.document_id)}.each do |b|
|
157
|
+
b.user_id = current_user.id
|
158
|
+
b.save
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
125
162
|
##
|
126
163
|
# To handle failed authorization attempts, redirect the user to the
|
127
164
|
# login form and persist the current request uri as a parameter
|