# frozen_string_literal: true module Hyrax class WorkShowPresenter include ModelProxy include PresentsAttributes ## # @!attribute [w] member_presenter_factory # @return [MemberPresenterFactory] attr_writer :member_presenter_factory attr_accessor :solr_document, :current_ability, :request class_attribute :collection_presenter_class # modify this attribute to use an alternate presenter class for the collections self.collection_presenter_class = CollectionPresenter # Methods used by blacklight helpers delegate :has?, :first, :fetch, :export_formats, :export_as, to: :solr_document # delegate fields from Hyrax::Works::Metadata to solr_document delegate :based_near_label, :related_url, :depositor, :identifier, :resource_type, :keyword, :itemtype, :admin_set, :rights_notes, :access_right, :abstract, to: :solr_document # @param [SolrDocument] solr_document # @param [Ability] current_ability # @param [ActionDispatch::Request] request the http request context. Used so # the GraphExporter knows what URLs to draw. def initialize(solr_document, current_ability, request = nil) @solr_document = Hyrax::SolrDocument::OrderedMembers.decorate(solr_document) @current_ability = current_ability @request = request end def page_title "#{human_readable_type} | #{title.first} | ID: #{id} | #{I18n.t('hyrax.product_name')}" end # CurationConcern methods delegate :stringify_keys, :human_readable_type, :collection?, :to_s, :suppressed?, to: :solr_document # Metadata Methods delegate :title, :date_created, :description, :creator, :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, to: :solr_document def workflow @workflow ||= WorkflowPresenter.new(solr_document, current_ability) end def inspect_work @inspect_workflow ||= InspectWorkPresenter.new(solr_document, current_ability) end # @return [String] a download URL, if work has representative media, or a blank string def download_url return '' if representative_presenter.nil? Hyrax::Engine.routes.url_helpers.download_url(representative_presenter, host: request.host) end # @return [Boolean] render a IIIF viewer def iiif_viewer? representative_id.present? && representative_presenter.present? && representative_presenter.image? && Hyrax.config.iiif_image_server? && members_include_viewable_image? end alias universal_viewer? iiif_viewer? deprecation_deprecate universal_viewer?: "use iiif_viewer? instead" # @return [Symbol] the name of the IIIF viewer partial to render # @example A work presenter with a custom iiif viewer # module Hyrax # class GenericWorkPresenter < Hyrax::WorkShowPresenter # def iiif_viewer # :my_iiif_viewer # end # end # end # # Custom iiif viewer partial at app/views/hyrax/base/iiif_viewers/_my_iiif_viewer.html.erb #

My IIIF Viewer!

