From edc0ccc1badc1c4af2f3bfbe66d2d78a4eba5458 Mon Sep 17 00:00:00 2001 From: Nathaniel Catchpole Date: Wed, 5 Feb 2014 10:50:00 +0000 Subject: [PATCH] Issue #2160575 by agentrickard, amateescu, plopesc: Option widgets integration is broken for the entity reference field. --- .../entity_reference/entity_reference.module | 21 ------ .../ConfigurableEntityReferenceItem.php | 69 ++++++++++++++++++- .../Tests/EntityReferenceIntegrationTest.php | 20 +++++- .../selection/TermSelection.php | 5 +- 4 files changed, 89 insertions(+), 26 deletions(-) diff --git a/core/modules/entity_reference/entity_reference.module b/core/modules/entity_reference/entity_reference.module index 7f6b51c30c2..7f79580b0b0 100644 --- a/core/modules/entity_reference/entity_reference.module +++ b/core/modules/entity_reference/entity_reference.module @@ -167,27 +167,6 @@ function entity_reference_settings_ajax_submit($form, &$form_state) { $form_state['rebuild'] = TRUE; } -/** - * Implements hook_options_list(). - */ -function entity_reference_options_list(FieldDefinitionInterface $field_definition, EntityInterface $entity) { - if (!$options = \Drupal::service('plugin.manager.entity_reference.selection')->getSelectionHandler($field_definition, $entity)->getReferenceableEntities()) { - return array(); - } - - // Rebuild the array by changing the bundle key into the bundle label. - $target_type = $field_definition->getSetting('target_type'); - $bundles = entity_get_bundles($target_type); - - $return = array(); - foreach ($options as $bundle => $entity_ids) { - $bundle_label = check_plain($bundles[$bundle]['label']); - $return[$bundle_label] = $entity_ids; - } - - return count($return) == 1 ? reset($return) : $return; -} - /** * Implements hook_query_TAG_alter(). */ diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php b/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php index 1a2a6181e1a..73cee86ed7b 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php @@ -7,10 +7,14 @@ namespace Drupal\entity_reference; +use Drupal\Component\Utility\String; +use Drupal\Core\Session\AccountInterface; +use Drupal\Core\TypedData\AllowedValuesInterface; use Drupal\Core\TypedData\DataDefinition; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\ConfigEntityReferenceItemBase; use Drupal\Core\Field\ConfigFieldItemInterface; +use Drupal\Core\Validation\Plugin\Validation\Constraint\AllowedValuesConstraint; /** * Alternative plugin implementation of the 'entity_reference' field type. @@ -24,7 +28,53 @@ use Drupal\Core\Field\ConfigFieldItemInterface; * @see entity_reference_field_info_alter(). * */ -class ConfigurableEntityReferenceItem extends ConfigEntityReferenceItemBase implements ConfigFieldItemInterface { +class ConfigurableEntityReferenceItem extends ConfigEntityReferenceItemBase implements ConfigFieldItemInterface, AllowedValuesInterface { + + /** + * {@inheritdoc} + */ + public function getPossibleValues(AccountInterface $account = NULL) { + return $this->getSettableValues($account); + } + + /** + * {@inheritdoc} + */ + public function getPossibleOptions(AccountInterface $account = NULL) { + return $this->getSettableOptions($account); + } + + /** + * {@inheritdoc} + */ + public function getSettableValues(AccountInterface $account = NULL) { + // Flatten options firstly, because Settable Options may contain group + // arrays. + $flatten_options = \Drupal::formBuilder()->flattenOptions($this->getSettableOptions($account)); + return array_keys($flatten_options); + } + + /** + * {@inheritdoc} + */ + public function getSettableOptions(AccountInterface $account = NULL) { + $field_definition = $this->getFieldDefinition(); + if (!$options = \Drupal::service('plugin.manager.entity_reference.selection')->getSelectionHandler($field_definition, $this->getEntity())->getReferenceableEntities()) { + return array(); + } + + // Rebuild the array by changing the bundle key into the bundle label. + $target_type = $field_definition->getSetting('target_type'); + $bundles = \Drupal::entityManager()->getBundleInfo($target_type); + + $return = array(); + foreach ($options as $bundle => $entity_ids) { + $bundle_label = String::checkPlain($bundles[$bundle]['label']); + $return[$bundle_label] = $entity_ids; + } + + return count($return) == 1 ? reset($return) : $return; + } /** * Definitions of the contained properties. @@ -63,6 +113,23 @@ class ConfigurableEntityReferenceItem extends ConfigEntityReferenceItemBase impl return static::$propertyDefinitions[$key]; } + /** + * {@inheritdoc} + */ + public function getConstraints() { + $constraints = parent::getConstraints(); + + // Remove the 'AllowedValuesConstraint' validation constraint because entity + // reference fields already use the 'ValidReference' constraint. + foreach ($constraints as $key => $constraint) { + if ($constraint instanceof AllowedValuesConstraint) { + unset($constraints[$key]); + } + } + + return $constraints; + } + /** * {@inheritdoc} */ diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceIntegrationTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceIntegrationTest.php index 76efe3d4c8a..3a892b2652f 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceIntegrationTest.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceIntegrationTest.php @@ -40,7 +40,7 @@ class EntityReferenceIntegrationTest extends WebTestBase { * * @var array */ - public static $modules = array('config_test', 'entity_test', 'entity_reference'); + public static $modules = array('config_test', 'entity_test', 'entity_reference', 'options'); public static function getInfo() { return array( @@ -62,7 +62,7 @@ class EntityReferenceIntegrationTest extends WebTestBase { } /** - * Tests the entity reference field with all its widgets. + * Tests the entity reference field with all its supported field widgets. */ public function testSupportedEntityTypesAndWidgets() { foreach ($this->getTestEntities() as $referenced_entities) { @@ -111,6 +111,22 @@ class EntityReferenceIntegrationTest extends WebTestBase { $entity = current(entity_load_multiple_by_properties($this->entityType, array('name' => $entity_name))); $this->drupalPostForm($this->entityType . '/manage/' . $entity->id(), array(), t('Save')); $this->assertFieldValues($entity_name, $referenced_entities); + + // Test all the other widgets supported by the entity reference field. + // Since we don't know the form structure for these widgets, just test + // that editing and saving an already created entity works. + $entity = current(entity_load_multiple_by_properties($this->entityType, array('name' => $entity_name))); + $supported_widgets = \Drupal::service('plugin.manager.field.widget')->getOptions('entity_reference'); + $supported_widget_types = array_diff(array_keys($supported_widgets), array('entity_reference_autocomplete', 'entity_reference_autocomplete_tags')); + + foreach ($supported_widget_types as $widget_type) { + entity_get_form_display($this->entityType, $this->bundle, 'default')->setComponent($this->fieldName, array( + 'type' => $widget_type, + ))->save(); + + $this->drupalPostForm($this->entityType . '/manage/' . $entity->id(), array(), t('Save')); + $this->assertFieldValues($entity_name, $referenced_entities); + } } } diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/entity_reference/selection/TermSelection.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/entity_reference/selection/TermSelection.php index 7894242fc52..43648452274 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/entity_reference/selection/TermSelection.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/entity_reference/selection/TermSelection.php @@ -7,6 +7,7 @@ namespace Drupal\taxonomy\Plugin\entity_reference\selection; +use Drupal\Component\Utility\String; use Drupal\Core\Database\Query\SelectInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase; @@ -63,9 +64,9 @@ class TermSelection extends SelectionBase { foreach ($bundle_names as $bundle) { if ($vocabulary = entity_load('taxonomy_vocabulary', $bundle)) { - if ($terms = taxonomy_get_tree($vocabulary->id(), 0)) { + if ($terms = taxonomy_get_tree($vocabulary->id(), 0, NULL, TRUE)) { foreach ($terms as $term) { - $options[$vocabulary->id()][$term->id()] = str_repeat('-', $term->depth) . check_plain($term->name); + $options[$vocabulary->id()][$term->id()] = str_repeat('-', $term->depth) . String::checkPlain($term->label()); } } }