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.
261 lines
9.1 KiB
261 lines
9.1 KiB
<?php |
|
|
|
declare(strict_types=1); |
|
|
|
namespace Drupal\ocfl_export\Form; |
|
|
|
use Drupal\Core\Config\ConfigFactoryInterface; |
|
use Drupal\Core\Entity\EntityTypeManagerInterface; |
|
use Drupal\Core\Form\ConfigFormBase; |
|
use Drupal\Core\Form\FormStateInterface; |
|
use Drupal\ocfl_export\OcflStorageService; |
|
use Symfony\Component\DependencyInjection\ContainerInterface; |
|
|
|
/** |
|
* Configuration form for OCFL Export settings. |
|
*/ |
|
class OcflSettingsForm extends ConfigFormBase { |
|
|
|
public function __construct( |
|
ConfigFactoryInterface $config_factory, |
|
protected EntityTypeManagerInterface $entityTypeManager, |
|
protected OcflStorageService $storageService, |
|
) { |
|
parent::__construct($config_factory); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public static function create(ContainerInterface $container): static { |
|
return new static( |
|
$container->get('config.factory'), |
|
$container->get('entity_type.manager'), |
|
$container->get('ocfl_export.storage'), |
|
); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
protected function getEditableConfigNames(): array { |
|
return ['ocfl_export.settings']; |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function getFormId(): string { |
|
return 'ocfl_export_settings_form'; |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function buildForm(array $form, FormStateInterface $form_state): array { |
|
$config = $this->config('ocfl_export.settings'); |
|
|
|
// Storage status. |
|
$form['status'] = [ |
|
'#type' => 'details', |
|
'#title' => $this->t('Storage Status'), |
|
'#open' => TRUE, |
|
]; |
|
|
|
$initialized = $this->storageService->isInitialized(); |
|
$form['status']['storage_status'] = [ |
|
'#type' => 'item', |
|
'#title' => $this->t('OCFL Storage'), |
|
'#markup' => $initialized |
|
? $this->t('<span style="color: green;">Initialized</span> at @path', ['@path' => $this->storageService->getStorageRoot()]) |
|
: $this->t('<span style="color: orange;">Not initialized</span> - will be created on first export'), |
|
]; |
|
|
|
// Storage settings. |
|
$form['storage'] = [ |
|
'#type' => 'details', |
|
'#title' => $this->t('Storage Settings'), |
|
'#open' => TRUE, |
|
]; |
|
|
|
$form['storage']['storage_root'] = [ |
|
'#type' => 'textfield', |
|
'#title' => $this->t('Storage Root Path'), |
|
'#description' => $this->t('The filesystem path where OCFL objects will be stored. Use stream wrappers like private:// or public://, or an absolute path.'), |
|
'#default_value' => $config->get('storage_root'), |
|
'#required' => TRUE, |
|
]; |
|
|
|
$form['storage']['ocfl_version'] = [ |
|
'#type' => 'select', |
|
'#title' => $this->t('OCFL Version'), |
|
'#options' => [ |
|
'1.1' => '1.1', |
|
'1.0' => '1.0', |
|
], |
|
'#default_value' => $config->get('ocfl_version') ?: '1.1', |
|
'#description' => $this->t('The OCFL specification version to use.'), |
|
]; |
|
|
|
// Export settings. |
|
$form['export'] = [ |
|
'#type' => 'details', |
|
'#title' => $this->t('Export Settings'), |
|
'#open' => TRUE, |
|
]; |
|
|
|
$form['export']['auto_export_enabled'] = [ |
|
'#type' => 'checkbox', |
|
'#title' => $this->t('Enable automatic export on node save'), |
|
'#description' => $this->t('When enabled, nodes will be automatically exported to OCFL when saved.'), |
|
'#default_value' => $config->get('auto_export_enabled'), |
|
]; |
|
|
|
// Get all content types. |
|
$contentTypes = $this->entityTypeManager->getStorage('node_type')->loadMultiple(); |
|
$options = []; |
|
foreach ($contentTypes as $type) { |
|
$options[$type->id()] = $type->label(); |
|
} |
|
|
|
$form['export']['content_types'] = [ |
|
'#type' => 'checkboxes', |
|
'#title' => $this->t('Content Types to Export'), |
|
'#description' => $this->t('Select which content types should be exported. Leave empty to export all content types.'), |
|
'#options' => $options, |
|
'#default_value' => $config->get('content_types') ?: [], |
|
]; |
|
|
|
// Media export settings. |
|
$form['media_export'] = [ |
|
'#type' => 'details', |
|
'#title' => $this->t('Media Export Settings'), |
|
'#open' => TRUE, |
|
]; |
|
|
|
$form['media_export']['auto_export_media_enabled'] = [ |
|
'#type' => 'checkbox', |
|
'#title' => $this->t('Enable automatic export on media save'), |
|
'#description' => $this->t('When enabled, media entities will be automatically exported to OCFL when saved.'), |
|
'#default_value' => $config->get('auto_export_media_enabled'), |
|
]; |
|
|
|
// Get all media types. |
|
$mediaTypes = $this->entityTypeManager->getStorage('media_type')->loadMultiple(); |
|
$mediaOptions = []; |
|
foreach ($mediaTypes as $type) { |
|
$mediaOptions[$type->id()] = $type->label(); |
|
} |
|
|
|
$form['media_export']['media_types'] = [ |
|
'#type' => 'checkboxes', |
|
'#title' => $this->t('Media Types to Export'), |
|
'#description' => $this->t('Select which media types should be exported. Leave empty to export all media types.'), |
|
'#options' => $mediaOptions, |
|
'#default_value' => $config->get('media_types') ?: [], |
|
]; |
|
|
|
// Files and relationships. |
|
$form['content'] = [ |
|
'#type' => 'details', |
|
'#title' => $this->t('Files and Relationships'), |
|
'#open' => TRUE, |
|
]; |
|
|
|
$form['content']['include_files'] = [ |
|
'#type' => 'checkbox', |
|
'#title' => $this->t('Copy files into OCFL objects'), |
|
'#description' => $this->t('Copy the binaries of associated media and of file/image fields into each object. Unchanged files are not copied again in later versions. When unchecked, only metadata is exported.'), |
|
'#default_value' => $config->get('include_files') ?? TRUE, |
|
]; |
|
|
|
$form['content']['media_of_field'] = [ |
|
'#type' => 'textfield', |
|
'#title' => $this->t('"Media of" field'), |
|
'#description' => $this->t('Media field that references the node the media belongs to (Islandora: field_media_of). Media found through it are included in the OCFL object of that node. Leave empty to disable.'), |
|
'#default_value' => $config->get('media_of_field'), |
|
]; |
|
|
|
$form['content']['member_of_field'] = [ |
|
'#type' => 'textfield', |
|
'#title' => $this->t('"Member of" field'), |
|
'#description' => $this->t('Node field that references parent nodes (Islandora: field_member_of). Used to record direct parents and the full collection hierarchy. Leave empty to disable.'), |
|
'#default_value' => $config->get('member_of_field'), |
|
]; |
|
|
|
$form['content']['model_field'] = [ |
|
'#type' => 'textfield', |
|
'#title' => $this->t('Model field'), |
|
'#description' => $this->t('Node field that references the model term (Islandora: field_model). Leave empty to disable.'), |
|
'#default_value' => $config->get('model_field'), |
|
]; |
|
|
|
// Initialize button. |
|
$form['actions']['initialize'] = [ |
|
'#type' => 'submit', |
|
'#value' => $this->t('Initialize Storage'), |
|
'#submit' => ['::initializeStorage'], |
|
'#weight' => 10, |
|
]; |
|
|
|
return parent::buildForm($form, $form_state); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function validateForm(array &$form, FormStateInterface $form_state): void { |
|
parent::validateForm($form, $form_state); |
|
|
|
$storagePath = $form_state->getValue('storage_root'); |
|
|
|
// Check if path uses a valid stream wrapper or is an absolute path. |
|
if (!str_contains($storagePath, '://') && !str_starts_with($storagePath, '/')) { |
|
$form_state->setErrorByName('storage_root', $this->t('Storage path must be an absolute path or use a stream wrapper (e.g., private://).')); |
|
} |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function submitForm(array &$form, FormStateInterface $form_state): void { |
|
// Filter out unchecked content types. |
|
$contentTypes = array_filter($form_state->getValue('content_types')); |
|
// Filter out unchecked media types. |
|
$mediaTypes = array_filter($form_state->getValue('media_types')); |
|
|
|
$this->config('ocfl_export.settings') |
|
->set('storage_root', $form_state->getValue('storage_root')) |
|
->set('auto_export_enabled', (bool) $form_state->getValue('auto_export_enabled')) |
|
->set('content_types', array_values($contentTypes)) |
|
->set('auto_export_media_enabled', (bool) $form_state->getValue('auto_export_media_enabled')) |
|
->set('media_types', array_values($mediaTypes)) |
|
->set('ocfl_version', $form_state->getValue('ocfl_version')) |
|
->set('include_files', (bool) $form_state->getValue('include_files')) |
|
->set('media_of_field', trim((string) $form_state->getValue('media_of_field'))) |
|
->set('member_of_field', trim((string) $form_state->getValue('member_of_field'))) |
|
->set('model_field', trim((string) $form_state->getValue('model_field'))) |
|
->save(); |
|
|
|
parent::submitForm($form, $form_state); |
|
} |
|
|
|
/** |
|
* Submit handler to initialize storage. |
|
*/ |
|
public function initializeStorage(array &$form, FormStateInterface $form_state): void { |
|
// Save config first. |
|
$this->submitForm($form, $form_state); |
|
|
|
// Initialize storage. |
|
if ($this->storageService->initializeStorageRoot()) { |
|
$this->messenger()->addStatus($this->t('OCFL storage has been initialized at @path.', [ |
|
'@path' => $this->storageService->getStorageRoot(), |
|
])); |
|
} |
|
else { |
|
$this->messenger()->addError($this->t('Failed to initialize OCFL storage. Check the logs for details.')); |
|
} |
|
} |
|
|
|
}
|
|
|