Compare commits

..

2 Commits

  1. 3
      metadata_profile.links.task.yml
  2. 15
      metadata_profile.module
  3. 21
      metadata_profile.routing.yml
  4. 11
      metadata_profile.services.yml
  5. 123
      src/Controller/MetadataProfileController.php
  6. 75
      src/Plugin/Derivative/MetadataProfileDisplayTask.php
  7. 61
      src/Routing/RouteEnhancer.php
  8. 86
      src/Routing/RouteSubscriber.php

3
metadata_profile.links.task.yml

@ -0,0 +1,3 @@
metadata_profile.display:
class: \Drupal\Core\Menu\LocalTaskDefault
deriver: \Drupal\metadata_profile\Plugin\Derivative\MetadataProfileDisplayTask

15
metadata_profile.module

@ -0,0 +1,15 @@
<?php
/**
* Implements hook_entity_type_alter().
*
* Adds the Metadata Profile tab to the entity configuration page.
*/
function metadata_profile_entity_type_alter(array &$entity_types) {
/** @var \Drupal\Core\Entity\EntityTypeInterface $entity_type */
foreach ($entity_types as $entity_type) {
if ($entity_type->getBundleOf() && $entity_type->hasLinkTemplate('edit-form')) {
$entity_type->setLinkTemplate('metadata-profile', $entity_type->getLinkTemplate('edit-form') . "/metadata-profile");
}
}
}

21
metadata_profile.routing.yml

@ -1,21 +0,0 @@
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
metadata_profile.test:
path: '/test'
defaults:
_controller: '\Drupal\metadata_profile\Controller\MetadataProfileController::test'
_title: 'Metadata Profile Test'
requirements:
_access: 'TRUE'

11
metadata_profile.services.yml

@ -0,0 +1,11 @@
services:
metadata_profile.route_subscriber:
class: Drupal\metadata_profile\Routing\RouteSubscriber
arguments: ['@entity_type.manager']
tags:
- { name: event_subscriber }
metadata_profile.route_enhancer:
class: Drupal\metadata_profile\Routing\RouteEnhancer
arguments: ['@entity_type.manager']
tags:
- { name: route_enhancer }

123
src/Controller/MetadataProfileController.php

