0

In Drupal 7, it was easy to update a referenced node with a value from the node referencing it, using rules: https://www.drupal.org/node/1836240

But how could I do the same in Drupal 8? This code is for updating a node programmatically:

use Drupal\node\Entity\Node;
$node = Node::load($nid);
$node->setTitle('MY NEW TITLE'); // This is a special meta field
$node->set('FIELD_NAME', 'THIS IS DATA'); // This is a Field added in to the content type
$node->save();

What hook should I call and place this code inside? I need when the user creates a new node or updates an existing node, then a field from the referenced node been updated with the value of a field from the current node. Should I use a form alter function? Is it possible with hook form alter to update, not only the current node, but also a field from the referenced node, or is there another hook for that?

1

2 Answers 2

1

Thank you both @GiorgosK and @4k4, for pointing me to the right direction! Here is the solution:

use Drupal\node\Entity\Node;


function my_module_entity_insert(Drupal\Core\Entity\EntityInterface
$entity) {
 if ($entity->getEntityTypeId() == 'node' && $entity->bundle() ==  'iamoriginal') {
   if (!$entity->field_my_reference->isEmpty() &&   !$entity->field_number->isEmpty() &&
 !$entity->field_hide_me->value) {
  _my_module_update_parent($entity, 'add');
 }
 }
}


function my_module_entity_update(Drupal\Core\Entity\EntityInterface $entity) {
 if ($entity->getEntityTypeId() == 'node' && $entity->bundle() == 'iamoriginal') {
$original = $entity->original;
if (!$entity->field_my_reference->isEmpty() && !$entity->field_number->isEmpty() &&
  $entity->field_hide_me->value != $original->field_hide_me->value) {
  $operation = ($entity->field_hide_me->value) ? 'sub' : 'add';
  _my_module_update_parent($entity, $operation);
}
 }
}

function _my_module_update_parent($entity, $operation) {
 $ref = $entity->get('field_my_reference')
   ->first()
   ->get('entity')
   ->getTarget()
  ->getValue();
 if ($ref->hasField('field_number_of_originals') &&        $ref->hasField('field_total_value')) {
$total = $ref->field_total_value->value;
$count = $ref->field_number_of_originals->value;
$number = $entity->field_number->value;
switch ($operation) {
  case 'add':
    $total += $number;
    $count++;
    break;
  case 'sub':
    $total -= $number;
    $count--;
    break;
}
$ref->set('field_total_value', $total);
$ref->set('field_number_of_originals', $count);
$ref->save();
 }
 }

If a user adds a new node of the post type "iamoriginal" then the value of the field_number is added to the refrenced node's field_total_value and +1 to the field_number_of_originals. If he later wants to disable the original node ,he gives a value to the field_hide_me and the previously added values to the referenced node are abstracted. Thank you again for your help!!!

0

I would take the route of not duplicating content and only deal with views configuration and theming instead.

This is how I would display such a field

using views

  1. add relationship to the entity reference field
  2. add field of the entity field (based on relationship)

using a node view/display add in your theme's node.html.twig code similar to this based on your actual entity reference

// get author's gender field value 
{{ node.uid.entity.field_gender.value }}

// get category name
{{ node.field_category.entity.name.value }}

NOTES:

If this Drupal 7 module field_extractor gets ported to D8 then it will make field integration a configurable option and you will not have to mess with twig files as it gives a entity reference field formatter that can extract any field

Alternatives that probably require more work

  • creating your own module (as per poster's request) using this as a start

    use \Drupal\Core\Entity\EntityInterface;
    //get control when entity saved or updated 
    function MODULENAME_entity_presave(EntityInterface $entity) {
      //see if its of specific type 
      if ($entity->bundle() == 'article') {
    
        //get values
        $title = $entity->getTitle();
        $nid = $entity->id();
        $cat = $entity->field_category[0]->entity->label();
    
        //set values
        $entity->field_teaser->value = 'teaser text';  
        $entity->setTitle($entity->get('field_date')->value);
    
        //no need to save anything its autosaved
      }
    }
    
  • create rules with React on event: updating a node

2
  • Thank you Giorgos, I know I can do that and show a field from another node but it is not what I need actually. I am trying to make a calculation and add the value of the current node to the value of a field of the refrenced node. That's why I need to update the referenced node's field. Do you know what function I need to to use to make that when a user is submiting a form? I need both nodes been updated the same time. Is that possible?
    – Ioannis
    Commented Jan 29, 2018 at 15:05
  • @Ioannis it was not apparent from your question, I edited answer, how is this for a start ? If you want more detail you have to make your post more detailed.
    – GiorgosK
    Commented Jan 29, 2018 at 15:25

Your Answer

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

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