diff --git a/core/includes/entity.api.php b/core/includes/entity.api.php
index a56c1ef..3d41178 100644
--- a/core/includes/entity.api.php
+++ b/core/includes/entity.api.php
@@ -97,15 +97,8 @@ function hook_entity_view_mode_info_alter(&$view_modes) {
* - admin: An array of information that allows Field UI pages to attach
* themselves to the existing administration pages for the bundle.
* Elements:
- * - path: the path of the bundle's main administration page, as defined
- * in hook_menu(). If the path includes a placeholder for the bundle,
- * the 'bundle argument', 'bundle helper' and 'real path' keys below
- * are required.
- * - bundle argument: The position of the placeholder in 'path', if any.
* - real path: The actual path (no placeholder) of the bundle's main
* administration page. This will be used to generate links.
- * - access callback: As in hook_menu(). 'user_access' will be assumed if
- * no value is provided.
* - access arguments: As in hook_menu().
* - translatable: (optional) A boolean value specifying whether this bundle
* has translation support enabled. Defaults to FALSE.
diff --git a/core/lib/Drupal/Core/Entity/Annotation/EntityType.php b/core/lib/Drupal/Core/Entity/Annotation/EntityType.php
index f3c02ed..43530a2 100644
--- a/core/lib/Drupal/Core/Entity/Annotation/EntityType.php
+++ b/core/lib/Drupal/Core/Entity/Annotation/EntityType.php
@@ -221,6 +221,18 @@ class EntityType extends Plugin {
public $bundle_keys;
/**
+ * The base path for the entity type administration page.
+ *
+ * If the entity type has a bundle, include {bundle} in the path.
+ *
+ * For example, the node entity type specifies
+ * "admin/structure/types/manage/{bundle}" as its base path.
+ *
+ * @var string
+ */
+ public $entity_menu_base_path;
+
+ /**
* The base menu router path to which the entity admin user interface responds.
*
* It can be used to generate UI links and to attach additional router items
diff --git a/core/modules/block/custom_block/custom_block.module b/core/modules/block/custom_block/custom_block.module
index 4a1cbcb..9226e68 100644
--- a/core/modules/block/custom_block/custom_block.module
+++ b/core/modules/block/custom_block/custom_block.module
@@ -189,9 +189,7 @@ function custom_block_entity_bundle_info() {
$bundles['custom_block'][$config->get('id')] = array(
'label' => $config->get('label'),
'admin' => array(
- 'path' => 'admin/structure/custom-blocks/manage/%',
'real path' => 'admin/structure/custom-blocks/manage/' . $config->get('id'),
- 'bundle argument' => 4,
),
);
}
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Core/Entity/CustomBlock.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Core/Entity/CustomBlock.php
index 933b890..df567c3 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Core/Entity/CustomBlock.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Core/Entity/CustomBlock.php
@@ -29,6 +29,7 @@
* translation_controller_class = "Drupal\custom_block\CustomBlockTranslationController",
* base_table = "custom_block",
* revision_table = "custom_block_revision",
+ * entity_menu_base_path = "admin/structure/custom-blocks/manage/{bundle}",
* menu_base_path = "block/%custom_block",
* fieldable = TRUE,
* translatable = TRUE,
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php
index eee184a..35f4b98 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php
@@ -99,7 +99,7 @@ public function testCustomBlockTypeEditing() {
$this->assertEqual(url('block/add/basic', array('absolute' => TRUE)), $this->getUrl(), 'Original machine name was used in URL.');
// Remove the body field.
- $this->drupalPost('admin/structure/custom-blocks/manage/basic/fields/block_body/delete', array(), t('Delete'));
+ $this->drupalPost('admin/structure/custom-blocks/manage/basic/fields/custom_block.basic.block_body/delete', array(), t('Delete'));
// Resave the settings for this type.
$this->drupalPost('admin/structure/custom-blocks/manage/basic', array(), t('Save'));
// Check that the body field doesn't exist.
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 5690c72..8466ce2 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -119,14 +119,6 @@ function comment_entity_bundle_info() {
// have to be extracted manually from the bundle name.
'node bundle' => $type,
'admin' => array(
- // Place the Field UI paths for comments one level below the
- // corresponding paths for nodes, so that they appear in the same set
- // of local tasks. Note that the paths use a different placeholder name
- // and thus a different menu loader callback, so that Field UI page
- // callbacks get a comment bundle name from the node type in the URL.
- // See comment_node_type_load() and comment_menu_alter().
- 'path' => 'admin/structure/types/manage/%comment_node_type/comment',
- 'bundle argument' => 4,
'real path' => 'admin/structure/types/manage/' . $type . '/comment',
),
);
@@ -301,10 +293,10 @@ function comment_menu_alter(&$items) {
// Adjust the Field UI tabs on admin/structure/types/manage/[node-type].
// See comment_entity_bundle_info().
- $items['admin/structure/types/manage/%comment_node_type/comment/fields']['title'] = 'Comment fields';
- $items['admin/structure/types/manage/%comment_node_type/comment/fields']['weight'] = 3;
- $items['admin/structure/types/manage/%comment_node_type/comment/display']['title'] = 'Comment display';
- $items['admin/structure/types/manage/%comment_node_type/comment/display']['weight'] = 4;
+ $items['admin/structure/types/manage/%/comment/fields']['title'] = 'Comment fields';
+ $items['admin/structure/types/manage/%/comment/fields']['weight'] = 3;
+ $items['admin/structure/types/manage/%/comment/display']['title'] = 'Comment display';
+ $items['admin/structure/types/manage/%/comment/display']['weight'] = 4;
}
/**
diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/Core/Entity/Comment.php b/core/modules/comment/lib/Drupal/comment/Plugin/Core/Entity/Comment.php
index e8af942..029868f 100644
--- a/core/modules/comment/lib/Drupal/comment/Plugin/Core/Entity/Comment.php
+++ b/core/modules/comment/lib/Drupal/comment/Plugin/Core/Entity/Comment.php
@@ -32,6 +32,7 @@
* fieldable = TRUE,
* translatable = TRUE,
* static_cache = FALSE,
+ * entity_menu_base_path = "admin/structure/types/manage/{bundle}/comment",
* entity_keys = {
* "id" = "cid",
* "bundle" = "node_type",
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentFieldsTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentFieldsTest.php
index a29db8c..c92d2ab 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentFieldsTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentFieldsTest.php
@@ -107,7 +107,7 @@ function testCommentFormat() {
// Disable text processing for comments.
$this->drupalLogin($this->admin_user);
$edit = array('instance[settings][text_processing]' => 0);
- $this->drupalPost('admin/structure/types/manage/article/comment/fields/comment_body', $edit, t('Save settings'));
+ $this->drupalPost('admin/structure/types/manage/article/comment/fields/comment.comment_node_article.comment_body', $edit, t('Save settings'));
// Post a comment without an explicit subject.
$this->drupalLogin($this->web_user);
diff --git a/core/modules/contact/contact.module b/core/modules/contact/contact.module
index e134ccc..c3e6fae 100644
--- a/core/modules/contact/contact.module
+++ b/core/modules/contact/contact.module
@@ -179,9 +179,7 @@ function contact_entity_bundle_info() {
$bundles['contact_message'][$config->get('id')] = array(
'label' => $config->get('label'),
'admin' => array(
- 'path' => 'admin/structure/contact/manage/%contact_category',
'real path' => 'admin/structure/contact/manage/' . $config->get('id'),
- 'bundle argument' => 4,
'access arguments' => array('administer contact forms'),
),
);
diff --git a/core/modules/field_ui/field_ui.admin.inc b/core/modules/field_ui/field_ui.admin.inc
index 2d7e7ca..510ff0b 100644
--- a/core/modules/field_ui/field_ui.admin.inc
+++ b/core/modules/field_ui/field_ui.admin.inc
@@ -292,31 +292,6 @@ function theme_field_ui_table($variables) {
}
/**
- * Returns the built and processed 'Manage fields' form of a bundle.
- *
- * The resulting form allows fields and pseudo-fields to be re-ordered.
- *
- * @param string $entity_type
- * The entity type for the fieldable entity.
- * @param string $bundle
- * The bundle for the fieldable entity.
- *
- * @return
- * The processed form for the given entity type and bundle.
- *
- * @see field_ui_menu()
- * @see Drupal\field_ui\FieldOverview::validate()
- * @see Drupal\field_ui\FieldOverview::submit()
- * @ingroup forms
- */
-function field_ui_field_overview($entity_type, $bundle) {
- $bundle = field_extract_bundle($entity_type, $bundle);
- field_ui_inactive_message($entity_type, $bundle);
-
- return drupal_get_form(new FieldOverview($entity_type, $bundle));
-}
-
-/**
* Render API callback: Checks if a field machine name is taken.
*
* @param $value
@@ -335,33 +310,6 @@ function _field_ui_field_name_exists($value) {
}
/**
- * Returns the built and processed 'Manage display' form of a bundle.
- *
- * The resulting form allows fields and pseudo-fields to be re-ordered.
- *
- * @param string $entity_type
- * The entity type for the fieldable entity.
- * @param string $bundle
- * The bundle for the fieldable entity.
- * @param string $view_mode
- * The view mode for the fieldable entity.
- *
- * @return
- * The processed form for the given entity type and bundle.
- *
- * @see field_ui_menu()
- * @see field_ui_display_overview_multistep_submit()
- * @see Drupal\field_ui\DisplayOverview::submit()
- * @ingroup forms
- */
-function field_ui_display_overview($entity_type, $bundle, $view_mode) {
- $bundle = field_extract_bundle($entity_type, $bundle);
- field_ui_inactive_message($entity_type, $bundle);
-
- return drupal_get_form(new DisplayOverview($entity_type, $bundle, $view_mode));
-}
-
-/**
* Returns an array of field_type options.
*/
function field_ui_field_type_options() {
@@ -488,552 +436,6 @@ function field_ui_existing_field_options($entity_type, $bundle) {
}
/**
- * Form constructor for the field settings edit page.
- *
- * @see field_ui_menu()
- * @see field_ui_field_settings_form_submit()
- * @ingroup forms
- */
-function field_ui_field_settings_form($form, &$form_state, $instance) {
- $bundle = $instance['bundle'];
- $entity_type = $instance['entity_type'];
- $field = field_info_field($instance['field_name']);
- $form['#field'] = $field;
- $form['#entity_type'] = $entity_type;
- $form['#bundle'] = $bundle;
-
- drupal_set_title($instance['label']);
-
- $description = '
' . t('These settings apply to the %field field everywhere it is used. These settings impact the way that data is stored in the database and cannot be changed once data has been created.', array('%field' => $instance['label'])) . '
';
-
- // Create a form structure for the field values.
- $form['field'] = array(
- '#prefix' => $description,
- '#tree' => TRUE,
- );
-
- // See if data already exists for this field.
- // If so, prevent changes to the field settings.
- $has_data = field_has_data($field);
- if ($has_data) {
- $form['field']['#prefix'] = '' . t('There is data for this field in the database. The field settings can no longer be changed.') . '
' . $form['field']['#prefix'];
- }
-
- // Build the configurable field values.
- $cardinality = $field['cardinality'];
- $form['field']['container'] = array(
- // We can't use the container element because it doesn't support the title
- // or description properties.
- '#type' => 'item',
- '#field_prefix' => '',
- '#field_suffix' => '
',
- '#title' => t('Maximum number of values users can enter'),
- );
- $form['field']['container']['cardinality'] = array(
- '#type' => 'select',
- '#options' => drupal_map_assoc(range(1, 5)) + array(FIELD_CARDINALITY_UNLIMITED => t('Unlimited')) + array('other' => t('More')),
- '#default_value' => ($cardinality < 6) ? $cardinality : 'other',
- );
- // @todo Convert when http://drupal.org/node/1207060 gets in.
- $form['field']['container']['cardinality_other'] = array(
- '#type' => 'number',
- '#default_value' => $cardinality > 5 ? $cardinality : 6,
- '#min' => 1,
- '#title' => t('Custom value'),
- '#title_display' => 'invisible',
- '#states' => array(
- 'visible' => array(
- ':input[name="field[container][cardinality]"]' => array('value' => 'other'),
- ),
- ),
- );
- if (field_behaviors_widget('multiple values', $instance) == FIELD_BEHAVIOR_DEFAULT) {
- $form['field']['container']['#description'] = t('%unlimited will provide an %add-more button so users can add as many values as they like.', array(
- '%unlimited' => t('Unlimited'),
- '%add-more' => t('Add another item'),
- ));
- }
-
- // Build the non-configurable field values.
- $form['field']['field_name'] = array('#type' => 'value', '#value' => $field['field_name']);
- $form['field']['type'] = array('#type' => 'value', '#value' => $field['type']);
- $form['field']['module'] = array('#type' => 'value', '#value' => $field['module']);
- $form['field']['active'] = array('#type' => 'value', '#value' => $field['active']);
-
- // Add settings provided by the field module. The field module is
- // responsible for not returning settings that cannot be changed if
- // the field already has data.
- $form['field']['settings'] = array(
- '#weight' => 10,
- );
- $additions = module_invoke($field['module'], 'field_settings_form', $field, $instance, $has_data);
- if (is_array($additions)) {
- $form['field']['settings'] += $additions;
- }
-
- $form['actions'] = array('#type' => 'actions');
- $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save field settings'));
- return $form;
-}
-
-/**
- * Form validation handler for field_ui_field_edit_form().
- *
- * @see field_ui_field_settings_form_submit().
- */
-function field_ui_field_settings_form_validate($form, &$form_state) {
- // Validate field cardinality.
- $cardinality = $form_state['values']['field']['container']['cardinality'];
- $cardinality_other = $form_state['values']['field']['container']['cardinality_other'];
- if ($cardinality == 'other' && empty($cardinality_other)) {
- form_error($form['field']['container']['cardinality_other'], t('Number of values is required.'));
- }
-}
-
-/**
- * Form submission handler for field_ui_field_settings_form().
- */
-function field_ui_field_settings_form_submit($form, &$form_state) {
- $form_values = $form_state['values'];
- $field_values = $form_values['field'];
-
- // Save field cardinality.
- $cardinality = $field_values['container']['cardinality'];
- $cardinality_other = $field_values['container']['cardinality_other'];
- $cardinality_other = $form_state['values']['field']['container']['cardinality_other'];
- if ($cardinality == 'other') {
- $cardinality = $cardinality_other;
- }
- $field_values['cardinality'] = $cardinality;
- unset($field_values['container']);
-
- // Merge incoming form values into the existing field.
- $field = field_info_field($field_values['field_name']);
- foreach ($field_values as $key => $value) {
- $field[$key] = $value;
- }
-
- $entity_type = $form['#entity_type'];
- $bundle = $form['#bundle'];
- $instance = field_info_instance($entity_type, $field['field_name'], $bundle);
-
- // Update the field.
- try {
- field_update_field($field);
- drupal_set_message(t('Updated field %label field settings.', array('%label' => $instance['label'])));
- $form_state['redirect'] = field_ui_next_destination($entity_type, $bundle);
- }
- catch (Exception $e) {
- drupal_set_message(t('Attempt to update field %label failed: %message.', array('%label' => $instance['label'], '%message' => $e->getMessage())), 'error');
- }
-}
-
-/**
- * Form constructor for the widget selection form.
- *
- * @see field_ui_menu()
- * @see field_ui_widget_type_form_submit()
- * @ingroup forms
- */
-function field_ui_widget_type_form($form, &$form_state, FieldInstance $instance) {
- drupal_set_title($instance['label']);
-
- $bundle = $instance['bundle'];
- $entity_type = $instance['entity_type'];
- $field_name = $instance['field_name'];
-
- $field = field_info_field($field_name);
- $bundles = entity_get_bundles();
- $bundle_label = $bundles[$entity_type][$bundle]['label'];
-
- $form = array(
- '#bundle' => $bundle,
- '#entity_type' => $entity_type,
- '#field_name' => $field_name,
- );
-
- $form['widget_type'] = array(
- '#type' => 'select',
- '#title' => t('Widget type'),
- '#required' => TRUE,
- '#options' => field_ui_widget_type_options($field['type']),
- '#default_value' => $instance->getWidget()->getPluginId(),
- '#description' => t('The type of form element you would like to present to the user when creating this field in the %type type.', array('%type' => $bundle_label)),
- );
-
- $form['actions'] = array('#type' => 'actions');
- $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Continue'));
-
- $form['#validate'] = array();
- $form['#submit'] = array('field_ui_widget_type_form_submit');
-
- return $form;
-}
-
-/**
- * Form submission handler for field_ui_widget_type_form().
- */
-function field_ui_widget_type_form_submit($form, &$form_state) {
- $form_values = $form_state['values'];
- $bundle = $form['#bundle'];
- $entity_type = $form['#entity_type'];
- $field_name = $form['#field_name'];
-
- // Retrieve the stored instance settings to merge with the incoming values.
- $instance = field_read_instance($entity_type, $field_name, $bundle);
-
- // Set the right module information.
- $widget_type = field_info_widget_types($form_values['widget_type']);
- $widget_module = $widget_type['module'];
-
- $instance['widget']['type'] = $form_values['widget_type'];
- $instance['widget']['module'] = $widget_module;
-
- try {
- field_update_instance($instance);
- drupal_set_message(t('Changed the widget for field %label.', array('%label' => $instance['label'])));
-
- if ($instance['required'] && empty($instance['default_value']) && empty($instance['default_value_function']) && $instance['widget']['type'] == 'field_hidden') {
- drupal_set_message(t('Field %label is required and uses the "hidden" widget. You might want to configure a default value.', array('%label' => $instance['label'])), 'warning');
- }
- }
- catch (Exception $e) {
- drupal_set_message(t('There was a problem changing the widget for field %label.', array('%label' => $instance['label'])), 'error');
- }
-
- $form_state['redirect'] = field_ui_next_destination($entity_type, $bundle);
-}
-
-/**
- * Form constructor for removing a field instance from a bundle.
- *
- * @see field_ui_menu()
- * @see field_ui_field_delete_form_submit()
- * @ingroup forms
- */
-function field_ui_field_delete_form($form, &$form_state, $instance) {
- $bundle = $instance['bundle'];
- $entity_type = $instance['entity_type'];
- $field = field_info_field($instance['field_name']);
-
- $admin_path = field_ui_bundle_admin_path($entity_type, $bundle);
-
- $form['entity_type'] = array('#type' => 'value', '#value' => $entity_type);
- $form['bundle'] = array('#type' => 'value', '#value' => $bundle);
- $form['field_name'] = array('#type' => 'value', '#value' => $field['field_name']);
-
- $output = confirm_form($form,
- t('Are you sure you want to delete the field %field?', array('%field' => $instance['label'])),
- $admin_path . '/fields',
- t('If you have any content left in this field, it will be lost. This action cannot be undone.'),
- t('Delete'), t('Cancel'),
- 'confirm'
- );
-
- if ($field['locked']) {
- unset($output['actions']['submit']);
- $output['description']['#markup'] = t('This field is locked and cannot be deleted.');
- }
-
- return $output;
-}
-
-/**
- * Form submission handler for field_ui_field_delete_form().
- *
- * Removes a field instance from a bundle. If the field has no more instances,
- * it will be marked as deleted too.
- */
-function field_ui_field_delete_form_submit($form, &$form_state) {
- $form_values = $form_state['values'];
- $field_name = $form_values['field_name'];
- $bundle = $form_values['bundle'];
- $entity_type = $form_values['entity_type'];
-
- $field = field_info_field($field_name);
- $instance = field_info_instance($entity_type, $field_name, $bundle);
- $bundles = entity_get_bundles();
- $bundle_label = $bundles[$entity_type][$bundle]['label'];
-
- if (!empty($bundle) && $field && !$field['locked'] && $form_values['confirm']) {
- field_delete_instance($instance);
- drupal_set_message(t('The field %field has been deleted from the %type content type.', array('%field' => $instance['label'], '%type' => $bundle_label)));
- }
- else {
- drupal_set_message(t('There was a problem removing the %field from the %type content type.', array('%field' => $instance['label'], '%type' => $bundle_label)), 'error');
- }
-
- $admin_path = field_ui_bundle_admin_path($entity_type, $bundle);
- $form_state['redirect'] = field_ui_get_destinations(array($admin_path . '/fields'));
-
- // Fields are purged on cron. However field module prevents disabling modules
- // when field types they provided are used in a field until it is fully
- // purged. In the case that a field has minimal or no content, a single call
- // to field_purge_batch() will remove it from the system. Call this with a
- // low batch limit to avoid administrators having to wait for cron runs when
- // removing instances that meet this criteria.
- field_purge_batch(10);
-}
-
-/**
- * Form constructor for the field instance settings form.
- *
- * @see field_ui_menu()
- * @see field_ui_field_edit_form_validate()
- * @see field_ui_field_edit_form_submit()
- * @see field_ui_field_edit_form_delete_submit()
- * @ingroup forms
- */
-function field_ui_field_edit_form($form, &$form_state, $instance) {
- $bundle = $instance['bundle'];
- $entity_type = $instance['entity_type'];
- $field = field_info_field($instance['field_name']);
- $bundles = entity_get_bundles();
-
- drupal_set_title(t('%instance settings for %bundle', array(
- '%instance' => $instance['label'],
- '%bundle' => $bundles[$entity_type][$bundle]['label'],
- )), PASS_THROUGH);
-
- $form['#field'] = $field;
- $form['#instance'] = $instance;
- // Create an arbitrary entity object (used by the 'default value' widget).
- $ids = (object) array('entity_type' => $instance['entity_type'], 'bundle' => $instance['bundle'], 'entity_id' => NULL);
- $form['#entity'] = _field_create_entity_from_ids($ids);
- $form['#entity']->field_ui_default_value = TRUE;
-
- if (!empty($field['locked'])) {
- $form['locked'] = array(
- '#markup' => t('The field %field is locked and cannot be edited.', array('%field' => $instance['label'])),
- );
- return $form;
- }
-
- $widget_type = field_info_widget_types($instance['widget']['type']);
-
- // Create a form structure for the instance values.
- $form['instance'] = array(
- '#tree' => TRUE,
- );
-
- // Build the non-configurable instance values.
- $form['instance']['field_name'] = array(
- '#type' => 'value',
- '#value' => $instance['field_name'],
- );
- $form['instance']['entity_type'] = array(
- '#type' => 'value',
- '#value' => $entity_type,
- );
- $form['instance']['bundle'] = array(
- '#type' => 'value',
- '#value' => $bundle,
- );
- $form['instance']['widget']['weight'] = array(
- '#type' => 'value',
- '#value' => !empty($instance['widget']['weight']) ? $instance['widget']['weight'] : 0,
- );
-
- // Build the configurable instance values.
- $form['instance']['label'] = array(
- '#type' => 'textfield',
- '#title' => t('Label'),
- '#default_value' => !empty($instance['label']) ? $instance['label'] : $field['field_name'],
- '#required' => TRUE,
- '#weight' => -20,
- );
-
- $form['instance']['description'] = array(
- '#type' => 'textarea',
- '#title' => t('Help text'),
- '#default_value' => !empty($instance['description']) ? $instance['description'] : '',
- '#rows' => 5,
- '#description' => t('Instructions to present to the user below this field on the editing form.
Allowed HTML tags: @tags', array('@tags' => _field_filter_xss_display_allowed_tags())) . '
' . t('This field supports tokens.'),
- '#weight' => -10,
- );
-
- $form['instance']['required'] = array(
- '#type' => 'checkbox',
- '#title' => t('Required field'),
- '#default_value' => !empty($instance['required']),
- '#weight' => -5,
- );
-
- // Build the widget component of the instance.
- $form['instance']['widget']['type'] = array(
- '#type' => 'value',
- '#value' => $instance['widget']['type'],
- );
-
- // Add additional field instance settings from the field module.
- $additions = module_invoke($field['module'], 'field_instance_settings_form', $field, $instance, $form_state);
- if (is_array($additions)) {
- $form['instance']['settings'] = $additions;
- $form['instance']['settings']['#weight'] = 10;
- }
-
- // Add widget settings for the widget type.
- $additions = $instance->getWidget()->settingsForm($form, $form_state);
- $form['instance']['widget']['settings'] = $additions ? $additions : array('#type' => 'value', '#value' => array());
- $form['instance']['widget']['#weight'] = 20;
-
- // Add handling for default value if not provided by any other module.
- if (field_behaviors_widget('default_value', $instance) == FIELD_BEHAVIOR_DEFAULT && empty($instance['default_value_function'])) {
- $form['instance']['default_value_widget'] = field_ui_default_value_widget($field, $instance, $form, $form_state);
- }
-
- $form['actions'] = array('#type' => 'actions');
- $form['actions']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Save settings')
- );
- $form['actions']['delete'] = array(
- '#type' => 'submit',
- '#value' => t('Delete field'),
- '#submit' => array('field_ui_field_edit_form_delete_submit'),
- );
- return $form;
-}
-
-/**
- * Form submission handler for 'Delete' button in field_ui_field_edit_form().
- */
-function field_ui_field_edit_form_delete_submit($form, &$form_state) {
- $destination = array();
- if (isset($_GET['destination'])) {
- $destination = drupal_get_destination();
- unset($_GET['destination']);
- }
- $instance = $form['#instance'];
- $form_state['redirect'] = array('admin/structure/types/manage/' . $instance['bundle'] . '/fields/' . $instance['field_name'] . '/delete', array('query' => $destination));
-}
-
-/**
- * Builds the default value widget for a given field instance.
- */
-function field_ui_default_value_widget($field, $instance, &$form, &$form_state) {
- $field_name = $field['field_name'];
- $entity = $form['#entity'];
-
- $element = array(
- '#type' => 'details',
- '#title' => t('Default value'),
- '#tree' => TRUE,
- '#description' => t('The default value for this field, used when creating new content.'),
- // Stick to an empty 'parents' on this form in order not to breaks widgets
- // that do not use field_widget_[field|instance]() and still access
- // $form_state['field'] directly.
- '#parents' => array(),
- );
-
- // Adjust the instance definition used for the form element. We want a
- // non-required input and no description.
- $instance['required'] = FALSE;
- $instance['description'] = '';
-
- // Adjust the instance definition to use the default widget of this field type
- // instead of the hidden widget.
- if ($instance['widget']['type'] == 'field_hidden') {
- $field_type = field_info_field_types($field['type']);
- $default_widget = field_info_widget_types($field_type['default_widget']);
-
- $instance['widget'] = array(
- 'type' => $default_widget['id'],
- 'settings' => $default_widget['settings'],
- 'weight' => 0,
- );
- }
-
- // Insert the widget. Since we do not use the "official" instance definition,
- // the whole flow cannot use field_invoke_method().
- $items = array();
- if (!empty($instance['default_value'])) {
- $items = (array) $instance['default_value'];
- }
- $element += $instance->getWidget()->form($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state);
-
- return $element;
-}
-
-/**
- * Form validation handler for field_ui_field_edit_form().
- *
- * @see field_ui_field_edit_form_submit().
- */
-function field_ui_field_edit_form_validate($form, &$form_state) {
- // Take the incoming values as the $instance definition, so that the 'default
- // value' gets validated using the instance settings being submitted.
- $instance = $form['#instance'];
- $field_name = $instance['field_name'];
- $entity = $form['#entity'];
-
- if (isset($form['instance']['default_value_widget'])) {
- $element = $form['instance']['default_value_widget'];
-
- // Extract the 'default value'.
- $items = array();
- $instance->getWidget()->extractFormValues($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state);
-
- // Grab the field definition from $form_state.
- $field_state = field_form_get_state($element['#parents'], $field_name, LANGUAGE_NOT_SPECIFIED, $form_state);
- $field = $field_state['field'];
-
- // Validate the value.
- $errors = array();
- $function = $field['module'] . '_field_validate';
- if (function_exists($function)) {
- $function(NULL, $field, $instance, LANGUAGE_NOT_SPECIFIED, $items, $errors);
- }
-
- // Report errors.
- if (isset($errors[$field_name][LANGUAGE_NOT_SPECIFIED])) {
- // Store reported errors in $form_state.
- $field_state['errors'] = $errors[$field_name][LANGUAGE_NOT_SPECIFIED];
- field_form_set_state($element['#parents'], $field_name, LANGUAGE_NOT_SPECIFIED, $form_state, $field_state);
-
- // Assign reported errors to the correct form element.
- $instance->getWidget()->flagErrors($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state);
- }
- }
-}
-
-/**
- * Form submission handler for field_ui_field_edit_form().
- *
- * @see field_ui_field_edit_form_validate().
- */
-function field_ui_field_edit_form_submit($form, &$form_state) {
- $instance = $form['#instance'];
- $field = $form['#field'];
- $entity = $form['#entity'];
-
- // Handle the default value.
- if (isset($form['instance']['default_value_widget'])) {
- $element = $form['instance']['default_value_widget'];
-
- // Extract field values.
- $items = array();
- $instance->getWidget()->extractFormValues($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state);
-
- $instance['default_value'] = $items ? $items : NULL;
- }
-
- // Merge incoming values into the instance.
- foreach ($form_state['values']['instance'] as $key => $value) {
- $instance[$key] = $value;
- }
- field_update_instance($instance);
-
- drupal_set_message(t('Saved %label configuration.', array('%label' => $instance['label'])));
-
- if ($instance['required'] && empty($instance['default_value']) && empty($instance['default_value_function']) && $instance['widget']['type'] == 'field_hidden') {
- drupal_set_message(t('Field %label is required and uses the "hidden" widget. You might want to configure a default value.', array('%label' => $instance['label'])), 'warning');
- }
-
- $form_state['redirect'] = field_ui_next_destination($instance['entity_type'], $instance['bundle']);
-}
-
-/**
* Extracts next redirect path from an array of multiple destinations.
*
* @see field_ui_next_destination()
diff --git a/core/modules/field_ui/field_ui.module b/core/modules/field_ui/field_ui.module
index a0f29e3..9071e54 100644
--- a/core/modules/field_ui/field_ui.module
+++ b/core/modules/field_ui/field_ui.module
@@ -65,128 +65,73 @@ function field_ui_menu() {
// Create tabs for all possible bundles.
foreach (entity_get_info() as $entity_type => $entity_info) {
- if ($entity_info['fieldable']) {
- foreach (entity_get_bundles($entity_type) as $bundle_name => $bundle_info) {
- if (isset($bundle_info['admin'])) {
- // Extract path information from the bundle.
- $path = $bundle_info['admin']['path'];
- // Different bundles can appear on the same path (e.g. %node_type and
- // %comment_node_type). To allow field_ui_instance_load() to extract
- // the actual bundle object from the translated menu router path
- // arguments, we need to identify the argument position of the bundle
- // name string ('bundle argument') and pass that position to the menu
- // loader. The position needs to be casted into a string; otherwise it
- // would be replaced with the bundle name string.
- if (isset($bundle_info['admin']['bundle argument'])) {
- $bundle_arg = $bundle_info['admin']['bundle argument'];
- $bundle_pos = (string) $bundle_arg;
- }
- else {
- $bundle_arg = $bundle_name;
- $bundle_pos = '0';
- }
- // This is the position of the %field_ui_instance placeholder in the
- // items below.
- $field_position = count(explode('/', $path)) + 1;
+ if ($entity_info['fieldable'] && isset($entity_info['entity_menu_base_path'])) {
+ // Extract path information from the entity type.
+ $path = $entity_info['entity_menu_base_path'];
+ $default_path = preg_replace('/{' . DRUPAL_PHP_FUNCTION_PATTERN . '}/', '%', $path);
+ // This is the position of the %field_ui_instance placeholder in the
+ // items below.
+ $field_position = count(explode('/', $path)) + 1;
- // User access check to be done against the permission to edit
- // fields or the display per entity type.
- $access_fields = array(
- 'access callback' => 'user_access',
- 'access arguments' => array('administer ' . $entity_type . ' fields'),
- );
- $access_display = array(
- 'access callback' => 'user_access',
- 'access arguments' => array('administer ' . $entity_type . ' display'),
- );
+ $items["$path/fields"] = array(
+ 'title' => 'Manage fields',
+ 'type' => MENU_LOCAL_TASK,
+ 'route_name' => "field_ui.overview.$entity_type",
+ 'weight' => 1,
+ );
+ $items["$path/fields/%"] = array(
+ 'title callback' => 'field_ui_instance_title',
+ 'title arguments' => array($field_position),
+ 'route_name' => "field_ui.edit.$entity_type",
+ );
+ $items["$default_path/fields/%/edit"] = array(
+ 'title' => 'Edit',
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ );
+ $items["$path/fields/%/field-settings"] = array(
+ 'title' => 'Field settings',
+ 'type' => MENU_LOCAL_TASK,
+ 'route_name' => "field_ui.settings.$entity_type",
+ );
+ $items["$path/fields/%/widget-type"] = array(
+ 'title' => 'Widget type',
+ 'type' => MENU_LOCAL_TASK,
+ 'route_name' => "field_ui.widget_type.$entity_type",
+ );
+ $items["$path/fields/%/delete"] = array(
+ 'title' => 'Delete',
+ 'type' => MENU_VISIBLE_IN_BREADCRUMB,
+ 'route_name' => "field_ui.delete.$entity_type",
+ 'weight' => 10,
+ );
- $items["$path/fields"] = array(
- 'title' => 'Manage fields',
- 'page callback' => 'field_ui_field_overview',
- 'page arguments' => array($entity_type, $bundle_arg),
- 'type' => MENU_LOCAL_TASK,
- 'weight' => 1,
- 'file' => 'field_ui.admin.inc',
- ) + $access_fields;
- $items["$path/fields/%field_ui_instance"] = array(
- 'load arguments' => array($entity_type, $bundle_arg, $bundle_pos, '%map'),
- 'title callback' => 'field_ui_instance_title',
- 'title arguments' => array($field_position),
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('field_ui_field_edit_form', $field_position),
- 'file' => 'field_ui.admin.inc',
- ) + $access_fields;
- $items["$path/fields/%field_ui_instance/edit"] = array(
- 'load arguments' => array($entity_type, $bundle_arg, $bundle_pos, '%map'),
- 'title' => 'Edit',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('field_ui_field_edit_form', $field_position),
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- 'file' => 'field_ui.admin.inc',
- ) + $access_fields;
- $items["$path/fields/%field_ui_instance/field-settings"] = array(
- 'load arguments' => array($entity_type, $bundle_arg, $bundle_pos, '%map'),
- 'title' => 'Field settings',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('field_ui_field_settings_form', $field_position),
- 'type' => MENU_LOCAL_TASK,
- 'file' => 'field_ui.admin.inc',
- ) + $access_fields;
- $items["$path/fields/%field_ui_instance/widget-type"] = array(
- 'load arguments' => array($entity_type, $bundle_arg, $bundle_pos, '%map'),
- 'title' => 'Widget type',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('field_ui_widget_type_form', $field_position),
- 'type' => MENU_LOCAL_TASK,
- 'file' => 'field_ui.admin.inc',
- ) + $access_fields;
- $items["$path/fields/%field_ui_instance/delete"] = array(
- 'load arguments' => array($entity_type, $bundle_arg, $bundle_pos, '%map'),
- 'title' => 'Delete',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('field_ui_field_delete_form', $field_position),
- 'type' => MENU_VISIBLE_IN_BREADCRUMB,
- 'weight' => 10,
- 'file' => 'field_ui.admin.inc',
- ) + $access_fields;
+ // 'Manage display' tab.
+ $items["$path/display"] = array(
+ 'title' => 'Manage display',
+ 'type' => MENU_LOCAL_TASK,
+ 'route_name' => "field_ui.display_overview.$entity_type",
+ 'weight' => 2,
+ );
- // 'Manage display' tab.
- $items["$path/display"] = array(
- 'title' => 'Manage display',
- 'page callback' => 'field_ui_display_overview',
- 'page arguments' => array($entity_type, $bundle_arg, 'default'),
- 'type' => MENU_LOCAL_TASK,
- 'weight' => 2,
- 'file' => 'field_ui.admin.inc',
- ) + $access_display;
-
- // View modes secondary tabs.
- // The same base $path for the menu item (with a placeholder) can be
- // used for all bundles of a given entity type; but depending on
- // administrator settings, each bundle has a different set of view
- // modes available for customisation. So we define menu items for all
- // view modes, and use an access callback to determine which ones are
- // actually visible for a given bundle.
- $weight = 0;
- $view_modes = array('default' => array('label' => t('Default'))) + entity_get_view_modes($entity_type);
- foreach ($view_modes as $view_mode => $view_mode_info) {
- $items["$path/display/$view_mode"] = array(
- 'title' => $view_mode_info['label'],
- 'page callback' => 'field_ui_display_overview',
- 'page arguments' => array($entity_type, $bundle_arg, $view_mode),
- // The access callback needs to check both the current 'custom
- // display' setting for the view mode, and the overall access
- // rules for the bundle admin pages.
- 'access callback' => '_field_ui_view_mode_menu_access',
- 'access arguments' => array($entity_type, $bundle_arg, $view_mode, $access_display['access arguments'][0]),
- 'type' => ($view_mode == 'default' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK),
- 'file' => 'field_ui.admin.inc',
- );
- if ($view_mode != 'default') {
- $items["$path/display/$view_mode"]['weight'] = $weight++;
- }
- }
- }
+ // View modes secondary tabs.
+ // The same base $path for the menu item (with a placeholder) can be
+ // used for all bundles of a given entity type; but depending on
+ // administrator settings, each bundle has a different set of view
+ // modes available for customisation. So we define menu items for all
+ // view modes, and use an access callback to determine which ones are
+ // actually visible for a given bundle.
+ $items["$default_path/display/default"] = array(
+ 'title' => t('Default'),
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ );
+ $weight = 0;
+ foreach (entity_get_view_modes($entity_type) as $view_mode => $view_mode_info) {
+ $items["$path/display/$view_mode"] = array(
+ 'title' => $view_mode_info['label'],
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => $weight++,
+ 'route_name' => "field_ui.display_overview.$entity_type.$view_mode",
+ );
}
}
}
@@ -267,25 +212,8 @@ function field_ui_instance_load($field_name, $entity_type, $bundle_name, $bundle
* @see field_ui_menu()
*/
function field_ui_instance_title($instance) {
- return $instance['label'];
-}
-
-/**
- * Access callback: Checks access for the 'view mode display settings' pages.
- *
- * @see field_ui_menu()
- */
-function _field_ui_view_mode_menu_access($entity_type, $bundle, $view_mode, $permission) {
- // First, determine visibility according to the 'use custom display'
- // setting for the view mode.
- $bundle = field_extract_bundle($entity_type, $bundle);
- $view_mode_settings = field_view_mode_settings($entity_type, $bundle);
- $visibility = ($view_mode == 'default') || !empty($view_mode_settings[$view_mode]['custom_settings']);
-
- // Then, determine access according to the $permission parameter.
- if ($visibility) {
- return user_access($permission);
- }
+ $entity = entity_load('field_instance', $instance);
+ return $entity->label();
}
/**
diff --git a/core/modules/field_ui/field_ui.services.yml b/core/modules/field_ui/field_ui.services.yml
new file mode 100644
index 0000000..cfc1214
--- /dev/null
+++ b/core/modules/field_ui/field_ui.services.yml
@@ -0,0 +1,10 @@
+services:
+ field_ui.subscriber:
+ class: Drupal\field_ui\Routing\RouteSubscriber
+ arguments: ['@plugin.manager.entity']
+ tags:
+ - { name: event_subscriber }
+ access_check.field_ui.view_mode:
+ class: Drupal\field_ui\Access\ViewModeAccessCheck
+ tags:
+ - { name: access_check }
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Access/ViewModeAccessCheck.php b/core/modules/field_ui/lib/Drupal/field_ui/Access/ViewModeAccessCheck.php
new file mode 100644
index 0000000..640ae84
--- /dev/null
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Access/ViewModeAccessCheck.php
@@ -0,0 +1,43 @@
+getRequirements());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function access(Route $route, Request $request) {
+ if ($entity_type = $request->attributes->get('entity_type')) {
+ $bundle = $request->attributes->get('bundle');
+ $view_mode = $request->attributes->get('view_mode');
+
+ $view_mode_settings = field_view_mode_settings($entity_type, $bundle);
+ $visibility = ($view_mode == 'default') || !empty($view_mode_settings[$view_mode]['custom_settings']);
+ if ($visibility) {
+ $permission = $route->getRequirement('_field_ui_view_mode_access');
+ return user_access($permission);
+ }
+ }
+ }
+
+}
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
index 7ee40f4..836cc88 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
@@ -41,7 +41,10 @@ public function getFormID() {
/**
* Implements \Drupal\Core\Form\FormInterface::buildForm().
*/
- public function buildForm(array $form, array &$form_state) {
+ public function buildForm(array $form, array &$form_state, $entity_type = NULL, $bundle = NULL, $view_mode = NULL) {
+ parent::buildForm($form, $form_state, $entity_type, $bundle);
+
+ $this->view_mode = (isset($view_mode) ? $view_mode : 'default');
// Gather type information.
$instances = field_info_instances($this->entity_type, $this->bundle);
$field_types = field_info_field_types();
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 c17bfb2..5347b20 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php
@@ -15,16 +15,6 @@
class FieldOverview extends OverviewBase {
/**
- * Overrides Drupal\field_ui\OverviewBase::__construct().
- */
- public function __construct($entity_type, $bundle, $view_mode = NULL) {
- $this->entity_type = $entity_type;
- $this->bundle = $bundle;
- $this->view_mode = 'form';
- $this->adminPath = field_ui_bundle_admin_path($this->entity_type, $this->bundle);
- }
-
- /**
* Implements Drupal\field_ui\OverviewBase::getRegions().
*/
public function getRegions() {
@@ -52,7 +42,10 @@ public function getFormID() {
/**
* Implements \Drupal\Core\Form\FormInterface::buildForm().
*/
- public function buildForm(array $form, array &$form_state) {
+ public function buildForm(array $form, array &$form_state, $entity_type = NULL, $bundle = NULL) {
+ parent::buildForm($form, $form_state, $entity_type, $bundle);
+
+ $this->view_mode = 'form';
// When displaying the form, make sure the list of fields is up-to-date.
if (empty($form_state['post'])) {
field_info_cache_clear();
@@ -94,7 +87,7 @@ public function buildForm(array $form, array &$form_state) {
// Fields.
foreach ($instances as $name => $instance) {
$field = field_info_field($instance['field_name']);
- $admin_field_path = $this->adminPath . '/fields/' . $instance['field_name'];
+ $admin_field_path = $this->adminPath . '/fields/' . $instance->id();
$table[$name] = array(
'#attributes' => array('class' => array('draggable', 'tabledrag-leaf')),
'#row_type' => 'field',
@@ -571,7 +564,7 @@ public function submitForm(array &$form, array &$form_state) {
// Create the field and instance.
try {
field_create_field($field);
- field_create_instance($instance);
+ $new_instance = field_create_instance($instance);
// Make sure the field is displayed in the 'default' view mode (using
// default formatter and settings). It stays hidden for other view
@@ -582,8 +575,8 @@ public function submitForm(array &$form, array &$form_state) {
// Always show the field settings step, as the cardinality needs to be
// configured for new fields.
- $destinations[] = $this->adminPath. '/fields/' . $field['field_name'] . '/field-settings';
- $destinations[] = $this->adminPath . '/fields/' . $field['field_name'];
+ $destinations[] = $this->adminPath. '/fields/' . $new_instance->id() . '/field-settings';
+ $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'];
@@ -613,7 +606,7 @@ public function submitForm(array &$form, array &$form_state) {
);
try {
- field_create_instance($instance);
+ $new_instance = field_create_instance($instance);
// Make sure the field is displayed in the 'default' view mode (using
// default formatter and settings). It stays hidden for other view
@@ -622,7 +615,7 @@ public function submitForm(array &$form, array &$form_state) {
->setComponent($field['field_name'])
->save();
- $destinations[] = $this->adminPath . '/fields/' . $instance['field_name'];
+ $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'];
}
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldDeleteForm.php b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldDeleteForm.php
new file mode 100644
index 0000000..5b6fa23
--- /dev/null
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldDeleteForm.php
@@ -0,0 +1,92 @@
+ $this->instance->label()));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getConfirmText() {
+ return t('Delete');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getCancelPath() {
+ return field_ui_bundle_admin_path($this->instance->entity_type, $this->instance->bundle) . '/fields';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildForm(array $form, array &$form_state, FieldInstance $field_instance = NULL) {
+ $this->instance = $form_state['instance'] = $field_instance;
+
+ return parent::buildForm($form, $form_state);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, array &$form_state) {
+ form_load_include($form_state, 'inc', 'field_ui', 'field_ui.admin');
+
+ $field = field_info_field($this->instance->field_name);
+ $bundles = entity_get_bundles();
+ $bundle_label = $bundles[$this->instance->entity_type][$this->instance->bundle]['label'];
+
+ if ($field && !$field['locked']) {
+ field_delete_instance($this->instance);
+ drupal_set_message(t('The field %field has been deleted from the %type content type.', array('%field' => $this->instance->label(), '%type' => $bundle_label)));
+ }
+ else {
+ drupal_set_message(t('There was a problem removing the %field from the %type content type.', array('%field' => $this->instance->label(), '%type' => $bundle_label)), 'error');
+ }
+
+ $admin_path = field_ui_bundle_admin_path($this->instance->entity_type, $this->instance->bundle);
+ $form_state['redirect'] = field_ui_get_destinations(array($admin_path . '/fields'));
+
+ // Fields are purged on cron. However field module prevents disabling modules
+ // when field types they provided are used in a field until it is fully
+ // purged. In the case that a field has minimal or no content, a single call
+ // to field_purge_batch() will remove it from the system. Call this with a
+ // low batch limit to avoid administrators having to wait for cron runs when
+ // removing instances that meet this criteria.
+ field_purge_batch(10);
+ }
+
+}
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
new file mode 100644
index 0000000..279100d
--- /dev/null
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php
@@ -0,0 +1,280 @@
+instance = $form_state['instance'] = $field_instance;
+
+ $bundle = $this->instance['bundle'];
+ $entity_type = $this->instance['entity_type'];
+ $field = field_info_field($this->instance['field_name']);
+ $bundles = entity_get_bundles();
+
+ drupal_set_title(t('%instance settings for %bundle', array(
+ '%instance' => $this->instance->label(),
+ '%bundle' => $bundles[$entity_type][$bundle]['label'],
+ )), PASS_THROUGH);
+
+ $form['#field'] = $field;
+ // Create an arbitrary entity object (used by the 'default value' widget).
+ $ids = (object) array('entity_type' => $this->instance['entity_type'], 'bundle' => $this->instance['bundle'], 'entity_id' => NULL);
+ $form['#entity'] = _field_create_entity_from_ids($ids);
+ $form['#entity']->field_ui_default_value = TRUE;
+
+ if (!empty($field['locked'])) {
+ $form['locked'] = array(
+ '#markup' => t('The field %field is locked and cannot be edited.', array('%field' => $this->instance->label())),
+ );
+ return $form;
+ }
+
+ $widget_type = field_info_widget_types($this->instance['widget']['type']);
+
+ // Create a form structure for the instance values.
+ $form['instance'] = array(
+ '#tree' => TRUE,
+ );
+
+ // Build the non-configurable instance values.
+ $form['instance']['field_name'] = array(
+ '#type' => 'value',
+ '#value' => $this->instance['field_name'],
+ );
+ $form['instance']['entity_type'] = array(
+ '#type' => 'value',
+ '#value' => $entity_type,
+ );
+ $form['instance']['bundle'] = array(
+ '#type' => 'value',
+ '#value' => $bundle,
+ );
+ $form['instance']['widget']['weight'] = array(
+ '#type' => 'value',
+ '#value' => !empty($this->instance['widget']['weight']) ? $this->instance['widget']['weight'] : 0,
+ );
+
+ // Build the configurable instance values.
+ $form['instance']['label'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Label'),
+ '#default_value' => $this->instance->label() ?: $field['field_name'],
+ '#required' => TRUE,
+ '#weight' => -20,
+ );
+
+ $form['instance']['description'] = array(
+ '#type' => 'textarea',
+ '#title' => t('Help text'),
+ '#default_value' => !empty($this->instance['description']) ? $this->instance['description'] : '',
+ '#rows' => 5,
+ '#description' => t('Instructions to present to the user below this field on the editing form.
Allowed HTML tags: @tags', array('@tags' => _field_filter_xss_display_allowed_tags())) . '
' . t('This field supports tokens.'),
+ '#weight' => -10,
+ );
+
+ $form['instance']['required'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Required field'),
+ '#default_value' => !empty($this->instance['required']),
+ '#weight' => -5,
+ );
+
+ // Build the widget component of the instance.
+ $form['instance']['widget']['type'] = array(
+ '#type' => 'value',
+ '#value' => $this->instance['widget']['type'],
+ );
+
+ // Add additional field instance settings from the field module.
+ $additions = module_invoke($field['module'], 'field_instance_settings_form', $field, $this->instance, $form_state);
+ if (is_array($additions)) {
+ $form['instance']['settings'] = $additions;
+ $form['instance']['settings']['#weight'] = 10;
+ }
+
+ // Add widget settings for the widget type.
+ $additions = $this->instance->getWidget()->settingsForm($form, $form_state);
+ $form['instance']['widget']['settings'] = $additions ?: array('#type' => 'value', '#value' => array());
+ $form['instance']['widget']['#weight'] = 20;
+
+ // Add handling for default value if not provided by any other module.
+ if (field_behaviors_widget('default_value', $this->instance) == FIELD_BEHAVIOR_DEFAULT && empty($this->instance['default_value_function'])) {
+ $form['instance']['default_value_widget'] = $this->getDefaultValueWidget($field, $form, $form_state);
+ }
+
+ $form['actions'] = array('#type' => 'actions');
+ $form['actions']['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Save settings')
+ );
+ $form['actions']['delete'] = array(
+ '#type' => 'submit',
+ '#value' => t('Delete field'),
+ '#submit' => array(array($this, 'delete')),
+ );
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateForm(array &$form, array &$form_state) {
+ // Take the incoming values as the $this->instance definition, so that the 'default
+ // value' gets validated using the instance settings being submitted.
+ $this->instance = $this->instance;
+ $field_name = $this->instance['field_name'];
+ $entity = $form['#entity'];
+
+ if (isset($form['instance']['default_value_widget'])) {
+ $element = $form['instance']['default_value_widget'];
+
+ // Extract the 'default value'.
+ $items = array();
+ $this->instance->getWidget()->extractFormValues($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state);
+
+ // Grab the field definition from $form_state.
+ $field_state = field_form_get_state($element['#parents'], $field_name, LANGUAGE_NOT_SPECIFIED, $form_state);
+ $field = $field_state['field'];
+
+ // Validate the value.
+ $errors = array();
+ $function = $field['module'] . '_field_validate';
+ if (function_exists($function)) {
+ $function(NULL, $field, $this->instance, LANGUAGE_NOT_SPECIFIED, $items, $errors);
+ }
+
+ // Report errors.
+ if (isset($errors[$field_name][LANGUAGE_NOT_SPECIFIED])) {
+ // Store reported errors in $form_state.
+ $field_state['errors'] = $errors[$field_name][LANGUAGE_NOT_SPECIFIED];
+ field_form_set_state($element['#parents'], $field_name, LANGUAGE_NOT_SPECIFIED, $form_state, $field_state);
+
+ // Assign reported errors to the correct form element.
+ $this->instance->getWidget()->flagErrors($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state);
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, array &$form_state) {
+ form_load_include($form_state, 'inc', 'field_ui', 'field_ui.admin');
+ $field = $form['#field'];
+ $entity = $form['#entity'];
+
+ // Handle the default value.
+ if (isset($form['instance']['default_value_widget'])) {
+ $element = $form['instance']['default_value_widget'];
+
+ // Extract field values.
+ $items = array();
+ $this->instance->getWidget()->extractFormValues($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state);
+
+ $this->instance['default_value'] = $items ? $items : NULL;
+ }
+
+ // Merge incoming values into the instance.
+ foreach ($form_state['values']['instance'] as $key => $value) {
+ $this->instance[$key] = $value;
+ }
+ field_update_instance($this->instance);
+
+ drupal_set_message(t('Saved %label configuration.', array('%label' => $this->instance->label())));
+
+ if ($this->instance['required'] && empty($this->instance['default_value']) && empty($this->instance['default_value_function']) && $this->instance['widget']['type'] == 'field_hidden') {
+ drupal_set_message(t('Field %label is required and uses the "hidden" widget. You might want to configure a default value.', array('%label' => $this->instance['label'])), 'warning');
+ }
+
+ $form_state['redirect'] = field_ui_next_destination($this->instance['entity_type'], $this->instance['bundle']);
+ }
+
+ /**
+ * Redirects to the field instance deletion form.
+ */
+ public function delete(array &$form, array &$form_state) {
+ $destination = array();
+ if (isset($_GET['destination'])) {
+ $destination = drupal_get_destination();
+ unset($_GET['destination']);
+ }
+ $form_state['redirect'] = array('admin/structure/types/manage/' . $this->instance['bundle'] . '/fields/' . $this->instance->id() . '/delete', array('query' => $destination));
+ }
+
+ /**
+ * Builds the default value widget for a given field instance.
+ */
+ protected function getDefaultValueWidget($field, array &$form, &$form_state) {
+ $field_name = $field['field_name'];
+ $entity = $form['#entity'];
+
+ $element = array(
+ '#type' => 'details',
+ '#title' => t('Default value'),
+ '#tree' => TRUE,
+ '#description' => t('The default value for this field, used when creating new content.'),
+ // Stick to an empty 'parents' on this form in order not to breaks widgets
+ // that do not use field_widget_[field|instance]() and still access
+ // $form_state['field'] directly.
+ '#parents' => array(),
+ );
+
+ // Adjust the instance definition used for the form element. We want a
+ // non-required input and no description.
+ $this->instance['required'] = FALSE;
+ $this->instance['description'] = '';
+
+ // Adjust the instance definition to use the default widget of this field type
+ // instead of the hidden widget.
+ if ($this->instance['widget']['type'] == 'field_hidden') {
+ $field_type = field_info_field_types($field['type']);
+ $default_widget = field_info_widget_types($field_type['default_widget']);
+
+ $this->instance['widget'] = array(
+ 'type' => $default_widget['id'],
+ 'settings' => $default_widget['settings'],
+ 'weight' => 0,
+ );
+ }
+
+ // Insert the widget. Since we do not use the "official" instance definition,
+ // the whole flow cannot use field_invoke_method().
+ $items = array();
+ if (!empty($this->instance['default_value'])) {
+ $items = (array) $this->instance['default_value'];
+ }
+ $element += $this->instance->getWidget()->form($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state);
+
+ return $element;
+ }
+
+}
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldSettingsForm.php b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldSettingsForm.php
new file mode 100644
index 0000000..6380f39
--- /dev/null
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldSettingsForm.php
@@ -0,0 +1,161 @@
+instance = $form_state['instance'] = $field_instance;
+ $field = field_info_field($this->instance->field_name);
+ $form['#field'] = $field;
+
+ drupal_set_title($this->instance->label());
+
+ $description = '' . t('These settings apply to the %field field everywhere it is used. These settings impact the way that data is stored in the database and cannot be changed once data has been created.', array('%field' => $this->instance->label())) . '
';
+
+ // Create a form structure for the field values.
+ $form['field'] = array(
+ '#prefix' => $description,
+ '#tree' => TRUE,
+ );
+
+ // See if data already exists for this field.
+ // If so, prevent changes to the field settings.
+ $has_data = field_has_data($field);
+ if ($has_data) {
+ $form['field']['#prefix'] = '' . t('There is data for this field in the database. The field settings can no longer be changed.') . '
' . $form['field']['#prefix'];
+ }
+
+ // Build the configurable field values.
+ $cardinality = $field['cardinality'];
+ $form['field']['container'] = array(
+ // We can't use the container element because it doesn't support the title
+ // or description properties.
+ '#type' => 'item',
+ '#field_prefix' => '',
+ '#field_suffix' => '
',
+ '#title' => t('Maximum number of values users can enter'),
+ );
+ $form['field']['container']['cardinality'] = array(
+ '#type' => 'select',
+ '#options' => drupal_map_assoc(range(1, 5)) + array(FIELD_CARDINALITY_UNLIMITED => t('Unlimited')) + array('other' => t('More')),
+ '#default_value' => ($cardinality < 6) ? $cardinality : 'other',
+ );
+ // @todo Convert when http://drupal.org/node/1207060 gets in.
+ $form['field']['container']['cardinality_other'] = array(
+ '#type' => 'number',
+ '#default_value' => $cardinality > 5 ? $cardinality : 6,
+ '#min' => 1,
+ '#title' => t('Custom value'),
+ '#title_display' => 'invisible',
+ '#states' => array(
+ 'visible' => array(
+ ':input[name="field[container][cardinality]"]' => array('value' => 'other'),
+ ),
+ ),
+ );
+ if (field_behaviors_widget('multiple values', $this->instance) == FIELD_BEHAVIOR_DEFAULT) {
+ $form['field']['container']['#description'] = t('%unlimited will provide an %add-more button so users can add as many values as they like.', array(
+ '%unlimited' => t('Unlimited'),
+ '%add-more' => t('Add another item'),
+ ));
+ }
+
+ // Build the non-configurable field values.
+ $form['field']['field_name'] = array('#type' => 'value', '#value' => $field['field_name']);
+ $form['field']['type'] = array('#type' => 'value', '#value' => $field['type']);
+ $form['field']['module'] = array('#type' => 'value', '#value' => $field['module']);
+ $form['field']['active'] = array('#type' => 'value', '#value' => $field['active']);
+
+ // Add settings provided by the field module. The field module is
+ // responsible for not returning settings that cannot be changed if
+ // the field already has data.
+ $form['field']['settings'] = array(
+ '#weight' => 10,
+ );
+ $additions = module_invoke($field['module'], 'field_settings_form', $field, $this->instance, $has_data);
+ if (is_array($additions)) {
+ $form['field']['settings'] += $additions;
+ }
+
+ $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) {
+ // Validate field cardinality.
+ $cardinality = $form_state['values']['field']['container']['cardinality'];
+ $cardinality_other = $form_state['values']['field']['container']['cardinality_other'];
+ if ($cardinality == 'other' && empty($cardinality_other)) {
+ form_error($form['field']['container']['cardinality_other'], t('Number of values is required.'));
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, array &$form_state) {
+ form_load_include($form_state, 'inc', 'field_ui', 'field_ui.admin');
+ $form_values = $form_state['values'];
+ $field_values = $form_values['field'];
+
+ // Save field cardinality.
+ $cardinality = $field_values['container']['cardinality'];
+ $cardinality_other = $field_values['container']['cardinality_other'];
+ $cardinality_other = $form_state['values']['field']['container']['cardinality_other'];
+ if ($cardinality == 'other') {
+ $cardinality = $cardinality_other;
+ }
+ $field_values['cardinality'] = $cardinality;
+ unset($field_values['container']);
+
+ // Merge incoming form values into the existing field.
+ $field = field_info_field($field_values['field_name']);
+ foreach ($field_values as $key => $value) {
+ $field[$key] = $value;
+ }
+
+ // Update the field.
+ try {
+ field_update_field($field);
+ drupal_set_message(t('Updated field %label field settings.', array('%label' => $this->instance->label())));
+ $form_state['redirect'] = field_ui_next_destination($this->instance->entity_type, $this->instance->bundle);
+ }
+ catch (Exception $e) {
+ drupal_set_message(t('Attempt to update field %label failed: %message.', array('%label' => $this->instance->label(), '%message' => $e->getMessage())), 'error');
+ }
+ }
+
+}
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldWidgetTypeForm.php b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldWidgetTypeForm.php
new file mode 100644
index 0000000..c461543
--- /dev/null
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldWidgetTypeForm.php
@@ -0,0 +1,109 @@
+instance = $form_state['instance'] = $field_instance;
+ form_load_include($form_state, 'inc', 'field_ui', 'field_ui.admin');
+ drupal_set_title($this->instance['label']);
+
+ $bundle = $this->instance['bundle'];
+ $entity_type = $this->instance['entity_type'];
+ $field_name = $this->instance['field_name'];
+
+ $field = field_info_field($field_name);
+ $bundles = entity_get_bundles();
+ $bundle_label = $bundles[$entity_type][$bundle]['label'];
+
+ $form = array(
+ '#bundle' => $bundle,
+ '#entity_type' => $entity_type,
+ '#field_name' => $field_name,
+ );
+
+ $form['widget_type'] = array(
+ '#type' => 'select',
+ '#title' => t('Widget type'),
+ '#required' => TRUE,
+ '#options' => field_ui_widget_type_options($field['type']),
+ '#default_value' => $this->instance->getWidget()->getPluginId(),
+ '#description' => t('The type of form element you would like to present to the user when creating this field in the %type type.', array('%type' => $bundle_label)),
+ );
+
+ $form['actions'] = array('#type' => 'actions');
+ $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Continue'));
+
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateForm(array &$form, array &$form_state) {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, array &$form_state) {
+ $form_values = $form_state['values'];
+ $bundle = $form['#bundle'];
+ $entity_type = $form['#entity_type'];
+ $field_name = $form['#field_name'];
+
+ // Retrieve the stored instance settings to merge with the incoming values.
+ $instance = field_read_instance($entity_type, $field_name, $bundle);
+
+ // Set the right module information.
+ $widget_type = field_info_widget_types($form_values['widget_type']);
+ $widget_module = $widget_type['module'];
+
+ $instance['widget']['type'] = $form_values['widget_type'];
+ $instance['widget']['module'] = $widget_module;
+
+ try {
+ field_update_instance($instance);
+ drupal_set_message(t('Changed the widget for field %label.', array('%label' => $instance['label'])));
+
+ if ($instance['required'] && empty($instance['default_value']) && empty($instance['default_value_function']) && $instance['widget']['type'] == 'field_hidden') {
+ drupal_set_message(t('Field %label is required and uses the "hidden" widget. You might want to configure a default value.', array('%label' => $instance['label'])), 'warning');
+ }
+ }
+ catch (Exception $e) {
+ drupal_set_message(t('There was a problem changing the widget for field %label.', array('%label' => $instance['label'])), 'error');
+ }
+
+ $form_state['redirect'] = field_ui_next_destination($entity_type, $bundle);
+ }
+
+}
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/OverviewBase.php b/core/modules/field_ui/lib/Drupal/field_ui/OverviewBase.php
index 5a76dc1..7ea8391 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/OverviewBase.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/OverviewBase.php
@@ -43,20 +43,17 @@
protected $adminPath = NULL;
/**
- * Constructs the overview object for a entity type, bundle and view mode.
- *
- * @param string $entity_type
- * The entity type.
- * @param string $bundle
- * The bundle for the entity of entity_type.
- * @param string $view_mode
- * (optional) The view mode for the entity which takes a string or
- * "default".
+ * {@inheritdoc}
*/
- public function __construct($entity_type, $bundle, $view_mode = NULL) {
+ public function buildForm(array $form, array &$form_state, $entity_type = NULL, $bundle = NULL) {
+ // @todo Comment has its own magical bundle naming.
+ if ($entity_type == 'comment' && module_exists('comment')) {
+ $bundle = comment_node_type_load($bundle);
+ }
+
+ form_load_include($form_state, 'inc', 'field_ui', 'field_ui.admin');
$this->entity_type = $entity_type;
$this->bundle = $bundle;
- $this->view_mode = (isset($view_mode) ? $view_mode : 'default');
$this->adminPath = field_ui_bundle_admin_path($this->entity_type, $this->bundle);
}
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
new file mode 100644
index 0000000..3884a3e
--- /dev/null
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Routing/RouteSubscriber.php
@@ -0,0 +1,116 @@
+manager = $manager;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getSubscribedEvents() {
+ $events[RoutingEvents::DYNAMIC] = 'routes';
+ return $events;
+ }
+
+ /**
+ * Adds routes for the Field UI.
+ */
+ public function routes(RouteBuildEvent $event) {
+ $collection = $event->getRouteCollection();
+ foreach ($this->manager->getDefinitions() as $entity_type => $entity_info) {
+ if ($entity_info['fieldable'] && isset($entity_info['entity_menu_base_path'])) {
+ $path = $entity_info['entity_menu_base_path'];
+
+ $route = new Route(
+ "$path/fields/{field_instance}",
+ array('_form' => '\Drupal\field_ui\Form\FieldEditForm'),
+ array('_permission' => 'administer ' . $entity_type . ' fields')
+ );
+ $collection->add("field_ui.edit.$entity_type", $route);
+
+ $route = new Route(
+ "$path/fields/{field_instance}/widget-type",
+ array('_form' => '\Drupal\field_ui\Form\FieldWidgetTypeForm'),
+ array('_permission' => 'administer ' . $entity_type . ' fields')
+ );
+ $collection->add("field_ui.widget_type.$entity_type", $route);
+
+ $route = new Route(
+ "$path/fields/{field_instance}/field-settings",
+ array('_form' => '\Drupal\field_ui\Form\FieldSettingsForm'),
+ array('_permission' => 'administer ' . $entity_type . ' fields')
+ );
+ $collection->add("field_ui.settings.$entity_type", $route);
+
+ $route = new Route(
+ "$path/fields/{field_instance}/delete",
+ array('_form' => '\Drupal\field_ui\Form\FieldDeleteForm'),
+ array('_permission' => 'administer ' . $entity_type . ' fields')
+ );
+ $collection->add("field_ui.delete.$entity_type", $route);
+
+ // If the entity type has no bundles, use the entity type.
+ $defaults['entity_type'] = $entity_type;
+ if (empty($entity_info['entity_keys']['bundle'])) {
+ $defaults['bundle'] = $entity_type;
+ }
+ $route = new Route(
+ "$path/fields",
+ array('_form' => '\Drupal\field_ui\FieldOverview') + $defaults,
+ array('_permission' => 'administer ' . $entity_type . ' fields')
+ );
+ $collection->add("field_ui.overview.$entity_type", $route);
+
+ $route = new Route(
+ "$path/display",
+ array('_form' => '\Drupal\field_ui\DisplayOverview') + $defaults,
+ array('_permission' => 'administer ' . $entity_type . ' display')
+ );
+ $collection->add("field_ui.display_overview.$entity_type", $route);
+
+ foreach (entity_get_view_modes($entity_type) as $view_mode => $view_mode_info) {
+ $route = new Route(
+ "$path/display/$view_mode",
+ array(
+ '_form' => '\Drupal\field_ui\DisplayOverview',
+ 'view_mode' => $view_mode,
+ ) + $defaults,
+ array('_field_ui_view_mode_access' => 'administer ' . $entity_type . ' display'));
+ $collection->add("field_ui.display_overview.$entity_type.$view_mode", $route);
+ }
+ }
+ }
+ }
+
+}
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/AlterTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/AlterTest.php
index 016b9d0..1c688fb 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/AlterTest.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/AlterTest.php
@@ -68,7 +68,7 @@ function testDefaultWidgetPropertiesAlter() {
// Test that field_test_field_widget_properties_alter() sets the size to
// 42 and that field_test_field_widget_form_alter() reports the correct
// size when the form is displayed.
- $this->drupalGet('admin/structure/types/manage/article/fields/alter_test_text');
+ $this->drupalGet('admin/structure/types/manage/article/fields/node.article.alter_test_text');
$this->assertText('Field size: 42', 'Altered field size is found in hook_field_widget_form_alter().');
// Test that hook_field_widget_form_alter() registers this is the default
// value form and sets a message.
@@ -102,11 +102,11 @@ function testDefaultWidgetPropertiesAlter() {
// Test that field_test_field_widget_properties_user_alter() replaces
// the widget and that field_test_field_widget_form_alter() reports the
// correct widget name when the form is displayed.
- $this->drupalGet('admin/config/people/accounts/fields/alter_test_options');
+ $this->drupalGet('admin/config/people/accounts/fields/user.user.alter_test_options');
$this->assertText('Widget type: options_buttons', 'Widget type is altered for users in hook_field_widget_form_alter().');
// Test that the widget is not altered on page nodes.
- $this->drupalGet('admin/structure/types/manage/page/fields/alter_test_options');
+ $this->drupalGet('admin/structure/types/manage/page/fields/node.page.alter_test_options');
$this->assertText('Widget type: options_select', 'Widget type is not altered for pages in hook_field_widget_form_alter().');
}
}
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 cbc132f..3fcabf2 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
@@ -123,8 +123,9 @@ function createField() {
* Tests editing an existing field.
*/
function updateField() {
+ $instance_id = 'node.' . $this->type . '.' . $this->field_name;
// Go to the field edit page.
- $this->drupalGet('admin/structure/types/manage/' . $this->type . '/fields/' . $this->field_name . '/field-settings');
+ $this->drupalGet('admin/structure/types/manage/' . $this->type . '/fields/' . $instance_id . '/field-settings');
// Populate the field settings with new settings.
$string = 'updated dummy test string';
@@ -134,7 +135,7 @@ function updateField() {
$this->drupalPost(NULL, $edit, t('Save field settings'));
// Go to the field instance edit page.
- $this->drupalGet('admin/structure/types/manage/' . $this->type . '/fields/' . $this->field_name);
+ $this->drupalGet('admin/structure/types/manage/' . $this->type . '/fields/' . $instance_id);
$edit = array(
'instance[settings][test_instance_setting]' => $string,
'instance[widget][settings][test_widget_setting]' => $string,
@@ -176,7 +177,7 @@ function addExistingField() {
* numeric value. That is tested already in FormTest::testNumber().
*/
function cardinalitySettings() {
- $field_edit_path = 'admin/structure/types/manage/article/fields/body/field-settings';
+ $field_edit_path = 'admin/structure/types/manage/article/fields/node.article.body/field-settings';
// Assert the cardinality other field cannot be empty when cardinality is
// set to other.
@@ -253,10 +254,10 @@ function testDefaultValue() {
'entity_type' => 'node',
'bundle' => $this->type,
);
- field_create_instance($instance);
+ $instance = field_create_instance($instance);
$langcode = LANGUAGE_NOT_SPECIFIED;
- $admin_path = 'admin/structure/types/manage/' . $this->type . '/fields/' . $field_name;
+ $admin_path = 'admin/structure/types/manage/' . $this->type . '/fields/' . $instance->id();
$element_id = "edit-$field_name-$langcode-0-value";
$element_name = "{$field_name}[$langcode][0][value]";
$this->drupalGet($admin_path);
@@ -320,7 +321,7 @@ function testDeleteField() {
$this->fieldUIAddExistingField($bundle_path2, $edit2);
// Delete the first instance.
- $this->fieldUIDeleteField($bundle_path1, $this->field_name, $this->field_label, $this->type);
+ $this->fieldUIDeleteField($bundle_path1, "node.$this->type.$this->field_name", $this->field_label, $this->type);
// Reset the fields info.
field_info_cache_clear();
@@ -330,7 +331,7 @@ function testDeleteField() {
$this->assertNotNull(field_info_field($this->field_name), 'Field was not deleted.');
// Delete the second instance.
- $this->fieldUIDeleteField($bundle_path2, $this->field_name, $this->field_label, $type_name2);
+ $this->fieldUIDeleteField($bundle_path2, "node.$type_name2.$this->field_name", $this->field_label, $type_name2);
// Reset the fields info.
field_info_cache_clear();
@@ -412,7 +413,7 @@ function testDuplicateFieldName() {
*/
function testWidgetChange() {
$url_fields = 'admin/structure/types/manage/article/fields';
- $url_tags_widget = $url_fields . '/field_tags/widget-type';
+ $url_tags_widget = $url_fields . '/node.article.field_tags/widget-type';
// Check that the field_tags field currently uses the 'options_select'
// widget.
@@ -463,7 +464,7 @@ function testDeleteTaxonomyField() {
$this->fieldUIAddNewField($bundle_path, $edit1);
// Delete the field.
- $this->fieldUIDeleteField($bundle_path, $this->field_name, $this->field_label, 'Tags');
+ $this->fieldUIDeleteField($bundle_path, "taxonomy_term.tags.$this->field_name", $this->field_label, 'Tags');
// Reset the fields info.
field_info_cache_clear();
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php
index 041e166..8268999 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php
@@ -205,12 +205,13 @@ function testPrivateFileSetting() {
$type_name = 'article';
$field_name = strtolower($this->randomName());
$this->createFileField($field_name, $type_name);
+ $instance = field_info_instance('node', $field_name, $type_name);
$test_file = $this->getTestFile('text');
// Change the field setting to make its files private, and upload a file.
$edit = array('field[settings][uri_scheme]' => 'private');
- $this->drupalPost("admin/structure/types/manage/$type_name/fields/$field_name/field-settings", $edit, t('Save field settings'));
+ $this->drupalPost("admin/structure/types/manage/$type_name/fields/$instance->id/field-settings", $edit, t('Save field settings'));
$nid = $this->uploadNodeFile($test_file, $field_name, $type_name);
$node = node_load($nid, TRUE);
$node_file = file_load($node->{$field_name}[LANGUAGE_NOT_SPECIFIED][0]['fid']);
@@ -222,12 +223,12 @@ function testPrivateFileSetting() {
// Ensure we can't change 'uri_scheme' field settings while there are some
// entities with uploaded files.
- $this->drupalGet("admin/structure/types/manage/$type_name/fields/$field_name/field-settings");
+ $this->drupalGet("admin/structure/types/manage/$type_name/fields/$instance->id/field-settings");
$this->assertFieldByXpath('//input[@id="edit-field-settings-uri-scheme-public" and @disabled="disabled"]', 'public', t('Upload destination setting disabled.'));
// Delete node and confirm that setting could be changed.
node_delete($nid);
- $this->drupalGet("admin/structure/types/manage/$type_name/fields/$field_name/field-settings");
+ $this->drupalGet("admin/structure/types/manage/$type_name/fields/$instance->id/field-settings");
$this->assertFieldByXpath('//input[@id="edit-field-settings-uri-scheme-public" and not(@disabled)]', 'public', t('Upload destination setting enabled.'));
}
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php
index a30b7ed..c8570c1 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php
@@ -74,7 +74,7 @@ function testDefaultImages() {
->save();
// Confirm the defaults are present on the article field settings form.
- $this->drupalGet("admin/structure/types/manage/article/fields/$field_name/field-settings");
+ $this->drupalGet("admin/structure/types/manage/article/fields/$instance->id/field-settings");
$this->assertFieldByXpath(
'//input[@name="field[settings][default_image][fids]"]',
$default_images['field']->fid,
@@ -84,7 +84,7 @@ function testDefaultImages() {
)
);
// Confirm the defaults are present on the article field edit form.
- $this->drupalGet("admin/structure/types/manage/article/fields/$field_name");
+ $this->drupalGet("admin/structure/types/manage/article/fields/$instance->id");
$this->assertFieldByXpath(
'//input[@name="instance[settings][default_image][fids]"]',
$default_images['instance']->fid,
@@ -95,7 +95,7 @@ function testDefaultImages() {
);
// Confirm the defaults are present on the page field settings form.
- $this->drupalGet("admin/structure/types/manage/page/fields/$field_name/field-settings");
+ $this->drupalGet("admin/structure/types/manage/page/fields/$instance->id/field-settings");
$this->assertFieldByXpath(
'//input[@name="field[settings][default_image][fids]"]',
$default_images['field']->fid,
@@ -105,7 +105,7 @@ function testDefaultImages() {
)
);
// Confirm the defaults are present on the page field edit form.
- $this->drupalGet("admin/structure/types/manage/page/fields/$field_name");
+ $this->drupalGet("admin/structure/types/manage/page/fields/$instance2->id");
$this->assertFieldByXpath(
'//input[@name="instance[settings][default_image][fids]"]',
$default_images['instance2']->fid,
@@ -144,7 +144,7 @@ function testDefaultImages() {
field_update_field($field);
// Confirm that the new default is used on the article field settings form.
- $this->drupalGet("admin/structure/types/manage/article/fields/$field_name/field-settings");
+ $this->drupalGet("admin/structure/types/manage/article/fields/$instance->id/field-settings");
$this->assertFieldByXpath(
'//input[@name="field[settings][default_image][fids]"]',
$default_images['field_new']->fid,
@@ -180,7 +180,7 @@ function testDefaultImages() {
// Confirm the new field instance default is used on the article field
// admin form.
- $this->drupalGet("admin/structure/types/manage/article/fields/$field_name");
+ $this->drupalGet("admin/structure/types/manage/article/fields/$instance->id");
$this->assertFieldByXpath(
'//input[@name="instance[settings][default_image][fids]"]',
$default_images['instance_new']->fid,
@@ -218,7 +218,7 @@ function testDefaultImages() {
field_update_instance($instance);
// Confirm the article field instance default has been removed.
- $this->drupalGet("admin/structure/types/manage/article/fields/$field_name");
+ $this->drupalGet("admin/structure/types/manage/article/fields/$instance->id");
$this->assertFieldByXpath(
'//input[@name="instance[settings][default_image][fids]"]',
'',
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
index b91d9af..cb2bad1 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
@@ -229,7 +229,7 @@ function testImageFieldDefaultImage() {
$edit = array(
'files[field_settings_default_image]' => drupal_realpath($images[0]->uri),
);
- $this->drupalPost("admin/structure/types/manage/article/fields/$field_name/field-settings", $edit, t('Save field settings'));
+ $this->drupalPost("admin/structure/types/manage/article/fields/node.article.$field_name/field-settings", $edit, t('Save field settings'));
// Clear field info cache so the new default image is detected.
field_info_cache_clear();
$field = field_info_field($field_name);
@@ -257,7 +257,7 @@ function testImageFieldDefaultImage() {
$edit = array(
'field[settings][default_image][fids]' => 0,
);
- $this->drupalPost("admin/structure/types/manage/article/fields/$field_name/field-settings", $edit, t('Save field settings'));
+ $this->drupalPost("admin/structure/types/manage/article/fields/node.article.$field_name/field-settings", $edit, t('Save field settings'));
// Clear field info cache so the new default image is detected.
field_info_cache_clear();
$field = field_info_field($field_name);
@@ -270,7 +270,7 @@ function testImageFieldDefaultImage() {
$edit = array(
'files[field_settings_default_image]' => drupal_realpath($images[1]->uri),
);
- $this->drupalPost('admin/structure/types/manage/article/fields/' . $private_field_name . '/field-settings', $edit, t('Save field settings'));
+ $this->drupalPost('admin/structure/types/manage/article/fields/node.article.' . $private_field_name . '/field-settings', $edit, t('Save field settings'));
// Clear field info cache so the new default image is detected.
field_info_cache_clear();
diff --git a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php
index de04d97..334ce54 100644
--- a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php
+++ b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php
@@ -81,7 +81,9 @@ protected function attachLoad(&$menu_links, $load_revision = FALSE) {
if ($routes) {
$route_objects = drupal_container()->get('router.route_provider')->getRoutesByNames($routes);
foreach ($routes as $entity_id => $route) {
- $menu_links[$entity_id]->setRouteObject($route_objects[$route]);
+ if (isset($route_objects[$route])) {
+ $menu_links[$entity_id]->setRouteObject($route_objects[$route]);
+ }
}
}
diff --git a/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php b/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php
index c4d8109..92746d6 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php
@@ -42,6 +42,7 @@
* bundle_keys = {
* "bundle" = "type"
* },
+ * entity_menu_base_path = "admin/structure/types/manage/{bundle}",
* permission_granularity = "bundle"
* )
*/
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php
index 0db0bda..452ed93 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php
@@ -75,7 +75,7 @@ function testNodeAccessAdministerField() {
$default = 'Sometimes words have two meanings';
$edit["{$this->field_name}[$langcode][0][value]"] = $default;
$this->drupalPost(
- "admin/structure/types/manage/page/fields/{$this->field_name}",
+ "admin/structure/types/manage/page/fields/node.page.{$this->field_name}",
$edit,
t('Save settings')
);
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTypeTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTypeTest.php
index 64fa105..6a5b5f6 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeTypeTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeTypeTest.php
@@ -121,7 +121,7 @@ function testNodeTypeEditing() {
$this->assertRaw('Body', 'Body field was found.');
// Remove the body field.
- $this->drupalPost('admin/structure/types/manage/bar/fields/body/delete', array(), t('Delete'));
+ $this->drupalPost('admin/structure/types/manage/bar/fields/node.bar.body/delete', array(), t('Delete'));
// Resave the settings for this type.
$this->drupalPost('admin/structure/types/manage/bar', array(), t('Save content type'));
// Check that the body field doesn't exist.
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index f663387..f79deac 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -229,9 +229,7 @@ function node_entity_bundle_info() {
$bundles['node'][$type] = array(
'label' => $name,
'admin' => array(
- 'path' => 'admin/structure/types/manage/%node_type',
'real path' => 'admin/structure/types/manage/' . $type,
- 'bundle argument' => 4,
),
);
}
diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php
index 11f6035..c69c414 100644
--- a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php
+++ b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php
@@ -266,7 +266,7 @@ protected function createOptionsField($type) {
);
field_create_instance($instance);
- $this->admin_path = 'admin/structure/types/manage/' . $this->type . '/fields/' . $this->field_name . '/field-settings';
+ $this->admin_path = 'admin/structure/types/manage/' . $this->type . '/fields/node.' . $this->type . '.' . $this->field_name . '/field-settings';
}
/**
diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php b/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php
index 78efa3e..4dfd302 100644
--- a/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php
+++ b/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php
@@ -495,7 +495,7 @@ function testOnOffCheckbox() {
field_create_instance($instance);
// Go to the edit page and check if the default settings works as expected
- $fieldEditUrl = 'admin/structure/types/manage/page/fields/bool';
+ $fieldEditUrl = 'admin/structure/types/manage/page/fields/node.page.bool';
$this->drupalGet($fieldEditUrl);
$this->assertText(
diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php
index 07c38ae..676d1ac 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php
@@ -146,11 +146,11 @@ function testBreadCrumbs() {
$trail += array(
"admin/structure/types/manage/$type/fields" => t('Manage fields'),
);
- $this->assertBreadcrumb("admin/structure/types/manage/$type/fields/body", $trail);
+ $this->assertBreadcrumb("admin/structure/types/manage/$type/fields/node.$type.body", $trail);
$trail += array(
- "admin/structure/types/manage/$type/fields/body" => t('Body'),
+ "admin/structure/types/manage/$type/fields/node.$type.body" => t('Body'),
);
- $this->assertBreadcrumb("admin/structure/types/manage/$type/fields/body/widget-type", $trail);
+ $this->assertBreadcrumb("admin/structure/types/manage/$type/fields/node.$type.body/widget-type", $trail);
// Verify Filter text format administration breadcrumbs.
$filter_formats = filter_formats();
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Term.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Term.php
index 07f2a81..793f06a 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Term.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Term.php
@@ -41,6 +41,7 @@
* "bundle" = "vid"
* },
* menu_base_path = "taxonomy/term/%taxonomy_term",
+ * entity_menu_base_path = "admin/structure/taxonomy/{bundle}",
* permission_granularity = "bundle"
* )
*/
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index ddd164c..3b2a42d 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -128,9 +128,7 @@ function taxonomy_entity_bundle_info() {
$bundles['taxonomy_term'][$id] = array(
'label' => $config->get('name'),
'admin' => array(
- 'path' => 'admin/structure/taxonomy/%taxonomy_vocabulary',
'real path' => 'admin/structure/taxonomy/' . $id,
- 'bundle argument' => 3,
),
);
}
diff --git a/core/modules/text/lib/Drupal/text/Tests/TextTranslationTest.php b/core/modules/text/lib/Drupal/text/Tests/TextTranslationTest.php
index 9aff558..b8b5656 100644
--- a/core/modules/text/lib/Drupal/text/Tests/TextTranslationTest.php
+++ b/core/modules/text/lib/Drupal/text/Tests/TextTranslationTest.php
@@ -63,7 +63,7 @@ function setUp() {
function testTextField() {
// Disable text processing for body.
$edit = array('instance[settings][text_processing]' => 0);
- $this->drupalPost('admin/structure/types/manage/article/fields/body', $edit, t('Save settings'));
+ $this->drupalPost('admin/structure/types/manage/article/fields/node.article.body', $edit, t('Save settings'));
// Login as translator.
$this->drupalLogin($this->translator);
@@ -92,7 +92,7 @@ function testTextField() {
function testTextFieldFormatted() {
// Make node body multiple.
$edit = array('field[container][cardinality]' => -1);
- $this->drupalPost('admin/structure/types/manage/article/fields/body/field-settings', $edit, t('Save field settings'));
+ $this->drupalPost('admin/structure/types/manage/article/fields/node.article.body/field-settings', $edit, t('Save field settings'));
$this->drupalGet('node/add/article');
$this->assertFieldByXPath("//input[@name='body_add_more']", t('Add another item'), 'Body field cardinality set to multiple.');
diff --git a/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/User.php b/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/User.php
index 5b167f4..99f052f 100644
--- a/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/User.php
+++ b/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/User.php
@@ -29,6 +29,7 @@
* translation_controller_class = "Drupal\user\ProfileTranslationController",
* base_table = "users",
* uri_callback = "user_uri",
+ * entity_menu_base_path = "admin/config/people/accounts",
* label_callback = "user_label",
* fieldable = TRUE,
* translatable = TRUE,
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index eddc8c3..79d7d5b 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -2533,7 +2533,7 @@ function user_block_user_action(&$entity, $context = array()) {
* field instance' form.
*/
function user_form_field_ui_field_edit_form_alter(&$form, &$form_state, $form_id) {
- $instance = $form['#instance'];
+ $instance = $form_state['instance'];
if ($instance['entity_type'] == 'user') {
$form['instance']['settings']['user_register_form'] = array(