bulkrax 7.0.0 → 8.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/bulkrax/datatables.js +1 -1
  3. data/app/controllers/bulkrax/exporters_controller.rb +1 -1
  4. data/app/controllers/bulkrax/importers_controller.rb +2 -1
  5. data/app/controllers/concerns/bulkrax/datatables_behavior.rb +15 -15
  6. data/app/factories/bulkrax/object_factory.rb +135 -163
  7. data/app/factories/bulkrax/object_factory_interface.rb +491 -0
  8. data/app/factories/bulkrax/valkyrie_object_factory.rb +402 -0
  9. data/app/helpers/bulkrax/importers_helper.rb +1 -1
  10. data/app/helpers/bulkrax/validation_helper.rb +4 -4
  11. data/app/jobs/bulkrax/create_relationships_job.rb +27 -16
  12. data/app/jobs/bulkrax/delete_job.rb +3 -2
  13. data/app/jobs/bulkrax/download_cloud_file_job.rb +16 -3
  14. data/app/jobs/bulkrax/import_file_set_job.rb +5 -2
  15. data/app/jobs/bulkrax/importer_job.rb +18 -2
  16. data/app/matchers/bulkrax/application_matcher.rb +0 -2
  17. data/app/models/bulkrax/csv_collection_entry.rb +1 -1
  18. data/app/models/bulkrax/csv_entry.rb +7 -6
  19. data/app/models/bulkrax/entry.rb +7 -11
  20. data/app/models/bulkrax/exporter.rb +2 -2
  21. data/app/models/bulkrax/importer.rb +1 -3
  22. data/app/models/bulkrax/oai_entry.rb +0 -3
  23. data/app/models/bulkrax/oai_set_entry.rb +1 -1
  24. data/app/models/bulkrax/rdf_collection_entry.rb +1 -1
  25. data/app/models/bulkrax/rdf_entry.rb +70 -69
  26. data/app/models/bulkrax/xml_entry.rb +0 -1
  27. data/app/models/concerns/bulkrax/dynamic_record_lookup.rb +2 -19
  28. data/app/models/concerns/bulkrax/export_behavior.rb +2 -2
  29. data/app/models/concerns/bulkrax/file_factory.rb +174 -118
  30. data/app/models/concerns/bulkrax/file_set_entry_behavior.rb +2 -2
  31. data/app/models/concerns/bulkrax/has_matchers.rb +28 -25
  32. data/app/models/concerns/bulkrax/import_behavior.rb +10 -17
  33. data/app/models/concerns/bulkrax/importer_exporter_behavior.rb +3 -2
  34. data/app/parsers/bulkrax/application_parser.rb +31 -7
  35. data/app/parsers/bulkrax/bagit_parser.rb +175 -174
  36. data/app/parsers/bulkrax/csv_parser.rb +15 -5
  37. data/app/parsers/bulkrax/oai_dc_parser.rb +18 -0
  38. data/app/parsers/bulkrax/parser_export_record_set.rb +18 -22
  39. data/app/parsers/bulkrax/xml_parser.rb +0 -2
  40. data/app/services/bulkrax/factory_class_finder.rb +2 -0
  41. data/app/services/bulkrax/remove_relationships_for_importer.rb +3 -1
  42. data/app/services/hyrax/custom_queries/find_by_source_identifier.rb +50 -0
  43. data/app/services/wings/custom_queries/find_by_source_identifier.rb +32 -0
  44. data/app/views/bulkrax/entries/_parsed_metadata.html.erb +2 -2
  45. data/app/views/bulkrax/entries/_raw_metadata.html.erb +2 -2
  46. data/app/views/bulkrax/entries/show.html.erb +9 -8
  47. data/app/views/bulkrax/exporters/edit.html.erb +1 -1
  48. data/app/views/bulkrax/exporters/new.html.erb +1 -1
  49. data/app/views/bulkrax/exporters/show.html.erb +4 -2
  50. data/app/views/bulkrax/importers/_browse_everything.html.erb +2 -2
  51. data/app/views/bulkrax/importers/_csv_fields.html.erb +1 -1
  52. data/app/views/bulkrax/importers/edit.html.erb +1 -1
  53. data/app/views/bulkrax/importers/new.html.erb +1 -1
  54. data/app/views/bulkrax/importers/show.html.erb +1 -1
  55. data/app/views/bulkrax/importers/upload_corrected_entries.html.erb +2 -2
  56. data/app/views/bulkrax/shared/_bulkrax_errors.html.erb +1 -1
  57. data/app/views/bulkrax/shared/_bulkrax_field_mapping.html.erb +1 -1
  58. data/config/locales/bulkrax.en.yml +7 -0
  59. data/db/migrate/20230608153601_add_indices_to_bulkrax.rb +20 -9
  60. data/db/migrate/20240307053156_add_index_to_metadata_bulkrax_identifier.rb +18 -0
  61. data/lib/bulkrax/engine.rb +23 -6
  62. data/lib/bulkrax/version.rb +1 -1
  63. data/lib/bulkrax.rb +54 -52
  64. data/lib/generators/bulkrax/templates/config/initializers/bulkrax.rb +2 -0
  65. data/lib/tasks/bulkrax_tasks.rake +1 -0
  66. data/lib/tasks/reset.rake +4 -4
  67. metadata +24 -8
  68. data/lib/bulkrax/persistence_layer/active_fedora_adapter.rb +0 -27
  69. data/lib/bulkrax/persistence_layer/valkyrie_adapter.rb +0 -8
  70. data/lib/bulkrax/persistence_layer.rb +0 -38
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ae65205e27f8cff17680fb48e361dd9ed1740decda56dcded099a44413c4ae89
4
- data.tar.gz: c4db878ab4205b3b6bbbb82f251ea3947ea5390dfaf1fe4138d2fc82f3cb0c6b
3
+ metadata.gz: 6ca767b1e461d5830774bb4d7c49eade799d14298625bdbdccdcbdc0ac997f88
4
+ data.tar.gz: b5024ea772132123fcb922fbe183d22950428ea50b7a8b4152c6bd781b94510f
5
5
  SHA512:
6
- metadata.gz: 4ee86776f2716cd07747e93ba4e3f8d48a8427c10595d14a0a24a321a9a28de8729494bdbb48b4f4b40db4ff102dc184401ab869135cbb36032dbf5f55f623f5
7
- data.tar.gz: 5daf4da40338fc769052052106fc051746967a4c8ecabc89219daddb87a676e2500a1c42906aa55a14bbbcf6749868b1d41dff5388dad636b4d806da7f62bb6d
6
+ metadata.gz: 91004f88a97054107a3bbbcbe7f3b3dd84226a286df47992c13bfc5fb483c3bfd4aaa9190e08e567258e5105a317a37bba58fa7857ee6c534153ba930b608ad7
7
+ data.tar.gz: 89a32c155c3931e486b2d41215942b291eb724c59833a031fdc4815a72d26a2df13b015c1b1e2c0dafd608e58ec481a574e20da7bcf95ed76b3e45c3d5f19287
@@ -133,7 +133,7 @@ function refreshLink() {
133
133
  refreshLink.onclick = function() {
134
134
  this.api().ajax.reload(null, false)
135
135
  }.bind(this)
136
- refreshLink.classList.value = 'glyphicon glyphicon-refresh'
136
+ refreshLink.classList.value = 'fa fa-refresh'
137
137
  refreshLink.style.marginLeft = '10px'
138
138
  document.querySelector('div.dataTables_filter').firstChild.append(refreshLink)
139
139
  }
@@ -60,7 +60,7 @@ module Bulkrax
60
60
  end
61
61
 
62
62
  # Correctly populate export_source_collection input
63
- @collection = Collection.find(@exporter.export_source) if @exporter.export_source.present? && @exporter.export_from == 'collection'
63
+ @collection = Bulkrax.object_factory.find(@exporter.export_source) if @exporter.export_source.present? && @exporter.export_from == 'collection'
64
64
  end
65
65
 
66
66
  # POST /exporters
@@ -214,10 +214,11 @@ module Bulkrax
214
214
  return if file.blank? && cloud_files.blank?
215
215
  @importer[:parser_fields]['import_file_path'] = @importer.parser.write_import_file(file) if file.present?
216
216
  if cloud_files.present?
217
+ @importer[:parser_fields]['cloud_file_paths'] = cloud_files
217
218
  # For BagIt, there will only be one bag, so we get the file_path back and set import_file_path
