Compare commits

..

No commits in common. 'b8592f5a13b1e2413499f2e8e105cd0ce7081252' and '503af8ce202d9f5ff81ba508a6838083fea82a7b' have entirely different histories.

  1. 3
      css/metadata_profile.css
  2. 8
      metadata_profile.routing.yml
  3. 317
      src/Controller/MetadataProfileController.php

3
css/metadata_profile.css

@ -15,6 +15,3 @@
.field-info .edit-link {
display: block;
}
.scrolling-table-container {
overflow-x: auto;
}

8
metadata_profile.routing.yml

@ -10,12 +10,4 @@ metadata_profile.node_profile:
parameters:
content_type:
type: string
metadata_profile.test:
path: '/test'
defaults:
_controller: '\Drupal\metadata_profile\Controller\MetadataProfileController::test'
_title: 'Metadata Profile Test'
requirements:
_access: 'TRUE'

317
src/Controller/MetadataProfileController.php

@ -8,11 +8,9 @@ use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Field\FieldTypePluginManagerInterface;
use Drupal\Core\Link;
use Drupal\Core\Messenger\MessengerTrait;
use Drupal\Core\Config\Config;
use Drupal\Core\Url;
use Drupal\field_permissions\Plugin\FieldPermissionType\Base;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
@ -38,16 +36,11 @@ class MetadataProfileController extends ControllerBase {
$container->get('entity_field.manager'),
$container->get('plugin.manager.field.field_type'),
$container->get('config.factory')
);
}
/**
* Returns a render array displaying the metadata profile for $content_type.
*
* @param $content_type
* @return array
*/
public function profile($content_type) {
public function profile( $content_type) {
// Get core content type information.
$node_type = $this->config('node.type.' . $content_type);
@ -56,22 +49,14 @@ class MetadataProfileController extends ControllerBase {
}
$build = $this->format_bundle($node_type);
$metadata_profile = $this->getMetadataProfile($content_type);
$build['summary_table'] = [
'#type' => 'container',
'#attributes'=> ['class' => ['scrolling-table-container']],
'data' => $this->buildSummaryTable($metadata_profile),
];
$build['fields'] = [
$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['fields'][$field_name] = $this->display_field($field_name, $field_definition, $metadata_profile[$field_name]);
$build['children'][$field_name] = $this->format_field($field_name, $field_definition);
}
return $build;
@ -104,101 +89,15 @@ class MetadataProfileController extends ControllerBase {
return $build;
}
public function getMetadataProfile($bundle) {
// $metadata_profile is an array of arrays. Its keys are the "short" machine names of the fields
// such as field_abstract. The values are arrays with the following keys:
// * 'label' - text. the bundle's human-readable label.
// * 'machine_name' - text. The short machine name such as 'field_abstract'.
// * 'id' - text. The long machine name such as 'node.islandora_object.field_abstract'. (same as this array's key)
// * 'edit_url' - Url object. The link to the edit page for that field (or to the base field override page).
// * 'type' - text. The human readable type of the field. (e.g. "Entity Reference")
// * 'type_machine_name' - text. The machine name of the type (e.g. 'entity_reference')
// * 'required' - 'Required'|'Not required'. Whether the field is required.
// * 'cardinality' - 'Not repeatable'|'Repeatable'|'Repeatable, limit N'
// * 'auto_create' - 'Create new'|'Create new #bundle'|'Do not create new'|NULL Whether a relationship field allows new entity creation on the fly.
// * 'target_bundles' - array. List of bundle names that are the target of this field.
// * 'search_api' - associative array. Has the following keys:
// * 'in_search_api' - True|False. True if some field matches.
// * 'fields' - array. The 'fields' array is keyed by the machine names of the search api fields,
// which are arrays with the following fields:
// * 'search_api_field_name' - the machine name of the search api field.
// * 'search_api_field_label' - the human readable label of the search api field.
// * 'property_path' - the method for getting the values.
// * 'index_name' - the name of the Search API index (in case there are more than one)
// * 'fields_included' - for aggregate and EDTF processor fields, which fields are in that field.
// * 'facets' - associative array. has the following keys
// * 'has_facet' - True|False. True if there is a facet, even if not showing up (can use with url alias)
// * 'facets' - array. the 'facets' array is keyed by the machine name of the facet. each facet is an
// array with keys:
// * 'facet_name'
// * 'facet_machine_name'
// * 'facet_source'
// * 'url_alias'
// * 'block_visible'
$metadata_profile = [];
$field_definitions = $this->entityFieldManager->getFieldDefinitions('node', $bundle);
foreach ($field_definitions as $field_name => $field_definition) {
$metadata_profile[$field_name] = [
'label' => $field_definition->getLabel(),
'machine_name' => $field_name,
'id' => method_exists($field_definition, 'id') ? $field_definition->id() : $field_definition->getUniqueIdentifier(),
'edit_url' => $this->getFieldEditUrl($field_definition),
'details_link' => $this->getDetailsFragmentLink($field_name, $field_definition),
'type' => $this->formatType($field_definition),
'type_machine_name' => $field_definition->getType(),
'required' => $this->formatRequired($field_definition),
'repeatable' => $this->formatCardinality($field_definition),
'auto_create' => $this->formatCreateNew($field_definition),
'target_bundles' => $this->formatTargetBundles($field_definition),
];
// Add solr
}
return $metadata_profile;
}
protected function buildSummaryTable($metadata_profile) {
$rows = [];
foreach ($metadata_profile as $field_name => $field_profile) {
if (str_starts_with( $field_name, 'field_') or $field_name == 'title') {
$rows[] = [
$field_profile['details_link'],
$field_profile['machine_name'],
$field_profile['type'],
$field_profile['required'],
$field_profile['repeatable'],
$field_profile['auto_create'],
$this->formatListForTable($field_profile['target_bundles']),
];
}
}
return [
'#type' => 'table',
'#header' => [
$this->t('Field'),
$this->t('Machine name'),
$this->t('Type'),
$this->t('Required'),
$this->t('Repeatable'),
$this->t('Create new'),
$this->t('Target bundles')
// TODO: add more columns
],
'#rows' => $rows,
];
}
protected function display_field(string $field_name, FieldDefinitionInterface $field_definition, array $field_profile) {
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->formatWeight($field_definition), // This doesn't work.
'#weight' => $this->format_weight($field_definition),
'title' => [
'#plain_text' => $field_profile['label'],
'#plain_text' => $field_definition->getLabel(),
'#prefix' => '<h2 id="' . $field_name . '">',
'#suffix' => '</h2> ',
],
@ -207,17 +106,30 @@ class MetadataProfileController extends ControllerBase {
'#prefix' => '(',
'#suffix' => ') ',
],
'edit_link' => $field_profile['edit_url'] ? $this->formatFieldEditLink($field_profile['edit_url']) : [],
'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_profile),
'#rows' => $this->getFieldTableRows($field_definition),
'#attributes' => ['class' => ['field-info-table']],
],
'description' => [
'#type' => 'markup',
'#markup' => $field_definition->getDescription() ?: $this->t('[No description]'),
'#prefix' => '<b>Description:</b> ',
],
'target_bundles' => [
'#title' => $this->t('Target Bundles'),
'#type' => 'container',
'bundles' => $this->format_target_bundles($field_definition),
],
'search_api' => $this->formatSearchApi($field_definition),
];
@ -227,69 +139,29 @@ class MetadataProfileController extends ControllerBase {
return $render_array;
}
protected function getFieldEditUrl(FieldDefinitionInterface $field_definition) {
$redirect_url = Url::fromRoute('<current>', ['fragment' => $field_definition->getName()]);
if ($field_definition->getFieldStorageDefinition() instanceof BaseFieldDefinition) {
if ($this->moduleHandler()->moduleExists('base_field_override_ui')) {
if (method_exists($field_definition, 'id')) {
$edit_url = Url::fromRoute('entity.base_field_override.node_base_field_override_edit_form', [
'node_type' => $field_definition->getTargetBundle(),
'base_field_override' => $field_definition->id(),
'destination' => $redirect_url->toString()
]);
}
else {
return NULL;
}
}
else {
return NULL;
}
}
else {
$edit_url = Url::fromRoute('entity.field_config.node_field_edit_form', [
'node_type' => $field_definition->getTargetBundle(),
'field_config' => $field_definition->id(),
'destination' => $redirect_url->toString(),
]);
}
return $edit_url;
}
protected function formatFieldEditLink(Url $edit_url) {
return [
'#type' => 'link',
'#url' => $edit_url,
'#title' => $this->t('Edit'),
'#attributes' => ['class' => ['edit-link']],
];
}
protected function getFieldTableRows(array $field_profile) {
protected function getFieldTableRows(FieldDefinitionInterface $field_definition) {
$rows = [
[$this->t('Type:'), $field_profile['type']],
[$this->t('Required:'), $field_profile['required']],
[$this->t('Repeatable:'), $field_profile['repeatable']],
[$this->t('Type:'), $this->format_type($field_definition)],
[$this->t('Required:'), $this->format_required($field_definition)],
[$this->t('Repeatable:'), $this->format_cardinality($field_definition)],
];
if ($field_profile['auto_create']) {
$rows[] = [$this->t('Create new:'), $field_profile['auto_create']];
// 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)];
}
if ($field_profile['target_bundles']) {
$rows[] = [$this->t('Target bundles:'), $this->formatListForTable($field_profile['target_bundles'])];
}
return $rows;
}
protected function formatType(FieldDefinitionInterface $field_definition) {
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');
$type_label = $type_label . ' (' . $field_definition->getSetting('target_type') . ')';
}
return $type_label;
}
protected function formatRequired(FieldDefinitionInterface $field_definition) {
protected function format_required(FieldDefinitionInterface $field_definition) {
if ($field_definition->isRequired()) {
return $this->t('Required');
}
@ -301,11 +173,11 @@ class MetadataProfileController extends ControllerBase {
/**
* This does not work - most fields dont have a form weight specified in getDisplayOptions.
*/
protected function formatWeight(FieldDefinitionInterface $field_definition) {
protected function format_weight(FieldDefinitionInterface $field_definition) {
return $field_definition->getDisplayOptions('form')['weight'];
}
protected function formatCardinality(FieldDefinitionInterface $field_definition) {
protected function format_cardinality(FieldDefinitionInterface $field_definition) {
$cardinality = $field_definition->getFieldStorageDefinition()->getCardinality();
if ($cardinality == 1) {
return $this->t('Not repeatable');
@ -317,24 +189,18 @@ class MetadataProfileController extends ControllerBase {
return NULL;
}
protected function formatCreateNew(FieldDefinitionInterface $field_definition) {
if (in_array($field_definition->getType(), ['entity_reference', 'typed_relation'])) {
$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_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 NULL;
return $this->t('Do not create new');
}
}
protected function formatTargetBundles(FieldDefinitionInterface $field_definition) {
protected function format_target_bundles(FieldDefinitionInterface $field_definition) {
$handler = $field_definition->getSetting('handler');
$setting = $field_definition->getSetting('handler_settings');
if (!$setting) {
@ -345,16 +211,11 @@ class MetadataProfileController extends ControllerBase {
if ($handler == 'default:taxonomy_term') {
$bundle_config = $this->entityTypeManager()->getStorage('taxonomy_vocabulary')->load($bundle);
}
if ($handler == 'default:node') {
$bundle_config = $this->entityTypeManager()->getStorage('node_type')->load($bundle);
}
// TODO: ADD MEDIA, PARAGRAPHS ETC
// TODO: ADD NODE ETC
if ($bundle_config) {
$target_bundles[$index] = $bundle_config->get('name') . ' (' . $bundle . ')';
}
}
return $target_bundles;
return [
'#theme' => 'item_list',
'#title' => $this->t('Target bundles:'),
@ -363,13 +224,6 @@ class MetadataProfileController extends ControllerBase {
];
}
protected function formatListForTable(array $list) {
return ['data' => [
'#theme' => 'item_list',
'#items' => array_values($list),
'#type' => 'ul',
]];
}
protected function formatSearchApi($field_definition) {
if ($this->moduleHandler()->moduleExists('search_api')) {
$build = [
@ -382,6 +236,7 @@ class MetadataProfileController extends ControllerBase {
'col0' => $this->t('Search API index'),
],
'#rows' => [],
'#caption' => $this->t('Search API')
];
$storage = $field_definition->getFieldStorageDefinition();
if ($storage instanceof BaseFieldDefinition) {
@ -392,40 +247,27 @@ class MetadataProfileController extends ControllerBase {
$field_id = 'field.storage.' . $storage->get('id');
}
$search_api_indexes = $this->configFactory->listAll('search_api.index');
foreach ($search_api_indexes as $index) {
$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_search_api_field($field_setting_name, $field_setting, $index_config);
$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_search_api_field($field_setting_name, $field_setting, $index_config);
$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_search_api_field($field_setting_name, $field_setting, $index_config);
}
}
// Get EDTF year.
if ($field_setting['property_path'] == 'edtf_year') {
$edtf_year_fields = $index_config->get('processor_settings')['edtf_year_only']['fields'] ?: [];
if (in_array(str_replace('.', '|', $field_definition->id()), $edtf_year_fields)) {
$build['#rows'][$field_setting_name] = $this->format_search_api_field($field_setting_name, $field_setting, $index_config);
}
}
// Get EDTF Date
if ($field_setting['property_path'] == 'edtf_dates') {
$edtf_date_fields = $index_config->get('processor_settings')['edtf_date_processor']['fields'] ?: [];
if (in_array(str_replace('.','|',$field_definition->id()), $edtf_date_fields)) {
$build['#rows'][$field_setting_name] = $this->format_search_api_field($field_setting_name, $field_setting, $index_config);
$build['#rows'][$field_setting_name] = $this->format_solr_field($field_setting_name, $field_setting, $index_config);
}
}
// Get EDTFyear.
}
if (count($build['#rows']) == 0) {
@ -439,7 +281,7 @@ class MetadataProfileController extends ControllerBase {
}
}
protected function format_search_api_field($field_setting_name, $field_setting, $index_config) {
protected function format_solr_field($field_setting_name, $field_setting, $index_config) {
$build = [
'data' => [
$field_setting['label'],
@ -450,64 +292,9 @@ class MetadataProfileController extends ControllerBase {
]
];
if ($field_setting['property_path'] == 'aggregated_field') {
$list_render_array = [
'#theme' => 'item_list',
'#items' => $field_setting['configuration']['fields']
];
$cell_element = [ 'data' => [
'#type' => 'container',
'label' => ['#markup' => $build['data'][2]],
'list' => $list_render_array,
]];
$build['data'][2] = $cell_element;
}
if (in_array($field_setting['property_path'], ['edtf_year', 'edtf_dates'])) {
$list_render_array = [
'#theme' => 'item_list',
'#items' => $index_config->get('processor_settings')['edtf_year_only']['fields'] ?: $this->t('No fields avaailable')
];
$cell_element = [ 'data' => [
'#type' => 'container',
'label' => ['#markup' => $build['data'][2]],
'list' => $list_render_array,
]];
$build['data'][2] = $cell_element;
$build['data'][2] .= ' -' . implode(', -', $field_setting['configuration']['fields']);
}
return $build;
}
public function test() {
$list = [
'one',
'two',
'three'
];
$list_render_array = [
'#theme' => 'item_list',
'#items' => $list,
];
$test = [
'data' => $list_render_array
];
$rows = [
['bar', 'xyz'],
['baz', $test ],
];
$build = [
'#type' => 'table',
'#rows' => $rows,
];
return $build;
}
private function getDetailsFragmentLink(string $field_name, FieldDefinitionInterface $field_definition)
{
$url = Url::fromRoute('<current>', [], ['fragment' => $field_name]);
return Link::fromTextAndUrl($field_definition->getLabel(), $url);
}
}

Loading…
Cancel
Save