From 744e09a3063dfdcf65024c5c8f70d13e6b629f1a Mon Sep 17 00:00:00 2001
From: Claudiu Cristea <clau.cristea@gmail.com>
Date: Mon, 3 Mar 2025 13:11:49 +0200
Subject: [PATCH 01/10] ISAICP-9538: Calendar fix.

---
 config/sync/views.view.calendar.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/config/sync/views.view.calendar.yml b/config/sync/views.view.calendar.yml
index 88649e1fb5..e9d808ccd9 100644
--- a/config/sync/views.view.calendar.yml
+++ b/config/sync/views.view.calendar.yml
@@ -343,7 +343,7 @@ display:
           value:
             min: ''
             max: ''
-            value: '-1 month'
+            value: '-40 day'
             type: offset
           group: 1
           exposed: false
@@ -388,7 +388,7 @@ display:
           value:
             min: ''
             max: ''
-            value: '+1 month'
+            value: '+40 day'
             type: offset
           group: 1
           exposed: false
-- 
GitLab


From 9653c1318404314dfab21993967a5dd6f4654301 Mon Sep 17 00:00:00 2001
From: Ilias Dimopoulos <idimopoulos@hotmail.com>
Date: Tue, 25 Feb 2025 13:39:46 +0200
Subject: [PATCH 02/10] ISAICP-9526: The suffix of a URI should be after a ?,
 not a /. There are IRIs that have the / as a separator.

---
 .../src/EventSubscriber/LegacyRdfUrlSubscriber.php         | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/web/modules/custom/joinup_rdf/src/EventSubscriber/LegacyRdfUrlSubscriber.php b/web/modules/custom/joinup_rdf/src/EventSubscriber/LegacyRdfUrlSubscriber.php
