Browse Source

Use local tasks and route subscribers and derivers to make work on all entities.

main
Rosie Le Faive 3 weeks ago
parent
commit
797451b568
  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. 98
      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 }

98
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,56 @@ 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,8 +84,10 @@ 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) {
@ -412,18 +451,20 @@ class MetadataProfileController extends ControllerBase {
$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);
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'] ?: [];
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);
// 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);
}
}
}
@ -478,33 +519,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