135 lines
5.3 KiB
Ruby
135 lines
5.3 KiB
Ruby
#
|
|
# Copyright (C) 2011 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 QuizGroup < ActiveRecord::Base
|
|
attr_accessible :name, :pick_count, :question_points, :assessment_question_bank
|
|
attr_readonly :quiz_id
|
|
belongs_to :quiz
|
|
belongs_to :assessment_question_bank
|
|
has_many :quiz_questions, :dependent => :destroy
|
|
before_save :infer_position
|
|
validates_presence_of :quiz_id
|
|
validates_length_of :name, :maximum => maximum_string_length, :allow_nil => true
|
|
|
|
def infer_position
|
|
if !self.position && self.quiz
|
|
self.position = self.quiz.root_entries_max_position + 1
|
|
end
|
|
end
|
|
protected :infer_position
|
|
|
|
def actual_pick_count
|
|
if self.assessment_question_bank
|
|
# don't do a valid question check because we don't want to instantiate all the bank's questions
|
|
count = self.assessment_question_bank.assessment_question_count
|
|
else
|
|
count = self.quiz_questions.select{|q| q.unsupported != true}.length rescue self.quiz_questions.length
|
|
end
|
|
|
|
[self.pick_count.to_i, count].min
|
|
end
|
|
|
|
def clone_for(quiz, dup=nil, options={})
|
|
dup ||= QuizGroup.new
|
|
self.attributes.delete_if{|k,v| [:id, :quiz_id].include?(k.to_sym) }.each do |key, val|
|
|
dup.send("#{key}=", val)
|
|
end
|
|
dup.quiz_id = quiz.id
|
|
dup
|
|
end
|
|
|
|
# QuizGroup.data is used when creating and editing a quiz, but
|
|
# once the quiz is "saved" then the "rendered" version of the
|
|
# quiz is stored in Quiz.quiz_data. Hence, the teacher can
|
|
# be futzing with questions and groups and not affect
|
|
# the quiz, as students see it.
|
|
def data
|
|
{
|
|
"id" => self.id,
|
|
"name" => self.name,
|
|
"pick_count" => self.pick_count,
|
|
"question_points" => self.question_points,
|
|
"questions" => self.assessment_question_bank_id ? [] : self.quiz_questions.map{|q| q.data},
|
|
"assessment_question_bank_id" => self.assessment_question_bank_id
|
|
}.with_indifferent_access
|
|
end
|
|
|
|
def self.import_from_migration(hash, context, quiz, question_data, position = nil, migration = nil)
|
|
hash = hash.with_indifferent_access
|
|
item ||= QuizGroup.find_by_quiz_id_and_migration_id(quiz.id, hash[:migration_id].nil? ? nil : hash[:migration_id].to_s)
|
|
item ||= quiz.quiz_groups.new
|
|
item.migration_id = hash[:migration_id]
|
|
item.question_points = hash[:question_points]
|
|
item.pick_count = hash[:pick_count]
|
|
item.position = position
|
|
item.name = hash[:title] || t('question_group', "Question Group")
|
|
if hash[:question_bank_migration_id]
|
|
if hash[:question_bank_is_external] && migration && migration.user && hash[:question_bank_context].present? && hash[:question_bank_migration_id].present?
|
|
bank = nil
|
|
bank_context = nil
|
|
|
|
if hash[:question_bank_context] =~ /account_(\d*)/
|
|
bank_context = Account.find_by_id($1)
|
|
elsif hash[:question_bank_context] =~ /course_(\d*)/
|
|
bank_context = Course.find_by_id($1)
|
|
end
|
|
|
|
if bank_context
|
|
bank = bank_context.assessment_question_banks.find_by_id(hash[:question_bank_migration_id])
|
|
end
|
|
|
|
if bank
|
|
if bank.grants_right?(migration.user, nil, :read)
|
|
item.assessment_question_bank_id = bank.id
|
|
else
|
|
migration.add_warning(t('errors.no_permissions', "User didn't have permission to reference question bank in quiz group %{group_name}", :group_name => item.name))
|
|
end
|
|
else
|
|
migration.add_warning(t('errors.no_bank', "Couldn't find the question bank for quiz group %{group_name}", :group_name => item.name))
|
|
end
|
|
else
|
|
if bank = context.assessment_question_banks.find_by_migration_id(hash[:question_bank_migration_id])
|
|
item.assessment_question_bank_id = bank.id
|
|
end
|
|
end
|
|
end
|
|
item.save!
|
|
hash[:questions].each_with_index do |question, i|
|
|
if qq = question_data[:qq_data][question[:migration_id]]
|
|
qq[:position] = i + 1
|
|
if qq[:assessment_question_migration_id]
|
|
if aq = question_data[:aq_data][qq[:assessment_question_migration_id]]
|
|
qq['assessment_question_id'] = aq['assessment_question_id']
|
|
aq_hash = AssessmentQuestion.prep_for_import(qq, context)
|
|
QuizQuestion.import_from_migration(aq_hash, context, quiz, item)
|
|
else
|
|
aq_hash = AssessmentQuestion.import_from_migration(qq, context)
|
|
QuizQuestion.import_from_migration(aq_hash, context, quiz, item)
|
|
end
|
|
end
|
|
elsif aq = question_data[:aq_data][question[:migration_id]]
|
|
aq[:points_possible] = question[:points_possible] if question[:points_possible]
|
|
aq[:position] = i + 1
|
|
QuizQuestion.import_from_migration(aq, context, quiz, item)
|
|
end
|
|
end
|
|
|
|
item
|
|
end
|
|
end
|