hyrax 3.3.0 → 3.4.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.
Files changed (172) hide show
  1. checksums.yaml +4 -4
  2. data/.dassie/config/initializers/hyrax.rb +11 -1
  3. data/.gitignore +3 -0
  4. data/.regen +1 -1
  5. data/.rubocop_fixme.yml +3 -1
  6. data/Dockerfile +2 -1
  7. data/app/actors/hyrax/actors/file_actor.rb +6 -4
  8. data/app/actors/hyrax/actors/transfer_request_actor.rb +3 -7
  9. data/app/assets/javascripts/hyrax/analytics_events.js +8 -2
  10. data/app/assets/javascripts/hyrax/autocomplete/linked_data.es6 +1 -3
  11. data/app/controllers/concerns/hyrax/controller.rb +21 -0
  12. data/app/controllers/concerns/hyrax/works_controller_behavior.rb +83 -59
  13. data/app/controllers/hyrax/admin/admin_sets_controller.rb +105 -19
  14. data/app/controllers/hyrax/admin/permission_template_accesses_controller.rb +12 -19
  15. data/app/controllers/hyrax/batch_edits_controller.rb +12 -3
  16. data/app/controllers/hyrax/batch_uploads_controller.rb +4 -0
  17. data/app/controllers/hyrax/citations_controller.rb +1 -1
  18. data/app/controllers/hyrax/dashboard/collections_controller.rb +19 -10
  19. data/app/forms/hyrax/forms/administrative_set_form.rb +19 -1
  20. data/app/forms/hyrax/forms/batch_edit_form.rb +1 -1
  21. data/app/forms/hyrax/forms/dashboard/nest_collection_form.rb +21 -6
  22. data/app/forms/hyrax/forms/pcdm_collection_form.rb +1 -0
  23. data/app/forms/hyrax/forms/permission_template_form.rb +17 -9
  24. data/app/forms/hyrax/forms/resource_form.rb +9 -5
  25. data/app/helpers/hyrax/collections_helper.rb +14 -0
  26. data/app/helpers/hyrax/membership_helper.rb +1 -1
  27. data/app/helpers/hyrax/trophy_helper.rb +1 -1
  28. data/app/helpers/hyrax/url_helper.rb +1 -1
  29. data/app/indexers/hyrax/administrative_set_indexer.rb +8 -2
  30. data/app/indexers/hyrax/deep_indexing_service.rb +1 -1
  31. data/app/indexers/hyrax/file_set_indexer.rb +1 -0
  32. data/app/indexers/hyrax/pcdm_collection_indexer.rb +3 -1
  33. data/app/indexers/hyrax/thumbnail_indexer.rb +31 -0
  34. data/app/indexers/hyrax/valkyrie_file_set_indexer.rb +6 -6
  35. data/app/indexers/hyrax/valkyrie_indexer.rb +4 -2
  36. data/app/indexers/hyrax/valkyrie_work_indexer.rb +13 -0
  37. data/app/inputs/controlled_vocabulary_input.rb +2 -0
  38. data/app/jobs/change_depositor_event_job.rb +47 -0
  39. data/app/jobs/characterize_job.rb +38 -2
  40. data/app/jobs/concerns/hyrax/members_permission_job_behavior.rb +1 -1
  41. data/app/jobs/content_depositor_change_event_job.rb +2 -1
  42. data/app/jobs/hyrax/propagate_change_depositor_job.rb +32 -0
  43. data/app/jobs/inherit_permissions_job.rb +1 -1
  44. data/app/jobs/valkyrie_create_derivatives_job.rb +25 -0
  45. data/app/jobs/valkyrie_ingest_job.rb +84 -16
  46. data/app/models/admin_set.rb +2 -2
  47. data/app/models/collection_branding_info.rb +8 -6
  48. data/app/models/concerns/hyrax/collection_behavior.rb +2 -2
  49. data/app/models/concerns/hyrax/file_set/characterization.rb +7 -1
  50. data/app/models/concerns/hyrax/solr_document/metadata.rb +1 -0
  51. data/app/models/concerns/hyrax/solr_document_behavior.rb +9 -3
  52. data/app/models/hyrax/administrative_set.rb +36 -1
  53. data/app/models/hyrax/collection_type.rb +2 -2
  54. data/app/models/hyrax/file_metadata.rb +5 -1
  55. data/app/models/hyrax/file_set.rb +42 -1
  56. data/app/models/hyrax/pcdm_collection.rb +56 -0
  57. data/app/models/hyrax/permission_template.rb +11 -5
  58. data/app/models/hyrax/work.rb +91 -0
  59. data/app/models/proxy_deposit_request.rb +1 -1
  60. data/app/presenters/hyrax/admin_set_presenter.rb +2 -2
  61. data/app/presenters/hyrax/pcdm_member_presenter_factory.rb +2 -2
  62. data/app/presenters/hyrax/work_show_presenter.rb +7 -3
  63. data/app/search_builders/hyrax/dashboard/collections_search_builder.rb +2 -2
  64. data/app/search_builders/hyrax/dashboard/managed_search_filters.rb +44 -4
  65. data/app/search_builders/hyrax/dashboard/nested_collections_search_builder.rb +2 -2
  66. data/app/search_builders/hyrax/my/collections_search_builder.rb +11 -4
  67. data/app/services/hyrax/access_control_list.rb +13 -0
  68. data/app/services/hyrax/admin_set_create_service.rb +21 -37
  69. data/app/services/hyrax/change_content_depositor_service.rb +2 -2
  70. data/app/services/hyrax/change_depositor_service.rb +70 -0
  71. data/app/services/hyrax/characterization/valkyrie_characterization_service.rb +1 -1
  72. data/app/services/hyrax/collections/nested_collection_query_service.rb +23 -11
  73. data/app/services/hyrax/custom_queries/navigators/child_file_sets_navigator.rb +45 -0
  74. data/app/services/hyrax/custom_queries/navigators/child_filesets_navigator.rb +7 -2
  75. data/app/services/hyrax/custom_queries/navigators/parent_work_navigator.rb +54 -0
  76. data/app/services/hyrax/default_middleware_stack.rb +3 -0
  77. data/app/services/hyrax/file_set_derivatives_service.rb +21 -2
  78. data/app/services/hyrax/file_set_type_service.rb +2 -5
  79. data/app/services/hyrax/listeners/file_metadata_listener.rb +20 -1
  80. data/app/services/hyrax/listeners/member_cleanup_listener.rb +23 -3
  81. data/app/services/hyrax/listeners/metadata_index_listener.rb +39 -0
  82. data/app/services/hyrax/listeners/proxy_deposit_listener.rb +14 -8
  83. data/app/services/hyrax/location_service.rb +33 -0
  84. data/app/services/hyrax/multiple_membership_checker.rb +44 -1
  85. data/app/services/hyrax/resource_visibility_propagator.rb +1 -1
  86. data/app/services/hyrax/simple_schema_loader.rb +5 -1
  87. data/app/services/hyrax/solr_query_service.rb +12 -7
  88. data/app/services/hyrax/thumbnail_path_service.rb +1 -1
  89. data/app/services/hyrax/work_uploads_handler.rb +0 -10
  90. data/app/validators/hyrax/collection_membership_validator.rb +38 -0
  91. data/app/views/catalog/_index_header_list_hyrax_pcdm_collection.html.erb +4 -0
  92. data/app/views/hyrax/admin/admin_sets/_form_participant_table.html.erb +2 -2
  93. data/app/views/hyrax/admin/admin_sets/_form_participants.html.erb +2 -2
  94. data/app/views/hyrax/admin/admin_sets/_form_visibility.html.erb +2 -2
  95. data/app/views/hyrax/admin/admin_sets/_form_workflow.erb +1 -1
  96. data/app/views/hyrax/admin/collection_types/index.html.erb +1 -1
  97. data/app/views/hyrax/base/_form.html.erb +1 -1
  98. data/app/views/hyrax/base/_form_child_work_relationships.html.erb +1 -1
  99. data/app/views/hyrax/dashboard/collections/_default_group.html.erb +2 -2
  100. data/app/views/hyrax/dashboard/collections/_form.html.erb +21 -15
  101. data/app/views/hyrax/dashboard/collections/_form_discovery.html.erb +6 -3
  102. data/app/views/hyrax/dashboard/collections/_form_share.html.erb +2 -2
  103. data/app/views/hyrax/dashboard/collections/_form_share_table.html.erb +3 -3
  104. data/app/views/hyrax/dashboard/collections/_list_collections.html.erb +2 -2
  105. data/app/views/hyrax/dashboard/works/_default_group.html.erb +1 -1
  106. data/app/views/hyrax/dashboard/works/_list_works.html.erb +1 -1
  107. data/app/views/hyrax/file_sets/_actions.html.erb +2 -2
  108. data/app/views/hyrax/my/_work_action_menu.html.erb +8 -9
  109. data/app/views/hyrax/my/collections/_default_group.html.erb +2 -2
  110. data/app/views/hyrax/my/collections/_list_collections.html.erb +2 -2
  111. data/app/views/hyrax/my/collections/index.html.erb +3 -2
  112. data/app/views/hyrax/my/works/_default_group.html.erb +1 -1
  113. data/app/views/hyrax/my/works/_list_works.html.erb +1 -2
  114. data/app/views/hyrax/my/works/index.html.erb +4 -2
  115. data/chart/hyrax/Chart.yaml +2 -2
  116. data/chart/hyrax/README.md +22 -1
  117. data/config/initializers/listeners.rb +0 -1
  118. data/config/locales/hyrax.de.yml +6 -5
  119. data/config/locales/hyrax.en.yml +30 -28
  120. data/config/locales/hyrax.es.yml +10 -9
  121. data/config/locales/hyrax.fr.yml +2 -1
  122. data/config/locales/hyrax.it.yml +3 -2
  123. data/config/locales/hyrax.pt-BR.yml +2 -1
  124. data/config/locales/hyrax.zh.yml +2 -1
  125. data/config/metadata/basic_metadata.yaml +2 -0
  126. data/config/metadata/core_metadata.yaml +1 -1
  127. data/docker-compose.yml +46 -42
  128. data/documentation/developing-your-hyrax-based-app.md +1 -1
  129. data/documentation/legacyREADME.md +1 -1
  130. data/lib/hyrax/administrative_set_name.rb +18 -0
  131. data/lib/hyrax/collection_name.rb +2 -0
  132. data/lib/hyrax/configuration.rb +10 -0
  133. data/lib/hyrax/controlled_vocabularies/location.rb +9 -2
  134. data/lib/hyrax/controlled_vocabularies/resource_label_caching.rb +42 -0
  135. data/lib/hyrax/controlled_vocabularies.rb +1 -0
  136. data/lib/hyrax/publisher.rb +45 -0
  137. data/lib/hyrax/specs/capybara.rb +1 -1
  138. data/lib/hyrax/specs/shared_specs/hydra_works.rb +11 -4
  139. data/lib/hyrax/specs/shared_specs/indexers.rb +117 -3
  140. data/lib/hyrax/transactions/admin_set_create.rb +2 -1
  141. data/lib/hyrax/transactions/admin_set_destroy.rb +22 -0
  142. data/lib/hyrax/transactions/admin_set_update.rb +21 -0
  143. data/lib/hyrax/transactions/collection_destroy.rb +22 -0
  144. data/lib/hyrax/transactions/collection_update.rb +3 -2
  145. data/lib/hyrax/transactions/container.rb +87 -23
  146. data/lib/hyrax/transactions/create_work.rb +3 -0
  147. data/lib/hyrax/transactions/destroy_work.rb +3 -0
  148. data/lib/hyrax/transactions/steps/apply_collection_permission_template.rb +2 -0
  149. data/lib/hyrax/transactions/steps/apply_permission_template.rb +2 -0
  150. data/lib/hyrax/transactions/steps/apply_visibility.rb +2 -0
  151. data/lib/hyrax/transactions/steps/change_depositor.rb +46 -0
  152. data/lib/hyrax/transactions/steps/check_for_empty_admin_set.rb +36 -0
  153. data/lib/hyrax/transactions/steps/delete_access_control.rb +32 -0
  154. data/lib/hyrax/transactions/steps/delete_resource.rb +19 -3
  155. data/lib/hyrax/transactions/steps/destroy_work.rb +3 -1
  156. data/lib/hyrax/transactions/steps/ensure_permission_template.rb +2 -0
  157. data/lib/hyrax/transactions/steps/save.rb +24 -6
  158. data/lib/hyrax/transactions/steps/save_access_control.rb +2 -2
  159. data/lib/hyrax/transactions/steps/save_work.rb +3 -0
  160. data/lib/hyrax/transactions/steps/set_user_as_creator.rb +41 -0
  161. data/lib/hyrax/transactions/steps/update_work_members.rb +51 -0
  162. data/lib/hyrax/transactions/update_work.rb +4 -3
  163. data/lib/hyrax/transactions/work_create.rb +1 -1
  164. data/lib/hyrax/transactions/work_destroy.rb +2 -1
  165. data/lib/hyrax/transactions/work_update.rb +19 -0
  166. data/lib/hyrax/version.rb +1 -1
  167. data/lib/wings/attribute_transformer.rb +5 -1
  168. data/lib/wings/setup.rb +3 -1
  169. data/lib/wings/valkyrie/query_service.rb +2 -1
  170. data/lib/wings/valkyrie/storage.rb +7 -1
  171. data/template.rb +1 -1
  172. metadata +24 -3
