toolshed-8.x-1.x-dev/src/Plugin/Derivative/OptionalLocalTaskDeriver.php
src/Plugin/Derivative/OptionalLocalTaskDeriver.php
<?php
namespace Drupal\toolshed\Plugin\Derivative;
use Drupal\Component\Plugin\Derivative\DeriverBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Drupal\Core\Routing\RouteProviderInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
/**
* Optionally create menu local task based on if there are overriding routes.
*
* Often times we want to provider default menu tabs for entity list pages, but
* will want to replace them with more advanced views functionality. Normally
* this would create double the tabs.
*
* Using this deriver checks if the route proposed for the tab is overridden
* and therefore doesn't need to be added.
*
* @todo Inspect views route to check for local task configuration to determine
* if a local task should be added or ignored.
*/
class OptionalLocalTaskDeriver extends DeriverBase implements ContainerDeriverInterface {
/**
* The ID of the plugin the deriver is implementing.
*
* @var string
*/
protected string $basePluginId;
/**
* The route provider.
*
* @var \Drupal\Core\Routing\RouteProviderInterface
*/
protected RouteProviderInterface $routeProvider;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected EntityTypeManagerInterface $entityTypeManager;
/**
* Create a new link object deriver.
*
* @param string $base_plugin_id
* The plugin ID of the deriver definition.
* @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
* The route provider.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
*/
public function __construct($base_plugin_id, RouteProviderInterface $route_provider, EntityTypeManagerInterface $entity_type_manager) {
$this->basePluginId = $base_plugin_id;
$this->routeProvider = $route_provider;
$this->entityTypeManager = $entity_type_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, $base_plugin_id): static {
return new static(
$base_plugin_id,
$container->get('router.route_provider'),
$container->get('entity_type.manager')
);
}
/**
* {@inheritdoc}
*/
public function getDerivativeDefinitions($base_plugin_definition): array {
$base = array_diff_key($base_plugin_definition, [
'deriver' => TRUE,
'entity_type' => TRUE,
'routes' => TRUE,
]);
if (empty($base['title'])) {
$entityType = $this->entityTypeManager->getDefinition($base_plugin_definition['entity_type']);
$base['title'] = $entityType->getPluralLabel();
}
foreach ($base_plugin_definition['routes'] as $routeName) {
try {
$route = $this->routeProvider->getRouteByName($routeName);
$matches = $this->routeProvider->getRoutesByPattern($route->getPath());
// If another path is overriding our tab (most likely a view), assume
// that they are taking care of the local task as well.
if ($matches->count() <= 1) {
$this->derivatives[$routeName] = [
'id' => $routeName,
'route_name' => $routeName,
] + $base;
}
}
catch (RouteNotFoundException $e) {
// Route doesn't exist, skip creating this tab.
}
}
return parent::getDerivativeDefinitions($base_plugin_definition);
}
}
