diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php index 57e4243..34640d4 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php @@ -235,7 +235,7 @@ protected function doSave($id, EntityInterface $entity) { } // Retrieve the desired properties and set them in config. - foreach ($entity->toArray() as $key => $value) { + foreach ($this->preSaveData($entity->toArray(), $entity) as $key => $value) { $config->set($key, $value); } $config->save(); @@ -244,6 +244,21 @@ protected function doSave($id, EntityInterface $entity) { } /** + * Alter data for the storage environment right before saving. + * + * @param array $data + * Raw configuration data being saved. + * @param \Drupal\Core\Entity\EntityInterface $entity + * Entity being saved. + * + * @return array + * Data to save with any modifications necessary for storage performed. + */ + protected function preSaveData($data, EntityInterface $entity) { + return $data; + } + + /** * {@inheritdoc} */ protected function has($id, EntityInterface $entity) { diff --git a/core/lib/Drupal/Core/Field/FieldItemBase.php b/core/lib/Drupal/Core/Field/FieldItemBase.php index 296c468..114b2ee 100644 --- a/core/lib/Drupal/Core/Field/FieldItemBase.php +++ b/core/lib/Drupal/Core/Field/FieldItemBase.php @@ -255,4 +255,24 @@ public function instanceSettingsForm(array $form, array &$form_state) { return array(); } + /** + * {@inheritdoc} + */ + public function preSaveSettings(array &$settings) { } + + /** + * {@inheritdoc} + */ + public function postLoadSettings(array &$settings) { } + + /** + * {@inheritdoc} + */ + public function preSaveInstanceSettings(array &$settings) { } + + /** + * {@inheritdoc} + */ + public function postLoadInstanceSettings(array &$settings) { } + } diff --git a/core/lib/Drupal/Core/Field/FieldItemInterface.php b/core/lib/Drupal/Core/Field/FieldItemInterface.php index ee27996..d70d366 100644 --- a/core/lib/Drupal/Core/Field/FieldItemInterface.php +++ b/core/lib/Drupal/Core/Field/FieldItemInterface.php @@ -183,6 +183,48 @@ public function view($display_options = array()); public function preSave(); /** + * Defines behavior for transforming field settings before being saved. + * + * May be used to alter settings to transform them to a storage-friendly form. + * + * @param array $settings + * Field settings. + */ + public function preSaveSettings(array &$settings); + + /** + * Defines custom behavior for transforming field settings when loading. + * + * May be used to alter settings to transform them from a storage-friendly + * form. + * + * @param array $settings + * Field settings. + */ + public function postLoadSettings(array &$settings); + + /** + * Defines behavior for transforming instance settings before being saved. + * + * May be used to alter settings to transform them to a storage-friendly form. + * + * @param array $settings + * Field settings. + */ + public function preSaveInstanceSettings(array &$settings); + + /** + * Defines custom behavior for transforming instance settings when loading. + * + * May be used to alter settings to transform them from a storage-friendly + * form. + * + * @param array $settings + * Field settings. + */ + public function postLoadInstanceSettings(array &$settings); + + /** * Defines custom insert behavior for field values. * * This method is called during the process of inserting an entity, just diff --git a/core/modules/aggregator/src/Entity/Feed.php b/core/modules/aggregator/src/Entity/Feed.php index de3daed..8c091c3 100644 --- a/core/modules/aggregator/src/Entity/Feed.php +++ b/core/modules/aggregator/src/Entity/Feed.php @@ -13,7 +13,6 @@ use Symfony\Component\DependencyInjection\Container; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\aggregator\FeedInterface; -use Drupal\options\Plugin\Field\FieldType\ListItemBase; /** * Defines the aggregator feed entity class. @@ -168,7 +167,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setDescription(t('The length of time between feed updates. Requires a correctly configured cron maintenance task.', array('@cron' => url('admin/reports/status')))) ->setSetting('unsigned', TRUE) ->setRequired(TRUE) - ->setSetting('allowed_values', ListItemBase::structureAllowedValues($period)) + ->setSetting('allowed_values', $period) ->setDisplayOptions('form', array( 'type' => 'options_select', 'weight' => -2, diff --git a/core/modules/field/src/Entity/FieldConfig.php b/core/modules/field/src/Entity/FieldConfig.php index af025e3..767e075 100644 --- a/core/modules/field/src/Entity/FieldConfig.php +++ b/core/modules/field/src/Entity/FieldConfig.php @@ -720,7 +720,7 @@ public function getUniqueStorageIdentifier() { /** * Helper to retrieve the field item class. */ - protected function getFieldItemClass() { + public function getFieldItemClass() { $type_definition = \Drupal::typedDataManager() ->getDefinition('field_item:' . $this->getType()); return $type_definition['class']; diff --git a/core/modules/field/src/FieldConfigStorage.php b/core/modules/field/src/FieldConfigStorage.php index 8419424..76566c9 100644 --- a/core/modules/field/src/FieldConfigStorage.php +++ b/core/modules/field/src/FieldConfigStorage.php @@ -10,6 +10,7 @@ use Drupal\Component\Uuid\UuidInterface; use Drupal\Core\Config\Config; use Drupal\Core\Config\Entity\ConfigEntityStorage; +use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\Query\QueryFactory; @@ -156,4 +157,35 @@ public function loadByProperties(array $conditions = array()) { return $matching_fields; } + + /** + * {@inheritdoc} + */ + protected function postLoad(array &$entities) { + foreach ($entities as $entity) { + // @todo This needs to modify the entity, so works off of the entity + // settings as it believes at the same. Because this came from storage + // it would technically be the same as the output of preSaveData() but + // philosophically it feels far from it. + if (is_array($entity->settings)) { + $field_class = $entity->getFieldItemClass(); + $field_class::postLoadSettings($entity->settings); + } + } + + parent::postLoad($entities); + } + + /** + * {@inheritdoc} + */ + protected function preSaveData($data, EntityInterface $entity) { + // @todo This looks ugly as it assumes a settings key which is not codified + // on this level otherwise. Also this works in a very different level, + // not using the entity anymore to avoid modifying it vs. load. + $field_class = $entity->getFieldItemClass(); + $data['settings'] = $field_class::preSaveSettings($data['settings']); + return $data; + } + } diff --git a/core/modules/field/src/Tests/FormTest.php b/core/modules/field/src/Tests/FormTest.php index c4bbf47..255c19d 100644 --- a/core/modules/field/src/Tests/FormTest.php +++ b/core/modules/field/src/Tests/FormTest.php @@ -358,7 +358,7 @@ function testFieldFormMultivalueWithRequiredRadio() { 'entity_type' => 'entity_test', 'type' => 'list_text', 'settings' => array( - 'allowed_values' => array(array('value' => 'yes', 'label' => 'yes'), array('value' => 'no', 'label' => 'no')), + 'allowed_values' => array('yes' => 'yes', 'no' => 'no'), ), ))->save(); $instance = array( diff --git a/core/modules/options/options.module b/core/modules/options/options.module index d0b6c00..d9a1b24 100644 --- a/core/modules/options/options.module +++ b/core/modules/options/options.module @@ -11,7 +11,6 @@ use Drupal\Core\Entity\Exception\FieldStorageDefinitionUpdateForbiddenException; use Drupal\field\FieldConfigInterface; use Drupal\field\FieldConfigUpdateForbiddenException; -use Drupal\options\Plugin\Field\FieldType\ListItemBase; /** * Implements hook_help(). @@ -61,9 +60,8 @@ function options_field_config_delete(FieldConfigInterface $field) { * The entity object. * * @return - * The array of allowed values. Each array element is an associative - * array with 'value' and 'label' keys. The 'value' key stores the raw stored - * value (number or text), the 'label' key stores the display labels. + * The array of allowed values. Keys of the array are the raw stored values + * (number or text), values of the array are the display labels. */ function options_allowed_values(FieldDefinitionInterface $field_definition, EntityInterface $entity) { $allowed_values = &drupal_static(__FUNCTION__, array()); @@ -101,11 +99,7 @@ function options_field_config_update_forbid(FieldConfigInterface $field, FieldCo // Forbid any update that removes allowed values with actual data. $allowed_values = $field->getSetting('allowed_values'); $prior_allowed_values = $prior_field->getSetting('allowed_values'); - $type_definition = \Drupal::typedDataManager()->getDefinition('field_item:' . $field->getType()); - $lost_keys = array_diff( - array_keys($type_definition['class']::simplifyAllowedValues($prior_allowed_values)), - array_keys($type_definition['class']::simplifyAllowedValues($allowed_values)) - ); + $lost_keys = array_diff(array_keys($prior_allowed_values), array_keys($allowed_values)); if (_options_values_in_use($field->entity_type, $field->getName(), $lost_keys)) { throw new FieldStorageDefinitionUpdateForbiddenException(t('A list field (@field_name) with existing data cannot have its keys changed.', array('@field_name' => $field->getName()))); } diff --git a/core/modules/options/src/Plugin/Field/FieldFormatter/OptionsDefaultFormatter.php b/core/modules/options/src/Plugin/Field/FieldFormatter/OptionsDefaultFormatter.php index c7ee86d..5c0b0d2 100644 --- a/core/modules/options/src/Plugin/Field/FieldFormatter/OptionsDefaultFormatter.php +++ b/core/modules/options/src/Plugin/Field/FieldFormatter/OptionsDefaultFormatter.php @@ -7,12 +7,8 @@ namespace Drupal\options\Plugin\Field\FieldFormatter; -use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FormatterBase; use Drupal\Core\Field\FieldItemListInterface; -use Drupal\Core\Plugin\ContainerFactoryPluginInterface; -use Drupal\Core\TypedData\TypedDataManager; -use Symfony\Component\DependencyInjection\ContainerInterface; /** * Plugin implementation of the 'list_default' formatter. @@ -28,48 +24,7 @@ * } * ) */ -class OptionsDefaultFormatter extends FormatterBase implements ContainerFactoryPluginInterface { - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { - return new static( - $plugin_id, - $plugin_definition, - $configuration['field_definition'], - $configuration['settings'], - $configuration['label'], - $configuration['view_mode'], - $configuration['third_party_settings'], - $container->get('typed_data_manager') - ); - } - - /** - * Constructs a new OptionsDefaultFormatter. - * - * @param string $plugin_id - * The plugin_id for the formatter. - * @param mixed $plugin_definition - * The plugin implementation definition. - * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition - * The definition of the field to which the formatter is associated. - * @param array $settings - * The formatter settings. - * @param string $label - * The formatter label display setting. - * @param string $view_mode - * The view mode. - * @param array $third_party_settings - * Third party settings. - * @param \Drupal\Core\TypedData\TypedDataManager $typed_data_manager - * The typed data manager. - */ - public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, TypedDataManager $typed_data_manager) { - parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings); - $this->typedDataManager = $typed_data_manager; - } +class OptionsDefaultFormatter extends FormatterBase { /** * {@inheritdoc} @@ -78,8 +33,7 @@ public function viewElements(FieldItemListInterface $items) { $elements = array(); $entity = $items->getEntity(); - $type_definition = $this->typedDataManager->getDefinition('field_item:' . $this->fieldDefinition->getType()); - $allowed_values = $type_definition['class']::simplifyAllowedValues(options_allowed_values($this->fieldDefinition, $entity)); + $allowed_values = options_allowed_values($this->fieldDefinition, $entity); foreach ($items as $delta => $item) { if (isset($allowed_values[$item->value])) { diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListBooleanItem.php b/core/modules/options/src/Plugin/Field/FieldType/ListBooleanItem.php index 6446017..5869ab6 100644 --- a/core/modules/options/src/Plugin/Field/FieldType/ListBooleanItem.php +++ b/core/modules/options/src/Plugin/Field/FieldType/ListBooleanItem.php @@ -64,7 +64,7 @@ public function getSettableValues(AccountInterface $account = NULL) { * {@inheritdoc} */ public function getSettableOptions(AccountInterface $account = NULL) { - return static::simplifyAllowedValues(options_allowed_values($this->getFieldDefinition(), $this->getEntity())); + return options_allowed_values($this->getFieldDefinition(), $this->getEntity()); } /** @@ -109,8 +109,8 @@ public function settingsForm(array &$form, array &$form_state, $has_data) { $allowed_values_function = $this->getSetting('allowed_values_function'); $values = $allowed_values; - $off_item = array_shift($values); - $on_item = array_shift($values); + $off_value = array_shift($values); + $on_value = array_shift($values); $element['allowed_values'] = array( '#type' => 'value', @@ -121,7 +121,7 @@ public function settingsForm(array &$form, array &$form_state, $has_data) { $element['allowed_values']['on'] = array( '#type' => 'textfield', '#title' => t('On value'), - '#default_value' => $on_item['label'], + '#default_value' => $on_value, '#required' => FALSE, '#description' => t('If left empty, "1" will be used.'), // Change #parents to make sure the element is not saved into field @@ -131,7 +131,7 @@ public function settingsForm(array &$form, array &$form_state, $has_data) { $element['allowed_values']['off'] = array( '#type' => 'textfield', '#title' => t('Off value'), - '#default_value' => $off_item['label'], + '#default_value' => $off_value, '#required' => FALSE, '#description' => t('If left empty, "0" will be used.'), // Change #parents to make sure the element is not saved into field @@ -162,7 +162,7 @@ public function settingsForm(array &$form, array &$form_state, $has_data) { public static function optionsBooleanAllowedValues($element, $input, $form_state) { $on = NestedArray::getValue($form_state['input'], $element['#on_parents']); $off = NestedArray::getValue($form_state['input'], $element['#off_parents']); - return array(array('value' => false, 'label' => $off), array('value' => true, 'label' => $on)); + return array($off, $on); } } diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php b/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php index 195e1c7..1b2d323 100644 --- a/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php +++ b/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php @@ -69,13 +69,16 @@ protected function allowedValuesDescription() { protected static function extractAllowedValues($string, $has_data) { $values = parent::extractAllowedValues($string, $has_data); if ($values) { - foreach ($values as $item) { + $keys = array_keys($values); + $labels = array_values($values); + $keys = array_map(function ($key) { // Float keys are represented as strings and need to be disambiguated // ('.5' is '0.5'). - $item['value'] = is_numeric($item['value']) ? (string) (float) $item['value'] : $item['value']; - } + return is_numeric($key) ? (string) (float) $key : $key; + }, $keys); + + return array_combine($keys, $labels); } - return $values; } /** diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListItemAllowedValuesTrait.php b/core/modules/options/src/Plugin/Field/FieldType/ListItemAllowedValuesTrait.php index d10e303..375e8ce 100644 --- a/core/modules/options/src/Plugin/Field/FieldType/ListItemAllowedValuesTrait.php +++ b/core/modules/options/src/Plugin/Field/FieldType/ListItemAllowedValuesTrait.php @@ -13,6 +13,24 @@ trait ListItemAllowedValuesTrait { /** + * Defined in \Drupal\Core\Field\FieldItemInterface. + */ + public static function preSaveSettings(array &$settings) { + if (isset($settings['allowed_values'])) { + $settings['allowed_values'] = static::structureAllowedValues($settings['allowed_values']); + } + } + + /** + * Defined in \Drupal\Core\Field\FieldItemInterface. + */ + public static function postLoadSettings(array &$settings) { + if (isset($settings['allowed_values'])) { + $settings['allowed_values'] = static::simplifyAllowedValues($settings['allowed_values']); + } + } + + /** * Simplify allowed values to a key-value array from the structured array. * * @param array $structured_values @@ -23,7 +43,7 @@ * Allowed values were the array key is the 'value' value, the value is * the 'label' value. */ - public static function simplifyAllowedValues(array $structured_values) { + protected static function simplifyAllowedValues(array $structured_values) { $values = array(); foreach ($structured_values as $item) { if (is_array($item['label'])) { @@ -47,7 +67,7 @@ public static function simplifyAllowedValues(array $structured_values) { * Array of items with a 'value' and 'label' key each for the allowed * values. */ - public static function structureAllowedValues(array $values) { + protected static function structureAllowedValues(array $values) { $structured_values = array(); foreach ($values as $value => $label) { if (is_array($label)) { diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php b/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php index 194b3f5..1237899 100644 --- a/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php +++ b/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php @@ -61,7 +61,7 @@ public function getSettableValues(AccountInterface $account = NULL) { */ public function getSettableOptions(AccountInterface $account = NULL) { $allowed_options = options_allowed_values($this->getFieldDefinition(), $this->getEntity()); - return static::simplifyAllowedValues($allowed_options); + return $allowed_options; } /** @@ -131,25 +131,16 @@ public static function validateAllowedValues($element, &$form_state) { } else { // Check that keys are valid for the field type. - $keys_in_use = array(); - foreach ($values as $item) { - if ($error = static::validateAllowedValue($item['value'])) { + foreach ($values as $key => $value) { + if ($error = static::validateAllowedValue($key)) { \Drupal::formBuilder()->setError($element, $form_state, $error); break; } - if (in_array($item['value'], $keys_in_use)) { - \Drupal::formBuilder()->setError($element, $form_state, t('One key can only be used once.')); - break; - } - $keys_in_use[] = $item['value']; } // Prevent removing values currently in use. if ($element['#field_has_data']) { - $lost_keys = array_diff( - array_keys(static::simplifyAllowedValues($element['#allowed_values'])), - array_keys(static::simplifyAllowedValues($values)) - ); + $lost_keys = array_diff(array_keys($element['#allowed_values']), array_keys($values)); if (_options_values_in_use($element['#entity_type'], $element['#field_name'], $lost_keys)) { \Drupal::formBuilder()->setError($element, $form_state, t('Allowed values list: some values are being removed while currently in use.')); } @@ -204,7 +195,7 @@ protected static function extractAllowedValues($string, $has_data) { return; } - $values[] = array('value' => $key, 'label' => $value); + $values[$key] = $value; } // We generate keys only if the list contains no explicit key at all. @@ -231,19 +222,19 @@ protected static function validateAllowedValue($option) { } * * This string format is suitable for edition in a textarea. * - * @param array $structured_values - * An array of values, where elements are arrays with 'value' and 'label' - * keys. + * @param array $values + * An array of values, where array keys are values and array values are + * labels. * * @return string * The string representation of the $values array: * - Values are separated by a carriage return. - * - Each value is in the format "value|label". + * - Each value is in the format "value|label" or "value". */ - protected function allowedValuesString($structured_values) { + protected function allowedValuesString($values) { $lines = array(); - foreach ($structured_values as $item) { - $lines[] = $item['value'] . '|' . $item['label']; + foreach ($values as $key => $value) { + $lines[] = "$key|$value"; } return implode("\n", $lines); } diff --git a/core/modules/options/src/Tests/OptionsFieldTest.php b/core/modules/options/src/Tests/OptionsFieldTest.php index aad59bf..ed775b4 100644 --- a/core/modules/options/src/Tests/OptionsFieldTest.php +++ b/core/modules/options/src/Tests/OptionsFieldTest.php @@ -45,7 +45,7 @@ function testUpdateAllowedValues() { $entity = entity_create('entity_test'); $entity->{$this->fieldName}->value = 1; $entity->save(); - $this->field->settings['allowed_values'] = array(array('value' => 2, 'label' => 'Two')); + $this->field->settings['allowed_values'] = array(2 => 'Two'); try { $this->field->save(); $this->fail(t('Cannot update a list field to not include keys with existing data.')); @@ -58,7 +58,7 @@ function testUpdateAllowedValues() { $entity->save(); // Removed options do not appear. - $this->field->settings['allowed_values'] = array(array('value' => 2, 'label' => 'Two')); + $this->field->settings['allowed_values'] = array(2 => 'Two'); $this->field->save(); $entity = entity_create('entity_test'); $form = \Drupal::service('entity.form_builder')->getForm($entity); @@ -67,7 +67,7 @@ function testUpdateAllowedValues() { $this->assertTrue(empty($form[$this->fieldName]['widget'][3]), 'Option 3 does not exist'); // Completely new options appear. - $this->field->settings['allowed_values'] = array(array('value' => 10, 'label' => 'Update'), array('value' => 20, 'label' => 'Twenty')); + $this->field->settings['allowed_values'] = array(10 => 'Update', 20 => 'Twenty'); $this->field->save(); // The entity holds an outdated field object with the old allowed values // setting, so we need to reintialize the entity object. diff --git a/core/modules/options/src/Tests/OptionsFieldUITest.php b/core/modules/options/src/Tests/OptionsFieldUITest.php index bf01335..baecfca 100644 --- a/core/modules/options/src/Tests/OptionsFieldUITest.php +++ b/core/modules/options/src/Tests/OptionsFieldUITest.php @@ -60,24 +60,15 @@ function testOptionsAllowedValuesInteger() { // Flat list of textual values. $string = "Zero\nOne"; - $array = array( - array('value' => 0, 'label' => 'Zero'), - array('value' => 1, 'label' => 'One'), - ); + $array = array('0' => 'Zero', '1' => 'One'); $this->assertAllowedValuesInput($string, $array, 'Unkeyed lists are accepted.'); // Explicit integer keys. $string = "0|Zero\n2|Two"; - $array = array( - array('value' => 0, 'label' => 'Zero'), - array('value' => 2, 'label' => 'Two'), - ); + $array = array('0' => 'Zero', '2' => 'Two'); $this->assertAllowedValuesInput($string, $array, 'Integer keys are accepted.'); // Check that values can be added and removed. $string = "0|Zero\n1|One"; - $array = array( - array('value' => 0, 'label' => 'Zero'), - array('value' => 1, 'label' => 'One'), - ); + $array = array('0' => 'Zero', '1' => 'One'); $this->assertAllowedValuesInput($string, $array, 'Values can be added and removed.'); // Non-integer keys. $this->assertAllowedValuesInput("1.1|One", 'keys must be integers', 'Non integer keys are rejected.'); @@ -97,31 +88,18 @@ function testOptionsAllowedValuesInteger() { // Check that values can be added but values in use cannot be removed. $string = "0|Zero\n1|One\n2|Two"; - $array = array( - array('value' => 0, 'label' => 'Zero'), - array('value' => 1, 'label' => 'One'), - array('value' => 2, 'label' => 'Two'), - ); + $array = array('0' => 'Zero', '1' => 'One', '2' => 'Two'); $this->assertAllowedValuesInput($string, $array, 'Values can be added.'); $string = "0|Zero\n1|One"; - $array = array( - array('value' => 0, 'label' => 'Zero'), - array('value' => 1, 'label' => 'One'), - ); + $array = array('0' => 'Zero', '1' => 'One'); $this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.'); $this->assertAllowedValuesInput("0|Zero", 'some values are being removed while currently in use', 'Values in use cannot be removed.'); // Delete the node, remove the value. $node->delete(); $string = "0|Zero"; - $array = array( - array('value' => 0, 'label' => 'Zero'), - ); + $array = array('0' => 'Zero'); $this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.'); - - // Check that the same key can only be used once. - $string = "0|Zero\n0|One"; - $this->assertAllowedValuesInput($string, 'One key can only be used once.', 'Same value cannot be used multiple times.'); } /** @@ -133,25 +111,15 @@ function testOptionsAllowedValuesFloat() { // Flat list of textual values. $string = "Zero\nOne"; - $array = array( - array('value' => (float) 0, 'label' => 'Zero'), - array('value' => (float) 1, 'label' => 'One'), - ); + $array = array('0' => 'Zero', '1' => 'One'); $this->assertAllowedValuesInput($string, $array, 'Unkeyed lists are accepted.'); // Explicit numeric keys. $string = "0|Zero\n.5|Point five"; - $array = array( - array('value' => (float) 0, 'label' => 'Zero'), - array('value' => (float) 0.5, 'label' => 'Point five'), - ); + $array = array('0' => 'Zero', '0.5' => 'Point five'); $this->assertAllowedValuesInput($string, $array, 'Integer keys are accepted.'); // Check that values can be added and removed. $string = "0|Zero\n.5|Point five\n1.0|One"; - $array = array( - array('value' => (float) 0, 'label' => 'Zero'), - array('value' => (float) 0.5, 'label' => 'Point five'), - array('value' => (float) 1, 'label' => 'One'), - ); + $array = array('0' => 'Zero', '0.5' => 'Point five', '1' => 'One'); $this->assertAllowedValuesInput($string, $array, 'Values can be added and removed.'); // Non-numeric keys. $this->assertAllowedValuesInput("abc|abc\n", 'each key must be a valid integer or decimal', 'Non numeric keys are rejected.'); @@ -161,7 +129,7 @@ function testOptionsAllowedValuesFloat() { // Create a node with actual data for the field. $settings = array( 'type' => $this->type, - $this->field_name => array(array('value' => (float) 0.5)), + $this->field_name => array(array('value' => .5)), ); $node = $this->drupalCreateNode($settings); @@ -170,35 +138,18 @@ function testOptionsAllowedValuesFloat() { // Check that values can be added but values in use cannot be removed. $string = "0|Zero\n.5|Point five\n2|Two"; - $array = array( - array('value' => (float) 0, 'label' => 'Zero'), - array('value' => (float) 0.5, 'label' => 'Point five'), - array('value' => (float) 2, 'label' => 'Two'), - ); + $array = array('0' => 'Zero', '0.5' => 'Point five', '2' => 'Two'); $this->assertAllowedValuesInput($string, $array, 'Values can be added.'); $string = "0|Zero\n.5|Point five"; - $array = array( - array('value' => (float) 0, 'label' => 'Zero'), - array('value' => (float) 0.5, 'label' => 'Point five'), - ); + $array = array('0' => 'Zero', '0.5' => 'Point five'); $this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.'); $this->assertAllowedValuesInput("0|Zero", 'some values are being removed while currently in use', 'Values in use cannot be removed.'); // Delete the node, remove the value. $node->delete(); $string = "0|Zero"; - $array = array( - array('value' => (float) 0, 'label' => 'Zero'), - ); + $array = array('0' => 'Zero'); $this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.'); - - // Check that the same key can only be used once. - $string = "0.5|Point five\n0.5|Half"; - $this->assertAllowedValuesInput($string, 'One key can only be used once.', 'Same value cannot be used multiple times.'); - - // Check that different forms of the same float value cannot be used. - $string = "0|Zero\n.5|Point five\n0.5|Half"; - $this->assertAllowedValuesInput($string, 'One key can only be used once.', 'Different forms of the same value cannot be used.'); } /** @@ -210,31 +161,19 @@ function testOptionsAllowedValuesText() { // Flat list of textual values. $string = "Zero\nOne"; - $array = array( - array('value' => 'Zero', 'label' => 'Zero'), - array('value' => 'One', 'label' => 'One'), - ); + $array = array('Zero' => 'Zero', 'One' => 'One'); $this->assertAllowedValuesInput($string, $array, 'Unkeyed lists are accepted.'); // Explicit keys. $string = "zero|Zero\none|One"; - $array = array( - array('value' => 'zero', 'label' => 'Zero'), - array('value' => 'one', 'label' => 'One'), - ); + $array = array('zero' => 'Zero', 'one' => 'One'); $this->assertAllowedValuesInput($string, $array, 'Explicit keys are accepted.'); // Check that values can be added and removed. $string = "zero|Zero\ntwo|Two"; - $array = array( - array('value' => 'zero', 'label' => 'Zero'), - array('value' => 'two', 'label' => 'Two'), - ); + $array = array('zero' => 'Zero', 'two' => 'Two'); $this->assertAllowedValuesInput($string, $array, 'Values can be added and removed.'); // Mixed list of keyed and unkeyed values. $string = "zero|Zero\nOne\n"; - $array = array( - array('value' => 'zero', 'label' => 'Zero'), - array('value' => 'One', 'label' => 'One'), - ); + $array = array('zero' => 'Zero', 'One' => 'One'); $this->assertAllowedValuesInput($string, $array, 'Mixed lists are accepted.'); // Overly long keys. $this->assertAllowedValuesInput("zero|Zero\n" . $this->randomName(256) . "|One", 'each key must be a string at most 255 characters long', 'Overly long keys are rejected.'); @@ -249,48 +188,23 @@ function testOptionsAllowedValuesText() { // Check that flat lists of values are still accepted once the field has // data. $string = "Zero\nOne"; - $array = array( - array('value' => 'Zero', 'label' => 'Zero'), - array('value' => 'One', 'label' => 'One'), - ); + $array = array('Zero' => 'Zero', 'One' => 'One'); $this->assertAllowedValuesInput($string, $array, 'Unkeyed lists are still accepted once the field has data.'); // Check that values can be added but values in use cannot be removed. $string = "Zero\nOne\nTwo"; - $array = array( - array('value' => 'Zero', 'label' => 'Zero'), - array('value' => 'One', 'label' => 'One'), - array('value' => 'Two', 'label' => 'Two'), - ); + $array = array('Zero' => 'Zero', 'One' => 'One', 'Two' => 'Two'); $this->assertAllowedValuesInput($string, $array, 'Values can be added.'); $string = "Zero\nOne"; - $array = array( - array('value' => 'Zero', 'label' => 'Zero'), - array('value' => 'One', 'label' => 'One'), - ); + $array = array('Zero' => 'Zero', 'One' => 'One'); $this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.'); $this->assertAllowedValuesInput("Zero", 'some values are being removed while currently in use', 'Values in use cannot be removed.'); // Delete the node, remove the value. $node->delete(); $string = "Zero"; - $array = array( - array('value' => 'Zero', 'label' => 'Zero'), - ); + $array = array('Zero' => 'Zero'); $this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.'); - - // Check that string values with dots can be used. - $node->delete(); - $string = "Zero\nexample.com|Example"; - $array = array( - array('value' => 'Zero', 'label' => 'Zero'), - array('value' => 'example.com', 'label' => 'Example'), - ); - $this->assertAllowedValuesInput($string, $array, 'String value with dot is supported.'); - - // Check that the same key can only be used once. - $string = "Zero\nZero"; - $this->assertAllowedValuesInput($string, 'One key can only be used once.', 'Same value cannot be used multiple times.'); } /** @@ -303,10 +217,7 @@ function testOptionsAllowedValuesBoolean() { // Check that the separate 'On' and 'Off' form fields work. $on = $this->randomName(); $off = $this->randomName(); - $allowed_values = array( - array('value' => false, 'label' => $off), - array('value' => true, 'label' => $on), - ); + $allowed_values = array(1 => $on, 0 => $off); $edit = array( 'on' => $on, 'off' => $off, @@ -333,15 +244,8 @@ function testOptionsTrimmedValuesText() { // Explicit keys. $string = "zero |Zero\none | One"; - $array = array( - array('value' => 'zero', 'label' => 'Zero'), - array('value' => 'one', 'label' => 'One'), - ); + $array = array('zero' => 'Zero', 'one' => 'One'); $this->assertAllowedValuesInput($string, $array, 'Explicit keys are accepted and trimmed.'); - - // Check that the same key can only be used once. - $string = " Zero \n Zero "; - $this->assertAllowedValuesInput($string, 'One key can only be used once.', 'Same value cannot be used multiple times.'); } /** diff --git a/core/modules/options/src/Tests/OptionsFieldUnitTestBase.php b/core/modules/options/src/Tests/OptionsFieldUnitTestBase.php index 2c97d2e..272e026 100644 --- a/core/modules/options/src/Tests/OptionsFieldUnitTestBase.php +++ b/core/modules/options/src/Tests/OptionsFieldUnitTestBase.php @@ -63,11 +63,7 @@ public function setUp() { 'type' => 'list_integer', 'cardinality' => 1, 'settings' => array( - 'allowed_values' => array( - array('value' => 1, 'label' => 'One'), - array('value' => 2, 'label' => 'Two'), - array('value' => 3, 'label' => 'Three') - ), + 'allowed_values' => array(1 => 'One', 2 => 'Two', 3 => 'Three'), ), ); $this->field = entity_create('field_config', $this->fieldDefinition); diff --git a/core/modules/options/src/Tests/OptionsWidgetsTest.php b/core/modules/options/src/Tests/OptionsWidgetsTest.php index 05bc1e5..bcec12c 100644 --- a/core/modules/options/src/Tests/OptionsWidgetsTest.php +++ b/core/modules/options/src/Tests/OptionsWidgetsTest.php @@ -70,12 +70,12 @@ function setUp() { 'settings' => array( 'allowed_values' => array( // Make sure that 0 works as an option. - array('value' => 0, 'label' => 'Zero'), - array('value' => 1, 'label' => 'One'), + 0 => 'Zero', + 1 => 'One', // Make sure that option text is properly sanitized. - array('value' => 2, 'label' => 'Some & unescaped markup'), + 2 => 'Some & unescaped markup', // Make sure that HTML entities in option text are not double-encoded. - array('value' => 3, 'label' => 'Some HTML encoded markup with < & >'), + 3 => 'Some HTML encoded markup with < & >', ), ), )); @@ -90,10 +90,10 @@ function setUp() { 'settings' => array( 'allowed_values' => array( // Make sure that 0 works as an option. - array('value' => 0, 'label' => 'Zero'), - array('value' => 1, 'label' => 'One'), + 0 => 'Zero', + 1 => 'One', // Make sure that option text is properly sanitized. - array('value' => 2, 'label' => 'Some & unescaped markup'), + 2 => 'Some & unescaped markup', ), ), )); @@ -108,9 +108,9 @@ function setUp() { 'settings' => array( 'allowed_values' => array( // Make sure that 0 works as an option. - array('value' => 0, 'label' => 'Zero'), + 0 => 'Zero', // Make sure that option text is properly sanitized. - array('value' => 1, 'label' => 'Some & unescaped markup'), + 1 => 'Some & unescaped markup', ), ), )); @@ -170,7 +170,7 @@ function testRadioButtons() { $this->assertFieldValues($entity_init, 'card_1', array()); // Check that required radios with one option is auto-selected. - $this->card_1->settings['allowed_values'] = array(array('value' => 99, 'label' => 'Only allowed value')); + $this->card_1->settings['allowed_values'] = array(99 => 'Only allowed value'); $this->card_1->save(); $instance->required = TRUE; $instance->save(); @@ -259,7 +259,7 @@ function testCheckBoxes() { $this->assertFieldValues($entity_init, 'card_2', array()); // Required checkbox with one option is auto-selected. - $this->card_2->settings['allowed_values'] = array(array('value' => 99, 'label' => 'Only allowed value')); + $this->card_2->settings['allowed_values'] = array(99 => 'Only allowed value'); $this->card_2->save(); $instance->required = TRUE; $instance->save(); diff --git a/core/modules/options/tests/options_test.module b/core/modules/options/tests/options_test.module index ba56132..1416fa0 100644 --- a/core/modules/options/tests/options_test.module +++ b/core/modules/options/tests/options_test.module @@ -7,7 +7,6 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Field\FieldDefinitionInterface; -use Drupal\options\Plugin\Field\FieldType\ListItemBase; /** * Allowed values callback. @@ -23,7 +22,7 @@ function options_test_allowed_values_callback(FieldDefinitionInterface $field_de ), ); - return ListItemBase::structureAllowedValues($values); + return $values; } /** @@ -38,5 +37,5 @@ function options_test_dynamic_values_callback(FieldDefinitionInterface $field_de $entity->bundle(), ); // We need the values of the entity as keys. - return ListItemBase::structureAllowedValues(array_combine($values, $values)); + return array_combine($values, $values); }