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.

163 lines
5.2 KiB

<?php
declare(strict_types=1);
namespace Drupal\ocfl_export\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Url;
use Drupal\media\MediaInterface;
use Drupal\node\NodeInterface;
use Drupal\ocfl_export\MediaSerializerService;
use Drupal\ocfl_export\NodeSerializerService;
use Drupal\ocfl_export\OcflStorageService;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Controller for manual OCFL export operations.
*/
class OcflExportController extends ControllerBase {
public function __construct(
protected OcflStorageService $storageService,
protected NodeSerializerService $nodeSerializerService,
protected MediaSerializerService $mediaSerializerService,
MessengerInterface $messenger,
) {
$this->messenger = $messenger;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container): static {
return new static(
$container->get('ocfl_export.storage'),
$container->get('ocfl_export.node_serializer'),
$container->get('ocfl_export.media_serializer'),
$container->get('messenger'),
);
}
/**
* Export a node to OCFL storage.
*
* @param \Drupal\node\NodeInterface $node
* The node to export.
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
* A redirect response back to the node.
*/
public function exportNode(NodeInterface $node): RedirectResponse {
try {
$data = $this->nodeSerializerService->serialize($node);
$success = $this->storageService->saveObject($node->uuid(), $data);
if ($success) {
$this->messenger->addStatus($this->t('Node "@title" has been exported to OCFL storage.', [
'@title' => $node->getTitle(),
]));
// Get object info for additional feedback.
$objectInfo = $this->storageService->getObjectInfo($node->uuid());
if ($objectInfo) {
$this->messenger->addStatus($this->t('OCFL object version: @version', [
'@version' => $objectInfo['head'] ?? 'unknown',
]));
}
}
else {
$this->messenger->addError($this->t('Failed to export node "@title" to OCFL storage.', [
'@title' => $node->getTitle(),
]));
}
}
catch (\Exception $e) {
$this->messenger->addError($this->t('An error occurred while exporting: @message', [
'@message' => $e->getMessage(),
]));
$this->getLogger('ocfl_export')->error('Export failed for node @nid: @message', [
'@nid' => $node->id(),
'@message' => $e->getMessage(),
]);
}
return new RedirectResponse(Url::fromRoute('entity.node.canonical', ['node' => $node->id()])->toString());
}
/**
* Export a media entity to OCFL storage.
*
* @param \Drupal\media\MediaInterface $media
* The media entity to export.
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
* A redirect response back to the media entity.
*/
public function exportMedia(MediaInterface $media): RedirectResponse {
try {
$data = $this->mediaSerializerService->serialize($media);
$success = $this->storageService->saveObject($media->uuid(), $data);
if ($success) {
$this->messenger->addStatus($this->t('Media "@name" has been exported to OCFL storage.', [
'@name' => $media->getName(),
]));
// Get object info for additional feedback.
$objectInfo = $this->storageService->getObjectInfo($media->uuid());
if ($objectInfo) {
$this->messenger->addStatus($this->t('OCFL object version: @version', [
'@version' => $objectInfo['head'] ?? 'unknown',
]));
}
}
else {
$this->messenger->addError($this->t('Failed to export media "@name" to OCFL storage.', [
'@name' => $media->getName(),
]));
}
}
catch (\Exception $e) {
$this->messenger->addError($this->t('An error occurred while exporting: @message', [
'@message' => $e->getMessage(),
]));
$this->getLogger('ocfl_export')->error('Export failed for media @mid: @message', [
'@mid' => $media->id(),
'@message' => $e->getMessage(),
]);
}
return new RedirectResponse(Url::fromRoute('entity.media.canonical', ['media' => $media->id()])->toString());
}
/**
* View the exported JSON file for an entity.
*
* @param string $entity_type
* The entity type ('node' or 'media').
* @param string $uuid
* The entity UUID.
*
* @return \Symfony\Component\HttpFoundation\Response
* A response containing the JSON content.
*/
public function viewExport(string $entity_type, string $uuid): Response {
$filePath = $this->storageService->getLatestExportPath($uuid);
if (!$filePath || !file_exists($filePath)) {
throw new NotFoundHttpException('OCFL export not found for this entity.');
}
$content = file_get_contents($filePath);
return new Response($content, 200, [
'Content-Type' => 'application/json',
]);
}
}