1

Goal: Programmatically change value of string field from "1" to "01" using entity ->set() and ->save()

When attempting to update a field on a node programmatically (via a custom module's cron hook), the initial value of the "Text (plain)" field is "1". When attempting to update the field programmatically to "01" (the 0 is important for business purposes), the change is ignored. However, it does work if I set to almost any other value.

// DOES NOT save update to field (Current value is "1")
$node = \Drupal\node\Entity\Node::load(1);
$node->set('field_code', '01'); // '01' is indeed a string
$node->save();
// DOES save update to field (Current value is "1")
$node = \Drupal\node\Entity\Node::load(1);
$node->set('field_code', '02');
$node->save();

If I were to make the change via the UI's node edit form, the change is saved in the same scenario.

Has anyone else encountered this? It seems that there must be some validation that is occurring that is comparing the strings before saving as '01' == '1'; // true (as string) in PHP.

  • 1
    If you compare a number with a string or the comparison involves numerical strings, then each string is converted to a number and the comparison performed numerically. These rules also apply to the switch statement. The type conversion does not take place when the comparison is === or !== as this involves comparing the type as well as the value. https://www.php.net/manual/en/language.operators.comparison.php – Triby Dec 18 '19 at 22:21
  • 2
    I would double check for that field type. If it's actually an integer field, your insight is good, and as a workaround you could save a dummy value eg. "666" before saving the proper value. I can't check the source code right now, but if you can do not hesitate to open a drupal issue regarding the PHP type juggling with string comparison (equal vs identical) during entity save operations. – EricLavault Dec 19 '19 at 08:42

1 Answers1

1

I encountered the same problem and I finally found the cause.

As you know, when updating an existing revision, keep the existing records if the field values did not change. And one field value and the original value are compared by not === but == at the last of FieldItemList::equals.

Unfortunately, it seems like we can't avoid this problem.

akkina
  • 11
  • 1