218
219
  # For CSV, we expect only file uploads, so we won't get the file_path back
219
220
  # and we expect the import_file_path to be set already
220
- target = @importer.parser.retrieve_cloud_files(cloud_files)
221
+ target = @importer.parser.retrieve_cloud_files(cloud_files, @importer)
221
222
  @importer[:parser_fields]['import_file_path'] = target if target.present?
222
223
  end
223
224
  @importer.save
@@ -103,7 +103,7 @@ module Bulkrax
103
103
  {
104
104
  data: result,
105
105
  recordsTotal: Bulkrax::Importer.count,
106
- recordsFiltered: importers.size
106
+ recordsFiltered: Bulkrax::Importer.count
107
107
  }
108
108
  end
109
109
 
@@ -120,7 +120,7 @@ module Bulkrax
120
120
  {
121
121
  data: result,
122
122
  recordsTotal: Bulkrax::Exporter.count,
123
- recordsFiltered: exporters.size
123
+ recordsFiltered: Bulkrax::Exporter.count
124
124
  }
125
125
  end
126
126
 
@@ -145,37 +145,37 @@ module Bulkrax
145
145
 
146
146
  def entry_util_links(e, item)
147
147
  links = []
148
- links << view_context.link_to(view_context.raw('<span class="glyphicon glyphicon-info-sign"></span>'), view_context.item_entry_path(item, e))
149
- links << "<a class='glyphicon glyphicon-repeat' data-toggle='modal' data-target='#bulkraxItemModal' data-entry-id='#{e.id}'></a>" if view_context.an_importer?(item)
150
- links << view_context.link_to(view_context.raw('<span class="glyphicon glyphicon-trash"></span>'), view_context.item_entry_path(item, e), method: :delete, data: { confirm: 'This will delete the entry and any work associated with it. Are you sure?' })
148
+ links << view_context.link_to(view_context.raw('<span class="fa fa-info-circle"></span>'), view_context.item_entry_path(item, e))
149
+ links << "<a class='fa fa-repeat' data-toggle='modal' data-target='#bulkraxItemModal' data-entry-id='#{e.id}'></a>" if view_context.an_importer?(item)
150
+ links << view_context.link_to(view_context.raw('<span class="fa fa-trash"></span>'), view_context.item_entry_path(item, e), method: :delete, data: { confirm: 'This will delete the entry and any work associated with it. Are you sure?' })
151
151
  links.join(" ")
152
152
  end
153
153
 
154
154
  def status_message_for(e)
155
155
  if e.status_message == "Complete"
156
- "<td><span class='glyphicon glyphicon-ok' style='color: green;'></span> #{e.status_message}</td>"
156
+ "<td><span class='fa fa-check' style='color: green;'></span> #{e.status_message}</td>"
157
157
  elsif e.status_message == "Pending"
158
- "<td><span class='glyphicon glyphicon-option-horizontal' style='color: blue;'></span> #{e.status_message}</td>"
158
+ "<td><span class='fa fa-ellipsis-h' style='color: blue;'></span> #{e.status_message}</td>"
159
159
  elsif e.status_message == "Skipped"
160
- "<td><span class='glyphicon glyphicon-step-forward' style='color: yellow;'></span> #{e.status_message}</td>"
160
+ "<td><span class='fa fa-step-forward' style='color: yellow;'></span> #{e.status_message}</td>"
161
161
  else
162
- "<td><span class='glyphicon glyphicon-remove' style='color: #{e.status == 'Deleted' ? 'green' : 'red'};'></span> #{e.status_message}</td>"
162
+ "<td><span class='fa fa-remove' style='color: #{e.status == 'Deleted' ? 'green' : 'red'};'></span> #{e.status_message}</td>"
163
163
  end
164
164
  end
165
165
 
166
166
  def importer_util_links(i)
167
167
  links = []
