hyrax 5.0.0 → 5.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (331) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +7 -176
  3. data/.dassie/.env +8 -3
  4. data/.dassie/Gemfile +13 -2
  5. data/.dassie/app/controllers/hyrax/generic_work_resources_controller.rb +17 -0
  6. data/.dassie/app/controllers/hyrax/generic_works_controller.rb +7 -1
  7. data/.dassie/app/forms/generic_work_resource_form.rb +20 -0
  8. data/.dassie/app/indexers/generic_work_resource_indexer.rb +16 -0
  9. data/.dassie/app/models/admin_set_resource.rb +9 -0
  10. data/.dassie/app/models/collection_resource.rb +2 -0
  11. data/.dassie/app/models/file_set.rb +2 -0
  12. data/.dassie/app/models/generic_work_resource.rb +10 -0
  13. data/.dassie/app/views/hyrax/generic_work_resources/_generic_work_resource.html.erb +2 -0
  14. data/.dassie/config/analytics.yml +6 -1
  15. data/.dassie/config/application.rb +24 -0
  16. data/.dassie/config/initializers/hyrax.rb +13 -3
  17. data/.dassie/config/initializers/wings.rb +109 -0
  18. data/.dassie/config/metadata/generic_work_resource.yaml +22 -0
  19. data/.dassie/config/valkyrie_index.yml +4 -10
  20. data/.dassie/db/migrate/20240506070809_valkyrie_id_to_string.rb +5 -0
  21. data/.dassie/db/schema.rb +2 -2
  22. data/.dassie/spec/indexers/generic_work_resource_indexer_spec.rb +13 -0
  23. data/.dassie/spec/models/generic_work_resource_spec.rb +12 -0
  24. data/.dassie/spec/views/generic_work_resources/_generic_work_resource.html.erb_spec.rb +7 -0
  25. data/.dockerignore +6 -4
  26. data/.github/release.yml +3 -0
  27. data/.github/workflows/lint-build-test.yml +130 -0
  28. data/.github/workflows/test-results.yml +40 -0
  29. data/.koppie/.env +7 -5
  30. data/.koppie/Gemfile +12 -1
  31. data/.koppie/config/analytics.yml +6 -1
  32. data/.koppie/config/environments/test.rb +2 -0
  33. data/.koppie/config/initializers/1_valkyrie.rb +6 -2
  34. data/.koppie/config/solr.yml +1 -1
  35. data/.regen +1 -1
  36. data/.rubocop.yml +5 -0
  37. data/Dockerfile +16 -36
  38. data/Gemfile +2 -0
  39. data/app/assets/javascripts/hydra-editor/field_manager.es6 +187 -0
  40. data/app/assets/javascripts/hyrax/analytics_events.js +48 -24
  41. data/app/assets/javascripts/hyrax/autocomplete/linked_data.es6 +3 -0
  42. data/app/assets/javascripts/hyrax/collapse.js +4 -4
  43. data/app/assets/javascripts/hyrax/editor/controlled_vocabulary.es6 +38 -5
  44. data/app/assets/javascripts/hyrax/file_manager/save_manager.es6 +2 -0
  45. data/app/assets/javascripts/hyrax/search.js +2 -3
  46. data/app/assets/javascripts/hyrax/select_work_type.es6 +3 -1
  47. data/app/assets/javascripts/hyrax/uploader.js +20 -18
  48. data/app/assets/javascripts/hyrax.js +1 -0
  49. data/app/assets/stylesheets/_bootstrap-default-overrides.scss +4 -0
  50. data/app/assets/stylesheets/hyrax/_card.scss +4 -0
  51. data/app/assets/stylesheets/hyrax/_catalog.scss +21 -0
  52. data/app/assets/stylesheets/hyrax/_collections.scss +1 -1
  53. data/app/assets/stylesheets/hyrax/_facets.scss +15 -3
  54. data/app/assets/stylesheets/hyrax/_featured.scss +4 -0
  55. data/app/assets/stylesheets/hyrax/_file_upload.scss +6 -0
  56. data/app/assets/stylesheets/hyrax/_form.scss +4 -0
  57. data/app/assets/stylesheets/hyrax/_forms.scss +2 -1
  58. data/app/assets/stylesheets/hyrax/_nestable.scss +9 -8
  59. data/app/assets/stylesheets/hyrax/_select_work_type.scss +12 -0
  60. data/app/assets/stylesheets/hyrax/_styles.scss +4 -0
  61. data/app/assets/stylesheets/hyrax/_work-show.scss +3 -0
  62. data/app/assets/stylesheets/hyrax/controlled_vocabulary.scss +2 -2
  63. data/app/controllers/concerns/hyrax/singular_subresource_controller.rb +7 -2
  64. data/app/controllers/concerns/hyrax/valkyrie_downloads_controller_behavior.rb +11 -2
  65. data/app/controllers/concerns/hyrax/works_controller_behavior.rb +9 -2
  66. data/app/controllers/hyrax/admin/analytics/collection_reports_controller.rb +2 -2
  67. data/app/controllers/hyrax/admin/analytics/work_reports_controller.rb +7 -8
  68. data/app/controllers/hyrax/dashboard/collections_controller.rb +2 -1
  69. data/app/controllers/hyrax/downloads_controller.rb +24 -3
  70. data/app/controllers/hyrax/file_sets_controller.rb +33 -7
  71. data/app/controllers/hyrax/my/works_controller.rb +20 -0
  72. data/app/controllers/hyrax/single_use_links_viewer_controller.rb +9 -2
  73. data/app/controllers/hyrax/stats_controller.rb +1 -1
  74. data/app/controllers/hyrax/uploads_controller.rb +28 -2
  75. data/app/forms/hyrax/forms/admin/appearance.rb +1 -1
  76. data/app/forms/hyrax/forms/admin/collection_type_form.rb +1 -7
  77. data/app/forms/hyrax/forms/pcdm_collection_form.rb +9 -0
  78. data/app/forms/hyrax/forms/work_embargo_form.rb +6 -0
  79. data/app/forms/hyrax/forms/work_lease_form.rb +6 -0
  80. data/app/indexers/concerns/hyrax/location_indexer.rb +2 -2
  81. data/app/indexers/hyrax/indexers/file_set_indexer.rb +4 -0
  82. data/app/indexers/hyrax/indexers/resource_indexer.rb +1 -0
  83. data/app/indexers/hyrax/valkyrie_indexer.rb +3 -5
  84. data/app/jobs/migrate_files_to_valkyrie_job.rb +109 -0
  85. data/app/jobs/migrate_resources_job.rb +34 -0
  86. data/app/jobs/valkyrie_create_derivatives_job.rb +2 -1
  87. data/app/models/admin_set.rb +1 -0
  88. data/app/models/collection.rb +13 -1
  89. data/app/models/concerns/hyrax/ar_resource.rb +104 -0
  90. data/app/models/concerns/hyrax/solr_document/ordered_members.rb +2 -1
  91. data/app/models/concerns/hyrax/solr_document_behavior.rb +13 -2
  92. data/app/models/concerns/hyrax/valkyrie_lazy_migration.rb +82 -0
  93. data/app/models/file_download_stat.rb +1 -1
  94. data/app/models/file_view_stat.rb +1 -1
  95. data/app/models/hyrax/collection_type.rb +12 -4
  96. data/app/models/hyrax/file_metadata.rb +19 -0
  97. data/app/models/hyrax/file_set.rb +25 -0
  98. data/app/models/hyrax/model_registry.rb +3 -4
  99. data/app/models/hyrax/resource.rb +5 -0
  100. data/app/models/hyrax/statistic.rb +12 -37
  101. data/app/presenters/hyrax/file_set_presenter.rb +2 -1
  102. data/app/presenters/hyrax/file_usage.rb +3 -3
  103. data/app/presenters/hyrax/iiif_manifest_presenter.rb +2 -1
  104. data/app/presenters/hyrax/member_presenter_factory.rb +7 -1
  105. data/app/presenters/hyrax/menu_presenter.rb +1 -1
  106. data/app/presenters/hyrax/pcdm_member_presenter_factory.rb +2 -2
  107. data/app/presenters/hyrax/stats_usage_presenter.rb +2 -1
  108. data/app/presenters/hyrax/work_show_presenter.rb +15 -19
  109. data/app/presenters/hyrax/work_usage.rb +5 -2
  110. data/app/search_builders/hyrax/expired_embargo_search_builder.rb +7 -1
  111. data/app/search_builders/hyrax/expired_lease_search_builder.rb +7 -1
  112. data/app/search_builders/hyrax/filter_by_type.rb +1 -3
  113. data/app/search_builders/hyrax/valkyrie_abstract_type_relation.rb +7 -2
  114. data/app/services/hyrax/access_control_list.rb +1 -1
  115. data/app/services/hyrax/admin_set_create_service.rb +16 -5
  116. data/app/services/hyrax/admin_set_service.rb +2 -1
  117. data/app/services/hyrax/analytics/ga4/base.rb +96 -0
  118. data/app/services/hyrax/analytics/ga4/events.rb +25 -0
  119. data/app/services/hyrax/analytics/ga4/events_daily.rb +36 -0
  120. data/app/services/hyrax/analytics/ga4/visits.rb +33 -0
  121. data/app/services/hyrax/analytics/ga4/visits_daily.rb +24 -0
  122. data/app/services/hyrax/analytics/ga4.rb +204 -0
  123. data/app/services/hyrax/analytics/google.rb +16 -2
  124. data/app/services/hyrax/analytics/matomo.rb +16 -3
  125. data/app/services/hyrax/analytics/results.rb +6 -0
  126. data/app/services/hyrax/custom_queries/find_access_control.rb +1 -1
  127. data/app/services/hyrax/custom_queries/find_by_date_range.rb +6 -23
  128. data/app/services/hyrax/custom_queries/find_collections_by_type.rb +2 -2
  129. data/app/services/hyrax/custom_queries/find_count_by.rb +3 -31
  130. data/app/services/hyrax/custom_queries/find_file_metadata.rb +2 -2
  131. data/app/services/hyrax/custom_queries/find_models_by_access.rb +5 -27
  132. data/app/services/hyrax/embargo_manager.rb +2 -1
  133. data/app/services/hyrax/file_set_file_service.rb +10 -1
  134. data/app/services/hyrax/listeners/file_listener.rb +39 -0
  135. data/app/services/hyrax/listeners/file_metadata_listener.rb +0 -30
  136. data/app/services/hyrax/lock_manager.rb +7 -7
  137. data/app/services/hyrax/lockable.rb +4 -3
  138. data/app/services/hyrax/simple_schema_loader.rb +1 -1
  139. data/app/services/hyrax/solr_service.rb +22 -8
  140. data/app/services/hyrax/statistics/query_service.rb +1 -1
  141. data/app/services/hyrax/statistics/works/over_time.rb +1 -1
  142. data/app/services/hyrax/thumbnail_path_service.rb +2 -0
  143. data/app/services/hyrax/user_stat_importer.rb +5 -5
  144. data/app/services/hyrax/valkyrie_upload.rb +14 -9
  145. data/app/services/hyrax/versioning_service.rb +10 -2
  146. data/app/services/hyrax/work_query_service.rb +2 -2
  147. data/app/services/migrate_resource_service.rb +55 -0
  148. data/app/views/_controls.html.erb +5 -5
  149. data/app/views/_masthead.html.erb +1 -1
  150. data/app/views/catalog/_search_form.html.erb +9 -16
  151. data/app/views/catalog/_thumbnail_list_collection.html.erb +1 -1
  152. data/app/views/catalog/_thumbnail_list_default.html.erb +2 -2
  153. data/app/views/hyrax/admin/analytics/collection_reports/index.html.erb +4 -4
  154. data/app/views/hyrax/admin/analytics/work_reports/index.html.erb +1 -1
  155. data/app/views/hyrax/admin/collection_types/_form.html.erb +4 -4
  156. data/app/views/hyrax/admin/collection_types/index.html.erb +1 -1
  157. data/app/views/hyrax/admin/features/index.html.erb +1 -1
  158. data/app/views/hyrax/base/_file_manager_actions.html.erb +1 -1
  159. data/app/views/hyrax/base/_file_manager_member.html.erb +7 -4
  160. data/app/views/hyrax/base/_file_manager_thumbnail.html.erb +1 -1
  161. data/app/views/hyrax/base/_form_files.html.erb +1 -1
  162. data/app/views/hyrax/base/_form_member_of_collections.html.erb +4 -0
  163. data/app/views/hyrax/base/_show_actions.html.erb +7 -8
  164. data/app/views/hyrax/base/_work_button_row.html.erb +1 -1
  165. data/app/views/hyrax/batch_select/_add_button.html.erb +1 -1
  166. data/app/views/hyrax/content_blocks/_form.html.erb +3 -3
  167. data/app/views/hyrax/dashboard/_sidebar.html.erb +1 -1
  168. data/app/views/hyrax/dashboard/_user_activity.html.erb +2 -2
  169. data/app/views/hyrax/dashboard/collections/_form.html.erb +4 -4
  170. data/app/views/hyrax/dashboard/collections/_form_share.html.erb +6 -4
  171. data/app/views/hyrax/dashboard/collections/_list_collections.html.erb +1 -1
  172. data/app/views/hyrax/dashboard/collections/_show_document_list_row.html.erb +1 -1
  173. data/app/views/hyrax/dashboard/show_admin.html.erb +18 -19
  174. data/app/views/hyrax/dashboard/sidebar/_activity.html.erb +1 -1
  175. data/app/views/hyrax/embargoes/_list_expired_active_embargoes.html.erb +7 -7
  176. data/app/views/hyrax/file_sets/_actions.html.erb +9 -1
  177. data/app/views/hyrax/file_sets/_permission_form.html.erb +4 -2
  178. data/app/views/hyrax/file_sets/_show_actions.html.erb +1 -1
  179. data/app/views/hyrax/homepage/_featured.html.erb +1 -1
  180. data/app/views/hyrax/homepage/_recent_document.html.erb +2 -2
  181. data/app/views/hyrax/leases/_list_expired_active_leases.html.erb +6 -6
  182. data/app/views/hyrax/my/collections/_list_collections.html.erb +1 -1
  183. data/app/views/hyrax/my/collections/_tabs.html.erb +1 -1
  184. data/app/views/hyrax/pages/_form.html.erb +8 -8
  185. data/app/views/hyrax/transfers/_received.html.erb +1 -1
  186. data/app/views/hyrax/uploads/_js_templates.html.erb +9 -9
  187. data/app/views/hyrax/uploads/_js_templates_branding.html.erb +3 -3
  188. data/app/views/hyrax/uploads/_js_templates_versioning.html.erb +1 -1
  189. data/app/views/hyrax/uploads/create.json.jbuilder +2 -2
  190. data/app/views/hyrax/users/_activity_log.html.erb +15 -9
  191. data/app/views/hyrax/users/_user_row.html.erb +6 -3
  192. data/app/views/hyrax/users/_vitals.html.erb +3 -2
  193. data/app/views/layouts/_head_tag_content.html.erb +2 -0
  194. data/app/views/shared/_appearance_styles.html.erb +5 -1
  195. data/app/views/shared/_ga4.html.erb +11 -0
  196. data/app/views/shared/_select_work_type_modal.html.erb +10 -1
  197. data/bin/db-migrate-seed.sh +3 -3
  198. data/bin/dev-entrypoint.sh +7 -2
  199. data/bin/{db-wait.sh → service-wait.sh} +1 -1
  200. data/bin/worker-entrypoint.sh +8 -0
  201. data/chart/hyrax/Chart.yaml +1 -1
  202. data/chart/hyrax/templates/deployment-worker.yaml +2 -2
  203. data/chart/hyrax/templates/deployment.yaml +12 -0
  204. data/chart/hyrax/values.yaml +10 -0
  205. data/config/locales/hyrax.en.yml +4 -2
  206. data/config/metadata/basic_metadata.yaml +20 -0
  207. data/config/metadata/hyrax_internal_metadata.yaml +1 -1
  208. data/docker-compose-dassie.yml +167 -0
  209. data/docker-compose-koppie.yml +21 -36
  210. data/docker-compose-sirenia.yml +50 -44
  211. data/docker-compose.yml +2 -183
  212. data/documentation/developing-your-hyrax-based-app.md +4 -4
  213. data/hyrax.gemspec +7 -12
  214. data/lib/freyja/custom_query_container.rb +5 -0
  215. data/lib/freyja/metadata_adapter.rb +32 -0
  216. data/lib/freyja/persister.rb +42 -0
  217. data/lib/freyja/query_service.rb +20 -0
  218. data/lib/freyja/resource_factory.rb +8 -0
  219. data/lib/freyja.rb +14 -0
  220. data/lib/frigg/custom_query_container.rb +5 -0
  221. data/lib/frigg/metadata_adapter.rb +22 -0
  222. data/lib/frigg/persister.rb +33 -0
  223. data/lib/frigg/query_service.rb +15 -0
  224. data/lib/frigg.rb +13 -0
  225. data/lib/generators/hyrax/install_generator.rb +5 -0
  226. data/lib/generators/hyrax/templates/config/analytics.yml +6 -1
  227. data/lib/generators/hyrax/templates/config/initializers/1_valkyrie.rb +6 -2
  228. data/lib/generators/hyrax/templates/config/valkyrie_index.yml +1 -1
  229. data/lib/goddess/custom_query_container.rb +71 -0
  230. data/lib/goddess/metadata.rb +13 -0
  231. data/lib/goddess/query.rb +176 -0
  232. data/lib/hyrax/configuration.rb +83 -0
  233. data/lib/hyrax/engine.rb +2 -0
  234. data/lib/hyrax/form_fields.rb +1 -3
  235. data/lib/hyrax/name.rb +5 -0
  236. data/lib/hyrax/publisher.rb +11 -0
  237. data/lib/hyrax/rubocop/custom_cops.rb +30 -0
  238. data/lib/hyrax/specs/capybara.rb +10 -6
  239. data/{spec → lib/hyrax/specs/shared_specs}/factories/admin_sets.rb +2 -0
  240. data/{spec → lib/hyrax/specs/shared_specs}/factories/hyrax_embargo.rb +4 -0
  241. data/{spec → lib/hyrax/specs/shared_specs}/factories/hyrax_lease.rb +4 -0
  242. data/{spec → lib/hyrax/specs/shared_specs}/factories/hyrax_work.rb +26 -1
  243. data/lib/hyrax/specs/shared_specs/hydra_works.rb +1 -1
  244. data/lib/hyrax/transactions/admin_set_destroy.rb +2 -1
  245. data/lib/hyrax/transactions/collection_destroy.rb +2 -1
  246. data/lib/hyrax/transactions/container.rb +9 -0
  247. data/lib/hyrax/transactions/steps/add_file_sets.rb +2 -1
  248. data/lib/hyrax/transactions/steps/delete_all_file_metadata.rb +4 -5
  249. data/lib/hyrax/transactions/steps/delete_permission_template.rb +30 -0
  250. data/lib/hyrax/transactions/steps/delete_resource.rb +1 -1
  251. data/lib/hyrax/transactions/steps/save_collection_logo.rb +2 -1
  252. data/lib/hyrax/valkyrie_can_can_adapter.rb +8 -1
  253. data/lib/hyrax/version.rb +1 -1
  254. data/lib/wings/active_fedora_converter.rb +13 -5
  255. data/lib/wings/converter_value_mapper.rb +1 -0
  256. data/lib/wings/services/custom_queries/find_collections_by_type.rb +2 -1
  257. data/lib/wings/services/custom_queries/find_file_metadata.rb +2 -2
  258. data/lib/wings/setup.rb +12 -3
  259. data/lib/wings/transformer_value_mapper.rb +5 -1
  260. data/lib/wings/valkyrie/persister.rb +3 -1
  261. data/template.rb +1 -1
  262. metadata +118 -94
  263. data/.koppie/scripts/db-migrate-seed.sh +0 -9
  264. data/.koppie/scripts/entrypoint.sh +0 -10
  265. data/spec/support/book_resource.rb +0 -36
  266. data/spec/support/can_can_overrides.rb +0 -43
  267. data/spec/support/clean_solr.rb +0 -7
  268. data/spec/support/controller_level_helpers.rb +0 -27
  269. data/spec/support/factory_helpers.rb +0 -94
  270. data/spec/support/fakes/fake_actor.rb +0 -22
  271. data/spec/support/fakes/fake_authority.rb +0 -14
  272. data/spec/support/fakes/fake_search_builder_scope.rb +0 -44
  273. data/spec/support/fakes/indexing_adapter.rb +0 -17
  274. data/spec/support/fakes/test_hydra_group_service.rb +0 -55
  275. data/spec/support/features/batch_edit_actions.rb +0 -37
  276. data/spec/support/features/session_helpers.rb +0 -15
  277. data/spec/support/features/workflow.rb +0 -10
  278. data/spec/support/features.rb +0 -11
  279. data/spec/support/form_with_validations.rb +0 -15
  280. data/spec/support/input_support.rb +0 -12
  281. data/spec/support/logging_formatter.rb +0 -67
  282. data/spec/support/matchers/api_responses.rb +0 -27
  283. data/spec/support/matchers/collection_type_property_matchers.rb +0 -30
  284. data/spec/support/matchers/embargo.rb +0 -9
  285. data/spec/support/matchers/lease.rb +0 -9
  286. data/spec/support/matchers/match_valkyrie_ids_with_af_ids.rb +0 -12
  287. data/spec/support/matchers/pcdm_matchers.rb +0 -34
  288. data/spec/support/matchers/permission.rb +0 -31
  289. data/spec/support/matchers/response_matchers.rb +0 -8
  290. data/spec/support/optional_example.rb +0 -17
  291. data/spec/support/rake.rb +0 -42
  292. data/spec/support/selectors.rb +0 -112
  293. data/spec/support/shared_examples_for_collection_presenter.rb +0 -44
  294. data/spec/support/simple_work.rb +0 -28
  295. data/spec/support/spec_statistic.rb +0 -24
  296. data/spec/support/speedup.rb +0 -7
  297. data/spec/support/statistic_helper.rb +0 -10
  298. data/spec/support/valkyrie_indexing.rb +0 -2
  299. data/spec/support/wings_models.rb +0 -9
  300. /data/{spec → lib/hyrax/specs/shared_specs}/factories/access_control.rb +0 -0
  301. /data/{spec → lib/hyrax/specs/shared_specs}/factories/admin_sets_lw.rb +0 -0
  302. /data/{spec → lib/hyrax/specs/shared_specs}/factories/administrative_sets.rb +0 -0
  303. /data/{spec → lib/hyrax/specs/shared_specs}/factories/api_items.rb +0 -0
  304. /data/{spec → lib/hyrax/specs/shared_specs}/factories/collection_branding_infos.rb +0 -0
  305. /data/{spec → lib/hyrax/specs/shared_specs}/factories/collection_type_participants.rb +0 -0
  306. /data/{spec → lib/hyrax/specs/shared_specs}/factories/collection_types.rb +0 -0
  307. /data/{spec → lib/hyrax/specs/shared_specs}/factories/collections.rb +0 -0
  308. /data/{spec → lib/hyrax/specs/shared_specs}/factories/collections_factory.rb +0 -0
  309. /data/{spec → lib/hyrax/specs/shared_specs}/factories/content_blocks.rb +0 -0
  310. /data/{spec → lib/hyrax/specs/shared_specs}/factories/counter_metrics.rb +0 -0
  311. /data/{spec → lib/hyrax/specs/shared_specs}/factories/featured_works.rb +0 -0
  312. /data/{spec → lib/hyrax/specs/shared_specs}/factories/file_sets.rb +0 -0
  313. /data/{spec → lib/hyrax/specs/shared_specs}/factories/generic_works.rb +0 -0
  314. /data/{spec → lib/hyrax/specs/shared_specs}/factories/hyrax_collection.rb +0 -0
  315. /data/{spec → lib/hyrax/specs/shared_specs}/factories/hyrax_default_admin_set.rb +0 -0
  316. /data/{spec → lib/hyrax/specs/shared_specs}/factories/hyrax_file_metadata.rb +0 -0
  317. /data/{spec → lib/hyrax/specs/shared_specs}/factories/hyrax_file_set.rb +0 -0
  318. /data/{spec → lib/hyrax/specs/shared_specs}/factories/hyrax_resource.rb +0 -0
  319. /data/{spec → lib/hyrax/specs/shared_specs}/factories/object_id.rb +0 -0
  320. /data/{spec → lib/hyrax/specs/shared_specs}/factories/operations.rb +0 -0
  321. /data/{spec → lib/hyrax/specs/shared_specs}/factories/permission.rb +0 -0
  322. /data/{spec → lib/hyrax/specs/shared_specs}/factories/permission_template_accesses.rb +0 -0
  323. /data/{spec → lib/hyrax/specs/shared_specs}/factories/permission_templates.rb +0 -0
  324. /data/{spec → lib/hyrax/specs/shared_specs}/factories/proxy_deposit_requests.rb +0 -0
  325. /data/{spec → lib/hyrax/specs/shared_specs}/factories/single_use_links.rb +0 -0
  326. /data/{spec → lib/hyrax/specs/shared_specs}/factories/sipity_entities.rb +0 -0
  327. /data/{spec → lib/hyrax/specs/shared_specs}/factories/uploaded_files.rb +0 -0
  328. /data/{spec → lib/hyrax/specs/shared_specs}/factories/users.rb +0 -0
  329. /data/{spec → lib/hyrax/specs/shared_specs}/factories/workflow_actions.rb +0 -0
  330. /data/{spec → lib/hyrax/specs/shared_specs}/factories/workflow_states.rb +0 -0
  331. /data/{spec → lib/hyrax/specs/shared_specs}/factories/workflows.rb +0 -0
