At #1777956-35: Provide a way to define default values for entity fields raised that having empty field items in $field objects is weird - as others. We've an empty field item object by default such that this gets cloned during prototyping the field object, thus speeds up getting further field objects.
"Sometimes there is an empty FieldItem, sometimes there isn't" sounds wrong ?
I think both cases are semantically equivalent as in both cases the overall field would be empty and storage would remain the same. So whether there is an empty field item or not is not something that matters to the persistent state of the entity, however yes - the different run-time state matters in some scenarios like should an empty item be rendered or presented in a form.
Right now, I fear we need to have that items due to the performance improvements it brings us. But let's research ways to remove that empty item when it's not needed here.
Thinking about it having getPropertyInstance() call setValue(NULL) for a NULL $value also should be good enough and still use the prototyped/cloned field item when a value is given to getPropertyInstance() - but not later on. Performance wise changes later on are not interesting, so that should not be a performance regression (to be verified).
Comment | File | Size | Author |
---|---|---|---|
#38 | 1988492_empty_item_list-38-interdiff.txt | 926 bytes | Berdir |
#38 | 1988492_empty_item_list-38.patch | 5.58 KB | Berdir |
#36 | 1988492_empty_item_list-36-interdiff.txt | 707 bytes | Berdir |
#36 | 1988492_empty_item_list-36.patch | 4.68 KB | Berdir |
#33 | 1988492_empty_item_list-32.patch | 5.37 KB | Berdir |
Comments
Comment #1
fagotagging
Comment #2
fagoI'm talking of that, let's see what the bot says.
Comment #3
fagoComment #4
fagoFixed/improved comment.
Comment #6
fago#4: d8_no_empty_items.patch queued for re-testing.
Comment #8
fagotagging
Comment #9
das-peter CreditAttribution: das-peter commentedComment #10
das-peter CreditAttribution: das-peter commentedDenormalizeTest::testMarkFieldForDeletion()
needs to differentiate betweenNULL
and an empty array instead of NULL and an array withNULL
values. Since there were no other test fails we assume the services handling does this already that way.Comment #11
fagoI think we ran over that hunk already in another issue as well.
We usually use isset() for checking null values.
Else patch looks good to me. So we need to
a) verify it really removes the ugly default values
b) comes not with a performance regression
However, yched pointed out that having those empty items would be a performance regression also once we start invoking field methods on existing items (prepareView, preSave, ...)
Comment #12
yched CreditAttribution: yched commentedIf this removes the empty Item that's present in Field::$list by default, is there maybe some code in some isEmpty() somewhere that had to account for that and can now be simplified ?
Comment #13
fagoWe cannot do that, as this does not remove the possibility of having those empty items. You still can set according empty values which would have to be filtered out be the according filterEmptyItems() method.
Comment #14
das-peter CreditAttribution: das-peter commentedAnything to do about / because of this?
Changed
is_null()
to!isset()
.I ran a performance test using the xhprof-kit(using 100 loops)
Results:
The patched branch had a performance regression of
0.3%
compared to the base line. The addition of1.1%
for function calls was expected.I've tested using 489 comments (to avoid the BC-decorator on nodes) all of them shown on one page in a view formatted as table (because of #2020353: Comments aren't displayed in Views when using Format: Unformatted list and Show: Comment | Full comment)
Comment #15
yched CreditAttribution: yched commented@fago: I think I bumped into some code yesterday in TypedData / EntityNG that seemed to be specifically about those "present by default" items. But I can't really remember where, so, well, never mind me :-)
Comment #16
jibran#14: d8-avoid-empty-field-items-1988492-14.patch queued for re-testing.
Comment #18
das-peter CreditAttribution: das-peter commentedThey see me re-rollin', they lovin' :P
Comment #20
das-peter CreditAttribution: das-peter commentedHmm, looks like there was a change I'm not sure how to handle.
While the updated patch should avoid lot's of errors I'm not sure if this is really the right approach.
As of now
TypedDataManager::getPropertyInstance()
is called byFieldItemBase::__construct()
without passing a value. That's a first and it seems like the currently optionalvalue
parameter ofTypedDataManager::getPropertyInstance()
shouldn't be optional.With this patch
NULL
is allowed and set as property-value. However, sinceNULL
is the default value of the optionalvalue
parameter, there's no guarantee thatNULL
is really an appropriate property-value.When e.g. an user object is built
FieldItemBase::__construct()
callsTypedDataManager::getPropertyInstance()
to build the computed property for the user image. Now, since no value is provided,TypedDataManager::getPropertyInstance()
set's the property-value to NULL. But later onFileWidget::formElement()
expects the property to be an array.The question now is:
value
parameter ofTypedDataManager::getPropertyInstance()
be really optional?FieldItemBase::__construct()
sets an appropriate value?The attached patch only changes the behaviour of
FileWidget::formElement()
to not assume it gets an array as property-value.Comment #21
fagoI think it's the job of the caller to set a suiting value. So in case of entities, it's either a new one with default values, or one with loaded values. If both contain an array the field contains always an array and the formatter can rely on it. Still, it's fine to default to have the factory create the object with a NULL value by default imho?
That sounds like a bug in there somewhere, then? It cannot rely on array() if no one sets that?
Comment #22
das-peter CreditAttribution: das-peter commentedAgreed.
That's where I'm not sure about. Currently I assume that if
TypedDataManager::getPropertyInstance()
wouldn't be called byFieldItemBase::__construct()
the assumption of having an array as value is valid (Even though a bit bold).Thus the patched version of
TypedDataManager::getPropertyInstance()
could be held responsible for breaking this assumption.However, let's see what the test-bot says to the patch in #20
Comment #24
das-peter CreditAttribution: das-peter commentedHmm, looks like I was looking at the wrong place to figure out why the empty array is lost.
Not
FieldItemBase::__construct()
butItemList::createItem()
should ensure it doesn't setNULL
when an empty array would be more appropriate.FieldAttachStorageTest
has tests like this$this->assertIdentical($read->{$this->field_name}[0]->getValue(), array(), "The test entity revision $vid is deleted.");
and for me that looks absolutely valid and we should try to meet these "assumptions".Comment #25
yched CreditAttribution: yched commented#24 looks better. Callers of getValue() should not have to worry about "should I check that it's a real array". See http://www.garfieldtech.com/blog/empty-return-values
Comment #26
das-peter CreditAttribution: das-peter commentedI totally agree. I just wasn't sure where I've to / can fix that. And frankly speaking I'm still not sure it's fixed in the right place now.
Comment #28
yched CreditAttribution: yched commentedWe really need to fix that IMO. In various patches I hit bugs with $items that are "in theory empty but in reality contain an $item object with NULL properties", which break various stuff in various subtle ways. Those require adding safeguard ->filterEmptyValues() calls in more and more places. This looks messy, and it's fairly hard to predict in which part of the code flow an $items object can be considered safe or not.
Comment #29
Berdir#24: d8-avoid-empty-field-items-1988492-24.patch queued for re-testing.
Comment #30.0
(not verified) CreditAttribution: commentedUpdated issue summary.
Comment #31
yched CreditAttribution: yched commentedWe still very much need to get rid of that issue.
Many things might have changed meanwhile, so rebooting the issue with a silly patch that just removes the "$this->list[0] = new Item" in FieldItemList::__construct().
From manual testing, basic stuff like installing drupal, creating and viewing a node, still work. Let's see what breaks.
Comment #32
yched CreditAttribution: yched commentedThis is a bug and is at least major, IMO.
Comment #33
BerdirComment #36
BerdirRe-adding the filter call before saving, this will hopefully fix most of them and is fine to keep.
Comment #38
BerdirImageItem shouldn't blindly assume that $this->entity can be loaded.
Comment #40
yched CreditAttribution: yched commentedThis happened in #2164601: Stop auto-creating FieldItems on mere reading of $entity->field[N]