2011-03-10 00:11:22 +08:00
class ContextExternalTool < ActiveRecord :: Base
include Workflow
has_many :content_tags , :as = > :content
belongs_to :context , :polymorphic = > true
2011-11-12 04:53:48 +08:00
belongs_to :cloned_item
2011-12-21 05:17:51 +08:00
attr_accessible :privacy_level , :domain , :url , :shared_secret , :consumer_key ,
:name , :description , :custom_fields , :custom_fields_string ,
:course_navigation , :account_navigation , :user_navigation ,
2011-12-11 03:39:42 +08:00
:resource_selection , :editor_button ,
:config_type , :config_url , :config_xml
2011-03-10 00:11:22 +08:00
validates_presence_of :name
validates_presence_of :consumer_key
validates_presence_of :shared_secret
2011-12-21 05:17:51 +08:00
validate :url_or_domain_is_set
2011-09-17 07:09:59 +08:00
serialize :settings
2011-12-11 03:39:42 +08:00
attr_accessor :config_type , :config_url , :config_xml
2011-03-10 00:11:22 +08:00
before_save :infer_defaults
2012-01-18 13:32:57 +08:00
after_save :touch_context
2011-12-11 03:39:42 +08:00
validate :check_for_xml_error
2011-07-14 00:24:17 +08:00
2011-03-10 00:11:22 +08:00
workflow do
state :anonymous
state :name_only
state :public
state :deleted
end
set_policy do
given { | user , session | self . cached_context_grants_right? ( user , session , :update ) }
2011-07-14 00:24:17 +08:00
can :read and can :update and can :delete
2011-03-10 00:11:22 +08:00
end
2011-12-21 05:17:51 +08:00
def url_or_domain_is_set
if url . present? && domain . present?
errors . add ( :url , t ( 'url_or_domain_not_both' , " Either the url or domain should be set, not both. " ) )
errors . add ( :domain , t ( 'url_or_domain_not_both' , " Either the url or domain should be set, not both. " ) )
elsif url . blank? && domain . blank?
errors . add ( :url , t ( 'url_or_domain_required' , " Either the url or domain should be set. " ) )
errors . add ( :domain , t ( 'url_or_domain_required' , " Either the url or domain should be set. " ) )
end
end
2011-03-10 00:11:22 +08:00
def settings
read_attribute ( :settings ) || write_attribute ( :settings , { } )
end
basic lti navigation links
By properly configuring external tools (see
/spec/models/course_spec/rb:898 for examples) they can
be added as left-side navigation links to a course,
an account, or to the user profile section of Canvas.
testing notes:
- you have to manually set options on the external tool:
- for user navigation the tool needs to be created on the root account
with the following settings:
{:user_navigation => {:url => <url>, :text => <tab label>} }
(there are also some optional language options you can set using
the :labels attribute)
- for account navigation it's the same
- for course navigation it's the same, except with :course_navigation
there's also some additional options:
:visibility => <value> // public, members, admins
:default => <value> // disabled, enabled
test plan:
- configure a user navigation tool at the root account level,
make sure it shows up in the user's profile section
- configure a course navigation tool at the account level,
make sure it shows up in the course's navigation
- configure a course navigation tool at the course level,
make sure it shows up in the course's navigation
- make sure :default => 'disabled' course navigation tools don't
appear by default in the navigation, but can be enabled on
the course settings page
- make sure :visibility => 'members' only shows up for course members
- make sure :visibility => 'admins' only shows up for course admins
- configure an account navigation tool at the account level,
make sure it shows up in the account's navigation, and
any sub-account's navigation
Change-Id: I977da3c6b89a9e32b4cff4c2b6b221f8162782ff
Reviewed-on: https://gerrit.instructure.com/5427
Reviewed-by: Brian Whitmer <brian@instructure.com>
Tested-by: Hudson <hudson@instructure.com>
2011-08-18 13:49:01 +08:00
def label_for ( key , lang = nil )
labels = settings [ key ] && settings [ key ] [ :labels ]
2011-12-11 03:39:42 +08:00
( labels && labels [ lang ] ) ||
( labels && lang && labels [ lang . split ( '-' ) . first ] ) ||
( settings [ key ] && settings [ key ] [ :text ] ) ||
settings [ :text ] || name || " External Tool "
basic lti navigation links
By properly configuring external tools (see
/spec/models/course_spec/rb:898 for examples) they can
be added as left-side navigation links to a course,
an account, or to the user profile section of Canvas.
testing notes:
- you have to manually set options on the external tool:
- for user navigation the tool needs to be created on the root account
with the following settings:
{:user_navigation => {:url => <url>, :text => <tab label>} }
(there are also some optional language options you can set using
the :labels attribute)
- for account navigation it's the same
- for course navigation it's the same, except with :course_navigation
there's also some additional options:
:visibility => <value> // public, members, admins
:default => <value> // disabled, enabled
test plan:
- configure a user navigation tool at the root account level,
make sure it shows up in the user's profile section
- configure a course navigation tool at the account level,
make sure it shows up in the course's navigation
- configure a course navigation tool at the course level,
make sure it shows up in the course's navigation
- make sure :default => 'disabled' course navigation tools don't
appear by default in the navigation, but can be enabled on
the course settings page
- make sure :visibility => 'members' only shows up for course members
- make sure :visibility => 'admins' only shows up for course admins
- configure an account navigation tool at the account level,
make sure it shows up in the account's navigation, and
any sub-account's navigation
Change-Id: I977da3c6b89a9e32b4cff4c2b6b221f8162782ff
Reviewed-on: https://gerrit.instructure.com/5427
Reviewed-by: Brian Whitmer <brian@instructure.com>
Tested-by: Hudson <hudson@instructure.com>
2011-08-18 13:49:01 +08:00
end
2011-12-11 03:39:42 +08:00
def xml_error ( error )
@xml_error = error
end
def check_for_xml_error
if @xml_error
errors . add_to_base ( @xml_error )
false
end
end
protected :check_for_xml_error
2011-03-10 00:11:22 +08:00
def readable_state
workflow_state . titleize
end
def privacy_level = ( val )
if [ 'anonymous' , 'name_only' , 'public' ] . include? ( val )
self . workflow_state = val
end
end
2011-12-21 05:17:51 +08:00
def privacy_level
self . workflow_state
end
2011-09-11 05:34:42 +08:00
def custom_fields_string
( settings [ :custom_fields ] || { } ) . map { | key , val |
" #{ key } = #{ val } "
} . join ( " \n " )
end
2011-12-11 03:39:42 +08:00
def config_type = ( val )
@config_type = val
process_extended_configuration
end
def config_xml = ( val )
@config_xml = val
process_extended_configuration
end
def config_url = ( val )
@config_url = val
process_extended_configuration
end
def process_extended_configuration
return unless ( config_type == 'by_url' && config_url ) || ( config_type == 'by_xml' && config_xml )
tool_hash = nil
begin
converter = CC :: Importer :: Canvas :: Converter . new ( { :no_archive_file = > true } )
if config_type == 'by_url'
tool_hash = converter . retrieve_and_convert_blti_url ( config_url )
else
tool_hash = converter . convert_blti_xml ( config_xml )
end
rescue CC :: Importer :: BLTIConverter :: CCImportError = > e
tool_hash = { :error = > e . message }
end
real_name = self . name
if tool_hash [ :error ]
xml_error ( tool_hash [ :error ] )
else
ContextExternalTool . import_from_migration ( tool_hash , self . context , self )
end
self . name = real_name unless real_name . blank?
end
2011-09-11 05:34:42 +08:00
def custom_fields_string = ( str )
hash = { }
str . split ( / \ n / ) . each do | line |
key , val = line . split ( / = / )
hash [ key ] = val if key . present? && val . present?
2011-03-10 00:11:22 +08:00
end
2011-09-11 05:34:42 +08:00
settings [ :custom_fields ] = hash
end
def custom_fields = ( hash )
settings [ :custom_fields ] = hash if hash . is_a? ( Hash )
2011-03-10 00:11:22 +08:00
end
2011-12-21 05:17:51 +08:00
def custom_fields
settings [ :custom_fields ]
end
def course_navigation = ( hash )
tool_setting ( :course_navigation , hash ) { | nav_settings |
if hash [ :visibility ] == 'members' || hash [ :visibility ] == 'admins'
nav_settings [ :visibility ] = hash [ :visibility ]
end
nav_settings [ :default ] = ! ! hash [ :default ]
}
end
def account_navigation = ( hash )
tool_setting ( :account_navigation , hash )
end
def account_navigation
settings [ :account_navigation ]
end
def user_navigation = ( hash )
tool_setting ( :user_navigation , hash )
end
def user_navigation
settings [ :user_navigation ]
end
def resource_selection = ( hash )
tool_setting ( :resource_selection , hash , :selection_width , :selection_height )
end
def resource_selection
settings [ :resource_selection ]
end
def editor_button = ( hash )
tool_setting ( :editor_button , hash , :selection_width , :selection_height , :icon_url )
end
def editor_button
settings [ :editor_button ]
end
2011-03-10 00:11:22 +08:00
def shared_secret = ( val )
write_attribute ( :shared_secret , val ) unless val . blank?
end
def infer_defaults
basic lti navigation links
By properly configuring external tools (see
/spec/models/course_spec/rb:898 for examples) they can
be added as left-side navigation links to a course,
an account, or to the user profile section of Canvas.
testing notes:
- you have to manually set options on the external tool:
- for user navigation the tool needs to be created on the root account
with the following settings:
{:user_navigation => {:url => <url>, :text => <tab label>} }
(there are also some optional language options you can set using
the :labels attribute)
- for account navigation it's the same
- for course navigation it's the same, except with :course_navigation
there's also some additional options:
:visibility => <value> // public, members, admins
:default => <value> // disabled, enabled
test plan:
- configure a user navigation tool at the root account level,
make sure it shows up in the user's profile section
- configure a course navigation tool at the account level,
make sure it shows up in the course's navigation
- configure a course navigation tool at the course level,
make sure it shows up in the course's navigation
- make sure :default => 'disabled' course navigation tools don't
appear by default in the navigation, but can be enabled on
the course settings page
- make sure :visibility => 'members' only shows up for course members
- make sure :visibility => 'admins' only shows up for course admins
- configure an account navigation tool at the account level,
make sure it shows up in the account's navigation, and
any sub-account's navigation
Change-Id: I977da3c6b89a9e32b4cff4c2b6b221f8162782ff
Reviewed-on: https://gerrit.instructure.com/5427
Reviewed-by: Brian Whitmer <brian@instructure.com>
Tested-by: Hudson <hudson@instructure.com>
2011-08-18 13:49:01 +08:00
self . url = nil if url . blank?
self . domain = nil if domain . blank?
2011-10-25 04:30:48 +08:00
settings . delete ( :user_navigation ) if settings [ :user_navigation ] && ( ! settings [ :user_navigation ] [ :url ] )
settings . delete ( :course_navigation ) if settings [ :course_navigation ] && ( ! settings [ :course_navigation ] [ :url ] )
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 ] )
[ :resource_selection , :editor_button ] . each do | type |
if settings [ type ]
settings [ type ] [ :selection_width ] = settings [ type ] [ :selection_width ] . to_i
settings [ type ] [ :selection_height ] = settings [ type ] [ :selection_height ] . to_i
end
end
basic lti navigation links
By properly configuring external tools (see
/spec/models/course_spec/rb:898 for examples) they can
be added as left-side navigation links to a course,
an account, or to the user profile section of Canvas.
testing notes:
- you have to manually set options on the external tool:
- for user navigation the tool needs to be created on the root account
with the following settings:
{:user_navigation => {:url => <url>, :text => <tab label>} }
(there are also some optional language options you can set using
the :labels attribute)
- for account navigation it's the same
- for course navigation it's the same, except with :course_navigation
there's also some additional options:
:visibility => <value> // public, members, admins
:default => <value> // disabled, enabled
test plan:
- configure a user navigation tool at the root account level,
make sure it shows up in the user's profile section
- configure a course navigation tool at the account level,
make sure it shows up in the course's navigation
- configure a course navigation tool at the course level,
make sure it shows up in the course's navigation
- make sure :default => 'disabled' course navigation tools don't
appear by default in the navigation, but can be enabled on
the course settings page
- make sure :visibility => 'members' only shows up for course members
- make sure :visibility => 'admins' only shows up for course admins
- configure an account navigation tool at the account level,
make sure it shows up in the account's navigation, and
any sub-account's navigation
Change-Id: I977da3c6b89a9e32b4cff4c2b6b221f8162782ff
Reviewed-on: https://gerrit.instructure.com/5427
Reviewed-by: Brian Whitmer <brian@instructure.com>
Tested-by: Hudson <hudson@instructure.com>
2011-08-18 13:49:01 +08:00
self . has_user_navigation = ! ! settings [ :user_navigation ]
self . has_course_navigation = ! ! settings [ :course_navigation ]
self . has_account_navigation = ! ! settings [ :account_navigation ]
self . has_resource_selection = ! ! settings [ :resource_selection ]
self . has_editor_button = ! ! settings [ :editor_button ]
true
2011-03-10 00:11:22 +08:00
end
def self . standardize_url ( url )
return " " if url . empty?
url = " http:// " + url unless url . match ( / : \/ \/ / )
res = URI . parse ( url ) . normalize
res . query = res . query . split ( / & / ) . sort . join ( '&' ) if ! res . query . blank?
res . to_s
end
alias_method :destroy! , :destroy
def destroy
self . workflow_state = 'deleted'
save!
end
def include_email?
public ?
end
def include_name?
name_only? || public ?
end
def precedence
if domain
# Somebody tell me if we should be expecting more than
# 25 dots in a url host...
25 - domain . split ( / \ . / ) . length
elsif url
25
else
26
end
end
def matches_url? ( url )
if ! defined? ( @standard_url )
@standard_url = ! self . url . blank? && ContextExternalTool . standardize_url ( self . url )
end
return true if url == @standard_url
host = URI . parse ( url ) . host rescue nil
! ! ( host && ( '.' + host ) . match ( / \ . #{ domain } \ z / ) )
end
def self . all_tools_for ( context )
contexts = [ ]
tools = [ ]
while context
if context . is_a? ( Group )
contexts << context
context = context . context || context . account
elsif context . is_a? ( Course )
contexts << context
context = context . account
elsif context . is_a? ( Account )
contexts << context
context = context . parent_account
else
context = nil
end
end
return nil if contexts . empty?
contexts . each do | context |
tools += context . context_external_tools . active
end
tools . sort_by ( & :name )
end
# Order of precedence: Basic LTI defines precedence as first
# checking for a match on domain. Subdomains count as a match
# on less-specific domains, but the most-specific domain will
# match first. So awesome.bob.example.com matches an
# external_tool with example.com as the domain, but only if
# there isn't another external_tool where awesome.bob.example.com
# or bob.example.com is set as the domain.
#
# If there is no domain match then check for an exact url match
# as configured by an admin. If there is still no match
# then check for a match on the current context (configured by
# the teacher).
2012-02-26 14:01:42 +08:00
def self . find_external_tool ( url , context , preferred_tool_id = nil )
2011-03-10 00:11:22 +08:00
url = ContextExternalTool . standardize_url ( url )
2012-04-07 09:22:00 +08:00
contexts = [ ]
2011-03-10 00:11:22 +08:00
while context
if context . is_a? ( Group )
2012-04-07 09:22:00 +08:00
contexts << context
2011-03-10 00:11:22 +08:00
context = context . context || context . account
elsif context . is_a? ( Course )
2012-04-07 09:22:00 +08:00
contexts << context
2011-03-10 00:11:22 +08:00
context = context . account
elsif context . is_a? ( Account )
2012-04-07 09:22:00 +08:00
contexts << context
2011-03-10 00:11:22 +08:00
context = context . parent_account
else
context = nil
end
end
2012-04-07 09:22:00 +08:00
return nil if contexts . empty?
contexts . each do | context |
res = context . context_external_tools . active . sort_by { | t | [ t . precedence , t . id == preferred_tool_id ? 0 : 1 ] } . detect { | tool | tool . url && tool . matches_url? ( url ) }
2011-03-10 00:11:22 +08:00
return res if res
end
2012-04-07 09:22:00 +08:00
contexts . each do | context |
res = context . context_external_tools . active . sort_by { | t | [ t . precedence , t . id == preferred_tool_id ? 0 : 1 ] } . detect { | tool | tool . domain && tool . matches_url? ( url ) }
2011-03-10 00:11:22 +08:00
return res if res
end
nil
end
basic lti navigation links
By properly configuring external tools (see
/spec/models/course_spec/rb:898 for examples) they can
be added as left-side navigation links to a course,
an account, or to the user profile section of Canvas.
testing notes:
- you have to manually set options on the external tool:
- for user navigation the tool needs to be created on the root account
with the following settings:
{:user_navigation => {:url => <url>, :text => <tab label>} }
(there are also some optional language options you can set using
the :labels attribute)
- for account navigation it's the same
- for course navigation it's the same, except with :course_navigation
there's also some additional options:
:visibility => <value> // public, members, admins
:default => <value> // disabled, enabled
test plan:
- configure a user navigation tool at the root account level,
make sure it shows up in the user's profile section
- configure a course navigation tool at the account level,
make sure it shows up in the course's navigation
- configure a course navigation tool at the course level,
make sure it shows up in the course's navigation
- make sure :default => 'disabled' course navigation tools don't
appear by default in the navigation, but can be enabled on
the course settings page
- make sure :visibility => 'members' only shows up for course members
- make sure :visibility => 'admins' only shows up for course admins
- configure an account navigation tool at the account level,
make sure it shows up in the account's navigation, and
any sub-account's navigation
Change-Id: I977da3c6b89a9e32b4cff4c2b6b221f8162782ff
Reviewed-on: https://gerrit.instructure.com/5427
Reviewed-by: Brian Whitmer <brian@instructure.com>
Tested-by: Hudson <hudson@instructure.com>
2011-08-18 13:49:01 +08:00
named_scope :having_setting , lambda { | setting |
{ :conditions = > { " has_ #{ setting . to_s } " = > true } }
}
def self . find_for ( id , context , type )
tool = context . context_external_tools . having_setting ( type ) . find_by_id ( id )
if ! tool && context . is_a? ( Group )
context = context . context
tool = context . context_external_tools . having_setting ( type ) . find_by_id ( id )
end
if ! tool
account_ids = context . account_chain_ids
tool = ContextExternalTool . having_setting ( type ) . find_by_context_type_and_context_id_and_id ( 'Account' , account_ids , id )
end
raise ActiveRecord :: RecordNotFound if ! tool
tool
end
2011-03-10 00:11:22 +08:00
named_scope :active , :conditions = > [ 'context_external_tools.workflow_state != ?' , 'deleted' ]
basic lti navigation links
By properly configuring external tools (see
/spec/models/course_spec/rb:898 for examples) they can
be added as left-side navigation links to a course,
an account, or to the user profile section of Canvas.
testing notes:
- you have to manually set options on the external tool:
- for user navigation the tool needs to be created on the root account
with the following settings:
{:user_navigation => {:url => <url>, :text => <tab label>} }
(there are also some optional language options you can set using
the :labels attribute)
- for account navigation it's the same
- for course navigation it's the same, except with :course_navigation
there's also some additional options:
:visibility => <value> // public, members, admins
:default => <value> // disabled, enabled
test plan:
- configure a user navigation tool at the root account level,
make sure it shows up in the user's profile section
- configure a course navigation tool at the account level,
make sure it shows up in the course's navigation
- configure a course navigation tool at the course level,
make sure it shows up in the course's navigation
- make sure :default => 'disabled' course navigation tools don't
appear by default in the navigation, but can be enabled on
the course settings page
- make sure :visibility => 'members' only shows up for course members
- make sure :visibility => 'admins' only shows up for course admins
- configure an account navigation tool at the account level,
make sure it shows up in the account's navigation, and
any sub-account's navigation
Change-Id: I977da3c6b89a9e32b4cff4c2b6b221f8162782ff
Reviewed-on: https://gerrit.instructure.com/5427
Reviewed-by: Brian Whitmer <brian@instructure.com>
Tested-by: Hudson <hudson@instructure.com>
2011-08-18 13:49:01 +08:00
def self . find_all_for ( context , type )
tools = [ ]
if ! context . is_a? ( Account ) && context . respond_to? ( :context_external_tools )
tools += context . context_external_tools . having_setting ( type . to_s )
end
account_ids = context . account_chain_ids
tools += ContextExternalTool . having_setting ( type . to_s ) . find_all_by_context_type_and_context_id ( 'Account' , account_ids )
end
2011-03-10 00:11:22 +08:00
def self . serialization_excludes ; [ :shared_secret , :settings ] ; end
2011-04-12 21:41:47 +08:00
def self . process_migration ( data , migration )
tools = data [ 'external_tools' ] ? data [ 'external_tools' ] : [ ]
tools . each do | tool |
2012-04-03 06:38:05 +08:00
if migration . import_object? ( " external_tools " , tool [ 'migration_id' ] )
2011-09-17 07:09:59 +08:00
item = import_from_migration ( tool , migration . context )
2012-03-28 22:52:21 +08:00
if item . consumer_key == 'fake' || item . shared_secret == 'fake'
migration . add_warning ( t ( 'external_tool_attention_needed' , 'The security parameters for the external tool "%{tool_name}" need to be set in Course Settings.' , :tool_name = > item . name ) )
end
2011-04-12 21:41:47 +08:00
end
end
end
basic lti navigation links
By properly configuring external tools (see
/spec/models/course_spec/rb:898 for examples) they can
be added as left-side navigation links to a course,
an account, or to the user profile section of Canvas.
testing notes:
- you have to manually set options on the external tool:
- for user navigation the tool needs to be created on the root account
with the following settings:
{:user_navigation => {:url => <url>, :text => <tab label>} }
(there are also some optional language options you can set using
the :labels attribute)
- for account navigation it's the same
- for course navigation it's the same, except with :course_navigation
there's also some additional options:
:visibility => <value> // public, members, admins
:default => <value> // disabled, enabled
test plan:
- configure a user navigation tool at the root account level,
make sure it shows up in the user's profile section
- configure a course navigation tool at the account level,
make sure it shows up in the course's navigation
- configure a course navigation tool at the course level,
make sure it shows up in the course's navigation
- make sure :default => 'disabled' course navigation tools don't
appear by default in the navigation, but can be enabled on
the course settings page
- make sure :visibility => 'members' only shows up for course members
- make sure :visibility => 'admins' only shows up for course admins
- configure an account navigation tool at the account level,
make sure it shows up in the account's navigation, and
any sub-account's navigation
Change-Id: I977da3c6b89a9e32b4cff4c2b6b221f8162782ff
Reviewed-on: https://gerrit.instructure.com/5427
Reviewed-by: Brian Whitmer <brian@instructure.com>
Tested-by: Hudson <hudson@instructure.com>
2011-08-18 13:49:01 +08:00
def set_custom_fields ( hash , resource_type )
fields = resource_type ? settings [ resource_type . to_sym ] [ :custom_fields ] : settings [ :custom_fields ]
2011-09-08 13:20:55 +08:00
( fields || { } ) . each do | key , val |
key = key . gsub ( / [^ \ w] / , '_' ) . downcase
if key . match ( / ^custom_ / )
hash [ key ] = val
else
hash [ " custom_ #{ key } " ] = val
end
end
end
2011-11-12 04:53:48 +08:00
def clone_for ( context , dup = nil , options = { } )
if ! self . cloned_item && ! self . new_record?
self . cloned_item = ClonedItem . create ( :original_item = > self )
self . save!
end
existing = ContextExternalTool . active . find_by_context_type_and_context_id_and_id ( context . class . to_s , context . id , self . id )
existing || = ContextExternalTool . active . find_by_context_type_and_context_id_and_cloned_item_id ( context . class . to_s , context . id , self . cloned_item_id )
return existing if existing && ! options [ :overwrite ]
new_tool = existing
new_tool || = ContextExternalTool . new
new_tool . context = context
new_tool . settings = self . settings . clone
[ :name , :shared_secret , :url , :domain , :consumer_key , :workflow_state , :description ] . each do | att |
new_tool . write_attribute ( att , self . read_attribute ( att ) )
end
new_tool . cloned_item_id = self . cloned_item_id
new_tool
end
2011-10-15 12:33:13 +08:00
def resource_selection_settings
settings [ :resource_selection ]
end
2011-11-12 04:53:48 +08:00
2011-04-12 21:41:47 +08:00
def self . import_from_migration ( hash , context , item = nil )
hash = hash . with_indifferent_access
return nil if hash [ :migration_id ] && hash [ :external_tools_to_import ] && ! hash [ :external_tools_to_import ] [ hash [ :migration_id ] ]
item || = find_by_context_id_and_context_type_and_migration_id ( context . id , context . class . to_s , hash [ :migration_id ] ) if hash [ :migration_id ]
item || = context . context_external_tools . new
item . migration_id = hash [ :migration_id ]
item . name = hash [ :title ]
item . description = hash [ :description ]
item . url = hash [ :url ] unless hash [ :url ] . blank?
item . domain = hash [ :domain ] unless hash [ :domain ] . blank?
2011-09-17 07:09:59 +08:00
item . privacy_level = hash [ :privacy_level ] || 'name_only'
2012-03-28 22:52:21 +08:00
item . consumer_key || = hash [ :consumer_key ] || 'fake'
item . shared_secret || = hash [ :shared_secret ] || 'fake'
2011-10-25 04:30:48 +08:00
item . settings = hash [ :settings ] . with_indifferent_access if hash [ :settings ] . is_a? ( Hash )
2011-09-17 07:09:59 +08:00
if hash [ :custom_fields ] . is_a? Hash
item . settings [ :custom_fields ] || = { }
item . settings [ :custom_fields ] . merge! hash [ :custom_fields ]
end
if hash [ :extensions ] . is_a? Array
item . settings [ :vendor_extensions ] || = [ ]
hash [ :extensions ] . each do | ext |
next unless ext [ :custom_fields ] . is_a? Hash
if existing = item . settings [ :vendor_extensions ] . find { | ve | ve [ :platform ] == ext [ :platform ] }
existing [ :custom_fields ] || = { }
existing [ :custom_fields ] . merge! ext [ :custom_fields ]
else
item . settings [ :vendor_extensions ] << { :platform = > ext [ :platform ] , :custom_fields = > ext [ :custom_fields ] }
end
end
end
2011-04-12 21:41:47 +08:00
item . save!
2012-01-13 13:34:34 +08:00
context . imported_migration_items << item if context . respond_to? ( :imported_migration_items ) && context . imported_migration_items && item . new_record?
2011-04-12 21:41:47 +08:00
item
end
2011-12-21 05:17:51 +08:00
private
def tool_setting ( setting , hash , * keys )
if ! hash || ! hash . is_a? ( Hash )
settings . delete setting
return
else
settings [ setting ] = { }
end
settings [ setting ] [ :url ] = hash [ :url ]
settings [ setting ] [ :text ] = hash [ :text ] if hash [ :text ]
keys . each { | key | settings [ setting ] [ key ] = hash [ key ] }
# if the type needs to do some validations for specific keys
yield settings [ setting ] if block_given?
settings [ setting ]
end
2011-04-12 21:41:47 +08:00
2011-03-10 00:11:22 +08:00
end