diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentNonNodeTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentNonNodeTest.php index e2b4597..234f645 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentNonNodeTest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentNonNodeTest.php @@ -350,13 +350,13 @@ function testCommentFunctionality() { $this->assertNoFieldChecked('edit-default-value-input-comment-0-status-2'); // Add a new comment field. - $this->drupalGet('entity_test/structure/entity_test/fields'); + $this->drupalGet('entity_test/structure/entity_test/add-field'); $edit = array( - 'fields[_add_new_field][label]' => 'Foobar', - 'fields[_add_new_field][field_name]' => 'foobar', - 'fields[_add_new_field][type]' => 'comment', + '_add_new_field[label]' => 'Foobar', + '_add_new_field[field_name]' => 'foobar', + 'type' => 'comment', ); - $this->drupalPostForm(NULL, $edit, t('Save')); + $this->drupalPostForm(NULL, $edit, t('Save field settings')); $this->drupalPostForm(NULL, array(), t('Save field settings')); $this->drupalPostForm(NULL, array(), t('Save settings')); $this->assertRaw(t('Saved %name configuration', array('%name' => 'Foobar'))); diff --git a/core/modules/contact/lib/Drupal/contact/Tests/ContactSitewideTest.php b/core/modules/contact/lib/Drupal/contact/Tests/ContactSitewideTest.php index b8ae287..8f87036 100644 --- a/core/modules/contact/lib/Drupal/contact/Tests/ContactSitewideTest.php +++ b/core/modules/contact/lib/Drupal/contact/Tests/ContactSitewideTest.php @@ -228,6 +228,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) { @@ -241,13 +242,14 @@ function testSiteWideContact() { $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->randomString(), + '_add_new_field[field_name]' => $name = strtolower($this->randomName()), + 'type' => 'text', ); - $field_name = 'field_' . $edit['fields[_add_new_field][field_name]']; - $this->drupalPostForm(NULL, $edit, t('Save')); + $this->drupalPostForm(NULL, $edit, t('Save field settings')); $this->drupalPostForm(NULL, array(), t('Save field settings')); $this->drupalPostForm(NULL, array(), t('Save settings')); @@ -256,6 +258,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 4c7327d..ba629ff 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->drupalPostForm($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->drupalPostForm($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'); @@ -111,6 +111,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"]//tr[@id="field-test"]/td[1]', 'Test label', 'Field was created and appears in the overview page.'); } } diff --git a/core/modules/field_ui/field_ui.local_actions.yml b/core/modules/field_ui/field_ui.local_actions.yml new file mode 100644 index 0000000..2939522 --- /dev/null +++ b/core/modules/field_ui/field_ui.local_actions.yml @@ -0,0 +1,3 @@ +field_ui.add: + class: \Drupal\Core\Menu\LocalActionDefault + derivative: \Drupal\field_ui\Plugin\Derivative\FieldUiLocalAction diff --git a/core/modules/field_ui/field_ui.module b/core/modules/field_ui/field_ui.module index bb8ec0b..3f53f40 100644 --- a/core/modules/field_ui/field_ui.module +++ b/core/modules/field_ui/field_ui.module @@ -135,6 +135,7 @@ function field_ui_element_info() { function field_ui_entity_info(&$entity_info) { /** @var $entity_info \Drupal\Core\Entity\EntityTypeInterface[] */ $entity_info['field_instance']->setFormClass('delete', 'Drupal\field_ui\Form\FieldDeleteForm'); + $entity_info['field_instance']->setListClass('Drupal\field_ui\FieldInstanceListController'); $entity_info['field_entity']->setListClass('Drupal\field_ui\FieldListController'); foreach ($entity_info as $info) { diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Controller/FieldInstanceListController.php b/core/modules/field_ui/lib/Drupal/field_ui/Controller/FieldInstanceListController.php new file mode 100644 index 0000000..26c902d --- /dev/null +++ b/core/modules/field_ui/lib/Drupal/field_ui/Controller/FieldInstanceListController.php @@ -0,0 +1,39 @@ +entityManager()->getDefinition($entity_type); + $bundle = $request->attributes->get('_raw_variables')->get($entity_info->getBundleEntityType()); + } + return $this->entityManager()->getListController('field_instance')->render($entity_type, $bundle, $request); + } + +} diff --git a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php index f11863b..7f084ca 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php @@ -12,12 +12,48 @@ use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldTypePluginManagerInterface; +use Drupal\Core\Form\FormBase; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Field UI display overview base class. */ -abstract class DisplayOverviewBase extends OverviewBase { +abstract class DisplayOverviewBase extends FormBase { + + /** + * The name of the entity type. + * + * @var string + */ + protected $entity_type = ''; + + /** + * The entity bundle. + * + * @var string + */ + protected $bundle = ''; + + /** + * The entity type of the entity bundle. + * + * @var string + */ + protected $bundleEntityType; + + /** + * The entity view or form mode. + * + * @var string + */ + protected $mode = ''; + + /** + * The entity manager. + * + * @var \Drupal\Core\Entity\EntityManagerInterface + */ + protected $entityManager; /** * The display context. Either 'view' or 'form'. @@ -51,8 +87,7 @@ * The widget or formatter plugin manager. */ public function __construct(EntityManagerInterface $entity_manager, FieldTypePluginManagerInterface $field_type_manager, PluginManagerBase $plugin_manager) { - parent::__construct($entity_manager); - + $this->entityManager = $entity_manager; $this->fieldTypes = $field_type_manager->getConfigurableDefinitions(); $this->pluginManager = $plugin_manager; } @@ -69,23 +104,6 @@ public static function create(ContainerInterface $container) { } /** - * {@inheritdoc} - */ - public function getRegions() { - return array( - 'content' => array( - 'title' => $this->t('Content'), - 'invisible' => TRUE, - 'message' => $this->t('No field is displayed.') - ), - 'hidden' => array( - 'title' => $this->t('Disabled'), - 'message' => $this->t('No field is hidden.') - ), - ); - } - - /** * Collects the definitions of fields whose display is configurable. * * @return \Drupal\Core\Field\FieldDefinitionInterface[] @@ -111,7 +129,22 @@ protected function getFieldDefinitions() { * {@inheritdoc} */ public function buildForm(array $form, array &$form_state, $entity_type = NULL, $bundle = NULL) { - parent::buildForm($form, $form_state, $entity_type, $bundle); + $entity_info = $this->entityManager->getDefinition($entity_type); + $this->bundleEntityType = $entity_info->getBundleEntityType(); + if (!isset($form_state['bundle'])) { + if (!$bundle) { + $bundle = $this->getRequest()->attributes->get('_raw_variables')->get($this->bundleEntityType); + } + $form_state['bundle'] = $bundle; + } + + $this->entity_type = $entity_type; + $this->bundle = $form_state['bundle']; + + // When displaying the form, make sure the list of fields is up-to-date. + if (empty($form_state['post'])) { + field_info_cache_clear(); + } if (empty($this->mode)) { $this->mode = 'default'; @@ -657,6 +690,157 @@ public function multistepAjax($form, &$form_state) { } /** + * Returns the regions needed to create the overview form. + * + * @return array + * Example usage: + * @code + * return array( + * 'content' => array( + * // label for the region. + * 'title' => $this->t('Content'), + * // Indicates if the region is visible in the UI. + * 'invisible' => TRUE, + * // A message to indicate that there is nothing to be displayed in + * // the region. + * 'message' => $this->t('No field is displayed.'), + * ), + * ); + * @endcode + */ + protected function getRegions() { + return array( + 'content' => array( + 'title' => $this->t('Content'), + 'invisible' => TRUE, + 'message' => $this->t('No field is displayed.') + ), + 'hidden' => array( + 'title' => $this->t('Disabled'), + 'message' => $this->t('No field is hidden.') + ), + ); + } + + /** + * Performs pre-render tasks on field_ui_table elements. + * + * This function is assigned as a #pre_render callback in + * field_ui_element_info(). + * + * @param array $elements + * A structured array containing two sub-levels of elements. Properties + * used: + * - #tabledrag: The value is a list of $options arrays that are passed to + * drupal_attach_tabledrag(). The HTML ID of the table is added to each + * $options array. + * + * @return array + * A renderable array. + * + * @see drupal_render() + * @see drupal_pre_render_table() + */ + public function tablePreRender($elements) { + $js_settings = array(); + + // For each region, build the tree structure from the weight and parenting + // data contained in the flat form structure, to determine row order and + // indentation. + $regions = $elements['#regions']; + $tree = array('' => array('name' => '', 'children' => array())); + $trees = array_fill_keys(array_keys($regions), $tree); + + $parents = array(); + $list = drupal_map_assoc(element_children($elements)); + + // Iterate on rows until we can build a known tree path for all of them. + while ($list) { + foreach ($list as $name) { + $row = &$elements[$name]; + $parent = $row['parent_wrapper']['parent']['#value']; + // Proceed if parent is known. + if (empty($parent) || isset($parents[$parent])) { + // Grab parent, and remove the row from the next iteration. + $parents[$name] = $parent ? array_merge($parents[$parent], array($parent)) : array(); + unset($list[$name]); + + // Determine the region for the row. + $region_name = call_user_func($row['#region_callback'], $row); + + // Add the element in the tree. + $target = &$trees[$region_name]['']; + foreach ($parents[$name] as $key) { + $target = &$target['children'][$key]; + } + $target['children'][$name] = array('name' => $name, 'weight' => $row['weight']['#value']); + + // Add tabledrag indentation to the first row cell. + if ($depth = count($parents[$name])) { + $children = element_children($row); + $cell = current($children); + $indentation = array( + '#theme' => 'indentation', + '#size' => $depth, + ); + $row[$cell]['#prefix'] = drupal_render($indentation) . (isset($row[$cell]['#prefix']) ? $row[$cell]['#prefix'] : ''); + } + + // Add row id and associate JS settings. + $id = drupal_html_class($name); + $row['#attributes']['id'] = $id; + if (isset($row['#js_settings'])) { + $row['#js_settings'] += array( + 'rowHandler' => $row['#row_type'], + 'name' => $name, + 'region' => $region_name, + ); + $js_settings[$id] = $row['#js_settings']; + } + } + } + } + // Determine rendering order from the tree structure. + foreach ($regions as $region_name => $region) { + $elements['#regions'][$region_name]['rows_order'] = array_reduce($trees[$region_name], array($this, 'reduceOrder')); + } + + $elements['#attached']['js'][] = array( + 'type' => 'setting', + 'data' => array('fieldUIRowsData' => $js_settings), + ); + + // If the custom #tabledrag is set and there is a HTML ID, add the table's + // HTML ID to the options and attach the behavior. + // @see drupal_pre_render_table() + if (!empty($elements['#tabledrag']) && isset($elements['#attributes']['id'])) { + foreach ($elements['#tabledrag'] as $options) { + $options['table_id'] = $elements['#attributes']['id']; + drupal_attach_tabledrag($elements, $options); + } + } + + return $elements; + } + + /** + * Determines the rendering order of an array representing a tree. + * + * Callback for array_reduce() within self::tablePreRender(). + */ + public function reduceOrder($array, $a) { + $array = !isset($array) ? array() : $array; + if ($a['name']) { + $array[] = $a['name']; + } + if (!empty($a['children'])) { + uasort($a['children'], array('Drupal\Component\Utility\SortArray', 'sortByWeightElement')); + $array = array_merge($array, array_reduce($a['children'], array($this, 'reduceOrder'))); + } + return $array; + } + + /** * Returns the entity display object used by this form. * * @param string $mode diff --git a/core/modules/field_ui/lib/Drupal/field_ui/FieldInstanceListController.php b/core/modules/field_ui/lib/Drupal/field_ui/FieldInstanceListController.php new file mode 100644 index 0000000..513619b --- /dev/null +++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldInstanceListController.php @@ -0,0 +1,211 @@ +get('entity.manager')->getStorageController($entity_info->id()), + $container->get('module_handler'), + $container->get('entity.manager'), + $container->get('field.info'), + $container->get('plugin.manager.field.field_type') + ); + } + + /** + * Constructs a new EntityListController object. + * + * @param \Drupal\Core\Entity\EntityTypeInterface $entity_info + * The entity info for the entity type. + * @param \Drupal\Core\Entity\EntityStorageControllerInterface $storage + * The entity storage controller class. + * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler + * The module handler to invoke hooks on. + * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager + * The entity manager. + * @param \Drupal\field\FieldInfo $field_info + * The field info service. + * @param \Drupal\Core\Field\FieldTypePluginManager $field_type_manager + * The field type manager + */ + public function __construct(EntityTypeInterface $entity_info, EntityStorageControllerInterface $storage, ModuleHandlerInterface $module_handler, EntityManagerInterface $entity_manager, FieldInfo $field_info, FieldTypePluginManagerInterface $field_type_manager) { + parent::__construct($entity_info, $storage, $module_handler); + + $this->entityManager = $entity_manager; + $this->fieldInfo = $field_info; + $this->fieldTypeManager = $field_type_manager; + } + + /** + * {inheritdoc} + */ + public function render($entity_type = NULL, $bundle = NULL, Request $request = NULl) { + $this->entityTypeId = $entity_type; + $this->bundle = $bundle; + $this->bundleEntityType = $this->entityManager->getDefinition($entity_type)->getBundleEntityType(); + $this->fieldTypes = $this->fieldTypeManager->getConfigurableDefinitions(); + + $build = array( + '#theme' => 'table', + '#header' => $this->buildHeader(), + '#title' => $this->getTitle(), + '#rows' => array(), + '#empty' => $this->t('No fields are present yet.'), + ); + foreach ($this->load() as $entity) { + if ($row = $this->buildRow($entity)) { + $build['#rows'][$entity->id()] = $row; + } + } + return $build; + } + + /** + * {@inheritdoc} + */ + public function load() { + $entities = $this->fieldInfo->getBundleInstances($this->entityTypeId, $this->bundle); + uasort($entities, array($this->entityType->getClass(), 'sort')); + return $entities; + } + + /** + * {@inheritdoc} + */ + public function buildHeader() { + $header = array( + 'label' => $this->t('Label'), + 'machine_name' => array( + 'data' => $this->t('Machine name'), + 'class' => array(RESPONSIVE_PRIORITY_MEDIUM), + ), + 'field_type' => $this->t('Field type'), + ); + return $header + parent::buildHeader(); + } + + /** + * {@inheritdoc} + */ + public function buildRow(EntityInterface $field_instance) { + $row['label'] = String::checkPlain($field_instance->getLabel()); + $row['machine_name'] = $field_instance->getName(); + $field_type = array( + '#type' => 'link', + '#title' => $this->fieldTypes[$field_instance->getField()->getType()]['label'], + '#route_name' => 'field_ui.field_edit_' . $this->entityTypeId, + '#route_parameters' => array( + $this->bundleEntityType => $this->bundle, + 'field_instance' => $field_instance->id(), + ), + '#options' => array('attributes' => array('title' => $this->t('Edit field settings.'))), + ); + $row['field_type'] = drupal_render($field_type); + + return $row += parent::buildRow($field_instance); + } + + /** + * {@inheritdoc} + */ + public function getOperations(EntityInterface $entity) { + $operations = array(); + $route_parameters = array( + $this->bundleEntityType => $this->bundle, + 'field_instance' => $entity->id(), + ); + + $operations['edit'] = array( + 'title' => $this->t('Edit'), + 'route_name' => 'field_ui.instance_edit_' . $this->entityTypeId, + 'route_parameters' => $route_parameters, + 'attributes' => array('title' => $this->t('Edit instance settings.')), + 'weight' => 10, + ); + $operations['field-settings'] = array( + 'title' => $this->t('Field settings'), + 'route_name' => 'field_ui.field_edit_' . $this->entityTypeId, + 'route_parameters' => $route_parameters, + 'attributes' => array('title' => $this->t('Edit field settings.')), + 'weight' => 20, + ); + $operations['delete'] = array( + 'title' => $this->t('Delete'), + 'route_name' => 'field_ui.delete_' . $this->entityTypeId, + 'route_parameters' => $route_parameters, + 'attributes' => array('title' => $this->t('Delete instance.')), + 'weight' => 30, + ); + + return $operations; + } + +} diff --git a/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php b/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php deleted file mode 100644 index 5fd2f69..0000000 --- a/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php +++ /dev/null @@ -1,566 +0,0 @@ -fieldTypeManager = $field_type_manager; - $this->moduleHandler = $module_handler; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container) { - return new static( - $container->get('entity.manager'), - $container->get('plugin.manager.field.field_type'), - $container->get('module_handler') - ); - } - - /** - * {@inheritdoc} - */ - public function getRegions() { - return array( - 'content' => array( - 'title' => $this->t('Content'), - 'invisible' => TRUE, - // @todo Bring back this message in https://drupal.org/node/1963340. - //'message' => $this->t('No fields are present yet.'), - ), - ); - } - - /** - * {@inheritdoc} - */ - public function getFormId() { - return 'field_ui_field_overview_form'; - } - - /** - * {@inheritdoc} - */ - public function buildForm(array $form, array &$form_state, $entity_type = NULL, $bundle = NULL) { - parent::buildForm($form, $form_state, $entity_type, $bundle); - - // Gather bundle information. - $instances = field_info_instances($this->entity_type, $this->bundle); - $field_types = $this->fieldTypeManager->getConfigurableDefinitions(); - - // Field prefix. - $field_prefix = \Drupal::config('field_ui.settings')->get('field_prefix'); - - $form += array( - '#entity_type' => $this->entity_type, - '#bundle' => $this->bundle, - '#fields' => array_keys($instances), - ); - - $table = array( - '#type' => 'field_ui_table', - '#tree' => TRUE, - '#header' => array( - $this->t('Label'), - array( - 'data' => $this->t('Machine name'), - 'class' => array(RESPONSIVE_PRIORITY_MEDIUM), - ), - $this->t('Field type'), - $this->t('Operations'), - ), - '#regions' => $this->getRegions(), - '#attributes' => array( - 'class' => array('field-ui-overview'), - 'id' => 'field-overview', - ), - ); - - // Fields. - foreach ($instances as $name => $instance) { - $field = $instance->getField(); - $route_parameters = array( - $this->bundleEntityType => $this->bundle, - 'field_instance' => $instance->id(), - ); - $table[$name] = array( - '#attributes' => array( - 'id' => drupal_html_class($name), - ), - 'label' => array( - '#markup' => check_plain($instance->getLabel()), - ), - 'field_name' => array( - '#markup' => $instance->getName(), - ), - 'type' => array( - '#type' => 'link', - '#title' => $field_types[$field->getType()]['label'], - '#route_name' => 'field_ui.field_edit_' . $this->entity_type, - '#route_parameters' => $route_parameters, - '#options' => array('attributes' => array('title' => $this->t('Edit field settings.'))), - ), - ); - - $links = array(); - $links['edit'] = array( - 'title' => $this->t('Edit'), - 'route_name' => 'field_ui.instance_edit_' . $this->entity_type, - 'route_parameters' => $route_parameters, - 'attributes' => array('title' => $this->t('Edit instance settings.')), - ); - $links['field-settings'] = array( - 'title' => $this->t('Field settings'), - 'route_name' => 'field_ui.field_edit_' . $this->entity_type, - 'route_parameters' => $route_parameters, - 'attributes' => array('title' => $this->t('Edit field settings.')), - ); - $links['delete'] = array( - 'title' => $this->t('Delete'), - 'route_name' => 'field_ui.delete_' . $this->entity_type, - 'route_parameters' => $route_parameters, - 'attributes' => array('title' => $this->t('Delete instance.')), - ); - // Allow altering the operations on this entity listing. - $this->moduleHandler->alter('entity_operation', $links, $instance); - $table[$name]['operations']['data'] = array( - '#type' => 'operations', - '#links' => $links, - ); - - if (!empty($field->locked)) { - $table[$name]['operations'] = array('#markup' => $this->t('Locked')); - $table[$name]['#attributes']['class'][] = 'menu-disabled'; - } - } - - // 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' => $this->t('New field label'), - '#title_display' => 'invisible', - '#size' => 15, - '#description' => $this->t('Label'), - '#prefix' => '
' . $this->t('Add new field') .'
', - '#suffix' => '
', - ), - 'field_name' => array( - '#type' => 'machine_name', - '#title' => $this->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' => $this->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::NAME_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' => $this->t('Type of new field'), - '#title_display' => 'invisible', - '#options' => $field_type_options, - '#empty_option' => $this->t('- Select a field type -'), - '#description' => $this->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 = $this->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' => $this->t('Existing field label'), - '#title_display' => 'invisible', - '#size' => 15, - '#description' => $this->t('Label'), - '#attributes' => array('class' => array('label-textfield')), - '#prefix' => '
' . $this->t('Re-use existing field') .'
', - '#suffix' => '
', - ), - 'field_name' => array( - '#type' => 'select', - '#title' => $this->t('Existing field to share'), - '#title_display' => 'invisible', - '#options' => $existing_field_options, - '#empty_option' => $this->t('- Select an existing field -'), - '#description' => $this->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. - foreach (element_children($table) as $name) { - $table['#regions']['content']['rows_order'][] = $name; - } - - $form['fields'] = $table; - - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Save')); - - 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']['fields']['_add_new_field']; - - // Validate if any information was provided in the 'add new field' row. - if (array_filter(array($field['label'], $field['field_name'], $field['type']))) { - // Missing label. - if (!$field['label']) { - $this->setFormError('fields][_add_new_field][label', $form_state, $this->t('Add new field: you need to provide a label.')); - } - - // Missing field name. - if (!$field['field_name']) { - $this->setFormError('fields][_add_new_field][field_name', $form_state, $this->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_name = \Drupal::config('field_ui.settings')->get('field_prefix') . $field_name; - form_set_value($form['fields']['_add_new_field']['field_name'], $field_name, $form_state); - } - - // Missing field type. - if (!$field['type']) { - $this->setFormError('fields][_add_new_field][type', $form_state, $this->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']['fields']['_add_existing_field'])) { - $field = $form_state['values']['fields']['_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']) { - $this->setFormError('fields][_add_existing_field][label', $form_state, $this->t('Re-use existing field: you need to provide a label.')); - } - - // Missing existing field name. - if (!$field['field_name']) { - $this->setFormError('fields][_add_existing_field][field_name', $form_state, $this->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) { - $form_values = $form_state['values']['fields']; - $destinations = array(); - - // Create new field. - if (!empty($form_values['_add_new_field']['field_name'])) { - $values = $form_values['_add_new_field']; - - $field = array( - 'name' => $values['field_name'], - 'entity_type' => $this->entity_type, - 'type' => $values['type'], - 'translatable' => $values['translatable'], - ); - $instance = array( - 'field_name' => $values['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($values['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($values['field_name']) - ->save(); - - // Always show the field settings step, as the cardinality needs to be - // configured for new fields. - $route_parameters = array( - $this->bundleEntityType => $this->bundle, - 'field_instance' => $new_instance->id(), - ); - $destinations[] = array('route_name' => 'field_ui.field_edit_' . $this->entity_type, 'route_parameters' => $route_parameters); - $destinations[] = array('route_name' => 'field_ui.instance_edit_' . $this->entity_type, 'route_parameters' => $route_parameters); - - // Store new field information for any additional submit handlers. - $form_state['fields_added']['_add_new_field'] = $values['field_name']; - } - catch (\Exception $e) { - drupal_set_message($this->t('There was a problem creating field %label: !message', array('%label' => $instance->getLabel(), '!message' => $e->getMessage())), 'error'); - } - } - - // Re-use existing field. - if (!empty($form_values['_add_existing_field']['field_name'])) { - $values = $form_values['_add_existing_field']; - $field_name = $values['field_name']; - $field = field_info_field($this->entity_type, $field_name); - if (!empty($field->locked)) { - drupal_set_message($this->t('The field %label cannot be added because it is locked.', array('%label' => $values['label'])), 'error'); - } - else { - $instance = array( - 'field_name' => $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_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_name) - ->save(); - - $destinations[] = array( - 'route_name' => 'field_ui.instance_edit_' . $this->entity_type, - 'route_parameters' => array( - $this->bundleEntityType => $this->bundle, - 'field_instance' => $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($this->t('There was a problem creating field instance %label: @message.', array('%label' => $instance->getLabel(), '@message' => $e->getMessage())), 'error'); - } - } - } - - if ($destinations) { - $destination = drupal_get_destination(); - $destinations[] = $destination['destination']; - $form_state['redirect_route'] = FieldUI::getNextDestination($destinations, $form_state); - } - else { - drupal_set_message($this->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() { - $options = array(); - - // Collect candidate field instances: all instances of fields for this - // entity type that are not already present in the current bundle. - $field_map = field_info_field_map(); - $instance_ids = array(); - if (!empty($field_map[$this->entity_type])) { - foreach ($field_map[$this->entity_type] as $field_name => $data) { - if (!in_array($this->bundle, $data['bundles'])) { - $bundle = reset($data['bundles']); - $instance_ids[] = $this->entity_type . '.' . $bundle . '.' . $field_name; - } - } - } - - // Load the instances and build the list of options. - if ($instance_ids) { - $field_types = $this->fieldTypeManager->getDefinitions(); - $instances = $this->entityManager->getStorageController('field_instance')->loadMultiple($instance_ids); - foreach ($instances as $instance) { - // Do not show: - // - locked fields, - // - fields that should not be added via user interface. - $field_type = $instance->getType(); - $field = $instance->getField(); - if (empty($field->locked) && empty($field_types[$field_type]['no_ui'])) { - $options[$instance->getName()] = array( - 'type' => $field_type, - 'type_label' => $field_types[$field_type]['label'], - 'field' => $instance->getName(), - 'label' => $instance->getLabel(), - ); - } - } - } - - return $options; - } - - /** - * 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) { - // Prefix with 'field_'. - $field_name = 'field_' . $value; - - return (bool) field_info_field($this->entity_type, $field_name); - } - -} 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..5b7cd60 --- /dev/null +++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldAddForm.php @@ -0,0 +1,507 @@ +entityManager = $entity_manager; + $this->fieldInfo = $field_info; + $this->fieldTypePluginManager = $field_type_plugin_manager; + } + + /** + * {@inheritdoc} + */ + public function getFormID() { + return 'field_ui_field_add_form'; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('entity.manager'), + $container->get('field.info'), + $container->get('plugin.manager.field.field_type') + ); + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, array &$form_state, $entity_type = NULL, $bundle = NULL) { + $entity_info = $this->entityManager->getDefinition($entity_type); + $this->bundleEntityTypeId = $entity_info->getBundleEntityType(); + if (!isset($form_state['bundle'])) { + if (!$bundle) { + $bundle = $this->getRequest()->attributes->get('_raw_variables')->get($this->bundleEntityTypeId); + } + $form_state['bundle'] = $bundle; + } + + $this->entityTypeId = $entity_type; + $this->bundle = $form_state['bundle']; + + $form = array( + '#attributes' => array( + 'id' => 'field-add-wrapper', + ), + ); + + // Gather valid field types to add. + $field_type_options = array(); + foreach ($this->fieldTypePluginManager->getConfigurableDefinitions() 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' => $this->t('Field type'), + '#options' => $field_type_options, + '#empty_option' => $this->t('- Select a field type -'), + '#description' => $this->t('Type of data to store.'), + '#ajax' => array( + 'callback' => array(get_class($this), 'updateForm'), + 'wrapper' => 'field-add-wrapper', + ), + ); + + $form['label'] = array( + '#type' => 'textfield', + '#title' => $this->t('Label'), + '#size' => 15, + '#weight' => 20, + ); + + $field_prefix = $this->config('field_ui.settings')->get('field_prefix'); + $form['field_name'] = array( + '#type' => 'machine_name', + // This field should stay LTR even for RTL languages. + '#field_prefix' => '' . $field_prefix, + '#field_suffix' => '‎', + '#size' => 15, + '#description' => $this->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::NAME_MAX_LENGTH - strlen($field_prefix), + '#machine_name' => array( + 'source' => array('label'), + 'exists' => array($this, 'fieldNameExists'), + ), + '#required' => FALSE, + '#weight' => 25, + ); + + // Place the 'translatable' property as an explicit value so that + // contrib modules can form_alter() the value for newly created fields. + $form['translatable'] = array( + '#type' => 'value', + '#value' => FALSE, + ); + + // Determine which options from the 'type' element already have existing + // fields so we know if the new-or-existing element should be displayed. + $field_type = isset($form_state['values']['type']) ? $form_state['values']['type'] : NULL; + $existing_fields = $this->getExistingFieldOptions($field_type); + + $form['new_or_existing'] = array( + '#type' => 'radios', + '#options' => array( + 'new' => $this->t('Create a new field'), + 'existing' => $this->t('Create a new instance of an existing field'), + ), + '#default_value' => 'new', + '#weight' => 10, + '#ajax' => array( + 'callback' => array(get_class($this), 'updateForm'), + 'wrapper' => 'field-add-wrapper', + ), + '#access' => !empty($existing_fields), + ); + + // Update the 'field_name' element if we are adding a new instance of an + // existing field. + if (!empty($existing_fields) && isset($form_state['values']['new_or_existing']) && $form_state['values']['new_or_existing'] == 'existing') { + $existing_field_options = array(); + foreach ($existing_fields as $field_name => $info) { + $text = $this->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); + + $form['field_name'] = array( + '#type' => 'select', + '#title' => $this->t('Existing field to share'), + '#options' => $existing_field_options, + '#empty_option' => $this->t('- Select an existing field -'), + '#weight' => 15, + ); + } + + $form['actions'] = array('#type' => 'actions'); + $form['actions']['submit'] = array( + '#type' => 'submit', + '#value' => $this->t('Save and continue'), + '#button_type' => 'primary', + ); + + return $form; + } + + /** + * Handles switching the 'new_or_existing' selector. + */ + public static function updateForm($form, &$form_state) { + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, array &$form_state) { + $values = $form_state['values']; + + // Missing field type. + if (!$values['type']) { + $this->setFormError('type', $form_state, $this->t('You need to select a field type.')); + } + + $this->validateAddNew($form, $form_state); + $this->validateAddExisting($form, $form_state); + } + + /** + * Validates the 'add new field' case. + * + * @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\Form\FieldAddForm::validateForm() + */ + protected function validateAddNew(array $form, array &$form_state) { + $values = $form_state['values']; + + // Validate if any information was provided in the 'add new field' case. + if ($values['new_or_existing'] == 'new' && array_filter(array($values['label'], $values['field_name']))) { + // Missing label. + if (!$values['label']) { + $this->setFormError('label', $form_state, $this->t('You need to provide a label.')); + } + + // Missing field name. + if (!$values['field_name']) { + $this->setFormError('field_name', $form_state, $this->t('You need to provide a field name.')); + } + // Field name validation. + else { + $field_name = $values['field_name']; + $field_prefix = $this->config('field_ui.settings')->get('field_prefix'); + + // Check if the field name is not longer then the max_length. + if(Field::NAME_MAX_LENGTH - (strlen($field_prefix) + strlen($field_name)) < 0) { + $this->setFormError('field_name', $form_state, $this->t('New field name cannot be longer than %max_length characters but is currently %current_length characters long.', array('%max_length' => Field::NAME_MAX_LENGTH - strlen($field_prefix), 'current_length' => strlen($field_name)))); + } + } + } + } + + /** + * Validates the 're-use existing field' case. + * + * @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\Form\FieldAddForm::validateForm() + */ + protected function validateAddExisting(array $form, array &$form_state) { + $values = $form_state['values']; + + // Validate if any information was provided. + if ($values['new_or_existing'] == 'existing' && array_filter(array($values['label'], $values['field_name']))) { + // Missing label. + if (!$values['label']) { + $this->setFormError('label', $form_state, $this->t('You need to provide a label.')); + } + + // Missing existing field name. + if (!$values['field_name']) { + $this->setFormError('field_name', $form_state, $this->t('You need to select an existing field.')); + } + } + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, array &$form_state) { + $values = $form_state['values']; + $destinations = array(); + + // Create new field. + if ($values['new_or_existing'] == 'new') { + $field_prefix = $this->config('field_ui.settings')->get('field_prefix'); + + $field = array( + 'entity_type' => $this->entityTypeId, + 'name' => $field_prefix . $form_state['values']['field_name'], + 'type' => $form_state['values']['type'], + 'translatable' => $form_state['values']['translatable'], + ); + $instance = array( + 'field_name' => $field['name'], + 'entity_type' => $this->entityTypeId, + 'bundle' => $this->bundle, + 'label' => $values['label'], + ); + + // Create the field and instance. + try { + $new_field = $this->entityManager->getStorageController('field_entity')->create($field); + $new_field->save(); + $new_instance = $this->entityManager->getStorageController('field_instance')->create($instance); + $new_instance->save(); + + $this->configureEntityDisplays($new_field); + + // Always show the field settings step, as the cardinality needs to be + // configured for new fields. + $route_parameters = array( + $this->bundleEntityTypeId => $this->bundle, + 'field_instance' => $new_instance->id(), + ); + $destinations[] = array('route_name' => 'field_ui.field_edit_' . $this->entityTypeId, 'route_parameters' => $route_parameters); + $destinations[] = array('route_name' => 'field_ui.instance_edit_' . $this->entityTypeId, 'route_parameters' => $route_parameters); + $destinations[] = array('route_name' => 'field_ui.overview_' . $this->entityTypeId, 'route_parameters' => $route_parameters); + } + catch (\Exception $e) { + drupal_set_message($this->t('There was a problem creating field %label: !message', array('%label' => $instance['label'], '!message' => $e->getMessage())), 'error'); + } + } + + // Re-use existing field. + if ($values['new_or_existing'] == 'existing') { + $field = $this->fieldInfo->getField($this->entityTypeId, $values['field_name']); + if (!empty($field->locked)) { + drupal_set_message($this->t('The field %label cannot be added because it is locked.', array('%label' => $values['label'])), 'error'); + } + else { + $instance = array( + 'field_name' => $field->getName(), + 'entity_type' => $this->entityTypeId, + 'bundle' => $this->bundle, + 'label' => $values['label'], + ); + + try { + $new_instance = $this->entityManager->getStorageController('field_instance')->create($instance); + $new_instance->save(); + + $this->configureEntityDisplays($field); + + $route_parameters = array( + $this->bundleEntityTypeId => $this->bundle, + 'field_instance' => $new_instance->id(), + ); + $destinations[] = array( + 'route_name' => 'field_ui.instance_edit_' . $this->entityTypeId, + 'route_parameters' => $route_parameters, + ); + $destinations[] = array( + 'route_name' => 'field_ui.overview_' . $this->entityTypeId, + 'route_parameters' => $route_parameters, + ); + } + catch (\Exception $e) { + drupal_set_message($this->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']; + $form_state['redirect_route'] = FieldUI::getNextDestination($destinations, $form_state); + } + else { + drupal_set_message($this->t('Your settings have been saved.')); + } + } + + /** + * Configures the newly created field for the default view and form modes. + * + * @param FieldDefinitionInterface $field + * The field definition. + */ + protected function configureEntityDisplays(FieldDefinitionInterface $field) { + // 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->entityTypeId, $this->bundle, 'default') + ->setComponent($field->getName()) + ->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->entityTypeId, $this->bundle, 'default') + ->setComponent($field->getName()) + ->save(); + } + + /** + * Returns an array of existing fields to be added to a bundle. + * + * @param string $field_type + * A field type. + * + * @return array + * An array of existing fields keyed by field name. + */ + protected function getExistingFieldOptions($field_type) { + $options = array(); + + // Collect candidate field instances: all instances of fields for this + // entity type that are not already present in the current bundle. + $field_map = $this->fieldInfo->getFieldMap(); + $instance_ids = array(); + if (!empty($field_map[$this->entityTypeId])) { + foreach ($field_map[$this->entityTypeId] as $field_name => $data) { + if ($data['type'] == $field_type && !in_array($this->bundle, $data['bundles'])) { + $bundle = reset($data['bundles']); + $instance_ids[] = $this->entityTypeId . '.' . $bundle . '.' . $field_name; + } + } + } + + // Load the instances and build the list of options. + if ($instance_ids) { + $field_types = $this->fieldTypePluginManager->getConfigurableDefinitions(); + $instances = $this->entityManager->getStorageController('field_instance')->loadMultiple($instance_ids); + foreach ($instances as $instance) { + // Do not show: + // - locked fields, + // - fields that should not be added via user interface. + $field_type = $instance->getType(); + $field = $instance->getField(); + if (empty($field->locked) && empty($field_types[$field_type]['no_ui'])) { + $options[$instance->getName()] = array( + 'type' => $field_type, + 'type_label' => $field_types[$field_type]['label'], + 'field' => $instance->getName(), + 'label' => $instance->getLabel(), + ); + } + } + } + + return $options; + } + + /** + * 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 = $this->config('field_ui.settings')->get('field_prefix'); + + return (bool) $this->fieldInfo->getField($this->entityTypeId, $field_prefix . $value); + } + +} diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php index 8536d2a..598a9ee 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php @@ -161,7 +161,11 @@ public function buildForm(array $form, array &$form_state, FieldInstanceInterfac $form['field']['settings'] += $entity->get($field->getName())->first()->settingsForm($form, $form_state, $field->hasData()); $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Save field settings')); + $form['actions']['submit'] = array( + '#type' => 'submit', + '#value' => $this->t('Save field settings'), + '#button_type' => 'primary', + ); return $form; } diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php index 751f1f5..81e442f 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php @@ -150,7 +150,8 @@ public function buildForm(array $form, array &$form_state, FieldInstanceInterfac $form['actions'] = array('#type' => 'actions'); $form['actions']['submit'] = array( '#type' => 'submit', - '#value' => $this->t('Save settings') + '#value' => $this->t('Save settings'), + '#button_type' => 'primary', ); $form['actions']['delete'] = array( '#type' => 'submit', diff --git a/core/modules/field_ui/lib/Drupal/field_ui/OverviewBase.php b/core/modules/field_ui/lib/Drupal/field_ui/OverviewBase.php deleted file mode 100644 index 334914b..0000000 --- a/core/modules/field_ui/lib/Drupal/field_ui/OverviewBase.php +++ /dev/null @@ -1,249 +0,0 @@ -entityManager = $entity_manager; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container) { - return new static( - $container->get('entity.manager') - ); - } - - /** - * {@inheritdoc} - */ - public function buildForm(array $form, array &$form_state, $entity_type = NULL, $bundle = NULL) { - $entity_info = $this->entityManager->getDefinition($entity_type); - $this->bundleEntityType = $entity_info->getBundleEntityType(); - if (!isset($form_state['bundle'])) { - if (!$bundle) { - $bundle = $this->getRequest()->attributes->get('_raw_variables')->get($this->bundleEntityType); - } - $form_state['bundle'] = $bundle; - } - - $this->entity_type = $entity_type; - $this->bundle = $form_state['bundle']; - - // When displaying the form, make sure the list of fields is up-to-date. - if (empty($form_state['post'])) { - field_info_cache_clear(); - } - } - - /** - * Implements \Drupal\Core\Form\FormInterface::submitForm(). - */ - public function submitForm(array &$form, array &$form_state) { - } - - /** - * Get the regions needed to create the overview form. - * - * @return array - * Example usage: - * @code - * return array( - * 'content' => array( - * // label for the region. - * 'title' => $this->t('Content'), - * // Indicates if the region is visible in the UI. - * 'invisible' => TRUE, - * // A message to indicate that there is nothing to be displayed in - * // the region. - * 'message' => $this->t('No field is displayed.'), - * ), - * ); - * @endcode - */ - abstract public function getRegions(); - - /** - * Returns an associative array of all regions. - */ - public function getRegionOptions() { - $options = array(); - foreach ($this->getRegions() as $region => $data) { - $options[$region] = $data['title']; - } - return $options; - } - - /** - * Performs pre-render tasks on field_ui_table elements. - * - * This function is assigned as a #pre_render callback in - * field_ui_element_info(). - * - * @param array $element - * A structured array containing two sub-levels of elements. Properties - * used: - * - #tabledrag: The value is a list of $options arrays that are passed to - * drupal_attach_tabledrag(). The HTML ID of the table is added to each - * $options array. - * - * @see drupal_render() - * @see drupal_pre_render_table() - */ - public function tablePreRender($elements) { - $js_settings = array(); - - // For each region, build the tree structure from the weight and parenting - // data contained in the flat form structure, to determine row order and - // indentation. - $regions = $elements['#regions']; - $tree = array('' => array('name' => '', 'children' => array())); - $trees = array_fill_keys(array_keys($regions), $tree); - - $parents = array(); - $list = drupal_map_assoc(element_children($elements)); - - // Iterate on rows until we can build a known tree path for all of them. - while ($list) { - foreach ($list as $name) { - $row = &$elements[$name]; - $parent = $row['parent_wrapper']['parent']['#value']; - // Proceed if parent is known. - if (empty($parent) || isset($parents[$parent])) { - // Grab parent, and remove the row from the next iteration. - $parents[$name] = $parent ? array_merge($parents[$parent], array($parent)) : array(); - unset($list[$name]); - - // Determine the region for the row. - $region_name = call_user_func($row['#region_callback'], $row); - - // Add the element in the tree. - $target = &$trees[$region_name]['']; - foreach ($parents[$name] as $key) { - $target = &$target['children'][$key]; - } - $target['children'][$name] = array('name' => $name, 'weight' => $row['weight']['#value']); - - // Add tabledrag indentation to the first row cell. - if ($depth = count($parents[$name])) { - $children = element_children($row); - $cell = current($children); - $indentation = array( - '#theme' => 'indentation', - '#size' => $depth, - ); - $row[$cell]['#prefix'] = drupal_render($indentation) . (isset($row[$cell]['#prefix']) ? $row[$cell]['#prefix'] : ''); - } - - // Add row id and associate JS settings. - $id = drupal_html_class($name); - $row['#attributes']['id'] = $id; - if (isset($row['#js_settings'])) { - $row['#js_settings'] += array( - 'rowHandler' => $row['#row_type'], - 'name' => $name, - 'region' => $region_name, - ); - $js_settings[$id] = $row['#js_settings']; - } - } - } - } - // Determine rendering order from the tree structure. - foreach ($regions as $region_name => $region) { - $elements['#regions'][$region_name]['rows_order'] = array_reduce($trees[$region_name], array($this, 'reduceOrder')); - } - - $elements['#attached']['js'][] = array( - 'type' => 'setting', - 'data' => array('fieldUIRowsData' => $js_settings), - ); - - // If the custom #tabledrag is set and there is a HTML ID, add the table's - // HTML ID to the options and attach the behavior. - // @see drupal_pre_render_table() - if (!empty($elements['#tabledrag']) && isset($elements['#attributes']['id'])) { - foreach ($elements['#tabledrag'] as $options) { - $options['table_id'] = $elements['#attributes']['id']; - drupal_attach_tabledrag($elements, $options); - } - } - - return $elements; - } - - /** - * Determines the rendering order of an array representing a tree. - * - * Callback for array_reduce() within - * \Drupal\field_ui\OverviewBase::tablePreRender(). - */ - public function reduceOrder($array, $a) { - $array = !isset($array) ? array() : $array; - if ($a['name']) { - $array[] = $a['name']; - } - if (!empty($a['children'])) { - uasort($a['children'], array('Drupal\Component\Utility\SortArray', 'sortByWeightElement')); - $array = array_merge($array, array_reduce($a['children'], array($this, 'reduceOrder'))); - } - return $array; - } - -} diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Plugin/Derivative/FieldUiLocalAction.php b/core/modules/field_ui/lib/Drupal/field_ui/Plugin/Derivative/FieldUiLocalAction.php new file mode 100644 index 0000000..210527b --- /dev/null +++ b/core/modules/field_ui/lib/Drupal/field_ui/Plugin/Derivative/FieldUiLocalAction.php @@ -0,0 +1,90 @@ +entityManager = $entity_manager; + $this->translationManager = $translation_manager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, $base_plugin_id) { + return new static( + $container->get('entity.manager'), + $container->get('string_translation') + ); + } + + /** + * {@inheritdoc} + */ + public function getDerivativeDefinitions(array $base_plugin_definition) { + $this->derivatives = array(); + + foreach ($this->entityManager->getDefinitions() as $entity_type => $info) { + if ($info->isFieldable() && $info->hasLinkTemplate('admin-form')) { + $this->derivatives["add_$entity_type"] = array( + 'route_name' => "field_ui.add_$entity_type", + 'title' => $this->t('Add field'), + 'appears_on' => array("field_ui.overview_$entity_type"), + ); + } + } + + foreach ($this->derivatives as &$entry) { + $entry += $base_plugin_definition; + } + + return $this->derivatives; + } + + /** + * Translates a string to the current language or to a given language. + * + * See the t() documentation for details. + */ + protected function t($string, array $args = array(), array $options = array()) { + return $this->translationManager->translate($string, $args, $options); + } + +} 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 2ec7438..8a5f9ce 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 @@ -80,7 +80,7 @@ protected function alterRoutes(RouteCollection $collection, $provider) { $route = new Route( "$path/fields", array( - '_form' => '\Drupal\field_ui\FieldOverview', + '_content' => '\Drupal\field_ui\Controller\FieldInstanceListController::listing', '_title' => 'Manage fields', ) + $defaults, array('_permission' => 'administer ' . $entity_type . ' fields') @@ -88,6 +88,16 @@ protected function alterRoutes(RouteCollection $collection, $provider) { $collection->add("field_ui.overview_$entity_type", $route); $route = new Route( + "$path/add-field", + array( + '_form' => '\Drupal\field_ui\Form\FieldAddForm', + '_title' => 'Add field', + ) + $defaults, + array('_permission' => 'administer ' . $entity_type . ' fields') + ); + $collection->add("field_ui.add_$entity_type", $route); + + $route = new Route( "$path/form-display", array( '_form' => '\Drupal\field_ui\FormDisplayOverview', diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/FieldUIRouteTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/FieldUIRouteTest.php index 6932cc3..3c307f1 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/FieldUIRouteTest.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/FieldUIRouteTest.php @@ -46,9 +46,7 @@ public function setUp() { */ public function testFieldUIRoutes() { $this->drupalGet('field-ui-test-no-bundle/manage/fields'); - // @todo Bring back this assertion in https://drupal.org/node/1963340. - // @see \Drupal\field_ui\FieldOverview::getRegions() - //$this->assertText('No fields are present yet.'); + $this->assertText('No fields are present yet.'); $this->drupalGet('admin/structure/types/manage/article/fields'); $this->assertTitle('Manage fields | Drupal'); 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 f103e6d..b6c36c9 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->drupalPostForm("$bundle_path/fields", $initial_edit, t('Save')); + $this->drupalPostForm("$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.'); // Test Breadcrumbs. $this->assertLink($label, 0, 'Field label is correct in the breadcrumb of the field settings page.'); @@ -85,6 +86,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"]//tr/td[1]', $label, 'Field was created and appears in the overview page.'); } @@ -101,16 +103,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->drupalPostForm("$bundle_path/fields", $initial_edit, t('Save')); + $this->drupalPostForm("$bundle_path/add-field", $initial_edit, t('Save field settings')); // Second step : 'Instance settings' form. $this->drupalPostForm(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"]//tr/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 4a25ca6..16e0049 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); @@ -120,8 +120,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); @@ -182,8 +182,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 @@ -254,8 +254,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 f86f50a..2342b89 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 @@ -9,6 +9,7 @@ use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Language\Language; +use Drupal\field\Entity\Field; use Drupal\Component\Utility\String; /** @@ -100,11 +101,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.'); } /** @@ -116,8 +114,8 @@ 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); } @@ -155,9 +153,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 fields of other entity types (here, the 'comment_body' field) // do not show up in the "Re-use existing field" list. @@ -165,8 +163,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); } @@ -260,16 +258,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->drupalPostForm('admin/structure/types/manage/' . $this->type . '/fields', $edit, t('Save')); - $this->assertText('New field name cannot be longer than 22 characters but is currently 23 characters long.'); + $this->drupalPostForm('admin/structure/types/manage/' . $this->type . '/add-field', $edit, t('Save field settings')); + $this->assertText(format_string('New field name cannot be longer than @max_length characters but is currently @current_length characters long.', array('@max_length' => (Field::NAME_MAX_LENGTH - strlen($field_prefix)), '@current_length' => strlen($field_exceed_max_length_input)))); // 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); @@ -343,8 +341,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); @@ -356,8 +354,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); @@ -457,7 +455,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."); // Check that non-configurable fields are not available. $field_types = \Drupal::service('plugin.manager.field.field_type')->getDefinitions(); @@ -491,12 +489,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->drupalPostForm($url, $edit, t('Save')); + $url = 'admin/structure/types/manage/' . $this->type . '/add-field'; + $this->drupalPostForm($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.'); @@ -509,8 +507,8 @@ function testDeleteTaxonomyField() { // Create a new field. $bundle_path = 'admin/structure/taxonomy/manage/tags/overview'; $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 bf80c17..ac10dba 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php +++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php @@ -253,11 +253,11 @@ function testPrivateFileComment() { // Create a new field. $this->container->get('comment.manager')->addDefaultField('node', 'article'); $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->randomString(), + '_add_new_field[field_name]' => $name = strtolower($this->randomName()), + 'type' => 'file', ); - $this->drupalPostForm('admin/structure/comments/manage/node__comment/fields', $edit, t('Save')); + $this->drupalPostForm('admin/structure/comments/manage/node__comment/add-field', $edit, t('Save field settings')); $edit = array('field[settings][uri_scheme]' => 'private'); $this->drupalPostForm(NULL, $edit, t('Save field settings')); $this->drupalPostForm(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 97fda35..b18ccb0 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->drupalPostForm("$type_path/fields", $edit, t('Save')); + $this->drupalPostForm($type_path . '/add-field', $edit, t('Save field settings')); // Proceed to the Edit (field instance settings) page. $this->drupalPostForm(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 4dfe210..45c0a7a 100644 --- a/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php +++ b/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php @@ -163,11 +163,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->drupalPostForm(NULL, $edit, t('Save')); + $this->drupalPostForm('admin/structure/types/manage/' . $type . '/add-field', $edit, t('Save field settings')); // Add prefix and suffix for the newly-created field. $prefix = $this->randomName();