Skip to content

Commit

Permalink
Merge pull request #6 from scientist-softserv/create-a-work
Browse files Browse the repository at this point in the history
🧹 Get works created
  • Loading branch information
ShanaLMoore authored Sep 27, 2023
2 parents de05509 + 840f788 commit 6540a27
Show file tree
Hide file tree
Showing 20 changed files with 478 additions and 487 deletions.
233 changes: 94 additions & 139 deletions app/actors/hyrax/actors/collections_membership_actor.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

# OVERRIDE Hyrax 2.9 Skips the single collection assignment logic if importing
# OVERRIDE Hyrax 2.9 Skips permission checks if importing
# OVERRIDE Hyrax 3.5.0 Skips the single collection assignment logic if importing
# OVERRIDE Hyrax 3.5.0 Skips permission checks if importing

module Hyrax
module Actors
Expand All @@ -18,7 +18,7 @@ class CollectionsMembershipActor < AbstractActor
# @param [Hyrax::Actors::Environment] env
# @return [Boolean] true if create was successful
def create(env)
extract_collection_id(env) unless env.importing # OVERRIDE Hyrax 2.9
extract_collection_id(env) unless env.importing # OVERRIDE Hyrax 3.5.0
assign_nested_attributes_for_collection(env) && next_actor.create(env)
end

Expand All @@ -30,148 +30,103 @@ def update(env)

private

##
# Attaches any unattached members. Deletes those that are marked _delete
#
# @param env [Hyrax::Actors::Enviornment]
# @return [Boolean]
#
def assign_nested_attributes_for_collection(env)
attributes_collection = env.attributes.delete(:member_of_collections_attributes)

return assign_for_collection_ids(env) unless attributes_collection

emit_deprecation if env.attributes.delete(:member_of_collection_ids)
# OVERRIDE Hyrax 2.9
collection_id_map = attributes_collection.map { |_, attributes| attributes['id'] }
return false unless env.importing ||
valid_membership?(env, collection_ids: collection_id_map)

attributes_collection = attributes_collection.sort_by { |i, _| i.to_i }.map { |_, attributes| attributes }
# checking for existing works to avoid rewriting/loading works that are already attached
existing_collections = env.curation_concern.member_of_collection_ids
boolean_type_caster = ActiveModel::Type::Boolean.new
attributes_collection.each do |attributes|
next if attributes['id'].blank?
if boolean_type_caster.cast(attributes['_destroy'])
# Likely someone in the UI sought to add the collection, then
# changed their mind and checked the "delete" checkbox and posted
# their update.
next unless existing_collections.include?(attributes['id'])
remove(env.curation_concern, attributes['id'])
else
next if existing_collections.include?(attributes['id'])
add(env, attributes['id'])
end
end

true
end
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity

##
# @deprecated supports old :member_of_collection_ids arguments
def emit_deprecation
Deprecation.warn(self, ':member_of_collections_attributes and :member_of_collection_ids were both ' \
' passed. :member_of_collection_ids is ignored when both are passed and is ' \
'deprecated for removal in Hyrax 3.0.')
end

##
# @deprecated supports old :member_of_collection_ids arguments
def assign_for_collection_ids(env)
collection_ids = env.attributes.delete(:member_of_collection_ids)

return false unless valid_membership?(env, collection_ids: collection_ids)

if collection_ids
Deprecation.warn(self, ':member_of_collection_ids has been deprecated for removal in Hyrax 3.0. ' \
'use :member_of_collections_attributes instead.')

collection_ids = [] if collection_ids.empty?
other_collections = collections_without_edit_access(env)

collections = ::Collection.find(collection_ids)
raise "Tried to assign collections with ids: #{collection_ids}, but none were found" unless
collections

env.curation_concern.member_of_collections = collections
env.curation_concern.member_of_collections.concat(other_collections)
end

true
end

##
# @deprecated supports old :member_of_collection_ids arguments
def collections_without_edit_access(env)
env.curation_concern.member_of_collections.select { |coll| env.current_ability.cannot?(:edit, coll) }
end

# Adds the item to the ordered members so that it displays in the items
# along side the FileSets on the show page
def add(env, id)
collection = Collection.find(id)
collection.reindex_extent = Hyrax::Adapters::NestingIndexAdapter::LIMITED_REINDEX

return unless env.current_ability.can?(:deposit, collection)
env.curation_concern.member_of_collections << collection
end

# Remove the object from the members set and the ordered members list
def remove(curation_concern, id)
collection = Collection.find(id)
curation_concern.member_of_collections.delete(collection)
end

# Extact a singleton collection id from the collection attributes and save it in env. Later in the actor stack,
# in apply_permission_template_actor.rb, `env.attributes[:collection_id]` will be used to apply the
# permissions of the collection to the created work. With one and only one collection, the work is seen as
# being created directly in that collection. The permissions will not be applied to the work if the collection
# type is configured not to allow that or if the work is being created in more than one collection.
#
# @param env [Hyrax::Actors::Enviornment]
#
# Given an array of collection_attributes when it is size:
# * 0 do not set `env.attributes[:collection_id]`
# * 1 set `env.attributes[:collection_id]` to the one and only one collection
# * 2+ do not set `env.attributes[:collection_id]`
#
# NOTE: Only called from create. All collections are being added as parents of a work. None are being removed.
def extract_collection_id(env)
attributes_collection =
env.attributes.fetch(:member_of_collections_attributes) { nil }

if attributes_collection
# Determine if the work is being created in one and only one collection.
return unless attributes_collection && attributes_collection.size == 1

# Extract the collection id from attributes_collection,
collection_id = attributes_collection.first.second['id']
##
# Attaches any unattached members. Deletes those that are marked _delete
#
# @param env [Hyrax::Actors::Enviornment]
# @return [Boolean]
#
# rubocop:disable Metrics/MethodLength
# rubocop:disable Metrics/PerceivedComplexity
# rubocop:disable Metrics/CyclomaticComplexity
def assign_nested_attributes_for_collection(env)
attributes_collection = env.attributes.delete(:member_of_collections_attributes)
return true unless attributes_collection

# OVERRIDE Hyrax 3.5.0 to skip permission checks if importing
return false unless env.importing ||
valid_membership?(env, collection_ids: attributes_collection.map { |_, attributes| attributes['id'] })

attributes_collection = attributes_collection.sort_by { |i, _| i.to_i }.map { |_, attributes| attributes }
# checking for existing works to avoid rewriting/loading works that are already attached
existing_collections = env.curation_concern.member_of_collection_ids
boolean_type_caster = ActiveModel::Type::Boolean.new
attributes_collection.each do |attributes|
next if attributes['id'].blank?
if boolean_type_caster.cast(attributes['_destroy'])
# Likely someone in the UI sought to add the collection, then
# changed their mind and checked the "delete" checkbox and posted
# their update.
next unless existing_collections.include?(attributes['id'])
remove(env.curation_concern, attributes['id'])
else
collection_ids = env.attributes.fetch(:member_of_collection_ids) { [] }
return unless collection_ids.size == 1
collection_id = collection_ids.first
# Let's not try to add an item already
next if existing_collections.include?(attributes['id'])
add(env, attributes['id'])
end
end
true
end
# rubocop:enable Metrics/MethodLength
# rubocop:enable Metrics/PerceivedComplexity
# rubocop:enable Metrics/CyclomaticComplexity

# Adds the item to the ordered members so that it displays in the items
# along side the FileSets on the show page
def add(env, id)
collection = Hyrax.config.collection_class.find(id)
collection.try(:reindex_extent=, Hyrax::Adapters::NestingIndexAdapter::LIMITED_REINDEX)

return unless env.current_ability.can?(:deposit, collection)
env.curation_concern.member_of_collections << collection
end

# Do not apply permissions to work if collection type is configured not to
collection = ::Collection.find(collection_id)
return unless collection.share_applies_to_new_works?
# Remove the object from the members set and the ordered members list
def remove(curation_concern, id)
collection = Hyrax.config.collection_class.find(id)
curation_concern.member_of_collections.delete(collection)
end

# Save the collection id in env for use in apply_permission_template_actor
env.attributes[:collection_id] = collection_id
end
# Extact a singleton collection id from the collection attributes and save it in env. Later in the actor stack,
# in apply_permission_template_actor.rb, `env.attributes[:collection_id]` will be used to apply the
# permissions of the collection to the created work. With one and only one collection, the work is seen as
# being created directly in that collection. The permissions will not be applied to the work if the collection
# type is configured not to allow that or if the work is being created in more than one collection.
#
# @param env [Hyrax::Actors::Enviornment]
#
# Given an array of collection_attributes when it is size:
# * 0 do not set `env.attributes[:collection_id]`
# * 1 set `env.attributes[:collection_id]` to the one and only one collection
# * 2+ do not set `env.attributes[:collection_id]`
#
# NOTE: Only called from create. All collections are being added as parents of a work. None are being removed.
def extract_collection_id(env)
attributes_collection =
env.attributes.fetch(:member_of_collections_attributes) { nil }

# Determine if the work is being created in one and only one collection.
return unless attributes_collection && attributes_collection.size == 1

# Extract the collection id from attributes_collection,
collection_id = attributes_collection.first.second['id']

# Do not apply permissions to work if collection type is configured not to
collection = Hyrax.config.collection_class.find(collection_id)
return unless collection.share_applies_to_new_works?

# Save the collection id in env for use in apply_permission_template_actor
env.attributes[:collection_id] = collection_id
end

def valid_membership?(env, collection_ids:)
multiple_memberships = Hyrax::MultipleMembershipChecker.new(item: env.curation_concern)
multiple_memberships = multiple_memberships.check(collection_ids: collection_ids)
if multiple_memberships
env.curation_concern.errors.add(:collections, multiple_memberships)
return false
end
true
def valid_membership?(env, collection_ids:)
multiple_memberships = Hyrax::MultipleMembershipChecker.new(item: env.curation_concern).check(collection_ids: collection_ids)
if multiple_memberships
env.curation_concern.errors.add(:collections, multiple_memberships)
return false
end
true
end
end
end
end
25 changes: 25 additions & 0 deletions app/actors/hyrax/actors/environment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

# OVERRIDE Hyrax 2.9 to add in import flag
module Hyrax
module Actors
class Environment
# @param [ActiveFedora::Base] curation_concern work to operate on
# @param [Ability] current_ability the authorizations of the acting user
# @param [ActionController::Parameters] attributes user provided form attributes
def initialize(curation_concern, current_ability, attributes, importing = false)
@curation_concern = curation_concern
@current_ability = current_ability
@attributes = attributes.to_h.with_indifferent_access
@importing = importing
end

attr_accessor :curation_concern, :current_ability, :attributes, :importing

# @return [User] the user from the current_ability
def user
current_ability.current_user
end
end
end
end
1 change: 0 additions & 1 deletion app/models/.#solr_document_decoraotor.rb

This file was deleted.

4 changes: 2 additions & 2 deletions app/models/concerns/slug_bug.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ module SlugBug
extend ActiveSupport::Concern

included do
before_save :set_slug
try(:before_save, :set_slug)
# Cribbed from https://gitlab.com/notch8/louisville-hyku/-/blob/main/app/models/custom_slugs/slug_behavior.rb#L14
after_update :remove_index_and_reindex
try(:after_update, :remove_index_and_reindex)
end

def to_param
Expand Down
52 changes: 30 additions & 22 deletions app/models/generic_work_decorator.rb
Original file line number Diff line number Diff line change
@@ -1,29 +1,37 @@
# frozen_string_literal: true

module GenericWorkDecorator
extend ActiveSupport::Concern

include VideoEmbedViewer
include ::Hyrax::WorkBehavior
include DogBiscuits::Abstract
include DogBiscuits::BibliographicCitation
include DogBiscuits::DateIssued
include DogBiscuits::Geo
include DogBiscuits::PartOf
include DogBiscuits::PlaceOfPublication
include SlugBug
include IiifPrint.model_configuration(
pdf_split_child_model: self,
pdf_splitter_service: IiifPrint::SplitPdfs::AdventistPagesToJpgsSplitter,
derivative_service_plugins: [
IiifPrint::TextExtractionDerivativeService
]
)
end

GenericWork.prepend(GenericWorkDecorator)
GenericWork.include(VideoEmbedViewer)
GenericWork.include(::Hyrax::WorkBehavior)
GenericWork.include(DogBiscuits::Abstract)
GenericWork.include(DogBiscuits::BibliographicCitation)
GenericWork.include(DogBiscuits::DateIssued)
GenericWork.include(DogBiscuits::Geo)
GenericWork.include(DogBiscuits::PartOf)
GenericWork.include(DogBiscuits::PlaceOfPublication)
GenericWork.include(SlugBug)
GenericWork.include(IiifPrint.model_configuration(
pdf_split_child_model: self,
pdf_splitter_service: IiifPrint::SplitPdfs::AdventistPagesToJpgsSplitter,
derivative_service_plugins: [
IiifPrint::TextExtractionDerivativeService
]
))

# This must come after the properties because it finalizes the metadata
# schema (by adding accepts_nested_attributes)
GenericWork.include SlugMetadata
GenericWork.include AdventistMetadata

GenericWork.instance_variable_set(:@generated_resource_class, nil)
GenericWork.resource_class

GenericWork.resource_class.send(:include, SlugMetadata)
GenericWork.resource_class.send(:include, AdventistMetadata)
GenericWork.resource_class.send(:include, VideoEmbedViewer)
GenericWork.resource_class.send(:include, DogBiscuits::Abstract)
GenericWork.resource_class.send(:include, DogBiscuits::BibliographicCitation)
GenericWork.resource_class.send(:include, DogBiscuits::DateIssued)
GenericWork.resource_class.send(:include, DogBiscuits::Geo)
GenericWork.resource_class.send(:include, DogBiscuits::PartOf)
GenericWork.resource_class.send(:include, DogBiscuits::PlaceOfPublication)
GenericWork.resource_class.send(:include, SlugBug)
Loading

0 comments on commit 6540a27

Please sign in to comment.