diff --git a/core/modules/workspace/src/EntityOperations.php b/core/modules/workspace/src/EntityOperations.php index 55f1322..4d0ff29 100644 --- a/core/modules/workspace/src/EntityOperations.php +++ b/core/modules/workspace/src/EntityOperations.php @@ -7,9 +7,11 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityStorageException; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Entity\RevisionableInterface; use Drupal\Core\Form\ConfigFormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; +use Drupal\views\Form\ViewsExposedForm; use Drupal\workspace\Form\WorkspaceFormInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -305,22 +307,29 @@ public function formAlter(array &$form, FormStateInterface $form_state, $form_id $form_object = $form_state->getFormObject(); $active_workspace = $this->workspaceManager->getActiveWorkspace(); - $is_workspace_form = $form_object instanceof WorkspaceFormInterface; - $is_form_supported = !$form_object instanceof ConfigFormBase - && $form_object instanceof EntityFormInterface + $is_entity_supported = $form_object instanceof EntityFormInterface && ($entity = $form_object->getEntity()) && $this->workspaceManager->isEntityTypeSupported($entity->getEntityType()); - // If this form does not have with a revisionable and publishable entity - // type, add a validation step which will always fail. - if (!$is_form_supported && !$is_workspace_form && !$active_workspace->isDefaultWorkspace()) { - $form['#validate'][] = [$this, 'validateEntityForm']; + // Add an additional validation step for every form that does not handle an + // revisionable and publishable entity. + if (!$is_entity_supported && !$active_workspace->isDefaultWorkspace()) { + $form['#validate'][] = [$this, 'validateForm']; return; } + // Add an entity builder to the form which marks the edited entity object as + // a pending revision. This is needed so validation constraints like + // \Drupal\path\Plugin\Validation\Constraint\PathAliasConstraintValidator + // know in advance (before hook_entity_presave()) that the new revision will + // a pending one. + if (!$active_workspace->isDefaultWorkspace()) { + $form['#entity_builders'][] = [$this, 'entityFormEntityBuild']; + } + /** @var \Drupal\workspace\WorkspaceAssociationStorageInterface $workspace_association_storage */ $workspace_association_storage = $this->entityTypeManager->getStorage('workspace_association'); - if ($is_form_supported && $workspace_ids = $workspace_association_storage->getEntityTrackingWorkspaceIds($entity)) { + if ($is_entity_supported && $workspace_ids = $workspace_association_storage->getEntityTrackingWorkspaceIds($entity)) { // An entity can only be edited in one workspace. $workspace_id = reset($workspace_ids); @@ -334,10 +343,27 @@ public function formAlter(array &$form, FormStateInterface $form_state, $form_id } /** - * Handles validation for every form of an entity type which is not supported. + * Validation handler for forms that do not handle a supported entity type. + */ + public function validateForm(array &$form, FormStateInterface $form_state) { + $form_object = $form_state->getFormObject(); + + $is_workspace_form = $form_object instanceof WorkspaceFormInterface; + $is_views_exposed_form = $form_object instanceof ViewsExposedForm; + $is_config_form = $form_object instanceof ConfigFormBase; + + if ((!$is_workspace_form && !$is_views_exposed_form) || $is_config_form) { + $form_state->setError($form, $this->t('This form can only be submitted in the default workspace.')); + } + } + + /** + * Entity builder that marks all supported entities as pending revisions. */ - public function validateEntityForm(array &$form, FormStateInterface $form_state) { - $form_state->setError($form, $this->t('This form can only be submitted in the default workspace.')); + public function entityFormEntityBuild($entity_type_id, RevisionableInterface $entity, &$form, FormStateInterface &$form_state) { + // Set the non-default revision flag so that validation constraints are also + // aware that a pending revision is about to be created. + $entity->isDefaultRevision(FALSE); } }