Browse Source

added README

main
ajstanley 10 months ago
parent
commit
8f0eef973d
  1. 31
      README.md
  2. 6
      doi_prefill.links.menu.yml
  3. 324
      src/Form/DOIFieldSettingsForm.php

31
README.md

@ -0,0 +1,31 @@
# DOI Prefill
Allows users create Drupal nodes with data retrieved from Crossref.
## Installation
Install as
[usual](https://www.drupal.org/docs/extending-drupal/installing-modules).
## Configuration
The form at `admin/config/system/doi_field_setting`s allows you to map the fields returned by Crossref to fields
in your Islandora installation e.g. Crossref's `Contributors` field can be mapped to `field_contributor`, or `field_linked_agent`.
You may optionally map the Crossref genre fields to your own taxonomy term e.g. `journal-article` to `Journal Article`
## Usage
After installing and enabling and configuring the module add a link to `doi-prefill/doi-prepopulate` in your [Shortcuts menu](admin/config/user-interface/shortcut/manage/default/customize)
Navigate to the form where you can enter a DOI, a collection for your new node, and choose whether you'd like to be taken the node's edit form or be returned to the same page.
## Maintainers
Current maintainers:
* [Robertson Library](https://library.upei.ca/)
## License
[GPLv3](http://www.gnu.org/licenses/gpl-3.0.txt)

6
doi_prefill.links.menu.yml

@ -0,0 +1,6 @@
doi_prefill.doi_settings:
title: DOI Prefill Settings
description: Configure DOI mappings
parent: system.admin_config_system
route_name: doi_prefill.doi_settings
weight: 10

324
src/Form/DOIFieldSettingsForm.php

@ -0,0 +1,324 @@
<?php
declare(strict_types=1);
namespace Drupal\doi_prefill\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\node\Entity\NodeType;
use Drupal\islandora\IslandoraUtils;
/**
* Configure DOI Prefill settings for this site.
*/
final class DOIFieldSettingsForm extends ConfigFormBase {
/**
* The entity field manager service.
*
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityFieldManager;
/**
* Islandora utility functions.
*
* @var \Drupal\islandora\IslandoraUtils
*/
protected $utils;
/**
* The entity type manager service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Constructs a new DOIFieldSettingsForm.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* The entity type manager service.
* @param \Drupal\Core\Entity\EntityFieldManagerInterface $entityFieldManager
* THe field manager.
*/
public function __construct(EntityTypeManagerInterface $entityTypeManager, EntityFieldManagerInterface $entityFieldManager, IslandoraUtils $utils) {
$this->entityTypeManager = $entityTypeManager;
$this->entityFieldManager = $entityFieldManager;
$this->utils = $utils;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_type.manager'),
$container->get('entity_field.manager'),
$container->get('islandora.utils'),
);
}
/**
* {@inheritdoc}
*/
public function getFormId(): string {
return 'doi_prefill_doi_field_settings';
}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames(): array {
return ['doi_prefill.settings'];
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state): array {
$doi_fields = [
'title' => 'Title',
'contributors' => 'Contributors',
'publisher' => 'Publisher',
'doi' => 'DOI',
'genre' => 'Genre',
'issue' => 'Issue',
'volume' => 'Volume',
'date_issued' => 'Date issued',
'abstract' => 'Abstract',
'host_title' => 'Host title',
'date_online' => 'Date online',
'page_range' => 'Page range',
'series_issn' => 'Series ISSN',
];
$config = $this->config('doi_prefill.settings');
$fields = $this->entityFieldManager->getFieldDefinitions('node', 'islandora_object');
$field_options = ['title' => 'Title'];
foreach ($fields as $field) {
if ($field instanceof FieldConfig) {
$label = (string) $field->getLabel();
$name = $field->getName();
$field_options[$name] = $label;
}
}
asort($field_options);
$content_types = NodeType::loadMultiple();
$destination_content_types = [];
foreach ($content_types as $type) {
if ($this->utils->isIslandoraType('node', $type->id())) {
$destination_content_types[$type->id()] = $type->label();
}
}
$form['content_type'] = [
'#type' => 'select',
'#title' => $this->t('Content Type'),
'#description' => $this->t("Choose content type for new node"),
'#options' => $destination_content_types,
'#default_value' => $config->get('content_type'),
];
// Display fields in a table format.
$form['description'] = [
'#type' => 'markup',
'#markup' => $this->t('DOI fields are returned by Crossref. Please choose field from your Islandora Installation to hold the returned value.'),
];
$form['field_table'] = [
'#type' => 'table',
'#header' => [
$this->t('DOI Field'),
$this->t('Islandora Field'),
],
'#prefix' => '<div id="field-table-wrapper">',
'#suffix' => '</div>',
];
foreach ($doi_fields as $machine_name => $field) {
$form['field_table'][$machine_name]['field_name'] = [
'#plain_text' => $field,
];
// Add a dropdown for each field.
$form['field_table'][$machine_name]['dropdown'] = [
'#type' => 'select',
'#options' => $field_options,
'#default_value' => $config->get('field_settings')[$machine_name] ?? '',
];
}
$form['#attached']['library'][] = 'doi_prefill/doi_field_selector_styles';
$form['pairs_description'] = [
'#type' => 'markup',
'#markup' => $this->t('DOI genre terms are returned by Crossref. Please choose any term you would like to replace from your own taxonomy.'),
];
$doi_term_islandora_term_pairs = $form_state->get('doi_term_islandora_term_pairs');
if (!$doi_term_islandora_term_pairs) {
$doi_term_islandora_term_pairs = $config->get('doi_term_islandora_term_pairs');
}
if (empty($doi_term_islandora_term_pairs)) {
// Initialize as an empty array if no pairs exist.
$doi_term_islandora_term_pairs = [];
}
// Set the form state for entry_count and doi_term_islandora_term_pairs.
$form_state->set('doi_term_islandora_term_pairs', $doi_term_islandora_term_pairs);
$entry_count = count($doi_term_islandora_term_pairs);
$form_state->set('entry_count', $entry_count);
// Define the table structure for key-value pairs.
$form['doi_term_islandora_term_pairs'] = [
'#type' => 'table',
'#prefix' => '<div id="key-value-pairs-wrapper">',
'#suffix' => '</div>',
];
// Generate the table rows dynamically based on stored pairs.
foreach ($doi_term_islandora_term_pairs as $entry_id => $pair) {
$pair['entry_id'] = $entry_id;
$unique_id = $pair['entry_id'] ?? uniqid();
$form['doi_term_islandora_term_pairs'][$unique_id]['key'] = [
'#type' => 'textfield',
'#default_value' => $pair['key'] ?? '',
'#title' => $this->t('term from DOI'),
'#required' => TRUE,
];
$form['doi_term_islandora_term_pairs'][$unique_id]['value'] = [
'#type' => 'textfield',
'#default_value' => $pair['value'] ?? '',
'#title' => $this->t('Genre term'),
'#required' => TRUE,
];
// Hidden field to store the correct entry ID.
$form['doi_term_islandora_term_pairs'][$unique_id]['entry_id'] = [
'#type' => 'hidden',
'#value' => $entry_id,
];
// Remove button for each entry.
$form['doi_term_islandora_term_pairs'][$unique_id]['remove'] = [
'#type' => 'submit',
'#value' => $this->t('Remove'),
'#submit' => ['::removeCallback'],
'#limit_validation_errors' => [],
'#ajax' => [
'callback' => '::ajaxCallback',
'wrapper' => 'key-value-pairs-wrapper',
],
// Instead of relying on `#attributes`, set a unique `#name`!
'#name' => 'remove_' . $unique_id,
];
}
// Button to add another key-value pair.
$form['add_more'] = [
'#type' => 'submit',
'#value' => $this->t('Add term'),
'#submit' => ['::addMoreCallback'],
'#ajax' => [
'callback' => '::ajaxCallback',
'wrapper' => 'key-value-pairs-wrapper',
],
];
// Submit button for the form.
$form['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Save term mappings'),
];
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state): void {
if (!empty($form_state->getValue('field_table'))) {
foreach ($form_state->getValue('field_table') as $doi_field => $islandora_field) {
$field_settings[$doi_field] = $islandora_field['dropdown'];
}
}
$doi_term_islandora_term_pairs = $form_state->getValue('doi_term_islandora_term_pairs');
$content_type = $form_state->getValue('content_type');
$this->config('doi_prefill.settings')
->set('field_settings', $field_settings)
->set('doi_term_islandora_term_pairs', $doi_term_islandora_term_pairs)
->set('content_type', $content_type)
->save();
parent::submitForm($form, $form_state);
}
/**
* AJAX callback to refresh the form.
*/
public function ajaxCallback(array &$form, FormStateInterface $form_state) {
return $form['doi_term_islandora_term_pairs'];
}
/**
* Adds more key-value pair fields.
*/
public function addMoreCallback(array &$form, FormStateInterface $form_state) {
// Retrieve existing key-value pairs.
$doi_term_islandora_term_pairs = $form_state->get('doi_term_islandora_term_pairs') ?? [];
// Get submitted values and merge with stored ones.
$user_input = $form_state->getUserInput();
if (!empty($user_input['doi_term_islandora_term_pairs'])) {
foreach ($user_input['doi_term_islandora_term_pairs'] as $id => $values) {
if (!isset($doi_term_islandora_term_pairs[$id])) {
$doi_term_islandora_term_pairs[$id] = $values;
}
}
}
// Add a new empty entry with a unique ID.
$unique_id = uniqid();
$doi_term_islandora_term_pairs[$unique_id] = [
'key' => '',
'value' => '',
'unique_id' => $unique_id,
];
// Store the updated values.
$form_state->set('doi_term_islandora_term_pairs', $doi_term_islandora_term_pairs);
$form_state->set('entry_count', count($doi_term_islandora_term_pairs));
// Rebuild the form.
$form_state->setRebuild();
}
/**
* Remove chosen element.
*/
public function removeCallback(array &$form, FormStateInterface $form_state) {
$triggering_element = $form_state->getTriggeringElement();
// Using hidden field to get around Drupal's issues with ajax.
$button_name = $triggering_element['#name'] ?? '';
// Extract the unique ID from the button name.
if (preg_match('/remove_(.+)/', $button_name, $matches)) {
$clicked_id = $matches[1];
}
$doi_term_islandora_term_pairs = $form_state->get('doi_term_islandora_term_pairs') ?? [];
if (isset($doi_term_islandora_term_pairs[$clicked_id])) {
unset($doi_term_islandora_term_pairs[$clicked_id]);
}
$form_state->set('doi_term_islandora_term_pairs', $doi_term_islandora_term_pairs);
$form_state->set('entry_count', count($doi_term_islandora_term_pairs));
$form_state->setRebuild();
}
}
Loading…
Cancel
Save