diff --git a/core/modules/workspaces/src/EntityOperations.php b/core/modules/workspaces/src/EntityOperations.php index 118c68bd895e66863bb8adec040b2f81e951003d..b46929b3d025e9e9a256f67a1998ae8fda817c26 100644 --- a/core/modules/workspaces/src/EntityOperations.php +++ b/core/modules/workspaces/src/EntityOperations.php @@ -147,6 +147,16 @@ public function entityPresave(EntityInterface $entity) { $entity->isDefaultRevision(FALSE); } + // In ::entityFormEntityBuild() we mark the entity as a non-default revision + // so that validation constraints can rely on $entity->isDefaultRevision() + // always returning FALSE when an entity form is submitted in a workspace. + // However, after validation has run, we need to revert that flag so the + // first revision of a new entity is correctly seen by the system as the + // default revision. + if ($entity->isNew()) { + $entity->isDefaultRevision(TRUE); + } + // Track the workspaces in which the new revision was saved. if (!$entity->isSyncing()) { $field_name = $entity->getEntityType()->getRevisionMetadataKey('workspace'); @@ -326,6 +336,10 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, $f * Entity builder that marks all supported entities as pending revisions. */ public static function entityFormEntityBuild($entity_type_id, RevisionableInterface $entity, &$form, FormStateInterface &$form_state) { + // Ensure that all entity forms are signaling that a new revision will be + // created. + $entity->setNewRevision(TRUE); + // 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); diff --git a/core/modules/workspaces/tests/src/Functional/WorkspaceMenuLinkContentIntegrationTest.php b/core/modules/workspaces/tests/src/Functional/WorkspaceMenuLinkContentIntegrationTest.php index 7c8451730652d7c9dbe48cb42db170d32cb96b75..8df9d5632e574bf4b93a923d2bdb5c599fb826a4 100644 --- a/core/modules/workspaces/tests/src/Functional/WorkspaceMenuLinkContentIntegrationTest.php +++ b/core/modules/workspaces/tests/src/Functional/WorkspaceMenuLinkContentIntegrationTest.php @@ -4,7 +4,6 @@ namespace Drupal\Tests\workspaces\Functional; -use Drupal\menu_link_content\Entity\MenuLinkContent; use Drupal\Tests\BrowserTestBase; use Drupal\workspaces\Entity\Workspace; @@ -31,6 +30,7 @@ class WorkspaceMenuLinkContentIntegrationTest extends BrowserTestBase { protected static $modules = [ 'block', 'menu_link_content', + 'menu_ui', 'node', 'workspaces', ]; @@ -48,6 +48,7 @@ protected function setUp(): void { $permissions = [ 'access administration pages', + 'administer menu', 'administer site configuration', 'administer workspaces', ]; @@ -65,19 +66,29 @@ public function testWorkspacesWithCustomMenuLinks() { $default_title = 'default'; $default_link = '#live'; - $menu_link_content = MenuLinkContent::create([ - 'title' => $default_title, - 'menu_name' => 'main', - 'link' => [['uri' => 'internal:/' . $default_link]], - ]); - $menu_link_content->save(); + + // Add a new menu link in Live. + $this->drupalGet('admin/structure/menu/manage/main/add'); + $this->submitForm([ + 'title[0][value]' => $default_title, + 'link[0][uri]' => $default_link, + ], 'Save'); + $menu_links = \Drupal::entityTypeManager() + ->getStorage('menu_link_content') + ->loadByProperties(['title' => $default_title]); + $menu_link = reset($menu_links); $pending_title = 'pending'; $pending_link = 'http://example.com'; + + // Change the menu link in 'stage' and check that the updated values are + // visible in that workspace. $this->switchToWorkspace($stage); - $menu_link_content->set('title', $pending_title); - $menu_link_content->set('link', [['uri' => $pending_link]]); - $menu_link_content->save(); + $this->drupalGet("admin/structure/menu/item/{$menu_link->id()}/edit"); + $this->submitForm([ + 'title[0][value]' => $pending_title, + 'link[0][uri]' => $pending_link, + ], 'Save'); $this->drupalGet(''); $assert_session = $this->assertSession(); @@ -85,12 +96,11 @@ public function testWorkspacesWithCustomMenuLinks() { $assert_session->linkByHrefExists($pending_link); // Add a new menu link in the Stage workspace. - $menu_link_content = MenuLinkContent::create([ - 'title' => 'stage link', - 'menu_name' => 'main', - 'link' => [['uri' => 'internal:/#stage']], - ]); - $menu_link_content->save(); + $this->drupalGet('admin/structure/menu/manage/main/add'); + $this->submitForm([ + 'title[0][value]' => 'stage link', + 'link[0][uri]' => '#stage', + ], 'Save'); $this->drupalGet(''); $assert_session->linkExists('stage link'); diff --git a/core/modules/workspaces/workspaces.module b/core/modules/workspaces/workspaces.module index 09c91af77ad1f74a32bb69b457c18be3e1a21775..cc8cf8e1dabdf76000f7b4a3b7887a77c633e8f3 100644 --- a/core/modules/workspaces/workspaces.module +++ b/core/modules/workspaces/workspaces.module @@ -39,11 +39,19 @@ function workspaces_help($route_name, RouteMatchInterface $route_match) { * Implements hook_module_implements_alter(). */ function workspaces_module_implements_alter(&$implementations, $hook): void { + // Move our 'hook_entity_presave' implementation at the beginning to ensure + // that other presave implementations are aware of the changes done in + // \Drupal\workspaces\EntityOperations::entityPresave(). + if ($hook === 'entity_presave') { + $implementation = $implementations['workspaces']; + $implementations = ['workspaces' => $implementation] + $implementations; + } + + // Move our 'hook_entity_insert' implementation at the end to ensure that + // the second (pending) revision created for published entities is not used + // by other 'hook_entity_insert' implementations. + // @see \Drupal\workspaces\EntityOperations::entityInsert() if ($hook === 'entity_insert') { - // Move our 'hook_entity_insert' implementation at the end to ensure that - // the second (pending) revision created for published entities is not used - // by other 'hook_entity_insert' implementations. - // @see \Drupal\workspaces\EntityOperations::entityInsert() $group = $implementations['workspaces']; unset($implementations['workspaces']); $implementations['workspaces'] = $group;