diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php index 6c2a700..e4804ca 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php @@ -369,20 +369,21 @@ public function __sleep() { $keys_to_unset = []; if ($this instanceof EntityWithPluginCollectionInterface) { $vars = get_object_vars($this); - // Any changes to the plugin configuration must be saved to the entity's - // copy as well, then unset the plugin collection. foreach ($this->getPluginCollections() as $plugin_config_key => $plugin_collection) { + // Save any changes to the plugin configuration to the entity. $this->set($plugin_config_key, $plugin_collection->getConfiguration()); - foreach ($vars as $key => $value) { - if ($plugin_collection === $value) { - $keys_to_unset[] = $key; - } - } + // If the plugin collections are stored as properties on the entity, + // mark them to be unset. + $keys_to_unset += array_filter($vars, function ($value) use ($plugin_collection) { + return $plugin_collection === $value; + }); } } + $vars = parent::__sleep(); - foreach ($keys_to_unset as $key) { - unset($vars[array_search($key, $vars)]); + + if (!empty($keys_to_unset)) { + $vars = array_diff($vars, array_keys($keys_to_unset)); } return $vars; } diff --git a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php index feca9e9..489ec67 100644 --- a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php @@ -7,8 +7,11 @@ namespace Drupal\Tests\Core\Config\Entity; +use Drupal\Component\Plugin\PluginManagerInterface; use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\Language\Language; +use Drupal\Core\Plugin\DefaultLazyPluginCollection; +use Drupal\Tests\Core\Config\Entity\Fixtures\ConfigEntityBaseWithPluginCollections; use Drupal\Tests\Core\Plugin\Fixtures\TestConfigurablePlugin; use Drupal\Tests\UnitTestCase; @@ -308,6 +311,37 @@ public function testCalculateDependenciesWithThirdPartySettings() { } /** + * @covers ::__sleep + */ + public function testSleepWithPluginCollections() { + $instance_id = 'the_instance_id'; + $instance = new TestConfigurablePlugin([], $instance_id, []); + + $plugin_manager = $this->prophesize(PluginManagerInterface::class); + $plugin_manager->createInstance($instance_id, ['id' => $instance_id])->willReturn($instance); + + $entity_values = ['the_plugin_collection_config' => [$instance_id => ['foo' => 'original_value']]]; + $entity = new TestConfigEntityWithPluginCollections($entity_values, $this->entityTypeId); + $entity->setPluginManager($plugin_manager->reveal()); + + // After creating the entity, change the plugin configuration. + $instance->setConfiguration(['foo' => 'new_value']); + + // After changing the plugin configuration, the entity still has the + // original value. + $expected_plugin_config = [$instance_id => ['foo' => 'original_value']]; + $this->assertSame($expected_plugin_config, $entity->get('the_plugin_collection_config')); + + $entity_keys = array_values($entity->__sleep()); + // Ensure the plugin collection is not stored. + $this->assertFalse(in_array('pluginCollection', $entity_keys)); + + $expected_plugin_config = [$instance_id => ['foo' => 'new_value']]; + // Ensure the updated values are stored in the entity. + $this->assertSame($expected_plugin_config, $entity->get('the_plugin_collection_config')); + } + + /** * @covers ::setOriginalId * @covers ::getOriginalId */ @@ -579,3 +613,20 @@ public function testThirdPartySettings() { } } + +class TestConfigEntityWithPluginCollections extends ConfigEntityBaseWithPluginCollections { + + protected $pluginCollection; + + public function setPluginManager(PluginManagerInterface $plugin_manager) { + $this->pluginCollection = new DefaultLazyPluginCollection($plugin_manager, ['the_instance_id' => ['id' => 'the_instance_id']]); + } + + /** + * {@inheritdoc} + */ + public function getPluginCollections() { + return ['the_plugin_collection_config' => $this->pluginCollection]; + } + +}