Class: Bronto::Base

Inherits:
Object show all
Defined in:
lib/bronto/base.rb

Direct Known Subclasses

Contact, Delivery, Field, List, Message

Constant Summary collapse

@@api_key =
nil

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Base

Accepts a hash whose keys should be setters on the object.



164
165
166
167
168
# File 'lib/bronto/base.rb', line 164

def initialize(options = {})
  self.api_key = self.class.api_key
  self.errors = Errors.new
  options.each { |k,v| send("#{k}=", v) if respond_to?("#{k}=") }
end

Instance Attribute Details

#api_keyObject

Returns the value of attribute api_key.



3
4
5
# File 'lib/bronto/base.rb', line 3

def api_key
  @api_key
end

#errorsObject

Returns the value of attribute errors.



3
4
5
# File 'lib/bronto/base.rb', line 3

def errors
  @errors
end

#idObject

Returns the value of attribute id.



3
4
5
# File 'lib/bronto/base.rb', line 3

def id
  @id
end

Class Method Details

.apiObject

Sets up the Savon SOAP client object (if necessary) and returns it.



42
43
44
45
46
47
48
49
# File 'lib/bronto/base.rb', line 42

def self.api
  return @api unless @api.nil?

  @api = Savon::Client.new do
    wsdl.endpoint = "https://api.bronto.com/v4"
    wsdl.namespace = "http://api.bronto.com/v4"
  end
end

.api_keyObject



12
13
14
# File 'lib/bronto/base.rb', line 12

def self.api_key
  @@api_key
end

.api_key=(api_key) ⇒ Object

Getter/Setter for global API Key.



8
9
10
# File 'lib/bronto/base.rb', line 8

def self.api_key=(api_key)
  @@api_key = api_key
end

.create(*objs) ⇒ Object

Tells the remote server to create the passed in collection of Bronto::Base objects. The object should implement ‘to_hash` to return a hash in the format expected by the SOAP API.

Returns the same collection of objects that was passed in. Objects whose creation succeeded will be assigned the ID returned from Bronto. The first element passed in can be a string containing the API key; if none passed, will fall back to the global key.



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/bronto/base.rb', line 96

def self.create(*objs)
  objs = objs.flatten
  api_key = objs.first.is_a?(String) ? objs.shift : self.api_key

  resp = request(:add, api_key) do
    soap.body = {
      plural_class_name => objs.map(&:to_hash)
    }
  end

  objs.each { |o| o.errors.clear }

  Array.wrap(resp[:return][:results]).each_with_index do |result, i|
    if result[:is_error]
      objs[i].errors.add(result[:error_code], result[:error_string])
    else
      objs[i].id = result[:id]
    end
  end

  objs
end

.destroy(*objs) ⇒ Object

Destroys a collection of Bronto::Base objects on the remote server.

Returns the same collection of objects that was passed in. Objects whose destruction succeeded will have a nil ID.

The first element passed in can be a string containing the API key; if none passed, will fall back to the global key.



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/bronto/base.rb', line 142

def self.destroy(*objs)
  objs = objs.flatten
  api_key = objs.first.is_a?(String) ? objs.shift : self.api_key

  resp = request(:delete, api_key) do
    soap.body = {
      plural_class_name => objs.map { |o| { id: o.id }}
    }
  end

  Array.wrap(resp[:return][:results]).each_with_index do |result, i|
    if result[:is_error]
      objs[i].errors.add(result[:error_code], result[:error_string])
    else
      objs[i].id = nil
    end
  end

  objs
end

.find(filter = Bronto::Filter.new, page_number = 1, api_key = nil) ⇒ Object

Finds objects matching the ‘filter` (a Bronto::Filter instance).



80
81
82
83
84
85
86
87
88
# File 'lib/bronto/base.rb', line 80

def self.find(filter = Bronto::Filter.new, page_number = 1, api_key = nil)
  api_key = api_key || self.api_key

  resp = request(:read, api_key) do
    soap.body = { filter: filter.to_hash, page_number: page_number }
  end

  Array.wrap(resp[:return]).map { |hash| new(hash) }
end

.plural_class_nameObject

Simple helper method to convert class name to downcased pluralized version (e.g., Field -> fields).



17
18
19
# File 'lib/bronto/base.rb', line 17

def self.plural_class_name
  self.to_s.split("::").last.downcase.pluralize
end

