Skip to content
Snippets Groups Projects
Commit 01d2ac85 authored by jurgenhaas's avatar jurgenhaas
Browse files

drupal-config#2 Move default config and patches to the new...

drupal-config#2 Move default config and patches to the new project composer/plugin/drupal-config
parent 412609f7
No related branches found
No related tags found
1 merge request!382Merging develop into main
Pipeline #1383945 passed
Showing
with 0 additions and 4326 deletions
This diff is collapsed.
diff --git a/core/lib/Drupal/Core/Layout/LayoutDefault.php b/core/lib/Drupal/Core/Layout/LayoutDefault.php
index bd3780987a..8fc99d76ea 100644
--- a/core/lib/Drupal/Core/Layout/LayoutDefault.php
+++ b/core/lib/Drupal/Core/Layout/LayoutDefault.php
@@ -8,6 +8,7 @@
use Drupal\Core\Plugin\ContextAwarePluginTrait;
use Drupal\Core\Plugin\PluginBase;
use Drupal\Core\Plugin\PluginFormInterface;
+use Drupal\Core\Plugin\PluginWithFormsTrait;
use Drupal\Core\Plugin\PreviewAwarePluginInterface;
/**
@@ -17,6 +18,7 @@ class LayoutDefault extends PluginBase implements LayoutInterface, PluginFormInt
use ContextAwarePluginAssignmentTrait;
use ContextAwarePluginTrait;
+ use PluginWithFormsTrait;
/**
* Whether the plugin is being rendered in preview mode.
@@ -127,6 +129,13 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s
$this->configuration['label'] = $form_state->getValue('label');
}
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormClass($operation) {
+ return $this->getPluginDefinition()->get('forms')[$operation] ?? static::class;
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/core/lib/Drupal/Core/Layout/LayoutInterface.php b/core/lib/Drupal/Core/Layout/LayoutInterface.php
index 33858a546d..2e62ba85da 100644
--- a/core/lib/Drupal/Core/Layout/LayoutInterface.php
+++ b/core/lib/Drupal/Core/Layout/LayoutInterface.php
@@ -7,11 +7,12 @@
use Drupal\Component\Plugin\ConfigurableInterface;
use Drupal\Component\Plugin\DependentPluginInterface;
use Drupal\Core\Plugin\ContextAwarePluginInterface;
+use Drupal\Core\Plugin\PluginWithFormsInterface;
/**
* Provides an interface for static Layout plugins.
*/
-interface LayoutInterface extends PluginInspectionInterface, DerivativeInspectionInterface, ConfigurableInterface, DependentPluginInterface, ContextAwarePluginInterface {
+interface LayoutInterface extends PluginInspectionInterface, DerivativeInspectionInterface, ConfigurableInterface, DependentPluginInterface, ContextAwarePluginInterface, PluginWithFormsInterface {
/**
* Build a render array for layout with regions.
diff --git a/core/modules/layout_builder/src/Controller/ChooseSectionController.php b/core/modules/layout_builder/src/Controller/ChooseSectionController.php
index 46b969e2f8..bc22d1f004 100644
--- a/core/modules/layout_builder/src/Controller/ChooseSectionController.php
+++ b/core/modules/layout_builder/src/Controller/ChooseSectionController.php
@@ -4,8 +4,10 @@
use Drupal\Core\Ajax\AjaxHelperTrait;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
+use Drupal\Core\Layout\LayoutInterface;
use Drupal\Core\Layout\LayoutPluginManagerInterface;
use Drupal\Core\Plugin\PluginFormInterface;
+use Drupal\Core\Plugin\PluginWithFormsInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Drupal\layout_builder\Context\LayoutBuilderContextTrait;
@@ -52,6 +54,23 @@ public static function create(ContainerInterface $container) {
);
}
+ /**
+ * Determines if the layout provides a configuration form.
+ *
+ * @param \Drupal\Core\Layout\LayoutInterface $layout
+ * The layout plugin.
+ *
+ * @return bool
+ * TRUE if the layout has a configure form, FALSE otherwise.
+ */
+ protected function hasConfigurationForm(LayoutInterface $layout) {
+ if ($layout instanceof PluginWithFormsInterface && $layout->hasFormClass('configure')) {
+ return TRUE;
+ }
+
+ return $layout instanceof PluginFormInterface;
+ }
+
/**
* Choose a layout plugin to add as a section.
*
@@ -78,7 +97,7 @@ public function build(SectionStorageInterface $section_storage, int $delta) {
],
],
'#url' => Url::fromRoute(
- $layout instanceof PluginFormInterface ? 'layout_builder.configure_section' : 'layout_builder.add_section',
+ $this->hasConfigurationForm($layout) ? 'layout_builder.configure_section' : 'layout_builder.add_section',
[
'section_storage_type' => $section_storage->getStorageType(),
'section_storage' => $section_storage->getStorageId(),
diff --git a/core/modules/layout_builder/src/Element/LayoutBuilder.php b/core/modules/layout_builder/src/Element/LayoutBuilder.php
index 451927e540..8234a476ab 100644
--- a/core/modules/layout_builder/src/Element/LayoutBuilder.php
+++ b/core/modules/layout_builder/src/Element/LayoutBuilder.php
@@ -3,8 +3,10 @@
namespace Drupal\layout_builder\Element;
use Drupal\Core\Ajax\AjaxHelperTrait;
+use Drupal\Core\Layout\LayoutInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\PluginFormInterface;
+use Drupal\Core\Plugin\PluginWithFormsInterface;
use Drupal\Core\Render\Attribute\RenderElement;
use Drupal\Core\Render\Element;
use Drupal\Core\Render\Element\RenderElement as RenderElementBase;
@@ -325,6 +327,7 @@ protected function buildAdministrativeSection(SectionStorageInterface $section_s
$build['#attributes']['class'][] = 'layout-builder__layout';
$build['#attributes']['data-layout-builder-highlight-id'] = $this->sectionUpdateHighlightId($delta);
+ $has_configure_form = $this->hasConfigurationForm($layout);
return [
'#type' => 'container',
'#attributes' => [
@@ -354,12 +357,12 @@ protected function buildAdministrativeSection(SectionStorageInterface $section_s
// link, and is only visible when the move block dialog is open.
'section_label' => [
'#markup' => $this->t('<span class="layout-builder__section-label" aria-hidden="true">@section</span>', ['@section' => $section_label]),
- '#access' => !$layout instanceof PluginFormInterface,
+ '#access' => !$has_configure_form,
],
'configure' => [
'#type' => 'link',
'#title' => $this->t('Configure @section', ['@section' => $section_label]),
- '#access' => $layout instanceof PluginFormInterface,
+ '#access' => $has_configure_form,
'#url' => Url::fromRoute('layout_builder.configure_section', [
'section_storage_type' => $storage_type,
'section_storage' => $storage_id,
@@ -379,4 +382,21 @@ protected function buildAdministrativeSection(SectionStorageInterface $section_s
];
}
+ /**
+ * Determines if the layout provides a configuration form.
+ *
+ * @param \Drupal\Core\Layout\LayoutInterface $layout
+ * The layout plugin.
+ *
+ * @return bool
+ * TRUE if the layout has a configure form, FALSE otherwise.
+ */
+ protected function hasConfigurationForm(LayoutInterface $layout) {
+ if ($layout instanceof PluginWithFormsInterface && $layout->hasFormClass('configure')) {
+ return TRUE;
+ }
+
+ return $layout instanceof PluginFormInterface;
+ }
+
}
diff --git a/core/modules/layout_builder/tests/modules/layout_builder_test/layout_builder_test.module b/core/modules/layout_builder/tests/modules/layout_builder_test/layout_builder_test.module
index fa027a6b01..443bbcfdfa 100644
--- a/core/modules/layout_builder/tests/modules/layout_builder_test/layout_builder_test.module
+++ b/core/modules/layout_builder/tests/modules/layout_builder_test/layout_builder_test.module
@@ -13,6 +13,7 @@
use Drupal\Core\Link;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
+use Drupal\layout_builder_test\PluginForm\CustomLayoutForm;
/**
* Implements hook_plugin_filter_TYPE__CONSUMER_alter().
@@ -177,6 +178,27 @@ function layout_builder_test_module_implements_alter(&$implementations, $hook) {
}
}
+/**
+ * Implements hook_layout_alter().
+ */
+function layout_builder_test_layout_alter(&$definitions) {
+ /** @var \Drupal\Core\Layout\LayoutDefinition[] $definitions */
+ $forms['configure'] = CustomLayoutForm::class;
+ $definitions['layout_builder_test_no_form_plugin']->set('forms', $forms);
+ if (isset($definitions['layout_test_plugin'])) {
+ $definitions['layout_test_plugin']->set('forms', $forms);
+ }
+}
+
+/**
+ * Implements hook_preprocess_HOOK() for layout templates.
+ */
+function layout_builder_test_preprocess_layout(&$variables) {
+ if (isset($variables['settings']['custom_element'])) {
+ $variables['content']['main']['custom_element']['#markup'] = $variables['settings']['custom_element'];
+ }
+}
+
/**
* Implements hook_theme().
*/
diff --git a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php
index 631159a8b3..24f0ff05e7 100644
--- a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php
+++ b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php
@@ -458,6 +458,46 @@ public function testPreviewAwareTemplates() {
$assert_session->pageTextNotContains('This is a preview, indeed');
}
+ /**
+ * Tests a layout with a custom form.
+ */
+ public function testCustomForm() {
+ $assert_session = $this->assertSession();
+ $page = $this->getSession()->getPage();
+
+ $this->drupalLogin($this->drupalCreateUser(['configure any layout']));
+
+ LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default')
+ ->enableLayoutBuilder()
+ ->setOverridable()
+ ->save();
+
+ $this->drupalGet('node/1');
+ $page->clickLink('Layout');
+
+ // Test a custom plugin form that is specified by the plugin annotation.
+ $page->clickLink('Add section');
+ $page->clickLink('Layout Builder Test Custom Form Plugin');
+ $page->fillField('layout_settings[custom_element]', 'This is a custom form specified by the plugin');
+ $page->pressButton('Add section');
+ $assert_session->pageTextContains('This is a custom form specified by the plugin');
+
+ // Test a custom plugin form that is altered onto a plugin that has no form.
+ $page->clickLink('Add section');
+ $page->clickLink('Layout Builder Test No Form Plugin');
+ $page->fillField('layout_settings[custom_element]', 'This had no form now it does');
+ $page->pressButton('Add section');
+ $assert_session->pageTextContains('This had no form now it does');
+
+ // Test a custom plugin form that is altered onto a plugin that has an
+ // existing form.
+ $page->clickLink('Add section');
+ $page->clickLink('Layout Builder Test No Form Plugin');
+ $page->fillField('layout_settings[custom_element]', 'This had an existing form now it has more');
+ $page->pressButton('Add section');
+ $assert_session->pageTextContains('This had an existing form now it has more');
+ }
+
/**
* Tests that extra fields work before and after enabling Layout Builder.
*/
diff --git a/core/lib/Drupal/Core/Layout/LayoutDefault.php b/core/lib/Drupal/Core/Layout/LayoutDefault.php
index 607b34a48cd91bf740f3e6eda563a8de8b659467..bb97f8b42ffd61d185ed25eab2d91b12dc91c3d5 100644
--- a/core/lib/Drupal/Core/Layout/LayoutDefault.php
+++ b/core/lib/Drupal/Core/Layout/LayoutDefault.php
@@ -8,6 +8,7 @@
use Drupal\Core\Plugin\ContextAwarePluginTrait;
use Drupal\Core\Plugin\PluginBase;
use Drupal\Core\Plugin\PluginFormInterface;
+use Drupal\Core\Plugin\PluginWithFormsTrait;
use Drupal\Core\Plugin\PreviewAwarePluginInterface;
/**
@@ -17,6 +18,7 @@ class LayoutDefault extends PluginBase implements LayoutInterface, PluginFormInt
use ContextAwarePluginAssignmentTrait;
use ContextAwarePluginTrait;
+ use PluginWithFormsTrait;
/**
* Whether the plugin is being rendered in preview mode.
@@ -126,6 +128,13 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s
$this->configuration['label'] = $form_state->getValue('label');
}
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormClass($operation) {
+ return $this->getPluginDefinition()->get('forms')[$operation] ?? static::class;
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/core/lib/Drupal/Core/Layout/LayoutInterface.php b/core/lib/Drupal/Core/Layout/LayoutInterface.php
index 33858a546d7fc0f2696c408873f4b9bf51cb9b7c..2e62ba85da65ed7029abd5df9571348e9bfcd7fa 100644
--- a/core/lib/Drupal/Core/Layout/LayoutInterface.php
+++ b/core/lib/Drupal/Core/Layout/LayoutInterface.php
@@ -7,11 +7,12 @@
use Drupal\Component\Plugin\ConfigurableInterface;
use Drupal\Component\Plugin\DependentPluginInterface;
use Drupal\Core\Plugin\ContextAwarePluginInterface;
+use Drupal\Core\Plugin\PluginWithFormsInterface;
/**
* Provides an interface for static Layout plugins.
*/
-interface LayoutInterface extends PluginInspectionInterface, DerivativeInspectionInterface, ConfigurableInterface, DependentPluginInterface, ContextAwarePluginInterface {
+interface LayoutInterface extends PluginInspectionInterface, DerivativeInspectionInterface, ConfigurableInterface, DependentPluginInterface, ContextAwarePluginInterface, PluginWithFormsInterface {
/**
* Build a render array for layout with regions.
diff --git a/core/modules/layout_builder/src/Controller/ChooseSectionController.php b/core/modules/layout_builder/src/Controller/ChooseSectionController.php
index 46b969e2f8ba15a75da1be3b0f9a3bb71f30e138..bc22d1f004b7a828155a811758026e7d631a1ed9 100644
--- a/core/modules/layout_builder/src/Controller/ChooseSectionController.php
+++ b/core/modules/layout_builder/src/Controller/ChooseSectionController.php
@@ -4,8 +4,10 @@
use Drupal\Core\Ajax\AjaxHelperTrait;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
+use Drupal\Core\Layout\LayoutInterface;
use Drupal\Core\Layout\LayoutPluginManagerInterface;
use Drupal\Core\Plugin\PluginFormInterface;
+use Drupal\Core\Plugin\PluginWithFormsInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Drupal\layout_builder\Context\LayoutBuilderContextTrait;
@@ -52,6 +54,23 @@ public static function create(ContainerInterface $container) {
);
}
+ /**
+ * Determines if the layout provides a configuration form.
+ *
+ * @param \Drupal\Core\Layout\LayoutInterface $layout
+ * The layout plugin.
+ *
+ * @return bool
+ * TRUE if the layout has a configure form, FALSE otherwise.
+ */
+ protected function hasConfigurationForm(LayoutInterface $layout) {
+ if ($layout instanceof PluginWithFormsInterface && $layout->hasFormClass('configure')) {
+ return TRUE;
+ }
+
+ return $layout instanceof PluginFormInterface;
+ }
+
/**
* Choose a layout plugin to add as a section.
*
@@ -78,7 +97,7 @@ public function build(SectionStorageInterface $section_storage, int $delta) {
],
],
'#url' => Url::fromRoute(
- $layout instanceof PluginFormInterface ? 'layout_builder.configure_section' : 'layout_builder.add_section',
+ $this->hasConfigurationForm($layout) ? 'layout_builder.configure_section' : 'layout_builder.add_section',
[
'section_storage_type' => $section_storage->getStorageType(),
'section_storage' => $section_storage->getStorageId(),
diff --git a/core/modules/layout_builder/src/Element/LayoutBuilder.php b/core/modules/layout_builder/src/Element/LayoutBuilder.php
index 5c91b1e39208a7895c6cb664c1f5e793c8d9522c..e8c83d975fd37c8c80af9f97b0fd47c942f1f615 100644
--- a/core/modules/layout_builder/src/Element/LayoutBuilder.php
+++ b/core/modules/layout_builder/src/Element/LayoutBuilder.php
@@ -3,8 +3,10 @@
namespace Drupal\layout_builder\Element;
use Drupal\Core\Ajax\AjaxHelperTrait;
+use Drupal\Core\Layout\LayoutInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\PluginFormInterface;
+use Drupal\Core\Plugin\PluginWithFormsInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Render\Element\RenderElement;
use Drupal\Core\Url;
@@ -337,6 +339,7 @@ protected function buildAdministrativeSection(SectionStorageInterface $section_s
$build['#attributes']['class'][] = 'layout-builder__layout';
$build['#attributes']['data-layout-builder-highlight-id'] = $this->sectionUpdateHighlightId($delta);
+ $has_configure_form = $this->hasConfigurationForm($layout);
return [
'#type' => 'container',
'#attributes' => [
@@ -366,12 +369,12 @@ protected function buildAdministrativeSection(SectionStorageInterface $section_s
// link, and is only visible when the move block dialog is open.
'section_label' => [
'#markup' => $this->t('<span class="layout-builder__section-label" aria-hidden="true">@section</span>', ['@section' => $section_label]),
- '#access' => !$layout instanceof PluginFormInterface,
+ '#access' => !$has_configure_form,
],
'configure' => [
'#type' => 'link',
'#title' => $this->t('Configure @section', ['@section' => $section_label]),
- '#access' => $layout instanceof PluginFormInterface,
+ '#access' => $has_configure_form,
'#url' => Url::fromRoute('layout_builder.configure_section', [
'section_storage_type' => $storage_type,
'section_storage' => $storage_id,
@@ -391,4 +394,21 @@ protected function buildAdministrativeSection(SectionStorageInterface $section_s
];
}
+ /**
+ * Determines if the layout provides a configuration form.
+ *
+ * @param \Drupal\Core\Layout\LayoutInterface $layout
+ * The layout plugin.
+ *
+ * @return bool
+ * TRUE if the layout has a configure form, FALSE otherwise.
+ */
+ protected function hasConfigurationForm(LayoutInterface $layout) {
+ if ($layout instanceof PluginWithFormsInterface && $layout->hasFormClass('configure')) {
+ return TRUE;
+ }
+
+ return $layout instanceof PluginFormInterface;
+ }
+
}
diff --git a/core/modules/layout_builder/tests/modules/layout_builder_test/layout_builder_test.module b/core/modules/layout_builder/tests/modules/layout_builder_test/layout_builder_test.module
index cd6070f53ff33d4f20ef609513ff335c57b63c60..8b6b00419be68eb7d48072f6e0d223f25f9c400c 100644
--- a/core/modules/layout_builder/tests/modules/layout_builder_test/layout_builder_test.module
+++ b/core/modules/layout_builder/tests/modules/layout_builder_test/layout_builder_test.module
@@ -13,6 +13,7 @@
use Drupal\Core\Link;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
+use Drupal\layout_builder_test\PluginForm\CustomLayoutForm;
/**
* Implements hook_plugin_filter_TYPE__CONSUMER_alter().
@@ -131,3 +132,24 @@ function layout_builder_test_module_implements_alter(&$implementations, $hook) {
] + $implementations;
}
}
+
+/**
+ * Implements hook_layout_alter().
+ */
+function layout_builder_test_layout_alter(&$definitions) {
+ /** @var \Drupal\Core\Layout\LayoutDefinition[] $definitions */
+ $forms['configure'] = CustomLayoutForm::class;
+ $definitions['layout_builder_test_no_form_plugin']->set('forms', $forms);
+ if (isset($definitions['layout_test_plugin'])) {
+ $definitions['layout_test_plugin']->set('forms', $forms);
+ }
+}
+
+/**
+ * Implements hook_preprocess_HOOK() for layout templates.
+ */
+function layout_builder_test_preprocess_layout(&$variables) {
+ if (isset($variables['settings']['custom_element'])) {
+ $variables['content']['main']['custom_element']['#markup'] = $variables['settings']['custom_element'];
+ }
+}
diff --git a/core/modules/layout_builder/tests/modules/layout_builder_test/src/Plugin/Layout/LayoutBuilderTestCustomFormPlugin.php b/core/modules/layout_builder/tests/modules/layout_builder_test/src/Plugin/Layout/LayoutBuilderTestCustomFormPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..059a3eb4d8847695d1cbc02fee806c72b9cf94d6
--- /dev/null
+++ b/core/modules/layout_builder/tests/modules/layout_builder_test/src/Plugin/Layout/LayoutBuilderTestCustomFormPlugin.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Drupal\layout_builder_test\Plugin\Layout;
+
+use Drupal\Core\Layout\LayoutDefault;
+
+/**
+ * @Layout(
+ * id = "layout_builder_test_custom_form_plugin",
+ * label = @Translation("Layout Builder Test Custom Form Plugin"),
+ * regions = {
+ * "main" = {
+ * "label" = @Translation("Main Region")
+ * }
+ * },
+ * forms = {
+ * "configure" = "Drupal\layout_builder_test\PluginForm\CustomLayoutForm",
+ * },
+ * )
+ */
+class LayoutBuilderTestCustomFormPlugin extends LayoutDefault {
+
+}
diff --git a/core/modules/layout_builder/tests/modules/layout_builder_test/src/Plugin/Layout/LayoutBuilderTestNoFormPlugin.php b/core/modules/layout_builder/tests/modules/layout_builder_test/src/Plugin/Layout/LayoutBuilderTestNoFormPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..4cef17f51f56591ab331a465274c6fc8e241adc3
--- /dev/null
+++ b/core/modules/layout_builder/tests/modules/layout_builder_test/src/Plugin/Layout/LayoutBuilderTestNoFormPlugin.php
@@ -0,0 +1,75 @@
+<?php
+
+namespace Drupal\layout_builder_test\Plugin\Layout;
+
+use Drupal\Component\Utility\NestedArray;
+use Drupal\Core\Layout\LayoutInterface;
+use Drupal\Core\Plugin\PluginBase;
+use Drupal\Core\Plugin\PluginWithFormsTrait;
+
+/**
+ * Provides a plugin that does not extend \Drupal\Core\Layout\LayoutDefault.
+ *
+ * @Layout(
+ * id = "layout_builder_test_no_form_plugin",
+ * label = @Translation("Layout Builder Test No Form Plugin"),
+ * regions = {
+ * "main" = {
+ * "label" = @Translation("Main Region")
+ * }
+ * },
+ * )
+ */
+class LayoutBuilderTestNoFormPlugin extends PluginBase implements LayoutInterface {
+
+ use PluginWithFormsTrait;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function build(array $regions) {
+ $build = $regions;
+ $build['#settings'] = $this->getConfiguration();
+ $build['#layout'] = $this->pluginDefinition;
+ $build['#theme'] = $this->pluginDefinition->getThemeHook();
+ return $build;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getConfiguration() {
+ return $this->configuration;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setConfiguration(array $configuration) {
+ $this->configuration = NestedArray::mergeDeep($this->defaultConfiguration(), $configuration);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function defaultConfiguration() {
+ return [
+ 'label' => '',
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function calculateDependencies() {
+ return [];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormClass($operation) {
+ return $this->getPluginDefinition()->get('forms')[$operation] ?? NULL;
+ }
+
+}
diff --git a/core/modules/layout_builder/tests/modules/layout_builder_test/src/PluginForm/CustomLayoutForm.php b/core/modules/layout_builder/tests/modules/layout_builder_test/src/PluginForm/CustomLayoutForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..8499f8bde1faa443b4d8220f50599d92c43291c2
--- /dev/null
+++ b/core/modules/layout_builder/tests/modules/layout_builder_test/src/PluginForm/CustomLayoutForm.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Drupal\layout_builder_test\PluginForm;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\PluginFormBase;
+use Drupal\Core\Plugin\PluginFormInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+
+/**
+ * Provides a custom form for a layout plugin.
+ */
+class CustomLayoutForm extends PluginFormBase {
+
+ use StringTranslationTrait;
+
+ /**
+ * The plugin.
+ *
+ * @var \Drupal\Core\Layout\LayoutInterface
+ */
+ protected $plugin;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+ $form = $this->plugin instanceof PluginFormInterface ? $this->plugin->buildConfigurationForm($form, $form_state) : [];
+ $form['custom_element'] = [
+ '#title' => $this->t('Custom element'),
+ '#type' => 'textfield',
+ '#default_value' => $this->plugin->getConfiguration()['custom_element'] ?? '',
+ ];
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
+ if ($this->plugin instanceof PluginFormInterface) {
+ $this->plugin->submitConfigurationForm($form, $form_state);
+ }
+ $configuration = $this->plugin->getConfiguration();
+ $configuration['custom_element'] = $form_state->getValue('custom_element');
+ $this->plugin->setConfiguration($configuration);
+ }
+
+}
diff --git a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php
index f135ac4cb17ca6155dde107c2a04205677e82a5d..ec692e9b45cd777fdc324a366aaf7a89f6614a68 100644
--- a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php
+++ b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php
@@ -963,6 +963,46 @@ public function testLayoutBuilderChooseBlocksAlter() {
$assert_session->linkExists('Changed');
}
+ /**
+ * Tests a layout with a custom form.
+ */
+ public function testCustomForm() {
+ $assert_session = $this->assertSession();
+ $page = $this->getSession()->getPage();
+
+ $this->drupalLogin($this->drupalCreateUser(['configure any layout']));
+
+ LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default')
+ ->enableLayoutBuilder()
+ ->setOverridable()
+ ->save();
+
+ $this->drupalGet('node/1');
+ $page->clickLink('Layout');
+
+ // Test a custom plugin form that is specified by the plugin annotation.
+ $page->clickLink('Add section');
+ $page->clickLink('Layout Builder Test Custom Form Plugin');
+ $page->fillField('layout_settings[custom_element]', 'This is a custom form specified by the plugin');
+ $page->pressButton('Add section');
+ $assert_session->pageTextContains('This is a custom form specified by the plugin');
+
+ // Test a custom plugin form that is altered onto a plugin that has no form.
+ $page->clickLink('Add section');
+ $page->clickLink('Layout Builder Test No Form Plugin');
+ $page->fillField('layout_settings[custom_element]', 'This had no form now it does');
+ $page->pressButton('Add section');
+ $assert_session->pageTextContains('This had no form now it does');
+
+ // Test a custom plugin form that is altered onto a plugin that has an
+ // existing form.
+ $page->clickLink('Add section');
+ $page->clickLink('Layout Builder Test No Form Plugin');
+ $page->fillField('layout_settings[custom_element]', 'This had an existing form now it has more');
+ $page->pressButton('Add section');
+ $assert_session->pageTextContains('This had an existing form now it has more');
+ }
+
/**
* Tests that extra fields work before and after enabling Layout Builder.
*/
diff --git a/src/ConfigReverter.php b/src/ConfigReverter.php
index 90d046b8bff50f6cac969a433604a6af79de4674..81395829023ae89f07a20b3cea7734ae8786e78f 100644
--- a/src/ConfigReverter.php
+++ b/src/ConfigReverter.php
@@ -2,6 +2,7 @@
namespace Drupal\config_update;
+use Drupal\Component\Utility\Crypt;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\StorageInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
@@ -108,11 +109,12 @@ class ConfigReverter implements ConfigRevertInterface, ConfigDeleteInterface {
// Save it as a new config entity or simple config.
if ($type === 'system.simple') {
- $this->configFactory->getEditable($full_name)->setData($value)->save();
+ $this->configFactory->getEditable($full_name)->setData($value)->set('_core', ['default_config_hash' => Crypt::hashBase64(serialize($value))])->save();
}
else {
$entity_storage = $this->entityManager->getStorage($type);
$entity = $entity_storage->createFromStorageRecord($value);
+ $entity->set('_core', ['default_config_hash' => Crypt::hashBase64(serialize($value))]);
$entity->save();
}
@@ -156,10 +158,9 @@ class ConfigReverter implements ConfigRevertInterface, ConfigDeleteInterface {
// hash (which is part of the _core config key's value).
if ($type === 'system.simple') {
$config = $this->configFactory->getEditable($full_name);
- $core = $config->get('_core');
$config
->setData($value)
- ->set('_core', $core)
+ ->set('_core', ['default_config_hash' => Crypt::hashBase64(serialize($value))])
->save();
}
else {
@@ -168,9 +169,8 @@ class ConfigReverter implements ConfigRevertInterface, ConfigDeleteInterface {
$id = $value[$id_key];
$entity_storage = $this->entityManager->getStorage($type);
$entity = $entity_storage->load($id);
- $core = $entity->get('_core');
$entity = $entity_storage->updateFromStorageRecord($entity, $value);
- $entity->set('_core', $core);
+ $entity->set('_core', ['default_config_hash' => Crypt::hashBase64(serialize($value))]);
$entity->save();
}
diff --git a/src/EntityImportSourceManager.php b/src/EntityImportSourceManager.php
index eec012051537b67e4079a6d0886c9fdb81620fc5..29c8668a97335ab75798f6521d7bb0e480b8cf00 100644
--- a/src/EntityImportSourceManager.php
+++ b/src/EntityImportSourceManager.php
@@ -78,6 +78,7 @@ class EntityImportSourceManager implements EntityImportSourceManagerInterface {
protected function getDefinitions() {
$definitions = [];
+ require_once 'core/modules/content_translation/src/Plugin/migrate/source/I18nQueryTrait.php';
foreach ($this->migrateSourceManager->getDefinitions() as $plugin_id => $definition) {
$interface = 'Drupal\entity_import\Plugin\migrate\source\EntityImportSourceInterface';
diff --git a/src/BookExport.php b/src/BookExport.php
index d130610b..edcf8541 100644
--- a/src/BookExport.php
+++ b/src/BookExport.php
@@ -131,7 +131,6 @@ class BookExport {
*/
protected function bookNodeExport(NodeInterface $node, $children = '') {
$build = $this->viewBuilder->view($node, 'print', NULL);
- unset($build['#theme']);
return [
'#theme' => 'book_node_export_html',
diff --git a/architect.info.yml b/architect.info.yml
index 58e1fc9b3e7d9cc4d143613a0808c98a9d07ec01..d6a66420948fb0e7e9964069ec2ed18745d68053 100644
--- a/architect.info.yml
+++ b/architect.info.yml
@@ -1,7 +1,8 @@
name: Architect
type: theme
description: the ARCHITECT Theme - A DESIGN SAVVY THEME USING UIKITTY.
-core: 8.x
+# core: 8.x
+core_version_requirement: ^8.8 || ^9
base theme: uikitty
libraries:
- architect/default
diff --git a/uikitty.info.yml b/uikitty.info.yml
index 0a44d98b8e56bf3a5065409e852d868dc8bd739c..df7117253a9b3e089023d81402ab0224b2ed264a 100644
--- a/uikitty.info.yml
+++ b/uikitty.info.yml
@@ -1,7 +1,8 @@
name: uikitty
type: theme
description: A building block theme using uikit awesomeness.
-core: 8.x
+# core: 8.x
+core_version_requirement: ^8.8 || ^9
base theme: classy
libraries:
- uikitty/global
@@ -22,4 +23,4 @@ regions:
offcanvas: 'Off-canvas'
ckeditor_stylesheets:
- - uikit/css/uikit.almost-flat.min.css
\ No newline at end of file
+ - uikit/css/uikit.almost-flat.min.css
diff --git a/uikitty.theme b/uikitty.theme
index 15609cc19631ad86d47683e8a473f3542bed957d..aa61fd2c233a61f742a7e586e5e237da8fd55025 100644
--- a/uikitty.theme
+++ b/uikitty.theme
@@ -36,5 +36,5 @@ function uikitty_theme_suggestions_menu_alter(array &$suggestions, array $variab
function uikitty_preprocess_html(&$variables) {
$current_path = \Drupal::service('path.current')->getPath();
- $variables['current_path'] = \Drupal::service('path.alias_manager')->getAliasByPath($current_path);
-}
\ No newline at end of file
+ $variables['current_path'] = \Drupal::service('path_alias.manager')->getAliasByPath($current_path);
+}
diff --git a/core/lib/Drupal/Core/Database/Schema.php b/core/lib/Drupal/Core/Database/Schema.php
index 9530c8fbf8..4ac5503e69 100644
--- a/core/lib/Drupal/Core/Database/Schema.php
+++ b/core/lib/Drupal/Core/Database/Schema.php
@@ -167,8 +167,8 @@ protected function buildTableNameCondition($table_name, $operator = '=', $add_pr
* @return bool
* TRUE if the given table exists, otherwise FALSE.
*/
- public function tableExists($table, bool $add_prefix = TRUE) {
- $condition = $this->buildTableNameCondition($table, '=', $add_prefix);
+ public function tableExists($table) {
+ $condition = $this->buildTableNameCondition($table);
$condition->compile($this->connection, $this);
// Normally, we would heartily discourage the use of string
// concatenation for conditionals like this however, we
diff --git a/content_lock.module b/content_lock.module
index 0bae073d352baebf7cb934e1243c0ad87ab61703..e11bf199b891b1019566a06104c0529054d11103 100644
--- a/content_lock.module
+++ b/content_lock.module
@@ -95,16 +95,17 @@ function content_lock_form_alter(&$form, FormStateInterface $form_state, $form_i
if ($lock_service->isJsLock($entity_type)) {
$form['#attached']['library'][] = 'content_lock/drupal.content_lock.lock_form';
+ $args = [
+ 'entity' => $entity->id(),
+ 'langcode' => $entity->language()->getId(),
+ 'form_op' => $form_op,
+ ];
$form['#attached']['drupalSettings']['content_lock'] = [
Html::cleanCssIdentifier($form_id) => [
- 'lockUrl' => Url::fromRoute('content_lock.create_lock.' . $entity_type,
- [
- 'entity' => $entity->id(),
- 'langcode' => $entity->language()->getId(),
- 'form_op' => $form_op,
- ],
- ['query' => ['destination' => Drupal::request()->getRequestUri()]]
- )->toString(),
+ 'lockUrl' => Url::fromRoute('content_lock.create_lock.' . $entity_type, $args, [
+ 'query' => ['destination' => Drupal::request()->getRequestUri()],
+ ])->toString(),
+ 'releaseUrl' => Url::fromRoute('content_lock.release_lock.' . $entity_type, $args)->toString(),
],
];
diff --git a/js/content_lock_form.js b/js/content_lock_form.js
index 2661f311e9c689cfc7bc303edd43b96c53eec6ca..58827cb7302130a213cabd1f234501570dc99363 100644
--- a/js/content_lock_form.js
+++ b/js/content_lock_form.js
@@ -73,5 +73,16 @@
});
}
};
+
+ var onBeforeUnLoadEvent = false;
+
+ window.onunload = window.onbeforeunload= function() {
+ if (!onBeforeUnLoadEvent) {
+ onBeforeUnLoadEvent = true;
+ if (typeof navigator.sendBeacon === 'function') {
+ navigator.sendBeacon(settings.releaseUrl);
+ }
+ }
+ };
};
})(jQuery, Drupal, once);
diff --git a/src/ContentLock/ContentLock.php b/src/ContentLock/ContentLock.php
index 5d6f693fc4526e0c93f8a81a7c1063ec39e69872..dea173950eda995e41d599f03d39ca02be475ca4 100644
--- a/src/ContentLock/ContentLock.php
+++ b/src/ContentLock/ContentLock.php
@@ -344,6 +344,7 @@ class ContentLock implements ContentLockInterface {
*/
public function locking($entity_id, $langcode, $form_op, $uid, $entity_type = 'node', $quiet = FALSE, $destination = NULL) {
$translation_lock = $this->isTranslationLockEnabled($entity_type);
+ $js_lock = $this->isJsLock($entity_type);
if (!$translation_lock) {
$langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED;
}
@@ -371,12 +372,20 @@ class ContentLock implements ContentLockInterface {
if ($this->verbose() && !$quiet) {
if ($translation_lock) {
- $this->messenger->addStatus($this->t('This content translation is now locked against simultaneous editing. This content translation will remain locked if you navigate away from this page without saving or unlocking it.'));
+ $message = 'This content translation is now locked against simultaneous editing.';
+ if (!$js_lock) {
+ $message .= ' This content translation will remain locked if you navigate away from this page without saving or unlocking it.';
+ }
}
else {
- $this->messenger->addStatus($this->t('This content is now locked against simultaneous editing. This content will remain locked if you navigate away from this page without saving or unlocking it.'));
+ $message = 'This content is now locked against simultaneous editing.';
+ if (!$js_lock) {
+ $message .= ' This content will remain locked if you navigate away from this page without saving or unlocking it.';
+ }
}
+ $this->messenger->addStatus($this->t($message));
}
+
// Post locking hook.
$this->moduleHandler->invokeAll('content_lock_locked', [
$entity_id,
@@ -424,11 +433,18 @@ class ContentLock implements ContentLockInterface {
// Locked by current user.
if ($this->verbose() && !$quiet) {
if ($translation_lock) {
- $this->messenger->addStatus($this->t('This content translation is now locked by you against simultaneous editing. This content translation will remain locked if you navigate away from this page without saving or unlocking it.'));
+ $message = 'This content translation is now locked by you against simultaneous editing.';
+ if (!$js_lock) {
+ $message .= ' This content translation will remain locked if you navigate away from this page without saving or unlocking it.';
+ }
}
else {
- $this->messenger->addStatus($this->t('This content is now locked by you against simultaneous editing. This content will remain locked if you navigate away from this page without saving or unlocking it.'));
+ $message = 'This content is now locked by you against simultaneous editing.';
+ if (!$js_lock) {
+ $message .= ' This content will remain locked if you navigate away from this page without saving or unlocking it.';
+ }
}
+ $this->messenger->addStatus($this->t($message));
}
// Send success flag.
diff --git a/src/Controller/ContentLockController.php b/src/Controller/ContentLockController.php
index b0270fb2242492a1f0c62c8070173f9ed7e99298..5d214cac26d4fda3edbfe33366d536a484d43379 100644
--- a/src/Controller/ContentLockController.php
+++ b/src/Controller/ContentLockController.php
@@ -5,7 +5,6 @@ namespace Drupal\content_lock\Controller;
use Drupal\content_lock\Ajax\LockFormCommand;
use Drupal\content_lock\ContentLock\ContentLockInterface;
use Drupal\Core\Ajax\AjaxResponse;
-use Drupal\Core\Ajax\AppendCommand;
use Drupal\Core\Ajax\PrependCommand;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\ContentEntityInterface;
@@ -78,19 +77,31 @@ class ContentLockController extends ControllerBase {
// Render status messages from locking service.
$response->addCommand(new PrependCommand('', ['#type' => 'status_messages']));
-
- if ($lock) {
- $language = $this->languageManager()->getLanguage($langcode);
- $url = $entity->toUrl('canonical', ['language' => $language]);
- $unlock_button = $this->lockService->unlockButton($entity->getEntityTypeId(), $entity->id(), $langcode, $form_op, $url->toString());
- $response->addCommand(new AppendCommand('.content-lock-actions.form-actions', $unlock_button));
- }
}
$response->addCommand(new LockFormCommand($lockable, $lock));
return $response;
}
+ /**
+ * Custom callback for the release lock route.
+ *
+ * @param \Symfony\Component\HttpFoundation\Request $request
+ * The current request.
+ * @param \Drupal\Core\Entity\ContentEntityInterface $entity
+ * The locked entity.
+ * @param string $langcode
+ * The langcode.
+ * @param string $form_op
+ * The form op.
+ *
+ * @see \Drupal\content_lock\Routing\ContentLockRoutes::routes()
+ */
+ public function releaseCall(Request $request, ContentEntityInterface $entity, $langcode, $form_op) {
+ $this->lockService->release($entity->id(), $entity->language()->getId(), $form_op, $this->currentUser()->id(), $entity->getEntityTypeId());
+ return [];
+ }
+
/**
* Custom access checker for the create lock requirements route.
*
diff --git a/src/Form/ContentLockSettingsForm.php b/src/Form/ContentLockSettingsForm.php
index c5baea93f91a5321599cb13ee62bab0ac755a659..4f8e372b80d7ff213c2ab2a95c52a294949f2b52 100644
--- a/src/Form/ContentLockSettingsForm.php
+++ b/src/Form/ContentLockSettingsForm.php
@@ -184,9 +184,9 @@ class ContentLockSettingsForm extends ConfigFormBase {
$form['entities'][$definition->id()]['settings']['js_lock'] = [
'#type' => 'checkbox',
- '#title' => $this->t('Lock form using JS.'),
- '#default_value' => in_array($definition->id(), $config->get('types_js_lock') ?: []),
- '#description' => $this->t('Activating this options activates the lock when the user is on the form. This helps if modules interacting with form without a user interacting with the form, like the prefetch_cache module.'),
+ '#title' => $this->t('Lock and release form using JS.'),
+ '#default_value' => in_array($definition->id(), $config->get('types_js_lock')?: []),
+ '#description' => $this->t('Activating this options activates the lock when the user is on the form. This helps if modules interacting with form without a user interacting with the form, like the prefetch_cache module. The form is automatically released when navigating away from the page.'),
];
if (!empty($definition->getHandlerClasses()['form'])) {
diff --git a/src/Routing/ContentLockRoutes.php b/src/Routing/ContentLockRoutes.php
index a0004621619ce7f11f31bd642cf1402847fb94df..289bdff22c16b99a05ad310b3ac34dae69978b08 100644
--- a/src/Routing/ContentLockRoutes.php
+++ b/src/Routing/ContentLockRoutes.php
@@ -76,6 +76,22 @@ class ContentLockRoutes implements ContainerInjectionInterface {
],
]
);
+ $routes['content_lock.release_lock.' . $definition->id()] = new Route(
+ '/admin/lock/release/' . $definition->id() . '/{entity}/{langcode}/{form_op}',
+ [
+ '_controller' => '\Drupal\content_lock\Controller\ContentLockController::releaseCall',
+ ],
+ [
+ '_custom_access' => '\Drupal\content_lock\Controller\ContentLockController::access',
+ ],
+ [
+ 'parameters' => [
+ 'entity' => [
+ 'type' => 'entity:' . $definition->id(),
+ ],
+ ],
+ ]
+ );
}
}
return $routes;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
diff --git a/src/Plugin/Field/FieldWidget/InlineEntityFormSimple.php b/src/Plugin/Field/FieldWidget/InlineEntityFormSimple.php
index 51e0acca397a35054ce08568a32d1ca76cdc8912..840478e2a98964b70b28f7f61d2fdceda4a8ffea 100644
--- a/src/Plugin/Field/FieldWidget/InlineEntityFormSimple.php
+++ b/src/Plugin/Field/FieldWidget/InlineEntityFormSimple.php
@@ -134,12 +134,12 @@ class InlineEntityFormSimple extends InlineEntityFormBase {
$submitted_values = $form_state->getValue($parents);
$values = [];
foreach ($items as $delta => $value) {
- if ($element = NestedArray::getValue(
- $form,
- [$field_name, 'widget', $delta]
- )) {
+ if (
+ ($element = NestedArray::getValue($form, [$field_name, 'widget', $delta]))
/** @var \Drupal\Core\Entity\EntityInterface $entity */
- $entity = $element['inline_entity_form']['#entity'];
+ && ($entity = $element['inline_entity_form']['#entity'] ?? NULL)
+ ) {
+ // @todo Can this be unset? If yes, can the '0' fallback clash?
$weight = $submitted_values[$delta]['_weight'] ?? 0;
$values[$weight] = ['entity' => $entity];
}
diff --git a/fakeobjects.install b/fakeobjects.install
index c664d41134301a481031235484bb759b7b5beae1..8f6925ce601bef811ef46598251c192c9e899eae 100644
--- a/fakeobjects.install
+++ b/fakeobjects.install
@@ -12,7 +12,7 @@ function fakeobjects_requirements($phase) {
$requirements = [];
if ($phase == 'install' || $phase == 'runtime') {
- $plugin_detected = file_exists(DRUPAL_ROOT . '/libraries/fakeobjects/plugin.js');
+ $plugin_detected = file_exists(DRUPAL_ROOT . '/libraries/ckeditor.fakeobjects/plugin.js');
if ($plugin_detected) {
$requirements['fakeobjects'] = [
@@ -26,7 +26,7 @@ function fakeobjects_requirements($phase) {
'title' => t('FakeObjects'),
'value' => t('Plugin not detected'),
'severity' => REQUIREMENT_ERROR,
- 'description' => t('Before you can use the FakeObjects module, you need to download the plugin from ckeditor.com and place it in /libraries/fakeobjects. Check the README.txt for more information. <a href=":plugin_url">Get the plugin here</a>.', [':plugin_url' => 'http://ckeditor.com/addon/fakeobjects']),
+ 'description' => t('Before you can use the FakeObjects module, you need to download the plugin from ckeditor.com and place it in /libraries/ckeditor.fakeobjects. Check the README.txt for more information. <a href=":plugin_url">Get the plugin here</a>.', [':plugin_url' => 'http://ckeditor.com/addon/fakeobjects']),
];
}
}
diff --git a/src/Plugin/CKEditorPlugin/FakeObjects.php b/src/Plugin/CKEditorPlugin/FakeObjects.php
index e405394fdc2a59be87974b0592f3fa38672b72d0..dd222dc702a9c22f635febf777a33cfc869ecbeb 100644
--- a/src/Plugin/CKEditorPlugin/FakeObjects.php
+++ b/src/Plugin/CKEditorPlugin/FakeObjects.php
@@ -19,7 +19,7 @@ class FakeObjects extends CKEditorPluginBase {
* {@inheritdoc}
*/
public function getFile() {
- return 'libraries/fakeobjects/plugin.js';
+ return 'libraries/ckeditor.fakeobjects/plugin.js';
}
/**
diff --git a/src/ConfigImporterExporter.php b/src/ConfigImporterExporter.php
index 1c0196151a0d8f0d0390e4043b27a5d0b5f7e9ca..88dc5cc47600e025e7c6a825869f92ae4f2a3e4c 100644
--- a/src/ConfigImporterExporter.php
+++ b/src/ConfigImporterExporter.php
@@ -230,7 +230,7 @@ class ConfigImporterExporter {
$written_files = [];
if ($file_names) {
- $data = $config->get();
+ $data = $config->getRawData();
$config_name = $config->getName();
unset($data['_core']);
if ($entity_type_id = $this->configManager->getEntityTypeIdByName($config_name)) {
diff --git a/src/EventSubscriber/ConfigDevelAutoExportSubscriber.php b/src/EventSubscriber/ConfigDevelAutoExportSubscriber.php
index 44dc76ecbb3de80ed6132171f9876151491a4268..406eb508aa08a00b9ddf0a399874c71e4748d7ce 100644
--- a/src/EventSubscriber/ConfigDevelAutoExportSubscriber.php
+++ b/src/EventSubscriber/ConfigDevelAutoExportSubscriber.php
@@ -98,7 +98,7 @@ class ConfigDevelAutoExportSubscriber extends ConfigDevelSubscriberBase implemen
public function writeBackConfig(Config $config, array $file_names) {
// TODO: use the config_devel.importer_exporter service.
if ($file_names) {
- $data = $config->get();
+ $data = $config->getRawData();
$config_name = $config->getName();
unset($data['_core']);
if ($entity_type_id = $this->configManager->getEntityTypeIdByName($config_name)) {
diff --git a/core/modules/book/src/Plugin/migrate/destination/Book.php b/core/modules/book/src/Plugin/migrate/destination/Book.php
index dcc5056c89af907650b90e5b02d5bb2df8531456..55496aed7fc0693a956bbfa1634a19ed2b200132 100644
--- a/core/modules/book/src/Plugin/migrate/destination/Book.php
+++ b/core/modules/book/src/Plugin/migrate/destination/Book.php
@@ -3,6 +3,7 @@
namespace Drupal\book\Plugin\migrate\destination;
use Drupal\Core\Entity\EntityInterface;
+use Drupal\menu_link_content\Entity\MenuLinkContent;
use Drupal\migrate\Plugin\migrate\destination\EntityContentBase;
use Drupal\migrate\Row;
@@ -34,6 +35,12 @@ protected function updateEntity(EntityInterface $entity, Row $row) {
else {
$entity->book = $row->getDestinationProperty('book');
}
+ if (($mid = $entity->book['pid']) && ($menuLink = MenuLinkContent::load($mid)) && $url = $menuLink->getUrlObject()) {
+ $parameters = $url->getRouteParameters();
+ if (isset($parameters['node'])) {
+ $entity->book['pid'] = $parameters['node'];
+ }
+ }
return parent::updateEntity($entity, $row);
}
diff --git a/core/modules/menu_link_content/src/Plugin/migrate/source/MenuLink.php b/core/modules/menu_link_content/src/Plugin/migrate/source/MenuLink.php
index 1b186a6e04a18749d3ccb7e09194364c5e485c44..f28ab3ec2f46c2df995ea588f0b2b316b3380ef2 100644
--- a/core/modules/menu_link_content/src/Plugin/migrate/source/MenuLink.php
+++ b/core/modules/menu_link_content/src/Plugin/migrate/source/MenuLink.php
@@ -23,7 +23,7 @@ public function query() {
$query = $this->select('menu_links', 'ml')
->fields('ml');
$and = $query->andConditionGroup()
- ->condition('ml.module', 'menu')
+ ->condition('ml.module', ['menu', 'book'], 'IN')
->condition('ml.router_path', ['admin/build/menu-customize/%', 'admin/structure/menu/manage/%'], 'NOT IN');
$condition = $query->orConditionGroup()
->condition('ml.customized', 1)
diff --git a/ldap_authentication/ldap_authentication.module b/ldap_authentication/ldap_authentication.module
index 07ac1740eac87f464f5801babcbbda94a07102bd..3fb89b4fec4550c70d04fde73aa6f7587c5f382b 100644
--- a/ldap_authentication/ldap_authentication.module
+++ b/ldap_authentication/ldap_authentication.module
@@ -169,6 +169,11 @@ function ldap_authentication_form_user_form_alter(&$form, FormStateInterface $fo
*/
function ldap_authentication_show_password_field($user = NULL): bool {
+ $config = \Drupal::config('ldap_authentication.settings');
+ if ($config->get('authenticationMode') === 'exclusive') {
+ return FALSE;
+ }
+
if (!$user) {
$user = \Drupal::currentUser();
}
@@ -182,8 +187,7 @@ function ldap_authentication_show_password_field($user = NULL): bool {
$authmap = \Drupal::service('externalauth.authmap');
$authname = $authmap->get($user->id(), 'ldap_user');
if ($authname) {
- $password_option = \Drupal::config('ldap_authentication.settings')
- ->get('passwordOption');
+ $password_option = $config->get('passwordOption');
return $password_option === 'allow';
}
This diff is collapsed.
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment