Compare commits

..

2 Commits

Author SHA1 Message Date
Rosie Le Faive 503af8ce20 Basic solr, no edtf. 3 months ago
Rosie Le Faive 3a0d1c1ee2 Proof of concept with tables. 3 months ago
  1. 17
      css/metadata_profile.css
  2. 4
      metadata_profile.libraries.yml
  3. 13
      metadata_profile.routing.yml
  4. 300
      src/Controller/MetadataProfileController.php

17
css/metadata_profile.css

@ -0,0 +1,17 @@
.field-info-table {
max-width: 40rem;
}
.field-info-table td {
max-width: 49%;
}
.field-info {
padding-bottom: 3rem;
border-bottom: gainsboro 1px solid;
margin-bottom: 3rem;
}
.field-info h2 {
display: inline-block;
}
.field-info .edit-link {
display: block;
}

4
metadata_profile.libraries.yml

@ -0,0 +1,4 @@
metadata_profile:
css:
theme:
css/metadata_profile.css: {}

13
metadata_profile.routing.yml

@ -0,0 +1,13 @@
metadata_profile.node_profile:
path: '/admin/structure/types/manage/{content_type}/metadata_profile'
defaults:
_controller: '\Drupal\metadata_profile\Controller\MetadataProfileController::profile'
_title: 'Metadata Profile'
requirements:
_access: 'TRUE'
content_type: '[a-zA-Z_]+'
options:
parameters:
content_type:
type: string

300
src/Controller/MetadataProfileController.php