168
- links << view_context.link_to(view_context.raw('<span class="glyphicon glyphicon-info-sign"></span>'), importer_path(i))
169
- links << view_context.link_to(view_context.raw('<span class="glyphicon glyphicon-pencil"></span>'), edit_importer_path(i))
170
- links << view_context.link_to(view_context.raw('<span class="glyphicon glyphicon-remove"></span>'), i, method: :delete, data: { confirm: 'Are you sure?' })
168
+ links << view_context.link_to(view_context.raw('<span class="fa fa-info-circle"></span>'), importer_path(i))
169
+ links << view_context.link_to(view_context.raw('<span class="fa fa-pencil"></span>'), edit_importer_path(i))
170
+ links << view_context.link_to(view_context.raw('<span class="fa fa-remove"></span>'), i, method: :delete, data: { confirm: 'Are you sure?' })
171
171
  links.join(" ")
172
172
  end
173
173
 
174
174
  def exporter_util_links(i)
175
175
  links = []
176
- links << view_context.link_to(view_context.raw('<span class="glyphicon glyphicon-info-sign"></span>'), exporter_path(i))
177
- links << view_context.link_to(view_context.raw('<span class="glyphicon glyphicon-pencil"></span>'), edit_exporter_path(i), data: { turbolinks: false })
178
- links << view_context.link_to(view_context.raw('<span class="glyphicon glyphicon-remove"></span>'), i, method: :delete, data: { confirm: 'Are you sure?' })
176
+ links << view_context.link_to(view_context.raw('<span class="fa fa-info-circle"></span>'), exporter_path(i))
177
+ links << view_context.link_to(view_context.raw('<span class="fa fa-pencil"></span>'), edit_exporter_path(i), data: { turbolinks: false })
178
+ links << view_context.link_to(view_context.raw('<span class="fa fa-remove"></span>'), i, method: :delete, data: { confirm: 'Are you sure?' })
179
179
  links.join(" ")
180
180
  end
181
181
 
@@ -1,153 +1,171 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bulkrax
4
- class ObjectFactory # rubocop:disable Metrics/ClassLength
5
- extend ActiveModel::Callbacks
4
+ # rubocop:disable Metrics/ClassLength
5
+ class ObjectFactory < ObjectFactoryInterface
6
6
  include Bulkrax::FileFactory
7
- include DynamicRecordLookup
8
7
 
9
- # @api private
10
- #
11
- # These are the attributes that we assume all "work type" classes (e.g. the given :klass) will
12
- # have in addition to their specific attributes.
13
- #
14
- # @return [Array<Symbol>]
15
- # @see #permitted_attributes
16
- class_attribute :base_permitted_attributes,
17
- default: %i[id edit_users edit_groups read_groups visibility work_members_attributes admin_set_id]
8
+ ##
9
+ # @!group Class Method Interface
18
10
 
19
- # @return [Boolean]
20
- #
21
- # @example
22
- # Bulkrax::ObjectFactory.transformation_removes_blank_hash_values = true
23
- #
24
- # @see #transform_attributes
25
- # @see https://github.com/samvera-labs/bulkrax/pull/708 For discussion concerning this feature
26
- # @see https://github.com/samvera-labs/bulkrax/wiki/Interacting-with-Metadata For documentation
27
- # concerning default behavior.
28
- class_attribute :transformation_removes_blank_hash_values, default: false
11
+ ##
12
+ # @note This does not save either object. We need to do that in another
13
+ # loop. Why? Because we might be adding many items to the parent.
14
+ def self.add_child_to_parent_work(parent:, child:)
15
+ return true if parent.ordered_members.to_a.include?(child_record)
29
16
 
30
- define_model_callbacks :save, :create
31
- attr_reader :attributes, :object, :source_identifier_value, :klass, :replace_files, :update_files, :work_identifier, :work_identifier_search_field, :related_parents_parsed_mapping, :importer_run_id
17
+ parent.ordered_members << child
18
+ end
32
19
 
33
- # rubocop:disable Metrics/ParameterLists
34
- def initialize(attributes:, source_identifier_value:, work_identifier:, work_identifier_search_field:, related_parents_parsed_mapping: nil, replace_files: false, user: nil, klass: nil, importer_run_id: nil, update_files: false)
35
- @attributes = ActiveSupport::HashWithIndifferentAccess.new(attributes)
36
- @replace_files = replace_files
37
- @update_files = update_files
38
- @user = user || User.batch_user
39
- @work_identifier = work_identifier
40
- @work_identifier_search_field = work_identifier_search_field
41
- @related_parents_parsed_mapping = related_parents_parsed_mapping
42
- @source_identifier_value = source_identifier_value
43
- @klass = klass || Bulkrax.default_work_type.constantize
44
- @importer_run_id = importer_run_id
20
+ def self.add_resource_to_collection(collection:, resource:, user:)
21
+ collection.try(:reindex_extent=, Hyrax::Adapters::NestingIndexAdapter::LIMITED_REINDEX) if
22
+ defined?(Hyrax::Adapters::NestingIndexAdapter)
23
+ resource.member_of_collections << collection
24
+ save!(resource: resource, user: user)
45
25
  end
