Browse Source

refactored

main
ajstanley 11 months ago
parent
commit
5d5e1c3470
  1. 4
      doi_prefill.services.yml
  2. 110
      src/Form/DoiPrepopulateForm.php
  3. 143
      src/NodeBuilder.php

4
doi_prefill.services.yml

@ -2,3 +2,7 @@ services:
doi_prefill.crossref_api_reader:
class: Drupal\doi_prefill\CrossrefApiReader
arguments: ['@http_client', '@logger.channel.islandora', '@config.factory']
doi_prefill.node_builder:
class: Drupal\doi_prefill\NodeBuilder
arguments: ['@entity_type.manager', '@doi_prefill.crossref_api_reader']

110
src/Form/DoiPrepopulateForm.php

@ -7,10 +7,9 @@ namespace Drupal\doi_prefill\Form;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\node\Entity\Node;
use Drupal\taxonomy\Entity\Term;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\doi_prefill\CrossrefApiReader;
use Drupal\doi_prefill\NodeBuilder;
use Symfony\Component\HttpFoundation\RedirectResponse;
/**
@ -25,6 +24,13 @@ final class DoiPrepopulateForm extends FormBase {
*/
protected $doiApi;
/**
* The Node builder.
*
* @var Drupal\doi_prefill\NodeBuilder
*/
protected $nodeBuilder;
/**
* The entity type manager service.
*
@ -40,9 +46,10 @@ final class DoiPrepopulateForm extends FormBase {
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* The EntityTypeManager.
*/
public function __construct(CrossrefApiReader $doiApi, EntityTypeManagerInterface $entityTypeManager) {
public function __construct(CrossrefApiReader $doiApi, EntityTypeManagerInterface $entityTypeManager, NodeBuilder $nodeBuilder) {
$this->doiApi = $doiApi;
$this->entityTypeManager = $entityTypeManager;
$this->nodeBuilder = $nodeBuilder;
}
/**
@ -53,7 +60,8 @@ final class DoiPrepopulateForm extends FormBase {
return new static(
// Load the service required to construct this class.
$container->get('doi_prefill.crossref_api_reader'),
$container->get('entity_type.manager')
$container->get('entity_type.manager'),
$container->get('doi_prefill.node_builder')
);
}
@ -127,103 +135,13 @@ final class DoiPrepopulateForm extends FormBase {
public function submitForm(array &$form, FormStateInterface $form_state): void {
$doi = trim($form_state->getValue('doi'));
$collection = $form_state->getValue('collection');
$contents = $this->doiApi->getWork($doi);
// Build typed relations.
$typed_relations = [];
$vid = 'person';
foreach ($contents['author'] as $author) {
$author_term = "{$author['family']}";
if (isset($author['given'])) {
$author_term = "{$author_term}, {$author['given']}";
}
$term = $this->getOrCreateTerm($author_term, $vid);
$typed_relations[] = [
'target_id' => $term->id(),
'rel_type' => 'relators:aut',
];
}
$genre = $this->getOrCreateTerm($contents['type'], 'genre');
// Build new node.
$new_node = Node::create([
'title' => $contents['title'][0],
'field_member_of' => $collection,
'type' => 'islandora_object',
'field_contributors' => $typed_relations,
'field_publisher' => $contents['publisher'] ?? '',
'field_doi' => $doi,
'field_genre' => $genre->id(),
'field_issue' => $contents['issue'] ?? '',
'field_volume' => $contents['volume'] ?? '',
]);
$nid = $this->nodeBuilder->buildNode($collection, $doi);
// Optional fields.
if (isset($contents['abstract'])) {
$new_node->set('field_abstract', [
'value' => $contents['abstract'],
'format' => 'basic_html',
]);
}
if (isset($contents['published-online'])) {
$field_date_online = [];
foreach ($contents['published-online']['date-parts'] as $date_parts) {
$field_date_online[] = ['value' => implode('-', $date_parts)];
}
$new_node->set('field_date_online', $field_date_online);
}
// Multivalued fields.
$field_date_issued = [];
foreach (($contents['created']['date-parts'] ?? []) as $date_parts) {
$field_date_issued[] = ['value' => implode('-', $date_parts)];
}
$new_node->set('field_date_issued', $field_date_issued);
$field_series_issn = [];
foreach (($contents['ISSN'] ?? []) as $issn) {
$field_series_issn[] = ['value' => $issn];
}
$new_node->set('field_series_issn', $field_series_issn);
$new_node->save();
if ($form_state->getValue('redirect') == 'edit') {
$destination = "/node/{$new_node->id()}/edit";
$destination = "/node/{$nid}/edit";
$response = new RedirectResponse($destination);
$response->send();
}
}
/**
* Check if a term exists in a vocabulary. If not, create it.
*
* @param string $term_name
* The name of the term.
* @param string $vocabulary
* The machine name of the vocabulary.
*
* @return \Drupal\taxonomy\Entity\Term|null
* The term entity if found or created, or NULL on failure.
*/
public function getOrCreateTerm($term_name, $vocabulary) {
$terms = $this->entityTypeManager->getStorage('taxonomy_term')->loadByProperties([
'name' => $term_name,
'vid' => $vocabulary,
]);
if ($terms) {
// Return the first found term.
return reset($terms);
}
// If the term does not exist, create it.
$term = Term::create([
'name' => $term_name,
'vid' => $vocabulary,
]);
$term->save();
return $term;
}
}

