public function resync_group_membership()

in local/o365/classes/feature/usergroups/coursegroups.php [517:686]


    public function resync_group_membership($courseid, $groupobjectid = null, $addownersonly = false) {
        global $DB;

        $this->mtrace('Syncing group membership for course #'.$courseid);

        if ($groupobjectid === null) {
            $params = [
                'type' => 'group',
                'subtype' => 'course',
                'moodleid' => $courseid,
            ];
            $objectrec = $DB->get_record('local_o365_objects', $params);
            if (empty($objectrec)) {
                $errmsg = 'Could not find group object ID in local_o365_objects for course '.$courseid.'. ';
                $errmsg .= 'Please ensure group exists first.';
                $this->mtrace($errmsg);
                return false;
            }
            $groupobjectid = $objectrec->objectid;
        }

        $this->mtrace('Syncing to group "'.$groupobjectid.'"');

        // Get current group membership.
        $members = $this->get_group_members($groupobjectid);
        $currentmembers = array_keys($members);

        $owners = $this->get_group_owners($groupobjectid);
        $currentowners = array_keys($owners);

        // Get intended group members.
        $intendedteamownerids = static::get_team_owner_ids_by_course_id($courseid);
        $intendedteammemberuserids = $this->get_team_member_ids_by_course_id($courseid);

        $intendedteamowners = \local_o365\feature\usergroups\utils::get_user_object_ids_by_user_ids($intendedteamownerids);
        $intendedteammembers = \local_o365\feature\usergroups\utils::get_user_object_ids_by_user_ids($intendedteammemberuserids);

        if (!empty($currentowners)) {
            $toaddowners = array_diff($intendedteamowners, $currentowners);
            $toremoveowners = array_diff($currentowners, $intendedteamowners);
        } else {
            $toaddowners = $intendedteamowners;
            $toremoveowners = [];
        }

        if (!empty($currentmembers)) {
            $toaddmembers = array_diff($intendedteammembers, $currentmembers);
            $toremovemembers = array_diff($currentmembers, $intendedteammembers);
        } else {
            $toaddmembers = $intendedteammembers;
            $toremovemembers = [];
        }

        // Check if group object is created.
        $this->mtrace('... Checking if group is setup ...', '');
        $retrycounter = 0;
        while ($retrycounter <= API_CALL_RETRY_LIMIT) {
            try {
                if ($retrycounter) {
                    $this->mtrace('...... Retry #' . $retrycounter);
                    sleep(10);
                }
                $result = $this->graphclient->get_group($groupobjectid);
                if (!empty($result['id'])) {
                    $this->mtrace('Success!');
                    break;
                } else {
                    $this->mtrace('Error!');
                    $this->mtrace('...... Received: ' . \local_o365\utils::tostring($result));
                    $retrycounter++;
                }
            } catch (\Exception $e) {
                $this->mtrace('Error!');
                $this->mtrace('...... Received: ' . $e->getMessage());
                $retrycounter++;
            }
        }

        // Remove owners.
        $this->mtrace('Owners to remove: ' . count($toremoveowners));
        foreach ($toremoveowners as $userobjectid) {
            $this->mtrace('... Removing ' . $userobjectid . '...', '');
            $result = $this->graphclient->remove_owner_from_group($groupobjectid, $userobjectid);
            if ($result === true) {
                $this->mtrace('Success!');
            } else {
                $this->mtrace('Error!');
                $this->mtrace('...... Received: '.\local_o365\utils::tostring($result));
            }
        }

        // Remove members.
        foreach ($toremovemembers as $key => $userobjectid) {
            if (in_array($userobjectid, $intendedteamowners)) {
                unset($toremovemembers[$key]);
            }
        }
        $this->mtrace('Members to remove: ' . count($toremovemembers));
        foreach ($toremovemembers as $userobjectid) {
            $this->mtrace('... Removing ' . $userobjectid . '...', '');
            $result = $this->graphclient->remove_member_from_group($groupobjectid, $userobjectid);
            if ($result === true) {
                $this->mtrace('Success!');
            } else {
                $this->mtrace('Error!');
                $this->mtrace('...... Received: '.\local_o365\utils::tostring($result));
            }
        }

        // Add owners.
        $this->mtrace('Owners to add: ' . count($toaddowners));
        foreach ($toaddowners as $userobjectid) {
            $this->mtrace('... Adding ' . $userobjectid . '...', '');
            $retrycounter = 0;
            while ($retrycounter <= API_CALL_RETRY_LIMIT) {
                if ($retrycounter) {
                    $this->mtrace('...... Retry #' . $retrycounter);
                    sleep(10);
                }
                $result = $this->graphclient->add_owner_to_group($groupobjectid, $userobjectid);
                if ($result === true) {
                    $this->mtrace('Success!');
                    break;
                } else {
                    $this->mtrace('Error!');
                    $this->mtrace('...... Received: ' . \local_o365\utils::tostring($result));
                    $retrycounter++;

                    if (strpos($result, 'Request_ResourceNotFound') === false) {
                        break;
                    }
                }
            }
        }

        // Add members.
        if ($addownersonly) {
            $this->mtrace('Skip adding members');
        } else {
            $this->mtrace('Members to add: ' . count($toaddmembers));
            foreach ($toaddmembers as $userobjectid) {
                $this->mtrace('... Adding ' . $userobjectid . '...', '');
                $retrycounter = 0;
                while ($retrycounter <= API_CALL_RETRY_LIMIT) {
                    if ($retrycounter) {
                        $this->mtrace('...... Retry #' . $retrycounter);
                        sleep(10);
                    }
                    $result = $this->graphclient->add_member_to_group($groupobjectid, $userobjectid);
                    if ($result === true) {
                        $this->mtrace('Success!');
                        break;
                    } else {
                        $this->mtrace('Error!');
                        $this->mtrace('...... Received: ' . \local_o365\utils::tostring($result));
                        $retrycounter++;

                        if (strpos($result, 'Request_ResourceNotFound') === false) {
                            break;
                        }
                    }
                }
            }
        }

        $this->mtrace('Done');

        return [array_unique(array_merge($toaddowners, $toaddmembers)),
            array_unique(array_merge($toremoveowners, $toremovemembers))];
    }