Issue #3426324 by Wim Leers: ExistsConstraintValidator should ignore NULL values and treat `core` as a valid module

(cherry picked from commit ab695b5cc6)
merge-requests/6999/head
Alex Pott 2024-03-08 14:03:20 +00:00
parent 2a4f67ca71
commit 5f758d452e
No known key found for this signature in database
GPG Key ID: BDA67E7EE836E5CE
2 changed files with 35 additions and 1 deletions

View File

@ -61,12 +61,26 @@ class ExtensionExistsConstraintValidator extends ConstraintValidator implements
switch ($constraint->type) { switch ($constraint->type) {
case 'module': case 'module':
// This constraint may be used to validate nullable (optional) values.
if ($extension_name === NULL) {
return;
}
// Some plugins are shipped in `core/lib`, which corresponds to the
// special `core` extension name.
// For example: \Drupal\Core\Menu\Plugin\Block\LocalActionsBlock.
if ($extension_name === 'core') {
return;
}
if (!$this->moduleHandler->moduleExists($extension_name)) { if (!$this->moduleHandler->moduleExists($extension_name)) {
$this->context->addViolation($constraint->moduleMessage, $variables); $this->context->addViolation($constraint->moduleMessage, $variables);
} }
break; break;
case 'theme': case 'theme':
// This constraint may be used to validate nullable (optional) values.
if ($extension_name === NULL) {
return;
}
if (!$this->themeHandler->themeExists($extension_name)) { if (!$this->themeHandler->themeExists($extension_name)) {
$this->context->addViolation($constraint->themeMessage, $variables); $this->context->addViolation($constraint->themeMessage, $variables);
} }

View File

@ -31,8 +31,13 @@ class ExtensionExistsConstraintValidatorTest extends KernelTestBase {
/** @var \Drupal\Core\TypedData\TypedDataManagerInterface $typed_data */ /** @var \Drupal\Core\TypedData\TypedDataManagerInterface $typed_data */
$typed_data = $this->container->get('typed_data_manager'); $typed_data = $this->container->get('typed_data_manager');
$data = $typed_data->create($definition, 'user');
// `core` provides many plugins without the need to install a module.
$data = $typed_data->create($definition, 'core');
$violations = $data->validate();
$this->assertCount(0, $violations);
$data->setValue('user');
$violations = $data->validate(); $violations = $data->validate();
$this->assertCount(1, $violations); $this->assertCount(1, $violations);
$this->assertSame("Module 'user' is not installed.", (string) $violations->get(0)->getMessage()); $this->assertSame("Module 'user' is not installed.", (string) $violations->get(0)->getMessage());
@ -40,6 +45,10 @@ class ExtensionExistsConstraintValidatorTest extends KernelTestBase {
$this->enableModules(['user']); $this->enableModules(['user']);
$this->assertCount(0, $data->validate()); $this->assertCount(0, $data->validate());
// NULL should not trigger a validation error: a value may be nullable.
$data->setValue(NULL);
$this->assertCount(0, $data->validate());
$definition->setConstraints(['ExtensionExists' => 'theme']); $definition->setConstraints(['ExtensionExists' => 'theme']);
$data = $typed_data->create($definition, 'stark'); $data = $typed_data->create($definition, 'stark');
@ -56,6 +65,17 @@ class ExtensionExistsConstraintValidatorTest extends KernelTestBase {
->create($definition, 'stark'); ->create($definition, 'stark');
$this->assertCount(0, $data->validate()); $this->assertCount(0, $data->validate());
// `core` provides many plugins without the need to install a module, but it
// does not work for themes.
$data = $typed_data->create($definition, 'core');
$violations = $data->validate();
$this->assertCount(1, $violations);
$this->assertSame("Theme 'core' is not installed.", (string) $violations->get(0)->getMessage());
// NULL should not trigger a validation error: a value may be nullable.
$data->setValue(NULL);
$this->assertCount(0, $data->validate());
// Anything but a module or theme should raise an exception. // Anything but a module or theme should raise an exception.
$definition->setConstraints(['ExtensionExists' => 'profile']); $definition->setConstraints(['ExtensionExists' => 'profile']);
$this->expectExceptionMessage("Unknown extension type: 'profile'"); $this->expectExceptionMessage("Unknown extension type: 'profile'");