@@ -2,4 +2,16 @@
2
2
 
3
3
  # Provide plain collection model if not defined by the application.
4
4
  # Needed until Hyrax internals do not assume its existence.
5
- class ::Collection < Hyrax.config.collection_class; end unless '::Collection'.safe_constantize
5
+ class ::Collection < Hyrax.config.collection_class; end unless ActiveSupport::Dependencies.then do |deps|
6
+ # In autoloading environments, when referencing +::Collection+ from the
7
+ # initializer, make sure that +safe_constantize+ wouldn’t just try loading
8
+ # this file again (which would produce a runtime error). Do this by manually
9
+ # searching for the file which should define +::Collection+ and checking if it
10
+ # is the one being currently loaded.
11
+ break true if Object.const_defined?(:Collection)
12
+ file_path = deps.search_for_file("collection")
13
+ expanded = File.expand_path(file_path)
14
+ expanded.delete_suffix!(".rb")
15
+ break false if deps.loading.include?(expanded)
16
+ '::Collection'.safe_constantize
17
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+ module Hyrax
3
+ # An optional model to bring active record like accessors to your Valkyrie resources. This
4
+ # is simply for simplicity in the console and backward compatibility.
5
+ module ArResource
6
+ extend ActiveSupport::Concern
7
+
8
+ class_methods do
9
+ ##
10
+ # find a Valkyrie object by its primary identifyer.
11
+ #
12
+ # @param id [String]
13
+ # @return [Valkyrie::Resource]
14
+ def find(id, query_service: Hyrax.query_service)
15
+ query_service.find_by(id: id)
16
+ end
17
+
18
+ ##
19
+ # find and item by an arbitrary keyword arguements if and only if that property is supported
20
+ # by the current query_service. custom queries are often limited so be aware that this does
21
+ # support all properties of an object.
22
+ #
23
+ # @params query_service [Valkyrie::QueryService] (optional) the query service to use
24
+ # @param [Hash] opts the options to send to the query service. Can only be one argument.
25
+ # this argument will be converted to the query in the form of find_by_#{opts.keys.first}
26
+ # @return [Valkyrie::Resource]
27
+ def find_by(query_service: Hyrax.query_service, **opts)
28
+ if opts.key?(:id)
29
+ find(opts[:id], query_service: query_service)
30
+ else
31
+ method_name = "find_by_#{opts.keys.first}"
32
+ value = opts[opts.values.first]
33
+ return query_service.send(method_name, value) if query_service.respond_to?(method_name)
34
+ query_service.custom_query.send(method_name, value)
35
+ end
36
+
37
+ rescue Valkyrie::Persistence::ObjectNotFoundError
38
+ nil
39
+ end
40
+ end
41
+
42
+ ##
43
+ # @param query_service [#find_parents]
44
+ #
45
+ # @return [NilClass] when this object does not have a parent.
46
+ # @return [Valkyrie::Resource] when this object has at least one parent.
47
+ def parent(query_service: Hyrax.query_service)
48
+ query_service.find_parents(resource: self).first
49
+ end
50
+
51
+ ##
52
+ # This will persist the object to the repository. Not a complete transaction set up, but will
53
+ # index and notify listeners of metadata update
54
+ #
55
+ # @param [Hyrax::Persister] Valkyrie persister (optional) will default to Hyrax.persister
56
+ # @param [Hyrax::IndexAdapter] Valkyrie index adapter (optional) will default to Hyrax.index_adapter
57
+ # @param [User] user the user to record the event for. Will not set depositor yet
58
+ # @return [Valkyrie::Resource]
59
+ def save(persister: Hyrax.persister, index_adapter: Hyrax.index_adapter, user: ::User.system_user)
60
+ is_new = new_record
61
+ result = persister.save(resource: self)
62
+ return nil unless result.persisted?
63
+ index_adapter.save(resource: result)
64
+ if result.collection?
65
+ Hyrax.publisher.publish('collection.metadata.updated', collection: result, user: user)
66
+ else
67
+ Hyrax.publisher.publish('object.deposited', object: result, user: user) if is_new
68
+ Hyrax.publisher.publish('object.metadata.updated', object: result, user: user)
69
+ end
70
+ # TODO: do we need to replace the properties here?
71
+ self.new_record = false
72
+ self.id = result.id
73
+
74
+ result
75
+ end
76
+ alias create save
77
+ alias update save
78
+
79
+ def save!(**opts)
80
+ raise Valkyrie::Persistence::ObjectNotFoundError unless save(**opts)
81
+ end
82
+ alias create! save!
83
+ alias update! save!
84
+
85
+ ##
86
+ # This will delete the resource and publish its delete event
87
+ #
88
+ # @param [Hyrax::Persister] Valkyrie persister (optional) will default to Hyrax.persister
89
+ # @param [Hyrax::IndexAdapter] Valkyrie index adapter (optional) will default to Hyrax.index_adapter
90
+ # @param [User] user the user to record the event for. Will not set depositor yet
91
+ # @return [Boolean]
92
+ def destroy(persister: Hyrax.persister, index_adapter: Hyrax.index_adapter, user: ::User.system_user)
93
+ return false unless persisted?
94
+ persister.delete(resource: self)
95
+ index_adapter.delete(resource: self)
96
+ Hyrax.publisher.publish('object.deleted', object: self, user: user)
97
+ true
98
+ end
99
+
100
+ def destroy!(**opts)
101
+ raise Valkyrie::Persistence::ObjectNotFoundError unless destroy(**opts)
102
+ end
103
+ end
104
+ end
@@ -26,7 +26,8 @@ module Hyrax
26
26
  # only includes ids of ordered members.
