From bcf45f5d871bef3718ca2b6064968fc39ca13442 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Mon, 15 Apr 2024 22:38:44 +0100
Subject: [PATCH] Issue #3440039 by samit.310@gmail.com, quietone, smustgrave,
 catch, mondrake: Log warning when relatable resource type references a
 missing entity type / bundle instead triggering E_USER_WARNING

---
 .../ResourceType/ResourceTypeRepository.php   | 22 +++++++------
 .../ResourceType/RelatedResourceTypesTest.php | 31 ++++++++++++-------
 2 files changed, 31 insertions(+), 22 deletions(-)

diff --git a/core/modules/jsonapi/src/ResourceType/ResourceTypeRepository.php b/core/modules/jsonapi/src/ResourceType/ResourceTypeRepository.php
index 5798403dd978..25bc5f8de3f2 100644
--- a/core/modules/jsonapi/src/ResourceType/ResourceTypeRepository.php
+++ b/core/modules/jsonapi/src/ResourceType/ResourceTypeRepository.php
@@ -16,6 +16,7 @@
 use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Installer\InstallerKernel;
 use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItemInterface;
+use Drupal\Core\Logger\LoggerChannelTrait;
 use Drupal\Core\TypedData\DataReferenceTargetDefinition;
 use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
 use Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException;
@@ -42,6 +43,8 @@
  */
 class ResourceTypeRepository implements ResourceTypeRepositoryInterface {
 
+  use LoggerChannelTrait;
+
   /**
    * The entity type manager.
    *
@@ -467,16 +470,15 @@ protected function getRelatableResourceTypesFromFieldDefinition(FieldDefinitionI
         // is not guaranteed during this period and may cause confusing and
         // unnecessary warnings.
         if (!InstallerKernel::installationAttempted()) {
-          trigger_error(
-            sprintf(
-              'The "%s" at "%s:%s" references the "%s:%s" entity type that does not exist.',
-              $field_definition->getName(),
-              $field_definition->getTargetEntityTypeId(),
-              $field_definition->getTargetBundle(),
-              $entity_type_id,
-              $target_bundle
-            ),
-            E_USER_WARNING
+          $this->getLogger('jsonapi')->warning(
+            'The "@name" at "@target_entity_type_id:@target_bundle" references the "@entity_type_id:@bundle" entity type that does not exist.',
+            [
+              '@name' => $field_definition->getName(),
+              '@target_entity_type_id' => $field_definition->getTargetEntityTypeId(),
+              '@target_bundle' => $field_definition->getTargetBundle(),
+              '@entity_type_id' => $entity_type_id,
+              '@bundle' => $target_bundle,
+            ],
           );
         }
       }
diff --git a/core/modules/jsonapi/tests/src/Kernel/ResourceType/RelatedResourceTypesTest.php b/core/modules/jsonapi/tests/src/Kernel/ResourceType/RelatedResourceTypesTest.php
index 5f9ba652a329..9080ed0bd441 100644
--- a/core/modules/jsonapi/tests/src/Kernel/ResourceType/RelatedResourceTypesTest.php
+++ b/core/modules/jsonapi/tests/src/Kernel/ResourceType/RelatedResourceTypesTest.php
@@ -4,9 +4,9 @@
 
 namespace Drupal\Tests\jsonapi\Kernel\ResourceType;
 
+use Drupal\Core\Database\Database;
 use Drupal\Tests\jsonapi\Kernel\JsonapiKernelTestBase;
 use Drupal\node\Entity\NodeType;
-use PHPUnit\Framework\Error\Warning;
 
 /**
  * @coversDefaultClass \Drupal\jsonapi\ResourceType\ResourceType
@@ -28,6 +28,7 @@ class RelatedResourceTypesTest extends JsonapiKernelTestBase {
     'system',
     'user',
     'field',
+    'dblog',
   ];
 
   /**
@@ -63,6 +64,7 @@ protected function setUp(): void {
     // Add the additional table schemas.
     $this->installSchema('node', ['node_access']);
     $this->installSchema('user', ['users_data']);
+    $this->installSchema('dblog', ['watchdog']);
 
     NodeType::create([
       'type' => 'foo',
@@ -202,17 +204,22 @@ public function testGetRelatableResourceTypesFromFieldDefinition() {
     ]);
     $fields = $field_config_storage->loadByProperties(['field_name' => 'field_ref_with_missing_bundle']);
     static::assertSame(['missing_bundle'], $fields['node.foo.field_ref_with_missing_bundle']->getItemDefinition()->getSetting('handler_settings')['target_bundles']);
-
-    try {
-      $this->resourceTypeRepository->get('node', 'foo')->getRelatableResourceTypesByField('field_ref_with_missing_bundle');
-      static::fail('The above code must produce a warning since the "missing_bundle" does not exist.');
-    }
-    catch (Warning $e) {
-      static::assertSame(
-        'The "field_ref_with_missing_bundle" at "node:foo" references the "node:missing_bundle" entity type that does not exist.',
-        $e->getMessage()
-      );
-    }
+    $a = $this->resourceTypeRepository->get('node', 'foo')->getRelatableResourceTypesByField('field_ref_with_missing_bundle');
+    static::assertSame(['missing_bundle'], $fields['node.foo.field_ref_with_missing_bundle']->getItemDefinition()->getSetting('handler_settings')['target_bundles']);
+    $arguments = [
+      '@name' => 'field_ref_with_missing_bundle',
+      '@target_entity_type_id' => 'node',
+      '@target_bundle' => 'foo',
+      '@entity_type_id' => 'node',
+      '@bundle' => 'missing_bundle',
+    ];
+    $logged = Database::getConnection()->select('watchdog')
+      ->fields('watchdog', ['variables'])
+      ->condition('type', 'jsonapi')
+      ->condition('message', 'The "@name" at "@target_entity_type_id:@target_bundle" references the "@entity_type_id:@bundle" entity type that does not exist.')
+      ->execute()
+      ->fetchField();
+    $this->assertEquals(serialize($arguments), $logged);
   }
 
   /**
-- 
GitLab