@ -11,6 +11,7 @@ use Drupal\Core\Field\FieldTypePluginManagerInterface;
use Drupal\Core\Link;
use Drupal\Core\Messenger\MessengerTrait;
use Drupal\Core\Config\Config;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\field_permissions\Plugin\FieldPermissionType\Base;
use Symfony\Component\DependencyInjection\ContainerInterface;
@ -24,20 +25,57 @@ class MetadataProfileController extends ControllerBase {
protected FieldTypePluginManagerInterface $fieldTypePluginManager;
protected $configFactory;
/**
* The route matcher.
*
* @var \Drupal\Core\Routing\RouteMatchInterface
*/
protected $routeMatch;
/**
* The entity type machine name.
*
* @var string
*/
protected $entityType;
/**
* The bundle machine name.
*
* @var string
*/
protected $entityBundle;
/**
* The entity type that our config entity describes bundles of.
*
* @var string
*/
protected $entityTypeBundleOf;
public function __construct(EntityFieldManagerInterface $entity_field_manager,
FieldTypePluginManagerInterface $field_type_plugin_manager,
ConfigFactoryInterface $config_factory) {
ConfigFactoryInterface $config_factory,
RouteMatchInterface $route_match) {
$this->entityFieldManager = $entity_field_manager;
$this->fieldTypePluginManager = $field_type_plugin_manager;
$this->configFactory = $config_factory;
$this->routeMatch = $route_match;
$route_options = $this->routeMatch->getRouteObject()->getOptions();
$array_keys = array_keys($route_options['parameters']);
$this->entityType = array_shift($array_keys);
$entity_type = $this->routeMatch->getParameter($this->entityType);
$this->entityBundle = $entity_type->id();
$this->entityTypeBundleOf = $entity_type->getEntityType()->getBundleOf();
}
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')
$container->get('config.factory'),
$container->get('current_route_match')
);
}
@ -47,14 +85,16 @@ class MetadataProfileController extends ControllerBase {
* @param $content_type
* @return array
*/
public function profile($content_type) {
public function profile($content_type = NULL) {
if (!$content_type) {
$content_type = $this->entityBundle;
}
// Get core content type information.
$node_type = $this->config('node.type.' . $content_type);
if (!$node_type) {
$bundle_config = $this->config(str_replace('_', '.', $this->entityType) . '.' . $content_type);
if (!$bundle_config) {
return ['#markup'=> 'Not a valid content type.'];
}
$build = $this->format_bundle($node_type);
$build = $this->format_bundle($bundle_config);
$metadata_profile = $this->getMetadataProfile($content_type);
@ -69,7 +109,7 @@ class MetadataProfileController extends ControllerBase {
'#weight' => '9',
];
// Get field information.
$field_definitions = $this->entityFieldManager->getFieldDefinitions('node', $content_type);
$field_definitions = $this->entityFieldManager->getFieldDefinitions($this->entityTypeBundleOf, $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]);
}
@ -81,22 +121,38 @@ class MetadataProfileController extends ControllerBase {
* Format information about a bundle.
*/
protected function format_bundle(Config $bundle) {
if (str_starts_with($bundle->getName(), 'node.type')) {
$label = $bundle->get('name');
$machine_name = $bundle->get('type');
$description = $bundle->get('description');
}
elseif (str_starts_with($bundle->getName(), 'taxonomy.vocabulary')) {
$label = $bundle->get('name');
$machine_name = $bundle->get('vid');
$description = $bundle->get('description');
}
elseif (str_starts_with($bundle->getName(), 'media.type')) {
$label = $bundle->get('label');
$machine_name = $bundle->get('id');
$description = $bundle->get('description');
}
$build = [
'#type' => 'container',
'#attached' => ['library' => ['metadata_profile/metadata_profile']],
'title' => [
'#plain_text' => $bundle->get('name'),
'#plain_text' => $label,
'#prefix' => '<h1>',
'#suffix' => '</h1>',
],
'machine_name' => [
'#plain_text' => $bundle->get('type'),
'#plain_text' => $machine_name,
'#prefix' => ' (',
'#suffix' => ')',
],
'description' => [
'#plain_text' => $bundle->get('description'),
'#plain_text' => $description,
'#prefix' => '<p>',
'#suffix' => '</p>',
],
@ -137,7 +193,7 @@ class MetadataProfileController extends ControllerBase {
// * 'block_visible'
$metadata_profile = [];
$field_definitions = $this->entityFieldManager->getFieldDefinitions('node', $bundle);
$field_definitions = $this->entityFieldManager->getFieldDefinitions($this->entityTypeBundleOf, $bundle);
foreach ($field_definitions as $field_name => $field_definition) {
$metadata_profile[$field_name] = [
'label' => $field_definition->getLabel(),
@ -160,7 +216,7 @@ class MetadataProfileController extends ControllerBase {
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') {
if (str_starts_with( $field_name, 'field_') or in_array($field_name, ['title', 'name'])) {
$rows[] = [
$field_profile['details_link'],
$field_profile['machine_name'],
@ -192,7 +248,7 @@ class MetadataProfileController extends ControllerBase {
protected function display_field(string $field_name, FieldDefinitionInterface $field_definition, array $field_profile) {
$render_array = [];
if (str_starts_with($field_name, 'field_') or $field_name == 'title') {
if (str_starts_with($field_name, 'field_') or in_array($field_name, ['title', 'name'])) {
$render_array = [
'#type' => 'container',
'#attributes' => ['class' => ['field-info']],
@ -232,8 +288,8 @@ class MetadataProfileController extends ControllerBase {
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(),
$edit_url = Url::fromRoute('entity.base_field_override.' . $this->entityTypeBundleOf . '_base_field_override_edit_form', [
$this->entityType => $field_definition->getTargetBundle(),
'base_field_override' => $field_definition->id(),
'destination' => $redirect_url->toString()
]);
@ -248,8 +304,8 @@ class MetadataProfileController extends ControllerBase {
}
}
else {
$edit_url = Url::fromRoute('entity.field_config.node_field_edit_form', [
'node_type' => $field_definition->getTargetBundle(),
$edit_url = Url::fromRoute('entity.field_config.' . $this->entityTypeBundleOf . '_field_edit_form', [
$this->entityType => $field_definition->getTargetBundle(),
'field_config' => $field_definition->id(),
'destination' => $redirect_url->toString(),
]);
@ -386,7 +442,7 @@ class MetadataProfileController extends ControllerBase {
$storage = $field_definition->getFieldStorageDefinition();
if ($storage instanceof BaseFieldDefinition) {
// Use property_path to find related fields.
$field_id = 'node.' . $storage->getName();
$field_id = $this->entityTypeBundleOf . '.' . $storage->getName();
}
else {
$field_id = 'field.storage.' . $storage->get('id');
@ -412,6 +468,7 @@ class MetadataProfileController extends ControllerBase {
$build['#rows'][$field_setting_name] = $this->format_search_api_field($field_setting_name, $field_setting, $index_config);
}
}
if ($field_definition->getType() == 'edtf') {
// Get EDTF year.
if ($field_setting['property_path'] == 'edtf_year') {
$edtf_year_fields = $index_config->get('processor_settings')['edtf_year_only']['fields'] ?: [];
@ -426,6 +483,7 @@ class MetadataProfileController extends ControllerBase {
$build['#rows'][$field_setting_name] = $this->format_search_api_field($field_setting_name, $field_setting, $index_config);
}
}
}
}
if (count($build['#rows']) == 0) {
@ -478,33 +536,6 @@ class MetadataProfileController extends ControllerBase {
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]);

75
src/Plugin/Derivative/MetadataProfileDisplayTask.php

@ -0,0 +1,75 @@
<?php
namespace Drupal\metadata_profile\Plugin\Derivative;
use Drupal\Component\Plugin\Derivative\DeriverBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
class MetadataProfileDisplayTask extends DeriverBase implements ContainerDeriverInterface
{
use StringTranslationTrait;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Creates an FieldUiLocalTask object.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager service.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager) {
$this->entityTypeManager = $entity_type_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, $base_plugin_id) {
return new static(
$container->get('entity_type.manager')
);
}
/**
* {@inheritdoc}
*/
public function getDerivativeDefinitions($base_plugin_definition) {
$this->derivatives = [];
foreach ($this->entityTypeManager->getDefinitions() as $entity_type_id => $entity_type) {
// Special handling of Taxonomy. See https://www.drupal.org/node/2822546
if ($entity_type_id == "taxonomy_vocabulary") {
$base_route = "entity.{$entity_type_id}.overview_form";
}
else {
$base_route = "entity.{$entity_type_id}.edit_form";
}
if ($entity_type->hasLinkTemplate('metadata-profile')) {
$this->derivatives["$entity_type_id.metadata_profile_tab"] = [
'route_name' => "entity.{$entity_type_id}.metadata_profile",
'title' => $this->t('Metadata Profile'),
'base_route' => $base_route,
'weight' => 100,
];
}
}
foreach ($this->derivatives as &$entry) {
$entry += $base_plugin_definition;
}
return $this->derivatives;
}
}

61
src/Routing/RouteEnhancer.php

@ -0,0 +1,61 @@
<?php
namespace Drupal\metadata_profile\Routing;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Routing\EnhancerInterface;
use Drupal\Core\Routing\RouteObjectInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Route;
/**
* RouteEnhancer Class.
*
* Enhances Metadata Profile routes by adding proper information about the
* bundle name.
*/
class RouteEnhancer implements EnhancerInterface {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Constructs a RouteEnhancer object.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager service.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager) {
$this->entityTypeManager = $entity_type_manager;
}
/**
* {@inheritdoc}
*/
public function enhance(array $defaults, Request $request) {
if (!$this->applies($defaults[RouteObjectInterface::ROUTE_OBJECT])) {
return $defaults;
}
if (($bundle = $this->entityTypeManager->getDefinition($defaults['entity_type_id'])->getBundleEntityType()) && isset($defaults[$bundle])) {
// Metadata Profiles only need the actual name of the bundle they're
// dealing with, not an upcasted entity object, so provide a simple way
// for them to get it.
$defaults['bundle'] = $defaults['_raw_variables']->get($bundle);
}
return $defaults;
}
/**
* {@inheritdoc}
*/
public function applies(Route $route) {
return ($route->hasOption('metadata_profile'));
}
}

86
src/Routing/RouteSubscriber.php

@ -0,0 +1,86 @@
<?php
namespace Drupal\metadata_profile\Routing;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Routing\RouteSubscriberBase;
use Drupal\Core\Routing\RoutingEvents;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
/**
* Subscriber for metadata profile routes.
*/
class RouteSubscriber extends RouteSubscriberBase {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Constructs a new RouteSubscriber object.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager) {
$this->entityTypeManager = $entity_type_manager;
}
/**
* {@inheritdoc}
*/
protected function alterRoutes(RouteCollection $collection) {
foreach ($this->entityTypeManager->getDefinitions() as $entity_type_id => $entity_type) {
if ($route = $this->getEntityProfileRoute($entity_type)) {
$collection->add("entity.$entity_type_id.metadata_profile", $route);
}
}
}
/**
* Gets the Metadata Profile route.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
*
* @return \Symfony\Component\Routing\Route|null
* The generated route, if available.
*/
protected function getEntityProfileRoute(EntityTypeInterface $entity_type) {
if ($route_load = $entity_type->getLinkTemplate('metadata-profile')) {
$entity_type_id = $entity_type->id();
$route = new Route($route_load);
$route
->addDefaults([
'_controller' => '\Drupal\metadata_profile\Controller\MetadataProfileController::profile',
'_title' => 'Metadata Profile',
])
->addRequirements([
'_permission' => 'administer content',
])
->setOption('_admin_route', TRUE)
->setOption('parameters', [
$entity_type_id => ['type' => 'entity:' . $entity_type_id],
]);
return $route;
}
return NULL;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents(): array {
$events = parent::getSubscribedEvents();
$events[RoutingEvents::ALTER] = ['onAlterRoutes', -100];
return $events;
}
}
Loading…
Cancel
Save