@@ -5,6 +5,40 @@ require_dependency 'hyrax/collection_name'
5
5
  module Hyrax
6
6
  ##
7
7
  # Valkyrie model for Collection domain objects in the Hydra Works model.
8
+ #
9
+ # ## Relationships
10
+ #
11
+ # ### Collection and Collection (TBA)
12
+ #
13
+ # ### Collection and Work
14
+ #
15
+ # * Defined: The relationship is defined by the inverse relationship stored in the
16
+ # work's `:member_of_collection_ids` attribute.
17
+ # * Tested: The work tests the relationship.
18
+ # * Collection to Work: (0..m) A collection can have many works.
19
+ #
20
+ # @example Get works in a collection:
21
+ # works = Hyrax.custom_queries.find_child_works(resource: collection)
22
+ #
23
+ # * Work to Collection: (0..m) A work can be in many collections.
24
+ # * See Hyrax::Work for code to get and set collections for the work.
25
+ #
26
+ # @note Some collection types limit a work to belong to one and only one collection of that type.
27
+ #
28
+ # ### All children
29
+ #
30
+ # * There are additional methods for finding all children without respect to
31
+ # the child's type.
32
+ #
33
+ # @example Get works and child collections in a collection using:
34
+ # members = Hyrax.custom_queries.find_members_of(resource: collection)
35
+ #
36
+ # @see Hyrax::Work
37
+ #
38
+ # @see Hyrax::CustomQueries::Navigators::ChildCollectionsNavigator#find_child_collections
39
+ # @see Hyrax::CustomQueries::Navigators::ChildWorksNavigator#find_child_works
40
+ # @see Hyrax::CustomQueries::Navigators::CollectionMembers#find_members_of
41
+ #
8
42
  class PcdmCollection < Hyrax::Resource