27
27
  def ordered_member_ids
28
28
  return [] if id.blank?
29
- @ordered_member_ids ||= query_for_ordered_ids
29
+ # Valkyrie members are always ordered
30
+ @ordered_member_ids ||= valkyrie? ? member_ids : query_for_ordered_ids
30
31
  end
31
32
 
32
33
  private
@@ -74,10 +74,17 @@ module Hyrax
74
74
  Hyrax::ModelRegistry.work_classes.include?(hydra_model)
75
75
  end
76
76
 
77
+ ##
78
+ # @return [Boolean]
79
+ def valkyrie?
80
+ self['valkyrie_bsi']
81
+ end
82
+
77
83
  # Method to return the model
78
84
  def hydra_model(classifier: nil)
79
- first('has_model_ssim')&.safe_constantize ||
80
- model_classifier(classifier).classifier(self).best_model
85
+ model = first('has_model_ssim')&.safe_constantize
86
+ model = (first('has_model_ssim')&.+ 'Resource')&.safe_constantize if Hyrax.config.valkyrie_transition?
87
+ model || model_classifier(classifier).classifier(self).best_model
81
88
  end
82
89
 
83
90
  def depositor(default = '')
@@ -135,6 +142,10 @@ module Hyrax
135
142
  self['visibility_ssi'] == indexed_lease_visibility
