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.

264 lines
6.9 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;
/**
* Implements hook_node_insert().
*/
function ocfl_export_node_insert(NodeInterface $node): void {
_ocfl_export_save_node($node);
}
/**
* Implements hook_node_update().
*/
function ocfl_export_node_update(NodeInterface $node): void {
_ocfl_export_save_node($node);
}
/**
* Implements hook_node_delete().
*/
function ocfl_export_node_delete(NodeInterface $node): void {
$config = \Drupal::config('ocfl_export.settings');
if (!$config->get('auto_export_enabled')) {
return;
}
$content_types = $config->get('content_types') ?: [];
if (!empty($content_types) && !in_array($node->bundle(), $content_types, TRUE)) {
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(),
]);
}
}
/**
* Helper function to save node to OCFL storage.
*/
function _ocfl_export_save_node(NodeInterface $node): void {
$config = \Drupal::config('ocfl_export.settings');
if (!$config->get('auto_export_enabled')) {
return;
}
$content_types = $config->get('content_types') ?: [];
if (!empty($content_types) && !in_array($node->bundle(), $content_types, TRUE)) {
return;
}
try {
/** @var \Drupal\ocfl_export\NodeSerializerService $serializer */
$serializer = \Drupal::service('ocfl_export.node_serializer');
/** @var \Drupal\ocfl_export\OcflStorageService $storage */
$storage = \Drupal::service('ocfl_export.storage');
$data = $serializer->serialize($node);
$storage->saveObject($node->uuid(), $data);
}
catch (\Exception $e) {
\Drupal::logger('ocfl_export')->error('Failed to export node @nid to OCFL: @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 {
$config = \Drupal::config('ocfl_export.settings');
if (!$config->get('auto_export_media_enabled')) {
return;
}
$media_types = $config->get('media_types') ?: [];
if (!empty($media_types) && !in_array($media->bundle(), $media_types, TRUE)) {
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 {
$config = \Drupal::config('ocfl_export.settings');
if (!$config->get('auto_export_media_enabled')) {
return;
}
$media_types = $config->get('media_types') ?: [];
if (!empty($media_types) && !in_array($media->bundle(), $media_types, TRUE)) {
return;
}
try {
/** @var \Drupal\ocfl_export\MediaSerializerService $serializer */
$serializer = \Drupal::service('ocfl_export.media_serializer');
/** @var \Drupal\ocfl_export\OcflStorageService $storage */
$storage = \Drupal::service('ocfl_export.storage');
$data = $serializer->serialize($media);
$storage->saveObject($media->uuid(), $data);
}
catch (\Exception $e) {
\Drupal::logger('ocfl_export')->error('Failed to export media @mid to OCFL: @message', [
'@mid' => $media->id(),
'@message' => $e->getMessage(),
]);
}
}
/**
* 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;
}