7

I am trying to get the moderation_state property from a node object in Drupal8 (see attached image); however, I cannot work out how to do this. In Drupal7 it was pretty straight forward $node->moderation_state.

How can I get this value in Drupal8 where $node is an instance of Drupal\node\Entity\Node?

I have tried: $node->moderation_state $node->moderation_state->value

attached image

  • Always use $node->toArray() when dumping it, then gives you a structure that's much closer to how you can access it. Maybe it uses a different property than value, that would tell you. – Berdir Mar 8 '16 at 7:07
14

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.

| improve this answer | |
  • Best explanation ever! Should be included in the drupal.org documentation. Thank you larowlan. – Prerit Mohan May 21 '19 at 3:44
1

This is a protected value. You won't be able to access it with kint() or toArray(). The node object protects this, because it wants you to use the node interface to read the status:

$node->isPublished()

This strict handling of protected values in drupal 8 will make your code survive longer, hopefully in drupal 9 and beyond. Because now there are changes inside the node object possible, without reflecting the interface to the outside.

Edit: Looked in core for moderation_state, it's not there, probably contrib. You have to look in available methods, which public function will give you the information similar to $node->isPublished(), which is for status.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.