View source
<?php
namespace Drupal\form_mode_manager\Controller;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Cache\Cache;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityFormBuilderInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Form\FormState;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Routing\UrlGeneratorTrait;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\form_mode_manager\FormModeManagerInterface;
use Drupal\form_mode_manager\EntityRoutingMapManager;
use Symfony\Component\DependencyInjection\ContainerInterface;
abstract class EntityFormModeBase implements ContainerInjectionInterface {
use StringTranslationTrait;
use UrlGeneratorTrait;
protected $dateFormatter;
protected $renderer;
protected $account;
protected $formModeManager;
protected $entityTypeManager;
protected $entityFormBuilder;
protected $entityRoutingMap;
protected $formBuilder;
public function __construct(RendererInterface $renderer, AccountInterface $account, FormModeManagerInterface $form_mode_manager, EntityTypeManagerInterface $entity_manager, EntityFormBuilderInterface $entity_form_builder, EntityRoutingMapManager $plugin_routes_manager, FormBuilderInterface $form_builder) {
$this->renderer = $renderer;
$this->account = $account;
$this->formModeManager = $form_mode_manager;
$this->entityTypeManager = $entity_manager;
$this->entityFormBuilder = $entity_form_builder;
$this->entityRoutingMap = $plugin_routes_manager;
$this->formBuilder = $form_builder;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('renderer'), $container
->get('current_user'), $container
->get('form_mode.manager'), $container
->get('entity_type.manager'), $container
->get('entity.form_builder'), $container
->get('plugin.manager.entity_routing_map'), $container
->get('form_builder'));
}
public function addPage(RouteMatchInterface $route_match) {
$entity_type_id = $route_match
->getRouteObject()
->getOption('_form_mode_manager_entity_type_id');
$entity_bundle_name = $route_match
->getRouteObject()
->getOption('_form_mode_manager_bundle_entity_type_id');
$form_mode_name = $route_match
->getRouteObject()
->getDefault('form_mode_name');
$entity_type_cache_tags = $this->entityTypeManager
->getDefinition($entity_bundle_name)
->getListCacheTags();
$entity_type_definitions = $this->entityTypeManager
->getStorage($entity_bundle_name)
->loadMultiple();
$build = [
'#theme' => 'form_mode_manager_add_list',
'#entity_type' => $entity_type_id,
'#cache' => [
'tags' => Cache::mergeTags($entity_type_cache_tags, $this->formModeManager
->getListCacheTags()),
],
];
$content = [];
foreach ($entity_type_definitions as $bundle) {
$bundle_id = $bundle
->id();
$access = $this->entityTypeManager
->getAccessControlHandler($entity_type_id)
->createAccess($bundle_id, $this->account, [], TRUE);
if ($access
->isAllowed() && $this->formModeManager
->isActive($entity_type_id, $bundle_id, $form_mode_name)) {
$content[$bundle_id] = $bundle;
$this->renderer
->addCacheableDependency($build, $access);
}
}
if (1 == count($content)) {
$bundle = array_shift($content);
$entity_routes_infos = $this->entityRoutingMap
->createInstance($entity_type_id, [
'entityTypeId' => $entity_type_id,
])
->getPluginDefinition();
return $this
->redirect($entity_routes_infos['operations']['add_form'] . ".{$form_mode_name}", [
$entity_bundle_name => $bundle
->id(),
]);
}
$build['#content'] = $content;
$build['#form_mode'] = $form_mode_name;
return $build;
}
public function entityAdd(RouteMatchInterface $route_match) {
$entity = $this
->getEntityFromRouteMatch($route_match);
if (empty($entity)) {
$route_entity_type_info = $this
->getEntityTypeFromRouteMatch($route_match);
$entity = $this->entityTypeManager
->getStorage($route_entity_type_info['entity_type_id'])
->create([
$route_entity_type_info['entity_key'] => $route_entity_type_info['bundle'],
]);
}
$form_mode_id = $this->formModeManager
->getFormModeMachineName($route_match
->getRouteObject()
->getDefault('_entity_form'));
$operation = empty($form_mode_id) ? 'default' : $form_mode_id;
if ($entity instanceof EntityInterface) {
return $this->entityFormBuilder
->getForm($entity, $operation);
}
}
public function entityEdit(RouteMatchInterface $route_match) {
$entity = $this
->getEntityFromRouteMatch($route_match);
$form_mode_id = $this->formModeManager
->getFormModeMachineName($route_match
->getRouteObject()
->getOption('parameters')['form_mode']['id']);
$operation = empty($form_mode_id) ? 'default' : 'edit_' . $form_mode_id;
if ($entity instanceof EntityInterface) {
return $this
->getForm($entity, $operation);
}
}
public function getForm(EntityInterface $entity, $operation = 'default', array $form_state_additions = []) {
$form_object = $this->entityTypeManager
->getFormObject($entity
->getEntityTypeId(), $operation);
$form_object
->setEntity($entity)
->setOperation($this
->getFormModeOperationName($operation));
$form_state = (new FormState())
->setFormState($form_state_additions);
return $this->formBuilder
->buildForm($form_object, $form_state);
}
public function getFormModeOperationName($operation) {
return preg_replace('/^(edit_)/', '', $operation);
}
public function addPageTitle(RouteMatchInterface $route_match) {
return $this
->pageTitle($route_match, $this
->t('Create'));
}
public function editPageTitle(RouteMatchInterface $route_match) {
return $this
->pageTitle($route_match, $this
->t('Edit'));
}
public function pageTitle(RouteMatchInterface $route_match, $operation) {
$entity_storage = $this
->getEntityBundle($route_match);
$form_mode_label = $route_match
->getRouteObject()
->getOption('parameters')['form_mode']['label'];
return $this
->t('@op @name as @form_mode_label', [
'@name' => $entity_storage
->label(),
'@form_mode_label' => $form_mode_label,
'@op' => $operation,
]);
}
private function getEntityBundle(RouteMatchInterface $route_match) {
$entity = $this
->getEntityFromRouteMatch($route_match);
if (empty($entity)) {
$route_entity_type_info = $this
->getEntityTypeFromRouteMatch($route_match);
$bundle = $this->entityTypeManager
->getStorage($route_entity_type_info['bundle_entity_type'])
->load($route_entity_type_info['bundle']);
}
else {
$bundle = $this->entityTypeManager
->getStorage($route_match
->getRouteObject()
->getOption('_form_mode_manager_bundle_entity_type_id'))
->load($entity
->bundle());
}
if (empty($bundle)) {
$bundle = $this->entityTypeManager
->getStorage($route_match
->getRouteObject()
->getOption('_form_mode_manager_bundle_entity_type_id'));
}
return $bundle;
}
public function checkAccess(RouteMatchInterface $route_match) {
$entity = $this
->getEntityFromRouteMatch($route_match);
$route = $route_match
->getRouteObject();
$form_mode_id = $route
->getDefault('_entity_form');
$cache_tags = $this->formModeManager
->getListCacheTags();
if (empty($entity)) {
$route_entity_type_info = $this
->getEntityTypeFromRouteMatch($route_match);
$entity_type_id = $route_entity_type_info['entity_type_id'];
$bundle_id = isset($route_entity_type_info['bundle']) ? $route_entity_type_info['bundle'] : $route
->getOption('_form_mode_manager_bundle_entity_type_id');
}
else {
$entity_type_id = $route
->getOption('_form_mode_manager_entity_type_id');
$bundle_id = !empty($route_match
->getParameter($entity_type_id)) ? $route_match
->getParameter($entity_type_id)
->bundle() : 'user';
}
$operation = $this
->getFormModeOperationName($this->formModeManager
->getFormModeMachineName($form_mode_id));
$result = AccessResult::allowedIf($this->formModeManager
->isActive($entity_type_id, $bundle_id, $operation))
->addCacheTags($cache_tags);
if ($entity) {
$result
->addCacheableDependency($entity);
}
return $result;
}
protected function getEntityFromRouteMatch(RouteMatchInterface $route_match) {
$parameter_name = $route_match
->getRouteObject()
->getOption('_form_mode_manager_entity_type_id');
$entity = $route_match
->getParameter($parameter_name);
return $entity;
}
protected function getEntityTypeFromRouteMatch(RouteMatchInterface $route_match) {
$route = $route_match
->getRouteObject();
$entity_type_id = $route
->getOption('_form_mode_manager_entity_type_id');
$bundle_entity_type_id = $route
->getOption('_form_mode_manager_bundle_entity_type_id');
$form_mode = $this->formModeManager
->getFormModeMachineName($route
->getDefault('_entity_form'));
$bundle = $route_match
->getRawParameter($bundle_entity_type_id);
$form_mode_definition = $this->formModeManager
->getActiveDisplaysByBundle($entity_type_id, $bundle);
$entity_type_key = $this->entityTypeManager
->getDefinition($entity_type_id)
->getKey('bundle');
return [
'bundle' => $bundle,
'bundle_entity_type' => $bundle_entity_type_id,
'entity_key' => $entity_type_key,
'entity_type_id' => $entity_type_id,
'form_mode' => isset($form_mode_definition[$entity_type_id][$form_mode]) ? $form_mode_definition[$entity_type_id][$form_mode] : NULL,
];
}
}