1

What I want: In hook_media_presave I want to set a field value according to the same field on the referring node.

By the referring node, I mean the node where the media entity is created through an entity reference field.

I don't know if this is possible at all, but if it is, then how?

My current approach is to get the node from the route like this inside the presave hook:

$node = \Drupal::routeMatch()->getParameter('node');

My problem: The node I get from the routeMatch doesn't contain the new changes. Is there a way to somehow get them using the routeMatch, or is there another way to get the node.

I thought maybe the media entity had some kind of getReferringEntity() method, but no.

Is this the correct approach, or am I wrong?

7
  • How is the referring node linked to the media entity? What is the user journey?
    – seroton
    Commented Jul 5, 2019 at 17:35
  • The media entity is a reference field on the node.
    – user72672
    Commented Jul 5, 2019 at 17:37
  • Sounds like a form issue. At that point, the changes may not be there on the node. Maybe if you do your logic in a custom submit callback and get what you need from form_state?
    – seroton
    Commented Jul 5, 2019 at 17:56
  • The reason you won't find that method is that it wouldn't really make sense for it to be there - a media entity being saved has no reliance on the action having been taken through an entity reference field on an entity form. Is there a reason you decided to go bottom to top rather than top to bottom, though? In hook_node_presave you'll have access to both the pieces of information you need, that's where I'd do it
    – Clive
    Commented Jul 5, 2019 at 18:13
  • @Clive, my thoughts was. I need to update all media entities even though they are refenced in a paragraph e.g. and there might be different field names for the different entity reference fields. So I thought if I somehow could get the node in a media presave I didn't have to know every single field and its location.
    – user72672
    Commented Jul 5, 2019 at 18:16

1 Answer 1

2

With the help from @Clive I found a solution:

/**
 * Implements hook_node_update().
 */
function MY_MODULE_node_update(\Drupal\node\NodeInterface $node) {
  foreach ($node->getFieldDefinitions() as $definition) {
    if (!in_array($definition->getType(), ['entity_reference', 'entity_reference_revisions'])) {
      continue;
    }
    if (!$definition->getSetting('target_type')) {
      continue;
    }
    if ($definition->getSetting('target_type') == 'media') {
      $media = $node->{$definition->getName()}->entity;
      if ($media) {
        $media->groups->target_id = $node->groups->target_id;
        $media->save();
      }
    }
    if ($definition->getSetting('target_type') == 'paragraph') {
      $paragraph = $node->{$definition->getName()}->entity;
      if ($paragraph) {
        MY_MODULE_update_media_items($paragraph, $node->groups);
      }
    }
  }
}

/**
 * Set groups on all media items referenced in a paragraph.
 *
 * @param $paragraph
 *   The paragraph.
 * @param $groups
 *   The groups to set.
 */
function MY_MODULE_update_media_items($paragraph, $groups) {
  foreach ($paragraph->getFieldDefinitions() as $definition) {
    if (!in_array($definition->getType(), ['entity_reference', 'entity_reference_revisions'])) {
      continue;
    }
    if (!$definition->getSetting('target_type')) {
      continue;
    }
    if ($definition->getSetting('target_type') == 'media') {
      $media = $paragraph->{$definition->getName()}->entity;
      if ($media) {
        $media->groups->target_id = $groups->target_id;
        $media->save();
      }
    }
    if ($definition->getSetting('target_type') == 'paragraph') {
      $paragraph = $paragraph->{$definition->getName()}->entity;
      if ($paragraph) {
        MY_MODULE_update_media_items($paragraph, $groups);
      }
    }
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.