Firstly, some background.
When you type $node->something
you're getting a FieldItemListInterface. How do you know what values you can use for something
? Well you can ask the entity.
$node->getFieldDefinitions()
Now you have a FieldItemListInterface
you can iterate over its values, or in the case of single-value field, just its first one. So even if you're using $node->title
, title is a FieldItemListInterface
even though you'd only expect one item in the list.
So lets get the first value in the list. $node->something->get(0)
. This gives you a FieldItemInterface. From here you can access the properties of the field item. E.g. $node->title->get(0)->get('value')
. Each of these is an instance of TypedDataInterface. But how do you know what you can use for value
. E.g. For an entity reference field $node->some_er_field->target_id
is valid but $node->some_er_field->value
is not. Well you can ask the FieldItemInterface
like so $node->title->get(0)->getProperties()
. Or alternatively, you can know the data-type of the field and inspect its propertyDefinitions
method. E.g. in the case of moderation_state field, it uses an Entity Reference field to track the reference to the moderation state config entity. So that means each FieldItemInterface
is actually an EntityReferenceItem and you can check its ::propertyDefinitions() method to see what properties it defines.
So now you have a TypedDataInterface
object, how do you get it's value? Well you use its ::getValue()
method.
But wait why does $node->title->value
work - I don't have to write $node->title->get(0)->get('value')->getValue()
- well thats because we're using PHP magic methods on FieldItemListInterface
and FieldItemInterface
such that $node->title->value
calls $node->title->get(0)->get('value')->getValue()
for you.
So in summary:
$node->moderation_state->get(0)->get('target_id')->getValue()
will give you the moderation state config entity's ID.
$node->moderation_state->get(0)->get('entity')->getValue()
will give you the ModerationState config entity, so you can use its methods direct - like ::isPublished()
and ::label()
.
$node->moderation_state->target_id
and $node->moderation_state->entity
would achieve the same thing respectively.
I did a lightning talk for my colleagues on this, if you're interested the slides are here unfortunately the recording didn't work.