46
- # rubocop:enable Metrics/ParameterLists
47
26
 
48
- # update files is set, replace files is set or this is a create
49
- def with_files
50
- update_files || replace_files || !object
27
+ def self.update_index_for_file_sets_of(resource:)
28
+ resource.file_sets.each(&:update_index) if resource.respond_to?(:file_sets)
51
29
  end
52
30
 
53
- def run
54
- arg_hash = { id: attributes[:id], name: 'UPDATE', klass: klass }
55
- @object = find
56
- if object
57
- object.reindex_extent = Hyrax::Adapters::NestingIndexAdapter::LIMITED_REINDEX if object.respond_to?(:reindex_extent)
58
- ActiveSupport::Notifications.instrument('import.importer', arg_hash) { update }
59
- else
60
- ActiveSupport::Notifications.instrument('import.importer', arg_hash.merge(name: 'CREATE')) { create }
61
- end
62
- yield(object) if block_given?
63
- object
31
+ ##
32
+ # @see Bulkrax::ObjectFactoryInterface
33
+ def self.export_properties
34
+ # TODO: Consider how this may or may not work for Valkyrie
35
+ properties = Bulkrax.curation_concerns.map { |work| work.properties.keys }.flatten.uniq.sort
36
+ properties.reject { |prop| Bulkrax.reserved_properties.include?(prop) }
64
37
  end
65
38
 
66
- def run!
67
- self.run
68
- # Create the error exception if the object is not validly saved for some reason
69
- raise ActiveFedora::RecordInvalid, object if !object.persisted? || object.changed?
70
- object
39
+ def self.field_multi_value?(field:, model:)
40
+ return false unless field_supported?(field: field, model: model)
41
+ return false unless model.singleton_methods.include?(:properties)
42
+
43
+ model&.properties&.[](field)&.[]("multiple")
71
44
  end
72
45
 
73
- def update
74
- raise "Object doesn't exist" unless object
75
- destroy_existing_files if @replace_files && ![Collection, FileSet].include?(klass)
76
- attrs = transform_attributes(update: true)
77
- run_callbacks :save do
78
- if klass == Collection
79
- update_collection(attrs)
80
- elsif klass == FileSet
81
- update_file_set(attrs)
82
- else
83
- update_work(attrs)
84
- end
85
- end
86
- object.apply_depositor_metadata(@user) && object.save! if object.depositor.nil?
87
- log_updated(object)
46
+ def self.field_supported?(field:, model:)
47
+ model.method_defined?(field) && model.properties[field].present?
48
+ end
49
+
50
+ def self.file_sets_for(resource:)
51
+ return [] if resource.blank?
52
+ return [resource] if resource.is_a?(Bulkrax.file_model_class)
53
+
54
+ resource.file_sets
88
55
  end
89
56
 
90
- def find
91
- found = find_by_id if attributes[:id].present?
92
- return found if found.present?
93
- return search_by_identifier if attributes[work_identifier].present?
57
+ ##
58
+ #
59
+ # @see Bulkrax::ObjectFactoryInterface
60
+ def self.find(id)
61
+ ActiveFedora::Base.find(id)
62
+ rescue ActiveFedora::ObjectNotFoundError => e
63
+ raise ObjectFactoryInterface::ObjectNotFoundError, e.message
94
64
  end
95
65
 
96
- def find_by_id
97
- klass.find(attributes[:id]) if klass.exists?(attributes[:id])
66
+ def self.find_or_create_default_admin_set
67
+ # NOTE: Hyrax 5+ removed this method
68
+ AdminSet.find_or_create_default_admin_set_id
98
69
  end
99
70
 
