diff --git a/core/modules/contact/lib/Drupal/contact/Tests/ContactSitewideTest.php b/core/modules/contact/lib/Drupal/contact/Tests/ContactSitewideTest.php index 56b902e..1f672bb 100644 --- a/core/modules/contact/lib/Drupal/contact/Tests/ContactSitewideTest.php +++ b/core/modules/contact/lib/Drupal/contact/Tests/ContactSitewideTest.php @@ -221,6 +221,7 @@ function testSiteWideContact() { // Test field UI and field integration. $this->drupalGet('admin/structure/contact'); + // Test the dropdown operations for administering forms. // Find out in which row the category we want to add a field to is. $i = 0; foreach($this->xpath('//table/tbody/tr') as $row) { @@ -229,18 +230,19 @@ function testSiteWideContact() { } $i++; } - $this->clickLink(t('Manage fields'), $i); $this->assertResponse(200); // Create a simple textfield. + $this->clickLink(t('Add field')); + $this->assertResponse(200); + $edit = array( - 'fields[_add_new_field][label]' => $field_label = $this->randomName(), - 'fields[_add_new_field][field_name]' => Unicode::strtolower($this->randomName()), - 'fields[_add_new_field][type]' => 'text', + '_add_new_field[label]' => $field_label = $this->randomName(), + '_add_new_field[field_name]' => $name = strtolower($this->randomName()), + 'type' => 'text', ); - $field_name = 'field_' . $edit['fields[_add_new_field][field_name]']; - $this->drupalPost(NULL, $edit, t('Save')); + $this->drupalPost(NULL, $edit, t('Save field settings')); $this->drupalPost(NULL, array(), t('Save field settings')); $this->drupalPost(NULL, array(), t('Save settings')); @@ -249,6 +251,7 @@ function testSiteWideContact() { $this->assertText($field_label); // Submit the contact form and verify the content. + $field_name = 'field_' . $name; $edit = array( 'subject' => $this->randomName(), 'message' => $this->randomName(), diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAdminTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAdminTest.php index 932f55f..d5cc4c6 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAdminTest.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAdminTest.php @@ -65,12 +65,12 @@ protected function getAllOptionsList($element) { public function testFieldAdminHandler() { $bundle_path = 'admin/structure/types/manage/' . $this->type; - // First step: 'Add new field' on the 'Manage fields' page. - $this->drupalPost($bundle_path . '/fields', array( - 'fields[_add_new_field][label]' => 'Test label', - 'fields[_add_new_field][field_name]' => 'test', - 'fields[_add_new_field][type]' => 'entity_reference', - ), t('Save')); + // First step: 'Add new field'. + $this->drupalPost($bundle_path . '/add-field', array( + '_add_new_field[label]' => 'Test label', + '_add_new_field[field_name]' => 'test', + 'type' => 'entity_reference', + ), t('Save field settings')); // Node should be selected by default. $this->assertFieldByName('field[settings][target_type]', 'node'); @@ -104,6 +104,7 @@ public function testFieldAdminHandler() { ), t('Save settings')); // Check that the field appears in the overview form. + $this->drupalGet($bundle_path . '/fields'); $this->assertFieldByXPath('//table[@id="field-overview"]//td[1]', 'Test label', 'Field was created and appears in the overview page.'); } } diff --git a/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php b/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php index 799f953..84c7d67 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php @@ -68,6 +68,7 @@ public function getRegions() { 'content' => array( 'title' => t('Content'), 'invisible' => TRUE, + 'rows_order' => array(), // @todo Bring back this message in https://drupal.org/node/1963340. //'message' => t('No fields are present yet.'), ), @@ -116,6 +117,19 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL, ), ); + // @todo + $form['inline_actions'] = array( + '#prefix' => '', + ); + $form['inline_actions']['add'] = array( + '#theme' => 'menu_local_action', + '#link' => array( + 'href' => $this->adminPath . '/add-field', + 'title' => t('Add field'), + ), + ); + // Fields. foreach ($instances as $name => $instance) { $field = field_info_field($instance['field_name']); @@ -167,114 +181,6 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL, } } - // Gather valid field types. - $field_type_options = array(); - foreach ($field_types as $name => $field_type) { - // Skip field types which should not be added via user interface. - if (empty($field_type['no_ui'])) { - $field_type_options[$name] = $field_type['label']; - } - } - asort($field_type_options); - - // Additional row: add new field. - if ($field_type_options) { - $name = '_add_new_field'; - $table[$name] = array( - '#attributes' => array('class' => array('add-new')), - 'label' => array( - '#type' => 'textfield', - '#title' => t('New field label'), - '#title_display' => 'invisible', - '#size' => 15, - '#description' => t('Label'), - '#prefix' => '
' . t('Add new field') .'
', - '#suffix' => '
', - ), - 'field_name' => array( - '#type' => 'machine_name', - '#title' => t('New field name'), - '#title_display' => 'invisible', - // This field should stay LTR even for RTL languages. - '#field_prefix' => '' . $field_prefix, - '#field_suffix' => '‎', - '#size' => 15, - '#description' => t('A unique machine-readable name containing letters, numbers, and underscores.'), - // Calculate characters depending on the length of the field prefix - // setting. Maximum length is 32. - '#maxlength' => Field::ID_MAX_LENGTH - strlen($field_prefix), - '#prefix' => '
 
', - '#machine_name' => array( - 'source' => array('fields', $name, 'label'), - 'exists' => array($this, 'fieldNameExists'), - 'standalone' => TRUE, - 'label' => '', - ), - '#required' => FALSE, - ), - 'type' => array( - '#type' => 'select', - '#title' => t('Type of new field'), - '#title_display' => 'invisible', - '#options' => $field_type_options, - '#empty_option' => t('- Select a field type -'), - '#description' => t('Type of data to store.'), - '#attributes' => array('class' => array('field-type-select')), - '#cell_attributes' => array('colspan' => 2), - '#prefix' => '
 
', - ), - // Place the 'translatable' property as an explicit value so that - // contrib modules can form_alter() the value for newly created fields. - 'translatable' => array( - '#type' => 'value', - '#value' => FALSE, - ), - ); - } - - // Additional row: re-use existing field. - $existing_fields = $this->getExistingFieldOptions(); - if ($existing_fields) { - // Build list of options. - $existing_field_options = array(); - foreach ($existing_fields as $field_name => $info) { - $text = t('@type: @field (@label)', array( - '@type' => $info['type_label'], - '@label' => $info['label'], - '@field' => $info['field'], - )); - $existing_field_options[$field_name] = truncate_utf8($text, 80, FALSE, TRUE); - } - asort($existing_field_options); - $name = '_add_existing_field'; - $table[$name] = array( - '#attributes' => array('class' => array('add-new')), - '#row_type' => 'add_new_field', - '#region_callback' => array($this, 'getRowRegion'), - 'label' => array( - '#type' => 'textfield', - '#title' => t('Existing field label'), - '#title_display' => 'invisible', - '#size' => 15, - '#description' => t('Label'), - '#attributes' => array('class' => array('label-textfield')), - '#prefix' => '
' . t('Re-use existing field') .'
', - '#suffix' => '
', - ), - 'field_name' => array( - '#type' => 'select', - '#title' => t('Existing field to share'), - '#title_display' => 'invisible', - '#options' => $existing_field_options, - '#empty_option' => t('- Select an existing field -'), - '#description' => t('Field to share'), - '#attributes' => array('class' => array('field-select')), - '#cell_attributes' => array('colspan' => 3), - '#prefix' => '
 
', - ), - ); - } - // We can set the 'rows_order' element, needed by theme_field_ui_table(), // here instead of a #pre_render callback because this form doesn't have the // tabledrag behavior anymore. diff --git a/core/modules/field_ui/lib/Drupal/field_ui/FieldUI.php b/core/modules/field_ui/lib/Drupal/field_ui/FieldUI.php index 6e4a6a2..9bbd23a 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/FieldUI.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUI.php @@ -33,4 +33,5 @@ public static function getNextDestination() { return $next_destination; } + } diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldAddForm.php b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldAddForm.php new file mode 100644 index 0000000..634f3d1 --- /dev/null +++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldAddForm.php @@ -0,0 +1,525 @@ +entityManager = $entity_manager; + } + + /** + * {@inheritdoc} + */ + public function getFormID() { + return 'field_ui_field_add_form'; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('plugin.manager.entity') + ); + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, array &$form_state, $entity_type = NULL, $bundle = NULL, $form_mode = NULL) { + $entity_info = $this->entityManager->getDefinition($entity_type); + if (!empty($entity_info['bundle_prefix'])) { + $bundle = $entity_info['bundle_prefix'] . $bundle; + } + + $this->entity_type = $entity_type; + $this->bundle = $bundle; + $this->mode = $form_mode; + $this->adminPath = $this->entityManager->getAdminPath($this->entity_type, $this->bundle); + + $form['#attributes'] = array( + 'class' => array('field-ui-overview'), + 'id' => 'field-display-overview', + ); + + // Gather bundle information. + $instances = \Drupal::service('field.info')->getBundleInstances($entity_type, $bundle); + $field_types = \Drupal::service('plugin.manager.entity.field.field_type')->getDefinitions(); + $extra_fields = \Drupal\field\Field::fieldInfo()->getBundleExtraFields($entity_type, $bundle); + $extra_fields = isset($extra_fields['form']) ? $extra_fields['form'] : array(); + + // Field prefix. + $field_prefix = \Drupal::config('field_ui.settings')->get('field_prefix'); + + drupal_set_title(t('Add a new field.')); + $form = array( + '#entity_type' => $this->entity_type, + '#bundle' => $this->bundle, + '#fields' => array_keys($instances), + '#extra' => array_keys($extra_fields), + '#tree' => TRUE, + '#attributes' => array( + 'class' => array('field-ui-overview'), + 'id' => 'field-display-overview', + ), + ); + + // Gather valid field types. + $field_type_options = array(); + foreach ($field_types as $name => $field_type) { + // Skip field types which should not be added via user interface. + if (empty($field_type['no_ui'])) { + $field_type_options[$name] = $field_type['label']; + } + } + asort($field_type_options); + + $form['type'] = array( + '#type' => 'select', + '#title' => t('Type of new field'), + '#title_display' => 'invisible', + '#options' => $field_type_options, + '#empty_option' => t('- Select a field type -'), + '#description' => t('Type of data to store.'), + '#attributes' => array('class' => array('field-type-select')), + ); + + // Determine which options from the 'type' field already have existing + // fields and add them to the $states array so we can determine if the + // new-or-existing select list should be displayed. + $existing_fields = $this->getExistingFieldOptions(); + + $states[] = array('value' => FALSE); + foreach ($existing_fields as $field) { + $states[] = array('value' => $field['type']); + } + + $form['new-or-existing'] = array( + '#type' => 'select', + '#title' => t('New or Existing'), + '#options' => array( + t('New'), + t('Existing'), + ), + '#empty_option' => t('- New or Existing -'), + '#states' => array( + 'visible' => array( + 'select[name="type"]' => $states, + ), + ), + ); + + if ($field_type_options) { + $states[] = array('value' => ''); + $name = '_add_new_field'; + $form[$name] = array( + '#type' => 'container', + '#attributes' => array('class' => array('new-field-settings')), + // Only show this field if a type has been selected and 'Existing' + // has not explicitly been selected. + '#states' => array( + 'invisible' => array( + 'select[name="type"]' => $states, + 'select[name="new-or-existing"]' => array('!value' => 0), + ), + ), + 'label' => array( + '#type' => 'textfield', + '#title' => t('New field label'), + '#size' => 15, + '#description' => t('Label'), + ), + 'field_name' => array( + '#type' => 'machine_name', + '#title' => t('New field name'), + // This field should stay LTR even for RTL languages. + '#field_prefix' => '' . $field_prefix, + '#field_suffix' => '‎', + '#size' => 15, + '#description' => t('A unique machine-readable name containing letters, numbers, and underscores.'), + // Calculate characters depending on the length of the field prefix + // setting. Maximum length is 32. + '#maxlength' => Field::ID_MAX_LENGTH - strlen($field_prefix), + '#machine_name' => array( + 'source' => array($name, 'label'), + 'exists' => array($this, 'fieldNameExists'), + 'standalone' => TRUE, + 'label' => '', + ), + '#required' => FALSE, + ), + // Place the 'translatable' property as an explicit value so that + // contrib modules can form_alter() the value for newly created fields. + 'translatable' => array( + '#type' => 'value', + '#value' => FALSE, + ), + ); + } + + // Additional row: re-use existing field. + if ($existing_fields) { + // Build list of options. + $existing_field_options = array(); + foreach ($existing_fields as $field_name => $info) { + $text = t('@type: @field (@label)', array( + '@type' => $info['type_label'], + '@label' => $info['label'], + '@field' => $info['field'], + )); + $existing_field_options[$field_name] = truncate_utf8($text, 80, FALSE, TRUE); + } + asort($existing_field_options); + + $name = '_add_existing_field'; + $form[$name] = array( + '#type' => 'container', + '#attributes' => array('class' => array('existing-field-settings')), + // Only show this field if 'Existing' has explicitly been selected. + '#states' => array( + 'invisible' => array( + 'select[name="new-or-existing"]' => array('!value' => 1), + ), + ), + 'field_name' => array( + '#type' => 'select', + '#title' => t('Existing field to share'), + '#options' => $existing_field_options, + '#empty_option' => t('- Select an existing field -'), + '#description' => t('Field to share'), + '#attributes' => array('class' => array('field-select')), + ), + 'label' => array( + '#type' => 'textfield', + '#title' => t('Existing field label'), + '#size' => 15, + '#description' => t('Label'), + '#attributes' => array('class' => array('label-textfield')), + ), + ); + } + + // This key is used to store the current updated field. + $form_state += array( + 'formatter_settings_edit' => NULL, + ); + + $form['actions'] = array('#type' => 'actions'); + $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save field settings')); + + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, array &$form_state) { + $this->validateAddNew($form, $form_state); + $this->validateAddExisting($form, $form_state); + } + + /** + * Validates the 'add new field' row. + * + * @param array $form + * An associative array containing the structure of the form. + * @param array $form_state + * A reference to a keyed array containing the current state of the form. + * + * @see Drupal\field_ui\FieldOverview::validateForm() + */ + protected function validateAddNew(array $form, array &$form_state) { + $field = $form_state['values']['_add_new_field']; + $values = $form_state['values']; + + // Validate if any information was provided in the 'add new field' row. + if (array_filter(array($field['label'], $field['field_name'], $values['type']))) { + // Missing label. + if (!$field['label']) { + form_set_error('_add_new_field][label', t('Add new field: you need to provide a label.')); + } + + // Missing field name. + if (!$field['field_name']) { + form_set_error('_add_new_field][field_name', t('Add new field: you need to provide a field name.')); + } + // Field name validation. + else { + $field_name = $field['field_name']; + + // Add the field prefix. + $field_prefix = \Drupal::config('field_ui.settings')->get('field_prefix'); + $field_name = $field_prefix . $field_name; + form_set_value($form['_add_new_field']['field_name'], $field_name, $form_state); + } + + // Missing field type. + if (!$values['type']) { + form_set_error('_add_new_field][type', t('Add new field: you need to select a field type.')); + } + } + } + + /** + * Validates the 're-use existing field' row. + * + * @param array $form + * An associative array containing the structure of the form. + * @param array $form_state + * A reference to a keyed array containing the current state of the form. + * + * @see Drupal\field_ui\FieldOverview::validate() + */ + protected function validateAddExisting(array $form, array &$form_state) { + // The form element might be absent if no existing fields can be added to + // this bundle. + if (isset($form_state['values']['_add_existing_field'])) { + $field = $form_state['values']['_add_existing_field']; + + // Validate if any information was provided in the + // 're-use existing field' row. + if (array_filter(array($field['label'], $field['field_name']))) { + // Missing label. + if (!$field['label']) { + form_set_error('_add_existing_field][label', t('Re-use existing field: you need to provide a label.')); + } + + // Missing existing field name. + if (!$field['field_name']) { + form_set_error('_add_existing_field][field_name', t('Re-use existing field: you need to select a field.')); + } + } + } + } + + /** + * Overrides \Drupal\field_ui\OverviewBase::submitForm(). + */ + public function submitForm(array &$form, array &$form_state) { + $destinations = array(); + + // Create new field. + if (!empty($form_state['values']['_add_new_field']['field_name'])) { + $values = $form_state['values']['_add_new_field']; + + $field = array( + 'field_name' => $form_state['values']['_add_new_field']['field_name'], + 'type' => $form_state['values']['type'], + 'translatable' => $form_state['values']['_add_new_field']['translatable'], + ); + $instance = array( + 'field_name' => $field['field_name'], + 'entity_type' => $this->entity_type, + 'bundle' => $this->bundle, + 'label' => $values['label'], + ); + + // Create the field and instance. + try { + $this->entityManager->getStorageController('field_entity')->create($field)->save(); + $new_instance = $this->entityManager->getStorageController('field_instance')->create($instance); + $new_instance->save(); + + // Make sure the field is displayed in the 'default' form mode (using + // default widget and settings). It stays hidden for other form modes + // until it is explicitly configured. + entity_get_form_display($this->entity_type, $this->bundle, 'default') + ->setComponent($field['field_name']) + ->save(); + + // Make sure the field is displayed in the 'default' view mode (using + // default formatter and settings). It stays hidden for other view + // modes until it is explicitly configured. + entity_get_display($this->entity_type, $this->bundle, 'default') + ->setComponent($field['field_name']) + ->save(); + + // Always show the field settings step, as the cardinality needs to be + // configured for new fields. + $destinations[] = $this->adminPath. '/fields/' . $new_instance->id() . '/field'; + $destinations[] = $this->adminPath . '/fields/' . $new_instance->id(); + + // Store new field information for any additional submit handlers. + $form_state['fields_added']['_add_new_field'] = $field['field_name']; + } + catch (\Exception $e) { + drupal_set_message(t('There was a problem creating field %label: !message', array('%label' => $instance['label'], '!message' => $e->getMessage())), 'error'); + } + } + + // Re-use existing field. + if (!empty($form_state['values']['_add_existing_field']['field_name'])) { + $values = $form_state['values']['_add_existing_field']; + $field = \Drupal\field\Field::fieldInfo()->getField($values['field_name']); + if (!empty($field['locked'])) { + drupal_set_message(t('The field %label cannot be added because it is locked.', array('%label' => $values['label'])), 'error'); + } + else { + $instance = array( + 'field_name' => $field['field_name'], + 'entity_type' => $this->entity_type, + 'bundle' => $this->bundle, + 'label' => $values['label'], + ); + + try { + $new_instance = $this->entityManager->getStorageController('field_instance')->create($instance); + $new_instance->save(); + + // Make sure the field is displayed in the 'default' form mode (using + // default widget and settings). It stays hidden for other form modes + // until it is explicitly configured. + entity_get_form_display($this->entity_type, $this->bundle, 'default') + ->setComponent($field['field_name']) + ->save(); + + // Make sure the field is displayed in the 'default' view mode (using + // default formatter and settings). It stays hidden for other view + // modes until it is explicitly configured. + entity_get_display($this->entity_type, $this->bundle, 'default') + ->setComponent($field['field_name']) + ->save(); + + $destinations[] = $this->adminPath . '/fields/' . $new_instance->id(); + // Store new field information for any additional submit handlers. + $form_state['fields_added']['_add_existing_field'] = $instance['field_name']; + } + catch (\Exception $e) { + drupal_set_message(t('There was a problem creating field instance %label: @message.', array('%label' => $instance['label'], '@message' => $e->getMessage())), 'error'); + } + } + } + + if ($destinations) { + $destination = drupal_get_destination(); + $destinations[] = $destination['destination']; + unset($_GET['destination']); + $path = array_shift($destinations); + $options = drupal_parse_url($path); + $options['query']['destinations'] = $destinations; + $form_state['redirect'] = array($options['path'], $options); + } + else { + drupal_set_message(t('Your settings have been saved.')); + } + } + + /** + * Returns an array of existing fields to be added to a bundle. + * + * @return array + * An array of existing fields keyed by field name. + */ + protected function getExistingFieldOptions() { + $info = array(); + $field_types = \Drupal::service('plugin.manager.entity.field.field_type')->getDefinitions(); + + $instances = \Drupal\field\Field::fieldInfo()->getInstances($this->entity_type); + foreach ($instances as $bundle => $instance) { + foreach ($instance as $field_name => $instance_settings) { + if (!($instance_settings->bundle == $this->bundle && $instance_settings->entity_type == $this->entity_type)) { + $field = \Drupal\field\Field::fieldInfo()->getField($field_name); + // Don't show + // - locked fields, + // - fields already in the current bundle, + // - fields that cannot be added to the entity type, + // - fields that should not be added via user interface. + if (empty($field->locked) + && !\Drupal\field\Field::fieldInfo()->getInstance($this->entity_type, $this->bundle, $field->id) + && empty($field_types[$field->type]['no_ui'])) { + $info[$instance_settings['field_name']] = array( + 'type' => $field->type, + 'type_label' => $field_types[$field->type]['label'], + 'field' => $field->id, + 'label' => $instance_settings['label'], + ); + } + } + } + } + return $info; + } + + /** + * Checks if a field machine name is taken. + * + * @param string $value + * The machine name, not prefixed with 'field_'. + * + * @return bool + * Whether or not the field machine name is taken. + */ + public function fieldNameExists($value) { + // Get the configured field prefix. + $field_prefix = \Drupal::config('field_ui.settings')->get('field_prefix'); + + // We need to check inactive fields as well, so we can't use + // field_info_fields(). + return (bool) \Drupal::entityManager() + ->getStorageController('field_entity') + ->loadByProperties(array( + 'field_name' => $field_prefix . $value, + 'include_inactive' => TRUE, + 'include_deleted' => TRUE) + ); + } + +} diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Routing/RouteSubscriber.php b/core/modules/field_ui/lib/Drupal/field_ui/Routing/RouteSubscriber.php index e994202..cf50aa8 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Routing/RouteSubscriber.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Routing/RouteSubscriber.php @@ -111,6 +111,13 @@ public function routes(RouteBuildEvent $event) { ); $collection->add("field_ui.display_overview.$entity_type", $route); + $route = new Route( + "$path/add-field", + array('_form' => '\Drupal\field_ui\Form\FieldAddForm') + $defaults, + array('_permission' => 'administer ' . $entity_type . ' fields') + ); + $collection->add("field_ui.add.$entity_type", $route); + foreach (entity_get_view_modes($entity_type) as $view_mode => $view_mode_info) { $route = new Route( "$path/display/$view_mode", diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/FieldUiTestBase.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/FieldUiTestBase.php index c836023..b2d6172 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/FieldUiTestBase.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/FieldUiTestBase.php @@ -66,12 +66,13 @@ function setUp() { function fieldUIAddNewField($bundle_path, $initial_edit, $field_edit = array(), $instance_edit = array()) { // Use 'test_field' field type by default. $initial_edit += array( - 'fields[_add_new_field][type]' => 'test_field', + 'type' => 'test_field', + 'new-or-existing' => 0, ); - $label = $initial_edit['fields[_add_new_field][label]']; + $label = $initial_edit['_add_new_field[label]']; // First step : 'Add new field' on the 'Manage fields' page. - $this->drupalPost("$bundle_path/fields", $initial_edit, t('Save')); + $this->drupalPost("$bundle_path/add-field", $initial_edit, t('Save field settings')); $this->assertRaw(t('These settings apply to the %label field everywhere it is used.', array('%label' => $label)), 'Field settings page was displayed.'); // Second step : 'Field settings' form. @@ -83,6 +84,7 @@ function fieldUIAddNewField($bundle_path, $initial_edit, $field_edit = array(), $this->assertRaw(t('Saved %label configuration.', array('%label' => $label)), 'Redirected to "Manage fields" page.'); // Check that the field appears in the overview form. + $this->drupalGet("$bundle_path/fields"); $this->assertFieldByXPath('//table[@id="field-overview"]//td[1]', $label, 'Field was created and appears in the overview page.'); } @@ -99,16 +101,20 @@ function fieldUIAddNewField($bundle_path, $initial_edit, $field_edit = array(), * form). */ function fieldUIAddExistingField($bundle_path, $initial_edit, $instance_edit = array()) { - $label = $initial_edit['fields[_add_existing_field][label]']; + $initial_edit += array( + 'new-or-existing' => 1, + ); + $label = $initial_edit['_add_existing_field[label]']; // First step : 'Re-use existing field' on the 'Manage fields' page. - $this->drupalPost("$bundle_path/fields", $initial_edit, t('Save')); + $this->drupalPost("$bundle_path/add-field", $initial_edit, t('Save field settings')); // Second step : 'Instance settings' form. $this->drupalPost(NULL, $instance_edit, t('Save settings')); $this->assertRaw(t('Saved %label configuration.', array('%label' => $label)), 'Redirected to "Manage fields" page.'); // Check that the field appears in the overview form. + $this->drupalGet("$bundle_path/fields"); $this->assertFieldByXPath('//table[@id="field-overview"]//td[1]', $label, 'Field was created and appears in the overview page.'); } diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php index d1edd6d..0fcb12a 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php @@ -38,8 +38,8 @@ function testFormatterUI() { // Create a field, and a node with some data for the field. $edit = array( - 'fields[_add_new_field][label]' => 'Test field', - 'fields[_add_new_field][field_name]' => 'test', + '_add_new_field[label]' => 'Test field', + '_add_new_field[field_name]' => 'test', ); $this->fieldUIAddNewField($manage_fields, $edit); @@ -104,8 +104,8 @@ public function testWidgetUI() { // Create a field, and a node with some data for the field. $edit = array( - 'fields[_add_new_field][label]' => 'Test field', - 'fields[_add_new_field][field_name]' => 'test', + '_add_new_field[label]' => 'Test field', + '_add_new_field[field_name]' => 'test', ); $this->fieldUIAddNewField($manage_fields, $edit); @@ -166,8 +166,8 @@ public function testWidgetUI() { function testViewModeCustom() { // Create a field, and a node with some data for the field. $edit = array( - 'fields[_add_new_field][label]' => 'Test field', - 'fields[_add_new_field][field_name]' => 'test', + '_add_new_field[label]' => 'Test field', + '_add_new_field[field_name]' => 'test', ); $this->fieldUIAddNewField('admin/structure/types/manage/' . $this->type, $edit); // For this test, use a formatter setting value that is an integer unlikely @@ -238,8 +238,8 @@ function testViewModeCustom() { function testNonInitializedFields() { // Create a test field. $edit = array( - 'fields[_add_new_field][label]' => 'Test', - 'fields[_add_new_field][field_name]' => 'test', + '_add_new_field[label]' => 'Test', + '_add_new_field[field_name]' => 'test', ); $this->fieldUIAddNewField('admin/structure/types/manage/' . $this->type, $edit); diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php index 69be9ec..00ad0ad 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php @@ -96,11 +96,8 @@ function manageFieldsPage($type = '') { $this->assertRaw($table_header . '', format_string('%table_header table header was found.', array('%table_header' => $table_header))); } - // "Add new field" and "Re-use existing field" aren't a table heading so just - // test the text. - foreach (array('Add new field', 'Re-use existing field') as $element) { - $this->assertText($element, format_string('"@element" was found.', array('@element' => $element))); - } + // "Add field" is a button. + $this->assertText('Add field', 'Add field button was found.'); } /** @@ -112,17 +109,13 @@ function manageFieldsPage($type = '') { function createField() { // Create a test field. $edit = array( - 'fields[_add_new_field][label]' => $this->field_label, - 'fields[_add_new_field][field_name]' => $this->field_name_input, + '_add_new_field[label]' => $this->field_label, + '_add_new_field[field_name]' => $this->field_name_input, ); $this->fieldUIAddNewField('admin/structure/types/manage/' . $this->type, $edit); - // Assert the field appears in the "re-use existing field" section for - // different entity types; e.g. if a field was added in a node entity, it - // should also appear in the 'taxonomy term' entity. - $vocabulary = entity_load('taxonomy_vocabulary', 'tags'); - $this->drupalGet('admin/structure/taxonomy/manage/' . $vocabulary->id() . '/fields'); - $this->assertTrue($this->xpath('//select[@name="fields[_add_existing_field][field_name]"]//option[@value="' . $this->field_name . '"]'), 'Existing field was found in taxonomy term fields.'); + $this->drupalGet('admin/structure/types/manage/' . $this->type . '/fields'); + $this->assertText($this->field_label, 'Field found on content type overview page.'); } /** @@ -158,9 +151,9 @@ function updateField() { * Tests adding an existing field in another content type. */ function addExistingField() { - // Check "Re-use existing field" appears. - $this->drupalGet('admin/structure/types/manage/page/fields'); - $this->assertRaw(t('Re-use existing field'), '"Re-use existing field" was found.'); + // Check "Existing field to share" appears. + $this->drupalGet('admin/structure/types/manage/page/add-field'); + $this->assertRaw('Existing field to share', '"Existing field to share" was found.'); // Check that the list of options respects entity type restrictions on // fields. The 'comment' field is restricted to the 'comment' entity type @@ -169,8 +162,8 @@ function addExistingField() { // Add a new field based on an existing field. $edit = array( - 'fields[_add_existing_field][label]' => $this->field_label . '_2', - 'fields[_add_existing_field][field_name]' => $this->field_name, + '_add_existing_field[label]' => $this->field_label . '_2', + '_add_existing_field[field_name]' => $this->field_name, ); $this->fieldUIAddExistingField("admin/structure/types/manage/page", $edit); } @@ -253,16 +246,16 @@ function testFieldPrefix() { // Try to create the field. $edit = array( - 'fields[_add_new_field][label]' => $field_exceed_max_length_label, - 'fields[_add_new_field][field_name]' => $field_exceed_max_length_input, + '_add_new_field[label]' => $field_exceed_max_length_label, + '_add_new_field[field_name]' => $field_exceed_max_length_input, ); - $this->drupalPost('admin/structure/types/manage/' . $this->type . '/fields', $edit, t('Save')); + $this->drupalPost('admin/structure/types/manage/' . $this->type . '/add-field', $edit, t('Save field settings')); $this->assertText('New field name cannot be longer than 22 characters but is currently 23 characters long.'); // Create a valid field. $edit = array( - 'fields[_add_new_field][label]' => $this->field_label, - 'fields[_add_new_field][field_name]' => $this->field_name_input, + '_add_new_field[label]' => $this->field_label, + '_add_new_field[field_name]' => $this->field_name_input, ); $this->fieldUIAddNewField('admin/structure/types/manage/' . $this->type, $edit); $this->drupalGet('admin/structure/types/manage/' . $this->type . '/fields/node.' . $this->type . '.' . $field_prefix . $this->field_name_input); @@ -340,8 +333,8 @@ function testDeleteField() { // Create a new field. $bundle_path1 = 'admin/structure/types/manage/' . $this->type; $edit1 = array( - 'fields[_add_new_field][label]' => $this->field_label, - 'fields[_add_new_field][field_name]' => $this->field_name_input, + '_add_new_field[label]' => $this->field_label, + '_add_new_field[field_name]' => $this->field_name_input, ); $this->fieldUIAddNewField($bundle_path1, $edit1); @@ -353,8 +346,8 @@ function testDeleteField() { // Add an instance to the second node type. $bundle_path2 = 'admin/structure/types/manage/' . $type_name2; $edit2 = array( - 'fields[_add_existing_field][label]' => $this->field_label, - 'fields[_add_existing_field][field_name]' => $this->field_name, + '_add_existing_field[label]' => $this->field_label, + '_add_existing_field[field_name]' => $this->field_name, ); $this->fieldUIAddExistingField($bundle_path2, $edit2); @@ -447,7 +440,7 @@ function testHiddenFields() { // on other bundles. $bundle_path = 'admin/structure/types/manage/article/fields/'; $this->drupalGet($bundle_path); - $this->assertFalse($this->xpath('//select[@id="edit-add-existing-field-field-name"]//option[@value=:field_name]', array(':field_name' => $field_name)), "The 're-use existing field' select respects field types 'no_ui' property."); + $this->assertFalse($this->xpath('//select[@id="edit-add-existing-field-field-name"]//option[@value=:field_name]', array(':field_name' => $field_name)), 'The "Existing field to share" select respects field types "no_ui" property.'); } /** @@ -470,12 +463,12 @@ function testDuplicateFieldName() { // field_tags already exists, so we're expecting an error when trying to // create a new field with the same name. $edit = array( - 'fields[_add_new_field][field_name]' => 'tags', - 'fields[_add_new_field][label]' => $this->randomName(), - 'fields[_add_new_field][type]' => 'taxonomy_term_reference', + '_add_new_field[field_name]' => 'tags', + '_add_new_field[label]' => $this->randomName(), + 'type' => 'taxonomy_term_reference', ); - $url = 'admin/structure/types/manage/' . $this->type . '/fields'; - $this->drupalPost($url, $edit, t('Save')); + $url = 'admin/structure/types/manage/' . $this->type . '/add-field'; + $this->drupalPost($url, $edit, t('Save field settings')); $this->assertText(t('The machine-readable name is already in use. It must be unique.')); $this->assertUrl($url, array(), 'Stayed on the same page.'); @@ -488,8 +481,8 @@ function testDeleteTaxonomyField() { // Create a new field. $bundle_path = 'admin/structure/taxonomy/manage/tags'; $edit1 = array( - 'fields[_add_new_field][label]' => $this->field_label, - 'fields[_add_new_field][field_name]' => $this->field_name_input, + '_add_new_field[label]' => $this->field_label, + '_add_new_field[field_name]' => $this->field_name_input, ); $this->fieldUIAddNewField($bundle_path, $edit1); diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php index e481384..5bc3999 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php +++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php @@ -251,11 +251,11 @@ function testPrivateFileComment() { // Create a new field. $edit = array( - 'fields[_add_new_field][label]' => $label = $this->randomName(), - 'fields[_add_new_field][field_name]' => $name = strtolower($this->randomName()), - 'fields[_add_new_field][type]' => 'file', + '_add_new_field[label]' => $label = $this->randomName(), + '_add_new_field[field_name]' => $name = strtolower($this->randomName()), + 'type' => 'file', ); - $this->drupalPost('admin/structure/types/manage/article/comment/fields', $edit, t('Save')); + $this->drupalPost('admin/structure/types/manage/article/comment/add-field', $edit, t('Save field settings')); $edit = array('field[settings][uri_scheme]' => 'private'); $this->drupalPost(NULL, $edit, t('Save field settings')); $this->drupalPost(NULL, array(), t('Save settings')); diff --git a/core/modules/link/lib/Drupal/link/Tests/LinkFieldUITest.php b/core/modules/link/lib/Drupal/link/Tests/LinkFieldUITest.php index 910ff14..f768c8e 100644 --- a/core/modules/link/lib/Drupal/link/Tests/LinkFieldUITest.php +++ b/core/modules/link/lib/Drupal/link/Tests/LinkFieldUITest.php @@ -48,11 +48,11 @@ function testFieldUI() { $label = $this->randomName(); $field_name = drupal_strtolower($label); $edit = array( - 'fields[_add_new_field][label]' => $label, - 'fields[_add_new_field][field_name]' => $field_name, - 'fields[_add_new_field][type]' => 'link', + '_add_new_field[label]' => $label, + '_add_new_field[field_name]' => $field_name, + 'type' => 'link', ); - $this->drupalPost("$type_path/fields", $edit, t('Save')); + $this->drupalPost($type_path . '/add-field', $edit, t('Save field settings')); // Proceed to the Edit (field instance settings) page. $this->drupalPost(NULL, array(), t('Save field settings')); // Proceed to the Manage fields overview page. diff --git a/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php b/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php index 1edfd9f..17046a7 100644 --- a/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php +++ b/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php @@ -164,11 +164,11 @@ function testNumberIntegerField() { $label = $this->randomName(); $field_name = drupal_strtolower($label); $edit = array( - 'fields[_add_new_field][label]'=> $label, - 'fields[_add_new_field][field_name]' => $field_name, - 'fields[_add_new_field][type]' => 'number_integer', + '_add_new_field[label]'=> $label, + '_add_new_field[field_name]' => $field_name, + 'type' => 'number_integer', ); - $this->drupalPost(NULL, $edit, t('Save')); + $this->drupalPost('admin/structure/types/manage/' . $type . '/add-field', $edit, t('Save field settings')); // Add prefix and suffix for the newly-created field. $prefix = $this->randomName();