diff --git a/core/includes/entity.api.php b/core/includes/entity.api.php index 3f39e75..d814cde 100644 --- a/core/includes/entity.api.php +++ b/core/includes/entity.api.php @@ -510,6 +510,27 @@ function hook_entity_display_alter(\Drupal\entity\Plugin\Core\Entity\EntityDispl } /** + * Alters the settings used for displaying an entity form. + * + * @param \Drupal\entity\Plugin\Core\Entity\EntityFormDisplay $form_display + * The entity_form_display object that will be used to display the entity form + * components. + * @param array $context + * An associative array containing: + * - entity_type: The entity type, e.g., 'node' or 'user'. + * - bundle: The bundle, e.g., 'page' or 'article'. + * - form_mode: The form mode, e.g. 'default', 'profile', 'register'... + */ +function hook_entity_form_display_alter(\Drupal\entity\Plugin\Core\Entity\EntityFormDisplay $form_display, array $context) { + // Hide the 'user_picture' field from the register form. + if ($context['entity_type'] == 'user' && $context['form_mode'] == 'register') { + $form_display->setComponent('user_picture', array( + 'type' => 'hidden', + )); + } +} + +/** * Define custom entity properties. * * @param string $entity_type diff --git a/core/includes/entity.inc b/core/includes/entity.inc index c2c97c4..66c9470 100644 --- a/core/includes/entity.inc +++ b/core/includes/entity.inc @@ -688,7 +688,7 @@ function entity_get_display($entity_type, $bundle, $view_mode) { $display = entity_create('entity_display', array( 'targetEntityType' => $entity_type, 'bundle' => $bundle, - 'viewMode' => $view_mode, + 'mode' => $view_mode, )); } @@ -717,7 +717,7 @@ function entity_get_display($entity_type, $bundle, $view_mode) { * @return \Drupal\entity\Plugin\Core\Entity\EntityDisplay * The display object that should be used to render the entity. * - * @see entity_get_render_display(). + * @see entity_get_display(). */ function entity_get_render_display(EntityInterface $entity, $view_mode) { $entity_type = $entity->entityType(); @@ -730,12 +730,102 @@ function entity_get_render_display(EntityInterface $entity, $view_mode) { $render_view_mode = !empty($view_mode_settings[$view_mode]['custom_settings']) ? $view_mode : 'default'; $display = entity_get_display($entity_type, $bundle, $render_view_mode); - $display->originalViewMode = $view_mode; + $display->originalMode = $view_mode; return $display; } /** + * Returns the entity_form_display object associated to a bundle and form mode. + * + * The function reads the entity_form_display object from the current + * configuration, or returns a ready-to-use empty one if configuration entry + * exists yet for this bundle and form mode. This streamlines manipulation of + * EntityFormDisplay objects by always returning a consistent object that + * reflects the current state of the configuration. + * + * Example usage: + * - Set the 'body' field to be displayed with the 'text_textarea_with_summary' + * widget and the 'field_image' field to be hidden on article nodes in the + * 'default' form mode. + * @code + * entity_get_form_display('node', 'article', 'default') + * ->setComponent('body', array( + * 'type' => 'text_textarea_with_summary', + * 'weight' => 1, + * )) + * ->setComponent('field_image', array( + * 'type' => 'hidden', + * )) + * ->save(); + * @endcode + * + * @param string $entity_type + * The entity type. + * @param string $bundle + * The bundle. + * @param string $form_mode + * (optional) The form mode. Defaults to 'default'. + * + * @todo Make the $form_mode parameter non-optional by introducing the form + * modes concept. + * + * @return \Drupal\entity\Plugin\Core\Entity\EntityFormDisplay + * The EntityFormDisplay object associated to the form mode. + */ +function entity_get_form_display($entity_type, $bundle, $form_mode = 'default') { + // Try loading the entity from configuration. + $entity_form_display = entity_load('entity_form_display', $entity_type . '.' . $bundle . '.' . $form_mode); + + // If not found, create a fresh entity object. We do not preemptively create + // new EntityFormDisplay configuration entries for each existing entity type + // and bundle whenever a new form mode becomes available. Instead, + // configuration entries are only created when a EntityFormDisplay object is + // explicitly configured and saved. + if (!$entity_form_display) { + $entity_form_display = entity_create('entity_form_display', array( + 'targetEntityType' => $entity_type, + 'bundle' => $bundle, + 'mode' => $form_mode, + )); + } + + return $entity_form_display; +} + +/** + * Returns the entity_form_display object used to render an entity form. + * + * This function should only be used internally when rendering an entity form. + * When assigning suggested form display options for a component in a given form + * mode, entity_get_form_display() should be used instead, in order to avoid + * inadvertently modifying the output of other form modes that might happen to + * use the 'default' form display too. Those options will then be effectively + * applied only if the form mode is configured to use them. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity for which the form is being rendered. + * @param string $form_mode + * The form mode being rendered. + * + * @return \Drupal\entity\Plugin\Core\Entity\EntityFormDisplay + * The form display object that should be used to render the entity form. + * + * @see entity_get_form_display(). + */ +function entity_get_render_form_display(EntityInterface $entity, $form_mode) { + $entity_type = $entity->entityType(); + $bundle = $entity->bundle(); + + // @todo Form modes don't have custom settings yet, so just return the display + // for the form mode that was requested. + $form_display = entity_get_form_display($entity_type, $bundle, $form_mode); + $form_display->originalMode = $form_mode; + + return $form_display; +} + +/** * Generic access callback for entity pages. * * @param \Drupal\Core\Entity\EntityInterface $entity diff --git a/core/lib/Drupal/Core/Entity/EntityFormController.php b/core/lib/Drupal/Core/Entity/EntityFormController.php index 6d2c9fb..2332d06 100644 --- a/core/lib/Drupal/Core/Entity/EntityFormController.php +++ b/core/lib/Drupal/Core/Entity/EntityFormController.php @@ -74,12 +74,35 @@ protected function init(array &$form_state, EntityInterface $entity) { * @see Drupal\Core\Entity\EntityFormController::build() */ public function form(array $form, array &$form_state, EntityInterface $entity) { + // Get the entity_form_display object for this form. + $form_display = entity_get_render_form_display($entity, 'default'); + + // Let modules alter the form display. + $form_display_context = array( + 'entity_type' => $entity->entityType(), + 'bundle' => $entity->bundle(), + 'form_mode' => $this->operation, + ); + drupal_alter('entity_form_display', $form_display, $form_display_context); + + // Persist the altered form display in $form_state so we can use it during + // validation and submit. + $form_state['form_display'] = $form_display; + // @todo Exploit the Field API to generate the default widgets for the // entity properties. $info = $entity->entityInfo(); if (!empty($info['fieldable'])) { field_attach_form($entity, $form, $form_state, $this->getFormLangcode($form_state)); } + + // Assign the weights configured in the form display. + foreach ($form_display->getComponents() as $name => $options) { + if (isset($form[$name])) { + $form[$name]['#weight'] = $options['weight']; + } + } + if (!isset($form['langcode'])) { // If the form did not specify otherwise, default to keeping the existing // language of the entity or defaulting to the site default language for diff --git a/core/lib/Drupal/Core/Entity/EntityFormControllerNG.php b/core/lib/Drupal/Core/Entity/EntityFormControllerNG.php index ef9bc89..f80bd5c 100644 --- a/core/lib/Drupal/Core/Entity/EntityFormControllerNG.php +++ b/core/lib/Drupal/Core/Entity/EntityFormControllerNG.php @@ -23,12 +23,35 @@ class EntityFormControllerNG extends EntityFormController { * Overrides EntityFormController::form(). */ public function form(array $form, array &$form_state, EntityInterface $entity) { + // Get the entity_form_display object for this form. + $form_display = entity_get_render_form_display($entity, 'default'); + + // Let modules alter the form display. + $form_display_context = array( + 'entity_type' => $entity->entityType(), + 'bundle' => $entity->bundle(), + 'form_mode' => $this->operation, + ); + drupal_alter('entity_form_display', $form_display, $form_display_context); + + // Persist the altered form display in $form_state so we can use it during + // validation and submit. + $form_state['form_display'] = $form_display; + // @todo Exploit the Field API to generate the default widgets for the - // entity fields. + // entity properties. $info = $entity->entityInfo(); if (!empty($info['fieldable'])) { field_attach_form($entity->getBCEntity(), $form, $form_state, $this->getFormLangcode($form_state)); } + + // Assign the weights configured in the form display. + foreach ($form_display->getComponents() as $name => $options) { + if (isset($form[$name])) { + $form[$name]['#weight'] = $options['weight']; + } + } + return $form; } diff --git a/core/modules/block/block.install b/core/modules/block/block.install index 01c5779..bb9806e 100644 --- a/core/modules/block/block.install +++ b/core/modules/block/block.install @@ -259,11 +259,19 @@ function block_update_8008() { 'entity_type' => 'custom_block', 'bundle' => 'basic', 'label' => 'Block body', - 'widget' => array('type' => 'text_textarea_with_summary'), 'settings' => array('display_summary' => FALSE), ); _update_7000_field_create_instance($body_field, $instance); + module_load_install('entity'); + // Assign form settings for the 'default' form mode. + $form_display = _update_8000_entity_get_form_display('custom_block', 'basic', 'default'); + $form_display->set('content.user_picture', array( + 'type' => 'text_textarea_with_summary', + )) + ->save(); + update_config_manifest_add('entity.form_display', array($form_display->get('id'))); + // Initialize state for future calls. $sandbox['last'] = 0; $sandbox['count'] = 0; diff --git a/core/modules/block/custom_block/custom_block.module b/core/modules/block/custom_block/custom_block.module index 4a1cbcb..e18b213 100644 --- a/core/modules/block/custom_block/custom_block.module +++ b/core/modules/block/custom_block/custom_block.module @@ -237,11 +237,17 @@ function custom_block_add_body_field($block_type_id, $label = 'Block body') { 'entity_type' => 'custom_block', 'bundle' => $block_type_id, 'label' => $label, - 'widget' => array('type' => 'text_textarea_with_summary'), 'settings' => array('display_summary' => FALSE), ); $instance = field_create_instance($instance); + // Assign widget settings for the 'default' form mode. + entity_get_form_display('custom_block', $block_type_id, 'default') + ->setComponent('block_body', array( + 'type' => 'text_textarea_with_summary', + )) + ->save(); + // Assign display settings for 'default' view mode. entity_get_display('custom_block', $block_type_id, 'default') ->setComponent('block_body', array( diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php index 8d49349..c62f4a7 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php @@ -77,17 +77,18 @@ public function testBlockFields() { 'settings' => array( 'title' => DRUPAL_OPTIONAL, ), - 'widget' => array( - 'type' => 'link_default', - ), - ); - $display_options = array( - 'type' => 'link', - 'label' => 'hidden', ); field_create_instance($this->instance); + entity_get_form_display('custom_block', 'link', 'default') + ->setComponent($this->field['field_name'], array( + 'type' => 'link_default', + )) + ->save(); entity_get_display('custom_block', 'link', 'default') - ->setComponent($this->field['field_name'], $display_options) + ->setComponent($this->field['field_name'], array( + 'type' => 'link', + 'label' => 'hidden', + )) ->save(); // Create a block. diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index 5690c72..7a4a21c 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -389,6 +389,15 @@ function _comment_body_field_create($info) { 'required' => TRUE, ); field_create_instance($instance); + + // Assign widget settings for the 'default' form mode. + entity_get_form_display('comment', 'comment_node_' . $info->type, 'default') + ->setComponent('comment_body', array( + 'type' => 'text_textarea', + )) + ->save(); + + // Assign display settings for the 'default' view mode. entity_get_display('comment', 'comment_node_' . $info->type, 'default') ->setComponent('comment_body', array( 'label' => 'hidden', diff --git a/core/modules/datetime/datetime.module b/core/modules/datetime/datetime.module index 79905f8..b545c36 100644 --- a/core/modules/datetime/datetime.module +++ b/core/modules/datetime/datetime.module @@ -134,9 +134,7 @@ function datetime_field_settings_form($field, $instance, $has_data) { * Implements hook_field_instance_settings_form(). */ function datetime_field_instance_settings_form($field, $instance) { - $widget = $instance['widget']; $settings = $instance['settings']; - $widget_settings = $instance['widget']['settings']; $form['default_value'] = array( '#type' => 'select', diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDatelistWidget.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDatelistWidget.php index 366a4c4..f0d60fe 100644 --- a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDatelistWidget.php +++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDatelistWidget.php @@ -36,23 +36,12 @@ class DateTimeDatelistWidget extends WidgetBase { /** - * Constructs a DateTimeDatelist Widget object. - * - * @param array $plugin_id - * The plugin_id for the widget. - * @param array $plugin_definition - * The plugin implementation definition. - * @param \Drupal\field\Plugin\Core\Entity\FieldInstance $instance - * The field instance to which the widget is associated. - * @param array $settings - * The widget settings. - * @param int $weight - * The widget weight. + * {@inheritdoc} */ - public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, array $settings, $weight) { + public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, array $settings) { // Identify the function used to set the default value. $instance['default_value_function'] = $this->defaultValueFunction(); - parent::__construct($plugin_id, $plugin_definition, $instance, $settings, $weight); + parent::__construct($plugin_id, $plugin_definition, $instance, $settings); } /** diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php index d51bac4..f0c45c0 100644 --- a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php +++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php @@ -30,23 +30,12 @@ class DateTimeDefaultWidget extends WidgetBase { /** - * Constructs a DateTimeDefault Widget object. - * - * @param array $plugin_id - * The plugin_id for the widget. - * @param array $plugin_definition - * The plugin implementation definition. - * @param \Drupal\field\Plugin\Core\Entity\FieldInstance $instance - * The field instance to which the widget is associated. - * @param array $settings - * The widget settings. - * @param int $weight - * The widget weight. + * {@inheritdoc} */ - public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, array $settings, $weight) { + public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, array $settings) { // Identify the function used to set the default value. $instance['default_value_function'] = $this->defaultValueFunction(); - parent::__construct($plugin_id, $plugin_definition, $instance, $settings, $weight); + parent::__construct($plugin_id, $plugin_definition, $instance, $settings); } /** diff --git a/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php b/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php index bb3bddf..ac3f4a3 100644 --- a/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php +++ b/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php @@ -57,14 +57,17 @@ function setUp() { 'field_name' => $this->field['field_name'], 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', - 'widget' => array( - 'type' => 'datetime_default', - ), 'settings' => array( 'default_value' => 'blank', ), )); + entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default') + ->setComponent($this->field['field_name'], array( + 'type' => 'datetime_default', + )) + ->save(); + $this->display_options = array( 'type' => 'datetime_default', 'label' => 'hidden', @@ -217,17 +220,16 @@ function testDatelistWidget() { field_update_field($this->field); // Change the widget to a datelist widget. - $increment = 1; - $date_order = 'YMD'; - $time_type = '12'; - - $this->instance['widget']['type'] = 'datetime_datelist'; - $this->instance['widget']['settings'] = array( - 'increment' => $increment, - 'date_order' => $date_order, - 'time_type' => $time_type, - ); - field_update_instance($this->instance); + entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default') + ->setComponent($this->instance['field_name'], array( + 'type' => 'datetime_datelist', + 'settings' => array( + 'increment' => 1, + 'date_order' => 'YMD', + 'time_type' => '12', + ), + )) + ->save(); field_cache_clear(); // Display creation form. diff --git a/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php b/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php index d3737bb..30aec3f 100644 --- a/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php +++ b/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php @@ -70,13 +70,16 @@ function createFieldWithInstance($field_name, $type, $cardinality, $label, $inst 'description' => $label, 'weight' => mt_rand(0, 127), 'settings' => $instance_settings, - 'widget' => array( + ); + field_create_instance($this->$instance); + + entity_get_form_display('entity_test', 'entity_test', 'default') + ->setComponent($field_name, array( 'type' => $widget_type, 'label' => $label, 'settings' => $widget_settings, - ), - ); - field_create_instance($this->$instance); + )) + ->save(); entity_get_display('entity_test', 'entity_test', 'default') ->setComponent($field_name, array( diff --git a/core/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php b/core/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php index c719c97..dbb2bed 100644 --- a/core/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php +++ b/core/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php @@ -54,14 +54,18 @@ function testEmailField() { 'field_name' => $this->field['field_name'], 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', - 'widget' => array( + ); + field_create_instance($this->instance); + + // Create a form display for the default form mode. + entity_get_form_display('test_entity', 'test_bundle', 'default') + ->setComponent($this->field['field_name'], array( 'type' => 'email_default', 'settings' => array( 'placeholder' => 'example@example.com', ), - ), - ); - field_create_instance($this->instance); + )) + ->save(); // Create a display for the full view mode. entity_get_display('test_entity', 'test_bundle', 'full') ->setComponent($this->field['field_name'], array( diff --git a/core/modules/email/lib/Drupal/email/Tests/EmailItemTest.php b/core/modules/email/lib/Drupal/email/Tests/EmailItemTest.php index def99f1..1555b8d 100644 --- a/core/modules/email/lib/Drupal/email/Tests/EmailItemTest.php +++ b/core/modules/email/lib/Drupal/email/Tests/EmailItemTest.php @@ -44,11 +44,15 @@ public function setUp() { 'entity_type' => 'entity_test', 'field_name' => 'field_email', 'bundle' => 'entity_test', - 'widget' => array( - 'type' => 'email_default', - ), ); field_create_instance($this->instance); + + // Create a form display for the default form mode. + entity_get_form_display('entity_test', 'entity_test', 'default') + ->setComponent('field_email', array( + 'type' => 'email_default', + )) + ->save(); } /** diff --git a/core/modules/entity/entity.install b/core/modules/entity/entity.install index 2e1efd7..af2aba1 100644 --- a/core/modules/entity/entity.install +++ b/core/modules/entity/entity.install @@ -37,7 +37,46 @@ function _update_8000_entity_get_display($entity_type, $bundle, $view_mode) { 'uuid' => $uuid->generate(), 'targetEntityType' => $entity_type, 'bundle' => $bundle, - 'viewMode' => $view_mode, + 'mode' => $view_mode, + 'content' => array(), + ); + foreach ($properties as $key => $value) { + $config->set($key, $value); + } + return $config; +} + +/** + * Returns the raw configuration object for an EntityFormDisplay entity. + * + * The function returns the existing configuration entry if it exists, or + * creates a fresh structure. + * + * @param string $entity_type + * The entity type. + * @param string $bundle + * The bundle name. + * @param string $form_mode + * The form mode. + * + * @return \Drupal\Core\Config\Config + * The configuration object. + */ +function _update_8000_entity_get_form_display($entity_type, $bundle, $form_mode) { + $id = $entity_type . '.' . $bundle . '.' . $form_mode; + $config = config("entity.form_display.$id"); + if ($config->get()) { + return $config; + } + + // Initialize a fresh structure. + $uuid = new Uuid(); + $properties = array( + 'id' => $id, + 'uuid' => $uuid->generate(), + 'targetEntityType' => $entity_type, + 'bundle' => $bundle, + 'mode' => $form_mode, 'content' => array(), ); foreach ($properties as $key => $value) { diff --git a/core/modules/entity/entity.module b/core/modules/entity/entity.module index 8fca683..7a9c8a8 100644 --- a/core/modules/entity/entity.module +++ b/core/modules/entity/entity.module @@ -14,20 +14,33 @@ * Implements hook_entity_bundle_rename(). */ function entity_entity_bundle_rename($entity_type, $bundle_old, $bundle_new) { - $entity_info = entity_get_info('entity_display'); - // Rename entity displays. + $entity_info = entity_get_info('entity_display'); if ($bundle_old !== $bundle_new) { $ids = config_get_storage_names_with_prefix('entity.display.' . $entity_type . '.' . $bundle_old); foreach ($ids as $id) { $id = ConfigStorageController::getIDFromConfigName($id, $entity_info['config_prefix']); $display = entity_load('entity_display', $id); - $new_id = $entity_type . '.' . $bundle_new . '.' . $display->viewMode; + $new_id = $entity_type . '.' . $bundle_new . '.' . $display->mode; $display->id = $new_id; $display->bundle = $bundle_new; $display->save(); } } + + // Rename entity form displays. + $entity_info = entity_get_info('entity_form_display'); + if ($bundle_old !== $bundle_new) { + $ids = config_get_storage_names_with_prefix('entity.form_display.' . $entity_type . '.' . $bundle_old); + foreach ($ids as $id) { + $id = ConfigStorageController::getIDFromConfigName($id, $entity_info['config_prefix']); + $form_display = entity_load('entity_form_display', $id); + $new_id = $entity_type . '.' . $bundle_new . '.' . $form_display->mode; + $form_display->id = $new_id; + $form_display->bundle = $bundle_new; + $form_display->save(); + } + } } /** @@ -42,4 +55,11 @@ function entity_entity_bundle_delete($entity_type, $bundle) { $id = ConfigStorageController::getIDFromConfigName($id, $entity_info['config_prefix']); } entity_delete_multiple('entity_display', $ids); + + // Remove entity form displays of the deleted bundle. + $ids = config_get_storage_names_with_prefix('entity.form_display.' . $entity_type . '.' . $bundle); + foreach ($ids as &$id) { + $id = ConfigStorageController::getIDFromConfigName($id, $entity_info['config_prefix']); + } + entity_delete_multiple('entity_form_display', $ids); } diff --git a/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php similarity index 65% copy from core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php copy to core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php index af01eb4..88d25a6 100644 --- a/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php +++ b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php @@ -2,34 +2,18 @@ /** * @file - * Contains \Drupal\entity\Plugin\Core\Entity\EntityDisplay. + * Contains \Drupal\entity\EntityDisplayBase. */ -namespace Drupal\entity\Plugin\Core\Entity; +namespace Drupal\entity; use Drupal\Core\Config\Entity\ConfigEntityBase; -use Drupal\Core\Entity\Annotation\EntityType; -use Drupal\Core\Annotation\Translation; /** - * Configuration entity that contains display options for all components of a - * rendered entity in a given view mode.. - * - * @EntityType( - * id = "entity_display", - * label = @Translation("Entity display"), - * module = "entity", - * controllers = { - * "storage" = "Drupal\Core\Config\Entity\ConfigStorageController" - * }, - * config_prefix = "entity.display", - * entity_keys = { - * "id" = "id", - * "uuid" = "uuid" - * } - * ) + * Base class for config entity types that store configuration for entity forms + * and displays. */ -class EntityDisplay extends ConfigEntityBase { +abstract class EntityDisplayBase extends ConfigEntityBase { /** * Unique ID for the config entity. @@ -60,11 +44,11 @@ class EntityDisplay extends ConfigEntityBase { public $bundle; /** - * View mode to be displayed. + * View or form mode to be displayed. * * @var string */ - public $viewMode; + public $mode; /** * List of component display options, keyed by component name. @@ -74,19 +58,33 @@ class EntityDisplay extends ConfigEntityBase { protected $content = array(); /** - * The original view mode that was requested (case of view modes being - * configured to fall back to the 'default' display). + * The original view or form mode that was requested (case of view/form modes + * being configured to fall back to the 'default' display). * * @var string */ - public $originalViewMode; + public $originalMode; /** - * The formatter objects used for this display, keyed by field name. + * The plugin objects used for this display, keyed by field name. * * @var array */ - protected $formatters = array(); + protected $plugins = array(); + + /** + * Context in which this entity will be used (e.g. 'display', 'form'). + * + * @var string + */ + protected $displayContext; + + /** + * The plugin manager used by this entity type. + * + * @var \Drupal\Component\Plugin\PluginManagerBase + */ + protected $pluginManager; /** * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::__construct(). @@ -96,19 +94,28 @@ public function __construct(array $values, $entity_type) { // currently produces invalid entities with a NULL bundle in some cases. // Add the validity checks back when http://drupal.org/node/1856556 is // fixed. - // if (!isset($values['targetEntityType']) || !isset($values['bundle']) || !isset($values['viewMode'])) { - // throw new \InvalidArgumentException('Missing required properties for an EntiyDisplay entity.'); + // if (!isset($values['targetEntityType']) || !isset($values['bundle']) || !isset($values['mode'])) { + // throw new \InvalidArgumentException('Missing required properties for an EntityDisplay entity.'); // } + + // A plugin manager and a context type needs to be set by extending classes. + if (!isset($this->pluginManager)) { + throw new \RuntimeException('Missing plugin manager.'); + } + if (!isset($this->displayContext)) { + throw new \RuntimeException('Missing display context type.'); + } + parent::__construct($values, $entity_type); - $this->originalViewMode = $this->viewMode; + $this->originalMode = $this->mode; } /** * Overrides \Drupal\Core\Entity\Entity::id(). */ public function id() { - return $this->targetEntityType . '.' . $this->bundle . '.' . $this->viewMode; + return $this->targetEntityType . '.' . $this->bundle . '.' . $this->mode; } /** @@ -131,7 +138,7 @@ public function getExportProperties() { 'uuid', 'targetEntityType', 'bundle', - 'viewMode', + 'mode', 'content', ); $properties = array(); @@ -142,20 +149,20 @@ public function getExportProperties() { } /** - * Creates a duplicate of the EntityDisplay object on a different view mode. + * Creates a duplicate object on a different form or view mode. * * The new object necessarily has the same $targetEntityType and $bundle - * properties than the original one. + * properties as the original one. * - * @param $view_mode - * The view mode for the new object. + * @param string $mode + * The form or view mode for the new object. * - * @return \Drupal\entity\Plugin\Core\Entity\EntityDisplay + * @return \Drupal\entity\EntityDisplayBase * The new object. */ - public function createCopy($view_mode) { + public function createCopy($mode) { $display = $this->createDuplicate(); - $display->viewMode = $display->originalViewMode = $view_mode; + $display->mode = $display->originalMode = $mode; return $display; } @@ -188,7 +195,7 @@ public function getComponents() { */ public function getComponent($name) { // We always store 'extra fields', whether they are visible or hidden. - $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, 'display'); + $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, $this->displayContext); if (isset($extra_fields[$name])) { // If we have explicit settings, return an array or NULL depending on // visibility. @@ -229,8 +236,8 @@ public function getComponent($name) { * @param array $options * The display options. * - * @return \Drupal\entity\Plugin\Core\Entity\EntityDisplay - * The EntityDisplay object. + * @return \Drupal\entity\EntityDisplayBase + * The EntityDisplayBase object. */ public function setComponent($name, array $options = array()) { // If no weight specified, make sure the field sinks at the bottom. @@ -241,14 +248,14 @@ public function setComponent($name, array $options = array()) { if ($instance = field_info_instance($this->targetEntityType, $name, $this->bundle)) { $field = field_info_field($instance['field_name']); - $options = drupal_container()->get('plugin.manager.field.formatter')->prepareConfiguration($field['type'], $options); + $options = $this->pluginManager->prepareConfiguration($field['type'], $options); - // Clear the persisted formatter, if any. - unset($this->formatters[$name]); + // Clear the persisted plugin, if any. + unset($this->plugins[$name]); } // We always store 'extra fields', whether they are visible or hidden. - $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, 'display'); + $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, $this->displayContext); if (isset($extra_fields[$name])) { $options['visible'] = TRUE; } @@ -264,11 +271,11 @@ public function setComponent($name, array $options = array()) { * @param string $name * The name of the component. * - * @return \Drupal\entity\Plugin\Core\Entity\EntityDisplay - * The EntityDisplay object. + * @return \Drupal\entity\EntityDisplayBase + * The EntityDisplayBase object. */ public function removeComponent($name) { - $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, 'display'); + $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, $this->displayContext); if (isset($extra_fields[$name])) { // 'Extra fields' are exposed in hooks and can appear at any given time. // Therefore we store extra fields that are explicitly being hidden, so @@ -280,7 +287,7 @@ public function removeComponent($name) { } else { unset($this->content[$name]); - unset($this->formatters[$name]); + unset($this->plugins[$name]); } return $this; @@ -304,44 +311,9 @@ public function getHighestWeight() { } // Let other modules feedback about their own additions. - $weights = array_merge($weights, module_invoke_all('field_info_max_weight', $this->targetEntityType, $this->bundle, $this->viewMode)); + $weights = array_merge($weights, module_invoke_all('field_info_max_weight', $this->targetEntityType, $this->bundle, $this->displayContext, $this->mode)); return $weights ? max($weights) : NULL; } - /** - * Returns the Formatter plugin for a field. - * - * @param string $field_name - * The field name. - * - * @return \Drupal\field\Plugin\Type\Formatter\FormatterInterface - * If the field is not hidden, the Formatter plugin to use for rendering - * it. - */ - public function getFormatter($field_name) { - if (isset($this->formatters[$field_name])) { - return $this->formatters[$field_name]; - } - - // Instantiate the formatter object from the stored display properties. - if ($configuration = $this->getComponent($field_name)) { - $instance = field_info_instance($this->targetEntityType, $field_name, $this->bundle); - $formatter = drupal_container()->get('plugin.manager.field.formatter')->getInstance(array( - 'instance' => $instance, - 'view_mode' => $this->originalViewMode, - // No need to prepare, defaults have been merged in setComponent(). - 'prepare' => FALSE, - 'configuration' => $configuration - )); - } - else { - $formatter = NULL; - } - - // Persist the formatter object. - $this->formatters[$field_name] = $formatter; - return $formatter; - } - } diff --git a/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php b/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php index af01eb4..05754d9 100644 --- a/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php +++ b/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php @@ -7,13 +7,13 @@ namespace Drupal\entity\Plugin\Core\Entity; -use Drupal\Core\Config\Entity\ConfigEntityBase; use Drupal\Core\Entity\Annotation\EntityType; use Drupal\Core\Annotation\Translation; +use Drupal\entity\EntityDisplayBase; /** * Configuration entity that contains display options for all components of a - * rendered entity in a given view mode.. + * rendered entity in a given view mode. * * @EntityType( * id = "entity_display", @@ -29,284 +29,16 @@ * } * ) */ -class EntityDisplay extends ConfigEntityBase { +class EntityDisplay extends EntityDisplayBase { /** - * Unique ID for the config entity. - * - * @var string - */ - public $id; - - /** - * Unique UUID for the config entity. - * - * @var string - */ - public $uuid; - - /** - * Entity type to be displayed. - * - * @var string - */ - public $targetEntityType; - - /** - * Bundle to be displayed. - * - * @var string - */ - public $bundle; - - /** - * View mode to be displayed. - * - * @var string - */ - public $viewMode; - - /** - * List of component display options, keyed by component name. - * - * @var array - */ - protected $content = array(); - - /** - * The original view mode that was requested (case of view modes being - * configured to fall back to the 'default' display). - * - * @var string - */ - public $originalViewMode; - - /** - * The formatter objects used for this display, keyed by field name. - * - * @var array - */ - protected $formatters = array(); - - /** - * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::__construct(). + * Overrides \Drupal\entity\EntityDisplayBase::__construct(). */ public function __construct(array $values, $entity_type) { - // @todo See http://drupal.org/node/1825044#comment-6847792: contact.module - // currently produces invalid entities with a NULL bundle in some cases. - // Add the validity checks back when http://drupal.org/node/1856556 is - // fixed. - // if (!isset($values['targetEntityType']) || !isset($values['bundle']) || !isset($values['viewMode'])) { - // throw new \InvalidArgumentException('Missing required properties for an EntiyDisplay entity.'); - // } - parent::__construct($values, $entity_type); - - $this->originalViewMode = $this->viewMode; - } - - /** - * Overrides \Drupal\Core\Entity\Entity::id(). - */ - public function id() { - return $this->targetEntityType . '.' . $this->bundle . '.' . $this->viewMode; - } - - /** - * Overrides \Drupal\config\ConfigEntityBase::save(). - */ - public function save() { - // Build an ID if none is set. - if (empty($this->id)) { - $this->id = $this->id(); - } - return parent::save(); - } - - /** - * Overrides \Drupal\config\ConfigEntityBase::getExportProperties(); - */ - public function getExportProperties() { - $names = array( - 'id', - 'uuid', - 'targetEntityType', - 'bundle', - 'viewMode', - 'content', - ); - $properties = array(); - foreach ($names as $name) { - $properties[$name] = $this->get($name); - } - return $properties; - } - - /** - * Creates a duplicate of the EntityDisplay object on a different view mode. - * - * The new object necessarily has the same $targetEntityType and $bundle - * properties than the original one. - * - * @param $view_mode - * The view mode for the new object. - * - * @return \Drupal\entity\Plugin\Core\Entity\EntityDisplay - * The new object. - */ - public function createCopy($view_mode) { - $display = $this->createDuplicate(); - $display->viewMode = $display->originalViewMode = $view_mode; - return $display; - } - - /** - * Gets the display options for all components. - * - * @return array - * The array of display options, keyed by component name. - */ - public function getComponents() { - $result = array(); - foreach ($this->content as $name => $options) { - if (!isset($options['visible']) || $options['visible'] === TRUE) { - unset($options['visible']); - $result[$name] = $options; - } - } - return $result; - } - - /** - * Gets the display options set for a component. - * - * @param string $name - * The name of the component. - * - * @return array|null - * The display options for the component, or NULL if the component is not - * displayed. - */ - public function getComponent($name) { - // We always store 'extra fields', whether they are visible or hidden. - $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, 'display'); - if (isset($extra_fields[$name])) { - // If we have explicit settings, return an array or NULL depending on - // visibility. - if (isset($this->content[$name])) { - if ($this->content[$name]['visible']) { - return array( - 'weight' => $this->content[$name]['weight'], - ); - } - else { - return NULL; - } - } - - // If no explicit settings for the extra field, look at the default - // visibility in its definition. - $definition = $extra_fields[$name]; - if (!isset($definition['visible']) || $definition['visible'] == TRUE) { - return array( - 'weight' => $definition['weight'] - ); - } - else { - return NULL; - } - } - - if (isset($this->content[$name])) { - return $this->content[$name]; - } - } - - /** - * Sets the display options for a component. - * - * @param string $name - * The name of the component. - * @param array $options - * The display options. - * - * @return \Drupal\entity\Plugin\Core\Entity\EntityDisplay - * The EntityDisplay object. - */ - public function setComponent($name, array $options = array()) { - // If no weight specified, make sure the field sinks at the bottom. - if (!isset($options['weight'])) { - $max = $this->getHighestWeight(); - $options['weight'] = isset($max) ? $max + 1 : 0; - } + $this->pluginManager = \Drupal::service('plugin.manager.field.formatter'); + $this->displayContext = 'display'; - if ($instance = field_info_instance($this->targetEntityType, $name, $this->bundle)) { - $field = field_info_field($instance['field_name']); - $options = drupal_container()->get('plugin.manager.field.formatter')->prepareConfiguration($field['type'], $options); - - // Clear the persisted formatter, if any. - unset($this->formatters[$name]); - } - - // We always store 'extra fields', whether they are visible or hidden. - $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, 'display'); - if (isset($extra_fields[$name])) { - $options['visible'] = TRUE; - } - - $this->content[$name] = $options; - - return $this; - } - - /** - * Sets a component to be hidden. - * - * @param string $name - * The name of the component. - * - * @return \Drupal\entity\Plugin\Core\Entity\EntityDisplay - * The EntityDisplay object. - */ - public function removeComponent($name) { - $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, 'display'); - if (isset($extra_fields[$name])) { - // 'Extra fields' are exposed in hooks and can appear at any given time. - // Therefore we store extra fields that are explicitly being hidden, so - // that we can differenciate with those that are simply not configured - // yet. - $this->content[$name] = array( - 'visible' => FALSE, - ); - } - else { - unset($this->content[$name]); - unset($this->formatters[$name]); - } - - return $this; - } - - /** - * Returns the highest weight of the components in the display. - * - * @return int|null - * The highest weight of the components in the display, or NULL if the - * display is empty. - */ - public function getHighestWeight() { - $weights = array(); - - // Collect weights for the components in the display. - foreach ($this->content as $options) { - if (isset($options['weight'])) { - $weights[] = $options['weight']; - } - } - - // Let other modules feedback about their own additions. - $weights = array_merge($weights, module_invoke_all('field_info_max_weight', $this->targetEntityType, $this->bundle, $this->viewMode)); - - return $weights ? max($weights) : NULL; + parent::__construct($values, $entity_type); } /** @@ -320,16 +52,16 @@ public function getHighestWeight() { * it. */ public function getFormatter($field_name) { - if (isset($this->formatters[$field_name])) { - return $this->formatters[$field_name]; + if (isset($this->plugins[$field_name])) { + return $this->plugins[$field_name]; } // Instantiate the formatter object from the stored display properties. if ($configuration = $this->getComponent($field_name)) { $instance = field_info_instance($this->targetEntityType, $field_name, $this->bundle); - $formatter = drupal_container()->get('plugin.manager.field.formatter')->getInstance(array( + $formatter = $this->pluginManager->getInstance(array( 'instance' => $instance, - 'view_mode' => $this->originalViewMode, + 'view_mode' => $this->originalMode, // No need to prepare, defaults have been merged in setComponent(). 'prepare' => FALSE, 'configuration' => $configuration @@ -340,7 +72,7 @@ public function getFormatter($field_name) { } // Persist the formatter object. - $this->formatters[$field_name] = $formatter; + $this->plugins[$field_name] = $formatter; return $formatter; } diff --git a/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityFormDisplay.php b/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityFormDisplay.php new file mode 100644 index 0000000..c69ed33 --- /dev/null +++ b/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityFormDisplay.php @@ -0,0 +1,97 @@ +pluginManager = \Drupal::service('plugin.manager.field.widget'); + $this->displayContext = 'form'; + + parent::__construct($values, $entity_type); + } + + /** + * Returns the Widget plugin for a field. + * + * @param string $field_name + * The field name. + * + * @return \Drupal\field\Plugin\Type\Widget\WidgetInterface|null + * A Widget plugin or NULL if the field does not exist. + */ + public function getWidget($field_name) { + if (isset($this->plugins[$field_name])) { + return $this->plugins[$field_name]; + } + + // Instantiate the widget object from the stored display properties. + if ($configuration = $this->getComponent($field_name)) { + $instance = field_info_instance($this->targetEntityType, $field_name, $this->bundle); + $widget = $this->pluginManager->getInstance(array( + 'instance' => $instance, + 'form_mode' => $this->originalMode, + // No need to prepare, defaults have been merged in setComponent(). + 'prepare' => FALSE, + 'configuration' => $configuration + )); + } + else { + $widget = NULL; + } + + // Persist the widget object. + $this->plugins[$field_name] = $widget; + return $widget; + } + + /** + * {@inheritdoc} + */ + public function serialize() { + // Only store the definition, not external objects or derived data. + $data = $this->getExportProperties() + array('entityType' => $this->entityType()); + return serialize($data); + } + + /** + * {@inheritdoc} + */ + public function unserialize($serialized) { + $data = unserialize($serialized); + $entity_type = $data['entityType']; + unset($data['entityType']); + $this->__construct($data, $entity_type); + } + +} diff --git a/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php b/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php index 11f6da7..f846594 100644 --- a/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php +++ b/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php @@ -36,7 +36,7 @@ public function testEntityDisplayCRUD() { $display = entity_create('entity_display', array( 'targetEntityType' => 'entity_test', 'bundle' => 'entity_test', - 'viewMode' => 'default', + 'mode' => 'default', )); $expected = array(); @@ -81,7 +81,7 @@ public function testEntityDisplayCRUD() { $new_display = entity_load('entity_display', $new_display->id()); $this->assertEqual($new_display->targetEntityType, $display->targetEntityType); $this->assertEqual($new_display->bundle, $display->bundle); - $this->assertEqual($new_display->viewMode, 'other_view_mode'); + $this->assertEqual($new_display->mode, 'other_view_mode'); $this->assertEqual($new_display->getComponents(), $display->getComponents()); } @@ -112,7 +112,7 @@ public function testExtraFieldComponent() { $display = entity_create('entity_display', array( 'targetEntityType' => 'entity_test', 'bundle' => 'entity_test', - 'viewMode' => 'default', + 'mode' => 'default', )); // Check that the default visibility taken into account for extra fields @@ -136,7 +136,7 @@ public function testFieldComponent() { $display = entity_create('entity_display', array( 'targetEntityType' => 'entity_test', 'bundle' => 'entity_test', - 'viewMode' => 'default', + 'mode' => 'default', )); // Create a field and an instance. diff --git a/core/modules/entity/lib/Drupal/entity/Tests/EntityFormDisplayTest.php b/core/modules/entity/lib/Drupal/entity/Tests/EntityFormDisplayTest.php new file mode 100644 index 0000000..f30b69c --- /dev/null +++ b/core/modules/entity/lib/Drupal/entity/Tests/EntityFormDisplayTest.php @@ -0,0 +1,121 @@ + 'Entity form display configuration entities', + 'description' => 'Tests the entity form display configuration entities.', + 'group' => 'Entity API', + ); + } + + protected function setUp() { + parent::setUp(); + $this->installConfig(array('field')); + } + + /** + * Tests entity_get_form_display(). + */ + public function testEntityGetFromDisplay() { + // Check that entity_get_form_display() returns a fresh object when no + // configuration entry exists. + $form_display = entity_get_form_display('entity_test', 'entity_test', 'default'); + $this->assertTrue($form_display->isNew()); + + // Add some components and save the display. + $form_display->setComponent('component_1', array('weight' => 10)) + ->save(); + + // Check that entity_get_form_display() returns the correct object. + $form_display = entity_get_form_display('entity_test', 'entity_test', 'default'); + $this->assertFalse($form_display->isNew()); + $this->assertEqual($form_display->id, 'entity_test.entity_test.default'); + $this->assertEqual($form_display->getComponent('component_1'), array('weight' => 10)); + } + + /** + * Tests the behavior of a field component within an EntityFormDisplay object. + */ + public function testFieldComponent() { + $this->enableModules(array('field_sql_storage', 'field_test')); + + $form_display = entity_create('entity_form_display', array( + 'targetEntityType' => 'entity_test', + 'bundle' => 'entity_test', + 'mode' => 'default', + )); + + // Create a field and an instance. + $field = array( + 'field_name' => 'test_field', + 'type' => 'test_field' + ); + field_create_field($field); + $instance = array( + 'field_name' => $field['field_name'], + 'entity_type' => 'entity_test', + 'bundle' => 'entity_test', + ); + field_create_instance($instance); + + // Check that providing no options results in default values being used. + $form_display->setComponent($field['field_name']); + $field_type_info = field_info_field_types($field['type']); + $default_widget = $field_type_info['default_widget']; + $default_settings = field_info_widget_settings($default_widget); + $expected = array( + 'weight' => 0, + 'type' => $default_widget, + 'settings' => $default_settings, + ); + $this->assertEqual($form_display->getComponent($field['field_name']), $expected); + + // Check that the getWidget() method returns the correct widget plugin. + $widget = $form_display->getWidget($field['field_name']); + $this->assertEqual($widget->getPluginId(), $default_widget); + $this->assertEqual($widget->getSettings(), $default_settings); + + // Check that the widget is statically persisted, by assigning an + // arbitrary property and reading it back. + $random_value = $this->randomString(); + $widget->randomValue = $random_value; + $widget = $form_display->getWidget($field['field_name']); + $this->assertEqual($widget->randomValue, $random_value ); + + // Check that changing the definition creates a new widget. + $form_display->setComponent($field['field_name'], array( + 'type' => 'field_test_multiple', + )); + $widget = $form_display->getWidget($field['field_name']); + $this->assertEqual($widget->getPluginId(), 'test_field_widget'); + $this->assertFalse(isset($widget->randomValue)); + + // Check that specifying an unknown widget (e.g. case of a disabled module) + // gets stored as is in the display, but results in the default widget being + // used. + $form_display->setComponent($field['field_name'], array( + 'type' => 'unknown_widget', + )); + $options = $form_display->getComponent($field['field_name']); + $this->assertEqual($options['type'], 'unknown_widget'); + $widget = $form_display->getWidget($field['field_name']); + $this->assertEqual($widget->getPluginId(), $default_widget); + } + +} diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php b/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php index b3fe3a0..dc2628b 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php @@ -75,7 +75,8 @@ public function getMatches($field, $instance, $entity_type, $entity_id = '', $pr if (isset($string)) { // Get an array of matching entities. - $match_operator = !empty($instance['widget']['settings']['match_operator']) ? $instance['widget']['settings']['match_operator'] : 'CONTAINS'; + $widget = entity_get_form_display($instance['entity_type'], $instance['bundle'])->getComponent($instance['field_name'], 'default'); + $match_operator = !empty($widget['settings']['match_operator']) ? $widget['settings']['match_operator'] : 'CONTAINS'; $entity_labels = $handler->getReferencableEntities($string, $match_operator, 10); // Loop through the entities and convert them into autocomplete output. diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php index 99ebe15..ace6f5d 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php @@ -66,6 +66,12 @@ function setUp() { ); field_create_instance($instance); + + entity_get_form_display('node', $referencing->type, 'default') + ->setComponent('test_field', array( + 'type' => 'entity_reference_autocomplete', + )) + ->save(); } /** diff --git a/core/modules/field/field.api.php b/core/modules/field/field.api.php index 5ba15c9..01d72aa 100644 --- a/core/modules/field/field.api.php +++ b/core/modules/field/field.api.php @@ -21,10 +21,9 @@ * in a #pre_render callback added by field_attach_form() and * field_attach_view(). * - * @see _field_extra_fields_pre_render() * @see hook_field_extra_fields_alter() * - * @return + * @return array * A nested array of 'pseudo-field' elements. Each list is nested within the * following keys: entity type, bundle name, context (either 'form' or * 'display'). The keys are the name of the elements as appearing in the @@ -33,8 +32,7 @@ * - label: The human readable name of the element. * - description: A short description of the element contents. * - weight: The default weight of the element. - * - visible: The default visibility of the element. Only for 'display' - * context. + * - visible: The default visibility of the element. * - edit: (optional) String containing markup (normally a link) used as the * element's 'edit' operation in the administration interface. Only for * 'form' context. @@ -784,38 +782,6 @@ function hook_field_widget_WIDGET_TYPE_form_alter(&$element, &$form_state, $cont } /** - * Alters the widget properties of a field instance before it gets displayed. - * - * Note that instead of hook_field_widget_properties_alter(), which is called - * for all fields on all entity types, - * hook_field_widget_properties_ENTITY_TYPE_alter() may be used to alter widget - * properties for fields on a specific entity type only. - * - * This hook is called once per field per added or edit entity. If the result - * of the hook involves reading from the database, it is highly recommended to - * statically cache the information. - * - * @param array $widget_properties - * The instance's widget properties. - * @param array $context - * An associative array containing: - * - entity_type: The entity type, e.g., 'node' or 'user'. - * - bundle: The bundle, e.g., 'page' or 'article'. - * - field: The field that the widget belongs to. - * - instance: The instance of the field. - * - * @see hook_field_widget_properties_ENTITY_TYPE_alter() - */ -function hook_field_widget_properties_alter(array &$widget_properties, array $context) { - // Change a widget's type according to the time of day. - $field = $context['field']; - if ($context['entity_type'] == 'node' && $field['field_name'] == 'field_foo') { - $time = date('H'); - $widget_properties['type'] = $time < 12 ? 'widget_am' : 'widget_pm'; - } -} - -/** * @} End of "defgroup field_widget". */ @@ -1819,21 +1785,24 @@ function hook_field_storage_pre_update(\Drupal\Core\Entity\EntityInterface $enti * Field API takes care of fields and 'extra_fields'. This hook is intended for * third-party modules adding other entity components (e.g. field_group). * - * @param $entity_type + * @param string $entity_type * The type of entity; e.g. 'node' or 'user'. - * @param $bundle + * @param string $bundle * The bundle name. - * @param $context - * The context for which the maximum weight is requested. Either 'form', or - * the name of a view mode. - * @return + * @param string $context + * The context for which the maximum weight is requested. Either 'form' or + * 'display'. + * @param string $context_mode + * The view or form mode name. + * + * @return int * The maximum weight of the entity's components, or NULL if no components * were found. */ -function hook_field_info_max_weight($entity_type, $bundle, $context) { +function hook_field_info_max_weight($entity_type, $bundle, $context, $context_mode) { $weights = array(); - foreach (my_module_entity_additions($entity_type, $bundle, $context) as $addition) { + foreach (my_module_entity_additions($entity_type, $bundle, $context, $context_mode) as $addition) { $weights[] = $addition['weight']; } @@ -1841,38 +1810,6 @@ function hook_field_info_max_weight($entity_type, $bundle, $context) { } /** - * Alters the widget properties of a field instance on a given entity type - * before it gets displayed. - * - * Modules can implement hook_field_widget_properties_ENTITY_TYPE_alter() to - * alter the widget properties for fields on a specific entity type, rather than - * implementing hook_field_widget_properties_alter(). - * - * This hook is called once per field per displayed widget entity. If the result - * of the hook involves reading from the database, it is highly recommended to - * statically cache the information. - * - * @param array $widget_properties - * The instance's widget properties. - * @param array $context - * An associative array containing: - * - entity_type: The entity type, e.g., 'node' or 'user'. - * - bundle: The bundle, e.g., 'page' or 'article'. - * - field: The field that the widget belongs to. - * - instance: The instance of the field. - * - * @see hook_field_widget_properties_alter() - */ -function hook_field_widget_properties_ENTITY_TYPE_alter(array &$widget_properties, array $context) { - // Change a widget's type according to the time of day. - $field = $context['field']; - if ($field['field_name'] == 'field_foo') { - $time = date('H'); - $widget_properties['type'] = $time < 12 ? 'widget_am' : 'widget_pm'; - } -} - -/** * @} End of "addtogroup field_storage". */ diff --git a/core/modules/field/field.attach.inc b/core/modules/field/field.attach.inc index cde15f4..b508454 100644 --- a/core/modules/field/field.attach.inc +++ b/core/modules/field/field.attach.inc @@ -8,6 +8,7 @@ use Drupal\field\FieldValidationException; use Drupal\Core\Entity\EntityInterface; use Drupal\entity\Plugin\Core\Entity\EntityDisplay; +use Drupal\entity\Plugin\Core\Entity\EntityFormDisplay; /** * @defgroup field_storage Field Storage API @@ -705,12 +706,15 @@ function _field_invoke_get_instances($entity_type, $bundle, $options) { * * Used to invoke methods on an instance's widget. * + * @param \Drupal\entity\Plugin\Core\Entity\EntityFormDisplay $form_display + * An EntityFormDisplay object. + * * @return callable $target_function * A 'target function' for field_invoke_method(). */ -function _field_invoke_widget_target() { - return function ($instance) { - return $instance->getWidget(); +function _field_invoke_widget_target($form_display) { + return function ($instance) use ($form_display) { + return $form_display->getWidget($instance['field_name']); }; } @@ -825,12 +829,13 @@ function field_attach_form(EntityInterface $entity, &$form, &$form_state, $langc // Set #parents to 'top-level' by default. $form += array('#parents' => array()); + // Get the entity_form_display object for this form. + $form_display = $form_state['form_display']; + // If no language is provided use the default site language. $options['langcode'] = field_valid_language($langcode); - $form += (array) field_invoke_method('form', _field_invoke_widget_target(), $entity, $form, $form_state, $options); + $form += (array) field_invoke_method('form', _field_invoke_widget_target($form_display), $entity, $form, $form_state, $options); - // Add custom weight handling. - $form['#pre_render'][] = '_field_extra_fields_pre_render'; $form['#entity_type'] = $entity->entityType(); $form['#bundle'] = $entity->bundle(); @@ -1092,7 +1097,8 @@ function field_attach_form_validate(EntityInterface $entity, $form, &$form_state field_form_set_state($form['#parents'], $field_name, $langcode, $form_state, $field_state); } } - field_invoke_method('flagErrors', _field_invoke_widget_target(), $entity, $form, $form_state, $options); + $form_display = $form_state['form_display']; + field_invoke_method('flagErrors', _field_invoke_widget_target($form_display), $entity, $form, $form_state, $options); } } @@ -1116,7 +1122,8 @@ function field_attach_form_validate(EntityInterface $entity, $form, &$form_state */ function field_attach_extract_form_values(EntityInterface $entity, $form, &$form_state, array $options = array()) { // Extract field values from submitted values. - field_invoke_method('extractFormValues', _field_invoke_widget_target(), $entity, $form, $form_state, $options); + $form_display = $form_state['form_display']; + field_invoke_method('extractFormValues', _field_invoke_widget_target($form_display), $entity, $form, $form_state, $options); // Let other modules act on submitting the entity. // Avoid module_invoke_all() to let $form_state be taken by reference. @@ -1432,7 +1439,7 @@ function field_attach_view(EntityInterface $entity, EntityDisplay $display, $lan $entity = $entity->getNGEntity(); // Let other modules alter the renderable array. - $view_mode = $display->originalViewMode; + $view_mode = $display->originalMode; $context = array( 'entity' => $entity, 'view_mode' => $view_mode, diff --git a/core/modules/field/field.info.inc b/core/modules/field/field.info.inc index 38edcdb..5505d33 100644 --- a/core/modules/field/field.info.inc +++ b/core/modules/field/field.info.inc @@ -130,20 +130,23 @@ function _field_info_collate_types_reset() { /** * Determines the behavior of a widget with respect to an operation. * - * @param $op - * The name of the operation. Currently supported: 'default value', 'multiple - * values'. - * @param $instance + * @param string $op + * The name of the operation. Currently supported: 'default_value', + * 'multiple_values'. + * @param array $instance * The field instance array. * - * @return + * @return int * One of these values: * - FIELD_BEHAVIOR_NONE: Do nothing for this operation. * - FIELD_BEHAVIOR_CUSTOM: Use the widget's callback function. * - FIELD_BEHAVIOR_DEFAULT: Use field.module default behavior. */ function field_behaviors_widget($op, $instance) { - $info = field_info_widget_types($instance['widget']['type']); + $info = array(); + if ($component = entity_get_form_display($instance['entity_type'], $instance['bundle'])->getComponent($instance['field_name'], 'default')) { + $info = field_info_widget_types($component['type']); + } return isset($info[$op]) ? $info[$op] : FIELD_BEHAVIOR_DEFAULT; } @@ -478,40 +481,6 @@ function field_info_extra_fields($entity_type, $bundle, $context) { } /** - * Returns the maximum weight of all the components in a form entity. - * - * This includes fields, 'extra_fields', and other components added by - * third-party modules (e.g. field_group). - * - * @param $entity_type - * The type of entity; e.g. 'node' or 'user'. - * @param $bundle - * The bundle name. - * - * @return - * The maximum weight of the entity's components, or NULL if no components - * were found. - */ -function field_info_max_weight($entity_type, $bundle) { - $weights = array(); - - // Collect weights for fields. - foreach (field_info_instances($entity_type, $bundle) as $instance) { - $weights[] = $instance['widget']['weight']; - } - // Collect weights for extra fields. - foreach (field_info_extra_fields($entity_type, $bundle, 'form') as $extra) { - $weights[] = $extra['weight']; - } - - // Let other modules feedback about their own additions. - $weights = array_merge($weights, module_invoke_all('field_info_max_weight', $entity_type, $bundle, 'form')); - $max_weight = $weights ? max($weights) : NULL; - - return $max_weight; -} - -/** * Returns a field type's default settings. * * @param $type diff --git a/core/modules/field/field.install b/core/modules/field/field.install index dcf2b38..dc20e25 100644 --- a/core/modules/field/field.install +++ b/core/modules/field/field.install @@ -250,12 +250,12 @@ function field_update_8001() { } /** - * Migrate all instance display settings to configuration. + * Migrate all instance widget and display settings to configuration. * * @ingroup config_upgrade */ function field_update_8002() { - $displays = array(); + $form_displays = $displays = array(); module_load_install('entity'); $query = db_select('field_config_instance', 'fc')->fields('fc'); @@ -266,28 +266,46 @@ function field_update_8002() { // Skip field instances that were created directly with the new API earlier // in the upgrade path. - if (!isset($data['display'])) { + if (!isset($data['widget']) && !isset($data['display'])) { continue; } - foreach ($data['display'] as $view_mode => $display_options) { - // Determine name and create initial entry in the $displays array if it - // does not exist yet. - $display_id = $record->entity_type . '.' . $record->bundle . '.' . $view_mode; - if (!isset($displays[$display_id])) { - $displays[$display_id] = _update_8000_entity_get_display($record->entity_type, $record->bundle, $view_mode); + // Migrate 'widget' settings. + if (isset($data['widget'])) { + $widget_options = $data['widget']; + // Determine name and create initial entry in the $form_displays array. + $form_display_id = $record->entity_type . '.' . $record->bundle . '.default'; + if (!isset($form_displays[$form_display_id])) { + $form_displays[$form_display_id] = _update_8000_entity_get_form_display($record->entity_type, $record->bundle, 'default'); } - // The display object does not store hidden fields. - if ($display_options['type'] != 'hidden') { - // We do not need the 'module' key anymore. - unset($display_options['module']); - $displays[$display_id]->set("content.$record->field_name", $display_options); + // We do not need the 'module' key anymore. + unset($widget_options['module']); + $form_displays[$form_display_id]->set("content.$record->field_name", $widget_options); + } + + // Migrate 'display' settings. + if (isset($data['display'])) { + foreach ($data['display'] as $view_mode => $display_options) { + // Determine name and create initial entry in the $displays array if it + // does not exist yet. + $display_id = $record->entity_type . '.' . $record->bundle . '.' . $view_mode; + if (!isset($displays[$display_id])) { + $displays[$display_id] = _update_8000_entity_get_display($record->entity_type, $record->bundle, $view_mode); + } + + // The display object does not store hidden fields. + if ($display_options['type'] != 'hidden') { + // We do not need the 'module' key anymore. + unset($display_options['module']); + $displays[$display_id]->set("content.$record->field_name", $display_options); + } } } - // Remove the 'display' key and save the record back into the table. - unset($data['display']); + // Remove the 'widget' and 'display' keys and save the record back into the + // table. + unset($data['display'], $data['widget']); db_update('field_config_instance') ->condition('id', $record->id) ->fields(array( @@ -302,8 +320,26 @@ function field_update_8002() { $variables = array_map('unserialize', db_query("SELECT name, value FROM {variable} WHERE name LIKE '%field_bundle_settings_%'")->fetchAllKeyed()); foreach ($variables as $variable_name => $variable_value) { if (preg_match('/field_bundle_settings_(.*)__(.*)/', $variable_name, $matches)) { + $variable_needs_update = FALSE; $entity_type = $matches[1]; $bundle = $matches[2]; + + if (isset($variable_value['extra_fields']['form'])) { + foreach ($variable_value['extra_fields']['form'] as $field_name => $field_settings) { + // Determine name and create initial entry in the $form_displays + // array if it does not exist yet. + $form_display_id = $entity_type . '.' . $bundle . '.default'; + if (!isset($form_displays[$form_display_id])) { + $form_displays[$form_display_id] = _update_8000_entity_get_form_display($entity_type, $bundle, 'default'); + } + $form_displays[$form_display_id]->set("content.$field_name", $field_settings); + } + + // Remove the old entry. + unset($variable_value['extra_fields']['form']); + $variable_needs_update = TRUE; + } + if (isset($variable_value['extra_fields']['display'])) { foreach ($variable_value['extra_fields']['display'] as $field_name => $field_settings) { foreach ($field_settings as $view_mode => $display_options) { @@ -322,16 +358,26 @@ function field_update_8002() { $new_options['weight'] = $display_options['weight']; } $displays[$display_id]->set("content.$field_name", $new_options); - - // Remove the old entry. - unset($variable_value['extra_fields']['display']); - variable_set($variable_name, $variable_value); } } + + // Remove the old entry. + unset($variable_value['extra_fields']['display']); + $variable_needs_update = TRUE; + } + + if ($variable_needs_update) { + variable_set($variable_name, $variable_value); } } } + // Save the form displays to configuration. + foreach ($form_displays as $config) { + $config->save(); + } + update_config_manifest_add('entity.form_display', array_keys($form_displays)); + // Save the displays to configuration. foreach ($displays as $config) { $config->save(); @@ -437,7 +483,6 @@ function field_update_8003() { 'default_value' => isset($record['data']['default_value']) ? $record['data']['default_value'] : array(), 'default_value_function' => isset($record['data']['default_value_function']) ? $record['data']['default_value_function'] : '', 'settings' => $record['data']['settings'], - 'widget' => $record['data']['widget'], 'status' => 1, 'langcode' => 'und', ); diff --git a/core/modules/field/field.module b/core/modules/field/field.module index 8f459a3..dfcc39d 100644 --- a/core/modules/field/field.module +++ b/core/modules/field/field.module @@ -603,10 +603,6 @@ function field_bundle_settings($entity_type, $bundle, $settings = NULL) { $settings = variable_get('field_bundle_settings_' . $entity_type . '__' . $bundle, array()); $settings += array( 'view_modes' => array(), - 'extra_fields' => array(), - ); - $settings['extra_fields'] += array( - 'form' => array(), ); return $settings; @@ -649,23 +645,6 @@ function field_view_mode_settings($entity_type, $bundle) { } /** - * Pre-render callback: Adjusts weights and visibility of non-field elements. - */ -function _field_extra_fields_pre_render($elements) { - $entity_type = $elements['#entity_type']; - $bundle = $elements['#bundle']; - - $extra_fields = field_info_extra_fields($entity_type, $bundle, 'form'); - foreach ($extra_fields as $name => $settings) { - if (isset($elements[$name])) { - $elements[$name]['#weight'] = $settings['weight']; - } - } - - return $elements; -} - -/** * Clears the field info and field data caches. */ function field_cache_clear() { diff --git a/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php index 4c66575..176641f 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php @@ -171,24 +171,6 @@ class FieldInstance extends ConfigEntityBase implements \ArrayAccess, \Serializa public $default_value_function = ''; /** - * The widget definition. - * - * An array of key/value pairs identifying the Form API input widget for - * the field when used by this bundle. - * - type: (string) The plugin ID of the widget, such as text_textfield. - * - settings: (array) A sub-array of key/value pairs of settings. The keys - * and default values are defined by the widget plugin in the 'settings' - * entry of its "plugin definition" (typycally plugin class annotations). - * - weight: (float) The weight of the widget relative to the other - * elements in entity edit forms. - * - module: (string, read-only) The name of the module that provides the - * widget plugin. - * - * @var array - */ - public $widget = array(); - - /** * Flag indicating whether the instance is deleted. * * The delete() method marks the instance as "deleted" and removes the @@ -211,13 +193,6 @@ class FieldInstance extends ConfigEntityBase implements \ArrayAccess, \Serializa protected $field; /** - * The widget plugin used for this instance. - * - * @var \Drupal\field\Plugin\Type\Widget\WidgetInterface - */ - protected $widgetPlugin; - - /** * Flag indicating whether the bundle name can be renamed or not. * * @var bool @@ -301,7 +276,6 @@ public function getExportProperties() { 'default_value', 'default_value_function', 'settings', - 'widget', ); $properties = array(); foreach ($names as $name) { @@ -366,22 +340,6 @@ public function save() { // Set the default instance settings. $this->settings += $field_type_info['instance_settings']; - // Set the default widget and settings. - $this->widget += array( - 'type' => $field_type_info['default_widget'], - 'settings' => array(), - ); - // Get the widget module and settings from the widget type. - if ($widget_type_info = \Drupal::service('plugin.manager.field.widget')->getDefinition($this->widget['type'])) { - $this->widget['module'] = $widget_type_info['module']; - $this->widget['settings'] += $widget_type_info['settings']; - } - // If no weight is specified, make sure the field sinks to the bottom. - if (!isset($this->widget['weight'])) { - $max_weight = field_info_max_weight($this->entity_type, $this->bundle, 'form'); - $this->widget['weight'] = isset($max_weight) ? $max_weight + 1 : 0; - } - // Save the configuration. $result = parent::save(); field_cache_clear(); @@ -429,6 +387,11 @@ public function delete($field_cleanup = TRUE) { // hook_field_delete_instance(). $module_handler->invokeAll('field_delete_instance', array($this)); + // Remove the instance from the entity form displays. + if ($form_display = entity_load('entity_form_display', $this->entity_type . '.' . $this->bundle . '.default')) { + $form_display->removeComponent($this->field->id)->save(); + } + // Delete the field itself if we just deleted its last instance. if ($field_cleanup && count($this->field->getBundles()) == 0) { $this->field->delete(); @@ -447,39 +410,6 @@ public function getField() { } /** - * Returns the Widget plugin for the instance. - * - * @return Drupal\field\Plugin\Type\Widget\WidgetInterface - * The Widget plugin to be used for the instance. - */ - public function getWidget() { - if (empty($this->widgetPlugin)) { - $widget_properties = $this->widget; - - // Let modules alter the widget properties. - $context = array( - 'entity_type' => $this->entity_type, - 'bundle' => $this->bundle, - 'field' => $this->field, - 'instance' => $this, - ); - // Invoke hook_field_widget_properties_alter() and - // hook_field_widget_properties_ENTITY_TYPE_alter(). - drupal_alter(array('field_widget_properties', 'field_widget_properties_' . $this->entity_type), $widget_properties, $context); - - $options = array( - 'instance' => $this, - 'type' => $widget_properties['type'], - 'settings' => $widget_properties['settings'], - 'weight' => $widget_properties['weight'], - ); - $this->widgetPlugin = \Drupal::service('plugin.manager.field.widget')->getInstance($options); - } - - return $this->widgetPlugin; - } - - /** * Allows a bundle to be renamed. * * Renaming a bundle on the instance is allowed when an entity's bundle diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php index 64c83a2..89c212a 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php @@ -39,13 +39,6 @@ protected $settings; /** - * The widget weight. - * - * @var int - */ - protected $weight; - - /** * Constructs a WidgetBase object. * * @param array $plugin_id @@ -56,16 +49,13 @@ * The field instance to which the widget is associated. * @param array $settings * The widget settings. - * @param int $weight - * The widget weight. */ - public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, array $settings, $weight) { + public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, array $settings) { parent::__construct(array(), $plugin_id, $plugin_definition); $this->instance = $instance; $this->field = field_info_field($instance['field_name']); $this->settings = $settings; - $this->weight = $weight; } /** @@ -140,7 +130,6 @@ public function form(EntityInterface $entity, $langcode, array $items, array &$f 'field-widget-' . drupal_html_class($this->getPluginId()), ), ), - '#weight' => $this->weight, ); // Populate the 'array_parents' information in $form_state['field'] after diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetFactory.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetFactory.php index 392ef5e..9b14e85 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetFactory.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetFactory.php @@ -20,6 +20,6 @@ class WidgetFactory extends DefaultFactory { public function createInstance($plugin_id, array $configuration) { $plugin_definition = $this->discovery->getDefinition($plugin_id); $plugin_class = static::getPluginClass($plugin_id, $plugin_definition); - return new $plugin_class($plugin_id, $plugin_definition, $configuration['instance'], $configuration['settings'], $configuration['weight']); + return new $plugin_class($plugin_id, $plugin_definition, $configuration['instance'], $configuration['settings']); } } diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php index 6cbad1f..d412a0d 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php @@ -45,30 +45,79 @@ public function __construct(\Traversable $namespaces) { } /** - * Overrides Drupal\Component\Plugin\PluginManagerBase::getInstance(). + * Overrides PluginManagerBase::getInstance(). + * + * @param array $options + * An array with the following key/value pairs: + * - instance: (FieldInstance) The field instance. + * - form_mode: (string) The form mode. + * - prepare: (bool, optional) Whether default values should get merged in + * the 'configuration' array. Defaults to TRUE. + * - configuration: (array) the configuration for the widget. The + * following key value pairs are allowed, and are all optional if + * 'prepare' is TRUE: + * - type: (string) The widget to use. Defaults to the + * 'default_widget' for the field type, specified in + * hook_field_info(). The default widget will also be used if the + * requested widget is not available. + * - settings: (array) Settings specific to the widget. Each setting + * defaults to the default value specified in the widget definition. + * + * @return \Drupal\field\Plugin\Type\Widget\WidgetInterface + * A Widget object. */ public function getInstance(array $options) { + $configuration = $options['configuration']; $instance = $options['instance']; - $type = $options['type']; - - $definition = $this->getDefinition($type); $field = field_info_field($instance['field_name']); + // Fill in default configuration if needed. + if (!isset($options['prepare']) || $options['prepare'] == TRUE) { + $configuration = $this->prepareConfiguration($field['type'], $configuration); + } + + $plugin_id = $configuration['type']; + // Switch back to default widget if either: // - $type_info doesn't exist (the widget type is unknown), // - the field type is not allowed for the widget. + $definition = $this->getDefinition($configuration['type']); if (!isset($definition['class']) || !in_array($field['type'], $definition['field_types'])) { // Grab the default widget for the field type. $field_type_definition = field_info_field_types($field['type']); - $type = $field_type_definition['default_widget']; + $plugin_id = $field_type_definition['default_widget']; } - $configuration = array( + $configuration += array( 'instance' => $instance, - 'settings' => $options['settings'], - 'weight' => $options['weight'], ); - return $this->createInstance($type, $configuration); + return $this->createInstance($plugin_id, $configuration); } + /** + * Merges default values for widget configuration. + * + * @param string $field_type + * The field type. + * @param array $configuration + * An array of widget configuration. + * + * @return array + * The display properties with defaults added. + */ + public function prepareConfiguration($field_type, array $configuration) { + // Fill in defaults for missing properties. + $configuration += array( + 'settings' => array(), + ); + // If no widget is specified, use the default widget. + if (!isset($configuration['type'])) { + $field_type = field_info_field_types($field_type); + $configuration['type'] = $field_type['default_widget']; + } + // Fill in default settings values for the widget. + $configuration['settings'] += field_info_widget_settings($configuration['type']); + + return $configuration; + } } diff --git a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php index 2e91a31..83a07eb 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php +++ b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php @@ -432,20 +432,8 @@ function fakeFieldInstance($formatter, $formatter_settings) { 'entity_type' => 'views_fake', 'bundle' => 'views_fake', - // Use the default field settings for settings and widget. + // Use the default field settings. 'settings' => field_info_instance_settings($field['type']), - 'widget' => array( - 'type' => $field_type['default_widget'], - 'settings' => array(), - ), - - // Build a dummy display mode. - 'display' => array( - '_custom' => array( - 'type' => $formatter, - 'settings' => $formatter_settings, - ), - ), // Set the other fields to their default values. 'required' => FALSE, diff --git a/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php b/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php index ca414bc..7ff4ff9 100644 --- a/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php @@ -117,9 +117,6 @@ function setUp() { 'field_name' => $field['field_name'], 'entity_type' => $this->entity_type, 'bundle' => $bundle, - 'widget' => array( - 'type' => 'test_field_widget', - ) ); $this->instances[] = field_create_instance($instance); } diff --git a/core/modules/field/lib/Drupal/field/Tests/CrudTest.php b/core/modules/field/lib/Drupal/field/Tests/CrudTest.php index 9ee6019..fe141d0 100644 --- a/core/modules/field/lib/Drupal/field/Tests/CrudTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/CrudTest.php @@ -284,9 +284,6 @@ function testDeleteField() { 'field_name' => $this->field['field_name'], 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', - 'widget' => array( - 'type' => 'test_field_widget', - ), ); field_create_instance($this->instance_definition); $this->another_instance_definition = $this->instance_definition; diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php index 86f1f34..b63d48d 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php @@ -46,9 +46,6 @@ function setUp() { 'field_name' => $this->field['field_name'], 'entity_type' => 'node', 'bundle' => $this->content_type, - 'widget' => array( - 'type' => 'text_textfield', - ), ); field_create_instance($this->instance); diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php index 1ec87cf..4bc03be 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php @@ -437,6 +437,7 @@ function testFieldAttachForm() { // When generating form for all fields. $form = array(); $form_state = form_state_defaults(); + $form_state['form_display'] = entity_get_form_display($entity_type, $this->instance['bundle'], 'default'); field_attach_form($entity, $form, $form_state); $this->assertEqual($form[$this->field_name][$langcode]['#title'], $this->instance['label'], "First field's form title is {$this->instance['label']}"); @@ -454,6 +455,7 @@ function testFieldAttachForm() { $options = array('field_name' => $this->field_name_2); $form = array(); $form_state = form_state_defaults(); + $form_state['form_display'] = entity_get_form_display($entity_type, $this->instance['bundle'], 'default'); field_attach_form($entity, $form, $form_state, NULL, $options); $this->assertFalse(isset($form[$this->field_name]), 'The first field does not exist in the form'); @@ -477,6 +479,7 @@ function testFieldAttachExtractFormValues() { // Build the form for all fields. $form = array(); $form_state = form_state_defaults(); + $form_state['form_display'] = entity_get_form_display($entity_type, $this->instance['bundle'], 'default'); field_attach_form($entity_init, $form, $form_state); // Simulate incoming values. diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php index 38499c8..b9e87c7 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php @@ -495,11 +495,7 @@ function testEntityDeleteBundle() { 'label' => $this->randomName() . '_label', 'description' => $this->randomName() . '_description', 'weight' => mt_rand(0, 127), - // test_field has no instance settings - 'widget' => array( - 'type' => 'test_field_widget', - 'settings' => array( - 'size' => mt_rand(0, 255)))); + ); field_create_instance($instance); // Save an entity with data for both fields diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php index 122d14c..dd093d5 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php @@ -79,11 +79,7 @@ function testFieldInfo() { 'label' => $this->randomName(), 'description' => $this->randomName(), 'weight' => mt_rand(0, 127), - // test_field has no instance settings - 'widget' => array( - 'type' => 'test_field_widget', - 'settings' => array( - 'test_setting' => 999))); + ); field_create_instance($instance); $info = entity_get_info('test_entity'); @@ -181,12 +177,6 @@ function testInstancePrepare() { // Check that all expected instance settings are in place. $field_type = field_info_field_types($field_definition['type']); $this->assertEqual($instance['settings'], $field_type['instance_settings'] , 'All expected instance settings are present.'); - - // Check that the default widget is used and expected settings are in place. - $widget = $instance->getWidget(); - $this->assertIdentical($widget->getPluginId(), $field_type['default_widget'], 'Unavailable widget replaced with default widget.'); - $widget_type = $widget->getDefinition(); - $this->assertIdentical($widget->getSettings(), $widget_type['settings'] , 'All expected widget settings are present.'); } /** diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php index 2455a31..5f9578a 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php @@ -55,17 +55,14 @@ function testCreateFieldInstance() { $config = \Drupal::config('field.instance.' . $instance->id())->get(); $field_type = field_info_field_types($this->field['type']); - $widget_type = field_info_widget_types($field_type['default_widget']); // Check that default values are set. $this->assertEqual($config['required'], FALSE, 'Required defaults to false.'); $this->assertIdentical($config['label'], $this->instance_definition['field_name'], 'Label defaults to field name.'); $this->assertIdentical($config['description'], '', 'Description defaults to empty string.'); - $this->assertIdentical($config['widget']['type'], $field_type['default_widget'], 'Default widget has been written.'); // Check that default settings are set. $this->assertEqual($config['settings'], $field_type['instance_settings'] , 'Default instance settings have been written.'); - $this->assertIdentical($config['widget']['settings'], $widget_type['settings'] , 'Default widget settings have been written.'); // Guarantee that the field/bundle combination is unique. try { @@ -147,26 +144,12 @@ function testUpdateFieldInstance() { $instance['label'] = $this->randomName(); $instance['description'] = $this->randomName(); $instance['settings']['test_instance_setting'] = $this->randomName(); - $instance['widget']['settings']['test_widget_setting'] =$this->randomName(); - $instance['widget']['weight']++; field_update_instance($instance); $instance_new = field_read_instance('test_entity', $this->instance_definition['field_name'], $this->instance_definition['bundle']); $this->assertEqual($instance['required'], $instance_new['required'], '"required" change is saved'); $this->assertEqual($instance['label'], $instance_new['label'], '"label" change is saved'); $this->assertEqual($instance['description'], $instance_new['description'], '"description" change is saved'); - $this->assertEqual($instance['widget']['settings']['test_widget_setting'], $instance_new['widget']['settings']['test_widget_setting'], 'Widget setting change is saved'); - $this->assertEqual($instance['widget']['weight'], $instance_new['widget']['weight'], 'Widget weight change is saved'); - - // Check that changing the widget type updates the default settings. - $instance = field_read_instance('test_entity', $this->instance_definition['field_name'], $this->instance_definition['bundle']); - $instance['widget']['type'] = 'test_field_widget_multiple'; - field_update_instance($instance); - - $instance_new = field_read_instance('test_entity', $this->instance_definition['field_name'], $this->instance_definition['bundle']); - $this->assertEqual($instance['widget']['type'], $instance_new['widget']['type'] , 'Widget type change is saved.'); - $settings = field_info_widget_settings($instance_new['widget']['type']); - $this->assertIdentical($settings, array_intersect_key($instance_new['widget']['settings'], $settings) , 'Widget type change updates default settings.'); // TODO: test failures. } diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldUnitTestBase.php b/core/modules/field/lib/Drupal/field/Tests/FieldUnitTestBase.php index 223e0ac..7b1b9b1 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FieldUnitTestBase.php +++ b/core/modules/field/lib/Drupal/field/Tests/FieldUnitTestBase.php @@ -69,15 +69,17 @@ function createFieldWithInstance($suffix = '') { 'settings' => array( 'test_instance_setting' => $this->randomName(), ), - 'widget' => array( + ); + field_create_instance($this->$instance); + + entity_get_form_display('test_entity', 'test_bundle', 'default') + ->setComponent($this->$field_name, array( 'type' => 'test_field_widget', - 'label' => 'Test Field', 'settings' => array( 'test_widget_setting' => $this->randomName(), ) - ) - ); - field_create_instance($this->$instance); + )) + ->save(); } /** diff --git a/core/modules/field/lib/Drupal/field/Tests/FormTest.php b/core/modules/field/lib/Drupal/field/Tests/FormTest.php index b0a830d..0f42718 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FormTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/FormTest.php @@ -43,13 +43,6 @@ function setUp() { 'settings' => array( 'test_instance_setting' => $this->randomName(), ), - 'widget' => array( - 'type' => 'test_field_widget', - 'label' => 'Test Field', - 'settings' => array( - 'test_widget_setting' => $this->randomName(), - ) - ) ); } @@ -59,6 +52,9 @@ function testFieldFormSingle() { $this->instance['field_name'] = $this->field_name; field_create_field($this->field); field_create_instance($this->instance); + entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default') + ->setComponent($this->field_name) + ->save(); $langcode = LANGUAGE_NOT_SPECIFIED; // Display creation form. @@ -125,6 +121,9 @@ function testFieldFormDefaultValue() { $this->instance['default_value'] = array(array('value' => $default)); field_create_field($this->field); field_create_instance($this->instance); + entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default') + ->setComponent($this->field_name) + ->save(); $langcode = LANGUAGE_NOT_SPECIFIED; // Display creation form. @@ -149,6 +148,9 @@ function testFieldFormSingleRequired() { $this->instance['required'] = TRUE; field_create_field($this->field); field_create_instance($this->instance); + entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default') + ->setComponent($this->field_name) + ->save(); $langcode = LANGUAGE_NOT_SPECIFIED; // Submit with missing required value. @@ -187,6 +189,9 @@ function testFieldFormUnlimited() { $this->instance['field_name'] = $this->field_name; field_create_field($this->field); field_create_instance($this->instance); + entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default') + ->setComponent($this->field_name) + ->save(); $langcode = LANGUAGE_NOT_SPECIFIED; // Display creation form -> 1 widget. @@ -267,6 +272,9 @@ function testFieldFormMultivalueWithRequiredRadio() { $this->instance['field_name'] = $this->field_name; field_create_field($this->field); field_create_instance($this->instance); + entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default') + ->setComponent($this->field_name) + ->save(); $langcode = LANGUAGE_NOT_SPECIFIED; // Add a required radio field. @@ -282,11 +290,13 @@ function testFieldFormMultivalueWithRequiredRadio() { 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', 'required' => TRUE, - 'widget' => array( - 'type' => 'options_buttons', - ), ); field_create_instance($instance); + entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default') + ->setComponent($instance['field_name'], array( + 'type' => 'options_buttons', + )) + ->save(); // Display creation form. $this->drupalGet('test-entity/add/test_bundle'); @@ -309,6 +319,9 @@ function testFieldFormJSAddMore() { $this->instance['field_name'] = $this->field_name; field_create_field($this->field); field_create_instance($this->instance); + entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default') + ->setComponent($this->field_name) + ->save(); $langcode = LANGUAGE_NOT_SPECIFIED; // Display creation form -> 1 widget. @@ -366,9 +379,13 @@ function testFieldFormMultipleWidget() { $this->field = $this->field_multiple; $this->field_name = $this->field['field_name']; $this->instance['field_name'] = $this->field_name; - $this->instance['widget']['type'] = 'test_field_widget_multiple'; field_create_field($this->field); field_create_instance($this->instance); + entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default') + ->setComponent($this->field_name, array( + 'type' => 'test_field_widget_multiple', + )) + ->save(); $langcode = LANGUAGE_NOT_SPECIFIED; // Display creation form. @@ -408,6 +425,9 @@ function testFieldFormAccess() { $instance['field_name'] = $field_name; field_create_field($field); field_create_instance($instance); + entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default') + ->setComponent($field_name) + ->save(); // Create a field with no edit access - see field_test_field_access(). $field_no_access = array( @@ -423,6 +443,9 @@ function testFieldFormAccess() { ); field_create_field($field_no_access); field_create_instance($instance_no_access); + entity_get_form_display($instance_no_access['entity_type'], $instance_no_access['bundle'], 'default') + ->setComponent($field_name_no_access) + ->save(); $langcode = LANGUAGE_NOT_SPECIFIED; @@ -433,6 +456,7 @@ function testFieldFormAccess() { $form = array(); $form_state = form_state_defaults(); + $form_state['form_display'] = entity_get_form_display($entity_type, $this->instance['bundle']); field_attach_form($entity, $form, $form_state); $this->assertEqual($form[$field_name_no_access][$langcode][0]['value']['#entity_type'], $entity_type, 'The correct entity type is set in the field structure.'); @@ -479,9 +503,15 @@ function testNestedFieldForm() { $this->instance['field_name'] = 'field_single'; $this->instance['label'] = 'Single field'; field_create_instance($this->instance); + entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default') + ->setComponent($this->instance['field_name']) + ->save(); $this->instance['field_name'] = 'field_unlimited'; $this->instance['label'] = 'Unlimited field'; field_create_instance($this->instance); + entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default') + ->setComponent($this->instance['field_name']) + ->save(); // Create two entities. $entity_1 = field_test_create_entity(1, 1); @@ -585,10 +615,14 @@ function testFieldFormHiddenWidget() { $this->field = $this->field_single; $this->field_name = $this->field['field_name']; $this->instance['field_name'] = $this->field_name; - $this->instance['widget']['type'] = 'hidden'; $this->instance['default_value'] = array(0 => array('value' => 99)); field_create_field($this->field); field_create_instance($this->instance); + entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default') + ->setComponent($this->instance['field_name'], array( + 'type' => 'hidden', + )) + ->save(); $langcode = LANGUAGE_NOT_SPECIFIED; // Display the entity creation form. @@ -607,8 +641,12 @@ function testFieldFormHiddenWidget() { // Update the instance to remove the default value and switch to the // default widget. $this->instance['default_value'] = NULL; - $this->instance['widget']['type'] = 'test_field_widget'; field_update_instance($this->instance); + entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default') + ->setComponent($this->instance['field_name'], array( + 'type' => 'test_field_widget', + )) + ->save(); // Display edit form. $this->drupalGet('test-entity/manage/' . $id . '/edit'); @@ -623,9 +661,12 @@ function testFieldFormHiddenWidget() { $entity = field_test_entity_test_load($id); $this->assertEqual($entity->{$this->field_name}[$langcode][0]['value'], $value, 'Field value was updated'); - // Update the instance and switch to the Hidden widget again. - $this->instance['widget']['type'] = 'hidden'; - field_update_instance($this->instance); + // Update the form display and switch to the Hidden widget again. + entity_get_form_display($this->instance['entity_type'], $this->instance['bundle'], 'default') + ->setComponent($this->instance['field_name'], array( + 'type' => 'hidden', + )) + ->save(); // Create a new revision. $edit = array('revision' => TRUE); diff --git a/core/modules/field/lib/Drupal/field/Tests/ShapeItemTest.php b/core/modules/field/lib/Drupal/field/Tests/ShapeItemTest.php index 2628256..4e92d7e 100644 --- a/core/modules/field/lib/Drupal/field/Tests/ShapeItemTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/ShapeItemTest.php @@ -43,9 +43,6 @@ public function setUp() { 'entity_type' => 'entity_test', 'field_name' => 'field_shape', 'bundle' => 'entity_test', - 'widget' => array( - 'type' => 'test_field_widget', - ), ); field_create_instance($this->instance); } diff --git a/core/modules/field/lib/Drupal/field/Tests/TestItemTest.php b/core/modules/field/lib/Drupal/field/Tests/TestItemTest.php index 198be2a..c8ff8fa 100644 --- a/core/modules/field/lib/Drupal/field/Tests/TestItemTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/TestItemTest.php @@ -43,9 +43,6 @@ public function setUp() { 'entity_type' => 'entity_test', 'field_name' => 'field_test', 'bundle' => 'entity_test', - 'widget' => array( - 'type' => 'test_field_widget', - ), ); field_create_instance($this->instance); } diff --git a/core/modules/field/lib/Drupal/field/Tests/TranslationWebTest.php b/core/modules/field/lib/Drupal/field/Tests/TranslationWebTest.php index 40447f1..a32cc81 100644 --- a/core/modules/field/lib/Drupal/field/Tests/TranslationWebTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/TranslationWebTest.php @@ -53,6 +53,10 @@ function setUp() { field_create_instance($instance); $this->instance = field_read_instance('test_entity', $this->field_name, 'test_bundle'); + entity_get_form_display($this->entity_type, 'test_bundle', 'default') + ->setComponent($this->field_name) + ->save(); + for ($i = 0; $i < 3; ++$i) { $language = new Language(array( 'langcode' => 'l' . $i, diff --git a/core/modules/field/tests/modules/field_test/field_test.entity.inc b/core/modules/field/tests/modules/field_test/field_test.entity.inc index d5b5e57..ac0905c 100644 --- a/core/modules/field/tests/modules/field_test/field_test.entity.inc +++ b/core/modules/field/tests/modules/field_test/field_test.entity.inc @@ -227,6 +227,7 @@ function field_test_entity_nested_form($form, &$form_state, $entity_1, $entity_2 '#value' => $entity_1->$key, ); } + $form_state['form_display'] = entity_get_form_display($entity_1->entityType(), $entity_1->bundle(), 'default'); field_attach_form($entity_1, $form, $form_state); // Second entity. @@ -243,6 +244,7 @@ function field_test_entity_nested_form($form, &$form_state, $entity_1, $entity_2 '#value' => $entity_2->$key, ); } + $form_state['form_display'] = entity_get_form_display($entity_1->entityType(), $entity_1->bundle(), 'default'); field_attach_form($entity_2, $form['entity_2'], $form_state); $form['save'] = array( diff --git a/core/modules/field/tests/modules/field_test/field_test.module b/core/modules/field/tests/modules/field_test/field_test.module index 4ecd1a9..b715224 100644 --- a/core/modules/field/tests/modules/field_test/field_test.module +++ b/core/modules/field/tests/modules/field_test/field_test.module @@ -196,36 +196,18 @@ function field_test_field_attach_view_alter(&$output, $context) { } /** - * Implements hook_field_widget_properties_alter(). - */ -function field_test_field_widget_properties_alter(&$widget, $context) { - // Make the alter_test_text field 42 characters for nodes and comments. - if (in_array($context['entity_type'], array('node', 'comment')) && ($context['field']['field_name'] == 'alter_test_text')) { - $widget['settings']['size'] = 42; - } -} - -/** - * Implements hook_field_widget_properties_ENTITY_TYPE_alter(). - */ -function field_test_field_widget_properties_user_alter(&$widget, $context) { - // Always use buttons for the alter_test_options field on user forms. - if ($context['field']['field_name'] == 'alter_test_options') { - $widget['type'] = 'options_buttons'; - } -} - -/** * Implements hook_field_widget_form_alter(). */ function field_test_field_widget_form_alter(&$element, &$form_state, $context) { + $instance = $context['instance']; + $entity_form_display = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default'); switch ($context['field']['field_name']) { case 'alter_test_text': - drupal_set_message('Field size: ' . $context['instance']->getWidget()->getSetting('size')); + drupal_set_message('Field size: ' . $entity_form_display->getWidget($context['field']['field_name'])->getSetting('size')); break; case 'alter_test_options': - drupal_set_message('Widget type: ' . $context['instance']->getWidget()->getPluginId()); + drupal_set_message('Widget type: ' . $entity_form_display->getWidget($context['field']['field_name'])->getPluginId()); break; } // Set a message if this is for the form displayed to set default value for diff --git a/core/modules/field/tests/modules/field_test_config/config/field.instance.test_entity.test_bundle.field_test_import.yml b/core/modules/field/tests/modules/field_test_config/config/field.instance.test_entity.test_bundle.field_test_import.yml index 4817a77..a179a55 100644 --- a/core/modules/field/tests/modules/field_test_config/config/field.instance.test_entity.test_bundle.field_test_import.yml +++ b/core/modules/field/tests/modules/field_test_config/config/field.instance.test_entity.test_bundle.field_test_import.yml @@ -11,10 +11,4 @@ default_value_function: '' settings: text_processing: '0' user_register_form: false -widget: - weight: '-2' - type: text_textfield - module: text - settings: - size: '60' field_type: text diff --git a/core/modules/field/tests/modules/field_test_config/staging/field.instance.test_entity.test_bundle.field_test_import_staging.yml b/core/modules/field/tests/modules/field_test_config/staging/field.instance.test_entity.test_bundle.field_test_import_staging.yml index 2e4229d..f751ad5 100644 --- a/core/modules/field/tests/modules/field_test_config/staging/field.instance.test_entity.test_bundle.field_test_import_staging.yml +++ b/core/modules/field/tests/modules/field_test_config/staging/field.instance.test_entity.test_bundle.field_test_import_staging.yml @@ -12,10 +12,4 @@ default_value_function: '' settings: text_processing: '0' user_register_form: '0' -widget: - type: text_textfield - weight: '-3' - settings: - size: '60' - module: text field_type: text diff --git a/core/modules/field_ui/field_ui.admin.inc b/core/modules/field_ui/field_ui.admin.inc index 2d7e7ca..715304c 100644 --- a/core/modules/field_ui/field_ui.admin.inc +++ b/core/modules/field_ui/field_ui.admin.inc @@ -5,6 +5,7 @@ * Administrative interface for custom field type creation. */ +use Drupal\Component\Utility\NestedArray; use Drupal\field\Plugin\Core\Entity\FieldInstance; use Drupal\field_ui\FieldOverview; use Drupal\field_ui\DisplayOverview; @@ -472,12 +473,13 @@ function field_ui_existing_field_options($entity_type, $bundle) { && !field_info_instance($entity_type, $field['field_name'], $bundle) && (empty($field['entity_types']) || in_array($entity_type, $field['entity_types'])) && empty($field_types[$field['type']]['no_ui'])) { + $widget = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')->getComponent($instance['field_name']); $info[$instance['field_name']] = array( 'type' => $field['type'], 'type_label' => $field_types[$field['type']]['label'], 'field' => $field['field_name'], 'label' => $instance['label'], - 'widget_type' => $instance['widget']['type'], + 'widget_type' => $widget['type'], ); } } @@ -547,7 +549,7 @@ function field_ui_field_settings_form($form, &$form_state, $instance) { ), ), ); - if (field_behaviors_widget('multiple values', $instance) == FIELD_BEHAVIOR_DEFAULT) { + 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'), @@ -642,6 +644,7 @@ function field_ui_widget_type_form($form, &$form_state, FieldInstance $instance) $entity_type = $instance['entity_type']; $field_name = $instance['field_name']; + $entity_form_display = entity_get_form_display($entity_type, $bundle, 'default'); $field = field_info_field($field_name); $bundles = entity_get_bundles(); $bundle_label = $bundles[$entity_type][$bundle]['label']; @@ -650,6 +653,7 @@ function field_ui_widget_type_form($form, &$form_state, FieldInstance $instance) '#bundle' => $bundle, '#entity_type' => $entity_type, '#field_name' => $field_name, + '#instance' => $instance, ); $form['widget_type'] = array( @@ -657,7 +661,7 @@ function field_ui_widget_type_form($form, &$form_state, FieldInstance $instance) '#title' => t('Widget type'), '#required' => TRUE, '#options' => field_ui_widget_type_options($field['type']), - '#default_value' => $instance->getWidget()->getPluginId(), + '#default_value' => $entity_form_display->getWidget($field_name)->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)), ); @@ -678,19 +682,15 @@ function field_ui_widget_type_form_submit($form, &$form_state) { $bundle = $form['#bundle']; $entity_type = $form['#entity_type']; $field_name = $form['#field_name']; + $instance = $form['#instance']; - // 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; + $entity_form_display = entity_get_form_display($entity_type, $bundle, 'default') + ->setComponent($field_name, array( + 'type' => $form_values['widget_type'], + )); try { - field_update_instance($instance); + $entity_form_display->save(); 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') { @@ -788,6 +788,7 @@ 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']); + $entity_form_display = entity_get_form_display($entity_type, $bundle, 'default'); $bundles = entity_get_bundles(); drupal_set_title(t('%instance settings for %bundle', array( @@ -797,6 +798,7 @@ function field_ui_field_edit_form($form, &$form_state, $instance) { $form['#field'] = $field; $form['#instance'] = $instance; + $form['#entity_form_display'] = $entity_form_display; // 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); @@ -809,8 +811,6 @@ function field_ui_field_edit_form($form, &$form_state, $instance) { return $form; } - $widget_type = field_info_widget_types($instance['widget']['type']); - // Create a form structure for the instance values. $form['instance'] = array( '#tree' => TRUE, @@ -829,10 +829,6 @@ function field_ui_field_edit_form($form, &$form_state, $instance) { '#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( @@ -859,12 +855,6 @@ function field_ui_field_edit_form($form, &$form_state, $instance) { '#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)) { @@ -873,7 +863,7 @@ function field_ui_field_edit_form($form, &$form_state, $instance) { } // Add widget settings for the widget type. - $additions = $instance->getWidget()->settingsForm($form, $form_state); + $additions = $entity_form_display->getWidget($instance['field_name'])->settingsForm($form, $form_state); $form['instance']['widget']['settings'] = $additions ? $additions : array('#type' => 'value', '#value' => array()); $form['instance']['widget']['#weight'] = 20; @@ -912,8 +902,8 @@ function field_ui_field_edit_form_delete_submit($form, &$form_state) { * 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']; + $entity_form_display = $form['#entity_form_display']; $element = array( '#type' => 'details', @@ -950,7 +940,7 @@ function field_ui_default_value_widget($field, $instance, &$form, &$form_state) if (!empty($instance['default_value'])) { $items = (array) $instance['default_value']; } - $element += $instance->getWidget()->form($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state); + $element += $entity_form_display->getWidget($instance['field_name'])->form($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state); return $element; } @@ -966,13 +956,14 @@ function field_ui_field_edit_form_validate($form, &$form_state) { $instance = $form['#instance']; $field_name = $instance['field_name']; $entity = $form['#entity']; + $entity_form_display = $form['#entity_form_display']; 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); + $entity_form_display->getWidget($instance['field_name'])->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); @@ -992,7 +983,7 @@ function field_ui_field_edit_form_validate($form, &$form_state) { 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); + $entity_form_display->getWidget($instance['field_name'])->flagErrors($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state); } } } @@ -1004,8 +995,8 @@ function field_ui_field_edit_form_validate($form, &$form_state) { */ function field_ui_field_edit_form_submit($form, &$form_state) { $instance = $form['#instance']; - $field = $form['#field']; $entity = $form['#entity']; + $entity_form_display = $form['#entity_form_display']; // Handle the default value. if (isset($form['instance']['default_value_widget'])) { @@ -1013,11 +1004,17 @@ function field_ui_field_edit_form_submit($form, &$form_state) { // Extract field values. $items = array(); - $instance->getWidget()->extractFormValues($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state); + $entity_form_display->getWidget($instance['field_name'])->extractFormValues($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state); $instance['default_value'] = $items ? $items : NULL; } + // Handle widget settings. + $options = $entity_form_display->getComponent($instance['field_name']); + $options['settings'] = $form_state['values']['instance']['widget']['settings']; + $entity_form_display->setComponent($instance['field_name'], $options)->save(); + unset($form_state['values']['instance']['widget']); + // Merge incoming values into the instance. foreach ($form_state['values']['instance'] as $key => $value) { $instance[$key] = $value; 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..4a385b8 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php @@ -46,7 +46,7 @@ public function buildForm(array $form, array &$form_state) { $instances = field_info_instances($this->entity_type, $this->bundle); $field_types = field_info_field_types(); $extra_fields = field_info_extra_fields($this->entity_type, $this->bundle, 'display'); - $entity_display = entity_get_display($this->entity_type, $this->bundle, $this->view_mode); + $entity_display = entity_get_display($this->entity_type, $this->bundle, $this->mode); $form_state += array( 'formatter_settings_edit' => NULL, @@ -55,7 +55,7 @@ public function buildForm(array $form, array &$form_state) { $form += array( '#entity_type' => $this->entity_type, '#bundle' => $this->bundle, - '#view_mode' => $this->view_mode, + '#view_mode' => $this->mode, '#fields' => array_keys($instances), '#extra' => array_keys($extra_fields), ); @@ -173,7 +173,7 @@ public function buildForm(array $form, array &$form_state) { if ($display_options && $display_options['type'] != 'hidden') { $formatter = drupal_container()->get('plugin.manager.field.formatter')->getInstance(array( 'instance' => $instance, - 'view_mode' => $this->view_mode, + 'view_mode' => $this->mode, 'configuration' => $display_options )); } @@ -206,7 +206,7 @@ public function buildForm(array $form, array &$form_state) { 'formatter' => $formatter, 'field' => $field, 'instance' => $instance, - 'view_mode' => $this->view_mode, + 'view_mode' => $this->mode, 'form' => $form, ); drupal_alter('field_formatter_settings_form', $settings_form, $form_state, $context); @@ -258,7 +258,7 @@ public function buildForm(array $form, array &$form_state) { 'formatter' => $formatter, 'field' => $field, 'instance' => $instance, - 'view_mode' => $this->view_mode, + 'view_mode' => $this->mode, ); drupal_alter('field_formatter_settings_summary', $summary, $context); @@ -342,7 +342,7 @@ public function buildForm(array $form, array &$form_state) { $form['fields'] = $table; // Custom display settings. - if ($this->view_mode == 'default') { + if ($this->mode == 'default') { $view_modes = entity_get_view_modes($this->entity_type); // Only show the settings if there is more than one view mode. if (count($view_modes) > 1) { @@ -411,7 +411,7 @@ public function buildForm(array $form, array &$form_state) { */ public function submitForm(array &$form, array &$form_state) { $form_values = $form_state['values']; - $display = entity_get_display($this->entity_type, $this->bundle, $this->view_mode); + $display = entity_get_display($this->entity_type, $this->bundle, $this->mode); // Collect data for 'regular' fields. foreach ($form['#fields'] as $field_name) { @@ -466,7 +466,7 @@ public function submitForm(array &$form, array &$form_state) { $display->save(); // Handle the 'view modes' checkboxes if present. - if ($this->view_mode == 'default' && !empty($form_values['view_modes_custom'])) { + if ($this->mode == 'default' && !empty($form_values['view_modes_custom'])) { $entity_info = entity_get_info($this->entity_type); $view_modes = entity_get_view_modes($this->entity_type); $bundle_settings = field_bundle_settings($this->entity_type, $this->bundle); 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..75eaae8 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() { @@ -63,6 +53,7 @@ public function buildForm(array $form, array &$form_state) { $field_types = field_info_field_types(); $widget_types = field_info_widget_types(); $extra_fields = field_info_extra_fields($this->entity_type, $this->bundle, 'form'); + $entity_form_display = entity_get_form_display($this->entity_type, $this->bundle, $this->mode); $form += array( '#entity_type' => $this->entity_type, @@ -94,6 +85,7 @@ public function buildForm(array $form, array &$form_state) { // Fields. foreach ($instances as $name => $instance) { $field = field_info_field($instance['field_name']); + $widget_configuration = $entity_form_display->getComponent($instance['field_name']); $admin_field_path = $this->adminPath . '/fields/' . $instance['field_name']; $table[$name] = array( '#attributes' => array('class' => array('draggable', 'tabledrag-leaf')), @@ -106,7 +98,7 @@ public function buildForm(array $form, array &$form_state) { '#type' => 'textfield', '#title' => t('Weight for @title', array('@title' => $instance['label'])), '#title_display' => 'invisible', - '#default_value' => $instance['widget']['weight'], + '#default_value' => $widget_configuration['weight'], '#size' => 3, '#attributes' => array('class' => array('field-weight')), ), @@ -137,7 +129,7 @@ public function buildForm(array $form, array &$form_state) { ), 'widget_type' => array( '#type' => 'link', - '#title' => $widget_types[$instance['widget']['type']]['label'], + '#title' => $widget_types[$widget_configuration['type']]['label'], '#href' => $admin_field_path . '/widget-type', '#options' => array('attributes' => array('title' => t('Change widget type.'))), ), @@ -212,7 +204,7 @@ public function buildForm(array $form, array &$form_state) { } // Additional row: add new field. - $max_weight = field_info_max_weight($this->entity_type, $this->bundle, 'form'); + $max_weight = $entity_form_display->getHighestWeight(); $field_type_options = field_ui_field_type_options(); $widget_type_options = field_ui_widget_type_options(NULL, TRUE); if ($field_type_options && $widget_type_options) { @@ -528,27 +520,29 @@ protected function validateAddExisting(array $form, array &$form_state) { */ public function submitForm(array &$form, array &$form_state) { $form_values = $form_state['values']['fields']; + $entity_form_display = entity_get_form_display($this->entity_type, $this->bundle, $this->mode); - $bundle_settings = field_bundle_settings($this->entity_type, $this->bundle); + // Collect data for 'regular' fields. + foreach ($form['#fields'] as $field_name) { + $options = $entity_form_display->getComponent($field_name); + $options['weight'] = $form_values[$field_name]['weight']; - // Update field weights. - foreach ($form_values as $key => $values) { - if (in_array($key, $form['#fields'])) { - $instance = field_read_instance($this->entity_type, $key, $this->bundle); - $instance['widget']['weight'] = $values['weight']; - field_update_instance($instance); - } - elseif (in_array($key, $form['#extra'])) { - $bundle_settings['extra_fields']['form'][$key]['weight'] = $values['weight']; - } + $entity_form_display->setComponent($field_name, $options); + } + + // Collect data for 'extra' fields. + foreach ($form['#extra'] as $field_name) { + $entity_form_display->setComponent($field_name, array( + 'weight' => $form_values[$field_name]['weight'], + )); } - field_bundle_settings($this->entity_type, $this->bundle, $bundle_settings); + // Save the form display. + $entity_form_display->save(); $destinations = array(); // Create new field. - $field = array(); if (!empty($form_values['_add_new_field']['field_name'])) { $values = $form_values['_add_new_field']; @@ -562,10 +556,6 @@ public function submitForm(array &$form, array &$form_state) { 'entity_type' => $this->entity_type, 'bundle' => $this->bundle, 'label' => $values['label'], - 'widget' => array( - 'type' => $values['widget_type'], - 'weight' => $values['weight'], - ), ); // Create the field and instance. @@ -573,6 +563,15 @@ public function submitForm(array &$form, array &$form_state) { field_create_field($field); field_create_instance($instance); + // Make sure the field is displayed in the 'default' form mode (using + // the configured widget and default settings). + entity_get_form_display($this->entity_type, $this->bundle, 'default') + ->setComponent($field['field_name'], array( + 'type' => $values['widget_type'], + 'weight' => $values['weight'], + )) + ->save(); + // Make sure the field is displayed in the 'default' view mode (using // default formatter and settings). It stays hidden for other view // modes until it is explicitly configured. @@ -588,7 +587,7 @@ public function submitForm(array &$form, array &$form_state) { // Store new field information for any additional submit handlers. $form_state['fields_added']['_add_new_field'] = $field['field_name']; } - catch (Exception $e) { + catch (\Exception $e) { drupal_set_message(t('There was a problem creating field %label: !message', array('%label' => $instance['label'], '!message' => $e->getMessage())), 'error'); } } @@ -606,15 +605,20 @@ public function submitForm(array &$form, array &$form_state) { 'entity_type' => $this->entity_type, 'bundle' => $this->bundle, 'label' => $values['label'], - 'widget' => array( - 'type' => $values['widget_type'], - 'weight' => $values['weight'], - ), ); try { field_create_instance($instance); + // Make sure the field is displayed in the 'default' form mode (using + // the configured widget and default settings). + entity_get_form_display($this->entity_type, $this->bundle, 'default') + ->setComponent($field['field_name'], array( + 'type' => $values['widget_type'], + 'weight' => $values['weight'], + )) + ->save(); + // Make sure the field is displayed in the 'default' view mode (using // default formatter and settings). It stays hidden for other view // modes until it is explicitly configured. @@ -626,7 +630,7 @@ public function submitForm(array &$form, array &$form_state) { // Store new field information for any additional submit handlers. $form_state['fields_added']['_add_existing_field'] = $instance['field_name']; } - catch (Exception $e) { + catch (\Exception $e) { drupal_set_message(t('There was a problem creating field instance %label: @message.', array('%label' => $instance['label'], '@message' => $e->getMessage())), 'error'); } } 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..8410925 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/OverviewBase.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/OverviewBase.php @@ -29,11 +29,11 @@ protected $bundle = ''; /** - * The entity view mode. + * The entity view or form mode. * * @var string */ - protected $view_mode = ''; + protected $mode = ''; /** * The admin path of the overview page. @@ -49,14 +49,14 @@ * 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 + * @param string $mode + * (optional) The view or form mode for the entity which takes a string or * "default". */ - public function __construct($entity_type, $bundle, $view_mode = NULL) { + public function __construct($entity_type, $bundle, $mode = NULL) { $this->entity_type = $entity_type; $this->bundle = $bundle; - $this->view_mode = (isset($view_mode) ? $view_mode : 'default'); + $this->mode = (isset($mode) ? $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/Tests/AlterTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/AlterTest.php deleted file mode 100644 index 016b9d0..0000000 --- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/AlterTest.php +++ /dev/null @@ -1,112 +0,0 @@ - 'Widget customization', - 'description' => 'Test custom field widget hooks and callbacks on field administration pages.', - 'group' => 'Field UI', - ); - } - - function setUp() { - parent::setUp(); - - // Create Article node type. - $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); - $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article')); - - // Create test user. - $admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer node fields', 'administer users', 'administer user fields')); - $this->drupalLogin($admin_user); - } - - /** - * Tests hook_field_widget_properties_alter() on the default field widget. - * - * @see field_test_field_widget_properties_alter() - * @see field_test_field_widget_properties_user_alter() - * @see field_test_field_widget_form_alter() - */ - function testDefaultWidgetPropertiesAlter() { - // Create the alter_test_text field and an instance on article nodes. - field_create_field(array( - 'field_name' => 'alter_test_text', - 'type' => 'text', - )); - $instance = array( - 'field_name' => 'alter_test_text', - 'entity_type' => 'node', - 'bundle' => 'article', - 'widget' => array( - 'type' => 'text_textfield', - 'size' => 60, - ), - ); - field_create_instance($instance); - - // 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->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. - $this->assertText('From hook_field_widget_form_alter(): Default form is true.', 'Default value form detected in hook_field_widget_form_alter().'); - - // Create the alter_test_options field. - field_create_field(array( - 'field_name' => 'alter_test_options', - 'type' => 'list_text' - )); - // Create instances on users and page nodes. - $instance = array( - 'field_name' => 'alter_test_options', - 'entity_type' => 'user', - 'bundle' => 'user', - 'widget' => array( - 'type' => 'options_select', - ) - ); - field_create_instance($instance); - $instance = array( - 'field_name' => 'alter_test_options', - 'entity_type' => 'node', - 'bundle' => 'page', - 'widget' => array( - 'type' => 'options_select', - ) - ); - field_create_instance($instance); - - // 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->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->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..7116b92 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 @@ -52,6 +52,10 @@ function setUp() { 'bundle' => 'article', ); field_create_instance($instance); + + entity_get_form_display('node', 'article', 'default') + ->setComponent('field_' . $vocabulary->id()) + ->save(); } /** @@ -234,7 +238,10 @@ function assertFieldSettings($bundle, $field_name, $string = 'dummy test string' // Assert instance and widget settings. $instance = field_info_instance($entity_type, $field_name, $bundle); $this->assertTrue($instance['settings']['test_instance_setting'] == $string, 'Field instance settings were found.'); - $this->assertTrue($instance['widget']['settings']['test_widget_setting'] == $string, 'Field widget settings were found.'); + + // Assert widget settings. + $widget_configuration = entity_get_form_display($entity_type, $bundle, 'default')->getComponent($field_name); + $this->assertTrue($widget_configuration['settings']['test_widget_setting'] == $string, 'Field widget settings were found.'); } /** @@ -255,6 +262,10 @@ function testDefaultValue() { ); field_create_instance($instance); + entity_get_form_display('node', $this->type, 'default') + ->setComponent($field_name) + ->save(); + $langcode = LANGUAGE_NOT_SPECIFIED; $admin_path = 'admin/structure/types/manage/' . $this->type . '/fields/' . $field_name; $element_id = "edit-$field_name-$langcode-0-value"; @@ -271,6 +282,7 @@ function testDefaultValue() { $edit = array($element_name => '1'); $this->drupalPost($admin_path, $edit, t('Save settings')); $this->assertText("Saved $field_name configuration", 'The form was successfully submitted.'); + field_info_cache_clear(); $instance = field_info_instance('node', $field_name, $this->type); $this->assertEqual($instance['default_value'], array(array('value' => 1)), 'The default value was correctly saved.'); @@ -287,8 +299,11 @@ function testDefaultValue() { $this->assertEqual($instance['default_value'], NULL, 'The default value was correctly saved.'); // Change the widget to TestFieldWidgetNoDefault. - $instance['widget']['type'] = 'test_field_widget_no_default'; - field_update_instance($instance); + entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default') + ->setComponent($field_name, array( + 'type' => 'test_field_widget_no_default', + )) + ->save(); $this->drupalGet($admin_path); $this->assertNoFieldById($element_id, '', t('No default value was possible for widget that disables default value.')); @@ -358,9 +373,11 @@ function testHiddenFields() { 'bundle' => $this->type, 'entity_type' => 'node', 'label' => t('Hidden field'), - 'widget' => array('type' => 'test_field_widget'), ); field_create_instance($instance); + entity_get_form_display('node', $this->type, 'default') + ->setComponent($field_name) + ->save(); $this->assertTrue(field_read_instance('node', $field_name, $this->type), format_string('An instance of the field %field was created programmatically.', array('%field' => $field_name))); // Check that the newly added instance appears on the 'Manage Fields' @@ -416,8 +433,8 @@ function testWidgetChange() { // Check that the field_tags field currently uses the 'options_select' // widget. - $instance = field_info_instance('node', 'field_tags', 'article'); - $this->assertEqual($instance['widget']['type'], 'options_select'); + $entity_form_display = entity_get_form_display('node', 'article', 'default')->getComponent('field_tags'); + $this->assertEqual($entity_form_display['type'], 'options_select'); // Check that the "Manage fields" page shows the correct widget type. $this->drupalGet($url_fields); @@ -441,8 +458,8 @@ function testWidgetChange() { // Check that the field uses the newly set widget. field_cache_clear(); - $instance = field_info_instance('node', 'field_tags', 'article'); - $this->assertEqual($instance['widget']['type'], 'options_buttons'); + $widget_configuration = entity_get_form_display('node', 'article', 'default')->getComponent('field_tags'); + $this->assertEqual($widget_configuration['type'], 'options_buttons'); // Go to the 'Widget type' form and check that the correct widget is // selected. diff --git a/core/modules/file/file.field.inc b/core/modules/file/file.field.inc index de03e50..59d068b 100644 --- a/core/modules/file/file.field.inc +++ b/core/modules/file/file.field.inc @@ -451,7 +451,6 @@ function file_field_widget_process($element, &$form_state, $form) { $field = field_widget_field($element, $form_state); $instance = field_widget_instance($element, $form_state); - $settings = $instance['widget']['settings']; $element['#theme'] = 'file_widget'; diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php index 8cff731..ac2f428 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php +++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php @@ -102,14 +102,16 @@ function attachFileField($name, $entity_type, $bundle, $instance_settings = arra 'bundle' => $bundle, 'required' => !empty($instance_settings['required']), 'settings' => array(), - 'widget' => array( - 'type' => 'file_generic', - 'settings' => array(), - ), ); $instance['settings'] = array_merge($instance['settings'], $instance_settings); - $instance['widget']['settings'] = array_merge($instance['widget']['settings'], $widget_settings); field_create_instance($instance); + + entity_get_form_display($entity_type, $bundle, 'default') + ->setComponent($name, array( + 'type' => 'file_generic', + 'settings' => $widget_settings, + )) + ->save(); } /** @@ -118,9 +120,14 @@ function attachFileField($name, $entity_type, $bundle, $instance_settings = arra function updateFileField($name, $type_name, $instance_settings = array(), $widget_settings = array()) { $instance = field_info_instance('node', $name, $type_name); $instance['settings'] = array_merge($instance['settings'], $instance_settings); - $instance['widget']['settings'] = array_merge($instance['widget']['settings'], $widget_settings); field_update_instance($instance); + + entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default') + ->setComponent($instance['field_name'], array( + 'settings' => $widget_settings, + )) + ->save(); } /** diff --git a/core/modules/forum/forum.install b/core/modules/forum/forum.install index 1bc6915..8d15b06 100644 --- a/core/modules/forum/forum.install +++ b/core/modules/forum/forum.install @@ -84,12 +84,16 @@ function forum_enable() { 'label' => $vocabulary->name, 'bundle' => 'forum', 'required' => TRUE, - 'widget' => array( - 'type' => 'options_select', - ), ); field_create_instance($instance); + // Assign form display settings for the 'default' form mode. + entity_get_form_display('node', 'forum', 'default') + ->setComponent('taxonomy_forums', array( + 'type' => 'options_select', + )) + ->save(); + // Assign display settings for the 'default' and 'teaser' view modes. entity_get_display('node', 'forum', 'default') ->setComponent('taxonomy_forums', array( diff --git a/core/modules/hal/lib/Drupal/hal/Tests/NormalizerTestBase.php b/core/modules/hal/lib/Drupal/hal/Tests/NormalizerTestBase.php index b40bffa..2d73a24 100644 --- a/core/modules/hal/lib/Drupal/hal/Tests/NormalizerTestBase.php +++ b/core/modules/hal/lib/Drupal/hal/Tests/NormalizerTestBase.php @@ -30,7 +30,7 @@ * * @var array */ - public static $modules = array('entity_test', 'entity_reference', 'field', 'field_sql_storage', 'hal', 'language', 'rest', 'serialization', 'system', 'text', 'user'); + public static $modules = array('entity', 'entity_test', 'entity_reference', 'field', 'field_sql_storage', 'hal', 'language', 'rest', 'serialization', 'system', 'text', 'user'); /** * The mock serializer. diff --git a/core/modules/image/lib/Drupal/image/ImageStyleStorageController.php b/core/modules/image/lib/Drupal/image/ImageStyleStorageController.php index 4bbbbde..97766b5 100644 --- a/core/modules/image/lib/Drupal/image/ImageStyleStorageController.php +++ b/core/modules/image/lib/Drupal/image/ImageStyleStorageController.php @@ -76,7 +76,7 @@ protected function replaceImageStyle(ImageStyle $style) { $instances = field_read_instances(); // Loop through all fields searching for image fields. foreach ($instances as $instance) { - if ($instance['widget']['module'] == 'image') { + if ($instance->getField()->type == 'image') { $view_modes = entity_get_view_modes($instance['entity_type']); $view_modes = array('default') + array_keys($view_modes); foreach ($view_modes as $view_mode) { @@ -92,9 +92,12 @@ protected function replaceImageStyle(ImageStyle $style) { ->save(); } } - if ($instance['widget']['settings']['preview_image_style'] == $style->getOriginalID()) { - $instance['widget']['settings']['preview_image_style'] = $style->id(); - field_update_instance($instance); + $entity_form_display = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default'); + $widget_configuration = $entity_form_display->getComponent($instance['field_name']); + if ($widget_configuration['settings']['preview_image_style'] == $style->getOriginalID()) { + $widget_options['settings']['preview_image_style'] = $style->id(); + $entity_form_display->setComponent($instance['field_name'], $widget_options) + ->save(); } } } diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php index a30b7ed..5600b4b 100644 --- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php +++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php @@ -65,10 +65,14 @@ function testDefaultImages() { 'settings' => array( 'default_image' => array($default_images['instance2']->fid), ), - 'widget' => $instance['widget'], ); field_create_instance($instance2); - $instance2 = field_info_instance('node', $field_name, 'page'); + + $widget_settings = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')->getComponent($instance['field_name']); + entity_get_form_display('node', 'page', 'default') + ->setComponent($field['field_name'], $widget_settings) + ->save(); + entity_get_display('node', 'page', 'default') ->setComponent($field['field_name']) ->save(); diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php index 5a4e20e..508c9bc 100644 --- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php +++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php @@ -85,16 +85,17 @@ function createImageField($name, $type_name, $field_settings = array(), $instanc 'required' => !empty($instance_settings['required']), 'description' => !empty($instance_settings['description']) ? $instance_settings['description'] : '', 'settings' => array(), - 'widget' => array( - 'type' => 'image_image', - 'settings' => array(), - ), ); $instance['settings'] = array_merge($instance['settings'], $instance_settings); - $instance['widget']['settings'] = array_merge($instance['widget']['settings'], $widget_settings); - $field_instance = field_create_instance($instance); + entity_get_form_display('node', $type_name, 'default') + ->setComponent($field['field_name'], array( + 'type' => 'image_image', + 'settings' => $widget_settings, + )) + ->save(); + entity_get_display('node', $type_name, 'default') ->setComponent($field['field_name']) ->save(); diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageItemTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageItemTest.php index 7f863cf..709073d 100644 --- a/core/modules/image/lib/Drupal/image/Tests/ImageItemTest.php +++ b/core/modules/image/lib/Drupal/image/Tests/ImageItemTest.php @@ -53,9 +53,6 @@ public function setUp() { 'entity_type' => 'entity_test', 'field_name' => 'image_test', 'bundle' => 'entity_test', - 'widget' => array( - 'type' => 'image_image', - ), ); field_create_instance($instance); file_unmanaged_copy(DRUPAL_ROOT . '/core/misc/druplicon.png', 'public://example.jpg'); diff --git a/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php b/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php index f28bcc2..0a6dc0b 100644 --- a/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php +++ b/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php @@ -56,14 +56,16 @@ function testURLValidation() { 'settings' => array( 'title' => DRUPAL_DISABLED, ), - 'widget' => array( + ); + field_create_instance($this->instance); + entity_get_form_display('test_entity', 'test_bundle', 'default') + ->setComponent($this->field['field_name'], array( 'type' => 'link_default', 'settings' => array( 'placeholder_url' => 'http://example.com', ), - ), - ); - field_create_instance($this->instance); + )) + ->save(); entity_get_display('test_entity', 'test_bundle', 'full') ->setComponent($this->field['field_name'], array( 'type' => 'link', @@ -125,15 +127,17 @@ function testLinkTitle() { 'settings' => array( 'title' => DRUPAL_OPTIONAL, ), - 'widget' => array( + ); + field_create_instance($this->instance); + entity_get_form_display('test_entity', 'test_bundle', 'default') + ->setComponent($this->field['field_name'], array( 'type' => 'link_default', 'settings' => array( 'placeholder_url' => 'http://example.com', 'placeholder_title' => 'Enter a title for this link', ), - ), - ); - field_create_instance($this->instance); + )) + ->save(); entity_get_display('test_entity', 'test_bundle', 'full') ->setComponent($this->field['field_name'], array( 'type' => 'link', @@ -238,15 +242,17 @@ function testLinkFormatter() { 'settings' => array( 'title' => DRUPAL_OPTIONAL, ), - 'widget' => array( - 'type' => 'link_default', - ), ); $display_options = array( 'type' => 'link', 'label' => 'hidden', ); field_create_instance($this->instance); + entity_get_form_display('test_entity', 'test_bundle', 'default') + ->setComponent($this->field['field_name'], array( + 'type' => 'link_default', + )) + ->save(); entity_get_display('test_entity', 'test_bundle', 'full') ->setComponent($this->field['field_name'], $display_options) ->save(); @@ -376,15 +382,17 @@ function testLinkSeparateFormatter() { 'settings' => array( 'title' => DRUPAL_OPTIONAL, ), - 'widget' => array( - 'type' => 'link_default', - ), ); $display_options = array( 'type' => 'link_separate', 'label' => 'hidden', ); field_create_instance($this->instance); + entity_get_form_display('test_entity', 'test_bundle', 'default') + ->setComponent($this->field['field_name'], array( + 'type' => 'link_default', + )) + ->save(); entity_get_display('test_entity', 'test_bundle', 'full') ->setComponent($this->field['field_name'], $display_options) ->save(); diff --git a/core/modules/link/lib/Drupal/link/Tests/LinkItemTest.php b/core/modules/link/lib/Drupal/link/Tests/LinkItemTest.php index e59e403..eb40cbc 100644 --- a/core/modules/link/lib/Drupal/link/Tests/LinkItemTest.php +++ b/core/modules/link/lib/Drupal/link/Tests/LinkItemTest.php @@ -44,9 +44,6 @@ public function setUp() { 'entity_type' => 'entity_test', 'field_name' => 'field_test', 'bundle' => 'entity_test', - 'widget' => array( - 'type' => 'link_default', - ), ); field_create_instance($this->instance); } diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php b/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php index 4f868f7..644fbcf 100644 --- a/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php +++ b/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php @@ -278,9 +278,10 @@ protected function build_filters(&$form, &$form_state) { $tag_fields = array(); foreach ($bundles as $bundle) { foreach (field_info_instances($this->entity_type, $bundle) as $instance) { + $widget = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default')->getComponent($instance['field_name']); // We define "tag-like" taxonomy fields as ones that use the // "Autocomplete term widget (tagging)" widget. - if ($instance['widget']['type'] == 'taxonomy_autocomplete') { + if ($widget['type'] == 'taxonomy_autocomplete') { $tag_fields[] = $instance['field_name']; } } diff --git a/core/modules/node/lib/Drupal/node/Tests/MultiStepNodeFormBasicOptionsTest.php b/core/modules/node/lib/Drupal/node/Tests/MultiStepNodeFormBasicOptionsTest.php index 7ee1e85..465a492 100644 --- a/core/modules/node/lib/Drupal/node/Tests/MultiStepNodeFormBasicOptionsTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/MultiStepNodeFormBasicOptionsTest.php @@ -54,16 +54,14 @@ function testMultiStepNodeFormBasicOptions() { 'settings' => array( 'text_processing' => TRUE, ), - 'widget' => array( - 'type' => 'text_textfield', - ), - 'display' => array( - 'full' => array( - 'type' => 'text_default', - ), - ), ); field_create_instance($this->instance); + entity_get_form_display('node', 'page', 'default') + ->setComponent($this->field_name, array( + 'type' => 'text_textfield', + )) + ->save(); + $langcode = LANGUAGE_NOT_SPECIFIED; $edit = array( diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php index 0db0bda..2ef9d03 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeAccessFieldTest.php @@ -48,6 +48,9 @@ public function setUp() { entity_get_display('node', 'page', 'default') ->setComponent($this->field_name) ->save(); + entity_get_form_display('node', 'page', 'default') + ->setComponent($this->field_name) + ->save(); } /** diff --git a/core/modules/node/lib/Drupal/node/Tests/PagePreviewTest.php b/core/modules/node/lib/Drupal/node/Tests/PagePreviewTest.php index 28b04cd..ebe6fc1 100644 --- a/core/modules/node/lib/Drupal/node/Tests/PagePreviewTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/PagePreviewTest.php @@ -76,20 +76,26 @@ function setUp() { 'field_name' => $this->field_name, 'entity_type' => 'node', 'bundle' => 'page', - 'widget' => array( - 'type' => 'options_select', - ), - // Hide on full display but render on teaser. - 'display' => array( - 'default' => array( - 'type' => 'hidden', - ), - 'teaser' => array( - 'type' => 'taxonomy_term_reference_link', - ), - ), ); field_create_instance($this->instance); + + entity_get_form_display('node', 'page', 'default') + ->setComponent($this->field['field_name'], array( + 'type' => 'options_select', + )) + ->save(); + + // Hide on full display but render on teaser. + entity_get_display('node', 'page', 'default') + ->setComponent($this->field['field_name'], array( + 'type' => 'hidden', + )) + ->save(); + entity_get_display('node', 'page', 'teaser') + ->setComponent($this->field['field_name'], array( + 'type' => 'taxonomy_term_reference_link', + )) + ->save(); } /** diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 8f9f17f..f65e814 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -579,11 +579,17 @@ function node_add_body_field($type, $label = 'Body') { 'entity_type' => 'node', 'bundle' => $type->type, 'label' => $label, - 'widget' => array('type' => 'text_textarea_with_summary'), 'settings' => array('display_summary' => TRUE), ); $instance = field_create_instance($instance); + // Assign widget settings for the 'default' form mode. + entity_get_form_display('node', $type->type, 'default') + ->setComponent($field['field_name'], array( + 'type' => 'text_textarea_with_summary', + )) + ->save(); + // Assign display settings for the 'default' and 'teaser' view modes. entity_get_display('node', $type->type, 'default') ->setComponent($field['field_name'], array( diff --git a/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php b/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php index aa6c06e..d0b98ac 100644 --- a/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php +++ b/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php @@ -57,16 +57,21 @@ function testNumberDecimalField() { 'field_name' => $this->field['field_name'], 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', - 'widget' => array( + ); + field_create_instance($this->instance); + + entity_get_form_display('test_entity', 'test_bundle', 'default') + ->setComponent($this->field['field_name'], array( 'type' => 'number', 'settings' => array( 'placeholder' => '0.00' ), - ), - ); - field_create_instance($this->instance); + )) + ->save(); entity_get_display('test_entity', 'test_bundle', 'default') - ->setComponent($this->field['field_name']) + ->setComponent($this->field['field_name'], array( + 'type' => 'number_decimal', + )) ->save(); // Display creation form. diff --git a/core/modules/number/lib/Drupal/number/Tests/NumberItemTest.php b/core/modules/number/lib/Drupal/number/Tests/NumberItemTest.php index a0fc778..fa7e0fa 100644 --- a/core/modules/number/lib/Drupal/number/Tests/NumberItemTest.php +++ b/core/modules/number/lib/Drupal/number/Tests/NumberItemTest.php @@ -45,9 +45,6 @@ public function setUp() { 'entity_type' => 'entity_test', 'field_name' => 'field_' . $type, 'bundle' => 'entity_test', - 'widget' => array( - 'type' => 'number', - ), ); field_create_instance($this->instance[$type]); } diff --git a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php b/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php index 40f24df..94ae0cb 100644 --- a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php +++ b/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php @@ -36,8 +36,8 @@ /** * {@inheritdoc} */ - public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, array $settings, $weight) { - parent::__construct($plugin_id, $plugin_definition, $instance, $settings, $weight); + public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, array $settings) { + parent::__construct($plugin_id, $plugin_definition, $instance, $settings); // Reset internal pointer since we're dealing with objects now. reset($this->field['columns']); diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsDynamicValuesTest.php b/core/modules/options/lib/Drupal/options/Tests/OptionsDynamicValuesTest.php index 4065b7d..4e97dbe 100644 --- a/core/modules/options/lib/Drupal/options/Tests/OptionsDynamicValuesTest.php +++ b/core/modules/options/lib/Drupal/options/Tests/OptionsDynamicValuesTest.php @@ -40,11 +40,14 @@ function setUp() { 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', 'required' => TRUE, - 'widget' => array( - 'type' => 'options_select', - ), ); $this->instance = field_create_instance($this->instance); + entity_get_form_display('test_entity', 'test_bundle', 'default') + ->setComponent($this->field_name, array( + 'type' => 'options_select', + )) + ->save(); + $this->test = array( 'id' => mt_rand(1, 10), // Make sure this does not equal the ID so that diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldTest.php b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldTest.php index 11ab663..02179d6 100644 --- a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldTest.php +++ b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldTest.php @@ -50,11 +50,13 @@ function setUp() { 'field_name' => $this->field_name, 'entity_type' => 'entity_test', 'bundle' => 'entity_test', - 'widget' => array( - 'type' => 'options_buttons', - ), ); $this->instance = field_create_instance($this->instance); + entity_get_form_display('entity_test', 'entity_test', 'default') + ->setComponent($this->field_name, array( + 'type' => 'options_buttons', + )) + ->save(); } /** @@ -114,11 +116,13 @@ function testUpdateAllowedValues() { 'field_name' => $this->field_name, 'entity_type' => 'entity_test', 'bundle' => 'entity_test', - 'widget' => array( - 'type' => 'options_buttons', - ), ); field_create_instance($this->instance); + entity_get_form_display('entity_test', 'entity_test', 'default') + ->setComponent($this->field_name, array( + 'type' => 'options_buttons', + )) + ->save(); $entity = entity_create('entity_test', array()); $form = entity_get_form($entity); $this->assertTrue(!empty($form[$this->field_name][$langcode][1]), 'Option 1 exists'); diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php index 11f6035..9dee440 100644 --- a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php +++ b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php @@ -223,6 +223,10 @@ function testOptionsAllowedValuesBoolean() { ); $this->drupalPost($this->admin_path, $edit, t('Save field settings')); $this->assertRaw(t('Updated field %label field settings.', array('%label' => $this->field_name))); + + // Clear field cache. + field_info_cache_clear(); + // Test the allowed_values on the field settings form. $this->drupalGet($this->admin_path); $this->assertFieldByName('on', $on, t("The 'On' value is stored correctly.")); @@ -266,6 +270,8 @@ protected function createOptionsField($type) { ); field_create_instance($instance); + entity_get_form_display('node', $this->type, 'default')->setComponent($this->field_name)->save(); + $this->admin_path = 'admin/structure/types/manage/' . $this->type . '/fields/' . $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..f921a58 100644 --- a/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php +++ b/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php @@ -81,11 +81,14 @@ function testRadioButtons() { 'field_name' => $this->card_1['field_name'], 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', - 'widget' => array( - 'type' => 'options_buttons', - ), ); $instance = field_create_instance($instance); + entity_get_form_display('test_entity', 'test_bundle', 'default') + ->setComponent($this->card_1['field_name'], array( + 'type' => 'options_buttons', + )) + ->save(); + $langcode = LANGUAGE_NOT_SPECIFIED; // Create an entity. @@ -135,11 +138,14 @@ function testCheckBoxes() { 'field_name' => $this->card_2['field_name'], 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', - 'widget' => array( - 'type' => 'options_buttons', - ), ); $instance = field_create_instance($instance); + entity_get_form_display('test_entity', 'test_bundle', 'default') + ->setComponent($this->card_2['field_name'], array( + 'type' => 'options_buttons', + )) + ->save(); + $langcode = LANGUAGE_NOT_SPECIFIED; // Create an entity. @@ -223,11 +229,14 @@ function testSelectListSingle() { 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', 'required' => TRUE, - 'widget' => array( - 'type' => 'options_select', - ), ); $instance = field_create_instance($instance); + entity_get_form_display('test_entity', 'test_bundle', 'default') + ->setComponent($this->card_1['field_name'], array( + 'type' => 'options_select', + )) + ->save(); + $langcode = LANGUAGE_NOT_SPECIFIED; // Create an entity. @@ -319,11 +328,14 @@ function testSelectListMultiple() { 'field_name' => $this->card_2['field_name'], 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', - 'widget' => array( - 'type' => 'options_select', - ), ); $instance = field_create_instance($instance); + entity_get_form_display('test_entity', 'test_bundle', 'default') + ->setComponent($this->card_2['field_name'], array( + 'type' => 'options_select', + )) + ->save(); + $langcode = LANGUAGE_NOT_SPECIFIED; // Create an entity. @@ -436,11 +448,14 @@ function testOnOffCheckbox() { 'field_name' => $this->bool['field_name'], 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', - 'widget' => array( - 'type' => 'options_onoff', - ), ); $instance = field_create_instance($instance); + entity_get_form_display('test_entity', 'test_bundle', 'default') + ->setComponent($this->bool['field_name'], array( + 'type' => 'options_onoff', + )) + ->save(); + $langcode = LANGUAGE_NOT_SPECIFIED; // Create an entity. @@ -487,13 +502,15 @@ function testOnOffCheckbox() { 'field_name' => $this->bool['field_name'], 'entity_type' => 'node', 'bundle' => 'page', - 'widget' => array( - 'type' => 'options_onoff', - 'module' => 'options', - ), ); field_create_instance($instance); + entity_get_form_display('node', 'page', 'default') + ->setComponent($this->bool['field_name'], array( + 'type' => 'options_onoff', + )) + ->save(); + // Go to the edit page and check if the default settings works as expected $fieldEditUrl = 'admin/structure/types/manage/page/fields/bool'; $this->drupalGet($fieldEditUrl); diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php index 6f99dae..5d917a4 100644 --- a/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php +++ b/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php @@ -117,6 +117,12 @@ function testAttributesInMarkupFile() { 'bundle' => $bundle_name, ); field_create_instance($instance); + + entity_get_form_display('node', $bundle_name, 'default') + ->setComponent($field_name, array( + 'type' => 'file_generic', + )) + ->save(); entity_get_display('node', $bundle_name, 'teaser') ->setComponent($field_name, array( 'type' => 'file_default', diff --git a/core/modules/simpletest/lib/Drupal/simpletest/Tests/DrupalUnitTestBaseTest.php b/core/modules/simpletest/lib/Drupal/simpletest/Tests/DrupalUnitTestBaseTest.php index 2379193..242bcd6 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/Tests/DrupalUnitTestBaseTest.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/Tests/DrupalUnitTestBaseTest.php @@ -229,7 +229,7 @@ function testEnableModulesFixedList() { $display = entity_create('entity_display', array( 'targetEntityType' => 'entity_test', 'bundle' => 'entity_test', - 'viewMode' => 'default', + 'mode' => 'default', )); $field = array( 'field_name' => 'test_field', diff --git a/core/modules/system/lib/Drupal/system/Tests/Ajax/MultiFormTest.php b/core/modules/system/lib/Drupal/system/Tests/Ajax/MultiFormTest.php index c9e7b6d..d3ba0b7 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Ajax/MultiFormTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Ajax/MultiFormTest.php @@ -46,6 +46,9 @@ function setUp() { 'bundle' => 'page', ); field_create_instance($instance); + entity_get_form_display('node', 'page', 'default') + ->setComponent($field_name, array('type' => 'text_default')) + ->save(); // Login a user who can create 'page' nodes. $this->web_user = $this->drupalCreateUser(array('create page content')); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFormTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFormTest.php index fbbd131..78ce17d 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFormTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFormTest.php @@ -46,6 +46,17 @@ function testFormCRUD() { } /** + * Tests hook_entity_form_display_alter(). + * + * @see entity_test_entity_form_display_alter() + */ + function testEntityFormDisplayAlter() { + $this->drupalGet('entity_test/add'); + $altered_field = $this->xpath('//input[@name="field_test_text[und][0][value]" and @size="42"]'); + $this->assertTrue(count($altered_field) === 1, 'The altered field has the correct size value.'); + } + + /** * Executes the form CRUD tests for the given entity type. * * @param string $entity_type diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUnitTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUnitTestBase.php index 41918d3..4da3b21 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUnitTestBase.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUnitTestBase.php @@ -19,7 +19,7 @@ * * @var array */ - public static $modules = array('user', 'system', 'field', 'text', 'field_sql_storage', 'entity_test'); + public static $modules = array('entity', 'user', 'system', 'field', 'text', 'field_sql_storage', 'entity_test'); public function setUp() { parent::setUp(); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php index a460b6f..b00bfea 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php @@ -19,7 +19,7 @@ class FieldAccessTest extends DrupalUnitTestBase { * * @var array */ - public static $modules = array('entity_test', 'field', 'field_sql_storage', 'system', 'text', 'user'); + public static $modules = array('entity', 'entity_test', 'field', 'field_sql_storage', 'system', 'text', 'user'); /** * Holds the currently active global user ID that initiated the test run. diff --git a/core/modules/system/lib/Drupal/system/Tests/Form/ArbitraryRebuildTest.php b/core/modules/system/lib/Drupal/system/Tests/Form/ArbitraryRebuildTest.php index 1604063..f049ac8 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Form/ArbitraryRebuildTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Form/ArbitraryRebuildTest.php @@ -42,16 +42,21 @@ function setUp() { field_create_field($field); $instance = array( - 'entity_type' => 'node', + 'entity_type' => 'user', 'field_name' => 'test_multiple', - 'bundle' => 'page', + 'bundle' => 'user', 'label' => 'Test a multiple valued field', - 'widget' => array( - 'type' => 'text_textfield', - 'weight' => 0, + 'settings' => array( + 'user_register_form' => TRUE, ), ); field_create_instance($instance); + entity_get_form_display('user', 'user', 'default') + ->setComponent('test_multiple', array( + 'type' => 'text_textfield', + 'weight' => 0, + )) + ->save(); } /** diff --git a/core/modules/system/lib/Drupal/system/Tests/Form/RebuildTest.php b/core/modules/system/lib/Drupal/system/Tests/Form/RebuildTest.php index 3c0c0c5..8e9f649 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Form/RebuildTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Form/RebuildTest.php @@ -83,6 +83,9 @@ function testPreserveFormActionAfterAJAX() { 'bundle' => 'page', ); field_create_instance($instance); + entity_get_form_display('node', 'page', 'default') + ->setComponent($field_name, array('type' => 'text_test')) + ->save(); // Log in a user who can create 'page' nodes. $this->web_user = $this->drupalCreateUser(array('create page content')); diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php index 0936aa5..621f114 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php @@ -88,6 +88,45 @@ public function testEntityDisplayUpgrade() { } /** + * Tests upgrade of entity form displays. + */ + public function testEntityFormDisplayUpgrade() { + $this->assertTrue($this->performUpgrade(), 'The upgrade was completed successfully.'); + + // Check that the configuration entries were created. + $form_display = config('entity.form_display.node.article.default')->get(); + $this->assertTrue(!empty($form_display)); + + // Check that manifest entries for the 'article' node type were correctly + // created. + $manifest = config('manifest.entity.form_display'); + $data = $manifest->get(); + $this->assertEqual($data['node.article.default'], array('name' => 'entity.form_display.node.article.default')); + + // Check that the 'body' field is configured as expected. + $expected = array( + 'type' => 'text_textarea_with_summary', + 'weight' => -4, + 'settings' => array( + 'rows' => '20', + 'summary_rows' => '5', + ), + ); + $this->assertEqual($form_display['content']['body'], $expected); + + // Check that the display key in the instance data was removed. + $body_instance = field_info_instance('node', 'body', 'article'); + $this->assertTrue(!isset($body_instance['widget'])); + + // Check that the 'title' extra field is configured as expected. + $expected = array( + 'weight' => -5, + 'visible' => 1, + ); + $this->assertEqual($form_display['content']['title'], $expected); + } + + /** * Tests migration of field and instance definitions to config. */ function testFieldUpgradeToConfig() { @@ -150,15 +189,6 @@ function testFieldUpgradeToConfig() { 'text_processing' => 1, 'user_register_form' => FALSE, ), - 'widget' => array( - 'type' => 'text_textarea_with_summary', - 'module' => 'text', - 'settings' => array( - 'rows' => 20, - 'summary_rows' => 5, - ), - 'weight' => -4, - ), 'status' => 1, 'langcode' => 'und', )); diff --git a/core/modules/system/tests/modules/entity_test/entity_test.install b/core/modules/system/tests/modules/entity_test/entity_test.install index 3465e8c..f7b8726 100644 --- a/core/modules/system/tests/modules/entity_test/entity_test.install +++ b/core/modules/system/tests/modules/entity_test/entity_test.install @@ -30,12 +30,12 @@ function entity_test_install() { 'field_name' => 'field_test_text', 'bundle' => $entity_type, 'label' => 'Test text-field', - 'widget' => array( - 'type' => 'text_textfield', - 'weight' => 0, - ), ); field_create_instance($instance); + + entity_get_form_display($entity_type, $entity_type, 'default') + ->setComponent('field_test_text', array('type' => 'text_text')) + ->save(); } } diff --git a/core/modules/system/tests/modules/entity_test/entity_test.module b/core/modules/system/tests/modules/entity_test/entity_test.module index 673ab67..2836d17 100644 --- a/core/modules/system/tests/modules/entity_test/entity_test.module +++ b/core/modules/system/tests/modules/entity_test/entity_test.module @@ -6,6 +6,7 @@ */ use Drupal\Core\Entity\EntityInterface; +use Drupal\entity\Plugin\Core\Entity\EntityFormDisplay; /** * Filter that limits test entity list to revisable ones. @@ -379,3 +380,16 @@ function entity_test_entity_field_access_alter(array &$grants, array $context) { $grants[':default'] = FALSE; } } + +/** + * Implements hook_entity_form_display_alter(). + */ +function entity_test_entity_form_display_alter(EntityFormDisplay $form_display, $context) { + // Make the field_test_text field 42 characters for entity_test_mul. + if ($context['entity_type'] == 'entity_test') { + if ($component_options = $form_display->getComponent('field_test_text')) { + $component_options['settings']['size'] = 42; + $form_display->setComponent('field_test_text', $component_options); + } + } +} diff --git a/core/modules/system/tests/upgrade/drupal-7.field.database.php b/core/modules/system/tests/upgrade/drupal-7.field.database.php index 9434c7c..baa5027 100644 --- a/core/modules/system/tests/upgrade/drupal-7.field.database.php +++ b/core/modules/system/tests/upgrade/drupal-7.field.database.php @@ -28,7 +28,12 @@ ), ), 'extra_fields' => array( - 'form' => array(), + 'form' => array( + 'title' => array( + 'weight' => -5, + 'visible' => 1, + ), + ), 'display' => array( 'language' => array( 'default' => array( diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php index 4c3e3d3..a1c0e67 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php @@ -53,11 +53,13 @@ function setUp() { 'field_name' => 'taxonomy_' . $this->vocabulary->id(), 'bundle' => 'article', 'entity_type' => 'node', - 'widget' => array( - 'type' => 'options_select', - ), ); field_create_instance($this->instance); + entity_get_form_display('node', 'article', 'default') + ->setComponent($field['field_name'], array( + 'type' => 'options_select', + )) + ->save(); entity_get_display('node', 'article', 'default') ->setComponent('taxonomy_' . $this->vocabulary->id(), array( 'type' => 'taxonomy_term_reference_link', diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermReferenceItemTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermReferenceItemTest.php index ea9bc3e..4f54df9 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermReferenceItemTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermReferenceItemTest.php @@ -60,9 +60,6 @@ public function setUp() { 'entity_type' => 'entity_test', 'field_name' => 'field_test_taxonomy', 'bundle' => 'entity_test', - 'widget' => array( - 'type' => 'options_select', - ), ); field_create_instance($instance); $this->term = entity_create('taxonomy_term', array( diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php index 8c5571c..0d317c4 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php @@ -63,11 +63,13 @@ function setUp() { 'field_name' => $this->field_name, 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', - 'widget' => array( - 'type' => 'options_select', - ), ); field_create_instance($this->instance); + entity_get_form_display('test_entity', 'test_bundle', 'default') + ->setComponent($this->field_name, array( + 'type' => 'options_select', + )) + ->save(); entity_get_display('test_entity', 'test_bundle', 'full') ->setComponent($this->field_name, array( 'type' => 'taxonomy_term_reference_link', diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php index d5de5fa..b1c2bcf 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php @@ -58,11 +58,13 @@ function setUp() { 'field_name' => $this->field_name, 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', - 'widget' => array( - 'type' => 'options_select', - ), ); field_create_instance($this->instance); + entity_get_form_display('test_entity', 'test_bundle', 'default') + ->setComponent($this->field_name, array( + 'type' => 'options_select', + )) + ->save(); entity_get_display('test_entity', 'test_bundle', 'full') ->setComponent($this->field_name, array( 'type' => 'taxonomy_term_reference_link', diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php index f9cba0d..e55945d 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php @@ -49,11 +49,13 @@ function setUp() { 'field_name' => $this->field_name_1, 'bundle' => 'article', 'entity_type' => 'node', - 'widget' => array( - 'type' => 'options_select', - ), ); field_create_instance($this->instance_1); + entity_get_form_display('node', 'article', 'default') + ->setComponent($this->field_name_1, array( + 'type' => 'options_select', + )) + ->save(); entity_get_display('node', 'article', 'default') ->setComponent($this->field_name_1, array( 'type' => 'taxonomy_term_reference_link', @@ -79,11 +81,13 @@ function setUp() { 'field_name' => $this->field_name_2, 'bundle' => 'article', 'entity_type' => 'node', - 'widget' => array( - 'type' => 'options_select', - ), ); field_create_instance($this->instance_2); + entity_get_form_display('node', 'article', 'default') + ->setComponent($this->field_name_2, array( + 'type' => 'options_select', + )) + ->save(); entity_get_display('node', 'article', 'default') ->setComponent($this->field_name_2, array( 'type' => 'taxonomy_term_reference_link', diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php index 6b8cff3..f9cbb5d 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php @@ -45,11 +45,13 @@ function setUp() { 'field_name' => 'taxonomy_' . $this->vocabulary->id(), 'bundle' => 'article', 'entity_type' => 'node', - 'widget' => array( - 'type' => 'options_select', - ), ); field_create_instance($this->instance); + entity_get_form_display('node', 'article', 'default') + ->setComponent('taxonomy_' . $this->vocabulary->id(), array( + 'type' => 'options_select', + )) + ->save(); entity_get_display('node', 'article', 'default') ->setComponent($this->instance['field_name'], array( 'type' => 'taxonomy_term_reference_link', @@ -142,13 +144,14 @@ function testTaxonomyNode() { function testNodeTermCreationAndDeletion() { // Enable tags in the vocabulary. $instance = $this->instance; - $instance['widget'] = array( - 'type' => 'taxonomy_autocomplete', - 'settings' => array( - 'placeholder' => 'Start typing here.', - ), - ); - field_update_instance($instance); + entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default') + ->setComponent($instance['field_name'], array( + 'type' => 'taxonomy_autocomplete', + 'settings' => array( + 'placeholder' => 'Start typing here.', + ), + )) + ->save(); $terms = array( 'term1' => $this->randomName(), 'term2' => $this->randomName(), @@ -506,8 +509,11 @@ function testTaxonomyGetTermByName() { function testReSavingTags() { // Enable tags in the vocabulary. $instance = $this->instance; - $instance['widget'] = array('type' => 'taxonomy_autocomplete'); - field_update_instance($instance); + entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default') + ->setComponent($instance['field_name'], array( + 'type' => 'taxonomy_autocomplete', + )) + ->save(); // Create a term and a node using it. $term = $this->createTerm($this->vocabulary); diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php index a792aad..f8ac51e 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php @@ -46,11 +46,13 @@ function setUp() { 'field_name' => 'taxonomy_' . $this->vocabulary->id(), 'bundle' => 'article', 'entity_type' => 'node', - 'widget' => array( - 'type' => 'options_select', - ), ); field_create_instance($this->instance); + entity_get_form_display('node', 'article', 'default') + ->setComponent('taxonomy_' . $this->vocabulary->id(), array( + 'type' => 'options_select', + )) + ->save(); entity_get_display('node', 'article', 'default') ->setComponent('taxonomy_' . $this->vocabulary->id(), array( 'type' => 'taxonomy_term_reference_link', diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyTestBase.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyTestBase.php index 5f98990..d73e479 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyTestBase.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyTestBase.php @@ -100,13 +100,16 @@ protected function mockStandardInstall() { 'entity_type' => 'node', 'label' => 'Tags', 'bundle' => 'article', - 'widget' => array( - 'type' => 'taxonomy_autocomplete', - 'weight' => -4, - ), ); field_create_instance($instance); + entity_get_form_display('node', 'article', 'default') + ->setComponent($instance['field_name'], array( + 'type' => 'taxonomy_autocomplete', + 'weight' => -4, + )) + ->save(); + entity_get_display('node', 'article', 'default') ->setComponent($instance['field_name'], array( 'type' => 'taxonomy_term_reference_link', diff --git a/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php b/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php index 1bec98f..0d5aa47 100644 --- a/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php +++ b/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php @@ -64,14 +64,17 @@ function testTelephoneField() { 'label' => 'Telephone Number', 'entity_type' => 'node', 'bundle' => 'article', - 'widget' => array( + ); + field_create_instance($instance); + + entity_get_form_display('node', 'article', 'default') + ->setComponent('field_telephone', array( 'type' => 'telephone_default', 'settings' => array( 'placeholder' => '123-456-7890', ), - ), - ); - field_create_instance($instance); + )) + ->save(); entity_get_display('node', 'article', 'default') ->setComponent('field_telephone', array( diff --git a/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneItemTest.php b/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneItemTest.php index 35012b3..d809161 100644 --- a/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneItemTest.php +++ b/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneItemTest.php @@ -44,9 +44,6 @@ public function setUp() { 'entity_type' => 'entity_test', 'field_name' => 'field_test', 'bundle' => 'entity_test', - 'widget' => array( - 'type' => 'telephone_default', - ), ); field_create_instance($this->instance); } diff --git a/core/modules/text/lib/Drupal/text/Tests/Formatter/TextPlainUnitTest.php b/core/modules/text/lib/Drupal/text/Tests/Formatter/TextPlainUnitTest.php index 7126384..3ec2d22 100644 --- a/core/modules/text/lib/Drupal/text/Tests/Formatter/TextPlainUnitTest.php +++ b/core/modules/text/lib/Drupal/text/Tests/Formatter/TextPlainUnitTest.php @@ -61,9 +61,6 @@ function setUp() { 'text_processing' => FALSE, ); - $this->widget_type = 'text_textarea'; - $this->widget_settings = array(); - $this->formatter_type = 'text_plain'; $this->formatter_settings = array(); @@ -80,10 +77,6 @@ function setUp() { 'field_name' => $this->field_name, 'label' => $this->randomName(), 'settings' => $this->instance_settings, - 'widget' => array( - 'type' => $this->widget_type, - 'settings' => $this->widget_settings, - ), ); $this->instance = field_create_instance($this->instance); diff --git a/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php b/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php index f8c585b..e12553f 100644 --- a/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php +++ b/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php @@ -62,14 +62,8 @@ function testTextFieldValidation() { 'field_name' => $this->field['field_name'], 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', - 'widget' => array( - 'type' => 'text_textfield', - ), ); field_create_instance($this->instance); - entity_get_display('test_entity', 'test_bundle', 'default') - ->setComponent($this->field['field_name']) - ->save(); // Test valid and invalid values with field_attach_validate(). $entity = field_test_create_entity(); @@ -111,14 +105,16 @@ function _testTextfieldWidgets($field_type, $widget_type) { 'settings' => array( 'text_processing' => TRUE, ), - 'widget' => array( + ); + field_create_instance($this->instance); + entity_get_form_display('test_entity', 'test_bundle', 'default') + ->setComponent($this->field_name, array( 'type' => $widget_type, 'settings' => array( 'placeholder' => 'A placeholder on ' . $widget_type, ), - ), - ); - field_create_instance($this->instance); + )) + ->save(); entity_get_display('test_entity', 'test_bundle', 'full') ->setComponent($this->field_name) ->save(); @@ -174,11 +170,13 @@ function _testTextfieldWidgetsFormatted($field_type, $widget_type) { 'settings' => array( 'text_processing' => TRUE, ), - 'widget' => array( - 'type' => $widget_type, - ), ); field_create_instance($this->instance); + entity_get_form_display('test_entity', 'test_bundle', 'default') + ->setComponent($this->field_name, array( + 'type' => $widget_type, + )) + ->save(); entity_get_display('test_entity', 'test_bundle', 'full') ->setComponent($this->field_name) ->save(); diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSyncImageTest.php b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSyncImageTest.php index 61f93cf..aa9c626 100644 --- a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSyncImageTest.php +++ b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSyncImageTest.php @@ -69,10 +69,6 @@ protected function setupTestFields() { 'field_name' => $this->fieldName, 'bundle' => $this->entityType, 'label' => 'Test translatable image field', - 'widget' => array( - 'type' => 'image_image', - 'weight' => 0, - ), 'settings' => array( 'translation_sync' => array( 'file' => FALSE, diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationTestBase.php b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationTestBase.php index 13e1f59..870321f 100644 --- a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationTestBase.php +++ b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationTestBase.php @@ -170,12 +170,14 @@ protected function setupTestFields() { 'field_name' => $this->fieldName, 'bundle' => $this->bundle, 'label' => 'Test translatable text-field', - 'widget' => array( - 'type' => 'text_textfield', - 'weight' => 0, - ), ); field_create_instance($instance); + entity_get_form_display($this->entityType, $this->bundle, 'default') + ->setComponent($this->fieldName, array( + 'type' => 'text_textfield', + 'weight' => 0, + )) + ->save(); } /** diff --git a/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php b/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php index 38ca376..db649b0 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php @@ -209,6 +209,9 @@ function testRegistrationWithUserFields() { 'settings' => array('user_register_form' => FALSE), ); field_create_instance($instance); + entity_get_form_display('user', 'user', 'default') + ->setComponent('test_user_field', array('type' => 'test_field_widget')) + ->save(); // Check that the field does not appear on the registration form. $this->drupalGet('user/register'); diff --git a/core/modules/user/user.install b/core/modules/user/user.install index dca417c..4f22958 100644 --- a/core/modules/user/user.install +++ b/core/modules/user/user.install @@ -335,17 +335,20 @@ function user_install_picture_field() { 'min_resolution' => '', 'default_image' => 0, ), - 'widget' => array( - 'module' => 'image', + ); + field_create_instance($instance); + + // Assign form display settings for the 'default' view mode. + entity_get_form_display('user', 'user', 'default') + ->setComponent('user_picture', array( 'type' => 'image_image', 'settings' => array( 'progress_indicator' => 'throbber', 'preview_image_style' => 'thumbnail', ), 'weight' => -1, - ), - ); - field_create_instance($instance); + )) + ->save(); // Assign display settings for the 'default' and 'compact' view modes. entity_get_display('user', 'user', 'default') @@ -731,29 +734,32 @@ function user_update_8011() { 'min_resolution' => '', 'default_image' => !empty($default_image_fid) ? $default_image_fid : 0, ), - 'widget' => array( - 'module' => 'image', - 'type' => 'image_image', + ); + _update_7000_field_create_instance($field, $instance); + + module_load_install('entity'); + if (update_variable_get('user_pictures', 0)) { + $formatter = 'image'; + $widget = 'image_image'; + } + else { + $formatter = $widget = 'hidden'; + } + + // Assign form settings for the 'default' form mode. + $form_display = _update_8000_entity_get_form_display('user', 'user', 'default'); + $form_display->set('content.user_picture', array( + 'type' => $widget, 'settings' => array( 'progress_indicator' => 'throbber', 'preview_image_style' => 'thumbnail', ), 'weight' => -1, - ), - ); - _update_7000_field_create_instance($field, $instance); - - // Assign display settings for the 'default' and 'compact' view modes. In D7, - // user pictures did not require Image module to work. Image module only - // allowed usage of an image style to format user pictures in the output. - // The 'user_pictures' variable had a global effect on the presence of the - // user picture functionality before. The new user picture image field is - // created regardless of that global setting, which means the field appears - // on the user account form after migration, even if user pictures were - // disabled previously. The picture is only hidden in the output. - $formatter = update_variable_get('user_pictures', 0) ? 'image' : 'hidden'; - module_load_install('entity'); + )) + ->save(); + update_config_manifest_add('entity.form_display', array($form_display->get('id'))); + // Assign display settings for the 'default' and 'compact' view modes. $display = _update_8000_entity_get_display('user', 'user', 'default'); $display->set('content.user_picture', array( 'label' => 'hidden', diff --git a/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php b/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php index c4f90b8..174c598 100644 --- a/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php @@ -77,16 +77,8 @@ protected function setUp() { 'field_name' => $this->field_name, 'entity_type' => 'node', 'bundle' => 'page', - 'widget' => array( - 'type' => 'options_select', - ), ); field_create_instance($this->instance); - entity_get_display('node', 'page', 'full') - ->setComponent($this->field_name, array( - 'type' => 'taxonomy_term_reference_link', - )) - ->save(); // Create a time in the past for the archive. $time = time() - 3600; diff --git a/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php b/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php index 7c150dc..f1a06a3 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php @@ -74,12 +74,15 @@ function setUp() { 'field_name' => 'field_views_testing_tags', 'entity_type' => 'node', 'bundle' => $this->node_type_with_tags->type, - 'widget' => array( - 'type' => 'taxonomy_autocomplete', - ), ); field_create_instance($this->tag_instance); + entity_get_form_display('node', $this->node_type_with_tags->type, 'default') + ->setComponent('field_views_testing_tags', array( + 'type' => 'taxonomy_autocomplete', + )) + ->save(); + entity_get_display('node', $this->node_type_with_tags->type, 'default') ->setComponent('field_views_testing_tags', array( 'type' => 'taxonomy_term_reference_link', @@ -185,6 +188,12 @@ function testTaggedWithByNodeType() { $instance = $this->tag_instance; $instance['bundle'] = $this->node_type_without_tags->type; field_create_instance($instance); + entity_get_form_display('node', $this->node_type_without_tags->type, 'default') + ->setComponent('field_views_testing_tags', array( + 'type' => 'taxonomy_autocomplete', + )) + ->save(); + $view['show[type]'] = $this->node_type_with_tags->type; $this->drupalPost('admin/structure/views/add', $view, t('Update "of type" choice')); $this->assertFieldByXpath($tags_xpath); diff --git a/core/profiles/standard/config/entity.display.node.article.default.yml b/core/profiles/standard/config/entity.display.node.article.default.yml index 7cd3ae0..330de2d 100644 --- a/core/profiles/standard/config/entity.display.node.article.default.yml +++ b/core/profiles/standard/config/entity.display.node.article.default.yml @@ -1,7 +1,7 @@ id: node.article.default targetEntityType: node bundle: article -viewMode: default +mode: default content: body: label: hidden diff --git a/core/profiles/standard/config/entity.display.node.article.teaser.yml b/core/profiles/standard/config/entity.display.node.article.teaser.yml index ae65eb4..44add7e 100644 --- a/core/profiles/standard/config/entity.display.node.article.teaser.yml +++ b/core/profiles/standard/config/entity.display.node.article.teaser.yml @@ -1,7 +1,7 @@ id: node.article.teaser targetEntityType: node bundle: article -viewMode: teaser +mode: teaser content: body: label: hidden diff --git a/core/profiles/standard/config/entity.form_display.node.article.default.yml b/core/profiles/standard/config/entity.form_display.node.article.default.yml new file mode 100644 index 0000000..dcd242e --- /dev/null +++ b/core/profiles/standard/config/entity.form_display.node.article.default.yml @@ -0,0 +1,25 @@ +id: node.article.default +targetEntityType: node +bundle: article +mode: default +content: + body: + type: text_textarea_with_summary + weight: '0' + settings: + rows: '9' + summary_rows: '3' + placeholder: '' + field_tags: + type: taxonomy_autocomplete + weight: '-4' + settings: + size: '60' + autocomplete_path: taxonomy/autocomplete + placeholder: '' + field_image: + type: image_image + settings: + progress_indicator: throbber + preview_image_style: thumbnail + weight: '-1' diff --git a/core/profiles/standard/config/field.instance.node.article.field_image.yml b/core/profiles/standard/config/field.instance.node.article.field_image.yml index 3412036..98bd0e3 100644 --- a/core/profiles/standard/config/field.instance.node.article.field_image.yml +++ b/core/profiles/standard/config/field.instance.node.article.field_image.yml @@ -19,12 +19,5 @@ settings: title_field_required: 0 default_image: 0 user_register_form: false -widget: - type: image_image - settings: - progress_indicator: throbber - preview_image_style: thumbnail - weight: -1 - module: image status: 1 langcode: und diff --git a/core/profiles/standard/config/field.instance.node.article.field_tags.yml b/core/profiles/standard/config/field.instance.node.article.field_tags.yml index bbca298..bb51b39 100644 --- a/core/profiles/standard/config/field.instance.node.article.field_tags.yml +++ b/core/profiles/standard/config/field.instance.node.article.field_tags.yml @@ -9,13 +9,5 @@ default_value: { } default_value_function: '' settings: user_register_form: false -widget: - type: taxonomy_autocomplete - weight: -4 - settings: - size: '60' - autocomplete_path: taxonomy/autocomplete - placeholder: '' - module: taxonomy status: 1 langcode: und