9
43
  include Hyrax::Schema(:core_metadata)
10
44
  include Hyrax::Schema(:basic_metadata)
@@ -32,5 +66,27 @@ module Hyrax
32
66
  def pcdm_object?
33
67
  true
34
68
  end
69
+
70
+ def permission_manager
71
+ @permission_manager ||= Hyrax::PermissionManager.new(resource: self)
72
+ end
73
+
74
+ def visibility=(value)
75
+ visibility_writer.assign_access_for(visibility: value)
76
+ end
77
+
78
+ def visibility
79
+ visibility_reader.read
80
+ end
81
+
82
+ protected
83
+
84
+ def visibility_writer
85
+ Hyrax::VisibilityWriter.new(resource: self)
86
+ end
87
+
88
+ def visibility_reader
89
+ Hyrax::VisibilityReader.new(resource: self)
90
+ end
35
91
  end
36
92
  end
@@ -4,7 +4,7 @@ module Hyrax
4
4
  # Holds policy data about the workflow and permissions applied objects when
5
5
  # they are deposited through an Administrative Set or a Collection. Each
6
6
  # template record has a {#source} (through {#source_id}); the template's
7
- # rules inform the behavior of objects deposited through that {#source_model}.
7
+ # rules inform the behavior of objects deposited through that {#source}.
8
8
  #
9
9
  # The {PermissionTemplate} specifies:
10
10
  #
@@ -81,6 +81,10 @@ module Hyrax
81
81
  # A bit of an analogue for a `belongs_to :source_model` as it crosses from Fedora to the DB
82
82
  # @return [AdminSet, ::Collection]
