Skip to content

Commit b34ced0

Browse files
committed
assignment freezing improvements and fixes
Adds an option to not allow already copied assignments from being copied again Assignment groups that contain a frozen assignment can not be deleted When an assignment is copied that didn't have the flag set to be frozen, the copied flag isn't set. This allows the assignment to be locked in the new course, but still edited Test Plan: * In the plugin settings for assignment freezer check the option to not allow assignments to be copied twice * Create an assignment and flag it to be frozen * Copy the course, verify it is frozen * Try to copy the course again as a non-admin - The frozen assignments should not be copied * As a teacher try to delete an assignment group for a frozen assignment. The trash can should not appear * Copy an assignment that is flagged to be frozen * In the new course, you should be able to set the flag and still edit the assignment closes #8736 #8549 #8537 Change-Id: Ia3f1be4d5c1b6112507338df7e5a49dd76a5ed7f Reviewed-on: https://gerrit.instructure.com/10995 Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Zach Pendleton <zachp@instructure.com>
1 parent 55fe0ed commit b34ced0

14 files changed

Lines changed: 154 additions & 12 deletions

app/controllers/assignment_groups_controller.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,15 @@ def update
175175
def destroy
176176
@assignment_group = AssignmentGroup.find(params[:id])
177177
if authorized_action(@assignment_group, @current_user, :delete)
178+
if @assignment_group.has_frozen_assignments?(@current_user)
179+
@assignment_group.errors.add('workflow_state', t('errors.cannot_delete_group', "You can not delete a group with a locked assignment.", :att_name => 'workflow_state'))
180+
respond_to do |format|
181+
format.html { redirect_to named_context_url(@context, :context_assignments_url) }
182+
format.json { render :json => @assignment_group.errors.to_json, :status => :bad_request }
183+
end
184+
return
185+
end
186+
178187
if params[:move_assignments_to]
179188
@new_group = @context.assignment_groups.active.find(params[:move_assignments_to])
180189
order = @new_group.assignments.active.map(&:id)

app/models/assignment.rb

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,8 +1526,12 @@ def self.import_from_migration(hash, context, item=nil)
15261526
description += hash[:instructions_in_html] == false ? ImportedHtmlConverter.convert_text(hash[:instructions] || "", context) : ImportedHtmlConverter.convert(hash[:instructions] || "", context)
15271527
description += Attachment.attachment_list_from_migration(context, hash[:attachment_ids])
15281528
item.description = description
1529-
item.copied = true
1530-
item.copying = true
1529+
1530+
if hash[:freeze_on_copy]
1531+
item.freeze_on_copy = true
1532+
item.copied = true
1533+
item.copying = true
1534+
end
15311535
if !hash[:submission_types].blank?
15321536
item.submission_types = hash[:submission_types]
15331537
elsif ['discussion_topic'].include?(hash[:submission_format])
@@ -1608,7 +1612,7 @@ def self.import_from_migration(hash, context, item=nil)
16081612
[:all_day, :turnitin_enabled, :peer_reviews_assigned, :peer_reviews,
16091613
:automatic_peer_reviews, :anonymous_peer_reviews,
16101614
:grade_group_students_individually, :allowed_extensions, :min_score,
1611-
:max_score, :mastery_score, :position, :peer_review_count, :freeze_on_copy
1615+
:max_score, :mastery_score, :position, :peer_review_count
16121616
].each do |prop|
16131617
item.send("#{prop}=", hash[prop]) unless hash[prop].nil?
16141618
end
@@ -1729,6 +1733,10 @@ def att_frozen?(att, user=nil)
17291733
false
17301734
end
17311735

1736+
def can_copy?(user)
1737+
!att_frozen?("no_copying", user)
1738+
end
1739+
17321740
def frozen_atts_not_altered
17331741
return if self.copying
17341742
FREEZABLE_ATTRIBUTES.each do |att|

app/models/assignment_group.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,4 +235,15 @@ def self.add_never_drop_assignment(group, assignment)
235235
group.save
236236
end
237237

238+
def has_frozen_assignments?(user)
239+
return false unless PluginSetting.settings_for_plugin(:assignment_freezer)
240+
return false unless self.active_assignments.length > 0
241+
242+
self.active_assignments.each do |asmnt|
243+
return true if asmnt.frozen_for_user?(user)
244+
end
245+
246+
false
247+
end
248+
238249
end

app/models/content_export.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def add_item_to_export(obj)
131131
selected_content[asset_type][CC::CCHelper.create_key(obj)] = true
132132
end
133133

134-
def add_error(user_message, exception_or_info)
134+
def add_error(user_message, exception_or_info=nil)
135135
self.settings[:errors] ||= []
136136
if exception_or_info.is_a?(Exception)
137137
er = ErrorReport.log_exception(:course_export, exception_or_info)

