Issue #2578249 by yched: Some e_r fields get the wrong Selection handler
parent
47e6ecfca3
commit
60b75a2da1
|
@ -51,7 +51,7 @@ class EntityReferenceItem extends FieldItemBase {
|
|||
*/
|
||||
public static function defaultFieldSettings() {
|
||||
return array(
|
||||
'handler' => 'default:' . (\Drupal::moduleHandler()->moduleExists('node') ? 'node' : 'user'),
|
||||
'handler' => 'default',
|
||||
'handler_settings' => array(),
|
||||
) + parent::defaultFieldSettings();
|
||||
}
|
||||
|
|
|
@ -11,8 +11,6 @@ use Drupal\Core\Form\FormStateInterface;
|
|||
use Drupal\Core\Render\Element;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\FieldStorageConfigInterface;
|
||||
use Drupal\field\FieldConfigInterface;
|
||||
|
||||
/**
|
||||
* Implements hook_help().
|
||||
|
@ -71,56 +69,6 @@ function entity_reference_field_widget_info_alter(&$info) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_ENTITY_TYPE_update() for 'field_storage_config'.
|
||||
*
|
||||
* Reset the instance handler settings, when the target type is changed.
|
||||
*/
|
||||
function entity_reference_field_storage_config_update(FieldStorageConfigInterface $field_storage) {
|
||||
if ($field_storage->getType() != 'entity_reference') {
|
||||
// Only act on entity reference fields.
|
||||
return;
|
||||
}
|
||||
|
||||
if ($field_storage->isSyncing()) {
|
||||
// Don't change anything during a configuration sync.
|
||||
return;
|
||||
}
|
||||
|
||||
if ($field_storage->getSetting('target_type') == $field_storage->original->getSetting('target_type')) {
|
||||
// Target type didn't change.
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($field_storage->getBundles() as $bundle) {
|
||||
$field = FieldConfig::loadByName($field_storage->getTargetEntityTypeId(), $bundle, $field_storage->getName());
|
||||
$field->setSetting('handler_settings', []);
|
||||
$field->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_ENTITY_TYPE_presave() for 'field_config'.
|
||||
*
|
||||
* Determine the selection handler plugin ID for an entity reference field.
|
||||
*/
|
||||
function entity_reference_field_config_presave(FieldConfigInterface $field) {
|
||||
if ($field->getType() != 'entity_reference') {
|
||||
// Only act on entity reference fields.
|
||||
return;
|
||||
}
|
||||
|
||||
if ($field->isSyncing()) {
|
||||
// Don't change anything during a configuration sync.
|
||||
return;
|
||||
}
|
||||
|
||||
$target_type = $field->getFieldStorageDefinition()->getSetting('target_type');
|
||||
$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));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_form_FORM_ID_alter() for 'field_ui_field_storage_add_form'.
|
||||
*/
|
||||
|
|
|
@ -8,10 +8,12 @@ use Drupal\Core\Config\ConfigImporter;
|
|||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Entity\DynamicallyFieldableEntityStorageInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\field\FieldConfigInterface;
|
||||
use Drupal\field\FieldStorageConfigInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/*
|
||||
* Load all public Field API functions. Drupal currently has no
|
||||
|
@ -280,3 +282,65 @@ function field_form_config_admin_import_form_alter(&$form, FormStateInterface $f
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_ENTITY_TYPE_update() for 'field_storage_config'.
|
||||
*
|
||||
* Reset the field handler settings, when the storage target_type is changed on
|
||||
* an entity reference field.
|
||||
*/
|
||||
function field_field_storage_config_update(FieldStorageConfigInterface $field_storage) {
|
||||
if ($field_storage->isSyncing()) {
|
||||
// Don't change anything during a configuration sync.
|
||||
return;
|
||||
}
|
||||
|
||||
// Act on all sub-types of the entity_reference field type.
|
||||
/** @var \Drupal\Core\Field\FieldTypePluginManager $field_type_manager */
|
||||
$field_type_manager = \Drupal::service('plugin.manager.field.field_type');
|
||||
$item_class = 'Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem';
|
||||
$class = $field_type_manager->getPluginClass($field_storage->getType());
|
||||
if ($class !== $item_class && !is_subclass_of($class, $item_class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If target_type changed, reset the handler in the fields using that storage.
|
||||
if ($field_storage->getSetting('target_type') !== $field_storage->original->getSetting('target_type')) {
|
||||
foreach ($field_storage->getBundles() as $bundle) {
|
||||
$field = FieldConfig::loadByName($field_storage->getTargetEntityTypeId(), $bundle, $field_storage->getName());
|
||||
// Reset the handler settings. This triggers field_field_config_presave(),
|
||||
// which will take care of reassigning the handler to the correct
|
||||
// derivative for the new target_type.
|
||||
$field->setSetting('handler_settings', []);
|
||||
$field->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_ENTITY_TYPE_presave() for 'field_config'.
|
||||
*
|
||||
* Determine the selection handler plugin ID for an entity reference field.
|
||||
*/
|
||||
function field_field_config_presave(FieldConfigInterface $field) {
|
||||
// Don't change anything during a configuration sync.
|
||||
if ($field->isSyncing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Act on all sub-types of the entity_reference field type.
|
||||
/** @var \Drupal\Core\Field\FieldTypePluginManager $field_type_manager */
|
||||
$field_type_manager = \Drupal::service('plugin.manager.field.field_type');
|
||||
$item_class = 'Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem';
|
||||
$class = $field_type_manager->getPluginClass($field->getType());
|
||||
if ($class !== $item_class && !is_subclass_of($class, $item_class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the selection handler plugin is the correct derivative for the
|
||||
// target entity type.
|
||||
$target_type = $field->getFieldStorageDefinition()->getSetting('target_type');
|
||||
$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));
|
||||
}
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Post update functions for Field.
|
||||
* Post update functions for Field module.
|
||||
*/
|
||||
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
|
||||
/**
|
||||
* @addtogroup updates-8.0.0-beta
|
||||
|
@ -23,6 +24,23 @@ function field_post_update_save_custom_storage_property() {
|
|||
return t('All field storage configuration objects re-saved.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes the 'handler' setting for entity reference fields.
|
||||
*/
|
||||
function field_post_update_entity_reference_handler_setting() {
|
||||
foreach (FieldConfig::loadMultiple() as $field_config) {
|
||||
$field_type_manager = \Drupal::service('plugin.manager.field.field_type');
|
||||
$item_class = 'Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem';
|
||||
$class = $field_type_manager->getPluginClass($field_config->getType());
|
||||
if ($class === $item_class || is_subclass_of($class, $item_class)) {
|
||||
// field_field_config_presave() will fix the 'handler' setting on save.
|
||||
$field_config->save();
|
||||
}
|
||||
}
|
||||
|
||||
return t('Selection handler for entity reference fields have been adjusted.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "addtogroup updates-8.0.0-beta".
|
||||
*/
|
||||
|
|
|
@ -303,20 +303,34 @@ class EntityReferenceItemTest extends FieldUnitTestBase {
|
|||
$field_storage->save();
|
||||
|
||||
// Do not specify any value for the 'handler' setting in order to verify
|
||||
// that the default value is properly used.
|
||||
// that the default handler with the correct derivative is used.
|
||||
$field = FieldConfig::create(array(
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => 'entity_test',
|
||||
));
|
||||
$field->save();
|
||||
|
||||
$field = FieldConfig::load($field->id());
|
||||
$this->assertTrue($field->getSetting('handler') == 'default:entity_test');
|
||||
$this->assertEqual($field->getSetting('handler'), 'default:entity_test');
|
||||
|
||||
// Change the target_type in the field storage, and check that the handler
|
||||
// was correctly reassigned in the field.
|
||||
$field_storage->setSetting('target_type', 'entity_test_rev');
|
||||
$field_storage->save();
|
||||
$field = FieldConfig::load($field->id());
|
||||
$this->assertEqual($field->getSetting('handler'), 'default:entity_test_rev');
|
||||
|
||||
// Change the handler to another, non-derivative plugin.
|
||||
$field->setSetting('handler', 'views');
|
||||
$field->save();
|
||||
$field = FieldConfig::load($field->id());
|
||||
$this->assertTrue($field->getSetting('handler') == 'views');
|
||||
$this->assertEqual($field->getSetting('handler'), 'views');
|
||||
|
||||
// Change the target_type in the field storage again, and check that the
|
||||
// non-derivative handler was unchanged.
|
||||
$field_storage->setSetting('target_type', 'entity_test_rev');
|
||||
$field_storage->save();
|
||||
$field = FieldConfig::load($field->id());
|
||||
$this->assertEqual($field->getSetting('handler'), 'views');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -79,9 +79,7 @@ class MigrateFieldInstanceTest extends MigrateDrupal6TestBase {
|
|||
'display_field' => FALSE,
|
||||
'display_default' => FALSE,
|
||||
'uri_scheme' => 'public',
|
||||
// This value should be 'default:file' but the test does not migrate field
|
||||
// storages so we end up with the default value for this setting.
|
||||
'handler' => 'default:node',
|
||||
'handler' => 'default:file',
|
||||
'handler_settings' => array(),
|
||||
);
|
||||
$field_settings = $field->getSettings();
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\field\Tests\Update\EntityReferenceHandlerSettingUpdateTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\field\Tests\Update;
|
||||
|
||||
use Drupal\system\Tests\Update\UpdatePathTestBase;
|
||||
|
||||
/**
|
||||
* Tests the update for the entity reference 'handler' setting.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class EntityReferenceHandlerSettingUpdateTest extends UpdatePathTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests field_post_update_entity_reference_handler_setting().
|
||||
*
|
||||
* @see field_post_update_entity_reference_handler_setting()
|
||||
*/
|
||||
public function testFieldPostUpdateERHandlerSetting() {
|
||||
$configFactory = $this->container->get('config.factory');
|
||||
|
||||
// Load the 'node.article.field_image' field config, and check that its
|
||||
// 'handler' setting is wrong.
|
||||
/** @var \Drupal\Core\Config\Config */
|
||||
$config = $configFactory->get('field.field.node.article.field_image');
|
||||
$settings = $config->get('settings');
|
||||
$this->assertEqual($settings['handler'], 'default:node');
|
||||
|
||||
// Run updates.
|
||||
$this->runUpdates();
|
||||
|
||||
// Reload the config, and check that the 'handler' setting has been fixed.
|
||||
$config = $configFactory->get('field.field.node.article.field_image');
|
||||
$settings = $config->get('settings');
|
||||
$this->assertEqual($settings['handler'], 'default:file');
|
||||
}
|
||||
|
||||
}
|
|
@ -10,6 +10,7 @@ namespace Drupal\file\Tests;
|
|||
use Drupal\Core\Field\FieldItemInterface;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Tests\FieldUnitTestBase;
|
||||
|
||||
/**
|
||||
|
@ -70,6 +71,12 @@ class FileItemTest extends FieldUnitTestBase {
|
|||
* Tests using entity fields of the file field type.
|
||||
*/
|
||||
public function testFileItem() {
|
||||
// Check that the selection handler was automatically assigned to
|
||||
// 'default:file'.
|
||||
$field_definition = FieldConfig::load('entity_test.entity_test.file_test');
|
||||
$handler_id = $field_definition->getSetting('handler');
|
||||
$this->assertEqual($handler_id, 'default:file');
|
||||
|
||||
// Create a test entity with the
|
||||
$entity = entity_create('entity_test');
|
||||
$entity->file_test->target_id = $this->file->id();
|
||||
|
|
|
@ -402,7 +402,6 @@ class Node extends ContentEntityBase implements NodeInterface {
|
|||
->setDescription(t('The username of the content author.'))
|
||||
->setRevisionable(TRUE)
|
||||
->setSetting('target_type', 'user')
|
||||
->setSetting('handler', 'default')
|
||||
->setDefaultValueCallback('Drupal\node\Entity\Node::getCurrentUserId')
|
||||
->setTranslatable(TRUE)
|
||||
->setDisplayOptions('view', array(
|
||||
|
|
|
@ -62,6 +62,7 @@ class UpdatePostUpdateTest extends UpdatePathTestBase {
|
|||
$updates = array_merge([
|
||||
'block_post_update_disable_blocks_with_missing_contexts',
|
||||
'field_post_update_save_custom_storage_property',
|
||||
'field_post_update_entity_reference_handler_setting',
|
||||
'system_post_update_fix_enforced_dependencies',
|
||||
'views_post_update_update_cacheability_metadata',
|
||||
], $updates);
|
||||
|
|
|
@ -32,6 +32,6 @@ settings:
|
|||
title: ''
|
||||
width: null
|
||||
height: null
|
||||
handler: 'default:node'
|
||||
handler: 'default:file'
|
||||
handler_settings: { }
|
||||
field_type: image
|
||||
|
|
|
@ -32,6 +32,6 @@ settings:
|
|||
height: null
|
||||
alt_field_required: false
|
||||
title_field_required: false
|
||||
handler: 'default:node'
|
||||
handler: 'default:file'
|
||||
handler_settings: { }
|
||||
field_type: image
|
||||
|
|
Loading…
Reference in New Issue