From 172e467ad92d276116a09cd8f1768945ddad2a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez?= <56769-technoveltyco@users.noreply.drupalcode.org> Date: Thu, 2 Feb 2023 10:18:02 +0000 Subject: [PATCH] Issue #3338369: Layout Builder - Add a refresh layout defaults feature --- .../src/Form/OverridesEntityForm.php | 6 + .../src/Form/RefreshOverridesForm.php | 177 ++++++++++++++++++ .../src/Routing/LayoutBuilderRoutesTrait.php | 8 + 3 files changed, 191 insertions(+) create mode 100644 core/modules/layout_builder/src/Form/RefreshOverridesForm.php diff --git a/core/modules/layout_builder/src/Form/OverridesEntityForm.php b/core/modules/layout_builder/src/Form/OverridesEntityForm.php index 789778fc8f..0f6017eede 100644 --- a/core/modules/layout_builder/src/Form/OverridesEntityForm.php +++ b/core/modules/layout_builder/src/Form/OverridesEntityForm.php @@ -209,6 +209,12 @@ protected function actions(array $form, FormStateInterface $form_state) { '#submit' => ['::redirectOnSubmit'], '#redirect' => 'revert', ]; + $actions['refresh'] = [ + '#type' => 'submit', + '#value' => $this->t('Refresh layout defaults'), + '#submit' => ['::redirectOnSubmit'], + '#redirect' => 'refresh', + ]; $actions['preview_toggle'] = $this->buildContentPreviewToggle(); return $actions; } diff --git a/core/modules/layout_builder/src/Form/RefreshOverridesForm.php b/core/modules/layout_builder/src/Form/RefreshOverridesForm.php new file mode 100644 index 0000000000..cd18c5ce91 --- /dev/null +++ b/core/modules/layout_builder/src/Form/RefreshOverridesForm.php @@ -0,0 +1,177 @@ +layoutTempstoreRepository = $layout_tempstore_repository; + $this->messenger = $messenger; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('layout_builder.tempstore_repository'), + $container->get('messenger') + ); + } + + /** + * {@inheritdoc} + */ + public function getFormId() { + return 'layout_builder_refresh_overrides'; + } + + /** + * {@inheritdoc} + */ + public function getQuestion() { + return $this->t('Are you sure you want to refresh this layout with the defaults?'); + } + + /** + * {@inheritdoc} + */ + public function getConfirmText() { + return $this->t('Refresh defaults'); + } + + /** + * {@inheritdoc} + */ + public function getCancelUrl() { + return $this->sectionStorage->getLayoutBuilderUrl(); + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state, SectionStorageInterface $section_storage = NULL) { + if (!$section_storage instanceof OverridesSectionStorageInterface) { + throw new \InvalidArgumentException(sprintf('The section storage with type "%s" and ID "%s" does not provide overrides', $section_storage->getStorageType(), $section_storage->getStorageId())); + } + + $this->sectionStorage = $section_storage; + // Mark this as an administrative page for JavaScript ("Back to site" link). + $form['#attached']['drupalSettings']['path']['currentPathIsAdmin'] = TRUE; + return parent::buildForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + // Refresh all sections with the defaults. + if ($this->sectionStorage instanceof OverridesSectionStorageInterface) { + + $layoutSections = $this->sectionStorage->getSections(); + $defaultSections = $this->sectionStorage->getDefaultSectionStorage()->getSections(); + + // Keep track of the delta when the layout sections are refreshed. + $refresh_layout_delta = array_key_first($layoutSections); + $refresh_default_delta = array_key_first($defaultSections); + + // Find the default sections in the layout, ... + foreach ($layoutSections as $layout_delta => $section) { + + $layoutSettings = $section->getLayoutSettings(); + $section_label = !empty($layoutSettings['label']) ? $layoutSettings['label'] : sprintf('Section %d', $layout_delta + 1); + + // ... looking from the last refreshed default section, ... + for ($default_delta = $refresh_default_delta; $default_delta < count($defaultSections); $default_delta++) { + + $defaultSection = $defaultSections[$default_delta]; + + $defaultLayoutSettings = $defaultSection->getLayoutSettings(); + $default_section_label = !empty($defaultLayoutSettings['label']) ? $defaultLayoutSettings['label'] : sprintf('Section %d', $default_delta + 1); + + // and when a default section is found in the layout, ... + if ($section_label === $default_section_label) { + + // ...remove the current default section, ... + $this->sectionStorage->removeSection($refresh_layout_delta); + + // ...insert all previous defaults before this one, ... + $previous_default_sections = array_slice($defaultSections, $refresh_default_delta, $default_delta - $refresh_default_delta, TRUE); + + foreach ($previous_default_sections as $previousDefaultSection) { + $this->sectionStorage->insertSection($refresh_layout_delta, $previousDefaultSection); + $refresh_default_delta++; + $refresh_layout_delta++; + } + + // ...re-insert the current default section, ... + $this->sectionStorage->insertSection($refresh_layout_delta, $defaultSection); + $refresh_default_delta++; + + // ... defaults added, so continue with another layout section, ... + break; + } + } + + // ...and refresh layout delta for the next section. + $refresh_layout_delta++; + } + + // Update the layout section storage with the new re-ordering. + $this->sectionStorage + ->save(); + $this->layoutTempstoreRepository->set($this->sectionStorage); + + $this->messenger->addMessage($this->t('The layout has been refreshed with the defaults.')); + } + else { + $this->messenger->addMessage($this->t('The layout has no available defaults to refresh.')); + } + + $form_state->setRedirectUrl($this->sectionStorage->getRedirectUrl()); + } + +} diff --git a/core/modules/layout_builder/src/Routing/LayoutBuilderRoutesTrait.php b/core/modules/layout_builder/src/Routing/LayoutBuilderRoutesTrait.php index aebc975565..0f74c9a346 100644 --- a/core/modules/layout_builder/src/Routing/LayoutBuilderRoutesTrait.php +++ b/core/modules/layout_builder/src/Routing/LayoutBuilderRoutesTrait.php @@ -86,6 +86,14 @@ protected function buildLayoutRoutes(RouteCollection $collection, SectionStorage ->setRequirements($requirements) ->setOptions($options); $collection->add("$route_name_prefix.revert", $route); + + $refresh_defaults = $defaults; + $refresh_defaults['_form'] = '\Drupal\layout_builder\Form\RefreshOverridesForm'; + $route = (new Route("$path/refresh")) + ->setDefaults($refresh_defaults) + ->setRequirements($requirements) + ->setOptions($options); + $collection->add("$route_name_prefix.refresh", $route); } elseif (is_subclass_of($definition->getClass(), DefaultsSectionStorageInterface::class)) { $disable_defaults = $defaults; -- 2.38.1