Cms: 3.4-RC1.1 Updating field values without using setFieldValue stopped working

Created on 16 Jan 2020  Â·  10Comments  Â·  Source: craftcms/cms

Description

Updating field values directly (without using setFieldValue) stopped working in 3.4

Steps to reproduce

Execute this code:

$entry = Entry::find()->section('home')->one();
$entry->setFieldValue('heroTitle', 'field value set using setFieldValue -> works');
$entry->heroTitle = 'some directly set value -> no longer working';
Craft::$app->getElements()->saveElement($entry);

Additional info

  • Craft version: 3.4.0-RC1.1
  • PHP version: 7.3.13
  • Database driver & version: PostgreSQL 11.5
  • Plugins & versions: -

Most helpful comment

Well it’s better for things to break consistently than inconsistently right?

I’ll add a warning to the changelog though.

All 10 comments

Setting field values directly like that was never supported. You have to go through setFieldValue() or setFieldValues().

@brandonkelly this is breaking the fixtures in Craft CMS core, see https://github.com/craftcms/cms/blob/3.4/src/test/fixtures/elements/ElementFixture.php#L108

Using the field: prefix in the fixture data files will fix this for now.
See this line.

Like this? 28635aebe9d0ea21ecd441bf1850cead02bd7249 😄

Let me know if I missed something though.

Just out of curiosity, what change broke this? And shouldn't it generate a deprecation warning?

I’m guessing it broke due to the new change tracking, where elements now track which field/attribute values are dirty (#4149), which is the basis of delta updating.

But it was already broken to a lesser degree. The reason you must go through setFieldValue() is so Craft knows that it needs to pass the value through the field type’s normalizeValue() method, to ensure it’s working with a normalized value. So for example this would not have worked:

$entry->myAssetsField = [100, 200];

But this would:

$entry->setFieldValue('myAssetsField', [100, 200]);

And shouldn't it generate a deprecation warning?

Ideally sure, but when you set the value like that, it’s setting a public property value directly on the ContentBehavior. Which means there’s no setter method invoked. (Which is the whole reason we don’t support this.)

@brandonkelly uhm, $entry->myAssetsField = [100, 200] worked in 3.3...
we used this a lot in our fixtures

Sorry I should clarify… yes that will work, _in the event that the field value hadn’t been normalized yet_, so Craft didn’t have a record of it being a normalized value. More specifically, this would not work:

// anything here that were to access $entry->myAssetsField
$entry->myAssetsField;

// then...
$entry->myAssetsField = [100, 200];

That probably explains why it works in our fixtures. I guess the quickest fix for our fixtures is to use the field: workaround. I'm guessing more people are going to stumble on this.

Well it’s better for things to break consistently than inconsistently right?

I’ll add a warning to the changelog though.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

angrybrad picture angrybrad  Â·  3Comments

bitboxfw picture bitboxfw  Â·  3Comments

michel-o picture michel-o  Â·  3Comments

mccombs picture mccombs  Â·  3Comments

angrybrad picture angrybrad  Â·  3Comments