136
143
  end
137
144
 
145
+ def extensions_and_mime_types
146
+ JSON.parse(self['extensions_and_mime_types_ssm'].first).map(&:with_indifferent_access) if self['extensions_and_mime_types_ssm']
147
+ end
148
+
138
149
  private
139
150
 
140
151
  def model_classifier(classifier)
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hyrax
4
+ ##
5
+ # This mixin is for {Valkyrie::Resource} objects to be able to read/write the same Solr document
6
+ # as their corresponding {ActiveFedora::Base} object.
7
+ #
8
+ # @see https://github.com/samvera/hyrax/pull/6221 Discussion about having one indexed document
9
+ module ValkyrieLazyMigration
10
+ ##
11
+ # Copy over even more of the {Wings::ModelRegistery} legacy model's model_name properties
12
+ #
13
+ # @note When we remove {Wings}, the downstream implementers will need to explicitly craft the
14
+ # properties of the model_name.
15
+ class ResourceName < ResourceName
16
+ def initialize(klass, *args)
17
+ super
18
+
19
+ legacy_model = Wings::ModelRegistry.lookup(klass)
20
+ return unless legacy_model
21
+
22
+ instance_variables.each do |ivar|
23
+ next if ivar == :@name
24
+ next if ivar == :@klass
25
+ instance_variable_set(ivar, legacy_model.model_name.send(ivar[1..-1]))
26
+ end
27
+ end
28
+ attr_reader :klass
29
+ end
30
+
31
+ ##
32
+ # This function helps configuration a work for a valkyrie migration; namely by helping re-use
33
+ # an existing SOLR document, by specifying that the given :klass is a migration :from another
34
+ # class.
35
+ #
36
+ # @note This is similar to the {Wings::ModelRegistry.register}, but is envisioned as part of
37
+ # the Frigg and Freyja adapters for Postges and Fedora lazy migrations.
38
+ #
39
+ # @param klass [Hyrax::Resource, .attribute]
40
+ # @param from [ActiveFedora::Base, .to_rdf_representation]
41
+ # @param name_class [Hyrax::Name] responsible, in part, for determining the various routing
42
+ # paths you might use.
43
+ #
44
+ # @example
45
+ # class MyWork < ActiveFedora::Base
46
+ # end
47
+ #
48
+ # class MyWorkResource < Hyrax::Resource
49
+ # Hyrax::ValkyrieLazyMigration.migrating(self, from: MyWork)
50
+ # end
51
+ def self.migrating(klass, from:, name_class: Hyrax::ValkyrieLazyMigration::ResourceName)
52
+ Wings::ModelRegistry.register(klass, from)
53
+ from.singleton_class.define_method(:migrating_from) { from }
54
+ from.singleton_class.define_method(:migrating_to) { klass }
55
+ klass.singleton_class.define_method(:migrating_from) { from }
56
+ klass.singleton_class.define_method(:migrating_to) { klass }
57
+ klass.singleton_class.define_method(:_hyrax_default_name_class) { name_class }
58
+ klass.singleton_class.define_method(:to_rdf_representation) { migrating_from.to_rdf_representation }
59
+
60
+ klass.include(self)
61
+ end
62
+
63
+ extend ActiveSupport::Concern
64
+
65
+ included do
66
+ attribute :internal_resource, Valkyrie::Types::Any.default(to_rdf_representation.freeze), internal: true
67
+ end
68
+
69
+ def members
70
+ return @members if @members.present?
71
+ @members = member_ids.map do |id|
72
+ Hyrax.query_service.find_by(id: id)
73
+ rescue Valkyrie::Persistence::ObjectNotFoundError
74
+ Rails.logger.warn("Could not find member #{id} for #{self.id}")
75
+ end
76
+ end
77
+
78
+ def to_solr
79
+ Hyrax::ValkyrieIndexer.for(resource: self).to_solr
80
+ end
81
+ end
82
+ end
@@ -21,7 +21,7 @@ class FileDownloadStat < Hyrax::Statistic
21
21
 
