Use another data as field in group-relationship

I ask myself on how to do the following thing :

Each user in the system has an avatar (media field in user account).

I use the group module to build “organizations”. Each organization has members. When a user is added to an organization, the admin has the choice to add or not an “avatar” to the added member. The avatar field is in the relationship.

The goal is the following :

If an avatar is set to the relationship, use it ; If not, use the standard avatar from the user profile ;

I implemented a custom module with hook_preprocess_group_relationship and check for the current relationship if the relation contains avatar or not, and if it’s not the case, I would like to attach to the “content” array the avatar from the user profile. But I don’t see how to do that…

Actually I use the following code :

    if (!isset($variables['content']['field_avatar']['#theme'])) {
      $user = $gr->getEntity();
      $medias = $user->get('field_user_avatar')->referencedEntities();
      if (count($medias)) {
        $media = $medias[0];
        $render = \Drupal::entityTypeManager()->getViewBuilder('media')->view($media, 'default');
        $variables['content']['field_avatar'] = $render;
      }
    }

The original field_avatar content is a “theme field”, but the one I put as replacement is a media, so it doesn’t display it.

An idea on how to manage the replacement to mimic the same use ?

Thanks in advance.

The problem you’re facing is that the avatar field in the relationship is being replaced by a media entity rendering, which differs from the original “themed field.” To solve this, you need to ensure that the rendering of the media entity matches the format that the original field_avatar field expects.

Here’s a step-by-step breakdown and a solution to achieve this:

Steps:

  1. Check if a Custom Avatar is Set for the Relationship:
  • First, you check if the field_avatar is set in the relationship.
  • If it’s not set, retrieve the avatar from the user profile (field_user_avatar).
  1. Render the Avatar:
  • When rendering the fallback avatar from the user profile, you need to ensure it’s rendered the same way a field is, so it seamlessly integrates into the rest of the page.

Updated Solution:

Instead of directly rendering the media entity, you should aim to render it in the same format as a field, which is done by attaching it using the Field API. This allows Drupal to handle the rendering for you, ensuring consistency in how the avatar is displayed.

Here’s how you can update your code:

php

Copy code

/**
 * Implements hook_preprocess_group_relationship().
 */
function mymodule_preprocess_group_relationship(&$variables) {
  $relationship = $variables['relationship'];

  // Check if the relationship has an avatar field and if it has content.
  if (empty($variables['content']['field_avatar']['#theme'])) {
    // Get the user entity from the relationship.
    $user = $relationship->getEntity();
    
    // Get the avatar from the user profile.
    $user_avatars = $user->get('field_user_avatar')->referencedEntities();
    
    // Check if the user has an avatar.
    if (!empty($user_avatars)) {
      $media = $user_avatars[0];
      
      // Render the user avatar as a field to mimic the original field output.
      $render = \Drupal::entityTypeManager()->getViewBuilder('media')->view($media, 'default');
      
      // Attach the render array to the field_avatar key in the content array.
      $variables['content']['field_avatar'] = $render;
    }
  }
}

Explanation:

  1. Check for Existing Avatar: The first part of your logic checks whether the field_avatar exists on the relationship. If it doesn’t, then you retrieve the user’s avatar.
  2. Render the User’s Avatar: The updated code retrieves the user’s avatar from the media field (field_user_avatar) and uses the entityTypeManager()->getViewBuilder('media')->view() method to render it in the desired format.
  3. Replace field_avatar: Instead of simply rendering the media entity and assigning it to field_avatar, you attach it to the content array in a way that mimics the field format. Drupal will handle the rendering as it would with any other field.

Field API Rendering:

To ensure that the rendering matches the field display, you can also make sure that the view mode used (default in this case) is correctly configured to display the media entity the way you want. You can adjust the display settings for media entities by going to:

  • Structure > Media Types > [Your Media Type] > Manage Display

This approach will maintain a consistent output for both the relationship-specific avatar and the fallback avatar from the user profile, ensuring they look the same on the front-end.

Alternate Approach: Creating a Custom Field Formatter

If this doesn’t fully solve the issue, an alternate solution would be to create a custom field formatter that handles this logic. That way, you can render the field_avatar field consistently, whether it’s from the relationship or the user entity.

Let me know if you need further help with either approach!