app/controllers/application_controller.rb
# Filters added to this controller will be run for all controllers in the application.
# Likewise, all the methods added will be available for all controllers.
class ApplicationController < ActionController::Base
# helper :all # include all helpers, all the time
protect_from_forgery # See ActionController::RequestForgeryProtection for details
include DefaultUrlOptions
include KeteAuthorisationSettings
before_filter :set_locale
# first take the locale in the url, then the session[:locale],
# then the users locale, finally the default site locale
def set_locale
available_locales = I18n.available_locales_with_labels
if params[:locale] && available_locales.key?(params[:locale])
I18n.locale = params[:locale]
elsif session[:locale] && available_locales.key?(session[:locale])
I18n.locale = session[:locale]
elsif current_user != :false && available_locales.key?(current_user.locale)
I18n.locale = current_user.locale
else
I18n.locale = I18n.default_locale
end
session[:locale] = I18n.locale # need to make sure this persists
end
# See lib/ssl_helpers.rb
include SslHelpers
include AuthenticatedSystem
include ZoomControllerHelpers
include FriendlyUrls
include Utf8UrlFor
include ZoomSearch
include PreviousSearches
include KeteUrlFor
# for the remember me functionality
before_filter :login_from_cookie
# Setup HTTP Basic Authentication if we have an SITE_LOCKDOWN constant that
# isn't a blank hash (set in config/initializers/site_lockdown_auth.rb)
before_filter :password_protect
def password_protect
unless SITE_LOCKDOWN.blank?
authenticate_or_request_with_http_basic do |user_name, password|
user_name == SITE_LOCKDOWN[:username] &&
password == SITE_LOCKDOWN[:password]
end
end
end
private :password_protect
# only permit site members to add/delete things
before_filter :login_required, only: %i[
new create
edit update destroy
appearance homepage_options
convert
make_theme
find_related
link_related
find_index
flag_form
flag_version
restore
reject
choose_type render_item_form
setup_rebuild
rebuild_zoom_index
add_portrait remove_portrait
make_selected_portrait
contact send_email
join]
# doesn't work for redirects, those are handled by
# after filters on registered on specific controllers
# based on SystemSetting.allowed_anonymous_actions specs
# this should prevent url surgery to subvert logging out of anonymous user though
before_filter :logout_anonymous_user_unless_allowed, except: %i[
logout
login
signup
show_captcha]
# all topics and content items belong in a basket
# and will always be specified in our routes
before_filter :load_standard_baskets
# sets up instance variables for authentication
include KeteAuthorization
before_filter :redirect_if_current_basket_isnt_approved_for_public_viewing
# Create an instance variable with a list of baskets the
# current user has roles in (member, admin etc)
before_filter :update_basket_permissions_hash
# keep track of tag_list input by version
before_filter :update_params_with_raw_tag_list, only: %i[create update]
# see method definition for details
# we often need baskets for edits
before_filter :load_array_of_baskets, only: %i[edit update restore]
# don't allow forms to set do_not_moderate
before_filter :security_check_of_do_not_moderate, only: %i[create update restore]
# set do_not_moderate if site_admin, otherwise things like moving from one basket to another
# may get tripped up
before_filter :set_do_not_moderate_if_site_admin_or_exempted, only: %i[create update]
# ensure that users who are in a basket where the action menu has been hidden can edit
# by posting a dummy form
before_filter :current_user_can_see_action_menu?, only: %i[new create edit update]
# TODO: NOT USED, delete code here and in lib/zoom_controller_helpers.rb
# related items only track title and url, therefore only update will change those attributes
after_filter :update_zoom_record_for_related_items, only: [:update]
# setup return_to for the session
# TODO: this needs to be updated to store location for newer actions
# might be better to do an except?
after_filter :store_location, only: %i[for all search index new show edit new_related_set_from_archive_file]
# RSS feed related operations
# no layout on rss pages
layout :determine_layout
def determine_layout
params[:action] == 'rss' ? nil : 'application'
end
# adjust request and response values
before_filter :adjust_http_headers_for_rss, only: [:rss]
def adjust_http_headers_for_rss
response.headers['Content-Type'] = 'application/xml; charset=utf-8'
request.format = :xml
end
helper :slideshows
helper :extended_fields
# set the current basket to the default
# unless we have urlified_name that is different
# than the default
# TODO: cache in memcache
def load_standard_baskets
# could DRY this up with one query for all the baskets
@site_basket ||= Basket.site_basket
@help_basket ||= Basket.help_basket
@about_basket ||= Basket.about_basket
@documentation_basket ||= Basket.documentation_basket
@standard_basket_ids ||= Basket.standard_basket_ids
if params[:urlified_name].blank?
@current_basket = @site_basket
else
case params[:urlified_name]
when @site_basket.urlified_name
@current_basket = @site_basket
when @about_basket.urlified_name
@current_basket = @about_basket
when @help_basket.urlified_name
@current_basket = @help_basket
when @documentation_basket.urlified_name
@current_basket = @documentation_basket
else
@current_basket = Basket.where(urlified_name: params[:urlified_name]).first
end
end
if @current_basket.nil?
@current_basket = @site_basket
# if were are already raising an error, don't call this again
unless @displaying_error
raise ActiveRecord::RecordNotFound, "Couldn't find Basket with NAME=#{params[:urlified_name]}."
end
end
end
# ROB: item_from_controller_and_id() should probably be gotten-rid-of/clarrified along with
# prepare_item_and_vars(). #get_item
# Walter McGinnis, 2008-09-29
# adding security fix, so you can't see another basket's item's history
# unless specifically allowed
def item_from_controller_and_id(and_basket = true)
if and_basket
@current_basket.send(zoom_class_from_controller(params[:controller]).tableize).find(params[:id])
else
Module.class_eval(zoom_class_from_controller(params[:controller])).find(params[:id])
end
end
# so we can transfer an item from one basket to another
def load_array_of_baskets
zoom_class = zoom_class_from_controller(params[:controller])
if ZOOM_CLASSES.include?(zoom_class) && (zoom_class != 'Comment')
@baskets = Basket.all(order: 'name').map { |basket| [basket.name, basket.id] }
end
end
def show_basket_list_naviation_menu?
return false unless SystemSetting.is_configured
return false if params[:controller] == 'baskets' && ['edit', 'appearance', 'homepage_options'].include?(params[:action])
return false if params[:controller] == 'search'
SystemSetting.uses_basket_list_navigation_menu_on_every_page?
end
def redirect_to_related_item(item, options = {})
redirect_to_show_for(item, options)
end
def update_zoom_and_related_caches_for(item, controller = nil)
# refresh data for the item
item = Module.class_eval(item.class.name).find(item)
# item.prepare_and_save_to_zoom
# use async backgroundrb process instead
update_search_record_for(item)
end
def add_relation_and_update_zoom_and_related_caches_for(item1, item2)
raise 'ERROR: Neither item 1 or 2 was a Topic' unless item1.is_a?(Topic) || item2.is_a?(Topic)
topic, related = (item1.is_a?(Topic) ? [item1, item2] : [item2, item1])
# clear out old zoom records before we change the items
# sometimes zoom updates are confused and create a duplicate new record
# instead of updating existing one
# zoom_destroy_for(topic)
# zoom_destroy_for(related)
successful = ContentItemRelation.new_relation_to_topic(topic, related)
update_zoom_and_related_caches_for(topic, zoom_class_controller(related.class.name))
update_zoom_and_related_caches_for(related, ('topics' if related.is_a?(Topic)))
successful
end
def remove_relation_between(related_item: item1, topic: item2)
raise 'ERROR: Neither topic is not a Topic' unless topic.is_a?(Topic)
ContentItemRelation.destroy_relation_to_topic(topic, related_item)
end
def setup_related_topic_and_zoom_and_redirect(item, commented_item = nil, options = {})
where_to_redirect = 'show_self'
if !commented_item.nil? && @successful
update_zoom_and_related_caches_for(commented_item)
where_to_redirect = 'commentable'
elsif !params[:relate_to_item].blank? && @successful
@relate_to_item = params[:relate_to_type].constantize.find(params[:relate_to_item])
add_relation_and_update_zoom_and_related_caches_for(@relate_to_item, item)
# reset the related images slideshow if realted image was added
session[:image_slideshow] = nil if item.is_a?(StillImage)
where_to_redirect = 'show_related'
elsif params[:is_theme] && (item.class.name == 'Document') && @successful
item.decompress_as_theme
where_to_redirect = 'appearance'
elsif params[:portrait] && (item.class.name == 'StillImage') && @successful
where_to_redirect = 'user_account'
elsif params[:as_service].present? &&
params[:as_service] == 'true' &&
params[:service_target].present?
where_to_redirect = 'service_target'
end
if @successful
build_relations_from_topic_type_extended_field_choices
update_zoom_and_related_caches_for(item)
# send notifications of private item create
private_item_notification_for(item, :created) if params[item.class_as_key][:private] == 'true'
case where_to_redirect
when 'show_related'
# TODO: replace with translation stuff when we get globalize going
flash[:notice] = t('application_controller.setup_related_topic_and_zoom_and_redirect.related_item', zoom_class: zoom_class_humanize(item.class.name))
redirect_to_related_item(@relate_to_item, { private: (params[:related_item_private] && params[:related_item_private] == 'true' && permitted_to_view_private_items?) })
when 'commentable'
redirect_to_show_for(commented_item, options)
when 'appearance'
redirect_to action: :appearance, controller: 'baskets'
when 'user_account'
if params[:portrait] && params[:selected_portrait]
flash[:notice] = t('application_controller.setup_related_topic_and_zoom_and_redirect.selected_portrait', zoom_class: zoom_class_humanize(item.class.name))
elsif params[:portrait]
flash[:notice] = t('application_controller.setup_related_topic_and_zoom_and_redirect.portrait', zoom_class: zoom_class_humanize(item.class.name))
end
redirect_to action: :show, controller: 'account', id: @current_user
when 'service_target'
service_target = params[:service_target]
if params[:append_show_url].present? &&
params[:append_show_url] == 'true'
service_target += url_for_dc_identifier(item).sub('://', '%3A%2F%2F').gsub('/', '%2F')
end
redirect_to service_target
else
flash[:notice] = t('application_controller.setup_related_topic_and_zoom_and_redirect.created', zoom_class: zoom_class_humanize(item.class.name))
redirect_to_show_for(item, options)
end
else
render action: 'new'
end
end
def link_related
@related_to_item = params[:relate_to_type].constantize.find(params[:relate_to_item])
unless params[:item].blank?
for id in params[:item].reject { |k, v| v != 'true' }.collect { |k, v| k }
item = only_valid_zoom_class(params[:related_class]).find(id)
if params[:relate_to_type] == 'Topic' && params[:related_class] == 'Topic'
@existing_relation = @related_to_item.related_topics.include?(item)
else
@existing_relation = @related_to_item.send(params[:related_class].tableize).include?(item)
end
if !@existing_relation
@successful = add_relation_and_update_zoom_and_related_caches_for(item, @related_to_item)
if @successful
# in this context, the item being related needs updating, too
update_zoom_and_related_caches_for(item)
flash[:notice] = t('application_controller.link_related.added_relation')
end
end
end
end
redirect_to controller: 'search', action: 'find_related',
relate_to_item: params[:relate_to_item], relate_to_type: params[:relate_to_type],
related_class: params[:related_class], function: 'remove'
end
def unlink_related
@related_to_item = params[:relate_to_type].constantize.find(params[:relate_to_item])
unless params[:item].blank?
for id in params[:item].reject { |k, v| v != 'true' }.collect { |k, v| k }
item = only_valid_zoom_class(params[:related_class]).find(id)
remove_relation_between(related_item: item, topic: @related_to_item)
flash[:notice] = t('application_controller.unlink_related.unlinked_relation')
end
end
redirect_to controller: 'search', action: 'find_related',
relate_to_item: params[:relate_to_item], relate_to_type: params[:relate_to_type],
related_class: params[:related_class], function: 'remove'
end
# overriding here, to grab title of page, too
# Store the URI of the current request in the session.
#
# We can return to this location by calling #redirect_back_or_default.
def store_location
# Because private files are served through a show action, this method gets called, but we
# don't want to set the return_to url to a private image link
return if params[:controller] == 'private_files'
# this should prevent the same page from being added to return_to
# but does not prevent case of differnt size images...
session[:return_to] = request.original_fullpath
session[:return_to_title] = @title
end
def redirect_to_search_for(zoom_class)
redirect_to(
controller: 'search',
trailing_slash: true,
action: :all,
controller_name_for_zoom_class: zoom_class
)
end
def redirect_to_default_all
redirect_to list_basket_baskets_url('site')
# redirect_to(basket_all_url(:controller_name_for_zoom_class => zoom_class_controller(SystemSetting.default_search_class)))
end
def redirect_to_all_for(controller)
redirect_to list_basket_baskets_url('site')
# redirect_to(basket_all_url(:controller_name_for_zoom_class => controller))
end
def redirect_to_show_for(item, options = {})
redirect_to path_to_show_for(item, options)
end
def path_to_show_for(item, options = {})
# By default, assume redirect to public version.
options = {
private: false
}.merge(options)
item = item.commentable if item.is_a?(Comment)
path_hash = {
urlified_name: item.basket.urlified_name,
controller: zoom_class_controller(item.class.name),
action: 'show',
id: item,
locale: false
}
# Redirect to private version if item is private.
if options[:private]
path_hash[:private] = 'true'
end
# Add the anchor if one is passed in
if options[:anchor]
path_hash[:anchor] = options[:anchor]
end
url_for(path_hash)
end
def render_oai_record_xml(options = {})
item = options[:item]
to_string = options[:to_string] || false
if to_string
item.oai_record
else
# :layout => false,
render text: item.oai_record, content_type: 'text/xml'
end
end
# TODO: this can likely be elimenated!
# just use user.user_name
def user_to_dc_creator_or_contributor(user)
user.user_name
end
def update_params_with_raw_tag_list
# only do this for a zoom_class
# this will return the model's tableized name
# if it can't find it, so we have to doublecheck it's a zoom_class
zoom_class = zoom_class_from_controller(params[:controller])
if ZOOM_CLASSES.include?(zoom_class)
item_key = zoom_class.underscore.to_sym
params[item_key][:raw_tag_list] = params[item_key][:tag_list]
end
end
def correct_url_for(item, version = nil)
correct_action = version.nil? ? 'show' : 'preview'
options = { action: correct_action, id: item }
options[:version] = version if correct_action == 'preview'
options[:private] = params[:private]
item_url = nil
if (item.class.name == 'Comment') && (correct_action != 'preview')
commented_item = item.commentable
item_url = url_for(
controller: zoom_class_controller(commented_item.class.name),
action: correct_action,
id: commented_item,
anchor: item.id,
urlified_name: commented_item.basket.urlified_name
)
else
item_url = url_for(options)
end
item_url
end
def stats_by_type_for(basket)
# prepare a hash of all the stats, so it's nice and easy to pass to partial
@basket_stats_hash = {}
# special case: site basket contains everything
# all contents of site basket plus all other baskets' contents
ZOOM_CLASSES.each do |zoom_class|
# pending items aren't counted
private_conditions = "title != '#{SystemSetting.blank_title}' "
local_public_conditions = PUBLIC_CONDITIONS
# comments are a special case
# they have a subtly different data model that means they need an different condition
if zoom_class == 'Comment'
commentable_private_condition = ' AND commentable_private = ?'
local_public_conditions = [local_public_conditions + commentable_private_condition, false]
private_conditions = [private_conditions + commentable_private_condition, true]
else
private_conditions += 'AND private_version_serialized IS NOT NULL'
end
if basket == @site_basket
@basket_stats_hash["#{zoom_class}_public"] = Module.class_eval(zoom_class).count(conditions: local_public_conditions)
else
@basket_stats_hash["#{zoom_class}_public"] = basket.send(zoom_class.tableize).count(conditions: local_public_conditions)
end
# Walter McGinnis, 2008-11-18
# normally the site basket is a special case, in that is shows all items from all baskets
# however in the context of private items, the rule is to show all private items that a USER has rights to see
# so the counts may vary by user
# because of caching, this becomes problematic to display counts for
# so instead, we only show private items that are actually in the site basket
# which happens to use the same code as other basket would, so we don't need to duplicate this at the moment
# TODO: we will want to change this to match browsing of private items in site basket later
if basket.show_privacy_controls_with_inheritance? && permitted_to_view_private_items?
@basket_stats_hash["#{zoom_class}_private"] = basket.send(zoom_class.tableize).count(conditions: private_conditions)
end
end
end
def prepare_short_summary(source_string, length = 30, end_string = '')
require 'hpricot'
source_string = source_string.to_s
# length is how many words, rather than characters
words = source_string.split
short_summary = words[0..(length - 1)].join(' ') + (words.length > length ? end_string : '')
# make sure that tags are closed
Hpricot(short_summary).to_html
end
# this happens after the basket on the item has been changed already
def update_comments_basket_for(item, original_basket)
if item.class.name != 'Comment'
new_basket = item.basket
if new_basket != original_basket
item.comments.each do |comment|
# get rid of zoom record that it tied to old basket
# zoom_destroy_for(comment)
comment.basket = new_basket
if comment.save
# moving the comment adds a version
comment.add_as_contributor(current_user)
end
# generate the new zoom record
# with the new basket
comment.prepare_and_save_to_zoom
end
end
end
end
def after_successful_zoom_item_update(item, version_after_update)
version_created = version_after_update ? item.versions.exists?(version: version_after_update) : false
# if we need to add a contributor (sometimes, a version isn't
# created if only timestamps were updated. In that case. we
# don't want to add an incorrect contributor to the previous
# version of the updated item)
if version_created
# James - 2008-12-21
# Ensure the contribution is added against the latest version, not the current verrsion as it could
# have been reverted automatically if full moderation is on for the basket.
version = item.versions.order('version DESC').first.version
# add this to the user's empire of contributions
# TODO: allow current_user whom is at least moderator to pick another user
# as contributor. uses virtual attr as hack to pass version to << method
item.add_as_contributor(current_user, version)
end
# if the basket has been changed, make sure comments are moved, too
update_comments_basket_for(item, @current_basket)
# if changes to the item's extended content should add new relations
build_relations_from_topic_type_extended_field_choices unless params[:controller] == 'search'
# finally, sync up our search indexes
# item.prepare_and_save_to_zoom if !item.already_at_blank_version?
# switched to async backgroundrb worker version
update_search_record_for(item) if !item.already_at_blank_version?
# send notifications if needed
item.do_notifications_if_pending(version_after_update, current_user) if version_created
# send notifications of private item edit
# do not do this when flagging, restoring, changing a homepage topic,
# or converting a document into the description
skipped_actions = ['flag_version', 'restore', 'find_index', 'convert']
if !skipped_actions.include?(params[:action]) && params[item.class_as_key][:private] == 'true'
private_item_notification_for(item, :edited)
end
end
def history_url(item)
# if we got sent a version object, we need to link to the latest version
item = item.latest_version if item.class.name =~ /Version/
url_for controller: zoom_class_controller(item.class.name), action: :history, id: item
end
# this is useful for creating a rss version of the request
# or for replacing the page number in an existing rss url
def derive_url_for_rss(options = {})
replace_page_with_rss = !options[:replace_page_with_rss].nil? ? options[:replace_page_with_rss] : false
page = !options.blank? && !options[:page].blank? ? options[:page] : nil
# whether we replace normal page controller_name_for_zoom_class with 'combined'
combined = options[:combined] || false
url = request.protocol
url += request.host_with_port
# split everything before the query string and the query string
url_parts = request.original_url.split('?')
# now split the path up and add rss to it
path_elements = url_parts[0].split('/')
# replace topics, images, etc. with combined if called for
if combined && !path_elements.include?('combined')
# array of zoom class controllers
CACHES_CONTROLLERS.each do |to_be_replaced|
existing_index = path_elements.index(to_be_replaced)
if existing_index
path_elements.delete_at(existing_index)
path_elements.insert(existing_index, 'combined')
end
end
end
# query string to hash
query_parameters = request.query_parameters
# delete the parameters that are artifacts from normal search
%w(number_of_results_per_page tabindex sort_type sort_direction).each do |not_relevant|
query_parameters.delete(not_relevant)
end
# also delete page, but only if this isn't already an rss request
query_parameters.delete('page') unless path_elements.include?('rss.xml')
# escape spaces in search terms
query_parameters['search_terms'] = query_parameters['search_terms'].tr(' ', '+') if query_parameters['search_terms']
# if we need to take off index/list actions, do that here
path_elements.pop if replace_page_with_rss
# add rss.xml to it, if it doesn't already exist
path_elements << 'rss.xml' unless path_elements.include?('rss.xml')
new_path = path_elements.join('/')
url += new_path
query_parameters['page'] = page if page
# if there is a query string, tack it on the end
unless query_parameters.blank?
formatted = query_parameters.collect { |k, v| k.to_s + '=' + v.to_s }
url += '?' + formatted.join('&')
end
url
end
def rss_tag(options = {})
auto_detect = !options[:auto_detect].nil? ? options[:auto_detect] : true
tag = ''
tag += auto_detect ? '<link rel="alternate" type="application/rss+xml" title="RSS" ' : '<a '
tag += 'href="' + derive_url_for_rss(options)
tag += auto_detect ? '" />' : '" tabindex="1">' # A tag has a closing </a> in application layout
tag
end
cattr_accessor :add_ons_full_width_content_wrapper_controllers, :add_ons_content_wrapper_end_controllers
def self.add_ons_full_width_content_wrapper_controllers
@@add_ons_full_width_content_wrapper_controllers || []
end
def self.add_ons_content_wrapper_end_controllers
@@add_ons_content_wrapper_end_controllers || []
end
# override in your add-on by adding to corresponding class attribute
# i.e ApplicationController.class_eval { self.add_ons_full_width_content_wrapper_controllers += ['your_controller'] }
def add_ons_full_width_content_wrapper_controllers
self.class.add_ons_full_width_content_wrapper_controllers
end
# i.e ApplicationController.class_eval { self.add_ons_full_width_content_wrapper_controllers += ['your_controller'] }
def add_ons_content_wrapper_end_controllers
self.class.add_ons_content_wrapper_end_controllers
end
def render_full_width_content_wrapper?
if @displaying_error
false
elsif (params[:controller] == 'baskets') && ['edit', 'update', 'homepage_options', 'appearance'].include?(params[:action])
false
elsif ['moderate', 'members', 'importers'].include?(params[:controller]) && ['list', 'create', 'new', 'new_related_set_from_archive_file', 'potential_new_members'].include?(params[:action])
false
elsif (params[:controller] == 'index_page') && (params[:action] == 'index')
false
elsif %w(tags search).include?(params[:controller])
false
elsif add_ons_full_width_content_wrapper_controllers.include?(params[:controller])
true
elsif (params[:controller] == 'account') && (params[:action] == 'show')
true
elsif !['show', 'preview', 'show_private'].include?(params[:action])
true
else
false
end
end
def render_content_wrapper_end?
return true if ACTIVE_SCAFFOLD_CONTROLLERS.include?(params[:controller])
return true if add_ons_content_wrapper_end_controllers.include?(params[:controller])
false
end
# Check whether the attached files for a given item should be displayed
# Note this is independent of file privacy.
def show_attached_files_for?(item)
if item.respond_to?(:private) && item.private?
# If viewing the private version of an item, then the user already has permission to
# see any attached files.
true
else
# Otherwise, show the files if viewing a public, non-disputed and non-placeholder
# version
!item.disputed_or_not_available?
end
end
def private_redirect_attribute_for(item)
item.respond_to?(:private) && item.private? ? 'true' : 'false'
end
def slideshow(key = 'slideshow')
# Instantiate a new slideshow object on the slideshow session key
session[key.to_sym] ||= HashWithIndifferentAccess.new
Slideshow.new(session[key.to_sym])
end
def image_slideshow
slideshow('image_slideshow')
end
# Append a query string to a URL.
def append_options_to_url(url, options)
options = options.join('&') if options.is_a?(Array)
append_operator = url.include?('?') ? '&' : '?'
url + append_operator + options
end
# ROB: I would like to get-rid-of/clarrify prepare_item_and_vars(). It feels like it should
# be something simpler in a controller. #get_item
# setup a few variables that will be used on topic/audio/etc items
def prepare_item_and_vars
zoom_class = zoom_class_from_controller(params[:controller])
if !ZOOM_CLASSES.member?(zoom_class)
raise(ArgumentError, "zoom_class name expected. #{zoom_class} is not registered in #{ZOOM_CLASSES}.")
end
@current_item = @current_basket.send(zoom_class.tableize).find(params[:id])
@show_privacy_chooser = true if permitted_to_view_private_items?
if params[:format] == 'xml' || allowed_to_access_private_version_of?(@current_item)
public_or_private_version_of(@current_item)
privacy = get_acceptable_privacy_type_for(@current_item)
if params[:format] == 'xml'
@title = @current_item.title
end
if params[:format] == 'xml'
@creator = @current_item.creator
@last_contributor = @current_item.contributors.last || @creator
end
if logged_in? && @at_least_a_moderator
if params[:format] == 'xml'
@comments = @current_item.non_pending_comments
end
else
if params[:format] == 'xml'
@comments = @current_item.non_pending_comments
end
end
end
@current_item
end
# ROB: WHy aren't using rails 404 page? Kill it. KILLLLL IIIITT! #custom_error_pages
def rescue_404
redirect_registration = RedirectRegistration.match(request).first
unless redirect_registration
@displaying_error = true
@title = t('application_controller.rescue_404.title')
render template: 'errors/error404', layout: 'application', status: '404'
else
redirect_to redirect_registration.new_url, status: redirect_registration.status_code
end
end
# ROB: see rescue_404() #custom_error_pages
def rescue_500(template)
@displaying_error = true
@title = t('application_controller.rescue_500.title')
render template: "errors/#{template}", layout: 'application', status: '500'
end
# ROB: current_item() should probably be gotten-rid-of/clarrified along with
# prepare_item_and_vars(). #get_item
def current_item
@current_item ||= @audio_recording || @document || @still_image || @topic || @video || @web_link || nil
end
def current_sorting_options(default_order, default_direction, valid_orders = [])
@order = valid_orders.include?(params[:order]) ? params[:order] : default_order
@direction = ['asc', 'desc'].include?(params[:direction]) ? params[:direction] : default_direction
"#{@order} #{@direction}"
end
def logout_anonymous
if logged_in? &&
current_user.anonymous?
session[:anonymous_user] = nil
current_user.reload
deauthenticate
end
end
def finished_as_anonymous_after
logout_anonymous
end
# methods that should be available in views as well
helper_method :prepare_short_summary, :history_url, :render_full_width_content_wrapper?, :render_content_wrapper_end?, :permitted_to_view_private_items?,
:permitted_to_edit_current_item?, :allowed_to_access_private_version_of?, :accessing_private_search_and_allowed?,
:get_acceptable_privacy_type_for, :current_user_can_see_contributors?, :current_user_can_see_add_links?,
:current_user_can_add_or_request_basket?, :basket_policy_request_with_permissions?, :current_user_can_see_action_menu?,
:current_user_can_see_discussion?, :current_user_can_see_private_files_for?, :current_user_can_see_private_files_in_basket?,
:current_user_can_see_memberlist_for?, :show_attached_files_for?, :slideshow, :append_options_to_url, :current_item,
:show_basket_list_naviation_menu?, :url_for_dc_identifier, :derive_url_for_rss, :show_notification_controls?, :path_to_show_for,
:permitted_to_edit_basket_homepage_topic?, :current_user_can_import_archive_sets?, :current_user_can_import_archive_sets_for?, :anonymous_ok_for?
# stub out methods to allow specs to run
def auto_complete_for(*args); end
protected
def local_request?
false
end
# ROB: see rescue_404() #custom_error_pages
def rescue_action_in_public(exception)
@displaying_error = true
# when an exception occurs, before filters arn't called, so we have to manually call them here
# only call the ones absolutely nessesary (required settings, themes, permissions etc)
load_standard_baskets
redirect_if_current_basket_isnt_approved_for_public_viewing
update_basket_permissions_hash
case exception
when ActionController::UnknownAction,
ActiveRecord::RecordNotFound,
ActiveRecord::RecordInvalid,
ActionController::MethodNotAllowed then
rescue_404
when BackgrounDRb::NoServerAvailable then
rescue_500('backgroundrb_connection_failed')
when ActionController::InvalidAuthenticityToken then
respond_to do |format|
format.html { rescue_500('invalid_authenticity_token') }
format.js { render file: File.join(Rails.root, 'app/views/errors/invalid_authenticity_token.js.rjs') }
end
else
if exception.to_s =~ /Connect\ failed/
rescue_500('zebra_connection_failed')
else
respond_to do |format|
format.html { rescue_500('error500') }
format.js { render file: File.join(Rails.root, 'app/views/errors/error500.js.rjs') }
end
end
end
end
private
def redirect_if_current_basket_isnt_approved_for_public_viewing
if @current_basket.status != 'approved' && !@site_admin && !@basket_admin
flash[:error] = t(
'application_controller.redirect_if_current_basket_isnt_approved_for_public_viewing.not_available',
basket_name: @current_basket.name
)
redirect_to "/#{@site_basket.urlified_name}"
end
end
def logout_anonymous_user_unless_allowed
if !anonymous_ok_for?(request.path)
logout_anonymous
end
end
def item_controllers
@item_controllers ||= ITEM_CLASSES.collect { |c| zoom_class_controller(c) }
end
end