diff --git a/core/modules/layout_builder/src/Access/LayoutBuilderLockAccessCheck.php b/core/modules/layout_builder/src/Access/LayoutBuilderLockAccessCheck.php index db90622bc0..7f8e8f403b 100644 --- a/core/modules/layout_builder/src/Access/LayoutBuilderLockAccessCheck.php +++ b/core/modules/layout_builder/src/Access/LayoutBuilderLockAccessCheck.php @@ -18,6 +18,13 @@ */ class LayoutBuilderLockAccessCheck implements AccessInterface { + /** + * The layout tempstore repository. + * + * @var \Drupal\layout_builder\LayoutTempstoreRepositoryInterface + */ + protected $layoutTempstoreRepository; + /** * Constructs a LayoutBuilderLockAccessCheck. * @@ -29,14 +36,7 @@ public function __construct(LayoutTempstoreRepositoryInterface $layout_tempstore } /** - * The layout tempstore repository. - * - * @var \Drupal\layout_builder\LayoutTempstoreRepositoryInterface - */ - protected $layoutTempstoreRepository; - - /** - * Checks for a lock from another user on the layout. + * Checks for a lock on the layout. * * @param \Drupal\layout_builder\SectionStorageInterface $section_storage * The section storage. diff --git a/core/modules/layout_builder/src/Element/LayoutBuilder.php b/core/modules/layout_builder/src/Element/LayoutBuilder.php index 46d92b9b43..25668871f2 100644 --- a/core/modules/layout_builder/src/Element/LayoutBuilder.php +++ b/core/modules/layout_builder/src/Element/LayoutBuilder.php @@ -3,13 +3,10 @@ namespace Drupal\layout_builder\Element; use Drupal\Core\Ajax\AjaxHelperTrait; -use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Plugin\PluginFormInterface; use Drupal\Core\Render\Element; use Drupal\Core\Render\Element\RenderElement; -use Drupal\Core\Session\AccountInterface; -use Drupal\Core\TempStore\Lock; use Drupal\Core\Url; use Drupal\layout_builder\Context\LayoutBuilderContextTrait; use Drupal\layout_builder\LayoutBuilderHighlightTrait; @@ -39,20 +36,6 @@ class LayoutBuilder extends RenderElement implements ContainerFactoryPluginInter */ protected $layoutTempstoreRepository; - /** - * The messenger service. - * - * @var \Drupal\Core\Messenger\MessengerInterface - */ - protected $messenger; - - /** - * The current user. - * - * @var \Drupal\Core\Session\AccountInterface - */ - protected $currentUser; - /** * Constructs a new LayoutBuilder. * @@ -64,16 +47,10 @@ class LayoutBuilder extends RenderElement implements ContainerFactoryPluginInter * The plugin implementation definition. * @param \Drupal\layout_builder\LayoutTempstoreRepositoryInterface $layout_tempstore_repository * The layout tempstore repository. - * @param \Drupal\Core\Messenger\MessengerInterface $messenger - * The messenger service. - * @param \Drupal\Core\Session\AccountInterface $current_user - * The current user. */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, LayoutTempstoreRepositoryInterface $layout_tempstore_repository, MessengerInterface $messenger, AccountInterface $current_user) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, LayoutTempstoreRepositoryInterface $layout_tempstore_repository) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->layoutTempstoreRepository = $layout_tempstore_repository; - $this->messenger = $messenger; - $this->currentUser = $current_user; } /** @@ -84,9 +61,7 @@ public static function create(ContainerInterface $container, array $configuratio $configuration, $plugin_id, $plugin_definition, - $container->get('layout_builder.tempstore_repository'), - $container->get('messenger'), - $container->get('current_user') + $container->get('layout_builder.tempstore_repository') ); } @@ -112,27 +87,6 @@ public function preRender($element) { return $element; } - /** - * Gets the lock message. - * - * @param \Drupal\layout_builder\SectionStorageInterface $section_storage - * The section storage. - * @param \Drupal\Core\TempStore\Lock $lock - * The lock object. - * - * @return string|\Drupal\Core\StringTranslation\TranslatableMarkup - * The lock message. - */ - protected function lockMessage(SectionStorageInterface $section_storage, Lock $lock) { - $message_array = [ - '#type' => 'break_lock_link', - '#label' => $this->t('layout'), - '#lock' => $lock, - '#url' => $section_storage->getLayoutBuilderUrl('discard_changes'), - ]; - return \Drupal::service('renderer')->render($message_array); - } - /** * Renders the Layout UI. * @@ -143,19 +97,7 @@ protected function lockMessage(SectionStorageInterface $section_storage, Lock $l * A render array. */ protected function layout(SectionStorageInterface $section_storage) { - // If the layout has pending changes, add a warning. - if ($lock = $this->layoutTempstoreRepository->getLock($section_storage)) { - if ($this->currentUser->id() === $lock->getOwnerId()) { - $this->messenger->addWarning($this->t('You have unsaved changes.')); - } - else { - $this->messenger->addWarning($this->lockMessage($section_storage, $lock)); - return []; - } - } - else { - $this->prepareLayout($section_storage); - } + $this->prepareLayout($section_storage); $output = []; if ($this->isAjax()) { @@ -188,7 +130,7 @@ protected function layout(SectionStorageInterface $section_storage) { protected function prepareLayout(SectionStorageInterface $section_storage) { // If the layout is an override that has not yet been overridden, copy the // sections from the corresponding default. - if ($section_storage instanceof OverridesSectionStorageInterface && !$section_storage->isOverridden()) { + if ($section_storage instanceof OverridesSectionStorageInterface && !$section_storage->isOverridden() && !$this->layoutTempstoreRepository->has($section_storage)) { $sections = $section_storage->getDefaultSectionStorage()->getSections(); foreach ($sections as $section) { $section_storage->appendSection($section); diff --git a/core/modules/layout_builder/src/Form/DefaultsEntityForm.php b/core/modules/layout_builder/src/Form/DefaultsEntityForm.php index 505de0edfd..737f7e3b9c 100644 --- a/core/modules/layout_builder/src/Form/DefaultsEntityForm.php +++ b/core/modules/layout_builder/src/Form/DefaultsEntityForm.php @@ -6,6 +6,7 @@ use Drupal\Core\Entity\EntityTypeBundleInfoInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Routing\RouteMatchInterface; +use Drupal\Core\TempStore\Lock; use Drupal\layout_builder\Entity\LayoutEntityDisplayInterface; use Drupal\layout_builder\LayoutTempstoreRepositoryInterface; use Drupal\layout_builder\SectionStorageInterface; @@ -80,6 +81,15 @@ public function getBaseFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, SectionStorageInterface $section_storage = NULL) { + if ($lock = $this->layoutTempstoreRepository->getLock($section_storage)) { + if ($this->currentUser()->id() === $lock->getOwnerId()) { + $this->messenger()->addWarning($this->t('You have unsaved changes.')); + } + else { + return $this->lockMessage($section_storage, $lock); + } + } + $form['layout_builder'] = [ '#type' => 'layout_builder', '#section_storage' => $section_storage, @@ -90,6 +100,36 @@ public function buildForm(array $form, FormStateInterface $form_state, SectionSt return parent::buildForm($form, $form_state); } + /** + * Builds the lock message. + * + * @param \Drupal\layout_builder\SectionStorageInterface $section_storage + * The section storage. + * @param \Drupal\Core\TempStore\Lock $lock + * The lock object. + * + * @return array + * A render array. + */ + protected function lockMessage(SectionStorageInterface $section_storage, Lock $lock) { + return [ + '#theme' => 'status_messages', + '#message_list' => [ + 'warning' => [ + [ + '#type' => 'break_lock_link', + '#label' => $this->t('layout'), + '#lock' => $lock, + '#url' => $section_storage->getLayoutBuilderUrl('discard_changes'), + ], + ], + ], + '#status_headings' => [ + 'warning' => $this->t('Warning message'), + ], + ]; + } + /** * Renders a message to display at the top of the layout builder. * diff --git a/core/modules/layout_builder/src/Form/DiscardLayoutChangesForm.php b/core/modules/layout_builder/src/Form/DiscardLayoutChangesForm.php index 826a1bcf68..d672e0887a 100644 --- a/core/modules/layout_builder/src/Form/DiscardLayoutChangesForm.php +++ b/core/modules/layout_builder/src/Form/DiscardLayoutChangesForm.php @@ -107,9 +107,9 @@ public function getCancelUrl() { public function buildForm(array $form, FormStateInterface $form_state, SectionStorageInterface $section_storage = NULL) { $this->sectionStorage = $section_storage; $lock = $this->layoutTempstoreRepository->getLock($section_storage); - // The current user is considered the owner if there are no changes made or - // if they are the ones who made the changes. - $this->isOwnerCurrentUser = !$lock ? TRUE : $lock->getOwnerId() === $this->currentUser()->id(); + // The current user is considered the owner if they are the ones who made + // the changes or if there are no changes made. + $this->isOwnerCurrentUser = $lock ? $lock->getOwnerId() === $this->currentUser()->id() : TRUE; return parent::buildForm($form, $form_state); } diff --git a/core/modules/layout_builder/src/Form/OverridesEntityForm.php b/core/modules/layout_builder/src/Form/OverridesEntityForm.php index d66f69ec62..5ced5b3186 100644 --- a/core/modules/layout_builder/src/Form/OverridesEntityForm.php +++ b/core/modules/layout_builder/src/Form/OverridesEntityForm.php @@ -9,6 +9,7 @@ use Drupal\Core\Entity\EntityRepositoryInterface; use Drupal\Core\Entity\EntityTypeBundleInfoInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\TempStore\Lock; use Drupal\layout_builder\LayoutTempstoreRepositoryInterface; use Drupal\layout_builder\OverridesSectionStorageInterface; use Drupal\layout_builder\Plugin\SectionStorage\OverridesSectionStorage; @@ -95,6 +96,15 @@ protected function init(FormStateInterface $form_state) { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, SectionStorageInterface $section_storage = NULL) { + if ($lock = $this->layoutTempstoreRepository->getLock($section_storage)) { + if ($this->currentUser()->id() === $lock->getOwnerId()) { + $this->messenger()->addWarning($this->t('You have unsaved changes.')); + } + else { + return $this->lockMessage($section_storage, $lock); + } + } + $this->sectionStorage = $section_storage; $form = parent::buildForm($form, $form_state); @@ -107,6 +117,36 @@ public function buildForm(array $form, FormStateInterface $form_state, SectionSt return $form; } + /** + * Builds the lock message. + * + * @param \Drupal\layout_builder\SectionStorageInterface $section_storage + * The section storage. + * @param \Drupal\Core\TempStore\Lock $lock + * The lock object. + * + * @return array + * A render array. + */ + protected function lockMessage(SectionStorageInterface $section_storage, Lock $lock) { + return [ + '#theme' => 'status_messages', + '#message_list' => [ + 'warning' => [ + [ + '#type' => 'break_lock_link', + '#label' => $this->t('layout'), + '#lock' => $lock, + '#url' => $section_storage->getLayoutBuilderUrl('discard_changes'), + ], + ], + ], + '#status_headings' => [ + 'warning' => $this->t('Warning message'), + ], + ]; + } + /** * Renders a message to display at the top of the layout builder. * diff --git a/core/modules/layout_builder/tests/src/Functional/Update/TempstoreKeyUpdatePathTest.php b/core/modules/layout_builder/tests/src/Functional/Update/TempstoreKeyUpdatePathTest.php index 7aaa93c18d..b220525d3f 100644 --- a/core/modules/layout_builder/tests/src/Functional/Update/TempstoreKeyUpdatePathTest.php +++ b/core/modules/layout_builder/tests/src/Functional/Update/TempstoreKeyUpdatePathTest.php @@ -27,7 +27,7 @@ protected function setDatabaseDumpFiles() { } /** - * Tests the upgrade path for Layout Builder extra fields. + * Tests the upgrade path for Layout Builder tempstore keys. */ public function testRunUpdates() { $page = $this->getSession()->getPage(); @@ -45,18 +45,12 @@ public function testRunUpdates() { $assert_session->elementNotExists('css', '.layout--twocol-section'); $page->clickLink('Layout'); - // User 1 is the owner of the lock. See layout-builder-tempstore.php. - if ($account->id() == 1) { - $assert_session->pageTextContains('You have unsaved changes.'); - $assert_session->elementNotExists('css', '.layout--onecol'); - $assert_session->elementExists('css', '.layout--twocol-section'); - } - else { - $user = User::load(1); - $assert_session->pageTextContains(sprintf('This layout is being edited by user %s, and is therefore locked from editing by others.', $user->getDisplayName())); - $assert_session->elementNotExists('css', '.layout'); - $assert_session->elementNotExists('css', '.layout--twocol-section'); - } + // User 1 is the owner of the lock and is not the current user. + $this->assertNotSame(1, $account->id()); + $user = User::load(1); + $assert_session->pageTextContains(sprintf('This layout is being edited by user %s, and is therefore locked from editing by others.', $user->getDisplayName())); + $assert_session->elementNotExists('css', '.layout'); + $assert_session->elementNotExists('css', '.layout--twocol-section'); } }