100
- def find_or_create
101
- o = find
102
- return o if o
103
- run(&:save!)
71
+ def self.publish(**)
72
+ return true
104
73
  end
105
74
 
106
- def search_by_identifier
107
- query = { work_identifier_search_field =>
108
- source_identifier_value }
109
- # Query can return partial matches (something6 matches both something6 and something68)
110
- # so we need to weed out any that are not the correct full match. But other items might be
111
- # in the multivalued field, so we have to go through them one at a time.
112
- match = klass.where(query).detect { |m| m.send(work_identifier).include?(source_identifier_value) }
75
+ ##
76
+ # @param value [String]
77
+ # @param klass [Class, #where]
78
+ # @param field [String, Symbol] A convenience parameter where we pass the
79
+ # same value to search_field and name_field.
80
+ # @param search_field [String, Symbol] the Solr field name
81
+ # (e.g. "title_tesim")
82
+ # @param name_field [String] the ActiveFedora::Base property name
83
+ # (e.g. "title")
84
+ # @param verify_property [TrueClass] when true, verify that the given :klass
85
+ #
86
+ # @return [NilClass] when no object is found.
87
+ # @return [ActiveFedora::Base] when a match is found, an instance of given
88
+ # :klass
89
+ # rubocop:disable Metrics/ParameterLists
90
+ #
91
+ # @note HEY WE'RE USING THIS FOR A WINGS CUSTOM QUERY. BE CAREFUL WITH
92
+ # REMOVING IT.
93
+ #
94
+ # @see # {Wings::CustomQueries::FindBySourceIdentifier#find_by_model_and_property_value}
95
+ def self.search_by_property(value:, klass:, field: nil, search_field: nil, name_field: nil, verify_property: false)
96
+ return nil unless klass.respond_to?(:where)
97
+ # We're not going to try to match nil nor "".
98
+ return if value.blank?
99
+ return if verify_property && !klass.properties.keys.include?(search_field)
100
+
101
+ search_field ||= field
102
+ name_field ||= field
103
+ raise "You must provide either (search_field AND name_field) OR field parameters" if search_field.nil? || name_field.nil?
104
+ # NOTE: Query can return partial matches (something6 matches both
105
+ # something6 and something68) so we need to weed out any that are not the
106
+ # correct full match. But other items might be in the multivalued field,
107
+ # so we have to go through them one at a time.
108
+ #
109
+ # A ssi field is string, so we're looking at exact matches.
110
+ # A tesi field is text, so partial matches work.
111
+ #
112
+ # We need to wrap the result in an Array, else we might have a scalar that
113
+ # will result again in partial matches.
114
+ match = klass.where(search_field => value).detect do |m|
115
+ # Don't use Array.wrap as we likely have an ActiveTriples::Relation
116
+ # which defiantly claims to be an Array yet does not behave consistently
117
+ # with an Array. Hopefully the name_field is not a Date or Time object,
118
+ # Because that too will be a mess.
119
+ Array(m.send(name_field)).include?(value)
120
+ end
113
121
  return match if match
114
122
  end
123
+ # rubocop:enable Metrics/ParameterLists
124
+
125
+ def self.query(q, **kwargs)
126
+ ActiveFedora::SolrService.query(q, **kwargs)
127
+ end
115
128
 
116
- # An ActiveFedora bug when there are many habtm <-> has_many associations means they won't all get saved.
117
- # https://github.com/projecthydra/active_fedora/issues/874
118
- # 2+ years later, still open!
119
- def create
120
- attrs = transform_attributes
121
- @object = klass.new
122
- object.reindex_extent = Hyrax::Adapters::NestingIndexAdapter::LIMITED_REINDEX if defined?(Hyrax::Adapters::NestingIndexAdapter) && object.respond_to?(:reindex_extent)
123
- run_callbacks :save do
124
- run_callbacks :create do
125
- if klass == Collection
126
- create_collection(attrs)
127
- elsif klass == FileSet
128
- create_file_set(attrs)
129
- else
130
- create_work(attrs)
131
- end
132
- end
129
+ def self.clean!
130
+ super do
131
+ ActiveFedora::Cleaner.clean!
133
132
  end
134
- object.apply_depositor_metadata(@user) && object.save! if object.depositor.nil?
135
- log_created(object)
136
133
  end
