diff options
14 files changed, 385 insertions, 245 deletions
diff --git a/core/.phpstan-baseline.php b/core/.phpstan-baseline.php index 3598385a373c..e52a99b406fc 100644 --- a/core/.phpstan-baseline.php +++ b/core/.phpstan-baseline.php @@ -1238,12 +1238,6 @@ $ignoreErrors[] = [ 'path' => __DIR__ . '/lib/Drupal/Core/Action/ActionManager.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\Core\\\\Action\\\\ConfigurableActionBase\\:\\:setConfiguration\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/lib/Drupal/Core/Action/ConfigurableActionBase.php', -]; -$ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\Core\\\\Action\\\\ConfigurableActionBase\\:\\:validateConfigurationForm\\(\\) has no return type specified\\.$#', 'identifier' => 'missingType.return', 'count' => 1, @@ -3968,12 +3962,6 @@ $ignoreErrors[] = [ 'path' => __DIR__ . '/lib/Drupal/Core/Display/VariantBase.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\Core\\\\Display\\\\VariantBase\\:\\:setConfiguration\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/lib/Drupal/Core/Display/VariantBase.php', -]; -$ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\Core\\\\Display\\\\VariantBase\\:\\:setWeight\\(\\) has no return type specified\\.$#', 'identifier' => 'missingType.return', 'count' => 1, @@ -5162,12 +5150,6 @@ $ignoreErrors[] = [ 'path' => __DIR__ . '/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginBase.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\Core\\\\Entity\\\\EntityReferenceSelection\\\\SelectionPluginBase\\:\\:setConfiguration\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginBase.php', -]; -$ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\Core\\\\Entity\\\\EntityReferenceSelection\\\\SelectionPluginBase\\:\\:submitConfigurationForm\\(\\) has no return type specified\\.$#', 'identifier' => 'missingType.return', 'count' => 1, @@ -8540,12 +8522,6 @@ $ignoreErrors[] = [ 'path' => __DIR__ . '/lib/Drupal/Core/Layout/LayoutDefault.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\Core\\\\Layout\\\\LayoutDefault\\:\\:setConfiguration\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/lib/Drupal/Core/Layout/LayoutDefault.php', -]; -$ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\Core\\\\Layout\\\\LayoutDefault\\:\\:setContext\\(\\) has no return type specified\\.$#', 'identifier' => 'missingType.return', 'count' => 1, @@ -18704,12 +18680,6 @@ $ignoreErrors[] = [ 'path' => __DIR__ . '/modules/image/src/Form/ImageStyleFormBase.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\image\\\\ImageEffectBase\\:\\:setConfiguration\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/modules/image/src/ImageEffectBase.php', -]; -$ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\image\\\\ImageEffectBase\\:\\:transformDimensions\\(\\) has no return type specified\\.$#', 'identifier' => 'missingType.return', 'count' => 1, @@ -29055,12 +29025,6 @@ $ignoreErrors[] = [ 'path' => __DIR__ . '/modules/search/src/Plugin/Block/SearchBlock.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\search\\\\Plugin\\\\ConfigurableSearchPluginBase\\:\\:setConfiguration\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/modules/search/src/Plugin/ConfigurableSearchPluginBase.php', -]; -$ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\search\\\\Plugin\\\\ConfigurableSearchPluginBase\\:\\:validateConfigurationForm\\(\\) has no return type specified\\.$#', 'identifier' => 'missingType.return', 'count' => 1, @@ -45579,12 +45543,6 @@ $ignoreErrors[] = [ 'path' => __DIR__ . '/modules/workflows/src/Form/WorkflowTransitionEditForm.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\workflows\\\\Plugin\\\\WorkflowTypeBase\\:\\:setConfiguration\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/modules/workflows/src/Plugin/WorkflowTypeBase.php', -]; -$ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\workflows\\\\Plugin\\\\WorkflowTypeConfigureFormBase\\:\\:setPlugin\\(\\) has no return type specified\\.$#', 'identifier' => 'missingType.return', 'count' => 1, @@ -51588,12 +51546,6 @@ $ignoreErrors[] = [ 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Plugin/FilteredPluginManagerTraitTest.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\Tests\\\\Core\\\\Plugin\\\\Fixtures\\\\TestConfigurablePlugin\\:\\:setConfiguration\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Plugin/Fixtures/TestConfigurablePlugin.php', -]; -$ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\Tests\\\\Core\\\\Plugin\\\\LazyPluginCollectionTestBase\\:\\:setupPluginCollection\\(\\) has no return type specified\\.$#', 'identifier' => 'missingType.return', 'count' => 1, diff --git a/core/lib/Drupal/Core/Action/ConfigurableActionBase.php b/core/lib/Drupal/Core/Action/ConfigurableActionBase.php index dd1e8ccdc541..a2a55f354e6a 100644 --- a/core/lib/Drupal/Core/Action/ConfigurableActionBase.php +++ b/core/lib/Drupal/Core/Action/ConfigurableActionBase.php @@ -5,6 +5,7 @@ namespace Drupal\Core\Action; use Drupal\Component\Plugin\ConfigurableInterface; use Drupal\Component\Plugin\DependentPluginInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Plugin\ConfigurableTrait; use Drupal\Core\Plugin\PluginFormInterface; /** @@ -12,6 +13,8 @@ use Drupal\Core\Plugin\PluginFormInterface; */ abstract class ConfigurableActionBase extends ActionBase implements ConfigurableInterface, DependentPluginInterface, PluginFormInterface { + use ConfigurableTrait; + /** * {@inheritdoc} */ @@ -24,27 +27,6 @@ abstract class ConfigurableActionBase extends ActionBase implements Configurable /** * {@inheritdoc} */ - public function defaultConfiguration() { - return []; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() { - return $this->configuration; - } - - /** - * {@inheritdoc} - */ - public function setConfiguration(array $configuration) { - $this->configuration = $configuration + $this->defaultConfiguration(); - } - - /** - * {@inheritdoc} - */ public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { } diff --git a/core/lib/Drupal/Core/Display/VariantBase.php b/core/lib/Drupal/Core/Display/VariantBase.php index dafb060d59f6..328bb89a2db0 100644 --- a/core/lib/Drupal/Core/Display/VariantBase.php +++ b/core/lib/Drupal/Core/Display/VariantBase.php @@ -4,7 +4,7 @@ namespace Drupal\Core\Display; use Drupal\Core\Cache\RefinableCacheableDependencyTrait; use Drupal\Core\Form\FormStateInterface; -use Drupal\Core\Plugin\PluginBase; +use Drupal\Core\Plugin\ConfigurablePluginBase; use Drupal\Core\Plugin\PluginDependencyTrait; use Drupal\Core\Session\AccountInterface; @@ -16,7 +16,7 @@ use Drupal\Core\Session\AccountInterface; * @see \Drupal\Core\Display\VariantManager * @see plugin_api */ -abstract class VariantBase extends PluginBase implements VariantInterface { +abstract class VariantBase extends ConfigurablePluginBase implements VariantInterface { use PluginDependencyTrait; use RefinableCacheableDependencyTrait; @@ -24,15 +24,6 @@ abstract class VariantBase extends PluginBase implements VariantInterface { /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition) { - parent::__construct($configuration, $plugin_id, $plugin_definition); - - $this->setConfiguration($configuration); - } - - /** - * {@inheritdoc} - */ public function label() { return $this->configuration['label']; } @@ -77,14 +68,6 @@ abstract class VariantBase extends PluginBase implements VariantInterface { /** * {@inheritdoc} */ - public function setConfiguration(array $configuration) { - $this->configuration = $configuration + $this->defaultConfiguration(); - return $this; - } - - /** - * {@inheritdoc} - */ public function defaultConfiguration() { return [ 'label' => '', diff --git a/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginBase.php b/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginBase.php index b40e32636719..019f8535ef6d 100644 --- a/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginBase.php +++ b/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginBase.php @@ -2,32 +2,15 @@ namespace Drupal\Core\Entity\EntityReferenceSelection; -use Drupal\Component\Plugin\ConfigurableInterface; use Drupal\Component\Plugin\DependentPluginInterface; -use Drupal\Component\Utility\NestedArray; use Drupal\Core\Database\Query\SelectInterface; use Drupal\Core\Form\FormStateInterface; -use Drupal\Core\Plugin\PluginBase; +use Drupal\Core\Plugin\ConfigurablePluginBase; /** * Provides a base class for configurable selection handlers. */ -abstract class SelectionPluginBase extends PluginBase implements SelectionInterface, ConfigurableInterface, DependentPluginInterface { - - /** - * Constructs a new selection object. - * - * @param array $configuration - * A configuration array containing information about the plugin instance. - * @param string $plugin_id - * The plugin ID for the plugin instance. - * @param mixed $plugin_definition - * The plugin implementation definition. - */ - public function __construct(array $configuration, $plugin_id, $plugin_definition) { - parent::__construct($configuration, $plugin_id, $plugin_definition); - $this->setConfiguration($configuration); - } +abstract class SelectionPluginBase extends ConfigurablePluginBase implements SelectionInterface, DependentPluginInterface { /** * {@inheritdoc} @@ -42,24 +25,6 @@ abstract class SelectionPluginBase extends PluginBase implements SelectionInterf /** * {@inheritdoc} */ - public function getConfiguration() { - return $this->configuration; - } - - /** - * {@inheritdoc} - */ - public function setConfiguration(array $configuration) { - // Merge in defaults. - $this->configuration = NestedArray::mergeDeep( - $this->defaultConfiguration(), - $configuration - ); - } - - /** - * {@inheritdoc} - */ public function calculateDependencies() { return []; } diff --git a/core/lib/Drupal/Core/Layout/LayoutDefault.php b/core/lib/Drupal/Core/Layout/LayoutDefault.php index 67980ba82e20..e9aac0eb4905 100644 --- a/core/lib/Drupal/Core/Layout/LayoutDefault.php +++ b/core/lib/Drupal/Core/Layout/LayoutDefault.php @@ -2,18 +2,17 @@ namespace Drupal\Core\Layout; -use Drupal\Component\Utility\NestedArray; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\ContextAwarePluginAssignmentTrait; use Drupal\Core\Plugin\ContextAwarePluginTrait; -use Drupal\Core\Plugin\PluginBase; +use Drupal\Core\Plugin\ConfigurablePluginBase; use Drupal\Core\Plugin\PluginFormInterface; use Drupal\Core\Plugin\PreviewAwarePluginInterface; /** * Provides a default class for Layout plugins. */ -class LayoutDefault extends PluginBase implements LayoutInterface, PluginFormInterface, PreviewAwarePluginInterface { +class LayoutDefault extends ConfigurablePluginBase implements LayoutInterface, PluginFormInterface, PreviewAwarePluginInterface { use ContextAwarePluginAssignmentTrait; use ContextAwarePluginTrait; @@ -35,14 +34,6 @@ class LayoutDefault extends PluginBase implements LayoutInterface, PluginFormInt /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition) { - parent::__construct($configuration, $plugin_id, $plugin_definition); - $this->setConfiguration($configuration); - } - - /** - * {@inheritdoc} - */ public function build(array $regions) { // Ensure $build only contains defined regions and in the order defined. $build = []; @@ -64,20 +55,6 @@ class LayoutDefault extends PluginBase implements LayoutInterface, PluginFormInt /** * {@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' => '', diff --git a/core/lib/Drupal/Core/Plugin/ConfigurablePluginBase.php b/core/lib/Drupal/Core/Plugin/ConfigurablePluginBase.php new file mode 100644 index 000000000000..0d51a8025562 --- /dev/null +++ b/core/lib/Drupal/Core/Plugin/ConfigurablePluginBase.php @@ -0,0 +1,31 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Core\Plugin; + +use Drupal\Component\Plugin\ConfigurableInterface; + +/** + * Base class for plugins that are configurable. + * + * Provides boilerplate methods for implementing + * Drupal\Component\Plugin\ConfigurableInterface. Configurable plugins may + * extend this base class instead of PluginBase. If your plugin must extend a + * different base class, you may use \Drupal\Component\Plugin\ConfigurableTrait + * directly and call setConfiguration() in your constructor. + * + * @see \Drupal\Core\Plugin\ConfigurableTrait + */ +abstract class ConfigurablePluginBase extends PluginBase implements ConfigurableInterface { + use ConfigurableTrait; + + /** + * {@inheritdoc} + */ + public function __construct(array $configuration, $plugin_id, $plugin_definition) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + $this->setConfiguration($configuration); + } + +} diff --git a/core/lib/Drupal/Core/Plugin/ConfigurableTrait.php b/core/lib/Drupal/Core/Plugin/ConfigurableTrait.php new file mode 100644 index 000000000000..bfe4a6615127 --- /dev/null +++ b/core/lib/Drupal/Core/Plugin/ConfigurableTrait.php @@ -0,0 +1,81 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Core\Plugin; + +use Drupal\Component\Utility\NestedArray; + +/** + * Implementation class for \Drupal\Component\Plugin\ConfigurableInterface. + * + * In order for configurable plugins to maintain their configuration, the + * default configuration must be merged into any explicitly defined + * configuration. This trait provides the appropriate getters and setters to + * handle this logic, removing the need for excess boilerplate. + * + * To use this trait implement ConfigurableInterface and add a constructor. In + * the constructor call the parent constructor and then call setConfiguration(). + * That will merge the explicitly defined plugin configuration and the default + * plugin configuration. + * + * @ingroup Plugin + */ +trait ConfigurableTrait { + + /** + * Configuration information passed into the plugin. + * + * This property is declared in \Drupal\Component\Plugin\PluginBase as well, + * which most classes using this trait will ultimately be extending. It is + * re-declared here to make the trait self-contained and to permit use of the + * trait in classes that do not extend PluginBase. + * + * @var array + */ + protected $configuration; + + /** + * Gets this plugin's configuration. + * + * @return array + * An associative array containing the plugin's configuration. + * + * @see \Drupal\Component\Plugin\ConfigurableInterface::getConfiguration() + */ + public function getConfiguration() { + return $this->configuration; + } + + /** + * Sets the configuration for this plugin instance. + * + * The provided configuration is merged with the plugin's default + * configuration. If the same configuration key exists in both configurations, + * then the value in the provided configuration will override the default. + * + * @param array $configuration + * An associative array containing the plugin's configuration. + * + * @return $this + * + * @see \Drupal\Component\Plugin\ConfigurableInterface::setConfiguration() + */ + public function setConfiguration(array $configuration) { + $this->configuration = NestedArray::mergeDeepArray([$this->defaultConfiguration(), $configuration], TRUE); + return $this; + } + + /** + * Gets default configuration for this plugin. + * + * @return array + * An associative array containing the default configuration. + * + * @see \Drupal\Component\Plugin\ConfigurableInterface::defaultConfiguration() + */ + public function defaultConfiguration() { + return []; + } + +} diff --git a/core/modules/image/src/ImageEffectBase.php b/core/modules/image/src/ImageEffectBase.php index 58be370c1e6e..745976133be7 100644 --- a/core/modules/image/src/ImageEffectBase.php +++ b/core/modules/image/src/ImageEffectBase.php @@ -3,7 +3,7 @@ namespace Drupal\image; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; -use Drupal\Core\Plugin\PluginBase; +use Drupal\Core\Plugin\ConfigurablePluginBase; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -17,7 +17,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; * @see \Drupal\image\ImageEffectManager * @see plugin_api */ -abstract class ImageEffectBase extends PluginBase implements ImageEffectInterface, ContainerFactoryPluginInterface { +abstract class ImageEffectBase extends ConfigurablePluginBase implements ImageEffectInterface, ContainerFactoryPluginInterface { /** * The image effect ID. @@ -46,7 +46,6 @@ abstract class ImageEffectBase extends PluginBase implements ImageEffectInterfac public function __construct(array $configuration, $plugin_id, $plugin_definition, LoggerInterface $logger) { parent::__construct($configuration, $plugin_id, $plugin_definition); - $this->setConfiguration($configuration); $this->logger = $logger; } @@ -154,13 +153,6 @@ abstract class ImageEffectBase extends PluginBase implements ImageEffectInterfac /** * {@inheritdoc} */ - public function defaultConfiguration() { - return []; - } - - /** - * {@inheritdoc} - */ public function calculateDependencies() { return []; } diff --git a/core/modules/search/src/Plugin/ConfigurableSearchPluginBase.php b/core/modules/search/src/Plugin/ConfigurableSearchPluginBase.php index 7ad95f16823b..acc2e49a5cb6 100644 --- a/core/modules/search/src/Plugin/ConfigurableSearchPluginBase.php +++ b/core/modules/search/src/Plugin/ConfigurableSearchPluginBase.php @@ -2,14 +2,16 @@ namespace Drupal\search\Plugin; -use Drupal\Component\Utility\NestedArray; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Plugin\ConfigurableTrait; /** * Provides a base implementation for a configurable Search plugin. */ abstract class ConfigurableSearchPluginBase extends SearchPluginBase implements ConfigurableSearchPluginInterface { + use ConfigurableTrait; + /** * The unique ID for the search page using this plugin. * @@ -29,27 +31,6 @@ abstract class ConfigurableSearchPluginBase extends SearchPluginBase implements /** * {@inheritdoc} */ - public function defaultConfiguration() { - return []; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() { - return $this->configuration; - } - - /** - * {@inheritdoc} - */ - public function setConfiguration(array $configuration) { - $this->configuration = NestedArray::mergeDeep($this->defaultConfiguration(), $configuration); - } - - /** - * {@inheritdoc} - */ public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { } diff --git a/core/modules/workflows/src/Plugin/WorkflowTypeBase.php b/core/modules/workflows/src/Plugin/WorkflowTypeBase.php index 47488b38801b..e86b77a22857 100644 --- a/core/modules/workflows/src/Plugin/WorkflowTypeBase.php +++ b/core/modules/workflows/src/Plugin/WorkflowTypeBase.php @@ -2,7 +2,7 @@ namespace Drupal\workflows\Plugin; -use Drupal\Component\Plugin\PluginBase; +use Drupal\Core\Plugin\ConfigurablePluginBase; use Drupal\Core\Plugin\PluginWithFormsTrait; use Drupal\workflows\State; use Drupal\workflows\StateInterface; @@ -16,7 +16,7 @@ use Drupal\workflows\WorkflowTypeInterface; * * @see \Drupal\workflows\Annotation\WorkflowType */ -abstract class WorkflowTypeBase extends PluginBase implements WorkflowTypeInterface { +abstract class WorkflowTypeBase extends ConfigurablePluginBase implements WorkflowTypeInterface { use PluginWithFormsTrait; @@ -28,14 +28,6 @@ abstract class WorkflowTypeBase extends PluginBase implements WorkflowTypeInterf /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition) { - parent::__construct($configuration, $plugin_id, $plugin_definition); - $this->setConfiguration($configuration); - } - - /** - * {@inheritdoc} - */ public function label() { $definition = $this->getPluginDefinition(); // The label can be an object. @@ -60,15 +52,9 @@ abstract class WorkflowTypeBase extends PluginBase implements WorkflowTypeInterf /** * {@inheritdoc} */ - public function getConfiguration() { - return $this->configuration; - } - - /** - * {@inheritdoc} - */ public function setConfiguration(array $configuration) { $this->configuration = $configuration + $this->defaultConfiguration(); + return $this; } /** diff --git a/core/tests/Drupal/Tests/Core/Plugin/ConfigurablePluginBaseTest.php b/core/tests/Drupal/Tests/Core/Plugin/ConfigurablePluginBaseTest.php new file mode 100644 index 000000000000..d05413eb444e --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Plugin/ConfigurablePluginBaseTest.php @@ -0,0 +1,47 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\Core\Plugin; + +use Drupal\Core\Plugin\ConfigurablePluginBase; +use PHPUnit\Framework\TestCase; + +/** + * Tests ConfigurablePluginBase. + * + * @group Plugin + * + * @coversDefaultClass \Drupal\Core\Plugin\ConfigurablePluginBase + */ +class ConfigurablePluginBaseTest extends TestCase { + + /** + * Tests the Constructor. + */ + public function testConstructor(): void { + $provided_configuration = [ + 'foo' => 'bar', + ]; + $merged_configuration = ['default' => 'default'] + $provided_configuration; + $plugin = new ConfigurablePluginBaseTestClass($provided_configuration, '', []); + $this->assertSame($merged_configuration, $plugin->getConfiguration()); + } + +} + +/** + * Test class for ConfigurablePluginBase. + */ +class ConfigurablePluginBaseTestClass extends ConfigurablePluginBase { + + /** + * {@inheritdoc} + */ + public function defaultConfiguration(): array { + return [ + 'default' => 'default', + ]; + } + +} diff --git a/core/tests/Drupal/Tests/Core/Plugin/ConfigurableTraitTest.php b/core/tests/Drupal/Tests/Core/Plugin/ConfigurableTraitTest.php new file mode 100644 index 000000000000..21543658769c --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Plugin/ConfigurableTraitTest.php @@ -0,0 +1,205 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\Core\Plugin; + +use Drupal\Component\Plugin\ConfigurableInterface; +use Drupal\Component\Plugin\PluginBase; +use Drupal\Core\Plugin\ConfigurableTrait; +use PHPUnit\Framework\TestCase; + +/** + * Tests for ConfigurableTrait. + * + * @group Plugin + * + * @coversDefaultClass \Drupal\Core\Plugin\ConfigurableTrait + */ +class ConfigurableTraitTest extends TestCase { + + /** + * Tests ConfigurableTrait::defaultConfiguration. + * + * @covers ::defaultConfiguration + */ + public function testDefaultConfiguration(): void { + /** @var \Drupal\Component\Plugin\ConfigurableInterface $configurable_plugin */ + $configurable_plugin = new ConfigurableTestClass(); + $this->assertSame([], $configurable_plugin->defaultConfiguration()); + } + + /** + * Tests ConfigurableTrait::getConfiguration. + * + * @covers ::getConfiguration + */ + public function testGetConfiguration(): void { + $test_configuration = [ + 'config_key_1' => 'config_value_1', + 'config_key_2' => [ + 'nested_key_1' => 'nested_value_1', + 'nested_key_2' => 'nested_value_2', + ], + ]; + $configurable_plugin = new ConfigurableTestClass($test_configuration); + $this->assertSame($test_configuration, $configurable_plugin->getConfiguration()); + } + + /** + * Tests configurableTrait::setConfiguration. + * + * Specifically test the way default and provided configurations are merged. + * + * @param array $default_configuration + * The default configuration to use for the trait. + * @param array $test_configuration + * The configuration to test. + * @param array $final_configuration + * The expected final plugin configuration. + * + * @covers ::setConfiguration + * + * @dataProvider setConfigurationDataProvider + */ + public function testSetConfiguration(array $default_configuration, array $test_configuration, array $final_configuration): void { + $test_object = new ConfigurableTestClass(); + $test_object->setDefaultConfiguration($default_configuration); + $test_object->setConfiguration($test_configuration); + $this->assertSame($final_configuration, $test_object->getConfiguration()); + } + + /** + * Provides data for testSetConfiguration. + * + * @return array + * The data. + */ + public static function setConfigurationDataProvider(): array { + return [ + 'Direct Override' => [ + 'default_configuration' => [ + 'default_key_1' => 'default_value_1', + 'default_key_2' => [ + 'default_nested_key_1' => 'default_nested_value_1', + 'default_nested_key_2' => 'default_nested_value_2', + ], + ], + 'test_configuration' => [ + 'default_key_1' => 'override_value_1', + 'default_key_2' => [ + 'default_nested_key_1' => 'override_nested_value_1', + 'default_nested_key_2' => 'override_nested_value_2', + ], + ], + 'final_configuration' => [ + 'default_key_1' => 'override_value_1', + 'default_key_2' => [ + 'default_nested_key_1' => 'override_nested_value_1', + 'default_nested_key_2' => 'override_nested_value_2', + ], + ], + ], + 'Mixed Override' => [ + 'default_configuration' => [ + 'default_key_1' => 'default_value_1', + 'default_key_2' => [ + 'default_nested_key_1' => 'default_nested_value_1', + 'default_nested_key_2' => 'default_nested_value_2', + ], + ], + 'test_configuration' => [ + 'override_key_1' => 'config_value_1', + 'default_key_2' => [ + 'default_nested_key_1' => 'override_value_1', + 'override_nested_key' => 'override_value', + ], + ], + 'final_configuration' => [ + 'default_key_1' => 'default_value_1', + 'default_key_2' => [ + 'default_nested_key_1' => 'override_value_1', + 'default_nested_key_2' => 'default_nested_value_2', + 'override_nested_key' => 'override_value', + ], + 'override_key_1' => 'config_value_1', + ], + ], + 'indexed_override' => [ + 'default_configuration' => [ + 'config_value_1', + 'config_value_2', + 'config_value_3', + ], + 'test_configuration' => [ + 'override_value_1', + 'override_value_2', + ], + 'final_configuration' => [ + 'override_value_1', + 'override_value_2', + 'config_value_3', + ], + ], + 'indexed_override_complex' => [ + 'default_configuration' => [ + 'config_value_1', + 'config_value_2', + 'config_value_3', + ], + 'test_configuration' => [ + 0 => 'override_value_1', + 2 => 'override_value_3', + ], + 'final_configuration' => [ + 'override_value_1', + 'config_value_2', + 'override_value_3', + ], + ], + ]; + } + +} + +/** + * A test class using ConfigurablePluginTrait that can modify the de. + */ +class ConfigurableTestClass extends PluginBase implements ConfigurableInterface { + use ConfigurableTrait { + defaultConfiguration as traitDefaultConfiguration; + } + + /** + * A default configuration for the test class to return. + * + * @var array|null + */ + protected ?array $defaultConfiguration = NULL; + + /** + * {@inheritdoc} + */ + public function __construct(array $configuration = [], string $plugin_id = '', array $plugin_definition = []) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + $this->setConfiguration($configuration); + } + + /** + * Sets the default configuration this test will return. + * + * @param array $default_configuration + * The default configuration to use. + */ + public function setDefaultConfiguration(array $default_configuration): void { + $this->defaultConfiguration = $default_configuration; + } + + /** + * {@inheritdoc} + */ + public function defaultConfiguration(): array { + return $this->defaultConfiguration ?? $this->traitDefaultConfiguration(); + } + +} diff --git a/core/tests/Drupal/Tests/Core/Plugin/DefaultSingleLazyPluginCollectionTest.php b/core/tests/Drupal/Tests/Core/Plugin/DefaultSingleLazyPluginCollectionTest.php index 99da7a2f9741..60e147f434a5 100644 --- a/core/tests/Drupal/Tests/Core/Plugin/DefaultSingleLazyPluginCollectionTest.php +++ b/core/tests/Drupal/Tests/Core/Plugin/DefaultSingleLazyPluginCollectionTest.php @@ -4,8 +4,7 @@ declare(strict_types=1); namespace Drupal\Tests\Core\Plugin; -use Drupal\Component\Plugin\ConfigurableInterface; -use Drupal\Component\Plugin\PluginBase; +use Drupal\Core\Plugin\ConfigurablePluginBase; use Drupal\Core\Plugin\DefaultSingleLazyPluginCollection; use PHPUnit\Framework\MockObject\Rule\InvocationOrder; @@ -98,24 +97,5 @@ class DefaultSingleLazyPluginCollectionTest extends LazyPluginCollectionTestBase /** * Stub configurable plugin class for testing. */ -class ConfigurablePlugin extends PluginBase implements ConfigurableInterface { - - public function __construct(array $configuration, $plugin_id, $plugin_definition) { - parent::__construct($configuration, $plugin_id, $plugin_definition); - - $this->configuration = $configuration + $this->defaultConfiguration(); - } - - public function defaultConfiguration() { - return []; - } - - public function getConfiguration() { - return $this->configuration; - } - - public function setConfiguration(array $configuration): void { - $this->configuration = $configuration; - } - +class ConfigurablePlugin extends ConfigurablePluginBase { } diff --git a/core/tests/Drupal/Tests/Core/Plugin/Fixtures/TestConfigurablePlugin.php b/core/tests/Drupal/Tests/Core/Plugin/Fixtures/TestConfigurablePlugin.php index 55695ace6de7..7b72a3df4530 100644 --- a/core/tests/Drupal/Tests/Core/Plugin/Fixtures/TestConfigurablePlugin.php +++ b/core/tests/Drupal/Tests/Core/Plugin/Fixtures/TestConfigurablePlugin.php @@ -4,35 +4,13 @@ declare(strict_types=1); namespace Drupal\Tests\Core\Plugin\Fixtures; -use Drupal\Component\Plugin\ConfigurableInterface; use Drupal\Component\Plugin\DependentPluginInterface; -use Drupal\Component\Plugin\PluginBase; +use Drupal\Core\Plugin\ConfigurablePluginBase; /** * A configurable plugin implementation used for testing. */ -class TestConfigurablePlugin extends PluginBase implements ConfigurableInterface, DependentPluginInterface { - - /** - * {@inheritdoc} - */ - public function getConfiguration() { - return $this->configuration; - } - - /** - * {@inheritdoc} - */ - public function setConfiguration(array $configuration) { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function defaultConfiguration() { - return []; - } +class TestConfigurablePlugin extends ConfigurablePluginBase implements DependentPluginInterface { /** * {@inheritdoc} |