Currently the mapFromStorageRecords() / mapToStorageRecord() methods only allow direct mapping of db column names to field names.
This works because, on load, new $entity_class(array('field_name' => 'value'))
automatically assumes "delta 0, first property".
But this forbids using field types with several properties for base fields, which in turn blocks "single set of field types for base fields & configurable fields".
Discussed with @fago and @plach in Vienna:
We should support both:
- the current default mapping - if "column name = a field name" -> the value gets assigned to delta 0, first property
- a mapping with property names - if "column name = [a field name]__[a property name]" -> the value gets assigned to delta 0, the right property
Comment | File | Size | Author |
---|---|---|---|
#44 | interdiff.txt | 1.06 KB | amateescu |
#44 | 2142549-44.patch | 20.85 KB | amateescu |
Comments
Comment #1
Berdir+1, thanks for opening the issue.
Small note on "This works because, on load, new $entity_class(array('field_name' => 'value')) automatically assumes "delta 0, first property".".
What actually happens is that the value gets through the setValue() chain of the field item list class and then field item, so they have full control on how to use it, reference fields for example support both the entity and the id being passed in like that.
Two use cases in core right now could use this (that I know of), term descriptions and user signatures. Both have a issue to make it a configurable field and term description might still make it, wondering if we should just keep it as a base field, as it has some rather special behavior, like being added to comments and not rendered on the user like other fields.
Comment #2
amateescu CreditAttribution: amateescu commentedThanks as well for opening this issue!
Two more relevant use cases for core are:
Based on the two points above, I think it's worthless to spend more time working on the menu_link conversion to the new API until this issue is completed.
Furthermore, the biggest benefit of this is that we'll be able to use any "configurable" field as a base field, if we know from the start that it will be single-valued, thus completing the unification of the the two APIs on the storage front.
I think that's, in a nutshell, what I described to @yched over our beer conversation two weeks ago :)
Comment #3
larowlanIf the p1 to p9 stuff is up for discussion, I'd be willing to take a crack at rewriting it using tree based logic, where you store left and right ids etc. that would remove the 9 parents limit and mean you could query a hierarchy in one go. Is so let me know and I'll file a new issue.
Comment #4
amateescu CreditAttribution: amateescu commented@larowlan, my plan for that is in #1915056-2: Use entity reference for taxonomy parents. As you can see there, replacing the current materialized path implementation of menu links *might* be up for discussion, but we're quite far from reaching step 6 in there and it all needs to start with this issue.
I'll try to work on this tomorrow if no one else takes it until then :)
Comment #5
yched CreditAttribution: yched commented@Berdir #1: yes, basically "single set of field types for base & config fields" & "widgets / formatters on base fields" mean that the various "Turn hardcoded X into a field" tasks do not necessarily mean "turn it into a configurable field". Still makes sense for node body, for example (auto-created as a reasonable default on new node types, but the site builder might want to remove it), but not necessarily for others...
(+ Hah, just realized that Term.php currently uses two separate base fields for "description" and "description format". Nice :-p)
Comment #6
BerdirYes, user signature works exactly the same way, just like node bodies used to in 6.x. For user signatures, it was a security fix that added the format.
If we convert those to a single field (base or configurable), we e.g. also fix file usage management within them that is provided by the wysiwyg editor stuff.
Comment #7
yched CreditAttribution: yched commentedDo we want to convert one of those (term description/format, user signature/format) in this issue here, as a proof that the patch works ?
Comment #8
amateescu CreditAttribution: amateescu commentedI do :)
Comment #9
amateescu CreditAttribution: amateescu commentedThis should do it.
Comment #10
amateescu CreditAttribution: amateescu commentedAnd a small self review:
WIN!!!!11
Comment #12
amateescu CreditAttribution: amateescu commentedComment #13
BerdirNo dreditor :(
- Do we need to be more error-prone in the first snippet when getting the values? What if someone has bla and bla__value? I don't know...
- We did discuss if we need getFieldPropertyNames() at some point, I think it overlaps with other methods. Maybe use getPropertyDefinitions()?
- I think user signatures would be a better and easier proof of concept, less special cases with forum.module and I still hope that #569434: Remove taxonomy term description field; provide description field for forum taxonomy will happen, because it makes sense for those.
Comment #14
yched CreditAttribution: yched commented- not sure about supporting bla & bla__second property. I'd say this adds confusion ?
- getFieldPropertyNames() / getPropertyDefinitions() :
You can use getFieldPropertyNames() on a mere FieldDefinition.
For getPropertyDefinitions() you need an instanciated FieldItem object - do we have one at this point ?
This area is a bit of a mess right now...
- for base fields, $definition->getFieldPropertyNames() creates a one-off FieldItem and calls its getPropertyDefinitions()
- for config fields, $definition->getFieldPropertyNames() uses the static FieldItem::schema()
This is not exactly the same thing, computed values are missing in the latter (but no biggie for our case here)
We know we want to move the static schema() method up from ConfigFieldItemInterface to FieldItemInterface at some point, and this is the info we'd need here (we're dealing with storage). I know @amateescu started by doing that right now as part of this patch, and then preferred to go simpler.
So maybe keep the code in based on getFieldPropertyNames() for now and move it to schema() later on ?
Comment #15
Berdiragreed that we can't support bla and bla__something, just wondering about better error handling for that case, right now, something very weird would happen if you'd do that :)
We have $field_items, so we also have a single field item and could call offsetGet(0)->getPropertyDefinitions() (#2110467: Add first(), get($index) and possibly other methods to ListInterface would make that first()->getPropertyDefinitions(), please review :))
Just wanted to point it out, if you think getFieldPropertyNames() is ok to use for now, then I'm fine with that too.
Comment #16
yched CreditAttribution: yched commentedSo yeah, this area about property names / schema columns is really fuzzy ATM.
What we need here is the schema info rather than the properties info, but using the properties info should work for now.
I opened #2144327: Make all field types provide a schema() for sorting this out, and meanwhile, we can move forward here using whatever solution based on properties, preferably with a "@todo reconsider after https://drupal.org/node/2144327" ?
Comment #17
amateescu CreditAttribution: amateescu commented@Berdir, discussed a bit with @yched in IRC and while we could throw an exception in the case where we have both "bla" and "bla__value" columns, I don't think it adds much value here since we already have a plan to make the schema generation dynamic, so there'll be no place for human error anymore.
About user signatures being a better PoC, I tried to convert them and I ended up in some misterious typed data validation errors, so I will open a followup (postponed on this one) to figure out the problem there.
Also, this patch actually makes #569434: Remove taxonomy term description field; provide description field for forum taxonomy easier, just remove the base field definition, remove code from the form controller that handles it and provide it as a default config.
Here's an updated patch with more comments and variable renames that try to provide some background for the new code.
Comment #18
yched CreditAttribution: yched commented@amateescu: Thanks!
Works for me, but I'll leave some time for others to chime in before pushing RTBC
Comment #19
amateescu CreditAttribution: amateescu commentedPosted the patch for user signatures in #1548204-16: Remove user signature and move it to contrib and postponed it on this one.
Comment #20
fagoMaybe the comment should say that we skip the levels if possible now, as it cannot always skip the property level any more.
Looping over the columns multiple times here seems in-efficient.
Instead of looking up the schema, should we look whether there is data in the "$name__$property" instead?
This should just do array_keys($field_items[0]->getPropertyDefinitinos()) for now as else it creates new item objects anyway....
what? defaults are not applied on schema level, but on entity / field api level. This is unrelated though.
Should be $term1->description->processed
Same here.
->processed
again
Comment #21
amateescu CreditAttribution: amateescu commentedComment #23
amateescu CreditAttribution: amateescu commentedComment #24
fago#20.2 still bugs me. It's not only that is in-efficient, what bugs me most is that we have to in which table it's stored. We shouldn't have to do that, but have a clear mapping based on the field definition (translatability, revisionability).
We'll need #2144631: Add a revisionable key to field definitions for being able to do that first though. thoughts?
Comment #25
amateescu CreditAttribution: amateescu commentedI agree that the logic should eventually be based on field definition properties, so how about this interdiff? If we postpone this issue, the dependency stack is getting too high IMO :)
Comment #27
fagoYes, I think that would be reasonable
Comment #28
fago25: 2142549-25.patch queued for re-testing.
Comment #30
cosmicdreams CreditAttribution: cosmicdreams commentedI'm trying to follow along here, but I'm having trouble understanding if this issue is like the effort Dave Reid is putting into multifield : https://drupal.org/project/multifield
Multifield intends to provide a better (IMO) architectural solution to field collection by providing a system driven way of handling the schema of your administratively controlled field. It does this by creating field tables with multiple columns. So on the surface it sounds like the same effort you're doing here (but for Drupal 7).
My question is:
If this API is available to developers can we build our own compounded fields with it? For example I tend to want to develop a field to handle all parts of an individual slide.
Comment #31
amateescu CreditAttribution: amateescu commented25: 2142549-25.patch queued for re-testing.
Comment #32
amateescu CreditAttribution: amateescu commented@cosmicdreams, this patch is not about building "compounded" fields, it's about letting you use fields that store data across multiple columns as base fields (stored in the base table(s) of the entity type).
Comment #33
BerdirShould this also switch to processed?
I assume we don't have any tests coverage with term descriptions and actually using a filter, because it's broken now.
processed/TextProcessed respects the text_processing setting, which defaults to FALSE, which means that this always uses check_plain() now.
We need to set the setting in the base field definition and we might need to add basic test coverage for this.
Also, this will not make the term description patch easier, because that *removes* all the custom code around that, which will then conflict with this quite bit. There might also be references in templates and similar things that could be affected, not sure, check the patch there. But I'm fine if we can move forward somehow, the other issue is currently blocked on the taxonomy maintainer (@xjm).
Comment #34
amateescu CreditAttribution: amateescu commentedThanks for catching that, fixed and added a test.
Comment #35
amateescu CreditAttribution: amateescu commentedRerolled after #2047229: Make use of classes for entity field and data definitions.
Comment #36
yched CreditAttribution: yched commentedMinor - grammar: "... when base fields are able to use formatters" ;-)
Also, we should include the issue URL (that would probably be #2144919: Allow widgets and formatters for base fields to be configured in Field UI rather than #1988612: Apply formatters and widgets to rendered entity base fields, starting with node.title)
Comment #37
yched CreditAttribution: yched commented@cosmicdreams: right, this is not about compound fields, but about allowing base fields to use the same set of field types than configurable fields, instead of currently having a de-facto, non-written restriction on field types that only store one "column/property".
This being said, and generally speaking, Dave Reid's approach for multifield should be much easier to code in D8 with Field types / widgets / formatters as OO classes - multifield is basically OO composition, the real challenge is shaping a good UI for creation and configuration. But yeah, unrelated to the task here.
Comment #38
amateescu CreditAttribution: amateescu commented:)
Comment #39
yched CreditAttribution: yched commentedOK, RTBC then ?
Comment #40
plachMinor, but could we use $field_name or similar instead of $field here? $field is usually an object.
Comment #41
yched CreditAttribution: yched commentedOh, yup, fully agreed with #40 - I thought I had commented on that in an earlier review, but apparently it got lost before I pressed "submit"...
Comment #42
amateescu CreditAttribution: amateescu commentedEntity field api team never sleeps :)
Comment #43
yched CreditAttribution: yched commentedOK, you're going to hate me...
$field_column_name is misleading, that var contains the part before the __, that is a field name.
$field_name itself is already taken, so maybe $data_field_name ?
Comment #44
amateescu CreditAttribution: amateescu commented<3
Comment #45
yched CreditAttribution: yched commented<3 and confirming RTBC :-)
Thanks!
Comment #46
pwolanin CreditAttribution: pwolanin commentedComment #47
pwolanin CreditAttribution: pwolanin commentedMarking as a beta blocker since this is blocking having translatable titles for menu links
Comment #48
catchCommitted/pushed to 8.x, thanks!