Problem/Motivation

It looks like the #2993086: Message related object entity type is empty issue didn't fix all the case where the target type of the message related object field might be empty. One of the user on our open social installation couldn't access the website and php logs were reporting

Drupal\Component\Plugin\Exception\PluginNotFoundException: The "" entity type does not exist. in Drupal\Core\Entity\EntityTypeManager->getDefinition() (line 133 of /code/web/core/lib/Drupal/Core/Entity/EntityTypeManager.php).

To fix this issue I went ahead and grep for all occurrences of ->getStorage($target_type) preceded by \Drupal::entityTypeManager() in all the open social distro and made the local patch below, but it felt ugly:

diff --git a/web/profiles/contrib/open_social/modules/custom/activity_logger/activity_logger.tokens.inc b/web/profiles/contrib/open_social/modules/custom/activity_logger/activity_logger.tokens.inc
index 94794a7..8aa6042 100644
--- a/web/profiles/contrib/open_social/modules/custom/activity_logger/activity_logger.tokens.inc
+++ b/web/profiles/contrib/open_social/modules/custom/activity_logger/activity_logger.tokens.inc
@@ -145,7 +145,7 @@ function activity_logger_tokens($type, $tokens, array $data, array $options, Bub
                 }
               }
 
-              if ($name === 'pmt-url') {
+              if ($name === 'pmt-url' && !empty($message->field_message_related_object->target_type)) {
                 // Get the related message.
                 $target_type = $message->field_message_related_object->target_type;
                 $target_id = $message->field_message_related_object->target_id;
diff --git a/web/profiles/contrib/open_social/modules/social_features/social_comment/social_comment.tokens.inc b/web/profiles/contrib/open_social/modules/social_features/social_comment/social_comment.tokens.inc
index d35cab7..133488e 100644
--- a/web/profiles/contrib/open_social/modules/social_features/social_comment/social_comment.tokens.inc
+++ b/web/profiles/contrib/open_social/modules/social_features/social_comment/social_comment.tokens.inc
@@ -59,7 +59,7 @@ function social_comment_tokens($type, $tokens, array $data, array $options, Bubb
 
         case 'parent_entity_author':
 
-          if (isset($message->field_message_related_object)) {
+          if (isset($message->field_message_related_object) && !empty($message->field_message_related_object->target_type)) {
             $target_type = $message->field_message_related_object->target_type;
             $target_id = $message->field_message_related_object->target_id;
 
@@ -90,7 +90,7 @@ function social_comment_tokens($type, $tokens, array $data, array $options, Bubb
         case 'commented_content_type':
         case 'commented_entity_link_html':
 
-          if (isset($message->field_message_related_object)) {
+          if (isset($message->field_message_related_object) && !empty($message->field_message_related_object->target_type)) {
             $target_type = $message->field_message_related_object->target_type;
             $target_id = $message->field_message_related_object->target_id;
 
diff --git a/web/profiles/contrib/open_social/modules/social_features/social_group/social_group.tokens.inc b/web/profiles/contrib/open_social/modules/social_features/social_group/social_group.tokens.inc
index 534e79d..e8eeeb6 100644
--- a/web/profiles/contrib/open_social/modules/social_features/social_group/social_group.tokens.inc
+++ b/web/profiles/contrib/open_social/modules/social_features/social_group/social_group.tokens.inc
@@ -61,7 +61,7 @@ function social_group_tokens($type, $tokens, array $data, array $options, Bubble
         case 'created_entity_link_html':
 
           // Get the related entity.
-          if (isset($message->field_message_related_object)) {
+          if (isset($message->field_message_related_object) && !empty($message->field_message_related_object->target_type)) {
             $target_type = $message->field_message_related_object->target_type;
             $target_id = $message->field_message_related_object->target_id;
             $entity = \Drupal::entityTypeManager()
diff --git a/web/profiles/contrib/open_social/modules/social_features/social_mentions/social_mentions.tokens.inc b/web/profiles/contrib/open_social/modules/social_features/social_mentions/social_mentions.tokens.inc
index 1f6938b..b5f4cf1 100644
--- a/web/profiles/contrib/open_social/modules/social_features/social_mentions/social_mentions.tokens.inc
+++ b/web/profiles/contrib/open_social/modules/social_features/social_mentions/social_mentions.tokens.inc
@@ -84,7 +84,7 @@ function social_mentions_tokens($type, $tokens, array $data, array $options, Bub
         case 'mentioned_user':
 
           if ($name === 'mentioned_user') {
-            if (isset($message->field_message_related_object)) {
+            if (isset($message->field_message_related_object) && !empty($message->field_message_related_object->target_type)) {
               $target_type = $message->field_message_related_object->target_type;
               $target_id = $message->field_message_related_object->target_id;
               $mention = \Drupal::entityTypeManager()
@@ -104,7 +104,7 @@ function social_mentions_tokens($type, $tokens, array $data, array $options, Bub
 
         case 'commented_entity_link_html':
 
-          if (isset($message->field_message_related_object)) {
+          if (isset($message->field_message_related_object) && !empty($message->field_message_related_object->target_type)) {
             $target_type = $message->field_message_related_object->target_type;
             $target_id = $message->field_message_related_object->target_id;
             /** @var \Drupal\mentions\Entity\Mentions $mention */

Proposed resolution

Avoid the use of entity type manager and use fields entity api to get the entities. Is there a way we can use something like

<?php
  if ($message->hasField('field_message_related_object') && !$message->get('field_message_related_object')->isEmpty()) {
    $entity = $message->get('field_message_related_object')->entity;
  }
?>

instead since this field is of type dynamic_entity_reference and reduce the calls to \Drupal::entityTypeManager()?

You will notice that the isEmpty() method at https://git.drupalcode.org/project/dynamic_entity_reference/blob/8.x-1.x... take care of doing the necessary if statement checks.

Remaining tasks

Implement the proposed resolution

Comments

nikathone created an issue. See original summary.

nikathone’s picture

Issue summary: View changes

Fixed some typo.

socialnicheguru’s picture

can you create a patch to test. I think I might be coming up against this same issue.

kingdutch’s picture

Issue summary: View changes

Hey nikathone,

Thanks for the report! Yes, using the proper field methods to check if it's empty and to load the entity is the right way to go and should improve the code.

I think it may be a good idea here to add a debug level message when the related object field is empty. Perhaps with some other identifying info about the message. That may help us to track down what is causing this scenario to occur in the first place (and perhaps discover a different bug) while also making our code more robust.

Thanks,

~ Kingdutch

colan’s picture

Issue summary: View changes
Status: Active » Needs review
StatusFileSize
new1.15 KB

Here's what I'm getting on a site at https://example.com/fr/notifications:

Le site Web a rencontré une erreur inattendue. Veuillez essayer de nouveau plus tard.

Drupal\Component\Plugin\Exception\PluginNotFoundException: The "" entity type does not exist. in Drupal\Core\Entity\EntityTypeManager->getDefinition() (line 150 of core/lib/Drupal/Core/Entity/EntityTypeManager.php).

Drupal\Core\Entity\EntityTypeManager->getHandler(NULL, 'storage') (Line: 208)
Drupal\Core\Entity\EntityTypeManager->getStorage(NULL) (Line: 80)
Drupal\social_activity\EmailTokenServices->getRelatedObject(Object) (Line: 275)
social_comment_tokens_alter(Array, Array, Object) (Line: 539)
Drupal\Core\Extension\ModuleHandler->alter('tokens', Array, Array, Object) (Line: 313)
Drupal\Core\Utility\Token->generate('message', Array, Array, Array, Object) (Line: 196)
Drupal\Core\Utility\Token->replace('<a href="absolute]">[message:author:display-name]</a> published [social_group:content_type] in the <a href="gurl]">[message:gtitle]</a> group [message:count_groups_per_node] you are member of:

[message:preview]

[message:cta_button]
', Array, Array, Object) (Line: 585)
Drupal\activity_creator\ActivityFactory->processTokens(Array, , Object) (Line: 509)
Drupal\activity_creator\ActivityFactory->getMessageText(Object) (Line: 276)
activity_creator_entity_view(Array, Object, Object, 'notification_archive')
call_user_func_array('activity_creator_entity_view', Array) (Line: 403)
Drupal\Core\Extension\ModuleHandler->invokeAll('entity_view', Array) (Line: 300)
Drupal\Core\Entity\EntityViewBuilder->buildMultiple(Array) (Line: 250)
Drupal\Core\Entity\EntityViewBuilder->build(Array)
call_user_func_array(Array, Array) (Line: 100)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. Support for this callback implementation is deprecated in 8.8.0 and will be removed in Drupal 9.0.0. See https://www.drupal.org/node/2966725', 'silenced_deprecation', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 781)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 372)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 200)
Drupal\Core\Render\Renderer->render(Array) (Line: 501)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 79)
__TwigTemplate_215e165a9ff99ade66b34d19130302003c7470ef2a7dc77a7fa2d6e3758f5487->block_rows(Array, Array) (Line: 216)
Twig\Template->displayBlock('rows', Array, Array) (Line: 67)
__TwigTemplate_215e165a9ff99ade66b34d19130302003c7470ef2a7dc77a7fa2d6e3758f5487->doDisplay(Array, Array) (Line: 455)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 422)
Twig\Template->display(Array) (Line: 434)
Twig\Template->render(Array) (Line: 64)
twig_render_template('themes/contrib/socialbase/templates/views/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 431)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 444)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 200)
Drupal\Core\Render\Renderer->render(Array) (Line: 501)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 82)
__TwigTemplate_bfab0a52f2ccee4e2dc141e3485ae3822f6d3ec256687cf542ec5548fb29d338->doDisplay(Array, Array) (Line: 455)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 422)
Twig\Template->display(Array) (Line: 434)
Twig\Template->render(Array) (Line: 64)
twig_render_template('themes/contrib/socialbase/templates/views/views-view--activity-stream-notifications--page.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view__activity_stream_notifications__page', Array) (Line: 431)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 444)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 200)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 226)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 573)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 227)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 117)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.view', Object) (Line: 156)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 708)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

Here's a patch to get things started. I prefer guard clauses because they prevent if-style nesting, which is a barrier to clean code.

colan’s picture

Version: 8.x-3.x-dev » 11.2.x-dev

Forgot to update the branch.

ressinel’s picture

Hi, @colan

Thanks for your work!

I have created PR with your changes: https://github.com/goalgorilla/open_social/pull/2881

tbsiqueira’s picture

Hi @colan, thank. you so much for your contribution!

We have a slightly different way of contributing for Open Social, if you would like to do it using pull requests instead of patches ;)

Please find at the following link how:

https://www.drupal.org/docs/drupal-distributions/open-social/contribute-...

Have a great day!

colan’s picture

Will do from now on!

tbsiqueira’s picture

Status: Needs review » Reviewed & tested by the community
ressinel’s picture

Status: Reviewed & tested by the community » Fixed

This will be released in Open Social 11.1.6 and above.

  • Ressinel committed 9aae945 on 11.1.x
    Merge pull request #2881 from goalgorilla/issue/3045872-...

  • Ressinel committed ad35c6c on 11.2.x
    Merge pull request #2881 from goalgorilla/issue/3045872-...

  • Ressinel committed 0e72d46 on 11.3.x
    Merge pull request #2881 from goalgorilla/issue/3045872-...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.