Problem/Motivation
Steps to reproduce:
- Install module
- Create new site settings entity type
- Move the Authored by field to the deactivated section in the form display configuration
- Create new instance of the entity with the new entity type, save --> error
Error:
Auf der Website ist ein unvorhergesehener Fehler aufgetreten. Bitte versuchen Sie es später nochmal.</br></br><em class="placeholder">Drupal\Core\Entity\EntityStorageException</em>: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'user_id' cannot be null: INSERT INTO {site_setting_entity_field_data} (id, type, langcode, user_id, name, fieldset, status, created, changed, default_langcode) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8, :db_insert_placeholder_9); Array
(
[:db_insert_placeholder_0] => 4
[:db_insert_placeholder_1] => footer_bottom_text
[:db_insert_placeholder_2] => de
[:db_insert_placeholder_3] =>
[:db_insert_placeholder_4] => Footer bottom text
[:db_insert_placeholder_5] => Footer
[:db_insert_placeholder_6] => 1
[:db_insert_placeholder_7] => 1562843674
[:db_insert_placeholder_8] => 1562843674
[:db_insert_placeholder_9] => 1
)
in <em class="placeholder">Drupal\Core\Entity\Sql\SqlContentEntityStorage->save()</em> (line <em class="placeholder">847</em> of <em class="placeholder">core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php</em>). <pre class="backtrace">Drupal\Core\Database\Statement->execute(Array, Array) (Line: 631)
Drupal\Core\Database\Connection->query('INSERT INTO {site_setting_entity_field_data} (id, type, langcode, user_id, name, fieldset, status, created, changed, default_langcode) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8, :db_insert_placeholder_9)', Array, Array) (Line: 358)
Drupal\Core\Database\Driver\mysql\Connection->query('INSERT INTO {site_setting_entity_field_data} (id, type, langcode, user_id, name, fieldset, status, created, changed, default_langcode) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8, :db_insert_placeholder_9)', Array, Array) (Line: 32)
Drupal\Core\Database\Driver\mysql\Insert->execute() (Line: 1052)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->saveToSharedTables(Object) (Line: 990)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->doSaveFieldItems(Object) (Line: 657)
Drupal\Core\Entity\ContentEntityStorageBase->doSave(NULL, Object) (Line: 449)
Drupal\Core\Entity\EntityStorageBase->save(Object) (Line: 838)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->save(Object) (Line: 394)
Drupal\Core\Entity\EntityBase->save() (Line: 79)
Drupal\site_settings\Form\SiteSettingEntityForm->save(Array, Object)
call_user_func_array(Array, Array) (Line: 111)
Drupal\Core\Form\FormSubmitter->executeSubmitHandlers(Array, Object) (Line: 51)
Drupal\Core\Form\FormSubmitter->doSubmitForm(Array, Object) (Line: 590)
Drupal\Core\Form\FormBuilder->processForm('site_setting_entity_footer_bottom_text_form', Array, Object) (Line: 319)
Drupal\Core\Form\FormBuilder->buildForm('site_setting_entity_footer_bottom_text_form', Object) (Line: 61)
Drupal\Core\Entity\EntityFormBuilder->getForm(Object) (Line: 99)
Drupal\site_settings\Controller\SiteSettingEntityAddController->addForm(Object, Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 582)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 151)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 693)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
</pre>
Some screenshots:



Proposed resolution
Support moving authored by field to deactivated section. Maybe just get the current user, and use it as the author, instead of using the form value, if it's always beeing hidden anyway.
Remaining tasks
Fix bug
User interface changes
None.
API changes
tbd.
Data model changes
None.
Comments
Comment #2
orlando.thoenyComment #3
anybodyYep, I can confirm this.
Comment #4
scott_euser commentedThanks for discovering this and providing thorough details. Attached patch.
Comment #5
scott_euser commentedAffects fieldsets as well, updating title.
Comment #6
anybodyThank you @scott_euser, is this a custom "trick" or did you have a look into core? I think nodes and other entities have to do a similar trick, because they also contain fields which may be hidden, but values like "created by", "created at" etc. are set correctly. I think we should do the same?
Setting the user id to "0" may have negative side-effects.
Comment #7
scott_euser commentedHappy if someone is willing to investigate and propose a solution.
Comment #8
nagy.balint commentedI did some research, it seems we can play with the default value in the baseFieldDefinitions, and that we can remove the extra entity save.
With the attached patch it will work, but on setting create it will get the "None" and 0 default value, and that will only be overriden on the first edit.
However we can define default value callbacks See trait EntityOwnerTrait
So the user id can be set similarly to "getDefaultEntityOwner() {"
And the same could be done for the fieldset i suppose by loading the entity type settings.
So that way even if the user_id or the fieldset is empty, it would call those functions to set the proper value, and then it will be right even on the create.
Comment #9
nagy.balint commentedSo something like this.
Comment #11
nagy.balint commentedI think the test fails because now without that extra save the system will actually display "Created the" and not "Saved the".
Comment #12
scott_euser commentedNice, this is way better than my original patch. Learned something new with the default value callbacks - thanks!
Comment #14
scott_euser commentedComment #16
tlthades commentedThanks, it works for me