Class: Rtml::Rules::TmlParamParser

Inherits:
Object
  • Object
show all
Defined in:
lib/rtml/rules/tml_param_parser.rb

Overview

TML data, when sent as an HTTP POST payload, is in XML format. This class is responsible for processing TMLPOST data into the familiar name-value pairs.

TODO: Groupe has agreed to look into implementing TML POST data as application/x-www-form-urlencoded data instead of XML, which would render this class unnecessary overhead.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data) ⇒ TmlParamParser

Returns a new instance of TmlParamParser.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/rtml/rules/tml_param_parser.rb', line 11

def initialize(data)
  tml = Hpricot.XML(data)
  tmlpost = tml.at('tmlpost')
  postvars = tml.search("//postvar")
  @params = {}.with_indifferent_access

  if tmlpost and postvars
    params[:post_id] = tmlpost['post_id'].to_i
    params[:date] = Date.parse(tmlpost['date'])
    params[:itid] = tmlpost['itid']
    params[:xmlns] = tmlpost['xmlns']
    p = {}
    postvars.each do |postvar|
      name, value = name_and_value_of postvar
      p[name] = value
    end

    # The reason this is broken into two phases is because if we don't, there's a chance we'll
    # miss a value that looks like (but isn't) a namespace. Example:
    #
    # card.pin = '3C30E0EEB1978A58' # this is actually the pin block itself
    # card.pin.smid = '00000E0001E000CB' # this is the smid
    #
    # When parsed from parmstr, card.pin.smid would normally create params[:card][:pin] = {:smid => '...'}
    # But this would overwrite card.pin = '3C30E0EEB1978A58', and we'd lose the pin block. It'd probably
    # be more correct to fix this at the TML level, but we can't expect every TML developer to figure that
    # out, and RTML can only help so much. It breaks the convention, but I think it's safer in the
    # long run to turn this into params[:card][:pin] and params[:card]['pin.smid']. Even though it
    # will doubtlessly add confusion to a developer who has to work with it, at least this confusion
    # should be rare in RTML (because RTML sorts all this info into its Transaction model and expects
    # the developer to deal with transactions through the model, and not the params themselves).
    #
    # TODO: Check with Groupe about addressing this. Obviously, 'card.pin.block' would be the preferred
    # syntax and this problem would never come up if all variables followed the same naming conventions.
    #
    # We have to sort the keys so that the shortest ones will be on top (and therefore card.pin will be
    # processed before card.pin.smid has a chance to determine that it's OK to make it a hash).
    #
    p.sort { |a,b| a[0] <=> b[0] }.each do |arr|
      name, value = arr
      sort_and_assign name, value
    end
  end
end

Instance Attribute Details

#paramsObject (readonly)

Returns the value of attribute params.



9
10
11
# File 'lib/rtml/rules/tml_param_parser.rb', line 9

def params
  @params
end