83
83
  # @raise [Hyrax::ObjectNotFoundError] when neither an AdminSet or Collection is found
84
+ # @note This method will eventually be replaced by #source which returns a Hyrax::Resource
85
+ # object. Many methods are equally able to process both Hyrax::Resource and
86
+ # ActiveFedora::Base. Only call this method if you need the ActiveFedora::Base object.
87
+ # @see #source
84
88
  def source_model
85
89
  ActiveFedora::Base.find(source_id)
86
90
  rescue ActiveFedora::ObjectNotFoundError
@@ -88,11 +92,11 @@ module Hyrax
88
92
  end
89
93
 
90
94
  # A bit of an analogue for a `belongs_to :admin_set` as it crosses from Fedora to the DB
91
- # @deprecated Use #source_model instead
95
+ # @deprecated Use #source instead
92
96
  # @return [AdminSet]
93
97
  # @raise [Hyrax::ObjectNotFoundError] when the we cannot find the AdminSet
94
98
  def admin_set
95
- Deprecation.warn('Use #source_model instead')
99
+ Deprecation.warn("#admin_set is deprecated; use #source instead.")
96
100
  return AdminSet.find(source_id) if AdminSet.exists?(source_id)
97
101
  raise Hyrax::ObjectNotFoundError
98
102
  rescue ActiveFedora::ActiveFedoraError # TODO: remove the rescue when active_fedora issue #1276 is fixed
@@ -100,11 +104,11 @@ module Hyrax
100
104
  end
101
105
 
102
106
  # A bit of an analogue for a `belongs_to :collection` as it crosses from Fedora to the DB
103
- # @deprecated Use #source_model instead
107
+ # @deprecated Use #source instead
104
108
  # @return [Collection]
105
109
  # @raise [Hyrax::ObjectNotFoundError] when the we cannot find the Collection
106
110
  def collection
107
- Deprecation.warn('Use #source_model instead')
111
+ Deprecation.warn("#collection is deprecated; use #source instead.")
108
112
  return ::Collection.find(source_id) if ::Collection.exists?(source_id)
109
113
  raise Hyrax::ObjectNotFoundError
110
114
  rescue ActiveFedora::ActiveFedoraError # TODO: remove the rescue when active_fedora issue #1276 is fixed
@@ -216,10 +220,12 @@ module Hyrax
216
220
  end
217
221
 
218
222
  ##
223
+ # @deprecated Use #reset_access_controls_for instead
219
224
  # @param interpret_visibility [Boolean] whether to retain the existing
220
225
  # visibility when applying permission template ACLs
221
226
  # @return [Boolean]
222
227
  def reset_access_controls(interpret_visibility: false)
228
+ Deprecation.warn("#reset_access_controls is deprecated; use #reset_access_controls_for instead.")
223
229
  reset_access_controls_for(collection: source_model,
224
230
  interpret_visibility: interpret_visibility)
225
231
  end
@@ -4,6 +4,97 @@ module Hyrax
4
4
  ##
5
5
  # Valkyrie model for `Work` domain objects in the Hydra Works model.
6
6
  #
