diff --git a/composer.json b/composer.json
index 2560be5..3fd07c4 100644
--- a/composer.json
+++ b/composer.json
@@ -2,9 +2,12 @@
"name": "discoverygarden/islandora_citations",
"license": "GPL-3.0-only",
"type": "drupal-module",
- "require": {
+ "require": {
+ "islandora/controlled_access_terms": "^2",
"seboettg/citeproc-php": "^2.6.0",
- "webflo/drupal-finder": "^1.2.2",
- "islandora/controlled_access_terms": "^2"
+ "webflo/drupal-finder": "^1.2.2"
+ },
+ "suggest": {
+ "drupal/base_field_override_ui": "To allow the use of 'base' entity fields in mappings."
}
}
diff --git a/config/schema/islandora_citations.schema.yml b/config/schema/islandora_citations.schema.yml
index 2e57f56..d470434 100644
--- a/config/schema/islandora_citations.schema.yml
+++ b/config/schema/islandora_citations.schema.yml
@@ -22,9 +22,11 @@ field.field.*.*.*.third_party.islandora_citations:
sequence:
type: string
label: 'CSL'
+ nullable: true
use_entity_checkbox:
label: 'CSL Mapping from Entity'
type: boolean
+ nullable: true
islandora_citations.settings:
type: config_object
diff --git a/islandora_citations.module b/islandora_citations.module
index 090b006..e0cc701 100644
--- a/islandora_citations.module
+++ b/islandora_citations.module
@@ -5,77 +5,87 @@
* General hook implementations.
*/
-use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
/**
* Implements hook_form_FORM_ID_alter().
*/
function islandora_citations_form_field_config_edit_form_alter(&$form, FormStateInterface $form_state, $form_id) {
- $schema = json_decode(file_get_contents(__DIR__ . '/data/csl-data.json'), 1);
+ _islandora_citations_form_field_config_edit_form_alter($form, $form_state, $form_id);
+}
- if ($schema) {
- $cslPropertyArray = array_keys($schema['items']['properties']);
- $cslFieldOptions = array_combine($cslPropertyArray, $cslPropertyArray);
- $entity = $form_state->getFormObject()->getEntity();
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function islandora_citations_form_base_field_override_add_form_alter(&$form, FormStateInterface $form_state, $form_id) {
+ _islandora_citations_form_field_config_edit_form_alter($form, $form_state, $form_id);
+}
- $form['islandora_citations'] = [
- '#title' => 'Citation Settings',
- '#type' => 'fieldset',
- ];
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function islandora_citations_form_base_field_override_edit_form_alter(&$form, FormStateInterface $form_state, $form_id) {
+ _islandora_citations_form_field_config_edit_form_alter($form, $form_state, $form_id);
+}
+
+/**
+ * Common form alteration callback to add third-party settings.
+ */
+function _islandora_citations_form_field_config_edit_form_alter(&$form, FormStateInterface $form_state, $form_id) {
+ $schema = json_decode(file_get_contents(__DIR__ . '/data/csl-data.json'), 1);
- // For typed relation, there is no separate mapping.
- // It can just be enabled and the mapping will be based on rel type.
- if ($entity->getType() == 'typed_relation') {
- $form['islandora_citations']['use_entity_checkbox'] = [
- '#title' => t('Map CSL from relation type'),
- '#description' => t('Enable mapping of this typed relation field from the selected relation type. Rel types, author and creator both get mapped to author.'),
- '#type' => 'checkbox',
- '#required' => FALSE,
- '#default_value' => $entity->getThirdPartySetting('islandora_citations', 'use_entity_checkbox'),
- ];
- }
+ if (!$schema) {
+ return;
+ }
- // For ERR (paragraphs), we only allow mapping from entity.
- // Fields mapped inside the paragraph are only considered, else ignored.
- // For ER fields, we allow both mapping selected from entity
- // or mapping just the title of the ER entity.
- if ($entity->getType() == 'entity_reference_revisions' || $entity->getType() == 'entity_reference') {
- $form['islandora_citations']['use_entity_checkbox'] = [
- '#title' => t('Map from referenced entity'),
- '#description' => \t('If this field is enabled, the csl mapping will be taken from the referenced entity. Make sure you map fields in the referenced entity before enabling this.'),
- '#type' => 'checkbox',
- '#required' => FALSE,
- '#default_value' => $entity->getThirdPartySetting('islandora_citations', 'use_entity_checkbox'),
- ];
- }
+ $cslPropertyArray = array_keys($schema['items']['properties']);
+ $cslFieldOptions = array_combine($cslPropertyArray, $cslPropertyArray);
+ /** @var \Drupal\field\FieldConfigInterface $entity */
+ $entity = $form_state->getFormObject()->getEntity();
- // We do not allow direct mapping for typed relation or ERR.
- if (!($entity->getType() === 'entity_reference_revisions' || $entity->getType() === 'typed_relation')) {
- $form['islandora_citations']['csl_field'] = [
- '#type' => 'select',
- '#title' => \t('CSL Field'),
- '#description' => \t('Select which CSL value this field should be mapped to.'),
- '#empty_option' => \t('- Select -'),
- '#multiple' => TRUE,
- '#options' => $cslFieldOptions,
- '#default_value' => $entity->getThirdPartySetting('islandora_citations', 'csl_field'),
- ];
- }
+ $form['third_party_settings']['islandora_citations'] = [
+ '#title' => 'Citation Settings',
+ '#type' => 'fieldset',
+ ];
- $form['#entity_builders'][] = 'islandora_citations_field_config_edit_form_form_builder';
- return $form;
+ // For typed relation, there is no separate mapping.
+ // It can just be enabled and the mapping will be based on rel type.
+ if ($entity->getType() == 'typed_relation') {
+ $form['third_party_settings']['islandora_citations']['use_entity_checkbox'] = [
+ '#title' => t('Map CSL from relation type'),
+ '#description' => t('Enable mapping of this typed relation field from the selected relation type. Rel types, author and creator both get mapped to author.'),
+ '#type' => 'checkbox',
+ '#required' => FALSE,
+ '#default_value' => $entity->getThirdPartySetting('islandora_citations', 'use_entity_checkbox'),
+ ];
}
-}
-/**
- * Entity builder for the config edit form with third party options.
- *
- * @see islandora_citations_field_config_edit_form_alter()
- */
-function islandora_citations_field_config_edit_form_form_builder($entity_type, EntityInterface $configEntity, &$form, FormStateInterface $form_state) {
- $configEntity->setThirdPartySetting('islandora_citations', 'csl_field', $form_state->getValue('csl_field'));
- $configEntity->setThirdPartySetting('islandora_citations', 'use_entity_checkbox', $form_state->getValue('use_entity_checkbox'));
+ // For ERR (paragraphs), we only allow mapping from entity.
+ // Fields mapped inside the paragraph are only considered, else ignored.
+ // For ER fields, we allow both mapping selected from entity
+ // or mapping just the title of the ER entity.
+ if ($entity->getType() == 'entity_reference_revisions' || $entity->getType() == 'entity_reference') {
+ $form['third_party_settings']['islandora_citations']['use_entity_checkbox'] = [
+ '#title' => t('Map from referenced entity'),
+ '#description' => \t('If this field is enabled, the csl mapping will be taken from the referenced entity. Make sure you map fields in the referenced entity before enabling this.'),
+ '#type' => 'checkbox',
+ '#required' => FALSE,
+ '#default_value' => $entity->getThirdPartySetting('islandora_citations', 'use_entity_checkbox'),
+ ];
+ }
+
+ // We do not allow direct mapping for typed relation or ERR.
+ if (!($entity->getType() === 'entity_reference_revisions' || $entity->getType() === 'typed_relation')) {
+ $form['third_party_settings']['islandora_citations']['csl_field'] = [
+ '#type' => 'select',
+ '#title' => \t('CSL Field'),
+ '#description' => \t('Select which CSL value this field should be mapped to.'),
+ '#empty_option' => \t('- Select -'),
+ '#multiple' => TRUE,
+ '#options' => $cslFieldOptions,
+ '#default_value' => $entity->getThirdPartySetting('islandora_citations', 'csl_field'),
+ ];
+ }
}
/**
diff --git a/islandora_citations.routing.yml b/islandora_citations.routing.yml
index 6aa1606..431c68b 100644
--- a/islandora_citations.routing.yml
+++ b/islandora_citations.routing.yml
@@ -40,7 +40,7 @@ entity.islandora_citations.add_from_file:
_permission: 'administer islandora_citations'
options:
_admin_route: TRUE
-
+
islandora_citations.tab.node:
path: '/admin/structure/types/manage/{node_type}/citations-map-configuration'
defaults:
diff --git a/islandora_citations.services.yml b/islandora_citations.services.yml
index de4dffb..f1273dd 100644
--- a/islandora_citations.services.yml
+++ b/islandora_citations.services.yml
@@ -5,7 +5,8 @@ services:
arguments: ['islandora_citations']
islandora_citations.controller:
class: Drupal\islandora_citations\Controller\IslandoraCitationsController
- arguments: ['@entity_field.manager']
+ factory: [null, 'create']
+ arguments: ['@service_container']
islandora_citations.helper:
class: Drupal\islandora_citations\IslandoraCitationsHelper
arguments: ['@entity_type.manager', '@file_system', '@serializer', '@logger.channel.islandora_citations']
diff --git a/src/Controller/IslandoraCitationsController.php b/src/Controller/IslandoraCitationsController.php
index 2576628..24518af 100644
--- a/src/Controller/IslandoraCitationsController.php
+++ b/src/Controller/IslandoraCitationsController.php
@@ -2,10 +2,17 @@
namespace Drupal\islandora_citations\Controller;
-use Drupal\Component\Render\FormattableMarkup;
+use Drupal\base_field_override_ui\BaseFieldOverrideUI;
+use Drupal\Core\Config\Entity\ConfigEntityBundleBase;
use Drupal\Core\Controller\ControllerBase;
-use Drupal\Core\Entity\EntityFieldManager;
+use Drupal\Core\Entity\EntityFieldManagerInterface;
+use Drupal\Core\Field\Entity\BaseFieldOverride;
+use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Link;
use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\Core\Url;
+use Drupal\node\Entity\NodeType;
+use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Returns responses for islandora_citations module routes.
@@ -15,40 +22,50 @@ class IslandoraCitationsController extends ControllerBase {
use StringTranslationTrait;
/**
- * The entity field manager.
+ * Drupal's entity field manager service.
*
- * @var \Drupal\Core\Entity\EntityFieldManager
+ * @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
+ protected EntityFieldManagerInterface $entityFieldManager;
- protected $entityFieldManager;
+ /**
+ * {@inheritDoc}
+ */
+ public static function create(ContainerInterface $container) {
+ return parent::create($container)
+ ->setEntityFieldManager($container->get('entity_field.manager'));
+ }
/**
- * Construct.
+ * Setter for the entity field manager service.
*
- * @param \Drupal\Core\Entity\EntityFieldManager $entityFieldManager
- * The entity type manager service.
+ * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entityFieldManager
+ * The entity field manager service to set.
+ *
+ * @return $this
*/
- public function __construct(EntityFieldManager $entityFieldManager) {
+ public function setEntityFieldManager(EntityFieldManagerInterface $entityFieldManager) : static {
$this->entityFieldManager = $entityFieldManager;
+ return $this;
}
/**
* Provide arguments for FieldConfigUpdate.
*
- * @param string $node_type
+ * @param \Drupal\node\Entity\NodeType $node_type
* Node type.
*
* @return array
* Form array.
*/
- public function provideArguments($node_type) {
+ public function provideArguments(NodeType $node_type) {
$header = [
'col1' => $this->t('Field'),
'col2' => $this->t('CSL Field'),
'col3' => $this->t('Operation'),
];
- $fields = $this->entityFieldManager->getFieldDefinitions('node', $node_type);
+ $fields = $this->entityFieldManager->getFieldDefinitions('node', $node_type->id());
$rows = [];
foreach ($fields as $field_definition) {
@@ -56,15 +73,12 @@ public function provideArguments($node_type) {
if (!empty($field_definition->getTargetBundle())) {
$data = $field_definition->getThirdPartySetting('islandora_citations', 'csl_field');
$dataForMappedEntities = $field_definition->getThirdPartySetting('islandora_citations', 'use_entity_checkbox');
- $rows[] = [$field_definition->getName(),
+ $rows[] = [
+ $field_definition->getName(),
$data ? implode(',', $data) : ($dataForMappedEntities ? 'Mapped from entity' : '-'),
- [
- 'data' => new FormattableMarkup('@name',
- [
- ':link' => 'fields/node.' . $node_type . '.' . $field_definition->getName(),
- '@name' => $this->t('Edit'),
- ]),
- ],
+ [
+ 'data' => $this->getLinkToField('node', $node_type, $field_definition),
+ ],
];
}
}
@@ -76,11 +90,59 @@ public function provideArguments($node_type) {
];
}
+ /**
+ * Helper; generate link to the field configuration page.
+ *
+ * @param string $type
+ * The type of entity to which the field is associated.
+ * @param \Drupal\Core\Config\Entity\ConfigEntityBundleBase $bundle
+ * The bundle with which the field is associated.
+ * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
+ * The field definition of which to link to the configuration page.
+ *
+ * @return \Drupal\Core\Link|\Drupal\Core\StringTranslation\TranslatableMarkup
+ * A link to a page to configure the given field, or a string.
+ */
+ protected function getLinkToField(string $type, ConfigEntityBundleBase $bundle, FieldDefinitionInterface $field_definition) {
+ $add_destination = static function (Url $url) {
+ $query = $url->getOption('query');
+ $query['destination'] = Url::fromRoute('')->toString();
+ $url->setOption('query', $query);
+ return $url;
+ };
+ /** @var \Drupal\Core\Field\Entity\BaseFieldOverride|\Drupal\field\Entity\FieldConfig $config */
+ $config = $field_definition->getConfig($bundle->id());
+ if ($config instanceof BaseFieldOverride) {
+ if ($this->moduleHandler()->moduleExists('base_field_override_ui')) {
+ return $config->isNew() ?
+ new Link(
+ $this->t('Add'),
+ $add_destination(BaseFieldOverrideUI::getAddRouteInfo($config)),
+ ) :
+ new Link(
+ $this->t('Edit'),
+ $add_destination(BaseFieldOverrideUI::getEditRouteInfo($config)),
+ );
+ }
+
+ return $this->t('Not applicable');
+ }
+ else {
+ return new Link(
+ $this->t('Edit'),
+ $add_destination(Url::fromRoute("entity.field_config.{$type}_field_edit_form", [
+ $bundle->getEntityTypeId() => $bundle->id(),
+ 'field_config' => $config->id(),
+ ])),
+ );
+ }
+ }
+
/**
* Provide arguments for FieldConfigUpdate.
*
- * @param string $paragraphs_type
- * Node type.
+ * @param \Drupal\paragraphs\Entity\ParagraphsType $paragraphs_type
+ * Paragraph type.
*
* @return array
* Form array.
@@ -101,11 +163,7 @@ public function paragraphsArguments($paragraphs_type) {
$rows[] = [$field_definition->getName(),
$data ? implode(',', $data) : '-',
[
- 'data' => new FormattableMarkup('@name',
- [
- ':link' => 'fields/paragraph.' . $paragraphs_type->id() . '.' . $field_definition->getName(),
- '@name' => $this->t('Edit'),
- ]),
+ 'data' => $this->getLinkToField('paragraph', $paragraphs_type, $field_definition),
],
];
}
diff --git a/src/Form/SelectCslForm.php b/src/Form/SelectCslForm.php
index 658c3a6..a1d395b 100644
--- a/src/Form/SelectCslForm.php
+++ b/src/Form/SelectCslForm.php
@@ -61,13 +61,15 @@ class SelectCslForm extends FormBase {
protected $logger;
/**
- * {@inheritdoc}
+ * Constructor.
*/
- public function __construct(IslandoraCitationsHelper $citationHelper,
- RouteMatchInterface $route_match,
- EntityTypeManagerInterface $entity_type_manager,
- AliasManagerInterface $pathAliasManager,
- LoggerInterface $logger) {
+ public function __construct(
+ IslandoraCitationsHelper $citationHelper,
+ RouteMatchInterface $route_match,
+ EntityTypeManagerInterface $entity_type_manager,
+ AliasManagerInterface $pathAliasManager,
+ LoggerInterface $logger,
+ ) {
$this->citationHelper = $citationHelper;
$this->routeMatch = $route_match;
$this->entityTypeManager = $entity_type_manager;
diff --git a/src/Normalizer/ContentEntityNormalizer.php b/src/Normalizer/ContentEntityNormalizer.php
index 3837bab..710cf29 100644
--- a/src/Normalizer/ContentEntityNormalizer.php
+++ b/src/Normalizer/ContentEntityNormalizer.php
@@ -2,7 +2,6 @@
namespace Drupal\islandora_citations\Normalizer;
-use Drupal\Core\Config\Entity\ThirdPartySettingsInterface;
use Drupal\Core\Entity\ContentEntityInterface;
/**
@@ -19,19 +18,18 @@ class ContentEntityNormalizer extends NormalizerBase {
* {@inheritdoc}
*/
public function normalize($object, $format = NULL, array $context = []) {
+ assert($object instanceof ContentEntityInterface);
$normalized_field_items = [];
foreach ($object->getFields(TRUE) as $field_item_list) {
/** @var \Drupal\Core\Field\FieldDefinitionInterface $fieldDefinition */
$fieldDefinition = $field_item_list->getFieldDefinition();
- // Do not process if there are no third party settings.
- if (!($fieldDefinition instanceof ThirdPartySettingsInterface)) {
- continue;
- }
+ /** @var \Drupal\Core\Field\Entity\BaseFieldOverride|\Drupal\field\Entity\FieldConfig $field_config */
+ $field_config = $fieldDefinition->getConfig($object->bundle());
- $mapFromSelectedCsl = $fieldDefinition->getThirdPartySetting('islandora_citations', 'csl_field');
- $mapFromEntity = $fieldDefinition->getThirdPartySetting('islandora_citations', 'use_entity_checkbox');
+ $mapFromSelectedCsl = $field_config->getThirdPartySetting('islandora_citations', 'csl_field');
+ $mapFromEntity = $field_config->getThirdPartySetting('islandora_citations', 'use_entity_checkbox');
// Do not process if field is not mapped.
if (empty($mapFromSelectedCsl) && empty($mapFromEntity)) {