Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DDST-455] BCELN24MIG-161: Feature/base fields #77

Merged
merged 7 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
{
"name": "discoverygarden/islandora_citations",
"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."
}
}
2 changes: 2 additions & 0 deletions config/schema/islandora_citations.schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
124 changes: 67 additions & 57 deletions islandora_citations.module
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty much just:

  • renamed the old function away from the hook name
  • adjusted its contents to exit early when failing to load the "schema", where much of mess comes from here with reindentation
  • readded the old hook to call the new renamed function, as well as two new hooks which call the renamed function to similarly attach when both adding and editing base field overrides.
  • slightly simplified the form flow: Putting things directly into $form['third_party_settings'] avoids have to separately handling things on submission.

Original file line number Diff line number Diff line change
Expand Up @@ -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'),
];
}
}

/**
Expand Down
6 changes: 5 additions & 1 deletion islandora_citations.routing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,15 @@ 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:
_title: 'Citations Map Configuration'
_controller: 'islandora_citations.controller:provideArguments'
requirements:
_permission: 'administer islandora_citations'
options:
parameters:
node_type:
type: entity:node_type
JojoVes marked this conversation as resolved.
Show resolved Hide resolved
3 changes: 2 additions & 1 deletion islandora_citations.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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']
Expand Down
112 changes: 85 additions & 27 deletions src/Controller/IslandoraCitationsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -15,56 +22,63 @@ 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) {

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('<a href=":link">@name</a>',
[
':link' => 'fields/node.' . $node_type . '.' . $field_definition->getName(),
'@name' => $this->t('Edit'),
]),
],
[
'data' => $this->getLinkToField('node', $node_type, $field_definition),
],
];
}
}
Expand All @@ -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('<current>')->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)),
) :
Comment on lines +118 to +121
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An outdated comment is applicable to this section of code so linking for future reference #77 (comment)

And yes I can confirm this is currently not applicable to the list of fields being iterated on, but I see no harm keeping it here in case things get extended/altered to iterate over all base fields rather than just the ones already included in a given content type.

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.
Expand All @@ -101,11 +163,7 @@ public function paragraphsArguments($paragraphs_type) {
$rows[] = [$field_definition->getName(),
$data ? implode(',', $data) : '-',
[
'data' => new FormattableMarkup('<a href=":link">@name</a>',
[
':link' => 'fields/paragraph.' . $paragraphs_type->id() . '.' . $field_definition->getName(),
'@name' => $this->t('Edit'),
]),
'data' => $this->getLinkToField('paragraph', $paragraphs_type, $field_definition),
],
];
}
Expand Down
14 changes: 8 additions & 6 deletions src/Form/SelectCslForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading
Loading