index 863a4056fe..406f5fff61 100644
--- a/web/modules/custom/joinup_rdf/src/EventSubscriber/LegacyRdfUrlSubscriber.php
+++ b/web/modules/custom/joinup_rdf/src/EventSubscriber/LegacyRdfUrlSubscriber.php
@@ -61,11 +61,16 @@ public function on404(ExceptionEvent $event): void {
    */
   public function getTargetEntity(string $path): array {
     // Extracts the encoded URI and everything that comes after.
-    $pattern = '@^(?<prefix>/rdf_entity/|/taxonomy/term/)(?<uri>http_e_f_f[^/]*)(?<suffix>/(?:.*))?$@';
+    $pattern = '@^(?<prefix>/rdf_entity/|/taxonomy/term/)(?<uri>http_e_f_f[^?]*)(?<suffix>/(?:.*))?$@';
     if (!preg_match($pattern, $path, $found)) {
       return [NULL, NULL];
     }
 
+    // Cases like eGovEra are redirected with a / in their URI. We need to fix
+    // this by replacing the prefix.
+    if ($found['uri'] && str_contains($found['uri'], '_fegovera/')) {
+      $found['uri'] = str_replace('/', '_f', $found['uri']);
+    }
     if (!$entity = $this->getEntity($found['uri'])) {
       return [NULL, NULL];
     }
-- 
GitLab


From bde32f0304267e7e96ccc37ce6876468c06a6c9d Mon Sep 17 00:00:00 2001
From: Ilias Dimopoulos <idimopoulos@hotmail.com>
Date: Tue, 25 Feb 2025 13:45:33 +0200
Subject: [PATCH 03/10] ISAICP-9526: Provide a test for the redirection.

---
 tests/features/update/ISAICP-9396.feature | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/tests/features/update/ISAICP-9396.feature b/tests/features/update/ISAICP-9396.feature
index 254fbd5769..9d1ee7b5f0 100644
--- a/tests/features/update/ISAICP-9396.feature
+++ b/tests/features/update/ISAICP-9396.feature
@@ -19,6 +19,13 @@ Feature: Library import check.
     # Text from the EIRA properties.
     And I should see the text "eira:InformationBusinessObject"
 
+    # Ensure the upstream redirection works as well.
+    Given I go to "/taxonomy/term/http_e_f_fdata_ceuropa_ceu_fdr8_fegovera/InvoiceBusinessObject"
+    Then I should see the heading "Invoice"
+    And I should see the text "EIRA properties"
+    # Text from the EIRA properties.
+    And I should see the text "egovera:InvoiceBusinessObject"
+
   @update:joinup_core_deploy_200301
   Scenario: Sample check that options are available in the solution type field.
     Given I am logged in as a moderator
-- 
GitLab


From 0239bad8c32fae71dc8bf7a9f34613869804e076 Mon Sep 17 00:00:00 2001
From: Ilias Dimopoulos <idimopoulos@hotmail.com>
Date: Tue, 25 Feb 2025 18:04:10 +0200
Subject: [PATCH 04/10] ISAICP-9526: Clean up the code a bit. We no longer have
 /rdf_entity/, there is no point to encode right before decode. Allow / in the
 suffix.

---
 .../custom/joinup_core/src/Controller/IdRedirect.php       | 1 -
 .../src/EventSubscriber/LegacyRdfUrlSubscriber.php         | 7 +------
 2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/web/modules/custom/joinup_core/src/Controller/IdRedirect.php b/web/modules/custom/joinup_core/src/Controller/IdRedirect.php
index e8d5c53225..c646a24a5c 100644
--- a/web/modules/custom/joinup_core/src/Controller/IdRedirect.php
+++ b/web/modules/custom/joinup_core/src/Controller/IdRedirect.php
@@ -77,7 +77,6 @@ public static function getEntityTypeFromPersistentUriNamespace(?string $namespac
     $namespaces = [
       'w21' => 'node',
       'dr8' => 'taxonomy_term',
-      'dr8/egovera' => 'taxonomy_term',
     ];
 
     if (!$namespace) {
diff --git a/web/modules/custom/joinup_rdf/src/EventSubscriber/LegacyRdfUrlSubscriber.php b/web/modules/custom/joinup_rdf/src/EventSubscriber/LegacyRdfUrlSubscriber.php
index 406f5fff61..f444cd744b 100644
--- a/web/modules/custom/joinup_rdf/src/EventSubscriber/LegacyRdfUrlSubscriber.php
+++ b/web/modules/custom/joinup_rdf/src/EventSubscriber/LegacyRdfUrlSubscriber.php
@@ -61,16 +61,11 @@ public function on404(ExceptionEvent $event): void {
    */
   public function getTargetEntity(string $path): array {
     // Extracts the encoded URI and everything that comes after.
-    $pattern = '@^(?<prefix>/rdf_entity/|/taxonomy/term/)(?<uri>http_e_f_f[^?]*)(?<suffix>/(?:.*))?$@';
+    $pattern = '@^(?<prefix>/taxonomy/term/)(?<uri>http_e_f_f[^?]*)(?<suffix>/(?:.*))?$@';
     if (!preg_match($pattern, $path, $found)) {
       return [NULL, NULL];
     }
 
-    // Cases like eGovEra are redirected with a / in their URI. We need to fix
-    // this by replacing the prefix.
-    if ($found['uri'] && str_contains($found['uri'], '_fegovera/')) {
-      $found['uri'] = str_replace('/', '_f', $found['uri']);
-    }
     if (!$entity = $this->getEntity($found['uri'])) {
       return [NULL, NULL];
     }
-- 
GitLab


From 13f9d8a9fc72a66da2408d9086576f2a3a05e3fa Mon Sep 17 00:00:00 2001
From: Ilias Dimopoulos <idimopoulos@hotmail.com>
Date: Wed, 26 Feb 2025 02:53:03 +0200
Subject: [PATCH 05/10] ISAICP-9526: Restore used functionality.

---
 .../joinup_rdf/src/EventSubscriber/LegacyRdfUrlSubscriber.php   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/web/modules/custom/joinup_rdf/src/EventSubscriber/LegacyRdfUrlSubscriber.php b/web/modules/custom/joinup_rdf/src/EventSubscriber/LegacyRdfUrlSubscriber.php
index f444cd744b..3b32375f5a 100644
--- a/web/modules/custom/joinup_rdf/src/EventSubscriber/LegacyRdfUrlSubscriber.php
+++ b/web/modules/custom/joinup_rdf/src/EventSubscriber/LegacyRdfUrlSubscriber.php
@@ -61,7 +61,7 @@ public function on404(ExceptionEvent $event): void {
    */
   public function getTargetEntity(string $path): array {
     // Extracts the encoded URI and everything that comes after.
-    $pattern = '@^(?<prefix>/taxonomy/term/)(?<uri>http_e_f_f[^?]*)(?<suffix>/(?:.*))?$@';
+    $pattern = '@^(?<prefix>/rdf_entity/|/taxonomy/term/)(?<uri>http_e_f_f[^?]*)(?<suffix>/(?:.*))?$@';
     if (!preg_match($pattern, $path, $found)) {
       return [NULL, NULL];
     }
-- 
GitLab


From 9350f7eb7e314d9ed25b5b5dc4aeaa15dcd4db55 Mon Sep 17 00:00:00 2001
From: Ilias Dimopoulos <idimopoulos@hotmail.com>
Date: Wed, 26 Feb 2025 04:09:46 +0200
Subject: [PATCH 06/10] ISAICP-9526: Use the logic of subpath_auto to construct
 the IRI both in case where the suffix is and is not part of the base IRI.

---
 .../LegacyRdfUrlSubscriber.php                | 36 ++++++++++++++-----
 1 file changed, 28 insertions(+), 8 deletions(-)

diff --git a/web/modules/custom/joinup_rdf/src/EventSubscriber/LegacyRdfUrlSubscriber.php b/web/modules/custom/joinup_rdf/src/EventSubscriber/LegacyRdfUrlSubscriber.php
index 3b32375f5a..df6d8accce 100644
--- a/web/modules/custom/joinup_rdf/src/EventSubscriber/LegacyRdfUrlSubscriber.php
+++ b/web/modules/custom/joinup_rdf/src/EventSubscriber/LegacyRdfUrlSubscriber.php
@@ -61,16 +61,20 @@ public function on404(ExceptionEvent $event): void {
    */
   public function getTargetEntity(string $path): array {
     // Extracts the encoded URI and everything that comes after.
-    $pattern = '@^(?<prefix>/rdf_entity/|/taxonomy/term/)(?<uri>http_e_f_f[^?]*)(?<suffix>/(?:.*))?$@';
+    $pattern = '@^(?<prefix>/rdf_entity/|/taxonomy/term/)(?<uri>http_e_f_f[^/]*)(?<suffix>/(?:.*))?$@';
     if (!preg_match($pattern, $path, $found)) {
       return [NULL, NULL];
     }
 
-    if (!$entity = $this->getEntity($found['uri'])) {
+    if (!$entity = $this->getEntity($found['uri'], $found['suffix'])) {
       return [NULL, NULL];
     }
 
-    return [$entity, $found['suffix'] ?? ''];
+    // In case we found that the suffix is part of the IRI, then, return an
+    // empty string as suffix.
+    return str_ends_with($entity->getUri(), $found['suffix'])
+      ? [$entity, '']
+      : [$entity, $found['suffix']];
   }
 
   /**
@@ -78,20 +82,36 @@ public function getTargetEntity(string $path): array {
    *
    * @param string $encodedUri
    *   The entity encoded URI path.
+   * @param string $suffix
+   *   The URL suffix that might be part of the URL.
    *
    * @return \Drupal\joinup_rdf\Entity\RdfSyncEntityInterface|null
    *   The entity or NULL if the request URL doesn't designate a mapped entity.
    */
-  protected function getEntity(string $encodedUri): ?RdfSyncEntityInterface {
+  protected function getEntity(string $encodedUri, string $suffix): ?RdfSyncEntityInterface {
     // With the legacy storage, RDF entity IDs were encoded URIs.
     $uri = strtr($encodedUri, self::MAP);
 
-    if (!$entity = $this->mapper->getEntityByUri($uri)) {
-      return NULL;
+    // Sometimes, the URI is served to us including '/' characters, like the
+    // eGovERA. Other times, the UUID is already properly set, like internal
+    // URLs. Try to construct the URL by adding parts of the suffix if the
+    // entity is not found with the solid URI.
+    $uriParts = array_filter(explode('/', $suffix));
+    $candidate = $uri;
+    $entity = $this->mapper->getEntityByUri($candidate);
+    if ($entity instanceof RdfSyncEntityInterface) {
+      return $entity;
     }
 
-    // Make sure is a mapped entity.
-    return $entity instanceof RdfSyncEntityInterface ? $entity : NULL;
+    while ($uriParts) {
+      $part = array_shift($uriParts);
+      $candidate .= '/' . $part;
+      $entity = $this->mapper->getEntityByUri($candidate);
+      if ($entity instanceof RdfSyncEntityInterface) {
+        return $entity;
+      }
+    }
+    return NULL;
   }
 
   /**
-- 
GitLab


From 8b50865bd979b92f8355f30c72b586945e2fc5c8 Mon Sep 17 00:00:00 2001
From: Ilias Dimopoulos <idimopoulos@hotmail.com>
Date: Wed, 26 Feb 2025 13:52:06 +0200
Subject: [PATCH 07/10] ISAICP-9526: Fix some cases where the suffix is empty.

---
 .../src/EventSubscriber/LegacyRdfUrlSubscriber.php        | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/web/modules/custom/joinup_rdf/src/EventSubscriber/LegacyRdfUrlSubscriber.php b/web/modules/custom/joinup_rdf/src/EventSubscriber/LegacyRdfUrlSubscriber.php
index df6d8accce..6b2df4b284 100644
--- a/web/modules/custom/joinup_rdf/src/EventSubscriber/LegacyRdfUrlSubscriber.php
+++ b/web/modules/custom/joinup_rdf/src/EventSubscriber/LegacyRdfUrlSubscriber.php
@@ -66,12 +66,16 @@ public function getTargetEntity(string $path): array {
       return [NULL, NULL];
     }
 
-    if (!$entity = $this->getEntity($found['uri'], $found['suffix'])) {
+    if (!$entity = $this->getEntity($found['uri'], $found['suffix'] ?? '')) {
       return [NULL, NULL];
     }
 
     // In case we found that the suffix is part of the IRI, then, return an
     // empty string as suffix.
+    if (!isset($found['suffix'])) {
+      return [$entity, ''];
+    }
+
     return str_ends_with($entity->getUri(), $found['suffix'])
       ? [$entity, '']
       : [$entity, $found['suffix']];
@@ -88,7 +92,7 @@ public function getTargetEntity(string $path): array {
    * @return \Drupal\joinup_rdf\Entity\RdfSyncEntityInterface|null
    *   The entity or NULL if the request URL doesn't designate a mapped entity.
    */
-  protected function getEntity(string $encodedUri, string $suffix): ?RdfSyncEntityInterface {
+  protected function getEntity(string $encodedUri, string $suffix = ''): ?RdfSyncEntityInterface {
     // With the legacy storage, RDF entity IDs were encoded URIs.
     $uri = strtr($encodedUri, self::MAP);
 
-- 
GitLab


From faffe6f2bb54f94e193594e60e65cdc68a8a68c5 Mon Sep 17 00:00:00 2001
From: Ilias Dimopoulos <idimopoulos@hotmail.com>
Date: Mon, 3 Mar 2025 13:14:24 +0200
Subject: [PATCH 08/10] ISAICP-9536: Add an update hook to delete the orphaned
 entities.

---
 .../group.delete_with_content.feature         | 34 +++++++++++++++++++
 tests/features/update/ISAICP-9536.feature     |  6 ++++
 tests/src/Context/DebugContext.php            | 21 ++++++++++++
 .../custom/joinup_core/joinup_core.deploy.php | 33 ++++++++++++++++++
 4 files changed, 94 insertions(+)
 create mode 100644 tests/features/joinup_group/group.delete_with_content.feature
 create mode 100644 tests/features/update/ISAICP-9536.feature

diff --git a/tests/features/joinup_group/group.delete_with_content.feature b/tests/features/joinup_group/group.delete_with_content.feature
new file mode 100644
index 0000000000..063429b11e
--- /dev/null
+++ b/tests/features/joinup_group/group.delete_with_content.feature
@@ -0,0 +1,34 @@
+@api @group-e
+Feature:
+  In order to not leave orphaned entities
+  As a collection owner
+  I need to be unable to delete groups that have group content.
+
+  Scenario Outline: Delete a group with group content
+    Given <group type> content:
+      | title                       | state   |
+      | <group label> with children | <state> |
+    And news content:
+      | title | state     |
+      | News  | published |
+    And event content:
+      | title | state     |
+      | Event | published |
+    And document content:
+      | title    | state     |
+      | Document | published |
+    And discussion content:
+      | title      | state     |
+      | Discussion | published |
+
+    When I am logged in as a moderator
+    And I go to the delete form of the "<group label> with children" <group type>
+    And I press "Delete"
+    Then I should see the text "The <group label> <group label> with children has been deleted."
+    When I go to the "Discussion" discussion
+    Then I should not see the heading "Discussion"
+
+    Examples:
+      | group label | group type |
+      | Collection  | collection |
+      | Solution    | solution   |
diff --git a/tests/features/update/ISAICP-9536.feature b/tests/features/update/ISAICP-9536.feature
new file mode 100644
index 0000000000..ef8f1f5b84
--- /dev/null
+++ b/tests/features/update/ISAICP-9536.feature
@@ -0,0 +1,6 @@
+@api @group-clone
+Feature: Test orphaned content
+
+  @update:joinup_core_deploy_200305
+  Scenario: Assert that no orphaned content exist in the website.
+    Then no orphaned content should exist in the website
diff --git a/tests/src/Context/DebugContext.php b/tests/src/Context/DebugContext.php
index c4a9490bc4..cc1c071a94 100644
--- a/tests/src/Context/DebugContext.php
+++ b/tests/src/Context/DebugContext.php
@@ -24,4 +24,25 @@ public function printMessages(): void {
     }
   }
 
+  /**
+   * Asserts that no orphaned content exists in the website.
+   *
+   * @Then /^no orphaned content should exist in the website$/
+   */
+  public function noOprhanedContentShouldExistInTheWebsite(): void {
+    $query = <<<SQL
+SELECT n1.nid, n1.type, n1.title, n2.type, n2.title
+FROM node_field_data n1
+         LEFT JOIN node__og_audience oa ON n1.nid = oa.entity_id
+         LEFT JOIN node_field_data n2 ON oa.og_audience_target_id = n2.nid
+WHERE n1.type IN('news', 'discussion', 'document', 'event', 'solution', 'distribution', 'release')
+  AND n2.nid IS NULL
+SQL;
+
+    $nids = \Drupal::database()->query($query)->fetchCol();
+    if (!empty($nids)) {
+      throw new \Exception('Orphaned content found: ' . implode(', ', $nids));
+    }
+  }
+
 }
diff --git a/web/modules/custom/joinup_core/joinup_core.deploy.php b/web/modules/custom/joinup_core/joinup_core.deploy.php
index b989aa0b66..0130856b02 100644
--- a/web/modules/custom/joinup_core/joinup_core.deploy.php
+++ b/web/modules/custom/joinup_core/joinup_core.deploy.php
@@ -183,3 +183,36 @@ function joinup_core_deploy_200304(): string {
   \Drupal::state()->delete('joinup_core_deploy_200200');
   return 'Solution type field and revision values have been restored.';
 }
+
+/**
+ * Delete content of an orphaned group.
+ */
+function joinup_core_deploy_200305(array &$sandbox): string {
+  if (empty($sandbox['nids'])) {
+    $query = <<<SQL
+SELECT n1.nid, n1.type, n1.title, n2.type, n2.title
+FROM node_field_data n1
+         LEFT JOIN node__og_audience oa ON n1.nid = oa.entity_id
+         LEFT JOIN node_field_data n2 ON oa.og_audience_target_id = n2.nid
+WHERE n1.type IN('news', 'discussion', 'document', 'event', 'solution', 'distribution', 'release')
+  AND n2.nid IS NULL
+SQL;
+
+    $sandbox['nids'] = \Drupal::database()->query($query)->fetchCol();
+    if (empty($sandbox['nids'])) {
+      return 'No orphaned content found.';
+    }
+
+    $sandbox['total'] = count($sandbox['nids']);
+    $sandbox['progress'] = 0;
+  }
+
+  $nids = array_splice($sandbox['nids'], 0, 100);
+  $storage = \Drupal::entityTypeManager()->getStorage('node');
+  $storage->delete($storage->loadMultiple($nids));
+
+  $sandbox['progress'] += count($nids);
+  $sandbox['#finished'] = (int) empty($sandbox['nids']);
+
+  return "Deleted {$sandbox['progress']} out of {$sandbox['total']} orphaned content.";
+}
-- 
GitLab


From 40e354dd5a33bc5bca012a143313320d6e6d3366 Mon Sep 17 00:00:00 2001
From: Ilias Dimopoulos <idimopoulos@hotmail.com>
Date: Mon, 3 Mar 2025 13:20:11 +0200
Subject: [PATCH 09/10] ISAICP-9536: Lower the number of nids per batch.

---
 web/modules/custom/joinup_core/joinup_core.deploy.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/web/modules/custom/joinup_core/joinup_core.deploy.php b/web/modules/custom/joinup_core/joinup_core.deploy.php
index 0130856b02..f7429ad7f8 100644
--- a/web/modules/custom/joinup_core/joinup_core.deploy.php
+++ b/web/modules/custom/joinup_core/joinup_core.deploy.php
@@ -207,7 +207,7 @@ function joinup_core_deploy_200305(array &$sandbox): string {
     $sandbox['progress'] = 0;
   }
 
-  $nids = array_splice($sandbox['nids'], 0, 100);
+  $nids = array_splice($sandbox['nids'], 0, 50);
   $storage = \Drupal::entityTypeManager()->getStorage('node');
   $storage->delete($storage->loadMultiple($nids));
 
-- 
GitLab


From be1a87824a25368b70a801144f10c3d8163991a6 Mon Sep 17 00:00:00 2001
From: Claudiu Cristea <clau.cristea@gmail.com>
Date: Mon, 3 Mar 2025 13:37:41 +0200
Subject: [PATCH 10/10] ISAICP-9536: QA remarks

---
 .../group.delete_with_content.feature         | 34 -------------------
 tests/src/Context/DebugContext.php            | 14 ++++----
 .../custom/joinup_core/joinup_core.deploy.php | 17 ++++------
 3 files changed, 14 insertions(+), 51 deletions(-)
 delete mode 100644 tests/features/joinup_group/group.delete_with_content.feature

diff --git a/tests/features/joinup_group/group.delete_with_content.feature b/tests/features/joinup_group/group.delete_with_content.feature
deleted file mode 100644
index 063429b11e..0000000000
--- a/tests/features/joinup_group/group.delete_with_content.feature
+++ /dev/null
@@ -1,34 +0,0 @@
-@api @group-e
-Feature:
-  In order to not leave orphaned entities
-  As a collection owner
-  I need to be unable to delete groups that have group content.
-
-  Scenario Outline: Delete a group with group content
-    Given <group type> content:
-      | title                       | state   |
-      | <group label> with children | <state> |
-    And news content:
-      | title | state     |
-      | News  | published |
-    And event content:
-      | title | state     |
-      | Event | published |
-    And document content:
-      | title    | state     |
-      | Document | published |
-    And discussion content:
-      | title      | state     |
-      | Discussion | published |
-
-    When I am logged in as a moderator
-    And I go to the delete form of the "<group label> with children" <group type>
-    And I press "Delete"
-    Then I should see the text "The <group label> <group label> with children has been deleted."
-    When I go to the "Discussion" discussion
-    Then I should not see the heading "Discussion"
-
-    Examples:
-      | group label | group type |
-      | Collection  | collection |
-      | Solution    | solution   |
diff --git a/tests/src/Context/DebugContext.php b/tests/src/Context/DebugContext.php
index cc1c071a94..1e0c628991 100644
--- a/tests/src/Context/DebugContext.php
+++ b/tests/src/Context/DebugContext.php
@@ -31,13 +31,13 @@ public function printMessages(): void {
    */
   public function noOprhanedContentShouldExistInTheWebsite(): void {
     $query = <<<SQL
-SELECT n1.nid, n1.type, n1.title, n2.type, n2.title
-FROM node_field_data n1
-         LEFT JOIN node__og_audience oa ON n1.nid = oa.entity_id
-         LEFT JOIN node_field_data n2 ON oa.og_audience_target_id = n2.nid
-WHERE n1.type IN('news', 'discussion', 'document', 'event', 'solution', 'distribution', 'release')
-  AND n2.nid IS NULL
-SQL;
+      SELECT n1.nid, n1.type, n1.title, n2.type, n2.title
+      FROM node_field_data n1
+        LEFT JOIN node__og_audience oa ON n1.nid = oa.entity_id
+        LEFT JOIN node_field_data n2 ON oa.og_audience_target_id = n2.nid
+      WHERE n1.type IN('news', 'discussion', 'document', 'event', 'solution', 'distribution', 'release')
+        AND n2.nid IS NULL
+      SQL;
 
     $nids = \Drupal::database()->query($query)->fetchCol();
     if (!empty($nids)) {
diff --git a/web/modules/custom/joinup_core/joinup_core.deploy.php b/web/modules/custom/joinup_core/joinup_core.deploy.php
index f7429ad7f8..19b32e7fb3 100644
--- a/web/modules/custom/joinup_core/joinup_core.deploy.php
+++ b/web/modules/custom/joinup_core/joinup_core.deploy.php
@@ -190,18 +190,15 @@ function joinup_core_deploy_200304(): string {
 function joinup_core_deploy_200305(array &$sandbox): string {
   if (empty($sandbox['nids'])) {
     $query = <<<SQL
-SELECT n1.nid, n1.type, n1.title, n2.type, n2.title
-FROM node_field_data n1
-         LEFT JOIN node__og_audience oa ON n1.nid = oa.entity_id
-         LEFT JOIN node_field_data n2 ON oa.og_audience_target_id = n2.nid
-WHERE n1.type IN('news', 'discussion', 'document', 'event', 'solution', 'distribution', 'release')
-  AND n2.nid IS NULL
-SQL;
+      SELECT n1.nid, n1.type, n1.title, n2.type, n2.title
+      FROM node_field_data n1
+        LEFT JOIN node__og_audience oa ON n1.nid = oa.entity_id
+        LEFT JOIN node_field_data n2 ON oa.og_audience_target_id = n2.nid
+      WHERE n1.type IN('news', 'discussion', 'document', 'event', 'solution', 'distribution', 'release')
+        AND n2.nid IS NULL
+      SQL;
 
     $sandbox['nids'] = \Drupal::database()->query($query)->fetchCol();
-    if (empty($sandbox['nids'])) {
-      return 'No orphaned content found.';
-    }
 
     $sandbox['total'] = count($sandbox['nids']);
     $sandbox['progress'] = 0;
-- 
GitLab