22
22
  # this is called by the parent class
23
23
  def filter(file)
24
- { file_id: file.id }
24
+ { file_id: file.id.to_s }
25
25
  end
26
26
  end
27
27
  end
@@ -6,7 +6,7 @@ class FileViewStat < Hyrax::Statistic
6
6
  class << self
7
7
  # this is called by the parent class
8
8
  def filter(file)
9
- { file_id: file.id }
9
+ { file_id: file.id.to_s }
10
10
  end
11
11
  end
12
12
  end
@@ -100,12 +100,20 @@ module Hyrax
100
100
 
101
101
  ##
102
102
  # @return [Enumerable<Collection, PcdmCollection>]
103
- def collections(use_valkyrie: Hyrax.config.use_valkyrie?)
103
+ def collections(use_valkyrie: Hyrax.config.use_valkyrie?, model: Hyrax.config.collection_class)
104
104
  return [] unless id
105
- return Hyrax.custom_queries.find_collections_by_type(global_id: to_global_id.to_s) if use_valkyrie
105
+ return Hyrax.custom_queries.find_collections_by_type(global_id: to_global_id.to_s, model:) if use_valkyrie
106
106
  ActiveFedora::Base.where(Hyrax.config.collection_type_index_field.to_sym => to_global_id.to_s)