7
+ # ## Relationships
8
+ #
9
+ # ### Administrative Set and Work
10
+ #
11
+ # * Defined: The relationship is defined by the work's `:admin_set_id` attribute.
12
+ # * Tested: The relationship is tested in shared spec `'a Hyrax::Work'` by testing
13
+ # `#admin_set_id`. Shared specs are defined in /lib/hyrax/specs/shared_specs/hydra_works.rb.
14
+ # * Administrative Set to Work: (1..m) An admin set can have many works.
15
+ # * See Hyrax::AdministrativeSet for code to get works in an admin set.
16
+ # * Work to Administrative Set: (1..1) A work must be in one and only one admin set.
17
+ #
18
+ # @example Set admin set for a work:
19
+ # work.admin_set_id = admin_set.id
20
+ # @example Get admin set a work is in:
21
+ # admin_set = Hyrax.query_service.find_by(id: work.admin_set_id)
22
+ #
23
+ # ### Collection and Work
24
+ #
25
+ # * Defined: The relationship is defined by the work's `:member_of_collection_ids` attribute.
26
+ # * Tested: The relationship is tested in shared spec `'a Hyrax::Work'` by testing
27
+ # `it_behaves_like 'belongs to collections'`. Shared specs are defined in /lib/hyrax/specs/shared_specs/hydra_works.rb.
28
+ # * Collection to Work: (0..m) A collection can have many works.
29
+ # * See Hyrax::PcdmCollection for code to get works in a collection.
30
+ # * Work to Collection: (0..m) A work can be in many collections.
31
+ #
32
+ # @example Add a work to a collection using Hyrax::CollectionMemberService (multiple method options)
33
+ # Hyrax::CollectionMemberService.add_members(collection_id: col.id, members: works, user: current_user)
34
+ # @example Get collections a work is in:
35
+ # collections = Hyrax.custom_queries.find_collections_for(resource: work)
36
+ #
37
+ # @note Some collection types limit a work to belong to one and only one collection of that type.
38
+ #
39
+ # ### Work and Work
40
+ #
41
+ # * Defined: The relationship is defined in the parent work's `:member_ids` attribute.
42
+ # * Tested: The relationship is tested in shared spec `'a Hyrax::Work'` by testing
43
+ # `it_behaves_like 'has_members'`. Shared specs are defined in /lib/hyrax/specs/shared_specs/hydra_works.rb.
44
+ # * Work to child Work: (0..m) A work can have many child works.
45
+ #
46
+ # @example Add a child work to a work:
47
+ # Hyrax::Transactions::Container['work_resource.add_to_parent']
48
+ # .call(child_work, parent_id: parent_work.id, user: current_user)
49
+ # @example Get child works:
50
+ # works = Hyrax.custom_queries.find_child_works(resource: parent_work)
51
+ #
52
+ # * Work to parent Work: (0..1) A work can be in at most one parent work.
53
+ #
54
+ # @example Get parent work:
55
+ # parent_work = Hyrax.custom_queries.find_parent_work(resource: child_work)
56
+ #
57
+ # @note `:member_ids` holds ids of child works and file sets.
58
+ #
59
+ # ### Work and File Set
60
+ #
61
+ # * Defined: The relationship is defined in the parent work's `:member_ids` attribute.
62
+ # * Tested: The relationship is tested in shared spec `'a Hyrax::Work'` by testing
63
+ # `it_behaves_like 'has_members'`. Shared specs are defined in /lib/hyrax/specs/shared_specs/hydra_works.rb.
64
+ # * Work to File Set: (0..m) A work can have many file sets.
65
+ # @example Add a file set to a work (code from Hyrax::WorkUploadsHandler#append_to_work)
66
+ # work.member_ids << file_set.id
67
+ # work.representative_id = file_set.id if work.respond_to?(:representative_id) && work.representative_id.blank?
68
+ # work.thumbnail_id = file_set.id if work.respond_to?(:thumbnail_id) && work.thumbnail_id.blank?
69
+ # Hyrax.persister.save(resource: work)
70
+ # Hyrax.publisher.publish('object.metadata.updated', object: work, user: files.first.user)
71
+ # @example Get file sets:
72
+ # file_sets = Hyrax.custom_queries.find_child_file_sets(resource: work)
73
+ #
74
+ # * File Set to Work: (1..1) A file set must be in one and only one work.
75
+ # * See Hyrax::FileSet for code to get the work a file set is in.
76
+ #
77
+ # @see Hyrax::AdministrativeSet
78
+ # @see Hyrax::PcdmCollection
79
+ # @see Hyrax::FileSet
80
+ #
81
+ # @see Hyrax::CollectionMemberService
82
+ # @see Hyrax::Transactions::Steps::AddToParent
83
+ # @see Hyrax::Transactions::Steps::AddFileSets
84
+ # @see Hyrax::WorksControllerBehavior
85
+ # @see Hyrax::WorkUploadsHandler#append_to_work
86
+ #
87
+ # @see Valkyrie query adapter's #find_by
88
+ # @see Hyrax::CustomQueries::Navigators::CollectionMembers#find_collections_for
89
+ # @see Hyrax::CustomQueries::Navigators::ParentWorkNavigator#find_parent_work
90
+ # @see Hyrax::CustomQueries::Navigators::ChildFileSetsNavigator#find_child_file_sets
91
+ #
92
+ # @see /lib/hyrax/specs/shared_specs/hydra_works.rb
93
+ #
94
+ # @todo The description in Hydra::Works Shared Modeling is out of date and uses
95
+ # terminology to describe the relationships that is no longer used in code.
96
+ # Update the model and link to it. This can be a simple relationship diagram
97
+ # with a link to the original Works Shared Modeling for historical perspective.
7
98
  # @see https://wiki.lyrasis.org/display/samvera/Hydra::Works+Shared+Modeling
8
99
  class Work < Hyrax::Resource
9
100
  include Hyrax::Schema(:core_metadata)
@@ -129,7 +129,7 @@ class ProxyDepositRequest < ActiveRecord::Base
129
129
 
130
130
  # @param [TrueClass,FalseClass] reset (false) if true, reset the access controls. This revokes edit access from the depositor
131
131
  def transfer!(reset = false)
132
- ContentDepositorChangeEventJob.perform_later(work, receiving_user, reset)
132
+ Hyrax::ChangeDepositorService.call(work, receiving_user, reset)
133
133
  fulfill!(status: ACCEPTED)
134
134
  end
135
135
 
@@ -8,11 +8,11 @@ module Hyrax
8
8
  end
9
9
 
10
10
  def total_items
11
- Hyrax::SolrService.count("{!field f=isPartOf_ssim}#{id}")
11
+ Hyrax::SolrService.count("{!field f=#{Hyrax.config.admin_set_predicate.qname.last}_ssim}#{id}")
12
12
  end
13
13
 
14
14
  def total_viewable_items
15
- field_pairs = { "isPartOf_ssim" => id.to_s }
15
+ field_pairs = { "#{Hyrax.config.admin_set_predicate.qname.last}_ssim" => id.to_s }
16
16
  SolrQueryService.new
17
17
  .with_field_pairs(field_pairs: field_pairs)
18
18
  .accessible_by(ability: current_ability)
@@ -97,7 +97,7 @@ module Hyrax
97
97
  # @return
98
98
  def presenter_for(document:, ability:)
99
99
  case document['has_model_ssim'].first
100
- when Hyrax::FileSet.name
100
+ when Hyrax::FileSet.name, ::FileSet.name # ActiveFedora FileSet within a Valkyrie Resource
101
101
  Hyrax::FileSetPresenter.new(document, ability)
102
102
  else
103
103
  Hyrax::WorkShowPresenter.new(document, ability)
@@ -111,7 +111,7 @@ module Hyrax
111
111
  query += "{!term f=generic_type_si}#{generic_type}" if generic_type
112
112
 
113
113
  Hyrax::SolrService
114
- .post(query, rows: 10_000)
114
+ .post(q: query, rows: 10_000)
115
115
  .fetch('response')
116
116
  .fetch('docs')
117
117
  end
@@ -305,9 +305,13 @@ module Hyrax
305
305
 
306
306
  def member_presenter_factory
307
307
  @member_presenter_factory ||=
