Commit 34965ce1 authored by catch's avatar catch

Issue #2925913 by alexpott, amateescu: EntityReferenceItem logs critical...

Issue #2925913 by alexpott, amateescu: EntityReferenceItem logs critical errors in onDependencyRemoval()
parent 33368a52
......@@ -503,19 +503,6 @@ public static function onDependencyRemoval(FieldDefinitionInterface $field_defin
}
$bundles_changed = TRUE;
// In case we deleted the only target bundle allowed by the field
// we have to log a critical message because the field will not
// function correctly anymore.
if ($handler_settings['target_bundles'] === []) {
\Drupal::logger('entity_reference')->critical('The %target_bundle bundle (entity type: %target_entity_type) was deleted. As a result, the %field_name entity reference field (entity_type: %entity_type, bundle: %bundle) no longer has any valid bundle it can reference. The field is not working correctly anymore and has to be adjusted.', [
'%target_bundle' => $bundle->label(),
'%target_entity_type' => $bundle->getEntityType()->getBundleOf(),
'%field_name' => $field_definition->getName(),
'%entity_type' => $field_definition->getTargetEntityTypeId(),
'%bundle' => $field_definition->getTargetBundle()
]);
}
}
}
}
......
......@@ -250,19 +250,6 @@ function field_entity_bundle_delete($entity_type_id, $bundle) {
unset($handler_settings['target_bundles'][$bundle]);
$field_config->setSetting('handler_settings', $handler_settings);
$field_config->save();
// In case we deleted the only target bundle allowed by the field we
// have to log a critical message because the field will not function
// correctly anymore.
if ($handler_settings['target_bundles'] === []) {
\Drupal::logger('entity_reference')->critical('The %target_bundle bundle (entity type: %target_entity_type) was deleted. As a result, the %field_name entity reference field (entity_type: %entity_type, bundle: %bundle) no longer has any valid bundle it can reference. The field is not working correctly anymore and has to be adjusted.', [
'%target_bundle' => $bundle,
'%target_entity_type' => $entity_type_id,
'%field_name' => $field_config->getName(),
'%entity_type' => $field_config->getTargetEntityTypeId(),
'%bundle' => $field_config->getTargetBundle()
]);
}
}
}
}
......@@ -407,4 +394,17 @@ function field_field_config_presave(FieldConfigInterface $field) {
$selection_manager = \Drupal::service('plugin.manager.entity_reference_selection');
list($current_handler) = explode(':', $field->getSetting('handler'), 2);
$field->setSetting('handler', $selection_manager->getPluginId($target_type, $current_handler));
// In case we removed all the target bundles allowed by the field in
// EntityReferenceItem::onDependencyRemoval() or field_entity_bundle_delete()
// we have to log a critical message because the field will not function
// correctly anymore.
$handler_settings = $field->getSetting('handler_settings');
if (isset($handler_settings['target_bundles']) && $handler_settings['target_bundles'] === []) {
\Drupal::logger('entity_reference')->critical('The %field_name entity reference field (entity_type: %entity_type, bundle: %bundle) no longer has any valid bundle it can reference. The field is not working correctly anymore and has to be adjusted.', [
'%field_name' => $field->getName(),
'%entity_type' => $field->getTargetEntityTypeId(),
'%bundle' => $field->getTargetBundle(),
]);
}
}
......@@ -3,11 +3,14 @@
namespace Drupal\Tests\field\Kernel\EntityReference;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Logger\RfcLogLevel;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
use Drupal\node\Entity\NodeType;
use Drupal\KernelTests\KernelTestBase;
use Drupal\taxonomy\Entity\Vocabulary;
use Symfony\Component\Debug\BufferingLogger;
/**
* Tests entity reference field settings.
......@@ -44,6 +47,13 @@ class EntityReferenceSettingsTest extends KernelTestBase {
*/
protected $customBundle;
/**
* The service name for a logger implementation that collects anything logged.
*
* @var string
*/
protected $testLogServiceName = 'entity_reference_settings_test.logger';
/**
* {@inheritdoc}
*/
......@@ -60,26 +70,38 @@ protected function setUp() {
]);
$this->nodeType->save();
$this->vocabulary = Vocabulary::create([
'vid' => Unicode::strtolower($this->randomMachineName()),
'name' => $this->randomString(),
]);
$this->vocabulary->save();
// Create a custom bundle.
$this->customBundle = 'test_bundle_' . Unicode::strtolower($this->randomMachineName());
entity_test_create_bundle($this->customBundle, NULL, 'entity_test');
// Prepare the logger for collecting the expected critical error.
$this->container->get($this->testLogServiceName)->cleanLogs();
}
/**
* Tests that config bundle deletions are mirrored in field config settings.
*/
public function testConfigTargetBundleDeletion() {
// Create two vocabularies.
/** @var \Drupal\taxonomy\Entity\Vocabulary[] $vocabularies */
$vocabularies = [];
for ($i = 0; $i < 2; $i++) {
$vid = Unicode::strtolower($this->randomMachineName());
$vocabularies[$i] = Vocabulary::create([
'name' => $this->randomString(),
'vid' => $vid,
]);
$vocabularies[$i]->save();
}
// Attach an entity reference field to $this->nodeType.
$name = Unicode::strtolower($this->randomMachineName());
$label = $this->randomString();
$vid = $this->vocabulary->id();
$handler_settings = ['target_bundles' => [$vid => $vid]];
$handler_settings = [
'target_bundles' => [
$vocabularies[0]->id() => $vocabularies[0]->id(),
$vocabularies[1]->id() => $vocabularies[1]->id(),
],
];
$this->createEntityReferenceField('node', $this->nodeType->id(), $name, $label, 'taxonomy_term', 'default', $handler_settings);
// Check that the 'target_bundle' setting contains the vocabulary.
......@@ -88,13 +110,32 @@ public function testConfigTargetBundleDeletion() {
$this->assertEqual($handler_settings, $actual_handler_settings);
// Delete the vocabulary.
$this->vocabulary->delete();
$vocabularies[0]->delete();
// Ensure that noting is logged.
$this->assertEmpty($this->container->get($this->testLogServiceName)->cleanLogs());
// Check that the deleted vocabulary is no longer present in the
// 'target_bundles' field setting.
$field_config = FieldConfig::loadByName('node', $this->nodeType->id(), $name);
$handler_settings = $field_config->getSetting('handler_settings');
$this->assertTrue(empty($handler_settings['target_bundles']));
$this->assertEquals([$vocabularies[1]->id() => $vocabularies[1]->id()], $handler_settings['target_bundles']);
// Delete the other vocabulary.
$vocabularies[1]->delete();
// Ensure that field_field_config_presave() logs the expected critical
// error.
$log_message = $this->container->get($this->testLogServiceName)->cleanLogs()[0];
$this->assertEquals(RfcLogLevel::CRITICAL, $log_message[0]);
$this->assertEquals('The %field_name entity reference field (entity_type: %entity_type, bundle: %bundle) no longer has any valid bundle it can reference. The field is not working correctly anymore and has to be adjusted.', $log_message[1]);
$this->assertEquals($field_config->getName(), $log_message[2]['%field_name']);
$this->assertEquals('node', $log_message[2]['%entity_type']);
$this->assertEquals($this->nodeType->id(), $log_message[2]['%bundle']);
// Check that the deleted bundle is no longer present in the
// 'target_bundles' field setting.
$field_config = FieldConfig::loadByName('node', $this->nodeType->id(), $name);
$handler_settings = $field_config->getSetting('handler_settings');
$this->assertEquals([], $handler_settings['target_bundles']);
}
/**
......@@ -115,6 +156,15 @@ public function testCustomTargetBundleDeletion() {
// Delete the custom bundle.
entity_test_delete_bundle($this->customBundle, 'entity_test');
// Ensure that field_field_config_presave() logs the expected critical
// error.
$log_message = $this->container->get($this->testLogServiceName)->cleanLogs()[0];
$this->assertEquals(RfcLogLevel::CRITICAL, $log_message[0]);
$this->assertEquals('The %field_name entity reference field (entity_type: %entity_type, bundle: %bundle) no longer has any valid bundle it can reference. The field is not working correctly anymore and has to be adjusted.', $log_message[1]);
$this->assertEquals($field_config->getName(), $log_message[2]['%field_name']);
$this->assertEquals('node', $log_message[2]['%entity_type']);
$this->assertEquals($this->nodeType->id(), $log_message[2]['%bundle']);
// Check that the deleted bundle is no longer present in the
// 'target_bundles' field setting.
$field_config = FieldConfig::loadByName('node', $this->nodeType->id(), $name);
......@@ -122,4 +172,14 @@ public function testCustomTargetBundleDeletion() {
$this->assertTrue(empty($handler_settings['target_bundles']));
}
/**
* {@inheritdoc}
*/
public function register(ContainerBuilder $container) {
parent::register($container);
$container
->register($this->testLogServiceName, BufferingLogger::class)
->addTag('logger');
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment