Issue #3438771 by amateescu, Michelle, smustgrave: Newly added menu links are invisible until published

merge-requests/7498/merge
catch 2024-04-22 11:43:24 +01:00
parent d78d49d668
commit 1522a33e41
3 changed files with 52 additions and 20 deletions

View File

@ -147,6 +147,16 @@ class EntityOperations implements ContainerInjectionInterface {
$entity->isDefaultRevision(FALSE); $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. // Track the workspaces in which the new revision was saved.
if (!$entity->isSyncing()) { if (!$entity->isSyncing()) {
$field_name = $entity->getEntityType()->getRevisionMetadataKey('workspace'); $field_name = $entity->getEntityType()->getRevisionMetadataKey('workspace');
@ -326,6 +336,10 @@ class EntityOperations implements ContainerInjectionInterface {
* Entity builder that marks all supported entities as pending revisions. * Entity builder that marks all supported entities as pending revisions.
*/ */
public static function entityFormEntityBuild($entity_type_id, RevisionableInterface $entity, &$form, FormStateInterface &$form_state) { 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 // Set the non-default revision flag so that validation constraints are also
// aware that a pending revision is about to be created. // aware that a pending revision is about to be created.
$entity->isDefaultRevision(FALSE); $entity->isDefaultRevision(FALSE);

View File

@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Drupal\Tests\workspaces\Functional; namespace Drupal\Tests\workspaces\Functional;
use Drupal\menu_link_content\Entity\MenuLinkContent;
use Drupal\Tests\BrowserTestBase; use Drupal\Tests\BrowserTestBase;
use Drupal\workspaces\Entity\Workspace; use Drupal\workspaces\Entity\Workspace;
@ -31,6 +30,7 @@ class WorkspaceMenuLinkContentIntegrationTest extends BrowserTestBase {
protected static $modules = [ protected static $modules = [
'block', 'block',
'menu_link_content', 'menu_link_content',
'menu_ui',
'node', 'node',
'workspaces', 'workspaces',
]; ];
@ -48,6 +48,7 @@ class WorkspaceMenuLinkContentIntegrationTest extends BrowserTestBase {
$permissions = [ $permissions = [
'access administration pages', 'access administration pages',
'administer menu',
'administer site configuration', 'administer site configuration',
'administer workspaces', 'administer workspaces',
]; ];
@ -65,19 +66,29 @@ class WorkspaceMenuLinkContentIntegrationTest extends BrowserTestBase {
$default_title = 'default'; $default_title = 'default';
$default_link = '#live'; $default_link = '#live';
$menu_link_content = MenuLinkContent::create([
'title' => $default_title, // Add a new menu link in Live.
'menu_name' => 'main', $this->drupalGet('admin/structure/menu/manage/main/add');
'link' => [['uri' => 'internal:/' . $default_link]], $this->submitForm([
]); 'title[0][value]' => $default_title,
$menu_link_content->save(); '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_title = 'pending';
$pending_link = 'http://example.com'; $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); $this->switchToWorkspace($stage);
$menu_link_content->set('title', $pending_title); $this->drupalGet("admin/structure/menu/item/{$menu_link->id()}/edit");
$menu_link_content->set('link', [['uri' => $pending_link]]); $this->submitForm([
$menu_link_content->save(); 'title[0][value]' => $pending_title,
'link[0][uri]' => $pending_link,
], 'Save');
$this->drupalGet(''); $this->drupalGet('');
$assert_session = $this->assertSession(); $assert_session = $this->assertSession();
@ -85,12 +96,11 @@ class WorkspaceMenuLinkContentIntegrationTest extends BrowserTestBase {
$assert_session->linkByHrefExists($pending_link); $assert_session->linkByHrefExists($pending_link);
// Add a new menu link in the Stage workspace. // Add a new menu link in the Stage workspace.
$menu_link_content = MenuLinkContent::create([ $this->drupalGet('admin/structure/menu/manage/main/add');
'title' => 'stage link', $this->submitForm([
'menu_name' => 'main', 'title[0][value]' => 'stage link',
'link' => [['uri' => 'internal:/#stage']], 'link[0][uri]' => '#stage',
]); ], 'Save');
$menu_link_content->save();
$this->drupalGet(''); $this->drupalGet('');
$assert_session->linkExists('stage link'); $assert_session->linkExists('stage link');

View File

@ -39,11 +39,19 @@ function workspaces_help($route_name, RouteMatchInterface $route_match) {
* Implements hook_module_implements_alter(). * Implements hook_module_implements_alter().
*/ */
function workspaces_module_implements_alter(&$implementations, $hook): void { function workspaces_module_implements_alter(&$implementations, $hook): void {
if ($hook === 'entity_insert') { // 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 // Move our 'hook_entity_insert' implementation at the end to ensure that
// the second (pending) revision created for published entities is not used // the second (pending) revision created for published entities is not used
// by other 'hook_entity_insert' implementations. // by other 'hook_entity_insert' implementations.
// @see \Drupal\workspaces\EntityOperations::entityInsert() // @see \Drupal\workspaces\EntityOperations::entityInsert()
if ($hook === 'entity_insert') {
$group = $implementations['workspaces']; $group = $implementations['workspaces'];
unset($implementations['workspaces']); unset($implementations['workspaces']);
$implementations['workspaces'] = $group; $implementations['workspaces'] = $group;