107
107
  end
108
108
 
109
+ # Query solr to see if any collections of this type exist
110
+ # This should be much more performant for certain adapters than calling collections.any?
111
+ # @return [Boolean] True if there are any collections of this collection type in the repository
112
+ def collections?
113
+ return false unless id
114
+ Hyrax::SolrQueryService.new.with_field_pairs(field_pairs: { Hyrax.config.collection_type_index_field.to_sym => to_global_id.to_s }).with_model(model: Hyrax.config.collection_class.to_rdf_representation).count > 0
115
+ end
116
+
109
117
  # @return [Boolean] True if this is the Admin Set type
110
118
  def admin_set?
111
119
  machine_id == ADMIN_SET_MACHINE_ID
@@ -154,7 +162,7 @@ module Hyrax
154
162
  end
155
163
 
156
164
  def ensure_no_collections
157
- return true unless collections.any?
165
+ return true unless collections?
158
166
  errors[:base] << I18n.t('hyrax.admin.collection_types.errors.not_empty')
159
167
  throw :abort
160
168
  end
@@ -172,7 +180,7 @@ module Hyrax
172
180
  end
173
181
 
174
182
  def ensure_no_settings_changes_if_collections_exist
175
- return true unless collections.any?
183
+ return true unless collections?
176
184
  return true unless collection_type_settings_changed?
177
185
  errors[:base] << I18n.t('hyrax.admin.collection_types.errors.no_settings_change_if_not_empty')
178
186
  throw :abort
@@ -42,6 +42,18 @@ module Hyrax
42
42
 
43
43
  THUMBNAIL = ::Valkyrie::Vocab::PCDMUse.ThumbnailImage # for compatibility with earlier versions of Hyrax; prefer +THUMBNAIL_IMAGE+
44
44
 
45
+ # @return [Array<RDF::URI>] list of all uses
46
+ def use_list
47
+ [ORIGINAL_FILE,
48
+ THUMBNAIL_IMAGE,
49
+ EXTRACTED_TEXT,
50
+ INTERMEDIATE_FILE,
51
+ PRESERVATION_FILE,
52
+ SERVICE_FILE,
53
+ TRANSCRIPT]
54
+ end
55
+ module_function :use_list
56
+
45
57
  ##
46
58
  # @param use [RDF::URI, Symbol]
47
59
  #
@@ -166,6 +178,13 @@ module Hyrax
166
178
  pcdm_use.include?(Use::EXTRACTED_TEXT)
167
179
  end
168
180
 
181
+ ##
182
+ # Filters out uses not recognized by Hyrax (e.g. http://fedora.info/definitions/v4/repository#Binary)
183
+ # @return [Array]
184
+ def filtered_pcdm_use
185
+ pcdm_use.select { |use| Use.use_list.include?(use) }
186
+ end
187
+
169
188
  ##
170
189
  # @return [String]
171
190
  def to_rdf_representation
@@ -106,6 +106,31 @@ module Hyrax
106
106
  extracted_text&.id
107
107
  end
108
108
 
