Module: PandaPal::LaunchUrlHelpers

Defined in:
app/lib/panda_pal/launch_url_helpers.rb

Class Method Summary collapse

Class Method Details

.absolute_launch_url(launch_type, host: uri_host, launch_handler: nil, default_auto_launch: false) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'app/lib/panda_pal/launch_url_helpers.rb', line 3

def self.absolute_launch_url(launch_type, host: uri_host, launch_handler: nil, default_auto_launch: false)
  opts = PandaPal.lti_paths[launch_type]

  if launch_handler.nil? && opts.present?
    launch_handler = opts[:message_type] == PandaPal::LtiConstants::MessageTypes::DEEP_LINKING_REQUEST ?
                    :v1p3_deep_link_request_path :
                    :v1p3_resource_link_request_path
  end

  auto_launch = opts[:auto_launch] != nil ? opts[:auto_launch] : default_auto_launch
  auto_launch = auto_launch && launch_handler.present?

  if auto_launch
    launch_handler = resolve_route(launch_handler) if launch_handler.is_a?(Symbol)
    return add_url_params([host.to_s, launch_handler].join, {
      launch_type: launch_type,
    })
  else
    final_url = launch_url(opts, launch_type: launch_type)
    return final_url if URI.parse(final_url).absolute?
    return [host.to_s, final_url].join
  end
end

.add_url_params(url, params) ⇒ Object



72
73
74
75
76
77
78
79
80
# File 'app/lib/panda_pal/launch_url_helpers.rb', line 72

def self.add_url_params(url, params)
  uri = URI(url)
  decoded_params = URI.decode_www_form(uri.query || "")
  params.each do |k, v|
    decoded_params << [k, v]
  end
  uri.query = URI.encode_www_form(decoded_params)
  uri.to_s
end


111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'app/lib/panda_pal/launch_url_helpers.rb', line 111

def self.deep_link_redirect_url(request)
  # Try placement-specific configuration first
  launch_type = request.query_parameters['launch_type']&.to_sym
  return global_configuration_url unless launch_type

  placement_config = PandaPal.lti_paths[launch_type]
  return global_configuration_url unless deep_linking_placement?(placement_config)

  # Check for explicit deep_link_redirect_url configuration
  redirect_url = placement_config[:deep_link_redirect_url]
  return normalize_redirect_url(redirect_url) if redirect_url.present?

  # Fall back to global configuration
  global_configuration_url
end

.deep_linking_placement?(placement_config) ⇒ Boolean

Returns:

  • (Boolean)


132
133
134
# File 'app/lib/panda_pal/launch_url_helpers.rb', line 132

def self.deep_linking_placement?(placement_config)
  placement_config&.dig(:message_type) == PandaPal::LtiConstants::MessageTypes::DEEP_LINKING_REQUEST
end

.global_configuration_urlObject



127
128
129
130
# File 'app/lib/panda_pal/launch_url_helpers.rb', line 127

def self.global_configuration_url
  redirect_url = PandaPal.lti_options[:deep_link_redirect_url]
  normalize_redirect_url(redirect_url) if redirect_url.present?
end

.launch_route(opts, launch_type: nil) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'app/lib/panda_pal/launch_url_helpers.rb', line 52

def self.launch_route(opts, launch_type: nil)
  if opts.is_a?(Symbol) || opts.is_a?(String)
    launch_type = opts.to_sym
    opts = PandaPal.lti_paths[launch_type] || {}
  end

  if opts[:route_helper_key]
    opts[:route_helper_key].to_sym
  else
    opts[:url] ||= launch_type
    opts[:url]
  end
end

.launch_url(opts, launch_type: nil) ⇒ Object



46
47
48
49
50
# File 'app/lib/panda_pal/launch_url_helpers.rb', line 46

def self.launch_url(opts, launch_type: nil)
  url = launch_route(opts, launch_type: launch_type)
  url = resolve_url_symbol(url) if url.is_a?(Symbol)
  url
end

.normalize_lti_launch_desc(opts) ⇒ Object



36
37
38
39
40
41
42
43
44
# File 'app/lib/panda_pal/launch_url_helpers.rb', line 36

def self.normalize_lti_launch_desc(opts)
  opts = opts.dup
  opts.delete(:route_helper_key)
  opts.delete(:auto_launch)
  opts.each do |k, v|
    opts[k] = v.call if v.is_a?(Proc)
  end
  opts
end

.normalize_redirect_url(url) ⇒ Object



136
137
138
139
# File 'app/lib/panda_pal/launch_url_helpers.rb', line 136

def self.normalize_redirect_url(url)
  return nil unless url.present?
  url.is_a?(Symbol) ? url : url.to_sym
end

.resolve_route(key, *arguments, engine: 'PandaPal', **kwargs) ⇒ Object



100
101
102
103
104
105
106
107
108
109
# File 'app/lib/panda_pal/launch_url_helpers.rb', line 100

def self.resolve_route(key, *arguments, engine: 'PandaPal', **kwargs)
  return key if key.is_a?(String)

  key_bits = key.to_s.split('/')
  key_bits.prepend(engine) if key_bits.count == 1
  key_bits[0] = key_bits[0].classify

  engine = key_bits[0] == 'MainApp' ? Rails.application : (key_bits[0].constantize)::Engine
  engine.routes.url_helpers.send(key_bits[1], *arguments, **kwargs)
end

.resolve_url_symbol(sym, **opts) ⇒ Object



66
67
68
69
70
# File 'app/lib/panda_pal/launch_url_helpers.rb', line 66

def self.resolve_url_symbol(sym, **opts)
  sym = :"#{sym}_url" unless sym.to_s.ends_with?('_url')
  opts[:only_path] = true unless opts.key?(:only_path)
  resolve_route(:"MainApp/#{sym}", **opts)
end

.uri_hostObject



95
96
97
98
# File 'app/lib/panda_pal/launch_url_helpers.rb', line 95

def self.uri_host
  request = Thread.current[:controller]&.request
  Thread.current[:panda_pal_access_uri]&.to_s || "#{request.scheme}://#{request.host_with_port}"
end

.url_for(options) ⇒ Object



27
28
29
30
31
32
33
34
# File 'app/lib/panda_pal/launch_url_helpers.rb', line 27

def self.url_for(options)
  if options.is_a?(Symbol)
    Rails.application.routes.url_helpers.send(options, host: uri_host)
  else
    options[:host] ||= uri_host
    Rails.application.routes.url_helpers.url_for(options)
  end
end

.with_uri_host(uri) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
# File 'app/lib/panda_pal/launch_url_helpers.rb', line 82

def self.with_uri_host(uri)
  uri = URI.parse(uri) unless uri.is_a?(URI)
  raise "host: param must have a protocal and no path" if uri.path.present?

  initial = Thread.current[:panda_pal_access_uri]
  begin
    Thread.current[:panda_pal_access_uri] = uri
    yield
  ensure
    Thread.current[:panda_pal_access_uri] = initial
  end
end