app/views/plugins/_assignment_freezer_settings.html.erb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ TEXT
99
%></p>
1010
</td>
1111
</tr>
12+
<tr>
13+
<td colspan="2">
14+
<%= f.check_box "no_copying", {}, 'yes', 'no' %>
15+
<%= f.label "no_copying", t('no_copying_frozen', "Don't allow frozen assignments to be copied.") %>
16+
</td>
17+
</tr>
1218
<% Assignment::FREEZABLE_ATTRIBUTES.sort.each do |att| %>
1319
<tr>
1420
<td colspan=2><%= f.check_box att, {}, 'yes', 'no' %>

app/views/shared/_assignment_group.html.erb

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@
3030
<a href="#" class="edit_group_link no-hover">
3131
<%= image_tag 'edit.png', :alt => t('alts.edit_group_details', "Edit"), :title => t('links.edit_group_details', "Edit Group Details") %>
3232
</a>
33-
<a href="<%= context_url(@context, :controller => :assignment_groups, :action => :destroy, :id => (assignment_group ? assignment_group.id : "{{ id }}")) %>" class="delete_group_link no-hover">
34-
<%= image_tag 'delete.png', :alt => t('alts.delete_assignment_group', "Delete"), :title => t('titles.delete_assignment_group', "Delete Assignment Group") %>
35-
</a>
33+
<% if !group || !group.has_frozen_assignments?(@current_user) %>
34+
<a href="<%= context_url(@context, :controller => :assignment_groups, :action => :destroy, :id => (assignment_group ? assignment_group.id : "{{ id }}")) %>" class="delete_group_link no-hover">
35+
<%= image_tag 'delete.png', :alt => t('alts.delete_assignment_group', "Delete"), :title => t('titles.delete_assignment_group', "Delete Assignment Group") %>
36+
</a>
37+
<% end %>
3638
</div>
3739
<div class="clear"></div>
3840
<div class="more_info" style="min-height: 30px; display: none; padding-left: 30px; font-size: 0.8em;">

lib/cc/assignment_resources.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,17 @@ module AssignmentResources
2121
def add_assignments
2222
@course.assignments.active.no_graded_quizzes_or_topics.each do |assignment|
2323
next unless export_object?(assignment)
24+
25+
title = assignment.title rescue I18n.t('course_exports.unknown_titles.assignment', "Unknown assignment")
26+
27+
if !assignment.can_copy?(@user)
28+
add_error(I18n.t('course_exports.errors.assignment_is_locked', "The assignment \"%{title}\" could not be copied because it is locked.", :title => title))
29+
next
30+
end
31+
2432
begin
2533
add_assignment(assignment)
2634
rescue
27-
title = assignment.title rescue I18n.t('course_exports.unknown_titles.assignment', "Unknown assignment")
2835
add_error(I18n.t('course_exports.errors.assignment', "The assignment \"%{title}\" failed to export", :title => title), $!)
2936
end
3037
end

lib/cc/manifest.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class Manifest
2020
include CCHelper
2121

2222
attr_accessor :exporter, :weblinks, :basic_ltis
23-
delegate :add_error, :set_progress, :export_object?, :for_course_copy, :add_item_to_export, :to => :exporter
23+
delegate :add_error, :set_progress, :export_object?, :for_course_copy, :add_item_to_export, :user, :to => :exporter
2424

2525
def initialize(exporter)
2626
@exporter = exporter

lib/cc/qti/qti_generator.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class QTIGenerator
2424

2525
def initialize(manifest, resources_node, html_exporter)
2626
@manifest = manifest
27+
@user = manifest.user
2728
@resources_node = resources_node
2829
@course = manifest.course
2930
@export_dir = @manifest.export_dir
@@ -55,10 +56,17 @@ def generate
5556

5657
@course.quizzes.active.each do |quiz|
5758
next unless export_object?(quiz) || export_object?(quiz.assignment)
59+
60+
title = quiz.title rescue I18n.t('unknown_quiz', "Unknown quiz")
61+
62+
if quiz.assignment && !quiz.assignment.can_copy?(@user)
63+
add_error(I18n.t('course_exports.errors.quiz_is_locked', "The quiz \"%{title}\" could not be copied because it is locked.", :title => title))
64+
next
65+
end
66+
5867
begin
5968
generate_quiz(quiz)
6069
rescue
61-
title = quiz.title rescue I18n.t('unknown_quiz', "Unknown quiz")
6270
add_error(I18n.t('course_exports.errors.quiz', "The quiz \"%{title}\" failed to export", :title => title), $!)
6371
end
6472
end

lib/cc/qti/qti_manifest.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class QTIManifest
2121
include CC::CCHelper
2222

2323
attr_accessor :exporter
24-
delegate :add_error, :set_progress, :export_object?, :qti_export?, :course, :to => :exporter
24+
delegate :add_error, :set_progress, :export_object?, :qti_export?, :course, :user, :to => :exporter
2525
delegate :referenced_files, :to => :@html_exporter
2626

2727
def initialize(exporter)

0 commit comments

Comments
 (0)