Skip to content
Snippets Groups Projects
Verified Commit 93a509c6 authored by Lee Rowlands's avatar Lee Rowlands
Browse files

Issue #3345149 by lauriii, shoroshanska, ranjith_kumar_k_u, quietone,...

Issue #3345149 by lauriii, shoroshanska, ranjith_kumar_k_u, quietone, smustgrave, tim.plunkett, mlncn, drugan, narendraR: Extra Default value field when adding a field with an unlimited values
parent bf22362c
No related branches found
No related tags found
42 merge requests!54479.5.x SF update,!5014Issue #3071143: Table Render Array Example Is Incorrect,!4868Issue #1428520: Improve menu parent link selection,!4594Applying patch for Views Global Text area field to allow extra HTML tags. As video, source and iframe tag is not rendering. Due to which Media embedded video and remote-video not rendering in Views Global Text area field.,!3878Removed unused condition head title for views,!38582585169-10.1.x,!3818Issue #2140179: $entity->original gets stale between updates,!3742Issue #3328429: Create item list field formatter for displaying ordered and unordered lists,!3731Claro: role=button on status report items,!3668Resolve #3347842 "Deprecate the trusted",!3651Issue #3347736: Create new SDC component for Olivero (header-search),!3546refactored dialog.pcss file,!3531Issue #3336994: StringFormatter always displays links to entity even if the user in context does not have access,!3502Issue #3335308: Confusing behavior with FormState::setFormState and FormState::setMethod,!3452Issue #3332701: Refactor Claro's tablesort-indicator stylesheet,!3451Issue #2410579: Allows setting the current language programmatically.,!3355Issue #3209129: Scrolling problems when adding a block via layout builder,!3226Issue #2987537: Custom menu link entity type should not declare "bundle" entity key,!3154Fixes #2987987 - CSRF token validation broken on routes with optional parameters.,!3147Issue #3328457: Replace most substr($a, $i) where $i is negative with str_ends_with(),!3146Issue #3328456: Replace substr($a, 0, $i) with str_starts_with(),!3133core/modules/system/css/components/hidden.module.css,!31312878513-10.1.x,!2812Issue #3312049: [Followup] Fix Drupal.Commenting.FunctionComment.MissingReturnType returns for NULL,!2614Issue #2981326: Replace non-test usages of \Drupal::logger() with IoC injection,!2378Issue #2875033: Optimize joins and table selection in SQL entity query implementation,!2334Issue #3228209: Add hasRole() method to AccountInterface,!2062Issue #3246454: Add weekly granularity to views date sort,!1591Issue #3199697: Add JSON:API Translation experimental module,!1255Issue #3238922: Refactor (if feasible) uses of the jQuery serialize function to use vanillaJS,!1105Issue #3025039: New non translatable field on translatable content throws error,!1073issue #3191727: Focus states on mobile second level navigation items fixed,!877Issue #2708101: Default value for link text is not saved,!844Resolve #3036010 "Updaters",!673Issue #3214208: FinishResponseSubscriber could create duplicate headers,!617Issue #3043725: Provide a Entity Handler for user cancelation,!579Issue #2230909: Simple decimals fail to pass validation,!560Move callback classRemove outside of the loop,!555Issue #3202493,!485Sets the autocomplete attribute for username/password input field on login form.,!30Issue #3182188: Updates composer usage to point at ./vendor/bin/composer,!23Issue #2879087: Use comment access handler instead of hardcoding permissions
......@@ -350,13 +350,27 @@ protected function defaultValueWidget(FormStateInterface $form_state) {
$definition->setRequired(FALSE);
$definition->setDescription('');
// Use the widget currently configured for the 'default' form mode, or
// fallback to the default widget for the field type.
/** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $entity_form_display */
$entity_form_display = \Drupal::service('entity_display.repository')
->getFormDisplay($entity->getEntityTypeId(), $entity->bundle());
$widget = $entity_form_display->getRenderer($this->getFieldDefinition()->getName());
if (!$widget) {
$widget = \Drupal::service('plugin.manager.field.widget')->getInstance(['field_definition' => $this->getFieldDefinition()]);
/** @var \Drupal\Core\Field\WidgetPluginManager $field_widget_plugin_manager */
$field_widget_plugin_manager = \Drupal::service('plugin.manager.field.widget');
// Use the widget currently configured for the 'default' form mode, or
// fallback to the default widget for the field type.
if (($configuration = $entity_form_display->getComponent($definition->getName())) && isset($configuration['type'])) {
// Get the plugin instance manually to ensure an up-to-date field
// definition is used.
// @see \Drupal\Core\Entity\Entity\EntityFormDisplay::getRenderer
$widget = $field_widget_plugin_manager->getInstance([
'field_definition' => $definition,
'form_mode' => $entity_form_display->getOriginalMode(),
'prepare' => FALSE,
'configuration' => $configuration,
]);
}
else {
$widget = $field_widget_plugin_manager->getInstance(['field_definition' => $definition]);
}
$form_state->set('default_value_widget', $widget);
......
......@@ -157,6 +157,10 @@ public function testEntityReferenceDefaultConfigValue() {
'default_value_input[' . $field_name . '][1][target_id]' => $referenced_node_type2->label() . ' (' . $referenced_node_type2->id() . ')',
];
$this->drupalGet('admin/structure/types/manage/reference_content/fields/node.reference_content.' . $field_name);
$this->assertSession()->fieldExists("default_value_input[{$field_name}][0][target_id]");
$this->assertSession()->fieldNotExists("default_value_input[{$field_name}][1][target_id]");
$this->submitForm([], 'Add another item');
$this->assertSession()->fieldExists("default_value_input[{$field_name}][1][target_id]");
$this->submitForm($field_edit, 'Save settings');
// Check that the field has a dependency on the default value.
......
......@@ -31,6 +31,7 @@ class FormTest extends FieldTestBase {
'options',
'entity_test',
'locale',
'field_ui',
];
/**
......@@ -75,6 +76,7 @@ protected function setUp(): void {
$web_user = $this->drupalCreateUser([
'view test entity',
'administer entity_test content',
'administer entity_test fields',
]);
$this->drupalLogin($web_user);
......@@ -271,6 +273,11 @@ public function testFieldFormUnlimited() {
->setComponent($field_name)
->save();
// Verify that only one "Default value" field
// exists on the Manage field display.
$this->drupalGet("entity_test/structure/entity_test/fields/entity_test.entity_test.{$field_name}");
$this->assertSession()->elementsCount('xpath', "//table[@id='field-unlimited-values']/tbody/tr//input[contains(@class, 'form-text')]", 1);
// Display creation form -> 1 widget.
$this->drupalGet('entity_test/add');
$this->assertSession()->fieldValueEquals("{$field_name}[0][value]", '');
......
......@@ -4,9 +4,13 @@
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Entity\Plugin\DataType\EntityAdapter;
use Drupal\Core\Field\FieldFilteredMarkup;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\TypedData\TypedDataInterface;
use Drupal\Core\TypedData\TypedDataManagerInterface;
use Drupal\Core\Url;
use Drupal\field\FieldConfigInterface;
use Drupal\field_ui\FieldUI;
......@@ -38,8 +42,10 @@ class FieldConfigEditForm extends EntityForm {
*
* @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
* The entity type bundle info service.
* @param \Drupal\Core\TypedData\TypedDataManagerInterface $typedDataManager
* The type data manger.
*/
public function __construct(EntityTypeBundleInfoInterface $entity_type_bundle_info) {
public function __construct(EntityTypeBundleInfoInterface $entity_type_bundle_info, protected TypedDataManagerInterface $typedDataManager) {
$this->entityTypeBundleInfo = $entity_type_bundle_info;
}
......@@ -48,7 +54,8 @@ public function __construct(EntityTypeBundleInfoInterface $entity_type_bundle_in
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_type.bundle.info')
$container->get('entity_type.bundle.info'),
$container->get('typed_data_manager')
);
}
......@@ -107,7 +114,7 @@ public function form(array $form, FormStateInterface $form_state) {
'entity_id' => NULL,
];
$form['#entity'] = _field_create_entity_from_ids($ids);
$items = $form['#entity']->get($this->entity->getName());
$items = $this->getTypedData($form['#entity']);
$item = $items->first() ?: $items->appendItem();
// Add field settings for the field type and a container for third party
......@@ -122,6 +129,10 @@ public function form(array $form, FormStateInterface $form_state) {
'#weight' => 11,
];
// Create a new instance of typed data for the field to ensure that default
// value widget is always rendered from a clean state.
$items = $this->getTypedData($form['#entity']);
// Add handling for default value.
if ($element = $items->defaultValuesForm($form, $form_state)) {
$has_required = $this->hasAnyRequired($element);
......@@ -219,9 +230,15 @@ protected function actions(array $form, FormStateInterface $form_state) {
public function validateForm(array &$form, FormStateInterface $form_state) {
parent::validateForm($form, $form_state);
// Before proceeding validation, rebuild the entity to make sure it's
// up-to-date. This is needed because element validators may update form
// state, and other validators use the entity for validating the field.
// @todo remove in https://www.drupal.org/project/drupal/issues/3372934.
$this->entity = $this->buildEntity($form, $form_state);
if (isset($form['default_value']) && (!isset($form['set_default_value']) || $form_state->getValue('set_default_value'))) {
$item = $form['#entity']->get($this->entity->getName());
$item->defaultValuesFormValidate($form['default_value'], $form, $form_state);
$items = $this->getTypedData($form['#entity']);
$items->defaultValuesFormValidate($form['default_value'], $form, $form_state);
}
}
......@@ -234,7 +251,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
// Handle the default value.
$default_value = [];
if (isset($form['default_value']) && (!isset($form['set_default_value']) || $form_state->getValue('set_default_value'))) {
$items = $form['#entity']->get($this->entity->getName());
$items = $this->getTypedData($form['#entity']);
$default_value = $items->defaultValuesFormSubmit($form['default_value'], $form, $form_state);
}
$this->entity->setDefaultValue($default_value);
......@@ -271,4 +288,17 @@ public function getTitle(FieldConfigInterface $field_config) {
return $field_config->label();
}
/**
* Gets typed data object for the field.
*
* @param \Drupal\Core\Entity\FieldableEntityInterface $parent
* The parent entity that the field is attached to.
*
* @return \Drupal\Core\TypedData\TypedDataInterface
*/
private function getTypedData(FieldableEntityInterface $parent): TypedDataInterface {
$entity_adapter = EntityAdapter::createFromEntity($parent);
return $this->typedDataManager->create($this->entity, $this->entity->getDefaultValue($parent), $this->entity->getName(), $entity_adapter);
}
}
......@@ -26,7 +26,8 @@ protected function setUp(): void {
parent::setUp();
$entity_type_bundle_info = $this->createMock('\Drupal\Core\Entity\EntityTypeBundleInfoInterface');
$this->fieldConfigEditForm = new FieldConfigEditForm($entity_type_bundle_info);
$typed_data = $this->createMock('\Drupal\Core\TypedData\TypedDataManagerInterface');
$this->fieldConfigEditForm = new FieldConfigEditForm($entity_type_bundle_info, $typed_data);
}
/**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment