From 7020a958b10da2093fd52ba1bcaba270daab1aad Mon Sep 17 00:00:00 2001 From: Vasile Chindris Date: Thu, 18 Apr 2024 16:16:57 +0300 Subject: [PATCH] feat(SLB-328): add readme and access checks on the entity creation route --- packages/drupal/entity_create_split/README.md | 13 +++++++ .../entity_create_split.module | 9 ++--- .../entity_create_split.routing.yml | 4 +- .../EntityCreateSplitController.php | 39 ++++++++++++++++--- 4 files changed, 52 insertions(+), 13 deletions(-) create mode 100644 packages/drupal/entity_create_split/README.md diff --git a/packages/drupal/entity_create_split/README.md b/packages/drupal/entity_create_split/README.md new file mode 100644 index 000000000..4a9c81851 --- /dev/null +++ b/packages/drupal/entity_create_split/README.md @@ -0,0 +1,13 @@ +# Entity Create Split + +A Drupal module which exposes routes to split an entity create form into two parts: +- on the first step, only the required fields are presented. After submitting the form, a entity is already created +- the second step is actually just the entity edit form, containing all the other optional form fields. + +One important thing is that there are no alterations done on the current entity create routes (for example, on /node/add/page). This module just exposes the route _/entity/create/{entity_type}/{entity_bundle}_ and how this route is used is subject to each specific project. + +## Special case for the Gutenberg editor + +The Gutenberg editor does a lot of alterations on the create form. For this reason, it is better that the form alter hook of the gutenberg module to not run at all. This is not easy possible, so right now the easieist approach is to just patch the module. The patch is included in the _patches/gutenberg_ folder. + +The functionality should also work without the patch, but the initial form will not look that nice. diff --git a/packages/drupal/entity_create_split/entity_create_split.module b/packages/drupal/entity_create_split/entity_create_split.module index b1bb96ec9..0058cf93f 100644 --- a/packages/drupal/entity_create_split/entity_create_split.module +++ b/packages/drupal/entity_create_split/entity_create_split.module @@ -9,18 +9,17 @@ use Drupal\Core\Entity\EntityFormInterface; use Drupal\Core\Form\FormStateInterface; -use Drupal\Core\Render\Element; /** * Implements hook_form_alter(). */ function entity_create_split_form_alter(&$form, FormStateInterface $form_state, $form_id) { - // We are only interested in entity create forms, and only when the - // splitRequiredFields flag is set on the entity (which means the form was - // requested from the entity_create_split.create route. + // We are only interested in entity forms, and only when the + // hideOptionalFormFields flag is set on the entity (which means the form was + // requested from the entity_create_split.create route). if ($form_state->getFormObject() instanceof EntityFormInterface) { $entity = $form_state->getFormObject()->getEntity(); - if (!$entity->isNew() || empty($entity->hideOptionalFormFields)) { + if (!$entity->hideOptionalFormFields) { return; } /* @var \Drupal\entity_create_split\FormOperationsInterface $formOperations */ diff --git a/packages/drupal/entity_create_split/entity_create_split.routing.yml b/packages/drupal/entity_create_split/entity_create_split.routing.yml index e4890ef8a..e5762db49 100644 --- a/packages/drupal/entity_create_split/entity_create_split.routing.yml +++ b/packages/drupal/entity_create_split/entity_create_split.routing.yml @@ -2,8 +2,8 @@ entity_create_split.create: path: '/entity/create/{entity_type}/{bundle}' defaults: _controller: '\Drupal\entity_create_split\Controller\EntityCreateSplitController::createForm' - _title: 'Create entity' + _title_callback: '\Drupal\entity_create_split\Controller\EntityCreateSplitController::getTitle' requirements: - _permission: 'administer graphql configuration' + _custom_access: '\Drupal\entity_create_split\Controller\EntityCreateSplitController::access' options: _admin_route: TRUE diff --git a/packages/drupal/entity_create_split/src/Controller/EntityCreateSplitController.php b/packages/drupal/entity_create_split/src/Controller/EntityCreateSplitController.php index 434af1835..fa1b39bd5 100644 --- a/packages/drupal/entity_create_split/src/Controller/EntityCreateSplitController.php +++ b/packages/drupal/entity_create_split/src/Controller/EntityCreateSplitController.php @@ -2,8 +2,8 @@ namespace Drupal\entity_create_split\Controller; +use Drupal\Core\Access\AccessResult; use Drupal\Core\Controller\ControllerBase; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class EntityCreateSplitController extends ControllerBase { @@ -19,17 +19,44 @@ class EntityCreateSplitController extends ControllerBase { * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException */ public function createForm($entity_type, $bundle) { - if (!$this->entityTypeManager()->hasDefinition($entity_type)) { - throw new NotFoundHttpException(); - } $entityTypeDefinition = $this->entityTypeManager()->getDefinition($entity_type); $bundleKey = $entityTypeDefinition->getKey('bundle'); - - // @todo: find a way to check if the bundle value is allowed. $entity = $this->entityTypeManager()->getStorage($entity_type)->create([$bundleKey => $bundle]); $entity->disableGutenberg = TRUE; $entity->hideOptionalFormFields = TRUE; $editForm = $this->entityTypeManager()->getFormObject($entity_type, 'default')->setEntity($entity); return \Drupal::formBuilder()->getForm($editForm); } + + /** + * Title callback for the createForm() route. + */ + public function getTitle($entity_type, $bundle) { + $entityTypeDefinition = $this->entityTypeManager()->getDefinition($entity_type); + $bundleEntityType = $entityTypeDefinition->getBundleEntityType(); + $bundleLabel = $this->entityTypeManager()->getStorage($bundleEntityType)->load($bundle)->label(); + return $this->t("Create %entity_type: %entity_bundle", [ + '%entity_type' => $entityTypeDefinition->getLabel(), + '%entity_bundle' => $bundleLabel, + ]); + } + + /** + * Access callback for the createForm() route. + */ + public function access($entity_type, $bundle) { + if (!$this->entityTypeManager()->hasDefinition($entity_type)) { + return AccessResult::forbidden(); + } + $entityTypeDefinition = $this->entityTypeManager()->getDefinition($entity_type); + $bundleEntityType = $entityTypeDefinition->getBundleEntityType(); + $bundleEntity = $this->entityTypeManager()->getStorage($bundleEntityType)->load($bundle); + if (!$bundleEntity) { + return AccessResult::forbidden(); + } + + return $this->entityTypeManager() + ->getAccessControlHandler($entity_type) + ->createAccess($bundle, NULL, [], TRUE); + } }