Manipulating entities

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. We can achieve the same thing via the entity type manager as well:

\Drupal::entityTypeManager()->getStorage('node')->save($node);  

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 \Drupal\node\Entity\NodeType $type */
$type = \Drupal::entityTypeManager()->getStorage('node_type')->load('article');
$type->set('name', 'News');
$type->save();

Nothing too complex going on here. We load the entity, set a property value and save it using the same API.