diff --git a/core/modules/field_layout/src/Display/EntityDisplayWithLayoutInterface.php b/core/modules/field_layout/src/Display/EntityDisplayWithLayoutInterface.php index 0ff9070..3623515 100644 --- a/core/modules/field_layout/src/Display/EntityDisplayWithLayoutInterface.php +++ b/core/modules/field_layout/src/Display/EntityDisplayWithLayoutInterface.php @@ -3,6 +3,7 @@ namespace Drupal\field_layout\Display; use Drupal\Core\Entity\Display\EntityDisplayInterface; +use Drupal\Core\Layout\LayoutInterface; /** * Provides a common interface for entity displays that have layout. @@ -43,7 +44,17 @@ public function getLayoutSettings(); * * @return $this */ - public function setLayout($layout_id, array $layout_settings = []); + public function setLayoutId($layout_id, array $layout_settings = []); + + /** + * Sets the layout for this display. + * + * @param \Drupal\Core\Layout\LayoutInterface $layout + * A layout. + * + * @return $this + */ + public function setLayout(LayoutInterface $layout); /** * Gets the layout plugin for this display. diff --git a/core/modules/field_layout/src/Entity/FieldLayoutEntityDisplayTrait.php b/core/modules/field_layout/src/Entity/FieldLayoutEntityDisplayTrait.php index 9cbf216..d92a191 100644 --- a/core/modules/field_layout/src/Entity/FieldLayoutEntityDisplayTrait.php +++ b/core/modules/field_layout/src/Entity/FieldLayoutEntityDisplayTrait.php @@ -3,6 +3,7 @@ namespace Drupal\field_layout\Entity; use Drupal\Core\Entity\EntityStorageInterface; +use Drupal\Core\Layout\LayoutInterface; /** * Provides shared code for entity displays. @@ -37,15 +38,23 @@ public function getLayoutSettings() { } /** - * Implements \Drupal\field_layout\Display\EntityDisplayWithLayoutInterface::setLayout(). + * Implements \Drupal\field_layout\Display\EntityDisplayWithLayoutInterface::setLayoutId(). */ - public function setLayout($layout_id, array $layout_settings = []) { + public function setLayoutId($layout_id, array $layout_settings = []) { $this->setThirdPartySetting('field_layout', 'id', $layout_id); $this->setThirdPartySetting('field_layout', 'settings', $layout_settings); return $this; } /** + * Implements \Drupal\field_layout\Display\EntityDisplayWithLayoutInterface::setLayout(). + */ + public function setLayout(LayoutInterface $layout) { + $this->setLayoutId($layout->getPluginId(), $layout->getConfiguration()); + return $this; + } + + /** * Implements \Drupal\field_layout\Display\EntityDisplayWithLayoutInterface::getLayoutPlugin(). */ public function getLayoutPlugin() { @@ -57,10 +66,41 @@ public function getLayoutPlugin() { */ public function preSave(EntityStorageInterface $storage) { if (!$this->getLayoutId()) { - $this->setLayout('onecol'); + $this->setLayoutId('onecol'); + } + else { + $this->setLayout($this->getLayoutPlugin()); } parent::preSave($storage); } + /** + * Overrides \Drupal\Core\Entity\EntityDisplayBase::calculateDependencies(). + * + * @todo Remove once https://www.drupal.org/node/2821191 is resolved. + * + * @see \Drupal\Core\Plugin\PluginDependencyTrait::calculatePluginDependencies() + */ + public function calculateDependencies() { + parent::calculateDependencies(); + + // This can be called during uninstallation, so check for a valid ID first. + if ($this->getLayoutId()) { + /** @var \Drupal\Core\Layout\LayoutInterface $layout */ + $layout = $this->getLayoutPlugin(); + $definition = $layout->getPluginDefinition(); + + if (!in_array($definition->getProvider(), ['core', 'component'])) { + $this->addDependency('module', $definition->getProvider()); + } + if ($config_dependencies = $definition->getConfigDependencies()) { + $this->addDependencies($config_dependencies); + } + if ($layout_dependencies = $layout->calculateDependencies()) { + $this->addDependencies($layout_dependencies); + } + } + } + } diff --git a/core/modules/field_layout/src/Form/FieldLayoutEntityDisplayFormTrait.php b/core/modules/field_layout/src/Form/FieldLayoutEntityDisplayFormTrait.php index e401ce8..6cfca76 100644 --- a/core/modules/field_layout/src/Form/FieldLayoutEntityDisplayFormTrait.php +++ b/core/modules/field_layout/src/Form/FieldLayoutEntityDisplayFormTrait.php @@ -190,7 +190,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { protected function updateLayout(EntityDisplayWithLayoutInterface $entity, FormStateInterface $form_state) { $old_layout = $entity->getLayoutId(); $new_layout = $form_state->getValue('field_layout'); - $entity->setLayout($new_layout, $this->getLayoutPlugin($entity, $form_state)->getConfiguration()); + $entity->setLayout($this->getLayoutPlugin($entity, $form_state)); return $old_layout !== $new_layout; } diff --git a/core/modules/field_layout/tests/modules/field_layout_test/config/schema/field_layout_test.schema.yml b/core/modules/field_layout/tests/modules/field_layout_test/config/schema/field_layout_test.schema.yml new file mode 100644 index 0000000..c397e73 --- /dev/null +++ b/core/modules/field_layout/tests/modules/field_layout_test/config/schema/field_layout_test.schema.yml @@ -0,0 +1,7 @@ +layout_plugin.settings.field_layout_test_plugin: + type: layout_plugin.settings + label: 'Layout test plugin settings' + mapping: + setting_1: + type: string + label: 'Setting 1' diff --git a/core/modules/field_layout/tests/modules/field_layout_test/src/Plugin/Layout/FieldLayoutTestPlugin.php b/core/modules/field_layout/tests/modules/field_layout_test/src/Plugin/Layout/FieldLayoutTestPlugin.php new file mode 100644 index 0000000..ae49263 --- /dev/null +++ b/core/modules/field_layout/tests/modules/field_layout_test/src/Plugin/Layout/FieldLayoutTestPlugin.php @@ -0,0 +1,48 @@ + 'Default', + ]; + } + + /** + * {@inheritdoc} + */ + public function calculateDependencies() { + $dependencies = parent::calculateDependencies(); + $dependencies['module'][] = 'dependency_from_calculateDependencies'; + return $dependencies; + } + +} diff --git a/core/modules/field_layout/tests/src/Kernel/FieldLayoutEntityDisplayTest.php b/core/modules/field_layout/tests/src/Kernel/FieldLayoutEntityDisplayTest.php new file mode 100644 index 0000000..5405214 --- /dev/null +++ b/core/modules/field_layout/tests/src/Kernel/FieldLayoutEntityDisplayTest.php @@ -0,0 +1,196 @@ + 'entity_test', + 'bundle' => 'entity_test', + 'mode' => 'default', + 'status' => TRUE, + 'content' => [ + 'foo' => ['type' => 'visible'], + 'bar' => ['type' => 'hidden'], + 'name' => ['type' => 'hidden', 'region' => 'content'], + ], + ]); + + $expected = [ + 'langcode' => 'en', + 'status' => TRUE, + 'dependencies' => [], + 'id' => 'entity_test.entity_test.default', + 'targetEntityType' => 'entity_test', + 'bundle' => 'entity_test', + 'mode' => 'default', + 'content' => [ + 'foo' => [ + 'type' => 'visible', + ], + 'bar' => [ + 'type' => 'hidden', + ], + ], + 'hidden' => [], + ]; + $this->assertEntityValues($expected, $entity_display); + + $entity_display->save(); + + $expected = [ + 'langcode' => 'en', + 'status' => TRUE, + 'dependencies' => [ + 'module' => [ + 'entity_test', + 'field_layout', + ], + ], + 'third_party_settings' => [ + 'field_layout' => [ + 'id' => 'onecol', + 'settings' => [], + ], + 'entity_test' => [ + 'foo' => 'bar', + ], + ], + 'id' => 'entity_test.entity_test.default', + 'targetEntityType' => 'entity_test', + 'bundle' => 'entity_test', + 'mode' => 'default', + 'content' => [ + 'foo' => [ + 'type' => 'visible', + 'region' => 'content', + ], + ], + 'hidden' => [ + 'bar' => TRUE, + ], + ]; + $this->assertEntityValues($expected, $entity_display); + + $entity_display->setLayoutId('field_layout_test_plugin'); + $entity_display->save(); + + $expected = [ + 'langcode' => 'en', + 'status' => TRUE, + 'dependencies' => [ + 'module' => [ + 'dependency_from_annotation', + 'dependency_from_calculateDependencies', + 'entity_test', + 'field_layout', + 'field_layout_test', + ], + ], + 'third_party_settings' => [ + 'field_layout' => [ + 'id' => 'field_layout_test_plugin', + 'settings' => [ + 'setting_1' => 'Default', + ], + ], + 'entity_test' => [ + 'foo' => 'bar', + ], + ], + 'id' => 'entity_test.entity_test.default', + 'targetEntityType' => 'entity_test', + 'bundle' => 'entity_test', + 'mode' => 'default', + 'content' => [ + 'foo' => [ + 'type' => 'visible', + 'region' => 'content', + ], + ], + 'hidden' => [ + 'bar' => TRUE, + ], + ]; + + $this->assertEntityValues($expected, $entity_display); + + $entity_display->setLayoutId('field_layout_test_plugin', ['setting_1' => 'foobar']); + $entity_display->save(); + + $expected = [ + 'langcode' => 'en', + 'status' => TRUE, + 'dependencies' => [ + 'module' => [ + 'dependency_from_annotation', + 'dependency_from_calculateDependencies', + 'entity_test', + 'field_layout', + 'field_layout_test', + ], + ], + 'third_party_settings' => [ + 'field_layout' => [ + 'id' => 'field_layout_test_plugin', + 'settings' => [ + 'setting_1' => 'foobar', + ], + ], + 'entity_test' => [ + 'foo' => 'bar', + ], + ], + 'id' => 'entity_test.entity_test.default', + 'targetEntityType' => 'entity_test', + 'bundle' => 'entity_test', + 'mode' => 'default', + 'content' => [ + 'foo' => [ + 'type' => 'visible', + 'region' => 'content', + ], + ], + 'hidden' => [ + 'bar' => TRUE, + ], + ]; + + $this->assertEntityValues($expected, $entity_display); + } + + /** + * Asserts than an entity has the correct values. + * + * @param mixed $expected + * @param \Drupal\Core\Entity\EntityInterface $entity + * @param string $message + */ + public static function assertEntityValues($expected, EntityInterface $entity, $message = '') { + $values = $entity->toArray(); + + static::assertArrayHasKey('uuid', $values); + unset($values['uuid']); + + static::assertSame($expected, $values, $message); + } + +}