KayakoClient 0.0.1b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/kayako_client.rb +36 -0
- data/lib/kayako_client/base.rb +98 -0
- data/lib/kayako_client/department.rb +31 -0
- data/lib/kayako_client/http/http.rb +217 -0
- data/lib/kayako_client/http/http_backend.rb +31 -0
- data/lib/kayako_client/http/http_client.rb +87 -0
- data/lib/kayako_client/http/http_response.rb +61 -0
- data/lib/kayako_client/http/net_http.rb +109 -0
- data/lib/kayako_client/mixins/api.rb +299 -0
- data/lib/kayako_client/mixins/attachment.rb +69 -0
- data/lib/kayako_client/mixins/authentication.rb +34 -0
- data/lib/kayako_client/mixins/client.rb +308 -0
- data/lib/kayako_client/mixins/logger.rb +29 -0
- data/lib/kayako_client/mixins/object.rb +456 -0
- data/lib/kayako_client/mixins/post_client.rb +42 -0
- data/lib/kayako_client/mixins/staff_visibility_api.rb +9 -0
- data/lib/kayako_client/mixins/ticket_api.rb +55 -0
- data/lib/kayako_client/mixins/ticket_client.rb +135 -0
- data/lib/kayako_client/mixins/user_visibility_api.rb +9 -0
- data/lib/kayako_client/staff.rb +25 -0
- data/lib/kayako_client/staff_group.rb +9 -0
- data/lib/kayako_client/ticket.rb +241 -0
- data/lib/kayako_client/ticket_attachment.rb +42 -0
- data/lib/kayako_client/ticket_count.rb +135 -0
- data/lib/kayako_client/ticket_custom_field.rb +110 -0
- data/lib/kayako_client/ticket_note.rb +105 -0
- data/lib/kayako_client/ticket_post.rb +61 -0
- data/lib/kayako_client/ticket_priority.rb +24 -0
- data/lib/kayako_client/ticket_status.rb +31 -0
- data/lib/kayako_client/ticket_time_track.rb +27 -0
- data/lib/kayako_client/ticket_type.rb +26 -0
- data/lib/kayako_client/user.rb +61 -0
- data/lib/kayako_client/user_group.rb +12 -0
- data/lib/kayako_client/user_organization.rb +23 -0
- data/lib/kayako_client/xml/lib_xml.rb +86 -0
- data/lib/kayako_client/xml/rexml_document.rb +77 -0
- data/lib/kayako_client/xml/xml.rb +63 -0
- data/lib/kayako_client/xml/xml_backend.rb +42 -0
- metadata +105 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'kayako_client/http/http_response'
|
2
|
+
require 'kayako_client/http/http_backend'
|
3
|
+
require 'kayako_client/http/http'
|
4
|
+
|
5
|
+
require 'kayako_client/xml/xml_backend'
|
6
|
+
require 'kayako_client/xml/xml'
|
7
|
+
|
8
|
+
require 'kayako_client/mixins/api'
|
9
|
+
require 'kayako_client/mixins/object'
|
10
|
+
require 'kayako_client/mixins/client'
|
11
|
+
require 'kayako_client/mixins/ticket_client'
|
12
|
+
require 'kayako_client/mixins/post_client'
|
13
|
+
require 'kayako_client/mixins/logger'
|
14
|
+
require 'kayako_client/mixins/authentication'
|
15
|
+
require 'kayako_client/mixins/attachment'
|
16
|
+
require 'kayako_client/mixins/ticket_api'
|
17
|
+
require 'kayako_client/mixins/user_visibility_api'
|
18
|
+
require 'kayako_client/mixins/staff_visibility_api'
|
19
|
+
|
20
|
+
require 'kayako_client/base'
|
21
|
+
require 'kayako_client/department'
|
22
|
+
require 'kayako_client/staff'
|
23
|
+
require 'kayako_client/staff_group'
|
24
|
+
require 'kayako_client/ticket'
|
25
|
+
require 'kayako_client/ticket_attachment'
|
26
|
+
require 'kayako_client/ticket_custom_field'
|
27
|
+
require 'kayako_client/ticket_note'
|
28
|
+
require 'kayako_client/ticket_post'
|
29
|
+
require 'kayako_client/ticket_priority'
|
30
|
+
require 'kayako_client/ticket_status'
|
31
|
+
require 'kayako_client/ticket_time_track'
|
32
|
+
require 'kayako_client/ticket_type'
|
33
|
+
require 'kayako_client/ticket_count'
|
34
|
+
require 'kayako_client/user'
|
35
|
+
require 'kayako_client/user_group'
|
36
|
+
require 'kayako_client/user_organization'
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module KayakoClient
|
2
|
+
|
3
|
+
class Base
|
4
|
+
include KayakoClient::API
|
5
|
+
include KayakoClient::Logger
|
6
|
+
include KayakoClient::Object
|
7
|
+
include KayakoClient::Authentication
|
8
|
+
include KayakoClient::HTTP
|
9
|
+
include KayakoClient::XML
|
10
|
+
|
11
|
+
def initialize(*args)
|
12
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
13
|
+
|
14
|
+
if args[0]
|
15
|
+
@api_url = args[0]
|
16
|
+
elsif options.has_key?(:api_url)
|
17
|
+
@api_url = options.delete(:api_url)
|
18
|
+
else
|
19
|
+
@api_url = Base.api_url
|
20
|
+
end
|
21
|
+
|
22
|
+
if args[1]
|
23
|
+
@api_key = args[1]
|
24
|
+
elsif options.has_key?(:api_key)
|
25
|
+
@api_key = options.delete(:api_key)
|
26
|
+
else
|
27
|
+
@api_key = Base.api_key
|
28
|
+
end
|
29
|
+
|
30
|
+
if args[2]
|
31
|
+
@secret_key = args[2]
|
32
|
+
elsif options.has_key?(:secret_key)
|
33
|
+
@secret_key = options.delete(:secret_key)
|
34
|
+
else
|
35
|
+
@secret_key = Base.secret_key
|
36
|
+
end
|
37
|
+
|
38
|
+
if options.has_key?(:client)
|
39
|
+
http = options.delete(:client)
|
40
|
+
if http
|
41
|
+
if http.class.included_modules.include?(KayakoClient::HTTPBackend)
|
42
|
+
@http_backend = http.class
|
43
|
+
@client = http
|
44
|
+
else
|
45
|
+
raise ArgumentError, "invalid HTTP client: #{http.class.name}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
if options.has_key?(:logger)
|
51
|
+
@logger = options.delete(:logger)
|
52
|
+
end
|
53
|
+
|
54
|
+
if self.instance_of?(KayakoClient::Base)
|
55
|
+
unless defined?(@client) && @client
|
56
|
+
@client = http_backend.new(proxy.merge(:logger => logger))
|
57
|
+
end
|
58
|
+
self.extend(KayakoClient::Client)
|
59
|
+
end
|
60
|
+
|
61
|
+
@associated = {}
|
62
|
+
import(options)
|
63
|
+
end
|
64
|
+
|
65
|
+
def inherited_options
|
66
|
+
inherited = {}
|
67
|
+
inherited[:api_url] = @api_url if defined?(@api_url)
|
68
|
+
inherited[:api_key] = @api_key if defined?(@api_key)
|
69
|
+
inherited[:secret_key] = @secret_key if defined?(@secret_key)
|
70
|
+
inherited[:client] = @client if defined?(@client)
|
71
|
+
inherited[:logger] = @logger if defined?(@logger)
|
72
|
+
inherited
|
73
|
+
end
|
74
|
+
|
75
|
+
class << self
|
76
|
+
|
77
|
+
def configure(&block)
|
78
|
+
instance_eval(&block)
|
79
|
+
end
|
80
|
+
|
81
|
+
def inherited_options(options)
|
82
|
+
inherited = {}
|
83
|
+
inherited[:api_url] = options[:api_url] if options.has_key?(:api_url)
|
84
|
+
inherited[:api_key] = options[:api_key] if options.has_key?(:api_key)
|
85
|
+
inherited[:secret_key] = options[:secret_key] if options.has_key?(:secret_key)
|
86
|
+
inherited[:client] = options[:client] if options.has_key?(:client)
|
87
|
+
inherited[:logger] = options[:logger] if options.has_key?(:logger)
|
88
|
+
inherited
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
class Tickets < Base
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'kayako_client/mixins/user_visibility_api'
|
2
|
+
|
3
|
+
require 'kayako_client/user_group'
|
4
|
+
|
5
|
+
module KayakoClient
|
6
|
+
class Department < KayakoClient::Base
|
7
|
+
include KayakoClient::UserVisibilityAPI
|
8
|
+
|
9
|
+
DEPARTMENT_TYPES = [ :public, :private ].freeze
|
10
|
+
DEPARTMENT_MODULES = [ :tickets, :livechat ].freeze
|
11
|
+
|
12
|
+
# NOTE: if :parent_department_id is set :module should have the same value
|
13
|
+
|
14
|
+
property :id, :integer, :readonly => true
|
15
|
+
property :title, :string, :required => [ :put, :post ]
|
16
|
+
property :type, :symbol, :in => DEPARTMENT_TYPES, :required => :post
|
17
|
+
property :module, :symbol, :in => DEPARTMENT_MODULES, :required => :post, :new => true
|
18
|
+
property :display_order, :integer
|
19
|
+
property :parent_department_id, :integer
|
20
|
+
property :user_visibility_custom, :boolean
|
21
|
+
property :user_group_ids, [ :integer ], :get => :usergroups, :set => :usergroupid, :condition => { :user_visibility_custom => true }
|
22
|
+
|
23
|
+
associate :parent_department, :parent_department_id, Department
|
24
|
+
associate :user_groups, :user_group_ids, UserGroup
|
25
|
+
|
26
|
+
def has_parent_department?
|
27
|
+
!parent_department_id.nil? && parent_department_id > 0
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,217 @@
|
|
1
|
+
module KayakoClient
|
2
|
+
module HTTP
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
def proxy=(options = {})
|
9
|
+
@proxy = {}
|
10
|
+
options.each do |key, value|
|
11
|
+
if [ :host, :port, :user, :pass ].include?(key)
|
12
|
+
@proxy[key] = value
|
13
|
+
else
|
14
|
+
raise ArgumentError, "unsupported option: #{key}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def proxy
|
20
|
+
@proxy ||= self.class.proxy
|
21
|
+
end
|
22
|
+
|
23
|
+
def http_backend=(backend)
|
24
|
+
if backend.is_a?(String)
|
25
|
+
raise ArgumentError, "invalid HTTP backend: #{backend}" unless backend =~ /^[A-Za-z_]+$/
|
26
|
+
file = backend.gsub(/([a-z])([A-Z])/, '\1_\2').gsub(/([A-Z])([A-Z][a-z])/, '\1_\2').downcase
|
27
|
+
require "kayako_client/http/#{file}"
|
28
|
+
backend = KayakoClient.const_get(backend)
|
29
|
+
end
|
30
|
+
if backend.is_a?(Class)
|
31
|
+
if backend.included_modules.include?(KayakoClient::HTTPBackend)
|
32
|
+
@http_backend = backend
|
33
|
+
@client = nil
|
34
|
+
else
|
35
|
+
raise ArgumentError, "invalid HTTP backend: #{backend.name}"
|
36
|
+
end
|
37
|
+
else
|
38
|
+
if backend.class.included_modules.include?(KayakoClient::HTTPBackend)
|
39
|
+
@http_backend = backend.class
|
40
|
+
@client = backend
|
41
|
+
else
|
42
|
+
raise ArgumentError, "invalid HTTP backend: #{backend.class.name}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def http_backend
|
48
|
+
@http_backend ||= self.class.http_backend
|
49
|
+
end
|
50
|
+
|
51
|
+
def client
|
52
|
+
@client ||= nil
|
53
|
+
unless @client
|
54
|
+
if !instance_of?(KayakoClient::Base) && http_backend == self.class.http_backend && self.class.client
|
55
|
+
@client = self.class.client
|
56
|
+
else
|
57
|
+
@client = http_backend.new(proxy.merge(:logger => logger))
|
58
|
+
end
|
59
|
+
end
|
60
|
+
@client
|
61
|
+
end
|
62
|
+
|
63
|
+
def put_request(params = {})
|
64
|
+
@errors ||= {}
|
65
|
+
raise RuntimeError, "undefined ID" unless id
|
66
|
+
random = self.class.salt
|
67
|
+
e = params.delete(:e) || "#{self.class.path}/#{id}"
|
68
|
+
data = self.class.validate(params.merge(:errors => @errors))
|
69
|
+
if @errors.empty?
|
70
|
+
client.put(api_url, data.merge(:e => e,
|
71
|
+
:apikey => api_key,
|
72
|
+
:salt => random,
|
73
|
+
:signature => self.class.signature(random, secret_key)))
|
74
|
+
else
|
75
|
+
@errors
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def post_request(params = {})
|
80
|
+
@errors ||= {}
|
81
|
+
random = self.class.salt
|
82
|
+
e = params.delete(:e) || self.class.path
|
83
|
+
data = self.class.validate(params.merge(:errors => @errors))
|
84
|
+
if @errors.empty?
|
85
|
+
client.post(api_url, data.merge(:e => e,
|
86
|
+
:apikey => api_key,
|
87
|
+
:salt => random,
|
88
|
+
:signature => self.class.signature(random, secret_key)))
|
89
|
+
else
|
90
|
+
@errors
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def delete_request(params = {})
|
95
|
+
raise RuntimeError, "undefined ID" unless id
|
96
|
+
random = self.class.salt
|
97
|
+
e = params.delete(:e) || "#{self.class.path}/#{id}"
|
98
|
+
client.delete(api_url, :e => e,
|
99
|
+
:apikey => api_key,
|
100
|
+
:salt => random,
|
101
|
+
:signature => self.class.signature(random, secret_key))
|
102
|
+
end
|
103
|
+
|
104
|
+
module ClassMethods
|
105
|
+
|
106
|
+
def proxy=(options = {})
|
107
|
+
@@proxy = {}
|
108
|
+
options.each do |key, value|
|
109
|
+
if [ :host, :port, :user, :pass ].include?(key)
|
110
|
+
@@proxy[key] = value
|
111
|
+
else
|
112
|
+
raise ArgumentError, "unsupported option: #{key}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def proxy
|
118
|
+
@@proxy ||= {}
|
119
|
+
end
|
120
|
+
|
121
|
+
def http_backend=(backend)
|
122
|
+
if backend.is_a?(String)
|
123
|
+
raise ArgumentError, "invalid HTTP backend: #{backend}" unless backend =~ /^[A-Za-z_]+$/
|
124
|
+
file = backend.gsub(/([a-z])([A-Z])/, '\1_\2').gsub(/([A-Z])([A-Z][a-z])/, '\1_\2').downcase
|
125
|
+
require "kayako_client/http/#{file}"
|
126
|
+
backend = KayakoClient.const_get(backend)
|
127
|
+
end
|
128
|
+
if backend.is_a?(Class)
|
129
|
+
if backend.included_modules.include?(KayakoClient::HTTPBackend)
|
130
|
+
@@http_backend = backend
|
131
|
+
@@client = nil
|
132
|
+
else
|
133
|
+
raise ArgumentError, "invalid HTTP backend: #{backend.name}"
|
134
|
+
end
|
135
|
+
else
|
136
|
+
if backend.class.included_modules.include?(KayakoClient::HTTPBackend)
|
137
|
+
@@http_backend = backend.class
|
138
|
+
@@client = backend
|
139
|
+
else
|
140
|
+
raise ArgumentError, "invalid HTTP backend: #{backend.class.name}"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def http_backend
|
146
|
+
begin
|
147
|
+
require 'kayako_client/http/http_client'
|
148
|
+
@@http_backend ||= KayakoClient::HTTPClient
|
149
|
+
rescue LoadError
|
150
|
+
require 'kayako_client/http/net_http'
|
151
|
+
@@http_backend ||= KayakoClient::NetHTTP
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def client
|
156
|
+
@@client ||= nil
|
157
|
+
unless @@client
|
158
|
+
@@client = http_backend.new(proxy.merge(:logger => logger))
|
159
|
+
end
|
160
|
+
@@client
|
161
|
+
end
|
162
|
+
|
163
|
+
def get_request(options = {})
|
164
|
+
random = salt
|
165
|
+
params = options.dup
|
166
|
+
|
167
|
+
id = params.delete(:id)
|
168
|
+
e = params.delete(:e) || (id.nil? ? path : "#{path}/#{id}")
|
169
|
+
http = params.delete(:client) || client
|
170
|
+
url = params.delete(:api_url) || api_url
|
171
|
+
key = params.delete(:api_key) || api_key
|
172
|
+
secret = params.delete(:secret_key) || secret_key
|
173
|
+
|
174
|
+
http.get(url, params.merge(:e => e,
|
175
|
+
:apikey => key,
|
176
|
+
:salt => random,
|
177
|
+
:signature => signature(random, secret)))
|
178
|
+
end
|
179
|
+
|
180
|
+
def post_request(options = {})
|
181
|
+
random = salt
|
182
|
+
params = options.dup
|
183
|
+
|
184
|
+
e = params.delete(:e) || path
|
185
|
+
http = params.delete(:client) || client
|
186
|
+
url = params.delete(:api_url) || api_url
|
187
|
+
key = params.delete(:api_key) || api_key
|
188
|
+
secret = params.delete(:secret_key) || secret_key
|
189
|
+
|
190
|
+
http.post(url, params.merge(:e => e,
|
191
|
+
:apikey => key,
|
192
|
+
:salt => random,
|
193
|
+
:signature => signature(random, secret)))
|
194
|
+
end
|
195
|
+
|
196
|
+
def delete_request(options = {})
|
197
|
+
random = salt
|
198
|
+
params = options.dup
|
199
|
+
|
200
|
+
id = params.delete(:id)
|
201
|
+
e = params.delete(:e) || "#{path}/#{id}"
|
202
|
+
http = params.delete(:client) || client
|
203
|
+
url = params.delete(:api_url) || api_url
|
204
|
+
key = params.delete(:api_key) || api_key
|
205
|
+
secret = params.delete(:secret_key) || secret_key
|
206
|
+
|
207
|
+
raise ArgumentError, "missing ID" unless id
|
208
|
+
http.delete(url, :e => e,
|
209
|
+
:apikey => key,
|
210
|
+
:salt => random,
|
211
|
+
:signature => signature(random, secret))
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
217
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module KayakoClient
|
4
|
+
module HTTPBackend
|
5
|
+
|
6
|
+
def initialize(options = {})
|
7
|
+
raise NotImplementedError, "not implemented"
|
8
|
+
end
|
9
|
+
|
10
|
+
def get(base, params = {})
|
11
|
+
raise NotImplementedError, "not implemented"
|
12
|
+
end
|
13
|
+
|
14
|
+
def put(base, params = {})
|
15
|
+
raise NotImplementedError, "not implemented"
|
16
|
+
end
|
17
|
+
|
18
|
+
def post(base, params = {})
|
19
|
+
raise NotImplementedError, "not implemented"
|
20
|
+
end
|
21
|
+
|
22
|
+
def delete(base, params = {})
|
23
|
+
raise NotImplementedError, "not implemented"
|
24
|
+
end
|
25
|
+
|
26
|
+
def response(resp)
|
27
|
+
raise NotImplementedError, "not implemented"
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'httpclient'
|
2
|
+
|
3
|
+
module KayakoClient
|
4
|
+
class HTTPClient
|
5
|
+
include KayakoClient::Logger
|
6
|
+
include KayakoClient::HTTPBackend
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
@client = ::HTTPClient.new
|
10
|
+
if options[:host]
|
11
|
+
@client.proxy = "http://#{options[:host]}:#{options[:port] || 80}"
|
12
|
+
@client.set_proxy_auth(options[:user], options[:pass])
|
13
|
+
end
|
14
|
+
@logger = options[:logger] if options[:logger]
|
15
|
+
end
|
16
|
+
|
17
|
+
def get(base, params = {})
|
18
|
+
log = params.delete(:logger) || logger
|
19
|
+
log.debug ":get => #{base} + #{params.inspect}" if log
|
20
|
+
resp = @client.request(:get, base, params)
|
21
|
+
response(resp)
|
22
|
+
end
|
23
|
+
|
24
|
+
def put(base, params = {})
|
25
|
+
query = { :e => params.delete(:e) }
|
26
|
+
data = form_data(params)
|
27
|
+
log = params.delete(:logger) || logger
|
28
|
+
if log
|
29
|
+
log.debug ":put => #{base} + #{query.inspect}"
|
30
|
+
log.debug "PUT Data: #{data.inspect}"
|
31
|
+
end
|
32
|
+
resp = @client.request(:put, base, query, data, { 'Content-Type' => 'application/x-www-form-urlencoded' })
|
33
|
+
response(resp)
|
34
|
+
end
|
35
|
+
|
36
|
+
def post(base, params = {})
|
37
|
+
query = { :e => params.delete(:e) }
|
38
|
+
data = form_data(params)
|
39
|
+
log = params.delete(:logger) || logger
|
40
|
+
if log
|
41
|
+
log.debug ":post => #{base} + #{query.inspect}"
|
42
|
+
log.debug "POST Data: #{data.inspect}"
|
43
|
+
end
|
44
|
+
resp = @client.request(:post, base, query, data, { 'Content-Type' => 'application/x-www-form-urlencoded' })
|
45
|
+
response(resp)
|
46
|
+
end
|
47
|
+
|
48
|
+
def delete(base, params = {})
|
49
|
+
log = params.delete(:logger) || logger
|
50
|
+
log.debug ":delete => #{base} + #{params.inspect}" if log
|
51
|
+
resp = @client.request(:delete, base, params)
|
52
|
+
response(resp)
|
53
|
+
end
|
54
|
+
|
55
|
+
def response(resp)
|
56
|
+
case resp.status
|
57
|
+
when 200
|
58
|
+
KayakoClient::HTTPOK.new(resp.content)
|
59
|
+
when 400
|
60
|
+
KayakoClient::HTTPBadRequest.new(resp.content)
|
61
|
+
when 401
|
62
|
+
KayakoClient::HTTPUnauthorized.new(resp.content)
|
63
|
+
when 403
|
64
|
+
KayakoClient::HTTPForbidden.new(resp.content)
|
65
|
+
when 404
|
66
|
+
KayakoClient::HTTPNotFound.new(resp.content)
|
67
|
+
when 405
|
68
|
+
KayakoClient::HTTPNotAllowed.new(resp.content)
|
69
|
+
else
|
70
|
+
KayakoClient::HTTPResponse.new(resp.status, resp.content)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def form_data(params = {})
|
77
|
+
params.inject([]) do |array, (name, value)|
|
78
|
+
if value.is_a?(Array)
|
79
|
+
array.concat(value.collect { |item| [ name.to_s + '[]', item.to_s ] })
|
80
|
+
else
|
81
|
+
array.push([ name.to_s, value.to_s ])
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|