canvas-lms/lib/enrollments_from_user_list.rb

105 lines
3.3 KiB
Ruby

# frozen_string_literal: true
#
# Copyright (C) 2011 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
class EnrollmentsFromUserList
class << self
def process(list, course, opts = {})
EnrollmentsFromUserList.new(course, opts).process(list)
end
end
attr_reader :students, :course
def initialize(course, opts = {})
@course = course
@enrollment_type = opts[:enrollment_type] || "StudentEnrollment"
@role = opts[:role]
@limit = opts[:limit]
@section = (opts[:course_section_id].present? ? @course.course_sections.active.where(id: opts[:course_section_id].to_i).first : nil) || @course.default_section
@limit_privileges_to_course_section = opts[:limit_privileges_to_course_section]
@enrolled_users = {}
@updating_user = opts[:updating_user]
end
def process(list)
raise ArgumentError, "Must provide a UserList or Array (of user tokens)" unless list.is_a?(UserList) || list.is_a?(Array)
@enrollments = []
@user_ids_to_touch = []
users =
if list.is_a?(UserList)
list.addresses.slice!(0, @limit) if @limit
list.users
else
# list of user ids
User.from_tokens(list)
end
users.each_slice(50) do |users_slice|
@course.transaction do
Enrollment.suspend_callbacks(:set_update_cached_due_dates) do
users_slice.each { |user| enroll_user(user) }
end
end
end
if @enrollments.present?
@course.transaction do
user_ids = @enrollments.map(&:user_id).uniq
SubmissionLifecycleManager.recompute_users_for_course(
user_ids,
@course,
nil,
executing_user: @updating_user,
update_grades: true
)
end
end
@user_ids_to_touch.uniq.each_slice(100) do |user_ids|
User.where(id: user_ids).touch_all
User.where(id: UserObservationLink.where(user_id: user_ids).select(:observer_id)).touch_all
end
@enrollments
end
protected
def enroll_user(user)
return unless user
return if @enrolled_users.key?(user.id)
@enrolled_users[user.id] = true
enrollment = @course.enroll_user(user,
@enrollment_type,
section: @section,
limit_privileges_to_course_section: @limit_privileges_to_course_section,
allow_multiple_enrollments: true,
role: @role,
skip_touch_user: true)
if enrollment
@enrollments << enrollment
if enrollment.need_touch_user
@user_ids_to_touch << enrollment.user_id
@user_ids_to_touch << enrollment.associated_user_id if enrollment.associated_user_id
end
end
end
end