Problem/Motivation

Implementations are different without need.
That leads to situation that access through get() does not returns default value when no data stored (when field added after entity created

Proposed resolution

Call get() from __get()

Remaining tasks

User interface changes

API changes

Data model changes

Comments

andypost created an issue. See original summary.

andypost’s picture

Status: Active » Needs review
StatusFileSize
new2.44 KB

Let's see what broken

stefan.r’s picture

Title: ConfigEntityBase get and __get() works differently » ContentEntityBase get and __get() works differently
andypost’s picture

StatusFileSize
new1.15 KB

Trying to check what's left with direct non-property access

Status: Needs review » Needs work

The last submitted patch, 4: 2563981-entity_get-3.patch, failed testing.

zviryatko’s picture

As a variant I've added check if <?php $field->isEmpty(); ?> and run <?php $field->applyDefaultValue(); ?>, it resolve a problem with default field value on views and on node page.

andypost’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work
zviryatko’s picture

daffie’s picture

Status: Needs work » Needs review

For the testbot

Status: Needs review » Needs work
andypost’s picture

Issue tags: +Performance

this could seriously affect performance

+++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php
@@ -452,9 +453,17 @@ public function hasField($field_name) {
+    if ($field instanceof FieldItemListInterface && $field->isEmpty()) {
+      $field->applyDefaultValue();

needs inline comment why we apply default value when field is empty

andypost’s picture

jibran’s picture

Priority: Normal » Major

IMO this is major WTF.

berdir’s picture

Didn't look closely yet, but applying the default value for empty fields is *wrong*, we can not do that.

Having a non-required field with a default value and then not actually saving a value is a perfectly valid thing to do. get() and __get() cannot be different in regards to that?

zviryatko’s picture

applying the default value for empty fields is *wrong*

I agree with that, but maybe we need way to get default value for field if it empty.

I've found this when tried to resolve this issue https://www.drupal.org/node/2348729, one of test failed, because views do not display default field value.

To reproduce this try to add node and after that add new field of type boolean to node content type, and show this field in views. Views must display default field value, but it doesn't.

andypost’s picture

@Berdir That's exactly the same issue with fields as we have for #1191464: Inconsistent behaviour in personal contact form for users created before versus after contact module is enabled
Here the state when we add new field (boolean) with default value but existing entities have no way to display this default value cos processing of get() and __get() is different.
So depending on a way of access value (magic or getter) you inconsistently get default values

More to that... when you create field with UI then you can have no default value #1919834: Field instance got no default value when created in field UI

PS: +1 to major wtf

The last submitted patch, 2: 2563981-entity_get-2.patch, failed testing.

isntall queued 2: 2563981-entity_get-2.patch for re-testing.

The last submitted patch, 2: 2563981-entity_get-2.patch, failed testing.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

wim leers’s picture

Issue tags: +DrupalWTF

Still a problem.

I suspect this actually belongs in the entity system component?

berdir’s picture

Priority: Major » Normal
Status: Needs work » Postponed (maintainer needs more info)

I think what @Wim refers to as DrupalWTF is adding a new field with a default value and then existing entities do not have it. Yeah, that is weird, but this is the wrong way to fix it. As I said above, this patch is wrong and has nothing to do with the issue title or summary.

Just because there is a default value doesn't mean that a user can not explicitly remove that and save it as empty. That is 100% valid and we must not break that.

The only case in which we could consider it is for required fields.

Also keep in mind that if we would do this, this would only fix it for entities when loading them. It does nothing to fix it in the database, so this might in fact be more confusing than the current behavior. If you'd load/edit/view your entity then the correct value would be there, but when you try to do an entity query against it for example it would not work.

Downgrading and set to normal until something can prove to me why this is a bug and can come up with code that does not break valid use cases. The only thing I can I think of right now is provide a UI to re-save all entities in a batch and set an explicit default value there.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

jibran’s picture

Version: 8.3.x-dev » 8.4.x-dev
Issue tags: +Needs issue summary update

This feels like a duplicate of the #2346019: Handle initial values when creating a new field storage definition after looking at the comments but IS is describing a different problem. We need an IS update.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

andypost’s picture

Status: Postponed (maintainer needs more info) » Needs review
Related issues: +#1191464: Inconsistent behaviour in personal contact form for users created before versus after contact module is enabled

I think that needs
- documentation for methods to explain difference that default values are not applied when using get() method
- follow-up to discuss addition some method to get field default values, see #16
- follow-up to "to re-save all entities in a batch and set an explicit default value" when new field added with default value but there's some entities already #24 but #26 said that issue fixed partially

The main problem that lots of people using get() method on entities when there's alredy some data in database at it takes hours to understand why that works in not expected way

berdir’s picture

Status: Needs review » Closed (cannot reproduce)

Discussed with @andypost in IRC.

I was able to clarify the misunderstanding that get() and __get() behave differently in regards to fields and default values. They do not. The fallback logic in __get() that initializes things to NULL is *only* about non-fields and is part of the BC layer that we can not remove until 9.x and I think we have issues for that.

Closing.

We still have issues like #1919834: Field instance got no default value when created in field UI about the specific problem of new fields not having a default value on existing entities.

andypost’s picture

@Berdir is there issue to remove this BC layer in 9.x?