Problem/Motivation
As long as field_storage_config and field_config are not validatable (see #2164373-28: [META] Untie config validation from form validation — enables validatable Recipes, decoupled admin UIs …, it will be difficult to build a "Field UI 2.0" with confidence, and we definitely won't be able to create such a thing as a decoupled JS application.
This would also allow us to remove the following in \Drupal\Tests\field\Kernel\FieldStorageCrudTest:
// TODO : test creation with
// - a full fledged $field structure, check that all the values are there
// - a minimal $field structure, check all default values are set
// defer actual $field comparison to a helper function, used for the two cases above
Proposed resolution
Remove form-coupled validation logic from:
field_storage_config-
\Drupal\field_ui\Form\FieldStorageAddForm::validateForm()\Drupal\field_ui\Form\FieldStorageAddForm::validateAddNew()\Drupal\field_ui\Form\FieldStorageAddForm::validateAddExisting()\Drupal\field_ui\Form\FieldStorageAddForm::fieldNameExists()\Drupal\field_ui\Form\FieldStorageConfigEditForm::validateCardinality()
field_config-
\Drupal\field\Entity\FieldConfig::postCreate()\Drupal\field\Entity\FieldConfig::preSave()\Drupal\field_ui\Form\FieldConfigEditForm::validateForm()
… and keep the existing test coverage the same, at most expand it.
Note that additional validation constraints will be necessary beyond what already exists, because a form-based UI only allows certain inputs, not arbitrary inputs, which are possible via an API.
Remaining tasks
The constraint MatchesOtherConfigValue needs testssee child issue, skipping extra tests- The constraint NoEntitiesExistYetWithHigherCardinality needs tests
User interface changes
None.
API changes
None.
Data model changes
None.
Release notes snippet
TBD
Issue fork drupal-3324140
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
wim leersWorking on this 🤓🥳
Comment #4
wim leersAnalysis completed. Pushed as a commit that says what constraints we should implement.
… and it shockingly passed tests! Clearly Drupal does not verify that validation constraints defined in the config schema actually exist 😱
Created #3324526: Validation constraints in config schema that don't exist should trigger error for that.
Comment #7
wim leersIf I try to run the test introduced by #3324984: Create test that reports % of config entity types (and config schema types) that is validatable while this merge request is applied, I get an error message. Turns out that there's a wrong config schema change here 😅
But … that really just points out how weak the DX is around config schemas 🫣
Pushed fix: e21361724e.
Comment #8
wim leersHow much progress does this MR help us make? Let's use #3324984: Create test that reports % of config entity types (and config schema types) that is validatable to answer that question!
Conclusion: the test coverage is able to detect and identify that there is indeed significant progress, but also that the validation constraints on
field.storage.*.*are still inadequate. It even shows exactly what's missing:(there are two missing pieces:
indexesand the many possible per-field type settings — which indeed had a@todoin the current merge request, because I was unsure how to address it — now it's starting to become clear how we can address it! 👍)and:
That shows that in order for this issue to achieve actual validatability of
FieldStorageConfigandFieldConfigentity types, we have a lot more work to do: we need to add validation constraints to all of the per-field type configurability too! 😳😳😳😳But … of course … that actually makes sense 😅 That means we'll have to somehow split this issue up.
Comment #9
wim leers#2920682: Add config validation for plugin IDs landed, this MR needed to be updated. Just did that 👍 This MR is now a bit smaller again 🥳 Also addressed all of @larowlan's early observations 🤓
I believe the next piece we can reasonably extract (because it too would be useful for config other than
Field(Storage)Config) would be:ImmutableFields(at least one other example:Editorconfig entity'sformat)MachineName(all over the place — at least one other example:FilterFormatconfig entity'sformatproperty) → already has an issue: #2920678: Add config validation for the allowed characters of machine names 🥳I'm hoping @phenaproxima wants to take on
MachineNamenext 🤓The MR is failing for nonsensical reasons:
…
composer.jsonhas not been touched at all. 😳Comment #10
wim leersThe latest commit I pushed to address @larowlan's
UniqueFieldremark results in this locally:⇒
UniqueFieldis the wrong constraint here, so despite https://git.drupalcode.org/project/drupal/-/merge_requests/3047/diffs?co... technically being a bugfix, we can't actually use that constraint here. That's a mistake I made.We need a new constraint, that uses
\Drupal\Core\Entity\Plugin\Validation\Constraint\CompositeConstraintBase. Something likeUniqueFieldCombination, which allows expressing "whatever values these fields contain, they need to be a unique combination across all entities of this type".For
FieldStorageConfigthat'd befor
FieldConfigthat'd be(One could argue that these are enforced implicitly thanks to those exact unique combinations being used to construct the entity ID … but they are not the "entity keys" — the
idis! Besides, that'd mean an error not at validation time, but post-validation: at the time when it being written to the database… that's not a good UX.)Thoughts, @larowlan?
Comment #11
larowlanYeah I think if we're working towards making this usable for API clients, I agree that being able to prevent it with a validation error rather than a DB exception feels like a nicer experience
Comment #13
borisson_Is this currently blocked on writing and implementing the proposed
UniqueFieldCombination?Comment #14
wim leersNeeds to be rebased now that #2920678: Add config validation for the allowed characters of machine names is in.
#13: yes, it is. And everything else that still needs validation in those 2 config entities. Per #8:
So it's especially the latter that still needs more attention.
Comment #15
wim leersIt seems that many of the 222 failures are originating from the previously discovered bug in
NotNullConstraintValidator— see #3364109-5: Configuration schema & required values: add test coverage for `nullable: true` validation support.Borrowing the fix from that issue…
Comment #16
wim leersImplemented the
UniqueFieldCombinationconstraint as discussed between @larowlan and I in #10 + #11.Tests still needed. Clean-up likely still needed too. First trying to get this MR green and fully validating both config entity types…
Comment #17
wim leersAnd one more push on
FieldConfig, which meansFieldConfigValidationTestshould be passing tests now too! 🤞Next up:
BundleExistsMatchesComment #18
wim leersComment #19
wim leersHere's a new
EntityBundleExistsconstraint, with explicit test coverage for bothFieldConfigValidationTestandBaseFieldOverrideValidationTest.Hopefully @phenaproxima will beat me to it, but the last remaining constraint we're missing is the
Matchesconstraint. Commenting it out for now to observe how many failures remain.Beyond
Matches, we still need detailed test coverage for each of the individual constraints. But the end is in sight! 🥳Comment #20
wim leersA lot of seemingly legitimate
test failures … 🤔 🕵️
Comment #21
wim leersBesides #20, the commits since #19 made
BaseFieldOverrideValidationTestpass tests but notFieldConfigValidationTest. These 2 commits should make both pass.Comment #22
wim leersGreat! Now the prime remaining problem is indeed #20.
\Drupal\KernelTests\Core\Field\FieldSettingsTest::testConfigurableFieldSettings()is pretty weird 😳. It does:Note that only
FieldConfigis saved, notFieldStorageConfig!Comment #23
wim leers@lauriii just surfaced #3165822: [PP-1] Creating comment field w/o a comment type is allowed, which further confirms the need for this 🤓
Comment #24
wim leersI won't have time to finish my investigation into #2327883: Field [storage] config have incomplete settings until they are saved to get this to green prior to being AFK for the next 5 workdays. I'll be back Monday the 24th of July, so unassigning.
It's possible we'll first need to solve #2327883: Field [storage] config have incomplete settings until they are saved, to allow removing the one line that @phenaproxima just questioned in his review last night. That one line is currently required to not violate the
RequiredConfigDependenciesconstraint. Uncomment that one line and you should see failures triggered by that validation constraint inFieldConfigValidationTest.Comment #25
lauriiiComment #26
phenaproximaAfter wrangling this for a whole day, I figured...what the hell is the point of adding that addDependency() call, which breaks a bunch of tests in weird ways due to the inherent strangeness of field config architecture, when we could just work around it in the relevant test, and explain our reasoning with a comment?
Comment #27
smustgrave commentedMoving to NW for #26 comment.
Also are additional tests needed?
Comment #28
wim leersWill do a deep review of where we are right now, but HUGE thanks to @phenaproxima for getting this to green! 🥳
#2327883: Field [storage] config have incomplete settings until they are saved is now very close, so we hopefully will soon be unblocked here!
Comment #29
wim leersComment #30
wim leersWhile waiting for #2327883: Field [storage] config have incomplete settings until they are saved to finally land, let's move forward with this one.
#26: that looks like a fine work-around — the best we can do for now! 👍 Thanks for figuring that out! 🧙😄
There's still plenty of
@todos left. 😇But there's also plenty of things that already exist in this MR that would also help other config become validatable. I identified two, and created new issues for them: #3382580: Add new `ImmutableProperties` constraint + #3382581: Add new `EntityBundleExists` constraint.
Comment #31
wim leersThis is now postponed on:
Comment #32
phenaproximaComment #33
wim leers#2327883: Field [storage] config have incomplete settings until they are saved landed 👍
Comment #34
wim leers#3382580: Add new `ImmutableProperties` constraint landed.
Comment #35
wim leers#3382581: Add new `EntityBundleExists` constraint landed. Time to catch this MR up on ~5 months of upstream changes 😅
Comment #36
wim leersFrom
20 files, +851, -4to11 files, +570, -17— thanks toComment #37
wim leersComment #38
wim leersDid a big push forward! One additional validation constraint, simplified another constraint that was added to this MR many months ago, removed ALL
NotNullconstraints thanks toFullyValidatableand triaged the remaining@todos.Comment #39
phenaproximaJust to note it in writing: I'm not marking the following config schema types as fully validatable right now, because their supported default values (for example,
IntegerItem's defaultminsetting is''(empty string), which is nonsense from a configuration standpoint) conflict with the logic in\Drupal\Core\Config\StorableConfigBase::castValue(), which specifically treats empty strings as NULL for integer and floats:I'm not exactly sure what the correct fix for this is, but it's definitely not something to fix in this issue without blowing up the scope.
Comment #40
wim leersComment #41
wim leers#3421626: Mark config schema types (field.field_settings.* and field.storage_settings.*)) for field types that have no settings as fully validatable landed! Time for an update here 😄
Comment #44
bbralaScary rebase, so made a new branch first to see how it handles itself.
Comment #45
borisson_I don't see the tests being run on drupal ci, so setting this to needs review to see if that triggers them to start.
Comment #47
bbralaSeems good enough, moving to main MR, shoudln't need 'Needs review' :)
Comment #48
bbralaTodo: re-addthe creation of the entity types removed in one of last 2 commits
Comment #49
bbralaWell at least tests are close to OK again so this can be worked on again.
Comment #50
borisson_Answered some of the comments.
Comment #51
wim leersSo glad to see this moving forward again! 🤓
Also, I had to do this yesterday:
That's for XB over at #3512433: Provide visibility into which (core) field types (74%), field type props (63%) can be mapped into Content Type Templates vs not, and which field widgets (36%) are supported, fixing this would allow me to remove those exclusions!
Comment #52
bbralaComment #53
bbralaAlthough there is some missing test:
Our tests are green :x
Comment #54
bbralaI've split two issues for the missing tests.
Comment #55
bbralaWhile working on #3513034: Implement MatchesOtherConfigValue tests i kinda concluded it seems kinda unneeded since there are loads of places where this validator is triggered in the tests showing it working.
Examples:
https://git.drupalcode.org/project/drupal/-/merge_requests/3047/diffs#25...
https://git.drupalcode.org/project/drupal/-/merge_requests/3047/diffs#25...
https://git.drupalcode.org/project/drupal/-/merge_requests/3047/diffs#25...
And quite a few more.
Comment #56
bbralaPosponed on #3513034: Implement MatchesOtherConfigValue tests
Comment #57
damienmckenna@bbrala: I think you linked to the wrong issue there :)
Comment #58
bbralayeah just noticed, thanks!
Comment #59
bbralaComment #60
bbralaComment #62
bbrala#3541535: Make the `field_config_base` structure fully validatable by adding a StringEqualsConcatenatedValuesConstraint was merged, which is good.
#3513035: New NoFieldItemsExistWithHigherCardinality constraint is in need review and looks pretty mergable.
When the second is merged, we might be close. I'll do a rebase here for now.
Comment #63
bbrala#3512962: Add validation to field.storage.*.* indexes landed.