diff --git a/app/models/context_external_tool.rb b/app/models/context_external_tool.rb index 9155cbfb849..5bcc0ec2cf2 100644 --- a/app/models/context_external_tool.rb +++ b/app/models/context_external_tool.rb @@ -7,7 +7,7 @@ class ContextExternalTool < ActiveRecord::Base :name, :description, :custom_fields, :custom_fields_string, :course_navigation, :account_navigation, :user_navigation, :resource_selection, :editor_button, - :config_type, :config_url, :config_xml + :config_type, :config_url, :config_xml, :tool_id validates_presence_of :name validates_presence_of :consumer_key validates_presence_of :shared_secret @@ -197,6 +197,7 @@ class ContextExternalTool < ActiveRecord::Base settings.delete(:account_navigation) if settings[:account_navigation] && (!settings[:account_navigation][:url]) settings.delete(:resource_selection) if settings[:resource_selection] && (!settings[:resource_selection][:url] || !settings[:resource_selection][:selection_width] || !settings[:resource_selection][:selection_height]) settings.delete(:editor_button) if settings[:editor_button] && (!settings[:editor_button][:url] || !settings[:editor_button][:icon_url]) + settings[:icon_url] ||= settings[:editor_button][:icon_url] if settings[:editor_button] && settings[:editor_button][:icon_url] [:resource_selection, :editor_button].each do |type| if settings[type] settings[type][:selection_width] = settings[type][:selection_width].to_i @@ -413,6 +414,7 @@ class ContextExternalTool < ActiveRecord::Base item.migration_id = hash[:migration_id] item.name = hash[:title] item.description = hash[:description] + item.tool_id = hash[:tool_id] item.url = hash[:url] unless hash[:url].blank? item.domain = hash[:domain] unless hash[:domain].blank? item.privacy_level = hash[:privacy_level] || 'name_only' diff --git a/app/models/developer_key.rb b/app/models/developer_key.rb index 9f173ec9bfa..592a04a465e 100644 --- a/app/models/developer_key.rb +++ b/app/models/developer_key.rb @@ -21,6 +21,7 @@ class DeveloperKey < ActiveRecord::Base belongs_to :account has_many :page_views has_many :access_tokens + has_many :context_external_tools, :primary_key => 'tool_id', :foreign_key => 'tool_id' attr_accessible :api_key, :name, :user, :account diff --git a/app/views/external_tools/tool_show.html.erb b/app/views/external_tools/tool_show.html.erb index e10bcc71f7f..8ba1f424fd7 100644 --- a/app/views/external_tools/tool_show.html.erb +++ b/app/views/external_tools/tool_show.html.erb @@ -16,7 +16,7 @@ <% end %> -
id="tool_form" class="<%= 'new_tab' if @tag.try(:new_tab) %>"> + id="tool_form" class="<%= 'new_tab' if @tag.try(:new_tab) %>" data-tool-id="<%= @tool.tool_id || 'unknown' %>"> <% @tool_settings.each do |key, value| %> <%= hidden_field_tag key, value %> <% end %> diff --git a/db/migrate/20120505003400_add_tool_id_to_external_tools.rb b/db/migrate/20120505003400_add_tool_id_to_external_tools.rb new file mode 100644 index 00000000000..1c6dfa4ca88 --- /dev/null +++ b/db/migrate/20120505003400_add_tool_id_to_external_tools.rb @@ -0,0 +1,20 @@ +class AddToolIdToExternalTools < ActiveRecord::Migration + tag :predeploy + def self.up + # using tool_id instead of developer_key.id lets us + # use the same keys as lti-examples.heroku.com for + # tying multiple context_external_tools to the + # same third-party tool + add_column :context_external_tools, :tool_id, :string + add_index :context_external_tools, [:tool_id] + add_column :developer_keys, :tool_id, :string + add_index :developer_keys, [:tool_id], :unique => true + end + + def self.down + remove_column :context_external_tools, :tool_id + remove_index :context_external_tools, [:tool_id] + remove_column :developer_keys, :tool_id + remove_index :developer_keys, [:tool_id] + end +end diff --git a/lib/cc/basic_lti_links.rb b/lib/cc/basic_lti_links.rb index e7e8ba9cbb3..26d8bf5920c 100644 --- a/lib/cc/basic_lti_links.rb +++ b/lib/cc/basic_lti_links.rb @@ -61,6 +61,7 @@ module CC elsif tool.url =~ %r{https://} blti_node.blti :secure_launch_url, tool.url end + blti_node.blti(:icon, tool.settings[:icon_url]) if tool.settings[:icon_url] blti_node.blti :vendor do |v_node| v_node.lticp :code, 'unknown' v_node.lticp :name, 'unknown' @@ -75,6 +76,7 @@ module CC end blti_node.blti(:extensions, :platform => CC::CCHelper::CANVAS_PLATFORM) do |ext_node| + ext_node.lticm(:property, tool.tool_id, 'name' => 'tool_id') if tool.tool_id ext_node.lticm :property, tool.workflow_state, 'name' => 'privacy_level' ext_node.lticm(:property, tool.domain, 'name' => 'domain') unless tool.domain.blank? if for_course_copy diff --git a/lib/cc/importer/blti_converter.rb b/lib/cc/importer/blti_converter.rb index 2791232a156..e5a3a113a59 100644 --- a/lib/cc/importer/blti_converter.rb +++ b/lib/cc/importer/blti_converter.rb @@ -79,12 +79,16 @@ module CC::Importer tool[:domain] = ext[:custom_fields].delete 'domain' tool[:consumer_key] = ext[:custom_fields].delete 'consumer_key' tool[:shared_secret] = ext[:custom_fields].delete 'shared_secret' - + tool[:tool_id] = ext[:custom_fields].delete 'tool_id' tool[:settings] = ext[:custom_fields] else tool[:extensions] << ext end end + if icon = get_node_val(doc, "#{blti}|icon") + tool[:settings] ||= {} + tool[:settings][:icon_url] = icon + end tool end diff --git a/public/javascripts/tool_inline.js b/public/javascripts/tool_inline.js index 45db7878206..36256398515 100644 --- a/public/javascripts/tool_inline.js +++ b/public/javascripts/tool_inline.js @@ -15,7 +15,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -define(['jquery'], function($) { +define(['jquery', 'jquery.google-analytics'], function($) { if(!$("#tool_form").hasClass('new_tab')) { $("#content").addClass('padless'); @@ -32,6 +32,10 @@ if(!$("#tool_form").hasClass('new_tab')) { $(this).find(".load_tab,.tab_loaded").toggle(); }); } + +var toolName = $("#tool_form").attr('data-tool-id') || "unknown"; +$.trackEvent('tool_launch', toolName); + $("#tool_form:not(.new_tab)").submit().hide(); $(document).ready(function() { if($("#tool_content").length) { diff --git a/spec/lib/cc/importer/canvas_cartridge_converter_spec.rb b/spec/lib/cc/importer/canvas_cartridge_converter_spec.rb index 374baf3d799..3e3ef770107 100644 --- a/spec/lib/cc/importer/canvas_cartridge_converter_spec.rb +++ b/spec/lib/cc/importer/canvas_cartridge_converter_spec.rb @@ -146,12 +146,14 @@ describe "Canvas Cartridge importing" do tool1.privacy_level = 'name_only' tool1.consumer_key = 'haha' tool1.shared_secret = "don't share me" + tool1.tool_id = "test_tool" tool1.settings[:custom_fields] = {"key1" => "value1", "key2" => "value2"} tool1.settings[:user_navigation] = {:url => "http://www.example.com", :text => "hello", :labels => {'en' => 'hello', 'es' => 'hola'}, :extra => 'extra'} tool1.settings[:course_navigation] = {:url => "http://www.example.com", :text => "hello", :labels => {'en' => 'hello', 'es' => 'hola'}, :default => 'disabled', :visibility => 'members', :extra => 'extra'} tool1.settings[:account_navigation] = {:url => "http://www.example.com", :text => "hello", :labels => {'en' => 'hello', 'es' => 'hola'}, :extra => 'extra'} tool1.settings[:resource_selection] = {:url => "http://www.example.com", :text => "hello", :labels => {'en' => 'hello', 'es' => 'hola'}, :selection_width => 100, :selection_height => 50, :extra => 'extra'} tool1.settings[:editor_button] = {:url => "http://www.example.com", :text => "hello", :labels => {'en' => 'hello', 'es' => 'hola'}, :selection_width => 100, :selection_height => 50, :icon_url => "http://www.example.com", :extra => 'extra'} + tool1.settings[:icon_url] = "http://www.example.com/favicon.ico" tool1.save! tool2 = @copy_from.context_external_tools.new tool2.domain = 'example.com' @@ -190,6 +192,8 @@ describe "Canvas Cartridge importing" do t1.domain.should == nil t1.consumer_key.should == 'fake' t1.shared_secret.should == 'fake' + t1.tool_id.should == 'test_tool' + t1.settings[:icon_url].should == 'http://www.example.com/favicon.ico' [:user_navigation, :course_navigation, :account_navigation].each do |type| t1.settings[type][:url].should == "http://www.example.com" t1.settings[type][:text].should == "hello" @@ -228,6 +232,8 @@ describe "Canvas Cartridge importing" do t2.workflow_state.should == tool2.workflow_state t2.consumer_key.should == 'fake' t2.shared_secret.should == 'fake' + t2.tool_id.should be_nil + t2.settings[:icon_url].should be_nil t2.settings[:user_navigation].should be_nil t2.settings[:course_navigation].should be_nil t2.settings[:account_navigation].should be_nil diff --git a/spec/lib/cc/importer/common_cartridge_converter_spec.rb b/spec/lib/cc/importer/common_cartridge_converter_spec.rb index d92403f1eb9..2288e7b40be 100644 --- a/spec/lib/cc/importer/common_cartridge_converter_spec.rb +++ b/spec/lib/cc/importer/common_cartridge_converter_spec.rb @@ -126,7 +126,7 @@ describe "Standard Common Cartridge importing" do et.name.should == "BLTI Test" et.url.should == 'http://www.imsglobal.org/developers/BLTI/tool.php' et.settings[:custom_fields].should == {"key1"=>"value1", "key2"=>"value2"} - et.settings[:vendor_extensions].should == [{:platform=>"my.lms.com", :custom_fields=>{"key"=>"value"}}, {:platform=>"your.lms.com", :custom_fields=>{"key"=>"value", "key2"=>"value2"}}] + et.settings[:vendor_extensions].should == [{:platform=>"my.lms.com", :custom_fields=>{"key"=>"value"}}, {:platform=>"your.lms.com", :custom_fields=>{"key"=>"value", "key2"=>"value2"}}].map(&:with_indifferent_access) @migration.warnings.member?("The security parameters for the external tool \"#{et.name}\" need to be set in Course Settings.").should be_true end diff --git a/spec/models/context_external_tool_spec.rb b/spec/models/context_external_tool_spec.rb index 7bf81b8b1fa..922d0d73553 100644 --- a/spec/models/context_external_tool_spec.rb +++ b/spec/models/context_external_tool_spec.rb @@ -335,6 +335,21 @@ describe ContextExternalTool do tool.has_editor_button.should be_true end + it "should allow setting tool_id and icon_url" do + tool = new_external_tool + tool.tool_id = "new_tool" + tool.settings[:icon_url] = "http://www.example.com/favicon.ico" + tool.save + tool.tool_id.should == "new_tool" + tool.settings[:icon_url].should == "http://www.example.com/favicon.ico" + end + + it "should use editor button's icon_url if none is set on the tool" do + tool = new_external_tool + tool.settings = {:editor_button => {:url => "http://www.example.com", :icon_url => "http://www.example.com/favicon.ico", :selection_width => 100, :selection_height => 100}} + tool.save + tool.settings[:icon_url].should == "http://www.example.com/favicon.ico" + end end describe "standardize_url" do