308
- self.class
309
- .presenter_factory_class
310
- .new(solr_document, current_ability, request)
308
+ if solr_document.hydra_model < Valkyrie::Resource
309
+ PcdmMemberPresenterFactory.new(solr_document, current_ability)
310
+ else
311
+ self.class
312
+ .presenter_factory_class
313
+ .new(solr_document, current_ability, request)
314
+ end
311
315
  end
312
316
 
313
317
  def graph
@@ -9,7 +9,7 @@ module Hyrax
9
9
 
10
10
  # This overrides the models in FilterByType
11
11
  def models
12
- [::AdminSet, ::Collection, Hyrax.config.collection_class].uniq.compact
12
+ [::AdminSet, Hyrax::AdministrativeSet, ::Collection, Hyrax.config.collection_class].uniq.compact
13
13
  end
14
14
 
15
15
  # adds a filter to exclude collections and admin sets created by the
@@ -19,7 +19,7 @@ module Hyrax
19
19
  return if current_ability.admin?
20
20
  clauses = [
21
21
  '-' + ActiveFedora::SolrQueryBuilder.construct_query_for_rel(depositor: current_user_key),
22
- '-' + ActiveFedora::SolrQueryBuilder.construct_query_for_rel(has_model: ::AdminSet.to_s, creator: current_user_key)
22
+ '-' + ActiveFedora::SolrQueryBuilder.construct_query_for_rel(has_model: Hyrax.config.admin_set_model, creator: current_user_key)
23
23
  ]
24
24
  solr_parameters[:fq] ||= []
25
25
  solr_parameters[:fq] += ["(#{clauses.join(' OR ')})"]
@@ -11,15 +11,55 @@ module Hyrax
11
11
 
12
12
  # Override to exclude 'public' and 'registered' groups from read access.
13
13
  def apply_group_permissions(permission_types, ability = current_ability)
14
+ search_terms = add_managing_role_search_filter(ability: ability)
14
15
  groups = ability.user_groups
15
- return [] if groups.empty?
16
- permission_types.map do |type|
16
+ return search_terms if groups.empty?
17
+ permission_types.each do |type|
17
18
  field = solr_field_for(type, 'group')
18
- user_groups = type == 'read' ? groups - [::Ability.public_group_name, ::Ability.registered_group_name] : groups
19
+ delete_groups = [::Ability.public_group_name, ::Ability.registered_group_name]
20
+ user_groups = type == 'read' ? groups - delete_groups : groups
19
21
  next if user_groups.empty?
20
- "({!terms f=#{field}}#{user_groups.join(',')})" # parens required to properly OR the clauses together.
22
+ # parens required to properly OR the clauses together:
23
+ search_terms << "({!terms f=#{field}}#{user_groups.join(',')})"
21
24
  end
25
+ search_terms
22
26
  end
27
+
28
+ # Look for a user's managing role and add filters for all admin sets that have permission
29
+ # templates that include managing roles.
30
+ #
31
+ # rubocop:disable Metrics/MethodLength
32
+ # rubocop:disable Metrics/PerceivedComplexity
33
+ # rubocop:disable Metrics/CyclomaticComplexity
34
+ def add_managing_role_search_filter(ability:, search_terms: [])
35
+ search_terms ||= []
36
+ # Look for managing role assignement
37
+ managing_role = Sipity::Role.find_by(name: Hyrax::RoleRegistry::MANAGING)
38
+ return search_terms if managing_role.blank?
39
+ agent = ability.current_user.to_sipity_agent
40
+ return search_terms if agent.workflow_responsibilities.blank?
41
+ managing_workflow_roles = []
42
+ agent.workflow_responsibilities.each do |workflow_responsibility|
43
+ wfr = Sipity::WorkflowRole.find_by(id: workflow_responsibility.workflow_role_id)
44
+ managing_workflow_roles << wfr if wfr.role_id == managing_role.id
45
+ end
46
+ return search_terms if managing_workflow_roles.empty?
47
+ # if the user has managing responsibilties, then look up the associated admin set ids
48
+ admin_set_ids = managing_workflow_roles.map do |wfr|
49
+ wf = Sipity::Workflow.find_by(id: wfr.workflow_id)
50
+ pt = Hyrax::PermissionTemplate.find_by(id: wf.permission_template_id)
51
+ pt.source_id
52
+ end
53
+ admin_set_ids.uniq!
54
+ # create search terms for works that are in managed admin sets
55
+ admin_set_ids.each do |id|
56
+ search_terms << "isPartOf_ssim:#{id}"
57
+ end
58
+ search_terms
59
+ end
60
+ # rubocop:enable Metrics/MethodLength
61
+ # rubocop:enable Metrics/PerceivedComplexity
62
+ # rubocop:enable Metrics/CyclomaticComplexity
23
63
  end
24
64
  end
25
65
  end
@@ -37,7 +37,7 @@ module Hyrax
37
37
 
38
38
  def limit_ids
39
39
  # exclude current collection from returned list
40
- limit_ids = [@collection.id]
40
+ limit_ids = [@collection.id.to_s]
41
41
  # cannot add a parent that is already a parent
42
42
  limit_ids += @nesting_attributes.parents if @nesting_attributes.parents && @nest_direction == :as_parent
43
43
  limit_ids
@@ -91,7 +91,7 @@ module Hyrax
91
91
 
92
92
  def exclude_if_already_parent
93
93
  # 2) Exclude any of Collection F's direct children
94
- "-" + ActiveFedora::SolrQueryBuilder.construct_query(Samvera::NestingIndexer.configuration.solr_field_name_for_storing_parent_ids => @collection.id)
94
+ "-" + ActiveFedora::SolrQueryBuilder.construct_query(Samvera::NestingIndexer.configuration.solr_field_name_for_storing_parent_ids => @collection.id.to_s)
95
95
  end
