diff --git a/app/overrides/presenters/blacklight/thumbnail_presenter_override.rb b/app/overrides/presenters/blacklight/thumbnail_presenter_override.rb new file mode 100644 index 000000000..52993d47b --- /dev/null +++ b/app/overrides/presenters/blacklight/thumbnail_presenter_override.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true +# https://github.com/projectblacklight/blacklight/blob/v8.7.0/app/presenters/blacklight/thumbnail_presenter.rb +module Blacklight + class ThumbnailPresenter + private + # [hyc-override] Retrieve the thumbnail of the first file_set of any given work instead of using the default if it exists + def retrieve_values(field_config) + # Return the default thumbnail if the document object is nil + unless document + return FieldRetriever.new(document, field_config, view_context).fetch + end + + solr_doc = extract_solr_document(document) + document_hash = solr_doc.to_h + + # Update the `thumbnail_path_ss` dynamically if needed + if needs_thumbnail_path_update?(document_hash) + file_set_id = document_hash['file_set_ids_ssim']&.first + document_hash['thumbnail_path_ss'] = "/downloads/#{file_set_id}?file=thumbnail" + Rails.logger.info("Updated thumbnail_path_ss: #{document_hash['thumbnail_path_ss']} for work with id #{document_hash['id']}") + # Create a temporary SolrDocument from the updated hash + updated_document = SolrDocument.new(document_hash) + FieldRetriever.new(updated_document, field_config, view_context).fetch + else + FieldRetriever.new(solr_doc, field_config, view_context).fetch + end + end + + # Extract the SolrDocument from the document object if it's nested + # Prevents errors when the document object is a presenter on work show pages + def extract_solr_document(doc) + if doc.is_a?(SolrDocument) + doc + elsif doc.respond_to?(:solr_document) && doc.solr_document.is_a?(SolrDocument) + doc.solr_document + end + end + + def needs_thumbnail_path_update?(document) + thumbnail_path = document['thumbnail_path_ss'] || '' + file_set_ids = document['file_set_ids_ssim'] + thumbnail_missing_or_default = thumbnail_path.blank? || thumbnail_path !~ %r{^/downloads/\w+\?file=thumbnail$} + + # Returns true if file_set_ids are present and the thumbnail path is the default or missing entirely + file_set_ids.present? && thumbnail_missing_or_default + end + end + end diff --git a/app/overrides/presenters/hyrax/work_show_presenter_override.rb b/app/overrides/presenters/hyrax/work_show_presenter_override.rb index 04fb777b7..3a5b84d54 100644 --- a/app/overrides/presenters/hyrax/work_show_presenter_override.rb +++ b/app/overrides/presenters/hyrax/work_show_presenter_override.rb @@ -2,11 +2,7 @@ # [hyc-override] Overriding helper in order to add doi to citation # https://github.com/samvera/hyrax/blob/hyrax-v4.0.0/app/presenters/hyrax/work_show_presenter.rb Hyrax::WorkShowPresenter.class_eval do - # delegating just :doi seems to exclude the other fields, so pull all fields in from original file - delegate :title, :date_created, :date_issued, :description, :doi, :creator, :place_of_publication, - :creator_display, :contributor, :subject, :publisher, :language, :embargo_release_date, - :lease_expiration_date, :license, :source, :rights_statement, :thumbnail_id, :representative_id, - :rendering_ids, :member_of_collection_ids, :alternative_title, :bibliographic_citation, to: :solr_document + include Hyrax::SharedDelegates # [hyc-override] Add default scholarly? method # Indicates if the work is considered scholarly according to google scholar @@ -14,4 +10,25 @@ def scholarly? false end + + def fetch_primary_fileset_id + res = representative_id.blank? ? member_ids.first : representative_id + res + end + + # [hyc-override] Use a work's first related fileset_id instead of the representative_id if it's nil + # @return FileSetPresenter presenter for the representative FileSets + def representative_presenter + @representative_presenter ||= + begin + primary_fileset_id = fetch_primary_fileset_id + return nil if primary_fileset_id.blank? + result = member_presenters([primary_fileset_id]).first + return nil if result.try(:id) == id + result.try(:representative_presenter) || result + rescue Hyrax::ObjectNotFoundError + Hyrax.logger.warn "Unable to find representative_id #{primary_fileset_id} for work #{id}" + return nil + end + end end diff --git a/app/presenters/hyrax/data_set_presenter.rb b/app/presenters/hyrax/data_set_presenter.rb index 27deca540..0260259d4 100644 --- a/app/presenters/hyrax/data_set_presenter.rb +++ b/app/presenters/hyrax/data_set_presenter.rb @@ -3,11 +3,7 @@ # `rails generate hyrax:work DataSet` module Hyrax class DataSetPresenter < Hyrax::WorkShowPresenter - delegate :abstract, :admin_note, :contributor_display, :copyright_date, :creator_display, :date_issued, :dcmi_type, :deposit_record, :doi, - :extent, :funder, :kind_of_data, :last_modified_date, :language_label, - :license_label, :methodology, :note, :orcid_label, :other_affiliation_label, :project_director_display, :researcher_display, - :rights_holder, :rights_statement_label, :sponsor, to: :solr_document - + include Hyrax::SharedDelegates # See: WorkShowPresenter.scholarly? def scholarly? true diff --git a/app/presenters/hyrax/shared_delegates.rb b/app/presenters/hyrax/shared_delegates.rb new file mode 100644 index 000000000..9f128e605 --- /dev/null +++ b/app/presenters/hyrax/shared_delegates.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true +module Hyrax + module SharedDelegates + extend ActiveSupport::Concern + included do + delegate :abstract, :admin_note, :alternative_title, :bibliographic_citation, :contributor, :contributor_display, :copyright_date, + :creator, :creator_display, :date_created, :date_issued, :dcmi_type, :deposit_record, :description, :doi, :embargo_release_date, + :extent, :funder, :human_readable_type, :identifier, :itemtype, :kind_of_data, :language, :language_label, :last_modified_date, + :lease_expiration_date, :license, :license_label, :member_ids, :member_of_collection_ids, :methodology, :note, :orcid_label, + :other_affiliation_label, :place_of_publication, :project_director_display, :publisher, :related_url, :rendering_ids, :representative_id, :researcher_display, + :resource_type, :rights_holder, :rights_notes, :rights_statement, :rights_statement_label, :sponsor, :source, :subject, + :thumbnail_id, :title, to: :solr_document + end + end + end diff --git a/app/views/hyrax/base/_representative_media.html.erb b/app/views/hyrax/base/_representative_media.html.erb new file mode 100644 index 000000000..52d74dbd6 --- /dev/null +++ b/app/views/hyrax/base/_representative_media.html.erb @@ -0,0 +1,12 @@ +<%# [hyc-override] https://github.com/samvera/hyrax/tree/hyrax-v4.0.0/app/views/hyrax/base/_representative_media.html.erb %> +<%# [hyc-override] Use custom function fetch_primary_fileset_id in place of representative_id %> + +<% if presenter.fetch_primary_fileset_id.present? && presenter.representative_presenter.present? %> + <% if defined?(viewer) && viewer %> + <%= iiif_viewer_display presenter %> + <% else %> + <%= render media_display_partial(presenter.representative_presenter), file_set: presenter.representative_presenter %> + <% end %> +<% else %> + <%= image_tag 'default.png', class: "canonical-image", alt: 'default representative image' %> +<% end %> diff --git a/app/views/hyrax/base/_show_actions.html.erb b/app/views/hyrax/base/_show_actions.html.erb index 31dbba1d6..7ff496546 100644 --- a/app/views/hyrax/base/_show_actions.html.erb +++ b/app/views/hyrax/base/_show_actions.html.erb @@ -41,7 +41,7 @@
<% if presenter.editor? && !workflow_restriction?(presenter) %> <%= link_to t('.edit'), edit_polymorphic_path([main_app, presenter]), class: 'btn btn-secondary' %> - <% if presenter.member_count > 1 %> + <% if presenter.member_count > 0 %> <%= link_to t("hyrax.file_manager.link_text"), polymorphic_path([main_app, :file_manager, presenter]), class: 'btn btn-secondary' %> <% end %> <% if presenter.valid_child_concerns.length > 0 %> diff --git a/config/application.rb b/config/application.rb index f0e5dceea..6fd468bc6 100755 --- a/config/application.rb +++ b/config/application.rb @@ -45,7 +45,7 @@ class Application < Rails::Application overrides = "#{Rails.root}/app/overrides" config.to_prepare do Dir.glob("#{overrides}/**/*_override.rb").sort.each do |c| - Rails.configuration.cache_classes ? require(c) : load(c) + Rails.configuration.cache_classes ? require(c) : require_dependency(c) end end diff --git a/spec/presenters/blacklight/thumbnail_presenter_spec.rb b/spec/presenters/blacklight/thumbnail_presenter_spec.rb new file mode 100644 index 000000000..8346aaa5a --- /dev/null +++ b/spec/presenters/blacklight/thumbnail_presenter_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true +require 'rails_helper' +require Rails.root.join('app/overrides/presenters/blacklight/thumbnail_presenter_override.rb') + +RSpec.describe Blacklight::ThumbnailPresenter do + describe '#retrieve_values' do + it 'does not attempt to process a solr document if it is nil' do + # Mock field config and view context + field_config = double('FieldConfig') + view_context = double('ViewContext') + presenter = Blacklight::ThumbnailPresenter.new(nil, view_context, field_config) + + retriever_instance = Blacklight::FieldRetriever.new(nil, nil, nil) + allow(Blacklight::FieldRetriever).to receive(:new).and_return(retriever_instance) + allow(retriever_instance).to receive(:fetch).and_return('default_thumbnail') + allow(presenter).to receive(:extract_solr_document) + + result = presenter.send(:retrieve_values, field_config) + expect(Blacklight::FieldRetriever).to have_received(:new).with(nil, field_config, view_context) + # Presenter should not process the document if it's nil + expect(presenter).not_to have_received(:extract_solr_document) + expect(result).to eq('default_thumbnail') + end + + it 'updates the thumbnail_path_ss if it needs an update' do + field_config = double('FieldConfig') + view_context = double('ViewContext') + retriever_instance = Blacklight::FieldRetriever.new(nil, nil, nil) + document_hash = { + 'thumbnail_path_ss' => '/assets/work-default.png', + 'file_set_ids_ssim' => ['file_set_1'], + 'id' => '1' + } + solr_doc = SolrDocument.new(document_hash) + presenter = Blacklight::ThumbnailPresenter.new(solr_doc, view_context, field_config) + + allow(presenter).to receive(:needs_thumbnail_path_update?).and_return(true) + allow(SolrDocument).to receive(:new).and_return(instance_double(SolrDocument)) + allow(Blacklight::FieldRetriever).to receive(:new).and_return(retriever_instance) + allow(retriever_instance).to receive(:fetch).and_return('updated_thumbnail') + allow(Rails.logger).to receive(:info) + + result = presenter.send(:retrieve_values, field_config) + expect(Rails.logger).to have_received(:info).with('Updated thumbnail_path_ss: /downloads/file_set_1?file=thumbnail for work with id 1') + expect(SolrDocument).to have_received(:new).with( + hash_including('thumbnail_path_ss' => '/downloads/file_set_1?file=thumbnail') + ) + expect(result).to eq('updated_thumbnail') + end + end +end diff --git a/spec/presenters/hyrax/work_show_presenter_spec.rb b/spec/presenters/hyrax/work_show_presenter_spec.rb index 4b1e2e91d..bc2a6fbb4 100644 --- a/spec/presenters/hyrax/work_show_presenter_spec.rb +++ b/spec/presenters/hyrax/work_show_presenter_spec.rb @@ -37,4 +37,20 @@ it { is_expected.to delegate_method(:resource_type).to(:solr_document) } it { is_expected.to delegate_method(:keyword).to(:solr_document) } it { is_expected.to delegate_method(:itemtype).to(:solr_document) } + + describe '#representative_presenter' do + context 'when member_presenters raises a Hyrax::ObjectNotFoundError' do + before do + allow(presenter).to receive(:fetch_primary_fileset_id).and_return('file_set_id_1') + allow(presenter).to receive(:member_presenters).and_raise(Hyrax::ObjectNotFoundError) + allow(Hyrax.logger).to receive(:warn) + end + + it 'logs a warning and returns nil' do + result = presenter.representative_presenter + expect(Hyrax.logger).to have_received(:warn).with('Unable to find representative_id file_set_id_1 for work 888888') + expect(result).to be_nil + end + end + end end