View source
<?php
namespace Drupal\form_mode_manager\Routing\EventSubscriber;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Routing\RouteSubscriberBase;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\form_mode_manager\FormModeManagerInterface;
use Drupal\form_mode_manager\EntityRoutingMapManager;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
class FormModesSubscriber extends RouteSubscriberBase {
use StringTranslationTrait;
const ROUTE_PATH_CONTEXT_REGEX = '/^.*?\\/edit[^$]*/';
const FORM_MODE_DEFAULT_CONTROLLER = '\\Drupal\\form_mode_manager\\Controller\\EntityFormModeController';
protected $entityTypeManager;
protected $entityDisplayRepository;
protected $formModeManager;
protected $entityRoutingMap;
public function __construct(EntityTypeManagerInterface $entity_manager, EntityDisplayRepositoryInterface $entity_display_repository, FormModeManagerInterface $form_mode_manager, EntityRoutingMapManager $plugin_routes_manager) {
$this->entityTypeManager = $entity_manager;
$this->entityDisplayRepository = $entity_display_repository;
$this->formModeManager = $form_mode_manager;
$this->entityRoutingMap = $plugin_routes_manager;
}
protected function alterRoutes(RouteCollection $collection) {
$form_modes_definitions = $this->formModeManager
->getAllFormModesDefinitions();
unset($form_modes_definitions['user']);
foreach ($form_modes_definitions as $entity_type_id => $form_modes) {
$entity_type = $this->entityTypeManager
->getDefinition($entity_type_id);
$this
->addFormModesRoutes($collection, $entity_type, $form_modes);
}
}
protected function addFormModesRoutes(RouteCollection $collection, EntityTypeInterface $entity_type, array $form_modes) {
foreach ($form_modes as $form_mode) {
$this
->setFormModeCollection($collection, $entity_type, $form_mode, 'admin_add');
$this
->setFormModeCollection($collection, $entity_type, $form_mode, 'add_form');
$this
->setFormModeCollection($collection, $entity_type, $form_mode, 'edit_form');
$this
->setAddPageCollection($collection, $entity_type, $form_mode);
}
}
public function setFormModeCollection(RouteCollection $collection, EntityTypeInterface $entity_type, array $form_mode, $operation) {
$entity_operation_mapping = $this->entityRoutingMap
->createInstance($entity_type
->id(), [
'entityTypeId' => $entity_type
->id(),
]);
if ($entity_operation_mapping
->getOperation($operation) && ($route = $this
->getFormModeRoute($collection, $entity_type, $form_mode, $operation))) {
$form_mode_name = $this->formModeManager
->getFormModeMachineName($form_mode['id']);
$collection
->add($entity_operation_mapping
->getOperation($operation) . ".{$form_mode_name}", $route);
}
}
public function setAddPageCollection(RouteCollection $collection, EntityTypeInterface $entity_type, array $form_mode) {
$form_mode_name = $this->formModeManager
->getFormModeMachineName($form_mode['id']);
if ($route = $this
->getFormModeListPageRoute($entity_type, $form_mode)) {
$collection
->add("form_mode_manager.{$entity_type->id()}.add_page.{$form_mode_name}", $route);
}
}
public function getFormModeListPageRoute(EntityTypeInterface $entity_type, array $form_mode) {
$route = NULL;
$entity_type_id = $entity_type
->id();
$entity_type_bundle_id = $entity_type
->getBundleEntityType();
$bundle_entity_type_id = !empty($entity_type_bundle_id) ? $entity_type_bundle_id : $entity_type_id;
$has_active_mode = $this->formModeManager
->hasActiveFormMode($entity_type_id, $this->formModeManager
->getFormModeMachineName($form_mode['id']));
if ($has_active_mode) {
$route = new Route("/{$entity_type_id}/add-list/{$this->formModeManager->getFormModeMachineName($form_mode['id'])}");
$route
->addDefaults([
'_controller' => static::FORM_MODE_DEFAULT_CONTROLLER . '::addPage',
'_title' => $this
->t('Add @entity_type', [
'@entity_type' => $entity_type
->getLabel(),
])
->render(),
'form_mode_name' => $this->formModeManager
->getFormModeMachineName($form_mode['id']),
])
->addRequirements([
'_permission' => "use {$form_mode['id']} form mode",
])
->setOptions([
'_form_mode_manager_entity_type_id' => $entity_type_id,
'_form_mode_manager_bundle_entity_type_id' => $bundle_entity_type_id,
'_admin_route' => TRUE,
]);
$this
->userListEnhancements($route, $entity_type
->id());
}
return $route;
}
public function getFormModeRoute(RouteCollection $collection, EntityTypeInterface $entity_type, array $form_mode, $operation) {
$entity_type_id = $entity_type
->id();
$has_active_mode = $this->formModeManager
->hasActiveFormMode($entity_type_id, $this->formModeManager
->getFormModeMachineName($form_mode['id']));
$entity_operation_mapping = $this->entityRoutingMap
->createInstance($entity_type_id, [
'entityTypeId' => $entity_type_id,
]);
if ($has_active_mode && ($entity_edit_route = $collection
->get($entity_operation_mapping
->getOperation($operation)))) {
return $this
->setRoutes($entity_edit_route, $entity_type, $form_mode);
}
return NULL;
}
public function userListEnhancements(Route $route, $entity_type_id) {
if ('user' !== $entity_type_id) {
return;
}
$route
->setDefault('_controller', '\\Drupal\\form_mode_manager\\Controller\\UserFormModeController::entityAdd')
->setDefault('_title_callback', '\\Drupal\\form_mode_manager\\Controller\\UserFormModeController::addPageTitle');
}
private function setRoutes(Route $parent_route, EntityTypeInterface $entity_type, array $form_mode) {
$route_defaults = NestedArray::mergeDeep($parent_route
->getDefaults(), $this
->getFormModeRouteDefaults($parent_route, $form_mode));
$roue_options = NestedArray::mergeDeep($parent_route
->getOptions(), $this
->getFormModeRouteOptions($form_mode, $entity_type));
$route_requirements = NestedArray::mergeDeep($parent_route
->getRequirements(), $this
->getFormModeRouteRequirements($form_mode));
$route = new Route("{$parent_route->getPath()}/{$this->formModeManager->getFormModeMachineName($form_mode['id'])}");
$route
->addDefaults($route_defaults)
->setOptions($roue_options)
->addRequirements($route_requirements);
return $route;
}
public static function isEditRoute(Route $route) {
return (bool) preg_match_all(self::ROUTE_PATH_CONTEXT_REGEX, $route
->getPath(), $matches, PREG_SET_ORDER, 0);
}
protected function getFormModeRouteDefaults(Route $route, array $form_mode) {
$route_parameters = [
'_entity_form' => $form_mode['id'],
'_controller' => static::FORM_MODE_DEFAULT_CONTROLLER . '::entityAdd',
'_title_callback' => static::FORM_MODE_DEFAULT_CONTROLLER . '::addPageTitle',
];
if (static::isEditRoute($route)) {
$route_parameters['_title_callback'] = static::FORM_MODE_DEFAULT_CONTROLLER . '::editPageTitle';
$route_parameters['_controller'] = static::FORM_MODE_DEFAULT_CONTROLLER . '::entityEdit';
}
return $route_parameters;
}
protected function getFormModeRouteOptions(array $form_mode, EntityTypeInterface $entity_type) {
$entity_type_id = $entity_type
->id();
$entity_type_bundle_id = $entity_type
->getBundleEntityType();
$bundle_entity_type_id = !empty($entity_type_bundle_id) ? $entity_type_bundle_id : $entity_type_id;
return [
'_form_mode_manager_entity_type_id' => $entity_type_id,
'_form_mode_manager_bundle_entity_type_id' => $bundle_entity_type_id,
'parameters' => [
$entity_type_id => [
'type' => "entity:{$entity_type_id}",
],
'form_mode' => $form_mode + [
'type' => NULL,
],
],
];
}
protected function getFormModeRouteRequirements(array $form_mode) {
return [
'_permission' => "use {$form_mode['id']} form mode",
'_custom_access' => static::FORM_MODE_DEFAULT_CONTROLLER . '::checkAccess',
];
}
}