137
134
 
138
- def log_created(obj)
139
- msg = "Created #{klass.model_name.human} #{obj.id}"
140
- Rails.logger.info("#{msg} (#{Array(attributes[work_identifier]).first})")
135
+ def self.solr_name(field_name)
136
+ if defined?(Hyrax)
137
+ Hyrax.index_field_mapper.solr_name(field_name)
138
+ else
139
+ ActiveFedora.index_field_mapper.solr_name(field_name)
140
+ end
141
+ end
142
+
143
+ def self.ordered_file_sets_for(object)
144
+ object&.ordered_members.to_a.select(&:file_set?)
145
+ end
146
+
147
+ def self.save!(resource:, **)
148
+ resource.save!
141
149
  end
142
150
 
143
- def log_updated(obj)
144
- msg = "Updated #{klass.model_name.human} #{obj.id}"
145
- Rails.logger.info("#{msg} (#{Array(attributes[work_identifier]).first})")
151
+ def self.update_index(resources: [])
152
+ Array(resources).each(&:update_index)
146
153
  end
154
+ # @!endgroup Class Method Interface
155
+ ##
147
156
 
148
- def log_deleted_fs(obj)
149
- msg = "Deleted All Files from #{obj.id}"
150
- Rails.logger.info("#{msg} (#{Array(attributes[work_identifier]).first})")
157
+ def find_by_id
158
+ return false if attributes[:id].blank?
159
+ # Rails / Ruby upgrade, we moved from :exists? to :exist? However we want to continue (for a
160
+ # bit) to support older versions.
161
+ method_name = klass.respond_to?(:exist?) ? :exist? : :exists?
162
+ klass.find(attributes[:id]) if klass.send(method_name, attributes[:id])
163
+ rescue Valkyrie::Persistence::ObjectNotFoundError
164
+ false
165
+ end
166
+
167
+ def delete(_user)
168
+ find&.delete
151
169
  end
152
170
 
153
171
  private
@@ -238,52 +256,6 @@ module Bulkrax
238
256
  update == true ? actor.update_content(tmp_file) : actor.create_content(tmp_file, from_url: true)
239
257
  tmp_file.close
240
258
  end
241
-
242
- def clean_attrs(attrs)
243
- # avoid the "ArgumentError: Identifier must be a string of size > 0 in order to be treeified" error
244
- # when setting object.attributes
245
- attrs.delete('id') if attrs['id'].blank?
246
- attrs
247
- end
248
-
249
- def collection_type(attrs)
250
- return attrs if attrs['collection_type_gid'].present?
251
-
252
- attrs['collection_type_gid'] = Hyrax::CollectionType.find_or_create_default_collection_type.to_global_id.to_s
253
- attrs
254
- end
255
-
256
- # Override if we need to map the attributes from the parser in
257
- # a way that is compatible with how the factory needs them.
258
- def transform_attributes(update: false)
259
- @transform_attributes = attributes.slice(*permitted_attributes)
260
- @transform_attributes.merge!(file_attributes(update_files)) if with_files
261
- @transform_attributes = remove_blank_hash_values(@transform_attributes) if transformation_removes_blank_hash_values?
262
- update ? @transform_attributes.except(:id) : @transform_attributes
263
- end
264
-
265
- # Regardless of what the Parser gives us, these are the properties we are prepared to accept.
266
- def permitted_attributes
267
- klass.properties.keys.map(&:to_sym) + base_permitted_attributes
268
- end
269
-
270
- # Return a copy of the given attributes, such that all values that are empty or an array of all
271
- # empty values are fully emptied. (See implementation details)
272
- #
273
- # @param attributes [Hash]
274
- # @return [Hash]
275
- #
276
- # @see https://github.com/emory-libraries/dlp-curate/issues/1973
277
- def remove_blank_hash_values(attributes)
278
- dupe = attributes.dup
279
- dupe.each do |key, values|
280
- if values.is_a?(Array) && values.all? { |value| value.is_a?(String) && value.empty? }
281
- dupe[key] = []
282
- elsif values.is_a?(String) && values.empty?
283
- dupe[key] = nil
284
- end
285
- end
286
- dupe
287
- end
288
259
  end
260
+ # rubocop:enable Metrics/ClassLength
289
261
  end