diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb
index f2fffd8f74c..e2fbd154f71 100644
--- a/app/controllers/submissions_controller.rb
+++ b/app/controllers/submissions_controller.rb
@@ -141,6 +141,7 @@ class SubmissionsController < ApplicationController
"online_url" => ["url"].freeze,
"online_upload" => ["file_ids"].freeze,
"media_recording" => ["media_comment_id", "media_comment_type"].freeze,
+ "basic_lti_launch" => ["url"].freeze
}.freeze
# @API Submit an assignment
@@ -158,7 +159,7 @@ class SubmissionsController < ApplicationController
# @argument comment[text_comment] [String]
# Include a textual comment with the submission.
#
- # @argument submission[submission_type] [Required, String, "online_text_entry"|"online_url"|"online_upload"|"media_recording"]
+ # @argument submission[submission_type] [Required, String, "online_text_entry"|"online_url"|"online_upload"|"media_recording"|"basic_lti_launch"]
# The type of submission being made. The assignment submission_types must
# include this submission type as an allowed option, or the submission will be rejected with a 400 error.
#
@@ -177,7 +178,7 @@ class SubmissionsController < ApplicationController
# Submit the assignment as a URL. The URL scheme must be "http" or "https",
# no "ftp" or other URL schemes are allowed. If no scheme is given (e.g.
# "www.example.com") then "http" will be assumed. Requires a submission_type
- # of "online_url".
+ # of "online_url" or "basic_lti_launch".
#
# @argument submission[file_ids][] [Integer]
# Submit the assignment as a set of one or more previously uploaded files
diff --git a/app/models/assignment.rb b/app/models/assignment.rb
index 08752a48b31..200482f2ccd 100644
--- a/app/models/assignment.rb
+++ b/app/models/assignment.rb
@@ -1321,7 +1321,7 @@ class Assignment < ActiveRecord::Base
submitted = case opts[:submission_type]
when "online_text_entry"
opts[:body].present?
- when "online_url"
+ when "online_url", "basic_lti_launch"
opts[:url].present?
when "online_upload"
opts[:attachments].size > 0
diff --git a/app/models/assignment/speed_grader.rb b/app/models/assignment/speed_grader.rb
index 51f68891e92..e9182975688 100644
--- a/app/models/assignment/speed_grader.rb
+++ b/app/models/assignment/speed_grader.rb
@@ -2,7 +2,6 @@ require_relative '../assignment'
class Assignment
class SpeedGrader
-
def initialize(assignment, user, avatars: false, grading_role: :grader)
@assignment = assignment
@user = user
@@ -117,7 +116,7 @@ class Assignment
res[:submissions] = submissions.map do |sub|
json = sub.as_json(:include_root => false,
- :methods => [:submission_history, :late],
+ :methods => [:submission_history, :late, :external_tool_url],
:only => submission_fields
).merge("from_enrollment_type" => enrollment_types_by_id[sub.user_id])
diff --git a/app/models/lti/lti_assignment_creator.rb b/app/models/lti/lti_assignment_creator.rb
index cd06d05a405..4fd9760309f 100644
--- a/app/models/lti/lti_assignment_creator.rb
+++ b/app/models/lti/lti_assignment_creator.rb
@@ -3,8 +3,9 @@ module Lti
SUBMISSION_TYPES_MAP = {
'online_upload' => 'file',
'online_url' => 'url',
- 'external_tool' => ['url', 'text']
- }
+ 'external_tool' => ['url', 'text'].freeze,
+ 'basic_lti_launch' => 'url'
+ }.freeze
def initialize(assignment, source_id = nil)
@assignment = assignment
diff --git a/app/models/submission.rb b/app/models/submission.rb
index e00fd1cee35..2cdd57b5b82 100644
--- a/app/models/submission.rb
+++ b/app/models/submission.rb
@@ -482,6 +482,13 @@ class Submission < ActiveRecord::Base
turnitin_data.select{|_, v| v.is_a?(Hash) && v.key?(:outcome_response)}.any?
end
+ def external_tool_url
+ if self.submission_type == 'basic_lti_launch'
+ base_url = "#{HostUrl.protocol}://#{HostUrl.default_host}"
+ base_url + "/courses/#{assignment.context.id}/external_tools/retrieve?display=borderless&assignment_id=#{assignment.id}&url=#{URI.encode(url)}"
+ end
+ end
+
def touch_graders
self.class.connection.after_transaction_commit do
if self.assignment && self.user && self.assignment.context.is_a?(Course)
diff --git a/lib/basic_lti/basic_outcomes.rb b/lib/basic_lti/basic_outcomes.rb
index 561d5f399d0..e7ecf71a1e7 100644
--- a/lib/basic_lti/basic_outcomes.rb
+++ b/lib/basic_lti/basic_outcomes.rb
@@ -124,6 +124,10 @@ module BasicLTI
@lti_request && @lti_request.at_css('imsx_POXBody > replaceResultRequest > resultRecord > result > resultData > url').try(:content)
end
+ def result_data_launch_url
+ @lti_request && @lti_request.at_css('imsx_POXBody > replaceResultRequest > resultRecord > result > resultData > ltiLaunchUrl').try(:content)
+ end
+
def to_xml
xml = LtiResponse.envelope.dup
xml.at_css('imsx_POXHeader imsx_statusInfo imsx_codeMajor').content = code_major
@@ -186,7 +190,7 @@ module BasicLTI
protected
- def handle_replaceResult(tool, course, assignment, user)
+ def handle_replaceResult(_tool, _course, assignment, user)
text_value = self.result_score
new_score = Float(text_value) rescue false
raw_score = Float(self.result_total_score) rescue false
@@ -196,9 +200,12 @@ module BasicLTI
if text = result_data_text
submission_hash[:body] = text
submission_hash[:submission_type] = 'online_text_entry'
- elsif url = result_data_url
+ elsif (url = result_data_url)
submission_hash[:url] = url
submission_hash[:submission_type] = 'online_url'
+ elsif (launch_url = result_data_launch_url)
+ submission_hash[:url] = launch_url
+ submission_hash[:submission_type] = 'basic_lti_launch'
end
old_submission = assignment.submissions.where(user_id: user.id).first
diff --git a/public/javascripts/speed_grader.js b/public/javascripts/speed_grader.js
index 748a1487e71..fca419628c2 100644
--- a/public/javascripts/speed_grader.js
+++ b/public/javascripts/speed_grader.js
@@ -1772,13 +1772,11 @@ define([
$iframe_holder.show().loadDocPreview($.extend(previewOptions, {
crocodoc_session_url: (attachment.provisional_crocodoc_url || attachment.crocodoc_url)
}));
- }
- else if (attachment && attachment.canvadoc_url) {
+ } else if (attachment && attachment.canvadoc_url) {
$iframe_holder.show().loadDocPreview($.extend(previewOptions, {
canvadoc_session_url: attachment.canvadoc_url
}));
- }
- else if ( attachment && ($.isPreviewable(attachment.content_type, 'google')) ) {
+ } else if ( attachment && ($.isPreviewable(attachment.content_type, 'google')) ) {
if (!INST.disableCrocodocPreviews) $no_annotation_warning.show();
var currentStudentIDAsOfAjaxCall = this.currentStudent.id;
@@ -1787,16 +1785,20 @@ define([
return(currentStudentIDAsOfAjaxCall == this.currentStudent.id);
},this)});
$iframe_holder.show().loadDocPreview(previewOptions);
- }
- else if (attachment && browserableCssClasses.test(attachment.mime_class)) {
- var src = unescape($submission_file_hidden.find('.display_name').attr('href'))
- .replace("{{submissionId}}", this.currentStudent.submission.user_id)
- .replace("{{attachmentId}}", attachment.id);
- $iframe_holder.html('').show();
- }
- else {
- //load in the iframe preview. if we are viewing a past version of the file pass the version to preview in the url
- $iframe_holder.html($.raw(
+ } else if (attachment && browserableCssClasses.test(attachment.mime_class)) {
+ var src = unescape($submission_file_hidden.find('.display_name').attr('href'))
+ .replace("{{submissionId}}", this.currentStudent.submission.user_id)
+ .replace("{{attachmentId}}", attachment.id);
+ $iframe_holder.html('').show();
+ } else if (this.currentStudent.submission.external_tool_url) {
+ $iframe_holder.html(
+ $.raw(''
+ )
+ ).show();
+ } else {
+ //load in the iframe preview. if we are viewing a past version of the file pass the version to preview in the url
+ $iframe_holder.html($.raw(
'