109
+ ##
110
+ # @return [Array] All ids, extensions, mime types, names, and uses
111
+ # @example
112
+ # [{:id=>"123", :extension=>"pdf", :mime_type=>"application/pdf", :name=>nil, :use=>"OriginalFile"},
113
+ # {:id=>"234", :extension=>"jpeg", :mime_type=>"application/octet-stream", :name=>"thumbnail", :use=>"ThumbnailImage"}]
114
+ # rubocop:disable Metrics/MethodLength
115
+ def extensions_and_mime_types
116
+ return [] if file_ids.empty?
117
+ Hyrax.custom_queries.find_files(file_set: self).each_with_object([]) do |fm, arr|
118
+ next unless fm.original_filename
119
+ extension = File.extname(fm.original_filename)
120
+ next if extension.empty?
121
+ use = fm.filtered_pcdm_use.first.to_s.split("#").last
122
+ name = use == 'OriginalFile' ? nil : File.basename(fm.original_filename, extension).split('-').last
123
+ arr << {
124
+ id: fm.id.to_s,
125
+ extension: extension[1..], # remove leading '.'
126
+ mime_type: fm.mime_type,
127
+ name: name,
128
+ use: use
129
+ }
130
+ end
131
+ # rubocop:enable Metrics/MethodLength
132
+ end
133
+
109
134
  ##
110
135
  # @return [Valkyrie::ID]
111
136
  def representative_id
@@ -85,7 +85,8 @@ module Hyrax
85
85
  #
86
86
  # @todo Consider the Wings::ModelRegistry and how we perform mappings.
87
87
  def self.work_class_names
88
- Hyrax.config.registered_curation_concern_types
88
+ @work_class_names ||= (Hyrax.config.registered_curation_concern_types +
89
+ Array(Rails.application.class.try(:work_types))).map(&:to_s).uniq
89
90
  end
90
91
 
91
92
  def self.work_classes
@@ -99,13 +100,11 @@ module Hyrax
99
100
  end
100
101
 
101
102
  def self.classes_from(strings)
102
- strings.map(&:safe_constantize).flatten.uniq
103
+ strings.map(&:safe_constantize).compact.uniq
103
104
  end
104
- private_class_method :classes_from
105
105
 
106
106
  def self.rdf_representations_from(klasses)
107
107
  klasses.map { |klass| klass.respond_to?(:to_rdf_representation) ? klass.to_rdf_representation : klass.name }.uniq
108
108
  end
109
- private_class_method :rdf_representations_from
110
109
  end
111
110
  end
@@ -149,6 +149,11 @@ module Hyrax
149
149
  self.class.work?
150
150
  end
151
151
 
152
+ # Its nice to know if a record is still in AF or not
153
+ def wings?
154
+ respond_to?(:head) && respond_to?(:tail)
155
+ end
156
+
152
157
  def ==(other)
153
158
  attributes.except(:created_at, :updated_at) == other.attributes.except(:created_at, :updated_at) if other.respond_to?(:attributes)
154
159
  end
@@ -25,47 +25,22 @@ module Hyrax
25
25
  combined_stats object, start_date, cache_column, event_type, user_id
26
26
  end
27
27
 
28
- # Hyrax::Download is sent to Hyrax::Analytics.profile as #hyrax__download
29
- # see Legato::ProfileMethods.method_name_from_klass
30
- def ga_statistics(start_date, object)
31
- path = polymorphic_path(object)
32
- profile = Hyrax::Analytics.profile
33
- unless profile
34
- Hyrax.logger.error("Google Analytics profile has not been established. Unable to fetch statistics.")
35
- return []
36
- end
37
- profile.hyrax__pageview(sort: 'date',
38
- start_date: start_date,
39
- end_date: Date.yesterday,
40
- limit: 10_000)
41
- .for_path(path)
42
- end
43
-
44
28
  def query_works(query)
45
- models = Hyrax.config.curation_concerns.map { |m| "\"#{m}\"" }
46
- Hyrax::SolrService.query("has_model_ssim:(#{models.join(' OR ')})", fl: query, rows: 100_000)
29
+ models = Hyrax::ModelRegistry.work_rdf_representations.map { |m| "\"#{m}\"" }
30
+ response = Hyrax::SolrService.get(fq: "has_model_ssim:(#{models.join(' OR ')})", 'facet.field': query, 'facet.missing': true, rows: 0)
31
+ Hash[*response['facet_counts']['facet_fields'][query]]
47
32
  end
48
33
 
49
34
  def work_types
50
- results = query_works("human_readable_type_tesim")
51
- results.group_by { |result| result['human_readable_type_tesim'].join('') }.transform_values(&:count)
35
+ types = query_works("human_readable_type_sim")
36
+ types['Unknown'] = types.delete(nil)
37
+ types
52
38
  end
53
39
 
54
40
  def resource_types
55
- results = query_works("resource_type_tesim")
56
- resource_types = []
57
- results.each do |y|
58
- if y["resource_type_tesim"].nil? || (y["resource_type_tesim"] == [""])
59
- resource_types.push("Unknown")
60
- elsif y["resource_type_tesim"].count > 1
61
- y["resource_type_tesim"].each do |t|
62
- resource_types.push(t)
63
- end
64
- else
65
- resource_types.push(y["resource_type_tesim"].join(""))
66
- end
67
- end
68
- resource_types.group_by { |rt| rt }.transform_values(&:count)
41
+ types = query_works("resource_type_sim")
42
+ types['Unknown'] = types.delete(nil)
43
+ types
69
44
  end
70
45
 
71
46
  private
@@ -80,10 +55,10 @@ module Hyrax
80
55
  stat_cache_info = cached_stats(object, start_date, object_method)
81
56
  stats = stat_cache_info[:cached_stats]
82
57
  if stat_cache_info[:ga_start_date] < Time.zone.today
83
- ga_stats = ga_statistics(stat_cache_info[:ga_start_date], object)
84
- ga_stats.each do |stat|
58
+ page_stats = Hyrax::Analytics.page_statistics(stat_cache_info[:ga_start_date], object)
59
+ page_stats.each do |stat|
85
60
  lstat = build_for(object, date: stat[:date], object_method => stat[ga_key], user_id: user_id)
86
- lstat.save unless Date.parse(stat[:date]) == Time.zone.today
61
+ lstat.save unless stat[:date].to_date == Time.zone.today
87
62
  stats << lstat
88
63
  end
89
64
  end
@@ -20,7 +20,8 @@ module Hyrax
20
20
 
21
21
  # CurationConcern methods
22
22
  delegate :stringify_keys, :human_readable_type, :collection?, :image?, :video?,
23
- :audio?, :pdf?, :office_document?, :representative_id, :to_s, to: :solr_document
23
+ :audio?, :pdf?, :office_document?, :representative_id, :to_s,
24
+ :extensions_and_mime_types, to: :solr_document
24
25
 
25
26
  # Methods used by blacklight helpers
26
27
  delegate :has?, :first, :fetch, to: :solr_document
@@ -5,7 +5,7 @@ module Hyrax
5
5
  # and prepares it for visualization in /app/views/stats/file.html.erb
6
6
  class FileUsage < StatsUsagePresenter
7
7
  def initialize(id)
8
- self.model = ::FileSet.find(id)
8
+ self.model = Hyrax.query_service.find_by(id: id)
9
9
  end
10
10
 
11
11
  alias file model
@@ -29,11 +29,11 @@ module Hyrax
29
29
  private
30
30
 
31
31
  def downloads
