/[drupal]/contributions/modules/freshbooks/freshbooks.class.inc
ViewVC logotype

Contents of /contributions/modules/freshbooks/freshbooks.class.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.5 - (show annotations) (download) (as text)
Fri Nov 7 05:59:31 2008 UTC (12 months, 2 weeks ago) by rszrama
Branch: MAIN
CVS Tags: HEAD
Changes since 1.4: +206 -7 lines
File MIME type: text/x-php
Changed parameters and return value types of DrupalFreshBooks method; added support for all client related API requests.
1 <?php
2 // $Id: freshbooks.class.inc,v 1.4 2008/09/17 14:01:14 rszrama Exp $
3
4 /**
5 * @file
6 * Defines the class used for communicating with the FreshBooks server.
7 *
8 * Developed by Wombats - http://www.bywombats.com
9 *
10 * To sign up for a free trial account and support this module, use the
11 * following link:
12 *
13 * https://bywombats.freshbooks.com/signup/
14 */
15
16 // Identifies this application on the FreshBooks server.
17 define('FRESHBOOKS_USERAGENT', 'FreshBooks for Drupal - By Wombats');
18
19 // The string we expect when verifying credentials.
20 define('FRESHBOOKS_MSG_VERIFY', 'Your XML is not formatted correctly.');
21
22 // The string that indicates an API request was successful.
23 define('FRESHBOOKS_REQUEST_OK', 'ok');
24
25 /**
26 * Defines the DrupalFreshBooks class used to communicate with the server.
27 */
28 class DrupalFreshBooks {
29 // Define variables for the API credentials.
30 public $api_url = '';
31 public $token = '';
32
33 // The raw XML of the last API request and response.
34 public $lastRequest = '';
35 public $lastResponse = '';
36
37 /**
38 * Constructs a DrupalFreshBooks object with a set of API credentials.
39 *
40 * @param $fb_api_url
41 * The API URL for the FreshBooks account you want to use.
42 * @param $fb_token
43 * The authentication token used to verify the connection.
44 */
45 function __construct($fb_api_url, $fb_token) {
46 // Set the appropriate member values.
47 $this->api_url = $fb_api_url;
48 $this->token = $fb_token;
49 }
50
51 /**
52 * Sends an API request to FreshBooks.
53 *
54 * @param $request
55 * The raw XML request to send to the API server.
56 * @return
57 * A SimpleXMLElement object loaded with the response XML.
58 */
59 function sendAPIRequest($request = '<?xml version="1.0" encoding="utf-8"?>') {
60 // Save the last request for later retrieval.
61 $this->lastRequest = $request;
62
63 // Initialize our cURL handler.
64 $ch = curl_init();
65 curl_setopt($ch, CURLOPT_URL, $this->api_url);
66 curl_setopt($ch, CURLOPT_USERPWD, $this->token);
67 curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
68 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
69 curl_setopt($ch, CURLOPT_TIMEOUT, 4);
70 curl_setopt($ch, CURLOPT_USERAGENT, FRESHBOOKS_USERAGENT);
71 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
72 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, TRUE);
73
74 // Retrieve a response from FreshBooks.
75 $this->lastResponse = curl_exec($ch);
76
77 // Report any errors.
78 if ($error = curl_error($ch)) {
79 watchdog('freshbooks', check_plain($error), array(), WATCHDOG_ERROR);
80 }
81 curl_close($ch);
82
83 // Create and return a SimpleXMLElement object with the response loaded.
84 try {
85 $response = new SimpleXMLElement($this->lastResponse);
86 }
87 catch (Exception $e) {
88 // Log the error message.
89 watchdog('freshbooks', check_plain($e->getMessage()), array(), WATCHDOG_ERROR);
90
91 // Create an empty response object.
92 $response = new SimpleXMLElement();
93 }
94
95 return $response;
96 }
97
98 // Creates a new SimpleXMLElement object for use when building a request.
99 function buildAPIRequest($method, $data) {
100 // Create the barebones request XML.
101 $xml = '<?xml version="1.0" encoding="utf-8"?><request method="'. $method .'"></request>';
102
103 // Load the XML into a SimpleXMLElement object.
104 $request = new SimpleXMLElement($xml);
105
106 // Use a method specific container in the XML if need be.
107 $parts = explode('.', $method);
108
109 // Only necessary for create and update methods.
110 if (in_array($parts[1], array('create', 'update'))) {
111 // As of now, the API uses the first part of the method to name the
112 // container. Obviously this will need an update if they ever deviate
113 // from this convention.
114 $container = $request->addChild($parts[0]);
115 }
116 else {
117 $container = $request;
118 }
119
120 // Get the acceptable arguments for the method.
121 $args = $this->getMethodArgs($method);
122
123 // Add children to the request based on the data given and the acceptable
124 // arguments.
125 foreach ($data as $key => $value) {
126 if (in_array($key, array_keys($args))) {
127 // Either add this as a child or a container if need be.
128 if ($args[$key] == 'container') {
129 $container2 = $container->addChild($key);
130
131 // Add the container objects to this new container.
132 foreach ($value as $key2 => $value2) {
133 $container2->addChild($key2, $value2);
134 }
135 }
136 else {
137 $container->addChild($key, $value);
138 }
139 }
140 }
141
142 return $request;
143 }
144
145 /**
146 * Returns an array of acceptable arguments and their data types for the
147 * specified API method.
148 *
149 * @param $method
150 * The lower case name of the FreshBooks API method to query.
151 * @return
152 * An array with keys representing the arguments and values the data types.
153 */
154 function getMethodArgs($method) {
155 switch ($method) {
156 case 'client.create':
157 return array('first_name' => 'str', 'last_name' => 'str', 'organization' => 'str', 'email' => 'email', 'username' => 'str', 'password' => 'str', 'work_phone' => 'phone', 'home_phone' => 'phone', 'mobile' => 'phone', 'fax' => 'phone', 'notes' => 'str', 'pstreet_1' => 'str', 'p_street2' => 'str', 'p_city' => 'str', 'p_state' => 'str', 'p_country' => 'str', 'p_code' => 'str', 's_street1' => 'str', 's_street2' => 'str', 's_city' => 'str', 's_state' => 'str', 's_country' => 'str', 's_code' => 'str');
158 case 'client.update':
159 return array_merge(array('client_id' => 'int'), $this->getMethodArgs('client.create'));
160 case 'client.get':
161 return array('client_id' => 'int');
162 case 'client.delete':
163 return array('client_id' => 'int');
164 case 'client.list':
165 return array('email' => 'str', 'username' => 'str', 'page' => 'int', 'per_page' => 'int');
166 default:
167 return array();
168 }
169 }
170
171 // Tests the connection to verify API credentials.
172 function verifyCredentials() {
173 // Send an empty request to the server.
174 $response = $this->sendAPIRequest();
175
176 // We consider it a failure if the authentication failed.
177 if ($response->error != FRESHBOOKS_MSG_VERIFY) {
178 watchdog('freshbooks', t('Attempted to connect with invalid API credentials.'), array(), WATCHDOG_ERROR);
179 return FALSE;
180 }
181
182 return TRUE;
183 }
184
185 /**
186 * Creates a new client in the FreshBooks account.
187 *
188 * @param $data
189 * An array of client parameters, including at least a first name, last
190 * name, organization, and e-mail address.
191 * @return
192 * The client ID or FALSE if the operation failed.
193 */
194 function clientCreate($data) {
195 // Build the request.
196 $request = $this->buildAPIRequest('client.create', $data);
197
198 // Get the response from FreshBooks.
199 $response = $this->sendAPIRequest($request->asXML());
200
201 // Return the client ID if the request was successful.
202 if ($response['status'] == FRESHBOOKS_REQUEST_OK) {
203 return $response->client_id;
204 }
205 else {
206 // Otherwise log the error and return FALSE.
207 watchdog('freshbooks', 'clientCreate for %first %last failed: @error', array('@first' => $data['first_name'], '@last' => $data['last_name'], '@error' => (string) $response->error), WATCHDOG_ERROR);
208 return FALSE;
209 }
210 }
211
212 /**
213 * Updates a client in the FreshBooks account.
214 *
215 * @param $client_id
216 * The ID of the FreshBooks client you want to update.
217 * @param $data
218 * An array of client parameters you want to update; any not specified will
219 * be left unchanged.
220 * @return
221 * TRUE or FALSE indicating the success of the update.
222 */
223 function clientUpdate($client_id, $data = array()) {
224 // Merge the client ID into the data array.
225 $data = array_merge(array('client_id' => $client_id), $data);
226
227 // Build the request.
228 $request = $this->buildAPIRequest('client.update', $data);
229
230 // Get the response from FreshBooks.
231 $response = $this->sendAPIRequest($request->asXML());
232
233 // Return TRUE if the update was successful.
234 if ($response['status'] == FRESHBOOKS_REQUEST_OK) {
235 return TRUE;
236 }
237 else {
238 // Otherwise log the error and return FALSE.
239 watchdog('freshbooks', 'clientUpdate for client @id failed: @error', array('@id' => $client_id, '@error' => (string) $response->error), WATCHDOG_ERROR);
240 return FALSE;
241 }
242 }
243
244 /**
245 * Returns a particular client from the FreshBooks account.
246 *
247 * @param $client_id
248 * The ID of the client to retrieve.
249 * @return
250 * A SimpleXMLElement object of the client if successful or FALSE if not.
251 */
252 function clientGet($client_id) {
253 // Build the request.
254 $request = $this->buildAPIRequest('client.get', array('client_id' => $client_id));
255
256 // Get the response from FreshBooks.
257 $response = $this->sendAPIRequest($request->asXML());
258
259 // Return TRUE if the request was successful.
260 if ($response['status'] == FRESHBOOKS_REQUEST_OK) {
261 return $response->client;
262 }
263 else {
264 // Otherwise log the error and return FALSE.
265 watchdog('freshbooks', 'clientGet for client @id failed: @error', array('@id' => $client_id, '@error' => (string) $response->error), WATCHDOG_ERROR);
266 return FALSE;
267 }
268 }
269
270 /**
271 * Deletes a particular client from the FreshBooks account.
272 *
273 * @param $client_id
274 * The ID of the client to retrieve.
275 * @return
276 * TRUE or FALSE indicating the success of the delete.
277 */
278 function clientDelete($client_id) {
279 // Build the request.
280 $request = $this->buildAPIRequest('client.delete', array('client_id' => $client_id));
281
282 // Get the response from FreshBooks.
283 $response = $this->sendAPIRequest($request->asXML());
284
285 // Return TRUE if the delete was successful.
286 if ($response['status'] == FRESHBOOKS_REQUEST_OK) {
287 return TRUE;
288 }
289 else {
290 // Otherwise log the error and return FALSE.
291 watchdog('freshbooks', 'clientDelete for client @id failed: @error', array('@id' => $client_id, '@error' => (string) $response->error), WATCHDOG_ERROR);
292 return FALSE;
293 }
294 }
295
296 /**
297 * Returns a list of client summaries in order of descending client_id.
298 *
299 * @param $email
300 * E-mail address to use to filter the client list.
301 * @param $username
302 * Username to use to filter the client list.
303 * @param $page
304 * The page number to show; defaults to 1.
305 * @param $per_page
306 * Number of results per page; defaults to 25.
307 * @return
308 * An array of the returned SimpleXMLElement client objects if successful or
309 * an empty array on failure.
310 */
311 function clientList($email = NULL, $username = NULL, $page = 1, $per_page = 25) {
312 // Build the data array from the parameters.
313 $data = array(
314 'page' => $page,
315 'per_page' => $per_page,
316 );
317
318 // Only add the e-mail filter if specified.
319 if (!empty($email)) {
320 $data['email'] = $email;
321 }
322
323 // Only add the username filter if specified.
324 if (!empty($username)) {
325 $data['username'] = $email;
326 }
327
328 // Build the request.
329 $request = $this->buildAPIRequest('client.list', $data);
330
331 // Get the response from FreshBooks.
332 $response = $this->sendAPIRequest($request->asXML());
333
334 // Return the array of client objects if successful.
335 if ($response['status'] == FRESHBOOKS_REQUEST_OK) {
336 return $response->clients->client;
337 }
338 else {
339 // Otherwise log the error and return FALSE.
340 watchdog('freshbooks', 'clientList request failed with parameters: <pre>@data</pre>', array('@data' => $data), WATCHDOG_ERROR);
341 return array();
342 }
343 }
344 }

  ViewVC Help
Powered by ViewVC 1.1.2