diff --git a/core/includes/form.inc b/core/includes/form.inc index 762bd99..7fc6850 100644 --- a/core/includes/form.inc +++ b/core/includes/form.inc @@ -6,11 +6,7 @@ */ use Drupal\Component\Utility\UrlHelper; -use Drupal\Component\Utility\Xss; -use Drupal\Core\Database\Database; use Drupal\Core\Form\FormOptionsHelper; -use Drupal\Core\Form\FormStateInterface; -use Drupal\Core\Form\OptGroup; use Drupal\Core\Render\Element; use Drupal\Core\Render\Element\RenderElement; use Drupal\Core\Template\Attribute; @@ -38,13 +34,13 @@ function template_preprocess_select(&$variables) { RenderElement::setAttributes($element, array('form-select')); $variables['attributes'] = $element['#attributes']; - $variables['options'] = form_select_options($element); + $variables['options'] = FormOptionsHelper::formSelectOptions($element); } /** * Converts an options form element into a structured array for output. * - * @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 8.0.0. + * @deprecated in Drupal 8.3.x, will be removed before Drupal 9.0.0. * Use \Drupal\Core\Form\FormOptionsHelper::formSelectOptions(). */ function form_select_options($element, $choices = NULL) { @@ -54,51 +50,11 @@ function form_select_options($element, $choices = NULL) { /** * Returns the indexes of a select element's options matching a given key. * - * This function is useful if you need to modify the options that are - * already in a form element; for example, to remove choices which are - * not valid because of additional filters imposed by another module. - * One example might be altering the choices in a taxonomy selector. - * To correctly handle the case of a multiple hierarchy taxonomy, - * #options arrays can now hold an array of objects, instead of a - * direct mapping of keys to labels, so that multiple choices in the - * selector can have the same key (and label). This makes it difficult - * to manipulate directly, which is why this helper function exists. - * - * This function does not support optgroups (when the elements of the - * #options array are themselves arrays), and will return FALSE if - * arrays are found. The caller must either flatten/restore or - * manually do their manipulations in this case, since returning the - * index is not sufficient, and supporting this would make the - * "helper" too complicated and cumbersome to be of any help. - * - * As usual with functions that can return array() or FALSE, do not - * forget to use === and !== if needed. - * - * @param $element - * The select element to search. - * @param $key - * The key to look for. - * - * @return - * An array of indexes that match the given $key. Array will be - * empty if no elements were found. FALSE if optgroups were found. + * @deprecated in Drupal 8.3.x, will be removed before Drupal 9.0.0. + * Use \Drupal\Core\Form\FormOptionsHelper::formGetOptions(). */ function form_get_options($element, $key) { - $keys = array(); - foreach ($element['#options'] as $index => $choice) { - if (is_array($choice)) { - return FALSE; - } - elseif (is_object($choice)) { - if (isset($choice->option[$key])) { - $keys[] = $index; - } - } - elseif ($index == $key) { - $keys[] = $index; - } - } - return $keys; + return FormOptionsHelper::formGetOptions($element, $key); } /** diff --git a/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/DefaultSelection.php b/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/DefaultSelection.php index 9565e77..8ccdcc8 100644 --- a/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/DefaultSelection.php +++ b/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/DefaultSelection.php @@ -9,6 +9,7 @@ use Drupal\Core\Entity\EntityReferenceSelection\SelectionWithAutocreateInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem; +use Drupal\Core\Form\FormOptionsHelper; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; @@ -114,7 +115,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta // equivalent to "no entities from any bundle can be referenced". 'target_bundles' => NULL, 'sort' => array( - 'field' => '_none', + 'field' => FormOptionsHelper::OPTIONS_EMPTY_OPTION, ), 'auto_create' => FALSE, 'auto_create_bundle' => NULL, @@ -184,7 +185,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta '#type' => 'select', '#title' => $this->t('Sort by'), '#options' => array( - '_none' => $this->t('- None -'), + FormOptionsHelper::OPTIONS_EMPTY_OPTION => $this->t('- None -'), ) + $fields, '#ajax' => TRUE, '#limit_validation_errors' => array(), @@ -197,7 +198,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta '#process' => [[EntityReferenceItem::class, 'formProcessMergeParent']], ); - if ($selection_handler_settings['sort']['field'] != '_none') { + if ($selection_handler_settings['sort']['field'] != FormOptionsHelper::OPTIONS_EMPTY_OPTION) { // Merge-in default values. $selection_handler_settings['sort'] += array( 'direction' => 'ASC', @@ -407,7 +408,7 @@ protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') // Add the sort option. if (!empty($handler_settings['sort'])) { $sort_settings = $handler_settings['sort']; - if ($sort_settings['field'] != '_none') { + if ($sort_settings['field'] != FormOptionsHelper::OPTIONS_EMPTY_OPTION) { $query->sort($sort_settings['field'], $sort_settings['direction']); } } diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/OptionsWidgetBase.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/OptionsWidgetBase.php index ca00bcc..664efe8 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/OptionsWidgetBase.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/OptionsWidgetBase.php @@ -7,6 +7,7 @@ use Drupal\Core\Field\FieldFilteredMarkup; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Field\WidgetBase; +use Drupal\Core\Form\FormOptionsHelper; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\OptGroup; @@ -67,7 +68,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen * The form state. */ public static function validateElement(array $element, FormStateInterface $form_state) { - if ($element['#required'] && $element['#value'] == '_none') { + if ($element['#required'] && $element['#value'] == FormOptionsHelper::OPTIONS_EMPTY_OPTION) { $form_state->setError($element, t('@name field is required.', array('@name' => $element['#title']))); } @@ -85,7 +86,7 @@ public static function validateElement(array $element, FormStateInterface $form_ // Filter out the 'none' option. Use a strict comparison, because // 0 == 'any string'. - $index = array_search('_none', $values, TRUE); + $index = array_search(FormOptionsHelper::OPTIONS_EMPTY_OPTION, $values, TRUE); if ($index !== FALSE) { unset($values[$index]); } @@ -117,7 +118,7 @@ protected function getOptions(FieldableEntityInterface $entity) { // Add an empty option if the widget needs one. if ($empty_label = $this->getEmptyLabel()) { - $options = ['_none' => $empty_label] + $options; + $options = [FormOptionsHelper::OPTIONS_EMPTY_OPTION => $empty_label] + $options; } $module_handler = \Drupal::moduleHandler(); diff --git a/core/lib/Drupal/Core/Form/FormOptionsHelper.php b/core/lib/Drupal/Core/Form/FormOptionsHelper.php index e3c2673..537f957 100644 --- a/core/lib/Drupal/Core/Form/FormOptionsHelper.php +++ b/core/lib/Drupal/Core/Form/FormOptionsHelper.php @@ -7,8 +7,6 @@ namespace Drupal\Core\Form; -use Drupal\Component\Utility\SafeMarkup; - /** * @todo. */ @@ -61,7 +59,7 @@ class FormOptionsHelper { public static function formSelectOptions(array $element, $choices = NULL) { if (!isset($choices)) { if (empty($element['#options'])) { - return ''; + return []; } $choices = $element['#options']; } @@ -71,29 +69,86 @@ public static function formSelectOptions(array $element, $choices = NULL) { $value_is_array = $value_valid && is_array($element['#value']); // Check if the element is multiple select and no value has been selected. $empty_value = (empty($element['#value']) && !empty($element['#multiple'])); - $options = ''; + $options = []; foreach ($choices as $key => $choice) { if (is_array($choice)) { - $options .= ''; - $options .= static::formSelectOptions($element, $choice); - $options .= ''; + $options[] = [ + 'type' => 'optgroup', + 'label' => $key, + 'options' => static::formSelectOptions($element, $choice), + ]; } elseif (is_object($choice) && isset($choice->option)) { - $options .= static::formSelectOptions($element, $choice->option); + $options = array_merge($options, static::formSelectOptions($element, $choice->option)); } else { + $option = []; $key = (string) $key; $empty_choice = $empty_value && $key == static::OPTIONS_EMPTY_OPTION; if ($value_valid && ((!$value_is_array && (string) $element['#value'] === $key || ($value_is_array && in_array($key, $element['#value']))) || $empty_choice)) { - $selected = ' selected="selected"'; + $option['selected'] = TRUE; } else { - $selected = ''; + $option['selected'] = FALSE; } - $options .= ''; + $option['type'] = 'option'; + $option['value'] = $key; + $option['label'] = $choice; + $options[] = $option; + } + } + + return $options; + } + + /** + * Returns the indexes of a select element's options matching a given key. + * + * This function is useful if you need to modify the options that are + * already in a form element; for example, to remove choices which are + * not valid because of additional filters imposed by another module. + * One example might be altering the choices in a taxonomy selector. + * To correctly handle the case of a multiple hierarchy taxonomy, + * #options arrays can now hold an array of objects, instead of a + * direct mapping of keys to labels, so that multiple choices in the + * selector can have the same key (and label). This makes it difficult + * to manipulate directly, which is why this helper function exists. + * + * This function does not support optgroups (when the elements of the + * #options array are themselves arrays), and will return FALSE if + * arrays are found. The caller must either flatten/restore or + * manually do their manipulations in this case, since returning the + * index is not sufficient, and supporting this would make the + * "helper" too complicated and cumbersome to be of any help. + * + * As usual with functions that can return array() or FALSE, do not + * forget to use === and !== if needed. + * + * @param $element + * The select element to search. + * @param $key + * The key to look for. + * + * @return array + * An array of indexes that match the given $key. Array will be + * empty if no elements were found. FALSE if optgroups were found. + */ + public static function formGetOptions($element, $key) { + $keys = []; + foreach ($element['#options'] as $index => $choice) { + if (is_array($choice)) { + return FALSE; + } + elseif (is_object($choice)) { + if (isset($choice->option[$key])) { + $keys[] = $index; + } + } + elseif ($index == $key) { + $keys[] = $index; } } - return SafeMarkup::set($options); + return $keys; } } diff --git a/core/modules/entity_reference/src/Tests/EntityReferenceAdminTest.php b/core/modules/entity_reference/src/Tests/EntityReferenceAdminTest.php deleted file mode 100644 index d8efae5..0000000 --- a/core/modules/entity_reference/src/Tests/EntityReferenceAdminTest.php +++ /dev/null @@ -1,308 +0,0 @@ -drupalPlaceBlock('system_breadcrumb_block'); - - // Create test user. - $admin_user = $this->drupalCreateUser(array('access content', 'administer node fields', 'administer node display')); - $this->drupalLogin($admin_user); - - // Create a content type, with underscores. - $type_name = strtolower($this->randomMachineName(8)) . '_test'; - $type = $this->drupalCreateContentType(array('name' => $type_name, 'type' => $type_name)); - $this->type = $type->id(); - } - - /** - * Tests the Entity Reference Admin UI. - */ - public function testFieldAdminHandler() { - $bundle_path = 'admin/structure/types/manage/' . $this->type; - - // First step: 'Add new field' on the 'Manage fields' page. - $this->drupalGet($bundle_path . '/fields/add-field'); - - // Check if the commonly referenced entity types appear in the list. - $this->assertOption('edit-new-storage-type', 'field_ui:entity_reference:node'); - $this->assertOption('edit-new-storage-type', 'field_ui:entity_reference:user'); - - $this->drupalPostForm(NULL, array( - 'label' => 'Test label', - 'field_name' => 'test', - 'new_storage_type' => 'entity_reference', - ), t('Save and continue')); - - // Node should be selected by default. - $this->assertFieldByName('field_storage[settings][target_type]', 'node'); - - // Check that all entity types can be referenced. - $this->assertFieldSelectOptions('field_storage[settings][target_type]', array_keys(\Drupal::entityManager()->getDefinitions())); - - // Second step: 'Field settings' form. - $this->drupalPostForm(NULL, array(), t('Save field settings')); - - // The base handler should be selected by default. - $this->assertFieldByName('field[settings][handler]', 'default:node'); - - // The base handler settings should be displayed. - $entity_type_id = 'node'; - $bundles = entity_get_bundles($entity_type_id); - foreach ($bundles as $bundle_name => $bundle_info) { - $this->assertFieldByName('field[settings][handler_settings][target_bundles][' . $bundle_name . ']'); - } - - reset($bundles); - - // Test the sort settings. - // Option 0: no sort. - $this->assertFieldByName('field[settings][handler_settings][sort][field]', FormOptionsHelper::OPTIONS_EMPTY_OPTION); - $this->assertNoFieldByName('field[settings][handler_settings][sort][direction]'); - // Option 1: sort by field. - $this->drupalPostAjaxForm(NULL, array('field[settings][handler_settings][sort][field]' => 'nid'), 'field[settings][handler_settings][sort][field]'); - $this->assertFieldByName('field[settings][handler_settings][sort][direction]', 'ASC'); - - // Test that a non-translatable base field is a sort option. - $this->assertFieldByXPath("//select[@name='field[settings][handler_settings][sort][field]']/option[@value='nid']"); - // Test that a translatable base field is a sort option. - $this->assertFieldByXPath("//select[@name='field[settings][handler_settings][sort][field]']/option[@value='title']"); - // Test that a configurable field is a sort option. - $this->assertFieldByXPath("//select[@name='field[settings][handler_settings][sort][field]']/option[@value='body.value']"); - - // Set back to no sort. - $this->drupalPostAjaxForm(NULL, array('field[settings][handler_settings][sort][field]' => FormOptionsHelper::OPTIONS_EMPTY_OPTION), 'field[settings][handler_settings][sort][field]'); - $this->assertNoFieldByName('field[settings][handler_settings][sort][direction]'); - - // Third step: confirm. - $this->drupalPostForm(NULL, array( - 'field[required]' => '1', - 'field[settings][handler_settings][target_bundles][' . key($bundles) . ']' => key($bundles), - ), t('Save settings')); - - // Check that the field appears in the overview form. - $this->assertFieldByXPath('//table[@id="field-overview"]//tr[@id="field-test"]/td[1]', 'Test label', 'Field was created and appears in the overview page.'); - - // Check that the field settings form can be submitted again, even when the - // field is required. - // The first 'Edit' link is for the Body field. - $this->clickLink(t('Edit'), 1); - $this->drupalPostForm(NULL, array(), t('Save settings')); - - // Switch the target type to 'taxonomy_term' and check that the settings - // specific to its selection handler are displayed. - $field_name = 'node.' . $this->type . '.field_test'; - $edit = array( - 'field_storage[settings][target_type]' => 'taxonomy_term', - ); - $this->drupalPostForm($bundle_path . '/fields/' . $field_name . '/storage', $edit, t('Save field settings')); - $this->drupalGet($bundle_path . '/fields/' . $field_name); - $this->assertFieldByName('field[settings][handler_settings][auto_create]'); - - // Switch the target type to 'user' and check that the settings specific to - // its selection handler are displayed. - $field_name = 'node.' . $this->type . '.field_test'; - $edit = array( - 'field_storage[settings][target_type]' => 'user', - ); - $this->drupalPostForm($bundle_path . '/fields/' . $field_name . '/storage', $edit, t('Save field settings')); - $this->drupalGet($bundle_path . '/fields/' . $field_name); - $this->assertFieldByName('field[settings][handler_settings][filter][type]', FormOptionsHelper::OPTIONS_EMPTY_OPTION); - - // Try to select the views handler. - $edit = array( - 'field[settings][handler]' => 'views', - ); - $this->drupalPostAjaxForm($bundle_path . '/fields/' . $field_name, $edit, 'field[settings][handler]'); - $this->drupalPostForm(NULL, $edit, t('Save settings')); - $this->assertResponse(200); - } - - - /** - * Tests the formatters for the Entity References - */ - public function testAvailableFormatters() { - // Create a new vocabulary. - Vocabulary::create(array('vid' => 'tags', 'name' => 'tags'))->save(); - - // Create entity reference field with taxonomy term as a target. - $taxonomy_term_field_name = $this->createEntityReferenceField('taxonomy_term', 'tags'); - - // Create entity reference field with user as a target. - $user_field_name = $this->createEntityReferenceField('user'); - - // Create entity reference field with node as a target. - $node_field_name = $this->createEntityReferenceField('node', $this->type); - - // Create entity reference field with date format as a target. - $date_format_field_name = $this->createEntityReferenceField('date_format'); - - // Display all newly created Entity Reference configuration. - $this->drupalGet('admin/structure/types/manage/' . $this->type . '/display'); - - // Check for Taxonomy Term select box values. - // Test if Taxonomy Term Entity Reference Field has the correct formatters. - $this->assertFieldSelectOptions('fields[field_' . $taxonomy_term_field_name . '][type]', array( - 'entity_reference_label', - 'entity_reference_entity_id', - 'entity_reference_rss_category', - 'entity_reference_entity_view', - 'hidden', - )); - - // Test if User Reference Field has the correct formatters. - // Author should be available for this field. - // RSS Category should not be available for this field. - $this->assertFieldSelectOptions('fields[field_' . $user_field_name . '][type]', array( - 'author', - 'entity_reference_entity_id', - 'entity_reference_entity_view', - 'entity_reference_label', - 'hidden', - )); - - // Test if Node Entity Reference Field has the correct formatters. - // RSS Category should not be available for this field. - $this->assertFieldSelectOptions('fields[field_' . $node_field_name . '][type]', array( - 'entity_reference_label', - 'entity_reference_entity_id', - 'entity_reference_entity_view', - 'hidden', - )); - - // Test if Date Format Reference Field has the correct formatters. - // RSS Category & Entity View should not be available for this field. - // This could be any field without a ViewBuilder. - $this->assertFieldSelectOptions('fields[field_' . $date_format_field_name . '][type]', array( - 'entity_reference_label', - 'entity_reference_entity_id', - 'hidden', - )); - } - - /** - * Creates a new Entity Reference fields with a given target type. - * - * @param $target_type - * The name of the target type - * @param $bundle - * Name of the bundle - * Default = NULL - * @return string - * Returns the generated field name - */ - public function createEntityReferenceField($target_type, $bundle = NULL) { - // Generates a bundle path for the newly created content type. - $bundle_path = 'admin/structure/types/manage/' . $this->type; - - // Generate a random field name, must be only lowercase characters. - $field_name = strtolower($this->randomMachineName()); - - $storage_edit = $field_edit = array(); - $storage_edit['field_storage[settings][target_type]'] = $target_type; - if ($bundle) { - $field_edit['field[settings][handler_settings][target_bundles][' . $bundle . ']'] = TRUE; - } - - $this->fieldUIAddNewField($bundle_path, $field_name, NULL, 'entity_reference', $storage_edit, $field_edit); - - // Returns the generated field name. - return $field_name; - } - - - /** - * Checks if a select element contains the specified options. - * - * @param string $name - * The field name. - * @param array $expected_options - * An array of expected options. - * - * @return bool - * TRUE if the assertion succeeded, FALSE otherwise. - */ - protected function assertFieldSelectOptions($name, array $expected_options) { - $xpath = $this->buildXPathQuery('//select[@name=:name]', array(':name' => $name)); - $fields = $this->xpath($xpath); - if ($fields) { - $field = $fields[0]; - $options = $this->getAllOptionsList($field); - - sort($options); - sort($expected_options); - - return $this->assertIdentical($options, $expected_options); - } - else { - return $this->fail('Unable to find field ' . $name); - } - } - - /** - * Extracts all options from a select element. - * - * @param \SimpleXMLElement $element - * The select element field information. - * - * @return array - * An array of option values as strings. - */ - protected function getAllOptionsList(\SimpleXMLElement $element) { - $options = array(); - // Add all options items. - foreach ($element->option as $option) { - $options[] = (string) $option['value']; - } - - // Loops trough all the option groups - foreach ($element->optgroup as $optgroup) { - $options = array_merge($this->getAllOptionsList($optgroup), $options); - } - - return $options; - } - -} diff --git a/core/modules/field/src/Tests/EntityReference/EntityReferenceAdminTest.php b/core/modules/field/src/Tests/EntityReference/EntityReferenceAdminTest.php index 0324c4a..e27612a 100644 --- a/core/modules/field/src/Tests/EntityReference/EntityReferenceAdminTest.php +++ b/core/modules/field/src/Tests/EntityReference/EntityReferenceAdminTest.php @@ -3,6 +3,7 @@ namespace Drupal\field\Tests\EntityReference; use Drupal\Component\Utility\Unicode; +use Drupal\Core\Form\FormOptionsHelper; use Drupal\field\Entity\FieldConfig; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\field_ui\Tests\FieldUiTestTrait; @@ -103,7 +104,7 @@ public function testFieldAdminHandler() { // Test the sort settings. // Option 0: no sort. - $this->assertFieldByName('settings[handler_settings][sort][field]', '_none'); + $this->assertFieldByName('settings[handler_settings][sort][field]', FormOptionsHelper::OPTIONS_EMPTY_OPTION); $this->assertNoFieldByName('settings[handler_settings][sort][direction]'); // Option 1: sort by field. $this->drupalPostAjaxForm(NULL, array('settings[handler_settings][sort][field]' => 'nid'), 'settings[handler_settings][sort][field]'); @@ -117,7 +118,7 @@ public function testFieldAdminHandler() { $this->assertFieldByXPath("//select[@name='settings[handler_settings][sort][field]']/option[@value='body.value']"); // Set back to no sort. - $this->drupalPostAjaxForm(NULL, array('settings[handler_settings][sort][field]' => '_none'), 'settings[handler_settings][sort][field]'); + $this->drupalPostAjaxForm(NULL, array('settings[handler_settings][sort][field]' => FormOptionsHelper::OPTIONS_EMPTY_OPTION), 'settings[handler_settings][sort][field]'); $this->assertNoFieldByName('settings[handler_settings][sort][direction]'); // Third step: confirm. @@ -153,7 +154,7 @@ public function testFieldAdminHandler() { ); $this->drupalPostForm($bundle_path . '/fields/' . $field_name . '/storage', $edit, t('Save field settings')); $this->drupalGet($bundle_path . '/fields/' . $field_name); - $this->assertFieldByName('settings[handler_settings][filter][type]', '_none'); + $this->assertFieldByName('settings[handler_settings][filter][type]', FormOptionsHelper::OPTIONS_EMPTY_OPTION); // Switch the target type to 'node'. $field_name = 'node.' . $this->type . '.field_test'; diff --git a/core/modules/options/src/Tests/OptionsWidgetsTest.php b/core/modules/options/src/Tests/OptionsWidgetsTest.php index 47798ee..809c730 100644 --- a/core/modules/options/src/Tests/OptionsWidgetsTest.php +++ b/core/modules/options/src/Tests/OptionsWidgetsTest.php @@ -293,7 +293,7 @@ function testSelectListSingle() { $this->assertTrue($this->xpath('//select[@id=:id]//option[@value=:value and text()=:label]', array(':id' => 'edit-card-1', ':value' => FormOptionsHelper::OPTIONS_EMPTY_OPTION, ':label' => t('- None -'))), 'A non-required select list has a "None" choice.'); // Submit form: Unselect the option. $edit = array('card_1' => FormOptionsHelper::OPTIONS_EMPTY_OPTION); - $this->drupalPostForm('entity_test/manage/' . $entity->id(), $edit, t('Save')); + $this->drupalPostForm('entity_test/manage/' . $entity->id() . '/edit', $edit, t('Save')); $this->assertFieldValues($entity_init, 'card_1', array()); // Test optgroups. @@ -324,7 +324,7 @@ function testSelectListSingle() { // Submit form: Unselect the option. $edit = array('card_1' => FormOptionsHelper::OPTIONS_EMPTY_OPTION); - $this->drupalPostForm('entity_test/manage/' . $entity->id(), $edit, t('Save')); + $this->drupalPostForm('entity_test/manage/' . $entity->id() . '/edit', $edit, t('Save')); $this->assertFieldValues($entity_init, 'card_1', array()); } @@ -353,7 +353,7 @@ function testSelectListMultiple() { $entity_init = clone $entity; // Display form: with no field data, nothing is selected. - $this->drupalGet('entity_test/manage/' . $entity->id()); + $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); $this->assertOptionSelected("edit-card-2", FormOptionsHelper::OPTIONS_EMPTY_OPTION); $this->assertNoOptionSelected('edit-card-2', 0); $this->assertNoOptionSelected('edit-card-2', 1); @@ -397,12 +397,12 @@ function testSelectListMultiple() { // Check that the 'none' option has no effect if actual options are selected // as well. $edit = array('card_2[]' => array(FormOptionsHelper::OPTIONS_EMPTY_OPTION => FormOptionsHelper::OPTIONS_EMPTY_OPTION, 0 => 0)); - $this->drupalPostForm('entity_test/manage/' . $entity->id(), $edit, t('Save')); + $this->drupalPostForm('entity_test/manage/' . $entity->id() . '/edit', $edit, t('Save')); $this->assertFieldValues($entity_init, 'card_2', array(0)); // Check that selecting the 'none' option empties the field. $edit = array('card_2[]' => array(FormOptionsHelper::OPTIONS_EMPTY_OPTION => FormOptionsHelper::OPTIONS_EMPTY_OPTION)); - $this->drupalPostForm('entity_test/manage/' . $entity->id(), $edit, t('Save')); + $this->drupalPostForm('entity_test/manage/' . $entity->id() . '/edit', $edit, t('Save')); $this->assertFieldValues($entity_init, 'card_2', array()); // A required select list does not have an empty key. @@ -445,7 +445,7 @@ function testSelectListMultiple() { // Submit form: Unselect the option. $edit = array('card_2[]' => array(FormOptionsHelper::OPTIONS_EMPTY_OPTION => FormOptionsHelper::OPTIONS_EMPTY_OPTION)); - $this->drupalPostForm('entity_test/manage/' . $entity->id(), $edit, t('Save')); + $this->drupalPostForm('entity_test/manage/' . $entity->id() . '/edit', $edit, t('Save')); $this->assertFieldValues($entity_init, 'card_2', array()); } @@ -476,7 +476,7 @@ function testEmptyValue() { // Display form: check that _none options are present and has label. $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); - $this->assertTrue($this->xpath('//div[@id=:id]//input[@value=:value]', array(':id' => 'edit-card-1', ':value' => '_none')), 'A test radio button has a "None" choice.'); + $this->assertTrue($this->xpath('//div[@id=:id]//input[@value=:value]', array(':id' => 'edit-card-1', ':value' => FormOptionsHelper::OPTIONS_EMPTY_OPTION)), 'A test radio button has a "None" choice.'); $this->assertTrue($this->xpath('//div[@id=:id]//label[@for=:for and text()=:label]', array(':id' => 'edit-card-1', ':for' => 'edit-card-1-none', ':label' => 'N/A')), 'A test radio button has a "N/A" choice.'); // Change it to the select widget. @@ -489,7 +489,7 @@ function testEmptyValue() { // Display form: check that _none options are present and has label. $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); // A required field without any value has a "none" option. - $this->assertTrue($this->xpath('//select[@id=:id]//option[@value="_none" and text()=:label]', array(':id' => 'edit-card-1', ':label' => t('- None -'))), 'A test select has a "None" choice.'); + $this->assertTrue($this->xpath('//select[@id=:id]//option[@value=:none and text()=:label]', array(':id' => 'edit-card-1', ':none' => FormOptionsHelper::OPTIONS_EMPTY_OPTION, ':label' => t('- None -'))), 'A test select has a "None" choice.'); } } diff --git a/core/modules/responsive_image/src/ResponsiveImageStyleForm.php b/core/modules/responsive_image/src/ResponsiveImageStyleForm.php index 3e5b051..5cb4284 100644 --- a/core/modules/responsive_image/src/ResponsiveImageStyleForm.php +++ b/core/modules/responsive_image/src/ResponsiveImageStyleForm.php @@ -4,6 +4,7 @@ use Drupal\breakpoint\BreakpointManagerInterface; use Drupal\Core\Entity\EntityForm; +use Drupal\Core\Form\FormOptionsHelper; use Drupal\Core\Form\FormStateInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -136,9 +137,9 @@ public function form(array $form, FormStateInterface $form_state) { '#options' => array( 'sizes' => $this->t('Select multiple image styles and use the sizes attribute.'), 'image_style' => $this->t('Select a single image style.'), - '_none' => $this->t('Do not use this breakpoint.'), + FormOptionsHelper::OPTIONS_EMPTY_OPTION => $this->t('Do not use this breakpoint.'), ), - '#default_value' => isset($image_style_mapping['image_mapping_type']) ? $image_style_mapping['image_mapping_type'] : '_none', + '#default_value' => isset($image_style_mapping['image_mapping_type']) ? $image_style_mapping['image_mapping_type'] : FormOptionsHelper::OPTIONS_EMPTY_OPTION, '#description' => $description, ); $form['keyed_styles'][$breakpoint_id][$multiplier]['image_style'] = array( @@ -184,7 +185,7 @@ public function form(array $form, FormStateInterface $form_state) { ); // Expand the details if "do not use this breakpoint" was not selected. - if ($form['keyed_styles'][$breakpoint_id][$multiplier]['image_mapping_type']['#default_value'] != '_none') { + if ($form['keyed_styles'][$breakpoint_id][$multiplier]['image_mapping_type']['#default_value'] != FormOptionsHelper::OPTIONS_EMPTY_OPTION) { $form['keyed_styles'][$breakpoint_id][$multiplier]['#open'] = TRUE; } } diff --git a/core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php b/core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php index 8f8b505..a4cd3a6 100644 --- a/core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php +++ b/core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php @@ -2,6 +2,7 @@ namespace Drupal\responsive_image\Tests; +use Drupal\Core\Form\FormOptionsHelper; use Drupal\simpletest\WebTestBase; /** @@ -118,7 +119,7 @@ public function testResponsiveImageAdmin() { // Check the mapping for multipliers 1x and 2x for the mobile breakpoint. $this->assertFieldByName('keyed_styles[responsive_image_test_module.mobile][1x][image_style]', 'thumbnail'); $this->assertFieldByName('keyed_styles[responsive_image_test_module.mobile][1x][image_mapping_type]', 'image_style'); - $this->assertFieldByName('keyed_styles[responsive_image_test_module.mobile][2x][image_mapping_type]', '_none'); + $this->assertFieldByName('keyed_styles[responsive_image_test_module.mobile][2x][image_mapping_type]', FormOptionsHelper::OPTIONS_EMPTY_OPTION); // Check the mapping for multipliers 1x and 2x for the narrow breakpoint. $this->assertFieldByName('keyed_styles[responsive_image_test_module.narrow][1x][image_mapping_type]', 'sizes'); @@ -126,12 +127,12 @@ public function testResponsiveImageAdmin() { $this->assertFieldChecked('edit-keyed-styles-responsive-image-test-modulenarrow-1x-sizes-image-styles-large'); $this->assertFieldChecked('edit-keyed-styles-responsive-image-test-modulenarrow-1x-sizes-image-styles-medium'); $this->assertNoFieldChecked('edit-keyed-styles-responsive-image-test-modulenarrow-1x-sizes-image-styles-thumbnail'); - $this->assertFieldByName('keyed_styles[responsive_image_test_module.narrow][2x][image_mapping_type]', '_none'); + $this->assertFieldByName('keyed_styles[responsive_image_test_module.narrow][2x][image_mapping_type]', FormOptionsHelper::OPTIONS_EMPTY_OPTION); // Check the mapping for multipliers 1x and 2x for the wide breakpoint. $this->assertFieldByName('keyed_styles[responsive_image_test_module.wide][1x][image_style]', 'large'); $this->assertFieldByName('keyed_styles[responsive_image_test_module.wide][1x][image_mapping_type]', 'image_style'); - $this->assertFieldByName('keyed_styles[responsive_image_test_module.wide][2x][image_mapping_type]', '_none'); + $this->assertFieldByName('keyed_styles[responsive_image_test_module.wide][2x][image_mapping_type]', FormOptionsHelper::OPTIONS_EMPTY_OPTION); // Delete the style. $this->drupalGet('admin/config/media/responsive-image-style/style_one/delete'); diff --git a/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php b/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php index cf23bc0..1466fed 100644 --- a/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php +++ b/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php @@ -7,6 +7,7 @@ use Drupal\Core\EventSubscriber\MainContentViewSubscriber; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\Form\FormOptionsHelper; +use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Url; use Drupal\field\Entity\FieldStorageConfig; use Drupal\field\Entity\FieldConfig; diff --git a/core/modules/user/src/Plugin/EntityReferenceSelection/UserSelection.php b/core/modules/user/src/Plugin/EntityReferenceSelection/UserSelection.php index 8dfba39..3c3852b 100644 --- a/core/modules/user/src/Plugin/EntityReferenceSelection/UserSelection.php +++ b/core/modules/user/src/Plugin/EntityReferenceSelection/UserSelection.php @@ -7,6 +7,7 @@ use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection; use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Form\FormOptionsHelper; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Session\AccountInterface; use Drupal\user\RoleInterface; @@ -88,7 +89,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta // Merge in default values. $selection_handler_settings += array( 'filter' => array( - 'type' => '_none', + 'type' => FormOptionsHelper::OPTIONS_EMPTY_OPTION, ), 'include_anonymous' => TRUE, ); @@ -104,7 +105,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta '#type' => 'select', '#title' => $this->t('Filter by'), '#options' => array( - '_none' => $this->t('- None -'), + FormOptionsHelper::OPTIONS_EMPTY_OPTION => $this->t('- None -'), 'role' => $this->t('User role'), ), '#ajax' => TRUE,