diff --git a/css/metadata_profile.css b/css/metadata_profile.css new file mode 100644 index 0000000..5c453a8 --- /dev/null +++ b/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; +} diff --git a/metadata_profile.libraries.yml b/metadata_profile.libraries.yml new file mode 100644 index 0000000..ffb39c4 --- /dev/null +++ b/metadata_profile.libraries.yml @@ -0,0 +1,4 @@ +metadata_profile: + css: + theme: + css/metadata_profile.css: {} diff --git a/metadata_profile.routing.yml b/metadata_profile.routing.yml new file mode 100644 index 0000000..a069f2f --- /dev/null +++ b/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 + diff --git a/src/Controller/MetadataProfileController.php b/src/Controller/MetadataProfileController.php new file mode 100644 index 0000000..cb07b74 --- /dev/null +++ b/src/Controller/MetadataProfileController.php @@ -0,0 +1,214 @@ +entityFieldManager = $entity_field_manager; + $this->fieldTypePluginManager = $field_type_plugin_manager; + } + + public static function create(ContainerInterface $container) { + return new static( + $container->get('entity_field.manager'), + $container->get('plugin.manager.field.field_type') + ); + } + + + 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' => '

', + '#suffix' => '

', + ], + 'machine_name' => [ + '#plain_text' => $bundle->get('type'), + '#prefix' => ' (', + '#suffix' => ')', + ], + 'description' => [ + '#plain_text' => $bundle->get('description'), + '#prefix' => '

', + '#suffix' => '

', + ], + ]; + 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' => '

', + '#suffix' => '

', + ], + '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' => ['',''], + '#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), + ], + ]; + } + + 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'); + } + } + + 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' + ]; + } + +}