From 37af046c473aff494d378e87a194f2db9440dc9d Mon Sep 17 00:00:00 2001
From: bluegeek9 <steveneayers@gmail.com>
Date: Sat, 22 Feb 2025 08:48:54 -0600
Subject: [PATCH 1/2] Issue #3508061 by bluegeek9: Restore Group v1 support:
 The website encountered an error when a non-administrator user cloned content

---
 quick_node_clone.module                       | 32 ++++++---
 .../QuickNodeCloneGroupIntegrationTest.php    | 69 +++++++++++++++++++
 2 files changed, 92 insertions(+), 9 deletions(-)

diff --git a/quick_node_clone.module b/quick_node_clone.module
index bd3b2cc..02369a1 100644
--- a/quick_node_clone.module
+++ b/quick_node_clone.module
@@ -11,6 +11,7 @@ use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Url;
+use Drupal\group\Entity\GroupContent;
 use Drupal\group\Entity\GroupRelationship;
 use Drupal\group\Plugin\Group\Relation\GroupRelationTypeManagerInterface;
 use Drupal\node\NodeInterface;
@@ -125,17 +126,30 @@ function quick_node_clone_node_access(NodeInterface $node, $operation, AccountIn
 
   if (\Drupal::moduleHandler()->moduleExists('gnode')) {
 
-    $group_relationships = GroupRelationship::loadByEntity($node);
-    $relation_type_manager = \Drupal::service('group_relation_type.manager');
-    assert($relation_type_manager instanceof GroupRelationTypeManagerInterface);
-    foreach ($group_relationships as $group_relationship) {
-      $access_handler = $relation_type_manager->getAccessControlHandler($group_relationship->getPluginId());
-      $access = $access_handler->entityCreateAccess($group_relationship->getGroup(), $account);
-      if ($access) {
-        return AccessResult::allowed();
+    // Check that user has permission to create a relationship.
+    // Support for group module version 1.x.
+    if (class_exists(GroupContent::class)) {
+      $group_relationships = GroupContent::loadByEntity($node);
+      foreach ($group_relationships as $group_relationship) {
+        $access = $group_relationship->getContentPlugin()->createEntityAccess($group_relationship->getGroup(), $current_user);
+        if ($access->isAllowed()) {
+          return AccessResult::allowed();
+        }
+      }
+    }
+    // Support for group module version 2.x and 3.x.
+    else {
+      $group_relationships = GroupRelationship::loadByEntity($node);
+      $relation_type_manager = \Drupal::service('group_relation_type.manager');
+      assert($relation_type_manager instanceof GroupRelationTypeManagerInterface);
+      foreach ($group_relationships as $group_relationship) {
+        $access_handler = $relation_type_manager->getAccessControlHandler($group_relationship->getPluginId());
+        $access = $access_handler->entityCreateAccess($group_relationship->getGroup(), $account);
+        if ($access) {
+          return AccessResult::allowed();
+        }
       }
     }
-
   }
 
   // Only check global access if we there is no group module enabled, or
diff --git a/tests/src/Functional/QuickNodeCloneGroupIntegrationTest.php b/tests/src/Functional/QuickNodeCloneGroupIntegrationTest.php
index 4df2365..9780cbd 100644
--- a/tests/src/Functional/QuickNodeCloneGroupIntegrationTest.php
+++ b/tests/src/Functional/QuickNodeCloneGroupIntegrationTest.php
@@ -5,9 +5,11 @@ namespace Drupal\Tests\quick_node_clone\Functional;
 use Drupal\Tests\BrowserTestBase;
 use Drupal\Tests\node\Traits\NodeCreationTrait;
 use Drupal\group\Entity\Group;
+use Drupal\group\Entity\GroupContent;
 use Drupal\group\Entity\GroupRelationship;
 use Drupal\group\Entity\GroupRole;
 use Drupal\group\Entity\GroupType;
+use Drupal\group\Entity\Storage\GroupContentTypeStorageInterface;
 use Drupal\group\Entity\Storage\GroupRelationshipTypeStorageInterface;
 use Drupal\group\PermissionScopeInterface;
 
@@ -57,6 +59,73 @@ class QuickNodeCloneGroupIntegrationTest extends BrowserTestBase {
    * Test node cloning.
    */
   public function testNodeClone() {
+    if (class_exists(GroupContent::class)) {
+      $this->checkGroupContent();
+    }
+    else {
+      $this->checkGroupRelations();
+    }
+  }
+
+  /**
+   * Test groups v1.
+   */
+  public function checkGroupContent() {
+    // Prepare a group type.
+    $group_type = GroupType::create([
+      'id' => $this->randomMachineName(),
+      'label' => $this->randomString(),
+      'creator_wizard' => FALSE,
+    ]);
+    $group_type->save();
+    $node_type = 'page';
+    $gnode_plugin_id = 'group_node:' . $node_type;
+    $content_type_storage = $this->entityTypeManager->getStorage('group_content_type');
+    /* @phpstan-ignore-next-line */
+    assert($content_type_storage instanceof GroupContentTypeStorageInterface);
+    $content_type_storage->save($content_type_storage->createFromPlugin($group_type, $gnode_plugin_id));
+
+    // Create a node and add it to a group.
+    $node = $this->createNode([
+      'type' => $node_type,
+      'title' => $this->randomString(200),
+    ]);
+    $group = Group::create([
+      'type' => $group_type->id(),
+      'label' => $this->randomString(),
+    ]);
+    $group->save();
+    $group->addContent($node, $gnode_plugin_id);
+
+    // Create a user with the required permissions.
+    $group_role = GroupRole::create([
+      'group_type' => $group_type->id(),
+      'id' => $this->randomMachineName(),
+      'label' => $this->randomString(),
+      'permissions' => ['administer group'],
+    ]);
+    $group_role->save();
+    $user = $this->drupalCreateUser(["clone $node_type content"]);
+    $group->addMember($user, ['group_roles' => [$group_role->id()]]);
+
+    // Clone the node and check that it is added to the group.
+    $this->drupalLogin($user);
+    $this->drupalGet("clone/{$node->id()}/quick_clone");
+    $cloned_node_title = $this->randomMachineName(200);
+    $edit = [
+      'title[0][value]' => $cloned_node_title,
+    ];
+    $this->submitForm($edit, 'Save');
+    $cloned_node = $this->getNodeByTitle($cloned_node_title);
+    /* @phpstan-ignore-next-line */
+    $cloned_relation = GroupContent::loadByEntity($cloned_node);
+    $this->assertCount(1, $cloned_relation);
+  }
+
+  /**
+   * Test groups v2 and higher.
+   */
+  protected function checkGroupRelations() {
     // Prepare a group type.
     $group_type = GroupType::create([
       'id' => $this->randomMachineName(),
-- 
GitLab


From 881560852e20112db21ab5e55fc7e254c1a6466e Mon Sep 17 00:00:00 2001
From: bluegeek9 <steveneayers@gmail.com>
Date: Sat, 22 Feb 2025 08:55:49 -0600
Subject: [PATCH 2/2] Issue #3508061 by bluegeek9: Restore Group v1 support:
 The website encountered an error when a non-administrator user cloned content

---
 quick_node_clone.module | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/quick_node_clone.module b/quick_node_clone.module
index 02369a1..f485a23 100644
--- a/quick_node_clone.module
+++ b/quick_node_clone.module
@@ -131,7 +131,7 @@ function quick_node_clone_node_access(NodeInterface $node, $operation, AccountIn
     if (class_exists(GroupContent::class)) {
       $group_relationships = GroupContent::loadByEntity($node);
       foreach ($group_relationships as $group_relationship) {
-        $access = $group_relationship->getContentPlugin()->createEntityAccess($group_relationship->getGroup(), $current_user);
+        $access = $group_relationship->getContentPlugin()->createEntityAccess($group_relationship->getGroup(), $account);
         if ($access->isAllowed()) {
           return AccessResult::allowed();
         }
-- 
GitLab