96
96
  end
97
97
  end
@@ -10,10 +10,7 @@ class Hyrax::My::CollectionsSearchBuilder < ::Hyrax::CollectionSearchBuilder
10
10
  # the current user has deposited
11
11
  # @param [Hash] solr_parameters
12
12
  def show_only_collections_deposited_by_current_user(solr_parameters)
13
- clauses = [
14
- ActiveFedora::SolrQueryBuilder.construct_query_for_rel(depositor: current_user_key),
15
- ActiveFedora::SolrQueryBuilder.construct_query_for_rel(has_model: ::AdminSet.to_s, creator: current_user_key)
16
- ]
13
+ clauses = [query_for_my_collections]
17
14
  solr_parameters[:fq] ||= []
18
15
  solr_parameters[:fq] += ["(#{clauses.join(' OR ')})"]
19
16
  end
@@ -23,4 +20,14 @@ class Hyrax::My::CollectionsSearchBuilder < ::Hyrax::CollectionSearchBuilder
23
20
  def models
24
21
  [::AdminSet, Hyrax::AdministrativeSet, ::Collection, Hyrax.config.collection_class].uniq.compact
25
22
  end
23
+
24
+ private
25
+
26
+ def query_for_my_collections
27
+ query_service = Hyrax::SolrQueryService.new
28
+ query_service.with_field_pairs(field_pairs: { depositor_ssim: current_user_key }, type: 'terms')
29
+ query_service.with_field_pairs(field_pairs: { has_model_ssim: Hyrax.config.admin_set_model,
30
+ creator_ssim: current_user_key }, type: 'terms')
31
+ query_service.build(join_with: 'OR')
32
+ end
26
33
  end
@@ -174,6 +174,19 @@ module Hyrax
174
174
  true
175
175
  end
176
176
 
177
+ ##
178
+ # @api public
179
+ #
180
+ # Deletes the ACL for the resource
181
+ #
182
+ # @return [Boolean]
183
+ def destroy
184
+ persister.delete(resource: change_set.resource) if change_set.resource.persisted?
185
+ @change_set = nil
186
+
187
+ true
188
+ end
189
+
177
190
  private
178
191
 
179
192
  ##
@@ -64,7 +64,7 @@ module Hyrax
64
64
  Deprecation.warn("'##{__method__}' will be removed in Hyrax 4.0. " \
65
65
  "Warning: This method may hide runtime errors. " \
66
66
  "Instead, use 'Hyrax::AdminSetCreateService.call!'. ")
67
- call!(admin_set: admin_set, creating_user: creating_user, **kwargs).present?
67
+ call!(admin_set: admin_set_resource(admin_set), creating_user: creating_user, **kwargs).present?
68
68
  rescue RuntimeError => err
69
69
  raise err if default_admin_set?(id: admin_set.id)
70
70
  false
@@ -152,13 +152,22 @@ module Hyrax
152
152
  id = find_unsaved_default_admin_set&.id&.to_s if id.blank?
153
153
  id
154
154
  end
155
+
156
+ def admin_set_resource(admin_set)
157
+ case admin_set
158
+ when Valkyrie::Resource
159
+ admin_set
160
+ else
161
+ admin_set.valkyrie_resource
162
+ end
163
+ end
155
164
  end
156
165
 
157
166
  # @param admin_set [Hyrax::AdministrativeSet | AdminSet] the admin set to operate on
158
167
  # @param creating_user [User] the user who created the admin set (if any).
159
168
  # @param workflow_importer [#call] imports the workflow
160
169
  def initialize(admin_set:, creating_user:, workflow_importer: default_workflow_importer, default_admin_set: false)
161
- @admin_set = admin_set
170
+ @admin_set = Hyrax::AdminSetCreateService.send(:admin_set_resource, admin_set)
162
171
  @creating_user = creating_user
163
172
  @workflow_importer = workflow_importer
164
173
  @default_admin_set = default_admin_set
@@ -182,28 +191,12 @@ module Hyrax
182
191
  # @return [Hyrax::AdministrativeSet] The fully created admin set.
183
192
  # @raise [RuntimeError] if admin set cannot be persisted
184
193
  def create!
185
- admin_set.respond_to?(:valkyrie_resource) ? active_fedora_create! : valkyrie_create!
186
- end
187
-
188
- private
189
-
190
- def default_admin_set?
191
- @default_admin_set
192
- end
193
-
194
- def admin_group_name
195
- ::Ability.admin_group_name
196
- end
197
-
198
- # Creates an admin set, setting the creator and the default access controls.
199
- # @return [Hyrax::AdministrativeSet] The fully created admin set.
200
- # @raise [RuntimeError] if admin set cannot be persisted
201
- def valkyrie_create!
202
194
  admin_set.creator = [creating_user.user_key] if creating_user
203
195
  updated_admin_set = Hyrax.persister.save(resource: admin_set).tap do |result|
204
196
  if result
205
197
  ActiveRecord::Base.transaction do
