Problem/Motivation
With Drupal 9.5.9, Reference Table Formatter 8.x-1.2, Entity Reference Revisions 8.x-1.10, Paragraphs 8.x-1.15. For peoples account a form with a set of fields.
In manage display, uri admin/config/people/accounts/display
, clicking the button in the Operations column to access the format settings, for the Table of Fields formatter from the Reference Table Formatter module, of a field of Entity Reference Revisions type on entities of paragraphs type, produce a lot of warning in the log, from the function copyFormValuesToEntity()
of the file core/modules/field_ui/src/Form/EntityDisplayFormBase.php
,
Warning : Undefined array key "field_courriel" dans Drupal\field_ui\Form\EntityDisplayFormBase->copyFormValuesToEntity() (RootFolder/web/core/modules/field_ui/src/Form/EntityDisplayFormBase.php ligne 594)
#0 RootFolder/web/core/includes/bootstrap.inc(347): _drupal_error_handler_real()
#1 RootFolder/web/core/modules/field_ui/src/Form/EntityDisplayFormBase.php(594): _drupal_error_handler()
#2 RootFolder/web/core/lib/Drupal/Core/Entity/EntityForm.php(293): Drupal\field_ui\Form\EntityDisplayFormBase->copyFormValuesToEntity()
#3 RootFolder/web/core/lib/Drupal/Core/Entity/EntityForm.php(170): Drupal\Core\Entity\EntityForm->buildEntity()
#4 [internal function]: Drupal\Core\Entity\EntityForm->afterBuild()
#5 RootFolder/web/core/lib/Drupal/Core/Form/FormBuilder.php(1083): call_user_func_array()
#6 RootFolder/web/core/lib/Drupal/Core/Form/FormBuilder.php(1075): Drupal\Core\Form\FormBuilder->doBuildForm()
#7 RootFolder/web/core/lib/Drupal/Core/Form/FormBuilder.php(1075): Drupal\Core\Form\FormBuilder->doBuildForm()
#8 RootFolder/web/core/lib/Drupal/Core/Form/FormBuilder.php(1075): Drupal\Core\Form\FormBuilder->doBuildForm()
#9 RootFolder/web/core/lib/Drupal/Core/Form/FormBuilder.php(1075): Drupal\Core\Form\FormBuilder->doBuildForm()
#10 RootFolder/web/core/lib/Drupal/Core/Form/FormBuilder.php(1075): Drupal\Core\Form\FormBuilder->doBuildForm()
#11 RootFolder/web/core/lib/Drupal/Core/Form/FormBuilder.php(449): Drupal\Core\Form\FormBuilder->doBuildForm()
#12 RootFolder/web/core/lib/Drupal/Core/Form/FormBuilder.php(633): Drupal\Core\Form\FormBuilder->rebuildForm()
#13 RootFolder/web/core/lib/Drupal/Core/Form/FormBuilder.php(325): Drupal\Core\Form\FormBuilder->processForm()
#14 RootFolder/web/core/lib/Drupal/Core/Controller/FormController.php(73): Drupal\Core\Form\FormBuilder->buildForm()
#15 [internal function]: Drupal\Core\Controller\FormController->getContentResult()
#16 RootFolder/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array()
#17 RootFolder/web/core/lib/Drupal/Core/Render/Renderer.php(580): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#18 RootFolder/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext()
#19 RootFolder/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext()
#20 RootFolder/vendor/symfony/http-kernel/HttpKernel.php(169): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#21 RootFolder/vendor/symfony/http-kernel/HttpKernel.php(81): Symfony\Component\HttpKernel\HttpKernel->handleRaw()
#22 RootFolder/web/core/lib/Drupal/Core/StackMiddleware/Session.php(58): Symfony\Component\HttpKernel\HttpKernel->handle()
#23 RootFolder/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle()
#24 RootFolder/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle()
#25 RootFolder/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass()
#26 RootFolder/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle()
#27 RootFolder/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle()
#28 RootFolder/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle()
#29 RootFolder/web/core/lib/Drupal/Core/DrupalKernel.php(718): Stack\StackedHttpKernel->handle()
#30 RootFolder/web/index.php(19): Drupal\Core\DrupalKernel->handle()
#31 {main}
Warning : Trying to access array offset on value of type null dans Drupal\field_ui\Form\EntityDisplayFormBase->copyFormValuesToEntity() (RootFolder/web/core/modules/field_ui/src/Form/EntityDisplayFormBase.php ligne 596)
#0 RootFolder/web/core/includes/bootstrap.inc(347): _drupal_error_handler_real()
#1 RootFolder/web/core/modules/field_ui/src/Form/EntityDisplayFormBase.php(596): _drupal_error_handler()
#2 RootFolder/web/core/lib/Drupal/Core/Entity/EntityForm.php(293): Drupal\field_ui\Form\EntityDisplayFormBase->copyFormValuesToEntity()
#3 RootFolder/web/core/lib/Drupal/Core/Entity/EntityForm.php(170): Drupal\Core\Entity\EntityForm->buildEntity()
#4 [internal function]: Drupal\Core\Entity\EntityForm->afterBuild()
#5 RootFolder/web/core/lib/Drupal/Core/Form/FormBuilder.php(1083): call_user_func_array()
#6 RootFolder/web/core/lib/Drupal/Core/Form/FormBuilder.php(1075): Drupal\Core\Form\FormBuilder->doBuildForm()
#7 RootFolder/web/core/lib/Drupal/Core/Form/FormBuilder.php(1075): Drupal\Core\Form\FormBuilder->doBuildForm()
#8 RootFolder/web/core/lib/Drupal/Core/Form/FormBuilder.php(1075): Drupal\Core\Form\FormBuilder->doBuildForm()
#9 RootFolder/web/core/lib/Drupal/Core/Form/FormBuilder.php(1075): Drupal\Core\Form\FormBuilder->doBuildForm()
#10 RootFolder/web/core/lib/Drupal/Core/Form/FormBuilder.php(1075): Drupal\Core\Form\FormBuilder->doBuildForm()
#11 RootFolder/web/core/lib/Drupal/Core/Form/FormBuilder.php(449): Drupal\Core\Form\FormBuilder->doBuildForm()
#12 RootFolder/web/core/lib/Drupal/Core/Form/FormBuilder.php(633): Drupal\Core\Form\FormBuilder->rebuildForm()
#13 RootFolder/web/core/lib/Drupal/Core/Form/FormBuilder.php(325): Drupal\Core\Form\FormBuilder->processForm()
#14 RootFolder/web/core/lib/Drupal/Core/Controller/FormController.php(73): Drupal\Core\Form\FormBuilder->buildForm()
#15 [internal function]: Drupal\Core\Controller\FormController->getContentResult()
#16 RootFolder/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array()
#17 RootFolder/web/core/lib/Drupal/Core/Render/Renderer.php(580): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#18 RootFolder/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext()
#19 RootFolder/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext()
#20 RootFolder/vendor/symfony/http-kernel/HttpKernel.php(169): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#21 RootFolder/vendor/symfony/http-kernel/HttpKernel.php(81): Symfony\Component\HttpKernel\HttpKernel->handleRaw()
#22 RootFolder/web/core/lib/Drupal/Core/StackMiddleware/Session.php(58): Symfony\Component\HttpKernel\HttpKernel->handle()
#23 RootFolder/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle()
#24 RootFolder/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle()
#25 RootFolder/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass()
#26 RootFolder/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle()
#27 RootFolder/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle()
#28 RootFolder/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle()
#29 RootFolder/web/core/lib/Drupal/Core/DrupalKernel.php(718): Stack\StackedHttpKernel->handle()
#30 RootFolder/web/index.php(19): Drupal\Core\DrupalKernel->handle()
#31 {main}
...
For one click, in our case, 97 warnings happen. Two series exist, and the total number is N = n0xm0 + n1x2m1
with (n0,m0;n1,m1) = (17,5;2,3)
where ni
are number of fields and mi
number of lines with a warning. The first one is for fields, the second for extra. The corresponding lines are 594, 596, 611, 612, 613 for the first series and 624, 629, 630 for the second series. The function with line numbers,
584 protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) {
585 $form_values = $form_state->getValues();
586
587 if ($this->entity instanceof EntityWithPluginCollectionInterface) {
588 // Do not manually update values represented by plugin collections.
589 $form_values = array_diff_key($form_values, $this->entity->getPluginCollections());
590 }
591
592 // Collect data for 'regular' fields.
593 foreach ($form['#fields'] as $field_name) {
594 $values = $form_values['fields'][$field_name];
595
596 if ($values['region'] == 'hidden') {
597 $entity->removeComponent($field_name);
598 }
599 else {
600 $options = $entity->getComponent($field_name);
601
602 // Update field settings only if the submit handler told us to.
603 if ($form_state->get('plugin_settings_update') === $field_name) {
604 // Only store settings actually used by the selected plugin.
605 $default_settings = $this->pluginManager->getDefaultSettings($options['type']);
606 $options['settings'] = isset($values['settings_edit_form']['settings']) ? array_intersect_key($values['settings_edit_form']['settings'], $default_setting>
607 $options['third_party_settings'] = $values['settings_edit_form']['third_party_settings'] ?? [];
608 $form_state->set('plugin_settings_update', NULL);
609 }
610
611 $options['type'] = $values['type'];
612 $options['weight'] = $values['weight'];
613 $options['region'] = $values['region'];
614 // Only formatters have configurable label visibility.
615 if (isset($values['label'])) {
616 $options['label'] = $values['label'];
617 }
618 $entity->setComponent($field_name, $options);
619 }
620 }
621
622 // Collect data for 'extra' fields.
623 foreach ($form['#extra'] as $name) {
624 if ($form_values['fields'][$name]['region'] == 'hidden') {
625 $entity->removeComponent($name);
626 }
627 else {
628 $entity->setComponent($name, [
629 'weight' => $form_values['fields'][$name]['weight'],
630 'region' => $form_values['fields'][$name]['region'],
631 ]);
632 }
633 }
634 }
These problems occur in the same way with Drupal 10.1.0-beta1, Reference Table Formatter 2.0.0-alpha2, Entity Reference Revisions 8.x-1.10, Paragraphs 8.x-1.15.
The isset function could be a solution, but may be not a good solution. A deeper problem may exist.
We observe that all the fields producing an error are after the reference field (i.e. the field with the formatter) for the alphabetical order. And fields before produce no error. Moreover when the reference field appends a process is loaded which leads to the function where the warning are produced. Warnings seem append since some data are missing. And the data are missing since the process is loaded before all the fields have been processed.
Therefore a solution may be to disable the intermediary process for the reference field.
Investigations show that the parameter which controls the intermediary process is #after_build
, with the line,
if (isset($element['#after_build']) && !isset($element['#after_build_done'])) {
in core/lib/Drupal/Core/Form/FormBuilder.php
line 1081 in function doBuildForm()
. And the presence of this key in the element/form comes from,
'settings' => $settings_form,
in modules/field_ui/src/Form/EntityDisplayFormBase.php
line 398 in function buildFieldRow()
, with the line 386,
$settings_form = $plugin->settingsForm($form, $form_state);
This settingsForm()
function is the one of Reference Table Formatter module, file reference_table_formatter/src/FormatterBase.php
line 82.
Steps to reproduce
Proposed resolution
A solution may be to neutralize the key #after_build
from the function settingsForm()
of the Reference Table Formatter module in the file reference_table_formatter/src/FormatterBase.php
. With,
if (isset($form['#after_build'])) {
$form['#after_build'] = NULL;
}
since then isset($element['#after_build'])
is FALSE
.
For module Reference Table Formatter 2.0.0-alpha2, the function settingsForm()
is in another file,
reference_table_formatter/src/Plugin/Field/FieldFormatter/EntityReferenceTableFormatter.php
.
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet