Issue #2346297 by fago: Move getting option providers to field definitions.

8.0.x
webchick 2014-09-28 16:14:33 -07:00
parent 64d6915d5b
commit e18b616131
6 changed files with 56 additions and 9 deletions

View File

@ -11,6 +11,7 @@ use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Field\Entity\BaseFieldOverride; use Drupal\Core\Field\Entity\BaseFieldOverride;
use Drupal\Core\Field\TypedData\FieldItemDataDefinition; use Drupal\Core\Field\TypedData\FieldItemDataDefinition;
use Drupal\Core\TypedData\ListDataDefinition; use Drupal\Core\TypedData\ListDataDefinition;
use Drupal\Core\TypedData\OptionsProviderInterface;
/** /**
* A class for defining entity fields. * A class for defining entity fields.
@ -431,6 +432,19 @@ class BaseFieldDefinition extends ListDataDefinition implements FieldDefinitionI
return $this; return $this;
} }
/**
* {@inheritdoc}
*/
public function getOptionsProvider($property_name, ContentEntityInterface $entity) {
// If the field item class implements the interface, proxy it through.
$item = $entity->get($this->getName())->first();
if ($item instanceof OptionsProviderInterface) {
return $item;
}
// @todo: Allow setting custom options provider, see
// https://www.drupal.org/node/2002138.
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

View File

@ -7,6 +7,8 @@
namespace Drupal\Core\Field; namespace Drupal\Core\Field;
use Drupal\Core\Entity\ContentEntityInterface;
/** /**
* Defines an interface for entity field storage definitions. * Defines an interface for entity field storage definitions.
* *
@ -130,6 +132,19 @@ interface FieldStorageDefinitionInterface {
*/ */
public function getDescription(); public function getDescription();
/**
* Gets an options provider for the given field item property.
*
* @param string $property_name
* The name of the property to get options for; e.g., 'value'.
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* The entity for which the options should be provided.
*
* @return \Drupal\Core\TypedData\OptionsProviderInterface|null
* An options provider, or NULL if no options are defined.
*/
public function getOptionsProvider($property_name, ContentEntityInterface $entity);
/** /**
* Returns whether the field can contain multiple items. * Returns whether the field can contain multiple items.
* *

View File

@ -10,9 +10,11 @@ namespace Drupal\field\Entity;
use Drupal\Component\Utility\String; use Drupal\Component\Utility\String;
use Drupal\Component\Utility\Unicode; use Drupal\Component\Utility\Unicode;
use Drupal\Core\Config\Entity\ConfigEntityBase; use Drupal\Core\Config\Entity\ConfigEntityBase;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Field\FieldException; use Drupal\Core\Field\FieldException;
use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\TypedData\OptionsProviderInterface;
use Drupal\field\FieldStorageConfigInterface; use Drupal\field\FieldStorageConfigInterface;
/** /**
@ -580,6 +582,19 @@ class FieldStorageConfig extends ConfigEntityBase implements FieldStorageConfigI
return FALSE; return FALSE;
} }
/**
* {@inheritdoc}
*/
public function getOptionsProvider($property_name, ContentEntityInterface $entity) {
// If the field item class implements the interface, proxy it through.
$item = $entity->get($this->getName())->first();
if ($item instanceof OptionsProviderInterface) {
return $item;
}
// @todo: Allow setting custom options provider, see
// https://www.drupal.org/node/2002138.
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

View File

@ -33,7 +33,7 @@ class ButtonsWidget extends OptionsWidgetBase {
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$element = parent::formElement($items, $delta, $element, $form, $form_state); $element = parent::formElement($items, $delta, $element, $form, $form_state);
$options = $this->getOptions($items[$delta]); $options = $this->getOptions($items->getEntity());
$selected = $this->getSelectedOptions($items); $selected = $this->getSelectedOptions($items);
// If required and there is one single option, preselect it. // If required and there is one single option, preselect it.

View File

@ -7,9 +7,9 @@
namespace Drupal\options\Plugin\Field\FieldWidget; namespace Drupal\options\Plugin\Field\FieldWidget;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FieldItemInterface;
use Drupal\Core\Field\WidgetBase; use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
@ -114,16 +114,19 @@ abstract class OptionsWidgetBase extends WidgetBase {
/** /**
* Returns the array of options for the widget. * Returns the array of options for the widget.
* *
* @param \Drupal\Core\Field\FieldItemInterface $item * @param \Drupal\Core\Entity\ContentEntityInterface $entity
* The field item. * The entity for which to return options.
* *
* @return array * @return array
* The array of options for the widget. * The array of options for the widget.
*/ */
protected function getOptions(FieldItemInterface $item) { protected function getOptions(ContentEntityInterface $entity) {
if (!isset($this->options)) { if (!isset($this->options)) {
// Limit the settable options for the current user account. // Limit the settable options for the current user account.
$options = $item->getSettableOptions(\Drupal::currentUser()); $options = $this->fieldDefinition
->getFieldStorageDefinition()
->getOptionsProvider($this->column, $entity)
->getSettableOptions(\Drupal::currentUser());
// Add an empty option if the widget needs one. // Add an empty option if the widget needs one.
if ($empty_option = $this->getEmptyOption()) { if ($empty_option = $this->getEmptyOption()) {
@ -143,7 +146,7 @@ abstract class OptionsWidgetBase extends WidgetBase {
$module_handler = \Drupal::moduleHandler(); $module_handler = \Drupal::moduleHandler();
$context = array( $context = array(
'fieldDefinition' => $this->fieldDefinition, 'fieldDefinition' => $this->fieldDefinition,
'entity' => $item->getEntity(), 'entity' => $entity,
); );
$module_handler->alter('options_list', $options, $context); $module_handler->alter('options_list', $options, $context);
@ -173,7 +176,7 @@ abstract class OptionsWidgetBase extends WidgetBase {
*/ */
protected function getSelectedOptions(FieldItemListInterface $items, $delta = 0) { protected function getSelectedOptions(FieldItemListInterface $items, $delta = 0) {
// We need to check against a flat list of options. // We need to check against a flat list of options.
$flat_options = $this->flattenOptions($this->getOptions($items[$delta])); $flat_options = $this->flattenOptions($this->getOptions($items->getEntity()));
$selected_options = array(); $selected_options = array();
foreach ($items as $item) { foreach ($items as $item) {

View File

@ -35,7 +35,7 @@ class SelectWidget extends OptionsWidgetBase {
$element += array( $element += array(
'#type' => 'select', '#type' => 'select',
'#options' => $this->getOptions($items[$delta]), '#options' => $this->getOptions($items->getEntity()),
'#default_value' => $this->getSelectedOptions($items, $delta), '#default_value' => $this->getSelectedOptions($items, $delta),
// Do not display a 'multiple' select box if there is only one option. // Do not display a 'multiple' select box if there is only one option.
'#multiple' => $this->multiple && count($this->options) > 1, '#multiple' => $this->multiple && count($this->options) > 1,