# >Manifest def iiif_viewer :universal_viewer end # @return FileSetPresenter presenter for the representative FileSets def representative_presenter return nil if representative_id.blank? @representative_presenter ||= begin result = member_presenters([representative_id]).first return nil if result.try(:id) == id result.try(:representative_presenter) || result end end # Get presenters for the collections this work is a member of via the member_of_collections association. # @return [Array] presenters def member_of_collection_presenters PresenterFactory.build_for(ids: member_of_authorized_parent_collections, presenter_class: collection_presenter_class, presenter_args: presenter_factory_arguments) end def date_modified solr_document.date_modified.try(:to_formatted_s, :standard) end def date_uploaded solr_document.date_uploaded.try(:to_formatted_s, :standard) end def link_name current_ability.can?(:read, id) ? to_s : 'Private' end def export_as_nt graph.dump(:ntriples) end def export_as_jsonld graph.dump(:jsonld, standard_prefixes: true) end def export_as_ttl graph.dump(:ttl) end ## # @deprecated use `::Ability.can?(:edit, presenter)`. Hyrax views calling # presenter {#editor} methods will continue to call them until Hyrax # 4.0.0. The deprecation time horizon for the presenter methods themselves # is 5.0.0. def editor? current_ability.can?(:edit, self) end def tweeter TwitterPresenter.twitter_handle_for(user_key: depositor) end def presenter_types Hyrax.config.registered_curation_concern_types.map(&:underscore) + ["collection"] end # @return [Array] presenters grouped by model name, used to show the parents of this object def grouped_presenters(filtered_by: nil, except: nil) # TODO: we probably need to retain collection_presenters (as parent_presenters) # and join this with member_of_collection_presenters grouped = member_of_collection_presenters.group_by(&:model_name).transform_keys { |key| key.to_s.underscore } grouped.select! { |obj| obj.downcase == filtered_by } unless filtered_by.nil? grouped.except!(*except) unless except.nil? grouped end def work_featurable? user_can_feature_works? && solr_document.public? end def display_feature_link? work_featurable? && FeaturedWork.can_create_another? && !featured? end def display_unfeature_link? work_featurable? && featured? end def stats_path Hyrax::Engine.routes.url_helpers.stats_work_path(self, locale: I18n.locale) end def model solr_document.to_model end delegate :member_presenters, :ordered_ids, :file_set_presenters, :work_presenters, to: :member_presenter_factory # @return [Array] list to display with Kaminari pagination def list_of_item_ids_to_display paginated_item_list(page_array: authorized_item_ids) end ## # @deprecated use `#member_presenters(ids)` instead # # @param [Array] ids a list of ids to build presenters for # @return [Array] presenters for the array of ids (not filtered by class) def member_presenters_for(an_array_of_ids) Deprecation.warn("Use `#member_presenters` instead.") member_presenters(an_array_of_ids) end # @return [Integer] total number of pages of viewable items def total_pages (total_items.to_f / rows_from_params.to_f).ceil end def manifest_url manifest_helper.polymorphic_url([:manifest, self]) end # IIIF rendering linking property for inclusion in the manifest # Called by the `iiif_manifest` gem to add a 'rendering' (eg. a link a download for the resource) # # @return [Array] array of rendering hashes def sequence_rendering solr_document.rendering_ids.each_with_object([]) do |file_set_id, renderings| renderings << manifest_helper.build_rendering(file_set_id) end.flatten end # IIIF metadata for inclusion in the manifest # Called by the `iiif_manifest` gem to add metadata # # @return [Array] array of metadata hashes def manifest_metadata Hyrax.config.iiif_metadata_fields.each_with_object([]) do |field, metadata| metadata << { 'label' => I18n.t("simple_form.labels.defaults.#{field}"), 'value' => Array.wrap(send(field).map { |f| Loofah.fragment(f.to_s).scrub!(:whitewash).to_s }) } end end ## # @return [Integer] def member_count @member_count ||= member_presenters.count end ## # Given a set of collections, which the caller asserts the current ability # can deposit to, decide whether to display actions to add this work to a # collection. # # By default, this returns `true` if any collections are passed in OR the # current ability can create a collection. # # @param collections [Enumerable<::Collection>, nil] list of collections to # which the current ability can deposit # # @return [Boolean] a flag indicating whether to display collection deposit # options. def show_deposit_for?(collections:) collections.present? || current_ability.can?(:create_any, Hyrax.config.collection_class) end ## # @return [Array] def valid_child_concerns Hyrax::ChildTypes.for(parent: solr_document.hydra_model).to_a end private # list of item ids to display is based on ordered_ids def authorized_item_ids(filter_unreadable: Flipflop.hide_private_items?) @member_item_list_ids ||= filter_unreadable ? ordered_ids.reject { |id| !current_ability.can?(:read, id) } : ordered_ids end # Uses kaminari to paginate an array to avoid need for solr documents for items here def paginated_item_list(page_array:) Kaminari.paginate_array(page_array, total_count: page_array.size).page(current_page).per(rows_from_params) end def total_items authorized_item_ids.size end def rows_from_params request.params[:rows].nil? ? Hyrax.config.show_work_item_rows : request.params[:rows].to_i end def current_page page = request.params[:page].nil? ? 1 : request.params[:page].to_i page > total_pages ? total_pages : page end def manifest_helper @manifest_helper ||= ManifestHelper.new(request.base_url) end def featured? # only look this up if it's not boolean; ||= won't work here @featured = FeaturedWork.where(work_id: solr_document.id).exists? if @featured.nil? @featured end def user_can_feature_works? current_ability.can?(:create, FeaturedWork) end def presenter_factory_arguments [current_ability, request] end def member_presenter_factory @member_presenter_factory ||= MemberPresenterFactory.new(solr_document, current_ability, request) end def graph GraphExporter.new(solr_document, hostname: request.host).fetch end # @return [Array] member_of_collection_ids with current_ability access def member_of_authorized_parent_collections @member_of ||= Hyrax::CollectionMemberService.run(solr_document, current_ability).map(&:id) end def members_include_viewable_image? file_set_presenters.any? { |presenter| presenter.image? && current_ability.can?(:read, presenter.id) } end end end