.request(method, api_key = nil, refresh_header = false, &_block) ⇒ Object

The primary method used to interface with the SOAP API. This method automatically adds the required session header and returns the actual response section of the SOAP response body.

If a symbol is passed in, it is converted to “method_plural_class_name” (e.g., :read => read_lists). A string method is used as-is. Pass in a block and assign a hash to soap.body with a structure appropriate to the method call.



27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/bronto/base.rb', line 27

def self.request(method, api_key = nil, refresh_header = false, &_block)
  _soap_header = self.soap_header(api_key, refresh_header)
  api_key = api_key || self.api_key

  method = "#{method}_#{plural_class_name}" if method.is_a? Symbol

  resp = api.request(:v4, method.to_sym) do
    soap.header = _soap_header
    evaluate(&_block) if _block # See Savon::Client#evaluate; necessary to preserve scope.
  end

  resp.body["#{method}_response".to_sym]
end

.save(*objs) ⇒ Object

Saves a collection of Bronto::Base objects. Objects without IDs are considered new and are ‘create`d; objects with IDs are considered existing and are `update`d.



65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/bronto/base.rb', line 65

def self.save(*objs)
  objs = objs.flatten
  api_key = objs.first.is_a?(String) ? objs.shift : self.api_key

  updates = []
  creates = []

  objs.each { |o| (o.id.present? ? updates : creates) << o }

  update(updates) if updates.count > 0
  create(creates) if creates.count > 0
  objs
end

.soap_header(api_key, refresh = false) ⇒ Object

Helper method to retrieve the session ID and return a SOAP header. Will return a header with the same initial session ID unless the ‘refresh` argument is `true`.



53
54
55
56
57
58
59
60
61
# File 'lib/bronto/base.rb', line 53

def self.soap_header(api_key, refresh = false)
  return @soap_header if !refresh and @soap_header.present?

  resp = api.request(:v4, :login) do
    soap.body = { api_token: api_key }
  end

  @soap_header = { "v4:sessionHeader" => { session_id: resp.body[:login_response][:return] } }
end

.update(*objs) ⇒ Object

Updates a collection of Bronto::Base objects. The objects should exist on the remote server. The object should implement ‘to_hash` to return a hash in the format expected by the SOAP API. The first element passed in can be a string containing the API key; if none passed, will fall back to the global key.



122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/bronto/base.rb', line 122

def self.update(*objs)
  objs = objs.flatten
  api_key = objs.first.is_a?(String) ? objs.shift : self.api_key

  resp = request(:update, api_key) do
    soap.body = {
      plural_class_name => objs.map(&:to_hash)
    }
  end

  objs.each { |o| o.errors.clear }
  objs
end

Instance Method Details

#createObject

Creates the object. See ‘Bronto::Base.create` for more info.



203
204
205
206
# File 'lib/bronto/base.rb', line 203

def create
  res = self.class.create(self.api_key, self)
  res.first
end

#destroyObject

Destroys the object. See ‘Bronto::Base.destroy` for more info.



214
215
216
# File 'lib/bronto/base.rb', line 214

def destroy
  self.class.destroy(self.api_key, self).first
end

#reloadObject



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/bronto/base.rb', line 180

def reload
  return if self.id.blank?

  # The block below is evaluated in a weird scope so we need to capture self as _self for use inside the block.
  _self = self

  resp = request(:read) do
    soap.body = { filter: { id: _self.id } }
  end

  resp[:return].each do |k, v|
    self.send("#{k}=", v) if self.respond_to? "#{k}="
  end

  nil
end

#request(method, &block) ⇒ Object

Convenience instance method that calls the class ‘request` method.



176
177
178
# File 'lib/bronto/base.rb', line 176

def request(method, &block)
  self.class.request(method, self.api_key, false, &block)
end

#saveObject

Saves the object. If the object has an ID, it is updated. Otherwise, it is created.



198
199
200
# File 'lib/bronto/base.rb', line 198

def save
  id.blank? ? create : update
end

#to_hashObject

‘to_hash` should be overridden to provide a hash whose structure matches the structure expected by the API.



171
172
173
# File 'lib/bronto/base.rb', line 171

def to_hash
  {}
end

#updateObject

Updates the object. See ‘Bronto::Base.update` for more info.



209
210
211
# File 'lib/bronto/base.rb', line 209

def update
  self.class.update(self.api_key, self).first
end