From cef2dd4fb4fcd213afa3f67815621663ea67f382 Mon Sep 17 00:00:00 2001
From: Marcin Grabias <mgrabias@ogtrading.eu>
Date: Thu, 8 May 2025 15:23:48 +0200
Subject: [PATCH] Make adding students to classes access mapped by course
 permission.

---
 lms.group.permissions.yml                |  3 +++
 lms.post_update.php                      | 17 +++++++++++++++++
 src/Access/ClassPermissionCalculator.php | 19 +++++++++++++------
 3 files changed, 33 insertions(+), 6 deletions(-)
 create mode 100644 lms.group.permissions.yml

diff --git a/lms.group.permissions.yml b/lms.group.permissions.yml
new file mode 100644
index 0000000..6e2d98b
--- /dev/null
+++ b/lms.group.permissions.yml
@@ -0,0 +1,3 @@
+add students:
+  title: 'Add students'
+  description: 'Add students to child classes. Effective only in LMS Courses.'
diff --git a/lms.post_update.php b/lms.post_update.php
index dfac7f6..1737f3a 100644
--- a/lms.post_update.php
+++ b/lms.post_update.php
@@ -41,3 +41,20 @@ function lms_post_update_set_statuses(array &$sandbox): void {
   $sandbox['progress']++;
   $sandbox['#finished'] = $sandbox['progress'] / $sandbox['total'];
 }
+
+/**
+ * BC - Add add students permission to all member course group roles.
+ */
+function lms_post_update_add_students_permission(): void {
+  $roles = \Drupal::entityTypeManager()->getStorage('group_role')->loadByProperties([
+    'group_type' => 'lms_course',
+    'scope' => ['insider', 'individual'],
+  ]);
+  /** @var Drupal\group\Entity\GroupRoleInterface $role */
+  foreach ($roles as $role) {
+    if ($role->hasPermission('add students')) {
+      continue;
+    }
+    $role->grantPermission('add students')->save();
+  }
+}
diff --git a/src/Access/ClassPermissionCalculator.php b/src/Access/ClassPermissionCalculator.php
index 0e0b165..57ca2db 100644
--- a/src/Access/ClassPermissionCalculator.php
+++ b/src/Access/ClassPermissionCalculator.php
@@ -9,6 +9,7 @@ use Drupal\Core\Session\AccountInterface;
 use Drupal\flexible_permissions\CalculatedPermissionsItem;
 use Drupal\flexible_permissions\PermissionCalculatorBase;
 use Drupal\flexible_permissions\RefinableCalculatedPermissionsInterface;
+use Drupal\group\Entity\GroupMembershipInterface;
 use Drupal\group\Entity\GroupRelationshipInterface;
 use Drupal\group\PermissionScopeInterface;
 use Drupal\lms\Entity\Bundle\Course;
@@ -51,9 +52,18 @@ final class ClassPermissionCalculator extends PermissionCalculatorBase {
     foreach ($memberships as $membership) {
       $calculated_permissions->addCacheableDependency($membership);
 
-      \assert($membership instanceof GroupRelationshipInterface);
+      \assert($membership instanceof GroupMembershipInterface);
       $course = $membership->getGroup();
       \assert($course instanceof Course);
+
+      $class_permissions = ['view group'];
+      foreach ($membership->getRoles(TRUE) as $role) {
+        $calculated_permissions->addCacheableDependency($role);
+        if ($role->hasPermission('add students')) {
+          $class_permissions[] = 'administer members';
+        }
+      }
+
       foreach ($course->getClasses() as $class) {
         $class_id = $class->id();
         if (\array_key_exists($class_id, $class_ids)) {
@@ -64,10 +74,7 @@ final class ClassPermissionCalculator extends PermissionCalculatorBase {
         $calculated_permissions->addItem(new CalculatedPermissionsItem(
           $scope,
           $class_id,
-          [
-            'administer members',
-            'view group',
-          ],
+          $class_permissions,
           FALSE,
         ));
       }
@@ -83,7 +90,7 @@ final class ClassPermissionCalculator extends PermissionCalculatorBase {
     $courses = [];
 
     foreach ($memberships as $membership) {
-      \assert($membership instanceof GroupRelationshipInterface);
+      \assert($membership instanceof GroupMembershipInterface);
       $course_relationships = $this->entityTypeManager->getStorage('group_relationship')->loadByProperties([
         'plugin_id' => 'lms_classes',
         'entity_id' => $membership->getGroupId(),
-- 
GitLab