Skip to content

Commit

Permalink
Merge pull request #77 from discoverygarden/feature/base-fields
Browse files Browse the repository at this point in the history
[DDST-455] BCELN24MIG-161: Feature/base fields
  • Loading branch information
chrismacdonaldw authored Aug 26, 2024
2 parents 35acc7c + 843ca51 commit 580d5ef
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 102 deletions.
9 changes: 6 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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."
}
}
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
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
2 changes: 1 addition & 1 deletion islandora_citations.routing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
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)),
) :
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

0 comments on commit 580d5ef

Please sign in to comment.