Commit ae4848f5 authored by alexpott's avatar alexpott

Issue #2436835 by amateescu, alexpott: Unable to create config schema for...

Issue #2436835 by amateescu, alexpott: Unable to create config schema for entity type specific entity reference selection plugin
parent eaffcfc5
......@@ -552,7 +552,7 @@ field.value.changed:
field.storage_settings.entity_reference:
type: mapping
label: 'Entity reference settings'
label: 'Entity reference field storage settings'
mapping:
target_type:
type: string
......@@ -560,14 +560,14 @@ field.storage_settings.entity_reference:
field.field_settings.entity_reference:
type: mapping
label: 'Entity reference settings'
label: 'Entity reference field settings'
mapping:
handler:
type: string
label: 'Reference method'
handler_settings:
type: entity_reference.[%parent.handler].handler_settings
label: 'Reference method settings'
type: entity_reference_selection.[%parent.handler]
label: 'Entity reference selection plugin settings'
field.value.entity_reference:
type: mapping
......@@ -750,3 +750,32 @@ text_format:
label: 'Text format'
# The text format should not be translated as part of the string
# translation system, so this is not marked as translatable.
# Schema for the configuration of the Entity reference selection plugins.
entity_reference_selection:
type: mapping
label: 'Entity reference selection plugin configuration'
mapping:
target_bundles:
type: sequence
label: 'types'
sequence:
type: string
label: 'Type'
sort:
type: mapping
label: 'Sort settings'
mapping:
field:
type: string
label: 'Sort by'
direction:
type: string
label: 'Sort direction'
auto_create:
type: boolean
label: 'Create referenced entities if they don''t already exist'
entity_reference_selection.*:
type: entity_reference_selection
......@@ -45,19 +45,35 @@ public function getInstance(array $options) {
// Initialize default options.
$options += array(
'handler' => 'default',
'handler' => $this->getPluginId($options['target_type'], 'default'),
'handler_settings' => array(),
);
// A specific selection plugin ID was already specified.
if (strpos($options['handler'], ':') !== FALSE) {
$plugin_id = $options['handler'];
}
// Only a selection group name was specified.
else {
$plugin_id = $this->getPluginId($options['target_type'], $options['handler']);
}
return $this->createInstance($plugin_id, $options);
}
/**
* {@inheritdoc}
*/
public function getPluginId($target_type, $base_plugin_id) {
// Get all available selection plugins for this entity type.
$selection_handler_groups = $this->getSelectionGroups($options['target_type']);
$selection_handler_groups = $this->getSelectionGroups($target_type);
// Sort the selection plugins by weight and select the best match.
uasort($selection_handler_groups[$options['handler']], array('Drupal\Component\Utility\SortArray', 'sortByWeightElement'));
end($selection_handler_groups[$options['handler']]);
$plugin_id = key($selection_handler_groups[$options['handler']]);
uasort($selection_handler_groups[$base_plugin_id], array('Drupal\Component\Utility\SortArray', 'sortByWeightElement'));
end($selection_handler_groups[$base_plugin_id]);
$plugin_id = key($selection_handler_groups[$base_plugin_id]);
return $this->createInstance($plugin_id, $options);
return $plugin_id;
}
/**
......@@ -86,7 +102,7 @@ public function getSelectionHandler(FieldDefinitionInterface $field_definition,
$options = array(
'target_type' => $field_definition->getFieldStorageDefinition()->getSetting('target_type'),
'handler' => $field_definition->getSetting('handler'),
'handler_settings' => $field_definition->getSetting('handler_settings'),
'handler_settings' => $field_definition->getSetting('handler_settings') ?: array(),
'entity' => $entity,
);
return $this->getInstance($options);
......
......@@ -16,6 +16,19 @@
*/
interface SelectionPluginManagerInterface extends PluginManagerInterface {
/**
* Gets the plugin ID for a given target entity type and base plugin ID.
*
* @param string $target_type
* The target entity type.
* @param string $base_plugin_id
* The base plugin ID (e.g. 'default' or 'views').
*
* @return string
* The plugin ID.
*/
public function getPluginId($target_type, $base_plugin_id);
/**
* Returns selection plugins that can reference a specific entity type.
*
......
......@@ -59,7 +59,8 @@ public static function defaultStorageSettings() {
*/
public static function defaultFieldSettings() {
return array(
'handler' => 'default',
'handler' => 'default:' . (\Drupal::moduleHandler()->moduleExists('node') ? 'node' : 'user'),
'handler_settings' => array(),
) + parent::defaultFieldSettings();
}
......
# Schema for the configuration files of the Entity Reference module.
entity_reference.default.handler_settings:
type: mapping
label: 'View handler settings'
mapping:
target_bundles:
type: sequence
label: 'types'
sequence:
type: string
label: 'Type'
sort:
type: mapping
label: 'Sort settings'
mapping:
field:
type: string
label: 'Sort by'
direction:
type: string
label: 'Sort direction'
filter:
type: mapping
label: 'Filter settings'
mapping:
type:
type: string
label: 'Filter by'
role:
type: sequence
label: 'Restrict to the selected roles'
sequence:
type: string
label: 'Role'
auto_create:
type: boolean
label: 'Create referenced entities if they don''t already exist'
include_anonymous:
type: boolean
label: 'Include the anonymous user in the matched entities.'
......@@ -13,6 +13,7 @@
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\FieldStorageConfigInterface;
use Drupal\field\FieldConfigInterface;
/**
* Implements hook_help().
......@@ -84,20 +85,33 @@ function entity_reference_field_storage_config_update(FieldStorageConfigInterfac
return;
}
if (empty($field_storage->bundles)) {
// Field storage has no fields.
return;
foreach ($field_storage->getBundles() as $bundle) {
$field = FieldConfig::loadByName($field_storage->getTargetEntityTypeId(), $bundle, $field_storage->getName());
$field->settings['handler_settings'] = array();
$field->save();
}
}
$field_name = $field_storage->getName();
/**
* 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;
}
foreach ($field_storage->bundles() as $entity_type => $bundles) {
foreach ($bundles as $bundle) {
$field = FieldConfig::loadByName($entity_type, $bundle, $field_name);
$field->settings['handler_settings'] = array();
$field->save();
}
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->settings['handler'] = $selection_manager->getPluginId($target_type, $current_handler);
}
/**
......
......@@ -42,15 +42,6 @@ public static function defaultStorageSettings() {
return $settings;
}
/**
* {@inheritdoc}
*/
public static function defaultFieldSettings() {
return array(
'handler_settings' => array(),
) + parent::defaultFieldSettings();
}
/**
* {@inheritdoc}
*/
......@@ -149,7 +140,7 @@ public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
}
elseif (array_key_exists($selection_group_id . ':' . $this->getSetting('target_type'), $selection_plugins[$selection_group_id])) {
$selection_group_plugin = $selection_group_id . ':' . $this->getSetting('target_type');
$handlers_options[$selection_group_id] = String::checkPlain($selection_plugins[$selection_group_id][$selection_group_plugin]['base_plugin_label']);
$handlers_options[$selection_group_plugin] = String::checkPlain($selection_plugins[$selection_group_id][$selection_group_plugin]['base_plugin_label']);
}
}
......
......@@ -78,7 +78,7 @@ public function testFieldAdminHandler() {
$this->drupalPostForm(NULL, array(), t('Save field settings'));
// The base handler should be selected by default.
$this->assertFieldByName('field[settings][handler]', 'default');
$this->assertFieldByName('field[settings][handler]', 'default:node');
// The base handler settings should be displayed.
$entity_type_id = 'node';
......
......@@ -11,6 +11,8 @@
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FieldItemInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\field\Tests\FieldUnitTestBase;
use Drupal\taxonomy\Entity\Term;
use Drupal\taxonomy\Entity\Vocabulary;
......@@ -27,7 +29,7 @@ class EntityReferenceItemTest extends FieldUnitTestBase {
*
* @var array
*/
public static $modules = array('entity_reference', 'taxonomy', 'text', 'filter');
public static $modules = array('entity_reference', 'taxonomy', 'text', 'filter', 'views');
/**
* The taxonomy vocabulary to test with.
......@@ -214,4 +216,36 @@ public function testEntitySaveOrder() {
$this->assertEqual($entity->field_test_taxonomy_term->entity->id(), $term->id());
}
/**
* Tests that the 'handler' field setting stores the proper plugin ID.
*/
public function testSelectionHandlerSettings() {
$field_name = Unicode::strtolower($this->randomMachineName());
$field_storage = FieldStorageConfig::create(array(
'field_name' => $field_name,
'entity_type' => 'entity_test',
'type' => 'entity_reference',
'settings' => array(
'target_type' => 'entity_test'
),
));
$field_storage->save();
// Do not specify any value for the 'handler' setting in order to verify
// that the default value is properly 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');
$field->settings['handler'] = 'views';
$field->save();
$field = FieldConfig::load($field->id());
$this->assertTrue($field->getSetting('handler') == 'views');
}
}
......@@ -46,6 +46,9 @@ base_file_field_field_settings:
handler:
type: string
label: 'Reference method'
handler_settings:
type: entity_reference_selection.[%parent.handler]
label: 'Entity reference selection settings'
file_directory:
type: string
label: 'File directory'
......
......@@ -134,12 +134,17 @@ public function testFieldInstanceSettings() {
'display_field' => FALSE,
'display_default' => FALSE,
'uri_scheme' => 'public',
'handler' => 'default',
// 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_settings' => array(),
'target_bundle' => NULL,
);
$field_settings = $field->getSettings();
ksort($expected);
ksort($field_settings);
// This is the only way to compare arrays.
$this->assertFalse(array_diff_assoc($field->getSettings(), $expected));
$this->assertFalse(array_diff_assoc($expected, $field->getSettings()));
$this->assertIdentical($expected, $field_settings);
// Test a link field.
$field = FieldConfig::load('node.story.field_test_link');
......
......@@ -62,6 +62,9 @@ field.field_settings.taxonomy_term_reference:
handler:
type: string
label: 'Reference method'
handler_settings:
type: entity_reference_selection.[%parent.handler]
label: 'Entity reference selection settings'
field.value.taxonomy_term_reference:
type: mapping
......
......@@ -47,6 +47,15 @@ public static function defaultStorageSettings() {
) + parent::defaultStorageSettings();
}
/**
* {@inheritdoc}
*/
public static function defaultFieldSettings() {
return array(
'handler' => 'default:taxonomy_term',
) + parent::defaultFieldSettings();
}
/**
* {@inheritdoc}
*/
......
......@@ -174,3 +174,23 @@ condition.plugin.user_role:
type: sequence
sequence:
type: string
entity_reference_selection.default:user:
type: entity_reference_selection
mapping:
filter:
type: mapping
label: 'Filter settings'
mapping:
type:
type: string
label: 'Filter by'
role:
type: sequence
label: 'Restrict to the selected roles'
sequence:
type: string
label: 'Role'
include_anonymous:
type: boolean
label: 'Include the anonymous user in the matched entities.'
# Schema for the views entity reference selection plugins.
entity_reference.views.handler_settings:
entity_reference_selection.views:
type: mapping
label: 'View handler settings'
mapping:
......
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