Score:1

Add a hero image and text when a node goes from unpublished to published

es flag

I'm trying to add a hero image and text when a node goes from unpublished to published. The things include:

  1. Add an image from my media library to a media field on the node
  2. Add a page title to the node, drawing upon a field already saved on the node

I'm attempting to build a hook on hook_node_update() but it's not working. I'm not sure why.

The code I am using, part of the running_event_adding_header.module file, is the following.

namespace Drupal\Core\Field\EntityReferenceFieldItemList;
namespace Drupal\node\Entity;


/**
 * Implements hook_node_update()
 */
 
function running_event_adding_header_node_update(Drupal\Core\Entity\EntityInterface $entity) {
  // End function if the entity is not an event
  if ($entity->bundle() !== 'event') {
    return;
  }
  
  // End function if the event is not a running type of event (running events are '30' in my system)
  if ($entity->bundle() === 'event' && $entity->get('field_event_type')->getString() != '30') {
      return;
  }

  // Check if the new state is "published" and the old state was something other than "published".

  if ($entity->get('moderation_state')->getString() === 'published') {

    /**
    * Add hero image and text to running event page, if not already present
    * The hero image field is 'field_hero_image'
    * The hero text field is 'field_tagline'
    */

    if ($entity->get('field_hero_image')->isEmpty()) {
      $media = Media::load(53); // 53 is the media ID for the image I'm wanting to load on all running pages: .../media/53/edit
      $entity->set('field_hero_image', $media);
    }

    //'field_tagline' is the hero title field
    if ($entity->get('field_tagline')->isEmpty()) {
      $entity->set('field_tagline', $entity->label());
    }
    $entity->save();  
  }
}//close function

Updated code (29 July).

Per @sonfd's recommendation, this uses hook_node_presave(), but is still not changing the node pages:

<?php

namespace Drupal\Core\Field\EntityReferenceFieldItemList;
namespace Drupal\node\Entity;

//In the function below, I'm attempting to update
//'event' type nodes, specifically those with an event_type of '30'

//In those nodes, I'm attempting to use a Media library image 
//and use the page's title in the hero section


function running_event_add_default_node_presave(Drupal\node\NodeInterface $entity) {
  if ($entity->bundle() === 'event' && $entity->get('field_event_type')->toString()=== '30') {
    if ($entity->get('field_hero_tagline')->isEmpty()) {
      $entity->set('field_hero_tagline', $entity->label());
    }
    if ($entity->get('field_hero_image')->isEmpty()) {
      $media = Media::load(53); 
      $entity->set('field_hero_image', $media);
    }
  }



}

sonfd avatar
in flag
1. Delete those namespaces - they shouldn't be there. 2. What is the machine name of your module and where is the presave hook located in your module. 3. What is `$entity->get('field_event_type')->toString() === '30'` supposed to be doing? I don't think it's doing what you want. Is field_event_type an entity reference and 30 is the id of the entity you're checking against?
scaffolding avatar
es flag
1. They're gone! 2. The machine name of the module and its directory are `running_event_add_default_content`. The presave hook is located in the module file, which is saved in the module directory. The code in the module file is pasted above. 3. You're right, that line is meant to look at the event type's 'field_event_type' field, then turn that value into a string. The event type is a way for us to reuse the event template for different types of events. The running events are equal to a '30' value.
sonfd avatar
in flag
Your hook is named incorrectly. It should be `running_event_add_default_content_node_presave`, i.e. `NAME_OF_MODULE_node_presave`
scaffolding avatar
es flag
Apologies, I mis-typed; they're named correctly in my code. I've removed ` if ($entity->bundle() === 'event' && $entity->get('field_event_type')->toString()=== '30') {` and unfortunately it's the same result - the new image and hero text aren't being added.
sonfd avatar
in flag
The code you show should work. Are you sure the fields are empty and your module is enabled?
scaffolding avatar
es flag
Thanks - I think it has to do with how I'm referring to the fields? I'm currently getting this error when I attempt to save an event node: `Drupal\Core\Entity\EntityStorageException: Field field_hero_tagline is unknown. in Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (line 846 of core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php). `
scaffolding avatar
es flag
Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/128041/discussion-between-scaffolding-and-sonfd).
Score:2
in flag

You can't use hook_ENTITY_TYPE_update() to update the entity's data. This is noted in the hook's docs:

This hook runs once the entity storage has been updated. Note that hook implementations may not alter the stored entity data. Get the original entity object from $entity->original.

If you need to update the entity's data, use hook_ENTITY_TYPE_presave() instead. Note that with hook_ENTITY_TYPE_presave() you must not call $entity->save(), you just set the entity's values and let the entity save on its own.

scaffolding avatar
es flag
Thank you @sonfd! I've tried this but am still not seeing the event node update following publication. The code I've used is: <?php namespace Drupal\Core\Field\EntityReferenceFieldItemList; namespace Drupal\node\Entity; use Drupal\node\NodeInterface; /* * Implements hook_ENTITY_TYPE_presave() */ function running_event_add_default_content_node_presave(Drupal\Core\Entity\EntityInterface $entity) { if ($entity->getType() == 'event') { //update the fundraising target field, 'field_target' $entity->set("field_target", "109"); } } ```
scaffolding avatar
es flag
Ideally what should happen is: The node is created and saved in an unpublished state. An editor reviews, then publishes. When they publish, the function should add additional values. I can't get that part to work - even the simpler example in my comment above isn't creating a new value upon publication.
sonfd avatar
in flag
Can you post your updated code in your question? Also you seem to have multiple namespaces defined, but are those supposed to be use statements? Are you sure your code is even firing?
scaffolding avatar
es flag
Thank you @sonfd - the updated code is now included in my question. The code seems to be firing; if I include a typo in it, Drupal responds with a showstopping error.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.