206
- permission_template = permissions_create_service.create_default(collection: result,
198
+ permission_template = PermissionTemplate.find_by(source_id: result.id.to_s) ||
199
+ permissions_create_service.create_default(collection: result,
207
200
  creating_user: creating_user)
208
201
  workflow = create_workflows_for(permission_template: permission_template)
209
202
  create_default_access_for(permission_template: permission_template, workflow: workflow) if default_admin_set?
@@ -214,23 +207,14 @@ module Hyrax
214
207
  updated_admin_set
215
208
  end
216
209
 
217
- # Creates an admin set, setting the creator and the default access controls.
218
- # @return [Hyrax::AdministrativeSet] The fully created admin set.
219
- # @raise [RuntimeError] if admin set cannot be persisted
220
- def active_fedora_create!
221
- admin_set.creator = [creating_user.user_key] if creating_user
222
- admin_set.save.tap do |result|
223
- if result
224
- ActiveRecord::Base.transaction do
225
- permission_template = permissions_create_service.create_default(collection: admin_set,
226
- creating_user: creating_user)
227
- workflow = create_workflows_for(permission_template: permission_template)
228
- create_default_access_for(permission_template: permission_template, workflow: workflow) if default_admin_set?
229
- end
230
- end
231
- end
232
- raise 'Admin set failed to persist.' unless admin_set.persisted?
233
- admin_set.valkyrie_resource
210
+ private
211
+
212
+ def default_admin_set?
213
+ @default_admin_set
214
+ end
215
+
216
+ def admin_group_name
217
+ ::Ability.admin_group_name
234
218
  end
235
219
 
236
220
  def create_workflows_for(permission_template:)
@@ -13,6 +13,7 @@ module Hyrax
13
13
  # sets; regardless of true/false make the given user
14
14
  # the depositor of the given work
15
15
  def self.call(work, user, reset)
16
+ Deprecation.warn("This class will be removed in the next major release. Use Hyrax::ChangeDepositorService.call instead.")
16
17
  case work
17
18
  when ActiveFedora::Base
18
19
  call_af(work, user, reset)
@@ -49,7 +50,6 @@ module Hyrax
49
50
  apply_valkyrie_changes_to_file_sets(work: work, user: user, reset: reset)
50
51
 
51
52
  Hyrax.persister.save(resource: work)
52
- work
53
53
  end
54
54
  private_class_method :call_valkyrie
55
55
 
@@ -61,7 +61,7 @@ module Hyrax
61
61
  private_class_method :apply_depositor_metadata
62
62
 
63
63
  def self.apply_valkyrie_changes_to_file_sets(work:, user:, reset:)
64
- Hyrax.custom_queries.find_child_filesets(resource: work).each do |f|
64
+ Hyrax.custom_queries.find_child_file_sets(resource: work).each do |f|
65
65
  if reset
66
66
  f.permission_manager.acl.permissions = []
67
67
  f.permission_manager.acl.save
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+ module Hyrax
3
+ class ChangeDepositorService
4
+ # Set the given `user` as the depositor of the given `work`; If
5
+ # `reset` is true, first remove all previous permissions.
6
+ #
7
+ # Used to transfer a an existing work, and to set
8
+ # depositor / proxy_depositor on a work newly deposited
9
+ # on_behalf_of another user
10
+ #
11
+ # @param work [ActiveFedora::Base, Valkyrie::Resource] the work
12
+ # that is receiving a change of depositor
13
+ # @param user [User] the user that will "become" the depositor of
14
+ # the given work
15
+ # @param reset [TrueClass, FalseClass] when true, first clear
16
+ # permissions for the given work and contained file
17
+ # sets; regardless of true/false make the given user
18
+ # the depositor of the given work
19
+ # @return work, updated if necessary
20
+ def self.call(work, user, reset)
21
+ # user_key is nil when there was no `on_behalf_of` in the form
22
+ return work unless user&.user_key
23
+ # Don't transfer to self
24
+ return work if user.user_key == work.depositor
25
+
26
+ work = case work
27
+ when ActiveFedora::Base
28
+ call_af(work, user, reset)
29
+ when Valkyrie::Resource
30
+ call_valkyrie(work, user, reset)
31
+ end
32
+ ChangeDepositorEventJob.perform_later(work)
33
+ work
34
+ end
35
+
36
+ def self.call_af(work, user, reset)
37
+ work.proxy_depositor = work.depositor
38
+ work.permissions = [] if reset
39
+ work.apply_depositor_metadata(user)
40
+ work.save!
41
+ Hyrax::PropagateChangeDepositorJob.perform_later(work.id.to_s, user, reset)
42
+ work
43
+ end
44
+ private_class_method :call_af
45
+
46
+ # @todo Should this include some dependency injection regarding
47
+ # the Hyrax.persister and Hyrax.custom_queries?
48
+ def self.call_valkyrie(work, user, reset)
49
+ if reset
50
+ work.permission_manager.acl.permissions = []
51
+ work.permission_manager.acl.save
52
+ end
53
+
54
+ work.proxy_depositor = work.depositor
55
+ apply_depositor_metadata(work, user)
56
+
57
+ work = Hyrax.persister.save(resource: work)
58
+ Hyrax::PropagateChangeDepositorJob.perform_later(work.id.to_s, user, reset)
59
+ work
60
+ end
61
+ private_class_method :call_valkyrie
62
+
63
+ def self.apply_depositor_metadata(resource, depositor)
64
+ depositor_id = depositor.respond_to?(:user_key) ? depositor.user_key : depositor
65
+ resource.depositor = depositor_id if resource.respond_to? :depositor=
66
+ Hyrax::AccessControlList.new(resource: resource).grant(:edit).to(::User.find_by_user_key(depositor_id)).save
67
+ end
68
+ private_class_method :apply_depositor_metadata
69
+ end
70
+ end
@@ -14,7 +14,7 @@ class Hyrax::Characterization::ValkyrieCharacterizationService
14
14
  def self.run(metadata:, file:, user: ::User.system_user, **options)
15
15
  new(metadata: metadata, file: file, **options).characterize
16
16
  saved = Hyrax.persister.save(resource: metadata)
17
- Hyrax.publisher.publish('object.metadata.updated', object: saved, user: user)
17
+ Hyrax.publisher.publish('file.metadata.updated', metadata: saved, user: user)
18
18
  end
19
19
 
20
20
  ##