Now that we know how we can read field data programmatically, let's see how we can change this data and persist it to the storage. So, let's look at the same Node title field and update its value programmatically.
The most common way you can change a field value on a content entity is this:
$node->set('title', 'new title');
This works well with fields that have only one value (cardinality == 1) and behind the scenes essentially this happens:
$node->get('title')->setValue('new title');
This one value gets transformed into a raw array of one value because we are dealing with a list of items and the first item receives the changed value. If the field has a higher cardinality and we pass only one value as such, we essentially remove both of them and replace them with only one. So, if we want to make sure we are not deleting items but instead adding to the list, we can do this:
$values = $node->get('field_multiple')->getValue();
$values[] = ['value' => 'extra value'];
$node->set('field_multiple', $values);
If we want to change a specific item in the list, we can do this:
$node->get('field_multiple')->get(1)->setValue('changed value');
This will change the value of the second item in the list. You just have to make sure it is set first before chaining:
$node->get('field_test')->offsetExists(1);
All these modifications we make to field values are, however, kept in memory (they are not persisted). To save them to a database we have to do something extremely complicated:
$node->save();
That's it. Under the hood, Drupal still uses some deprecated ways to do the saving using the old EntityManager , which is no longer recommended but is essentially responsible for saving the storage handler; of the entity type. So, we can achieve the same thing via the entity type manager:
\Drupal::entityTypeManager()->getStorage('node')->save($node);
But nobody is going to look down on you if you just use the save() helper method on the entity object. Since we are talking about saving, deleting entities can be done in the exact same way, except by using the delete() method on the entity object. We also have this method on the storage handler, however, it accepts an array of entities to delete, so you can use that to delete more entities at once.
Configuration entities have it a bit easier since their fields do not deal with TypedData. This is how we can easily change the value of a configuration entity field:
/** @var NodeType $type */
$type = \Drupal::entityTypeManager()->getStorage('node_type')->load('article');
$type->set('name', 'News');
$type->save();
Nothing to complex going on here. We load the entity, set a property value and save it using the same API.