public function saveRoles($UserID, $RoleIDs, $RecordEvent)
{
if (is_string($RoleIDs) && !is_numeric($RoleIDs)) {
// The $RoleIDs are a comma delimited list of role names.
$RoleNames = array_map('trim', explode(',', $RoleIDs));
$RoleIDs = $this->SQL->select('r.RoleID')->from('Role r')->whereIn('r.Name', $RoleNames)->get()->resultArray();
$RoleIDs = array_column($RoleIDs, 'RoleID');
}
if (!is_array($RoleIDs)) {
$RoleIDs = [$RoleIDs];
}
// Get the current roles.
$OldRoleIDs = [];
$OldRoleData = $this->SQL->select('ur.RoleID, r.Name')->from('UserRole ur')->join('Role r', 'r.RoleID = ur.RoleID', 'left')->where('ur.UserID', $UserID)->get()->resultArray();
if ($OldRoleData !== false) {
$OldRoleIDs = array_column($OldRoleData, 'RoleID');
}
// 1a) Figure out which roles to delete.
$DeleteRoleIDs = [];
foreach ($OldRoleData as $row) {
// The role should be deleted if it is an orphan or the user has not been assigned the role.
if ($row['Name'] === null || !in_array($row['RoleID'], $RoleIDs)) {
$DeleteRoleIDs[] = $row['RoleID'];
}
}
// 1b) Remove old role associations for this user.
if (!empty($DeleteRoleIDs)) {
$this->SQL->whereIn('RoleID', $DeleteRoleIDs)->delete('UserRole', ['UserID' => $UserID]);
}
// 2a) Figure out which roles to insert.
$InsertRoleIDs = array_diff($RoleIDs, $OldRoleIDs);
// 2b) Insert the new role associations for this user.
foreach ($InsertRoleIDs as $InsertRoleID) {
if (is_numeric($InsertRoleID)) {
$this->SQL->insert('UserRole', ['UserID' => $UserID, 'RoleID' => $InsertRoleID]);
}
}
$this->clearCache($UserID, ['roles', 'permissions']);
if ($RecordEvent) {
$User = $this->getID($UserID);
$OldRoles = [];
foreach ($DeleteRoleIDs as $deleteRoleID) {
$role = RoleModel::roles($deleteRoleID);
$OldRoles[] = val('Name', $role, t('Unknown') . ' (' . $deleteRoleID . ')');
}
$NewRoles = [];
foreach ($InsertRoleIDs as $insertRoleID) {
$role = RoleModel::roles($insertRoleID);
$NewRoles[] = val('Name', $role, t('Unknown') . ' (' . $insertRoleID . ')');
}
$RemovedRoles = array_diff($OldRoles, $NewRoles);
$NewRoles = array_diff($NewRoles, $OldRoles);
foreach ($RemovedRoles as $RoleName) {
Logger::event('role_remove', Logger::INFO, "{username} removed {toUsername} from the {role} role.", ['touserid' => $User->UserID, 'toUsername' => $User->Name, 'role' => $RoleName]);
}
foreach ($NewRoles as $RoleName) {
Logger::event('role_add', Logger::INFO, "{username} added {toUsername} to the {role} role.", ['touserid' => $User->UserID, 'toUsername' => $User->Name, 'role' => $RoleName]);
}
}
}