create OCFL node.json files for each node and associated media/files.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

226 lines
5.6 KiB

<?php
/**
* @file
* OCFL Export module hooks and functions.
*/
declare(strict_types=1);
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Url;
use Drupal\media\MediaInterface;
use Drupal\node\NodeInterface;
use Drupal\ocfl_export\OcflExporter;
/**
* Implements hook_node_insert().
*/
function ocfl_export_node_insert(NodeInterface $node): void {
_ocfl_export_exporter()->queueNode($node);
}
/**
* Implements hook_node_update().
*/
function ocfl_export_node_update(NodeInterface $node): void {
_ocfl_export_exporter()->queueNode($node);
}
/**
* Implements hook_node_delete().
*/
function ocfl_export_node_delete(NodeInterface $node): void {
$exporter = _ocfl_export_exporter();
$exporter->unqueueNode($node);
if (!$exporter->shouldAutoExportNode($node)) {
return;
}
try {
/** @var \Drupal\ocfl_export\OcflStorageService $storage */
$storage = \Drupal::service('ocfl_export.storage');
$storage->markDeleted($node);
}
catch (\Exception $e) {
\Drupal::logger('ocfl_export')->error('Failed to mark OCFL object as deleted for node @nid: @message', [
'@nid' => $node->id(),
'@message' => $e->getMessage(),
]);
}
}
/**
* Implements hook_media_insert().
*/
function ocfl_export_media_insert(MediaInterface $media): void {
_ocfl_export_save_media($media);
}
/**
* Implements hook_media_update().
*/
function ocfl_export_media_update(MediaInterface $media): void {
_ocfl_export_save_media($media);
}
/**
* Implements hook_media_delete().
*/
function ocfl_export_media_delete(MediaInterface $media): void {
$exporter = _ocfl_export_exporter();
// The owning node's object should no longer include this media.
$exporter->queueParentNodes($media);
if (!$exporter->shouldAutoExportMedia($media)) {
return;
}
try {
/** @var \Drupal\ocfl_export\OcflStorageService $storage */
$storage = \Drupal::service('ocfl_export.storage');
$storage->markMediaDeleted($media);
}
catch (\Exception $e) {
\Drupal::logger('ocfl_export')->error('Failed to mark OCFL object as deleted for media @mid: @message', [
'@mid' => $media->id(),
'@message' => $e->getMessage(),
]);
}
}
/**
* Helper function to save media to OCFL storage.
*/
function _ocfl_export_save_media(MediaInterface $media): void {
$exporter = _ocfl_export_exporter();
// Islandora media (and derivatives) belong to a node's object.
$exporter->queueParentNodes($media);
if (!$exporter->shouldAutoExportMedia($media)) {
return;
}
try {
$exporter->exportMedia($media);
}
catch (\Exception $e) {
\Drupal::logger('ocfl_export')->error('Failed to export media @mid to OCFL: @message', [
'@mid' => $media->id(),
'@message' => $e->getMessage(),
]);
}
}
/**
* Get the OCFL exporter service.
*/
function _ocfl_export_exporter(): OcflExporter {
return \Drupal::service('ocfl_export.exporter');
}
/**
* Implements hook_node_view().
*/
function ocfl_export_node_view(array &$build, NodeInterface $node, EntityViewDisplayInterface $display, string $view_mode): void {
if ($view_mode !== 'full') {
return;
}
if (!\Drupal::currentUser()->hasPermission('export ocfl content')) {
return;
}
$build['ocfl_export_status'] = _ocfl_export_build_status_element($node->uuid(), 'node', $node->id());
}
/**
* Implements hook_media_view().
*/
function ocfl_export_media_view(array &$build, MediaInterface $media, EntityViewDisplayInterface $display, string $view_mode): void {
if ($view_mode !== 'full') {
return;
}
if (!\Drupal::currentUser()->hasPermission('export ocfl content')) {
return;
}
$build['ocfl_export_status'] = _ocfl_export_build_status_element($media->uuid(), 'media', $media->id());
}
/**
* Build the OCFL export status render element.
*
* @param string $uuid
* The entity UUID.
* @param string $entity_type
* The entity type ('node' or 'media').
* @param int|string $entity_id
* The entity ID.
*
* @return array
* A render array for the OCFL export status.
*/
function _ocfl_export_build_status_element(string $uuid, string $entity_type, int|string $entity_id): array {
/** @var \Drupal\ocfl_export\OcflStorageService $storage */
$storage = \Drupal::service('ocfl_export.storage');
$status = $storage->getExportStatus($uuid);
$element = [
'#type' => 'container',
'#attributes' => [
'class' => ['ocfl-export-status'],
],
'#weight' => -100,
];
if ($status) {
$element['info'] = [
'#type' => 'html_tag',
'#tag' => 'div',
'#attributes' => [
'class' => ['ocfl-export-info'],
],
'#value' => t('OCFL Export: @version (exported @date)', [
'@version' => $status['version'],
'@date' => $status['created'] ? \Drupal::service('date.formatter')->format(strtotime($status['created']), 'short') : t('unknown'),
]),
];
$element['link'] = [
'#type' => 'html_tag',
'#tag' => 'div',
'#attributes' => [
'class' => ['ocfl-export-link'],
],
'content' => [
'#type' => 'link',
'#title' => t('View exported JSON file'),
'#url' => Url::fromRoute('ocfl_export.view_export', [
'entity_type' => $entity_type,
'uuid' => $uuid,
]),
'#attributes' => [
'target' => '_blank',
],
],
];
}
else {
$element['info'] = [
'#type' => 'html_tag',
'#tag' => 'div',
'#attributes' => [
'class' => ['ocfl-export-info', 'ocfl-not-exported'],
],
'#value' => t('Not yet exported to OCFL'),
];
}
return $element;
}