32
- to_flots(FileDownloadStat.statistics(model, created, user_id))
32
+ @downloads ||= to_flots(FileDownloadStat.statistics(model, created, user_id))
33
33
  end
34
34
 
35
35
  def pageviews
36
- to_flots(FileViewStat.statistics(model, created, user_id))
36
+ @pageviews ||= to_flots(FileViewStat.statistics(model, created, user_id))
37
37
  end
38
38
  end
39
39
  end
@@ -56,7 +56,8 @@ module Hyrax
56
56
  ##
57
57
  # @return [Boolean]
58
58
  def file_set?
59
- model.try(:file_set?) || Array(model[:has_model_ssim]).include?('FileSet') || Array(model[:has_model_ssim]).include?('Hyrax::FileSet')
59
+ return true if model.try(:file_set?)
60
+ (Array(model[:has_model_ssim]) & Hyrax::ModelRegistry.file_set_rdf_representations).any?
60
61
  end
61
62
 
62
63
  ##
@@ -47,7 +47,9 @@ module Hyrax
47
47
  # in order.
48
48
  # Arbitrarily maxed at 10 thousand; had to specify rows due to solr's default of 10
49
49
  def file_set_ids
50
- @file_set_ids ||= Hyrax::SolrService.query("{!field f=has_model_ssim}FileSet",
50
+ pairs = file_set_models.map { |model| ["has_model_ssim", model] }
51
+ query = Hyrax::SolrQueryBuilderService.construct_query(pairs, "OR")
52
+ @file_set_ids ||= Hyrax::SolrService.query(query,
51
53
  rows: 10_000,
52
54
  fl: Hyrax.config.id_field,
53
55
  fq: "{!join from=ordered_targets_ssim to=id}id:\"#{id}/list_source\"")
@@ -61,5 +63,9 @@ module Hyrax
61
63
  def composite_presenter_class
62
64
  CompositePresenterFactory.new(file_presenter_class, work_presenter_class, ordered_ids & file_set_ids)
63
65
  end
66
+
67
+ def file_set_models
68
+ Hyrax::ModelRegistry.file_set_rdf_representations
69
+ end
64
70
  end
65
71
  end
@@ -33,7 +33,7 @@ module Hyrax
33
33
  def nav_link(options, also_active_for: nil, **link_html_options)
34
34
  active_urls = [options, also_active_for].compact
35
35
  list_options = active_urls.any? { |url| current_page?(url) } ? { class: 'active nav-item' } : { class: 'nav-item' }
36
- tag.li(list_options) do
36
+ tag.li(**list_options) do
37
37
  link_to(options, link_html_options) do
38
38
  yield
39
39
  end
@@ -98,9 +98,9 @@ module Hyrax
98
98
  def presenter_for(document:, ability:)
99
99
  case document['has_model_ssim'].first
100
100
  when *Hyrax::ModelRegistry.file_set_rdf_representations
101
- Hyrax::FileSetPresenter.new(document, ability)
101
+ file_presenter_class.new(document, ability)
102
102
  else
103
- Hyrax::WorkShowPresenter.new(document, ability)
103
+ work_presenter_class.new(document, ability)
104
104
  end
105
105
  end
106
106
 
@@ -30,12 +30,13 @@ module Hyrax
30
30
  def date_for_analytics
31
31
  earliest = Hyrax.config.analytic_start_date
32
32
  date_uploaded = string_to_date(model.date_uploaded)
33
- date_analytics = date_uploaded ? date_uploaded : model.create_date
33
+ date_analytics = date_uploaded ? date_uploaded : (model.create_date || model.created_at)
34
34
  return date_analytics if earliest.blank?
35
35
  earliest > date_analytics ? earliest : date_analytics
36
36
  end
37
37
 
38
38
  def string_to_date(date_str)
39
+ return date_str if date_str.is_a?(Date)
39
40
  Time.zone.parse(date_str)
40
41
  rescue ArgumentError, TypeError
41
42
  nil
@@ -16,13 +16,6 @@ module Hyrax
16
16
  self.collection_presenter_class = CollectionPresenter
17
17
  self.presenter_factory_class = MemberPresenterFactory
18
18
 
19
- # Methods used by blacklight helpers
20
- delegate :has?, :first, :fetch, :export_formats, :export_as, to: :solr_document
21
-
22
- # delegate fields from Hyrax::Works::Metadata to solr_document
23
- delegate :based_near_label, :related_url, :depositor, :identifier, :resource_type,
24
- :keyword, :itemtype, :admin_set, :rights_notes, :access_right, :abstract, to: :solr_document
25
-
26
19
  # @param [SolrDocument] solr_document
27
20
  # @param [Ability] current_ability
28
21
  # @param [ActionDispatch::Request] request the http request context. Used so
@@ -33,20 +26,14 @@ module Hyrax
33
26
  @request = request
34
27
  end
35
28
 
29
+ # We cannot rely on the method missing to catch this delegation. Because
30
+ # most all objects implicitly implicitly implement #to_s
31
+ delegate :to_s, to: :solr_document
32
+
36
33
  def page_title
37
34
  "#{human_readable_type} | #{title.first} | ID: #{id} | #{I18n.t('hyrax.product_name')}"
38
35
  end
39
36
 
40
- # CurationConcern methods
41
- delegate :stringify_keys, :human_readable_type, :collection?, :to_s, :suppressed?,
42
- to: :solr_document
43
-
44
- # Metadata Methods
45
- delegate :title, :date_created, :description,
46
- :creator, :contributor, :subject, :publisher, :language, :embargo_release_date,
47
- :lease_expiration_date, :license, :source, :rights_statement, :thumbnail_id, :representative_id,
48
- :rendering_ids, :member_of_collection_ids, :alternative_title, :bibliographic_citation, to: :solr_document
49
-
50
37
  def workflow
51
38
  @workflow ||= WorkflowPresenter.new(solr_document, current_ability)
52
39
  end
@@ -63,10 +50,10 @@ module Hyrax
63
50
 
64
51
  # @return [Boolean] render a IIIF viewer
65
52
  def iiif_viewer?
66
- representative_id.present? &&
53
+ Hyrax.config.iiif_image_server? &&
54
+ representative_id.present? &&
67
55
  representative_presenter.present? &&
68
56
  representative_presenter.image? &&
69
- Hyrax.config.iiif_image_server? &&
70
57
  members_include_viewable_image?
71
58
  end
72
59
 
@@ -259,6 +246,15 @@ module Hyrax
259
246
 
260
247
  private
261
248
 
249
+ def method_missing(method_name, *args, &block)
250
+ return solr_document.public_send(method_name, *args, &block) if solr_document.respond_to?(method_name)
251
+ super
252
+ end
253
+
254
+ def respond_to_missing?(method_name, include_private = false)
255
+ solr_document.respond_to?(method_name, include_private) || super
256
+ end
257
+
262
258
  # list of item ids to display is based on ordered_ids
263
259
  def authorized_item_ids(filter_unreadable: Flipflop.hide_private_items?)
264
260
  @member_item_list_ids ||=