diff --git a/core/lib/Drupal/Core/TypedData/AllowedValuesInterface.php b/core/lib/Drupal/Core/TypedData/AllowedValuesInterface.php index 5227ed2..6715625 100644 --- a/core/lib/Drupal/Core/TypedData/AllowedValuesInterface.php +++ b/core/lib/Drupal/Core/TypedData/AllowedValuesInterface.php @@ -10,12 +10,12 @@ * Interface for retrieving allowed values. * * While allowed values define the values that are allowed to be set by a user, - * the available values may be used to get the list of possible values that may - * be already set on an object. + * possible values specify which values existing data might have. + * * For example, in an workflow scenario the allowed options for a state field - * depend on the currently set state, while available options are all states. - * Thus allowed values would be used during any editing context, while available - * values would be used when e.g. filtering for existing values. + * might depend on the currently set state, while possible options are all + * states. Thus allowed values would be used during any editing context, while + * possible values would be used for presenting filtering options in a search. */ interface AllowedValuesInterface { @@ -37,37 +37,39 @@ public function getValues($account = NULL); * (optional) The user account for which to generate the allowed options. * * @return array - * The array of allowed options for the object. Array keys are the values as - * expected by the object. Array values are the labels to display; e.g., - * within a widget. The labels should NOT be sanitized. + * The array of allowed options for the object; e.g. for display within a + * widget. This is either a flat array of option labels keyed by values, or + * a multi-dimensional array of option groups; i.e., an array of flat option + * arrays, keyed by option group label. Labels should NOT be sanitized. * * @see Drupal\Core\TypedData\AllowedValuesInterface::getValues() */ public function getOptions($account = NULL); /** - * Returns an array of available values. + * Returns an array of possible values. * * @param object $account - * (optional) The user account for which to generate the available values. + * (optional) The user account for which to generate the possible values. * * @return array - * An array of available values. + * An array of possible values. */ - public function getAvailableValues($account = NULL); + public function getPossibleValues($account = NULL); /** - * Returns an array of available options. + * Returns an array of possible options. * * @param object $account - * (optional) The user account for which to generate the available options. + * (optional) The user account for which to generate the possible options. * * @return array - * The array of available options for the object. Array keys are the values - * as expected by the object. Array values are the labels to display; e.g., - * within a widget. The labels should NOT be sanitized. + * The array of possible options for the object; e.g. for display within a + * widget. This is either a flat array of option labels keyed by values, or + * a multi-dimensional array of option groups; i.e., an array of flat option + * arrays, keyed by option group label. Labels should NOT be sanitized. * * @see Drupal\Core\TypedData\AllowedValuesInterface::getOptions() */ - public function getAvailableOptions($account = NULL); + public function getPossibleOptions($account = NULL); } diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigEntityReferenceItemBase.php b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigEntityReferenceItemBase.php index 7406134..40b6781 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigEntityReferenceItemBase.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigEntityReferenceItemBase.php @@ -147,6 +147,20 @@ public function instanceSettingsForm(array $form, array &$form_state) { } /** + * Returns options provided via hook_options_list(). + * + * @see \Drupal\Core\TypedData\AllowedValuesInterface + */ + public function getOptions() { + $definition = $this->getPluginDefinition(); + $callback = "{$definition['module']}_options_list"; + if (function_exists($callback)) { + $entity = $this->getParent()->getParent(); + return $callback($this->getInstance(), $entity); + } + } + + /** * Returns the legacy callback for a given field type "hook". * * Copied from \Drupal\field\Plugin\field\field_type\LegacyConfigFieldItem, diff --git a/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php b/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php index 0f122b6..58e83d4 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php +++ b/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php @@ -107,6 +107,20 @@ public function prepareCache() { } /** + * Returns options provided via hook_options_list(). + * + * @see \Drupal\Core\TypedData\AllowedValuesInterface + */ + public function getOptions() { + $definition = $this->getPluginDefinition(); + $callback = "{$definition['module']}_options_list"; + if (function_exists($callback)) { + $entity = $this->getParent()->getParent(); + return $callback($this->getInstance(), $entity); + } + } + + /** * Returns the legacy callback for a given field type "hook". * * @param string $hook diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterAPITest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterAPITest.php index 202757f..08dabf1 100644 --- a/core/modules/filter/lib/Drupal/filter/Tests/FilterAPITest.php +++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterAPITest.php @@ -31,7 +31,7 @@ function setUp() { parent::setUp(); $this->installConfig(array('system', 'filter')); - $this->installSchema('user', array('role_permission', 'users_roles')); + $this->installSchema('user', array('users_roles')); // Create Filtered HTML format. $filtered_html_format = entity_create('filter_format', array( @@ -204,9 +204,9 @@ function testTypedDataAPI() { // Test with anonymous user. $GLOBALS['user'] = drupal_anonymous_user(); - $available_values = $data->getAvailableValues(); + $available_values = $data->getPossibleValues(); $this->assertEqual($available_values, array('filtered_html', 'full_html', 'plain_text')); - $available_options = $data->getAvailableOptions(); + $available_options = $data->getPossibleOptions(); $expected_available_options = array( 'filtered_html' => 'Filtered HTML', 'full_html' => 'Full HTML', diff --git a/core/modules/filter/lib/Drupal/filter/Type/FilterFormat.php b/core/modules/filter/lib/Drupal/filter/Type/FilterFormat.php index cf3aba8..c3fc852 100644 --- a/core/modules/filter/lib/Drupal/filter/Type/FilterFormat.php +++ b/core/modules/filter/lib/Drupal/filter/Type/FilterFormat.php @@ -18,14 +18,14 @@ class FilterFormat extends String implements AllowedValuesInterface { /** * {@inheritdoc} */ - public function getAvailableValues($account = NULL) { - return array_keys($this->getAvailableOptions()); + public function getPossibleValues($account = NULL) { + return array_keys($this->getPossibleOptions()); } /** * {@inheritdoc} */ - public function getAvailableOptions($account = NULL) { + public function getPossibleOptions($account = NULL) { $values = array(); foreach (filter_formats() as $format) { $values[$format->id()] = $format->label(); diff --git a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php b/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php index f6801c0..cc27f07 100644 --- a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php +++ b/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php @@ -12,6 +12,13 @@ /** * Base class for the 'options_*' widgets. + * + * Field types willing to enable one or several of the widgets defined in + * options.module (select, radios/checkboxes, on/off checkbox) need to + * implement the AllowedValuesInterface to specify the list of options to + * display in the widgets. + * + * @see \Drupal\Core\TypedData\AllowedValuesInterface */ abstract class OptionsWidgetBase extends WidgetBase { @@ -106,17 +113,19 @@ public static function validateElement(array $element, array &$form_state) { /** * Returns the array of options for the widget. * + * @param int $delta + * (optional) The delta of the item to get options for. Defaults to 0. + * * @return array * The array of options for the widget. */ - protected function getOptions() { + protected function getOptions($delta = 0) { if (!isset($this->options)) { $module_handler = \Drupal::moduleHandler(); // Get the list of options from the field type module, and sanitize them. - $field_type_info = field_info_field_types($this->fieldDefinition->getFieldType()); - $module = $field_type_info['module']; - $options = (array) $module_handler->invoke($module, 'options_list', array($this->fieldDefinition, $this->entity)); + $items = $this->entity->getNGEntity()->get($this->fieldDefinition->getFieldName()); + $options = $items[$delta]->getOptions(); // Add an empty option if the widget needs one. if ($empty_option = $this->getEmptyOption()) { @@ -157,13 +166,14 @@ protected function getOptions() { * * @param array $items * The field values. - * + * @param int $delta + * (optional) The delta of the item to get options for. Defaults to 0. * @return array * The array of corresponding selected options. */ - protected function getSelectedOptions(array $items) { + protected function getSelectedOptions(array $items, $delta = 0) { // We need to check against a flat list of options. - $flat_options = $this->flattenOptions($this->getOptions()); + $flat_options = $this->flattenOptions($this->getOptions($delta)); $selected_options = array(); foreach ($items as $item) { diff --git a/core/modules/options/lib/Drupal/options/Plugin/field/widget/SelectWidget.php b/core/modules/options/lib/Drupal/options/Plugin/field/widget/SelectWidget.php index b17a448..4ca9ed2 100644 --- a/core/modules/options/lib/Drupal/options/Plugin/field/widget/SelectWidget.php +++ b/core/modules/options/lib/Drupal/options/Plugin/field/widget/SelectWidget.php @@ -35,8 +35,8 @@ public function formElement(array $items, $delta, array $element, $langcode, arr $element += array( '#type' => 'select', - '#options' => $this->getOptions(), - '#default_value' => $this->getSelectedOptions($items), + '#options' => $this->getOptions($delta), + '#default_value' => $this->getSelectedOptions($items, $delta), // Do not display a 'multiple' select box if there is only one option. '#multiple' => $this->multiple && count($this->options) > 1, ); diff --git a/core/modules/options/options.api.php b/core/modules/options/options.api.php index 5e8c694..152ed70 100644 --- a/core/modules/options/options.api.php +++ b/core/modules/options/options.api.php @@ -6,66 +6,6 @@ */ /** - * Returns the list of options to be displayed for a field. - * - * Field types willing to enable one or several of the widgets defined in - * options.module (select, radios/checkboxes, on/off checkbox) need to - * implement this hook to specify the list of options to display in the - * widgets. - * - * @param \Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition - * The field definition. - * @param \Drupal\Core\Entity\EntityInterface $entity - * The entity object the field is attached to. - * - * @return - * The array of options for the field. Array keys are the values to be - * stored, and should be of the data type (string, number...) expected by - * the first 'column' for the field type. Array values are the labels to - * display within the widgets. The labels should NOT be sanitized, - * options.module takes care of sanitation according to the needs of each - * widget. The HTML tags defined in _field_filter_xss_allowed_tags() are - * allowed, other tags will be filtered. - */ -function hook_options_list(\Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition, \Drupal\Core\Entity\EntityInterface $entity) { - // Sample structure. - $options = array( - 0 => t('Zero'), - 1 => t('One'), - 2 => t('Two'), - 3 => t('Three'), - ); - - // Sample structure with groups. Only one level of nesting is allowed. This - // is only supported by the 'options_select' widget. Other widgets will - // flatten the array. - $options = array( - t('First group') => array( - 0 => t('Zero'), - ), - t('Second group') => array( - 1 => t('One'), - 2 => t('Two'), - ), - 3 => t('Three'), - ); - - // In actual implementations, the array of options will most probably depend - // on properties of the field. Example from taxonomy.module: - $options = array(); - foreach ($field_definition->getFieldSetting('allowed_values') as $tree) { - $terms = taxonomy_get_tree($tree['vid'], $tree['parent'], NULL, TRUE); - if ($terms) { - foreach ($terms as $term) { - $options[$term->id()] = str_repeat('-', $term->depth) . $term->label(); - } - } - } - - return $options; -} - -/** * Alters the list of options to be displayed for a field. * * This hook can notably be used to change the label of the empty option.