@ -0,0 +1,300 @@
<?php
namespace Drupal\metadata_profile\Controller;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Field\FieldTypePluginManagerInterface;
use Drupal\Core\Messenger\MessengerTrait;
use Drupal\Core\Config\Config;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
class MetadataProfileController extends ControllerBase {
use MessengerTrait;
protected EntityFieldManagerInterface $entityFieldManager;
protected FieldTypePluginManagerInterface $fieldTypePluginManager;
protected $configFactory;
public function __construct(EntityFieldManagerInterface $entity_field_manager,
FieldTypePluginManagerInterface $field_type_plugin_manager,
ConfigFactoryInterface $config_factory) {
$this->entityFieldManager = $entity_field_manager;
$this->fieldTypePluginManager = $field_type_plugin_manager;
$this->configFactory = $config_factory;
}
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_field.manager'),
$container->get('plugin.manager.field.field_type'),
$container->get('config.factory')
);
}
public function profile( $content_type) {
// Get core content type information.
$node_type = $this->config('node.type.' . $content_type);
if (!$node_type) {
return ['#markup'=> 'Not a valid content type.'];
}
$build = $this->format_bundle($node_type);
$build['children'] = [
'#type' => 'container',
'#weight' => '9',
];
// Get field information.
$field_definitions = $this->entityFieldManager->getFieldDefinitions('node', $content_type);
foreach ($field_definitions as $field_name => $field_definition) {
$build['children'][$field_name] = $this->format_field($field_name, $field_definition);
}
return $build;
}
/**
* Format information about a bundle.
*/
protected function format_bundle(Config $bundle) {
$build = [
'#type' => 'container',
'#attached' => ['library' => ['metadata_profile/metadata_profile']],
'title' => [
'#plain_text' => $bundle->get('name'),
'#prefix' => '<h1>',
'#suffix' => '</h1>',
],
'machine_name' => [
'#plain_text' => $bundle->get('type'),
'#prefix' => ' (',
'#suffix' => ')',
],
'description' => [
'#plain_text' => $bundle->get('description'),
'#prefix' => '<p>',
'#suffix' => '</p>',
],
];
return $build;
}
protected function format_field(string $field_name, FieldDefinitionInterface $field_definition) {
$render_array = [];
if (str_starts_with($field_name, 'field_') or $field_name == 'title') {
$render_array = [
'#type' => 'container',
'#attributes' => ['class' => ['field-info']],
'#weight' => $this->format_weight($field_definition),
'title' => [
'#plain_text' => $field_definition->getLabel(),
'#prefix' => '<h2 id="' . $field_name . '">',
'#suffix' => '</h2> ',
],
'machine_name' => [
'#plain_text' => $field_name,
'#prefix' => '(',
'#suffix' => ') ',
],
'edit_link' => [
'#type' => 'link',
'#url' => Url::fromRoute('entity.field_config.node_field_edit_form', [
'node_type' => $field_definition->getTargetBundle(),
'field_config' => $field_definition->id(),
'destination' => Url::fromRoute('metadata_profile.node_profile', ['content_type' => $field_definition->getTargetBundle()], ['fragment' => $field_name])->toString(),
]),
'#title' => $this->t('Edit'),
'#attributes' => ['class' => ['edit-link']],
],
'table' => [
'#type' => 'table',
'#header' => ['Field Configuration',''],
'#rows' => $this->getFieldTableRows($field_definition),
'#attributes' => ['class' => ['field-info-table']],
],
'description' => [
'#type' => 'markup',
'#markup' => $field_definition->getDescription() ?: $this->t('[No description]'),
],
'target_bundles' => [
'#title' => $this->t('Target Bundles'),
'#type' => 'container',
'bundles' => $this->format_target_bundles($field_definition),
],
'search_api' => $this->formatSearchApi($field_definition),
];
}
return $render_array;
}
protected function getFieldTableRows(FieldDefinitionInterface $field_definition) {
$rows = [
[$this->t('Type:'), $this->format_type($field_definition)],
[$this->t('Required:'), $this->format_required($field_definition)],
[$this->t('Repeatable:'), $this->format_cardinality($field_definition)],
];
// TODO: use a class inheritance method to get entity reference and typed relation in one shot.
if (in_array($field_definition->getType(), ['entity_reference', 'typed_relation'])) {
$rows[] = [$this->t('Create new'), $this->format_create_new($field_definition)];
}
return $rows;
}
protected function format_type(FieldDefinitionInterface $field_definition) {
$type = $field_definition->getType();
$type_label = $this->fieldTypePluginManager->getDefinition($type)['label'];
if (in_array($type, ['entity_reference', 'typed_relation'])) {
$type_label = $type_label . ' (' . $field_definition->getSetting('target_type') . ')';
}
return $type_label;
}
protected function format_required(FieldDefinitionInterface $field_definition) {
if ($field_definition->isRequired()) {
return $this->t('Required');
}
else {
return $this->t('Not required');
}
}
/**
* This does not work - most fields dont have a form weight specified in getDisplayOptions.
*/
protected function format_weight(FieldDefinitionInterface $field_definition) {
return $field_definition->getDisplayOptions('form')['weight'];
}
protected function format_cardinality(FieldDefinitionInterface $field_definition) {
$cardinality = $field_definition->getFieldStorageDefinition()->getCardinality();
if ($cardinality == 1) {
return $this->t('Not repeatable');
} elseif ($cardinality < 0) {
return $this->t('Repeatable');
} elseif ($cardinality > 1) {
return $this->t('Repeatable, limit :limit', [':limit' => $cardinality]);
}
return NULL;
}
protected function format_create_new(FieldDefinitionInterface $field_definition) {
$create_new_bundle = $field_definition->getSetting('handler_settings')['auto_create_bundle'];
$create_new = $field_definition->getSetting('handler_settings')['auto_create_bundle'];
if ($create_new) {
return $create_new_bundle ? 'Create new (' . $create_new_bundle . ')' : 'Create new';
}
else {
return $this->t('Do not create new');
}
}
protected function format_target_bundles(FieldDefinitionInterface $field_definition) {
$handler = $field_definition->getSetting('handler');
$setting = $field_definition->getSetting('handler_settings');
if (!$setting) {
return [];
}
$target_bundles = $setting['target_bundles'];
foreach ($target_bundles as $index => $bundle) {
if ($handler == 'default:taxonomy_term') {
$bundle_config = $this->entityTypeManager()->getStorage('taxonomy_vocabulary')->load($bundle);
}
// TODO: ADD NODE ETC
if ($bundle_config) {
$target_bundles[$index] = $bundle_config->get('name') . ' (' . $bundle . ')';
}
}
return [
'#theme' => 'item_list',
'#title' => $this->t('Target bundles:'),
'#items' => $target_bundles,
'#type' => 'ul'
];
}
protected function formatSearchApi($field_definition) {
if ($this->moduleHandler()->moduleExists('search_api')) {
$build = [
'#type' => 'table',
'#header' => [
'col1' => $this->t('Search API field name'),
'col2' => $this->t('Search API machine name'),
'col3' => $this->t('Search API property path'),
'col4' => $this->t('Search API field type'),
'col0' => $this->t('Search API index'),
],
'#rows' => [],
'#caption' => $this->t('Search API')
];
$storage = $field_definition->getFieldStorageDefinition();
if ($storage instanceof BaseFieldDefinition) {
// Use property_path to find related fields.
$field_id = 'node.' . $storage->getName();
}
else {
$field_id = 'field.storage.' . $storage->get('id');
}
$indexes = $this->configFactory->listAll('search_api.index');
foreach ($indexes as $index) {
$index_config = $this->config($index);
// Loop over fields.
foreach ($index_config->get('field_settings') as $field_setting_name => $field_setting) {
// Check dependencies.
$field_dependencies = $field_setting['dependencies']['config'] ?: [];
if (in_array($field_id, $field_dependencies)) {
$build['#rows'][$field_setting_name] = $this->format_solr_field($field_setting_name, $field_setting, $index_config);
}
// Check by property path.
if ($field_setting['datasource_id'] == 'entity:node' and $field_setting['property_path'] == $field_definition->getName()) {
$build['#rows'][$field_setting_name] = $this->format_solr_field($field_setting_name, $field_setting, $index_config);
}
// Get Aggregated Fields.
if ($field_setting['property_path'] == 'aggregated_field') {
if (in_array('entity:node/' . $field_definition->getName(), $field_setting['configuration']['fields'])) {
$build['#rows'][$field_setting_name] = $this->format_solr_field($field_setting_name, $field_setting, $index_config);
}
}
// Get EDTFyear.
}
if (count($build['#rows']) == 0) {
return [];
}
}
return $build;
}
else {
return [];
}
}
protected function format_solr_field($field_setting_name, $field_setting, $index_config) {
$build = [
'data' => [
$field_setting['label'],
$field_setting_name,
$field_setting['property_path'],
$field_setting['type'],
$index_config->get('name'),
]
];
if ($field_setting['property_path'] == 'aggregated_field') {
$build['data'][2] .= ' -' . implode(', -', $field_setting['configuration']['fields']);
}
return $build;
}
}
Loading…
Cancel
Save