-2

I'm using the Private Message module version 8.x-2.0-beta16 and I want to change the message from 'Send private message' to 'Send private message to @username' which should display the username from the user's page that we are visiting and contacting.

The module uses the following code.

'#title' => t('Send private message'),

Is there are way to override this line directly and insert the username? I tried without success.

The relevant code is located in: private_message\src\Service\PrivateMessageService.php#L336-382.

public function createRenderablePrivateMessageThreadLink(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
  if ($display->getComponent('private_message_link')) {
    if ($entity instanceof UserInterface) {
      $author = $entity;
    }
    else {
      $author = $entity->getOwner();
    }
    $current_user = \Drupal::currentUser();
    if ($current_user->isAuthenticated()) {
      if ($current_user->hasPermission('use private messaging system') && $current_user->id() != $author->id()) {
        $members = [$current_user, $author];
        $thread_id = $this->mapper->getThreadIdForMembers($members);
        if ($thread_id) {
          $url = Url::fromRoute('entity.private_message_thread.canonical', ['private_message_thread' => $thread_id], ['attributes' => ['class' => ['private_message_link']]]);
          $build['private_message_link'] = [
            '#type' => 'link',
            '#url' => $url,
            '#title' => t('Send private message'),
            '#prefix' => '<div class="private_message_link_wrapper">',
            '#suffix' => '</div>',
          ];
        }
        else {
          $url = Url::fromRoute('private_message.private_message_create', [], ['query' => ['recipient' => $author->id()]]);
          $build['private_message_link'] = [
            '#type' => 'link',
            '#url' => $url,
            '#title' => t('Send private message'),
            '#prefix' => '<div class="private_message_link_wrapper">',
            '#suffix' => '</div>',
          ];
        }
      }
    }
    else {
      $url = Url::fromRoute('user.login');
      $build['private_message_link'] = [
        '#type' => 'link',
        '#url' => $url,
        '#title' => t('Send private message'),
        '#prefix' => '<div class="private_message_link_wrapper">',
        '#suffix' => '</div>',
      ];
    }
  }   
}
4
  • 2
    Don’t hack a module. Create a patch with your change and apply it with composer.
    – sonfd
    Commented Jul 21, 2021 at 12:02
  • 1
    I don't mind patching instead of hacking. But the question remains...
    – j0e
    Commented Jul 21, 2021 at 23:24
  • 1
    Can't you maybe preprocess the link and then check for $variables['element']['#prefix'] === '<div class="private_message_link_wrapper">' and then simply replace the $variables['element']['#title']?
    – leymannx
    Commented Jul 22, 2021 at 9:14
  • 1
    Yes, or you could even override the service and extend this method. See How to override a service.
    – sonfd
    Commented Jul 22, 2021 at 11:00

1 Answer 1

2

I think you're asking, "How can I create a translated string 'Send a private message to @username' where @username is replaced with the name of the user currently being viewed?"

If you're viewing the user's page, you can do this like:

// Get the user object currently being viewed from the route parameters.
$user = \Drupal::routeMatch()->getParameter('user');
// If we have a valid user object.
if ($user instanceof Drupal\user\Entity\User) {
  $message = t('Send a private message to @username', [
    '@username' => $user->getDisplayName(),
  ]);
}

However, looking at the specific code you posted, you're not guaranteed to be on the user's page. Additionally, the user that is to receive the message is already determined and stored in $author:

// I.e. user's page.
if ($entity instanceof UserInterface) {
  $author = $entity;
}
// I.e. a node or other entity authored by a user.
else {
  $author = $entity->getOwner();
}

In this case, you could just use something like:

$message = t('Send a private message to @username', [
  '@username' => $author->getDisplayName(),
]);
5
  • Still the question how they get it to override the current message. Maybe they should open a feature request and provide a patch/MR with the code you suggested.
    – leymannx
    Commented Jul 22, 2021 at 11:48
  • 1
    Agreed, definitely don't hack the module. As we mentioned above, I think the options are 1. Create an issue / post a patch to d.o and apply with composer. 2. Preprocess the link and do logic there. 3. Override the service and extend its class to override just this one method to alter the link text.
    – sonfd
    Commented Jul 22, 2021 at 12:06
  • Oh yeah, overriding the service, even better. 👌
    – leymannx
    Commented Jul 22, 2021 at 12:17
  • Thanks @sonfd. I didn't notice the $author variable. I got this to work based on your third solution, replacing the #title line with: '#title' => t('Send private message to @username', ['@username' => $author->getDisplayName()]),
    – j0e
    Commented Jul 25, 2021 at 3:01
  • @j0e - Great! I definitely recommend at least making a patch for your change and having composer apply it. Composer will attempt to reapply the patch when you update the module so your change is preserved (if the patch can't be applied then composer will tell you it failed so you can go fix it). As leymannx said above, you could also post as a FR on drupal.org (I would), but that's up to you :)
    – sonfd
    Commented Jul 25, 2021 at 12:26

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.