ispim-1.0.x-dev/src/PreviewImage/RouteProvider.php
src/PreviewImage/RouteProvider.php
<?php
declare(strict_types=1);
namespace Drupal\ispim\PreviewImage;
use Drupal\Core\Entity\EntityHandlerInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\RevisionableInterface;
use Drupal\Core\Entity\Routing\EntityRouteProviderInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\String\UnicodeString;
class RouteProvider implements EntityRouteProviderInterface, EntityHandlerInterface {
protected string $basePathPattern = '/admin/config/media/[entityTypeIdHyphen]/manage/{[entityTypeId]}';
protected string $classNamePattern = '\Drupal\[provider]\[idShortUpperCamel]';
protected RouteCollection $routes;
/**
* {@inheritdoc}
*/
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
// @phpstan-ignore-next-line
return new static(
$entity_type,
);
}
public function __construct(
protected EntityTypeInterface $entityType,
) {
}
/**
* {@inheritdoc}
*/
public function getRoutes(EntityTypeInterface $entity_type) {
$this->entityType = $entity_type;
$this->routes = new RouteCollection();
$this
->addCollectionRoute()
->addAddRoutes()
->addCanonicalRoute()
->addEditRoute()
->addRevisionRoute()
->addDeleteRoute();
return $this->routes;
}
protected function addCollectionRoute(): static {
$entityTypeId = $this->entityType->id();
$this->routes->add("entity.$entityTypeId.collection", $this->getCollectionRoute());
return $this;
}
public function getCollectionRoute(): Route {
$entityTypeId = $this->entityType->id();
$entityTypeIdHyphen = str_replace('_', '-', $entityTypeId);
$path = $this->entityType->getLinkTemplate('collection')
?: "/admin/content/{$entityTypeIdHyphen}/add";
return (new Route((string) $path))
->setDefault('_entity_list', $entityTypeId)
->setDefault('_title', (string) $this->entityType->getCollectionLabel())
->setRequirement('_permission', (string) $this->entityType->getAdminPermission());
}
protected function addAddRoutes(): static {
$entityTypeId = $this->entityType->id();
$this->routes->add("entity.$entityTypeId.add_page", $this->getAddPageRoute());
$this->routes->add("entity.$entityTypeId.add_form", $this->getAddFormRoute());
return $this;
}
protected function getAddPageRoute(): Route {
$entityTypeId = $this->entityType->id();
$entityTypeIdHyphen = str_replace('_', '-', $entityTypeId);
$class = $this->getClassName('Controller');
$path = $this->entityType->getLinkTemplate('create')
?: "/admin/content/{$entityTypeIdHyphen}/add";
return (new Route((string) $path))
->addDefaults([
'_title' => 'Create a new ' . $this->entityType->getLabel(),
'_controller' => "$class::addPageContent",
])
->setRequirement($this->entityType->id(), '\d+')
->setRequirement('_entity_create_access', $entityTypeId);
}
protected function getAddFormRoute(): Route {
$entityTypeId = $this->entityType->id();
$bundleEntityTypeId = $this->entityType->getBundleEntityType();
$route = $this->getAddPageRoute();
if ($bundleEntityTypeId) {
// @todo Check permission_granularity.
return $route
->setPath($route->getPath() . "/{{$bundleEntityTypeId}}")
->setDefault(
'_controller',
str_replace(
'::addPageContent',
'::addFormBundleable',
$route->getDefault('_controller'),
),
)
->setRequirement('_entity_create_access', "$entityTypeId:{{$bundleEntityTypeId}}");
}
return $route
->setPath($route->getPath() . "/{$entityTypeId}")
->setDefault(
'_controller',
str_replace(
'::addPageContent',
'::addFormFlat',
$route->getDefault('_controller'),
),
);
}
protected function addCanonicalRoute(): static {
$entityTypeId = $this->entityType->id();
$this->routes->add("entity.$entityTypeId.canonical", $this->getCanonicalRoute());
return $this;
}
protected function getCanonicalRoute(): Route {
$basePath = $this->getBasePath();
$entityTypeId = $this->entityType->id();
$class = $this->getClassName('ViewController');
return (new Route($basePath))
->addDefaults([
'_entity_view' => "$entityTypeId.full",
'_title_callback' => "$class::title",
])
->setRequirement($this->entityType->id(), '\d+')
->setRequirement('_entity_access', "$entityTypeId.view");
}
protected function addEditRoute(): static {
$entityTypeId = $this->entityType->id();
$this->routes->add("entity.$entityTypeId.edit_form", $this->getEditRoute());
return $this;
}
protected function getEditRoute(): Route {
$basePath = $this->getBasePath();
$entityTypeId = $this->entityType->id();
return (new Route("$basePath/edit"))
->setDefault('_entity_form', "$entityTypeId.edit")
->setRequirement($entityTypeId, '\d+')
->setRequirement('_entity_access', "$entityTypeId.update")
->setOption("_{$entityTypeId}_operation_route", TRUE);
}
protected function addRevisionRoute(): static {
if (!$this->entityType->entityClassImplements(RevisionableInterface::class)) {
return $this;
}
$entityTypeId = $this->entityType->id();
$this->routes->add("entity.$entityTypeId.revision_history", $this->getRevisionHistoryRoute());
$this->routes->add("entity.$entityTypeId.revision_view", $this->getRevisionViewRoute());
$this->routes->add("entity.$entityTypeId.revision_revert", $this->getRevisionRevertRoute());
$this->routes->add("entity.$entityTypeId.revision_revert_translation", $this->getRevisionRevertTranslationRoute());
$this->routes->add("entity.$entityTypeId.revision_delete", $this->getRevisionDeleteRoute());
return $this;
}
protected function getRevisionHistoryRoute(): Route {
$basePath = $this->getBasePath();
$entityTypeId = $this->entityType->id();
return (new Route("$basePath/revision"))
->setDefault('_title_callback', $this->getClassName('Controller') . '::revisionHistoryTitle')
->setDefault('_controller', $this->getClassName('Controller') . '::revisionHistoryContent')
->setRequirement($entityTypeId, '\d+')
->setRequirement('_entity_access', "$entityTypeId.revision_view")
->setOption("_{$entityTypeId}_operation_route", 'TRUE');
}
protected function getRevisionViewRoute(): Route {
$basePath = $this->getBasePath();
$entityTypeId = $this->entityType->id();
return (new Route("$basePath/revision/{{$entityTypeId}_revision}"))
->setDefault('_title_callback', $this->getClassName('Controller') . '::revisionViewTitle')
->setDefault('_controller', $this->getClassName('Controller') . '::revisionViewContent')
->setRequirement($entityTypeId, '\d+')
->setRequirement("{$entityTypeId}_revision", '\d+')
->setRequirement('_entity_access', "$entityTypeId.revision_view")
->setOptions([
"_{$entityTypeId}_operation_route" => TRUE,
'parameters' => [
$entityTypeId => [
'type' => "entity.$entityTypeId",
],
"{$entityTypeId}_revision" => [
'type' => "entity_revision.$entityTypeId",
],
],
]);
}
protected function getRevisionRevertRoute(): Route {
$basePath = $this->getBasePath();
$entityTypeId = $this->entityType->id();
return (new Route("$basePath/revision/{{$entityTypeId}_revision}/revert"))
->setDefault('_title', 'Revision revert')
->setDefault('_form', $this->getClassName('RevisionRevertForm'))
->setRequirement($entityTypeId, '\d+')
->setRequirement("{$entityTypeId}_revision", '\d+')
->setRequirement('_entity_access', "$entityTypeId.revision_revert")
->setOption("_{$entityTypeId}_operation_route", TRUE);
}
protected function getRevisionRevertTranslationRoute(): Route {
$basePath = $this->getBasePath();
$entityTypeId = $this->entityType->id();
return (new Route("$basePath/revision/{{$entityTypeId}_revision}/revert/{langcode}"))
->addDefaults([
'_title' => 'Revert to earlier revision of a translation',
'_form' => $this->getClassName('RevisionRevertTranslationForm'),
])
->setRequirement($entityTypeId, '\d+')
->setRequirement("{$entityTypeId}_revision", '\d+')
->setRequirement('_entity_access', "$entityTypeId.revision_revert")
->setOption("_{$entityTypeId}_operation_route", TRUE);
}
protected function getRevisionDeleteRoute(): Route {
$basePath = $this->getBasePath();
$entityTypeId = $this->entityType->id();
return (new Route("$basePath/revision/{{$entityTypeId}_revision}/delete"))
->setDefault('_title', 'Revision delete')
->setDefault('_form', $this->getClassName('RevisionDeleteForm'))
->setRequirement($entityTypeId, '\d+')
->setRequirement("{$entityTypeId}_revision", '\d+')
->setRequirement('_entity_access', "$entityTypeId.revision_delete")
->setRequirement('_access', 'TRUE')
->setOption("_{$entityTypeId}_operation_route", TRUE);
}
protected function addDeleteRoute(): static {
$entityTypeId = $this->entityType->id();
$this->routes->add("entity.$entityTypeId.delete_form", $this->getDeleteRoute());
return $this;
}
protected function getDeleteRoute(): Route {
$basePath = $this->getBasePath();
$entityTypeId = $this->entityType->id();
return (new Route("$basePath/delete"))
->addDefaults([
'_entity_form' => "$entityTypeId.delete",
'_title' => 'Delete',
])
->setRequirement($entityTypeId, '\d+')
->setRequirement('_entity_access', "$entityTypeId.delete")
->setOption("_{$entityTypeId}_operation_route", TRUE);
}
protected function getBasePath(): string {
$entityTypeId = $this->entityType->id();
$entityTypeIdHyphen = str_replace('_', '-', $entityTypeId);
$pairs = [
'[entityTypeId]' => $entityTypeId,
'[entityTypeIdHyphen]' => $entityTypeIdHyphen,
];
return strtr($this->basePathPattern, $pairs);
}
protected function getClassName(string $type): string {
$classParts = explode('\\', $this->entityType->getOriginalClass());
$pairs = [
'[provider]' => $this->entityType->getProvider(),
'[originalClass]' => end($classParts),
'[idShortUpperCamel]' => end($classParts),
];
if (str_starts_with($this->entityType->id(), $this->entityType->getProvider() . '_')) {
$pairs['[idShortUpperCamel]'] = (new UnicodeString($this->entityType->id()))
->trimPrefix($this->entityType->getProvider() . '_')
->prepend('a_')
->camel()
->trim('a')
->toString();
}
$pairs['[providerUpperCamel]'] = (new UnicodeString($pairs['[provider]']))
->prepend('a_')
->camel()
->trim('a')
->toString();
return strtr("{$this->classNamePattern}\\$type", $pairs);
}
}