143
src/NodeBuilder.php

@ -0,0 +1,143 @@
<?php
declare(strict_types=1);
namespace Drupal\doi_prefill;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\node\Entity\Node;
use Drupal\taxonomy\Entity\Term;
/**
* Class to construct nodes from crossref DOI harvest.
*/
final class NodeBuilder {
/**
* Mapping of content types to their respective classes.
*
* @var arraystringstring
*/
protected $mapping = [
'journal-article' => 'Journal Article',
'book-chapter' => 'Book, Section',
'monograph' => 'Book',
'proceedings-article' => 'Conference Proceedings',
];
/**
* Constructs a CrossrefApiReader object.
*/
public function __construct(
private readonly EntityTypeManager $entityTypeManager,
private readonly CrossrefApiReader $doiApi,
) {}
/**
* Builds and saves new node.
*
* @param int $collection
* The node ID of the collection.
* @param string $doi
* The DOI URL associated with the content.
*
* @return string
* The id of new node.
*/
public function buildNode($collection, $doi) {
$contents = $this->doiApi->getWork($doi);
// Build typed relations.
$typed_relations = [];
$vid = 'person';
foreach ($contents['author'] as $author) {
$author_term = "{$author['family']}";
if (isset($author['given'])) {
$author_term = "{$author_term}, {$author['given']}";
}
$term = $this->getOrCreateTerm($author_term, $vid);
$typed_relations[] = [
'target_id' => $term->id(),
'rel_type' => 'relators:aut',
];
}
$genre = $this->getOrCreateTerm($contents['type'], 'genre');
// Build new node.
$new_node = Node::create([
'title' => $contents['title'][0],
'field_member_of' => $collection,
'type' => 'islandora_object',
'field_contributors' => $typed_relations,
'field_publisher' => $contents['publisher'] ?? '',
'field_doi' => $doi,
'field_genre' => $genre->id(),
'field_issue' => $contents['issue'] ?? '',
'field_volume' => $contents['volume'] ?? '',
]);
// Optional fields.
if (isset($contents['abstract'])) {
$new_node->set('field_abstract', [
'value' => $contents['abstract'],
'format' => 'basic_html',
]);
}
if (isset($contents['published-online'])) {
$field_date_online = [];
foreach ($contents['published-online']['date-parts'] as $date_parts) {
$field_date_online[] = ['value' => implode('-', $date_parts)];
}
$new_node->set('field_date_online', $field_date_online);
}
// Multivalued fields.
$field_date_issued = [];
foreach (($contents['created']['date-parts'] ?? []) as $date_parts) {
$field_date_issued[] = ['value' => implode('-', $date_parts)];
}
$new_node->set('field_date_issued', $field_date_issued);
$field_series_issn = [];
foreach (($contents['ISSN'] ?? []) as $issn) {
$field_series_issn[] = ['value' => $issn];
}
$new_node->set('field_series_issn', $field_series_issn);
$new_node->save();
return $new_node->id();
}
/**
* Check if a term exists in a vocabulary. If not, create it.
*
* @param string $term_name
* The name of the term.
* @param string $vocabulary
* The machine name of the vocabulary.
*
* @return \Drupal\taxonomy\Entity\Term|null
* The term entity if found or created, or NULL on failure.
*/
public function getOrCreateTerm($term_name, $vocabulary) {
$terms = $this->entityTypeManager->getStorage('taxonomy_term')->loadByProperties([
'name' => $term_name,
'vid' => $vocabulary,
]);
if ($terms) {
// Return the first found term.
return reset($terms);
}
// If the term does not exist, create it.
$term = Term::create([
'name' => $term_name,
'vid' => $vocabulary,
]);
$term->save();
return $term;
}
}
Loading…
Cancel
Save