Skip to content

Commit c840490

Browse files
author
Jordan Boesch
committed
initial
0 parents  commit c840490

File tree

4 files changed

+431
-0
lines changed

4 files changed

+431
-0
lines changed

README.markdown

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# FreshBooksRequest PHP API
2+
3+
This class is meant to give you the ability to quickly access the FreshBooks API.
4+
5+
## Usage
6+
7+
* You need to know the method names and params when you're creating a new FreshBooksRequest instance. See all here http://developers.freshbooks.com/
8+
* The XML tag parameters you see on the freshbooks API page are the ones you pass to $fb->post() (as an array)
9+
* Require the lib and setup with your credentials (domain and token)
10+
11+
```php
12+
require('lib/FreshBooksRequest.php');
13+
14+
$domain = 'your-subdomain'; // https://your-subdomain.freshbooks.com/
15+
$token = '1234567890'; // your api token found in your account
16+
FreshBooks::init($domain, $token);
17+
```
18+
* Now let's say we want to list clients with an email of some@email.com
19+
20+
```php
21+
/**********************************************
22+
* Fetch all clients by a specific id
23+
**********************************************/
24+
// Method name found on the freshbooks API
25+
$fb = new FreshBooksRequest('client.list');
26+
// Any arguments you want to pass it
27+
$fb->post(array(
28+
'email' => 'some@email.com'
29+
));
30+
// Make the request
31+
$fb->request();
32+
if($fb->success())
33+
{
34+
echo 'successful! the full response is in an array below';
35+
print_r($fb->getResponse());
36+
}
37+
else
38+
{
39+
echo $fb->getError();
40+
print_r($fb->getResponse());
41+
}
42+
```
43+
* If you're creating a recurring profile with multiple line items, it might look something like this:
44+
45+
```php
46+
/**********************************************
47+
* Create a recurring profile with multiple line items
48+
**********************************************/
49+
$fb = new FreshBooksRequest('recurring.create');
50+
$fb->post(array(
51+
'recurring' => array(
52+
'client_id' => 41,
53+
'lines' => array(
54+
'line' => array(
55+
array(
56+
'name' => 'A prod name',
57+
'description' => 'The description',
58+
'unit_cost' => 10,
59+
'quantity' => 2
60+
),
61+
array(
62+
'name' => 'Another prod name',
63+
'description' => 'The other description',
64+
'unit_cost' => 20,
65+
'quantity' => 1
66+
)
67+
)
68+
)
69+
)
70+
));
71+
// You can view what the XML looks like that we're about to send over the wire
72+
//print_r($fb->getGeneratedXML());
73+
$fb->request();
74+
if($fb->success())
75+
{
76+
$res = $fb->getResponse();
77+
$recurrng_id = $res['recurring_id'];
78+
// Do something with the recurring_id you were returned
79+
}
80+
```
81+
82+
## Change Log
83+
84+
### Changes in 1.0 (Sept 18, 2011)
85+
86+
* Launched!

example.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?
2+
require('lib/FreshBooksRequest.php');
3+
4+
// Setup the login credentials
5+
$domain = '';
6+
$token = '';
7+
FreshBooksRequest::init($domain, $token);
8+
9+
/**********************************************
10+
* Fetch all clients by a specific id
11+
**********************************************/
12+
$fb = new FreshBooksRequest('client.list');
13+
$fb->post(array(
14+
'email' => 'some@email.com'
15+
));
16+
$fb->request();
17+
if($fb->success())
18+
{
19+
echo 'successful! the full response is in an array below';
20+
print_r($fb->getResponse());
21+
}
22+
else
23+
{
24+
echo $fb->getError();
25+
print_r($fb->getResponse());
26+
}
27+
28+
/**********************************************
29+
* List invoices from a specific client
30+
**********************************************/
31+
$fb = new FreshBooksRequest('invoice.list');
32+
$fb->post(array(
33+
'client_id' => 41
34+
));
35+
$fb->request();
36+
if($fb->success())
37+
{
38+
print_r($fb->getResponse());
39+
}
40+
41+
/**********************************************
42+
* Create a recurring profile with multiple line items
43+
**********************************************/
44+
45+
$fb = new FreshBooksRequest('recurring.create');
46+
$fb->post(array(
47+
'recurring' => array(
48+
'client_id' => 41,
49+
'lines' => array(
50+
'line' => array(
51+
array(
52+
'name' => 'A prod name',
53+
'description' => 'The description',
54+
'unit_cost' => 10,
55+
'quantity' => 2
56+
),
57+
array(
58+
'name' => 'Another prod name',
59+
'description' => 'The other description',
60+
'unit_cost' => 20,
61+
'quantity' => 1
62+
)
63+
)
64+
)
65+
)
66+
));
67+
//print_r($fb->getGeneratedXML());
68+
$fb->request();
69+
if($fb->success())
70+
{
71+
$res = $fb->getResponse();
72+
$recurrng_id = $res['recurring_id'];
73+
// Do something with the recurring_id you were returned
74+
}
75+
?>

lib/FreshBooksRequest.php

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
<?
2+
require_once('XmlDomConstruct.php');
3+
/**
4+
* A simple PHP API wrapper for the FreshBooks API.
5+
* All post vars can be found on the developer site: http://developers.freshbooks.com/
6+
* Stay up to date on Github:
7+
*
8+
* PHP version 5
9+
*
10+
* @author Jordan Boesch <jordan@7shifts.com>
11+
* @license Dual licensed under the MIT and GPL licenses.
12+
* @version 1.0
13+
*/
14+
15+
class FreshBooksRequest {
16+
17+
/*
18+
* The domain you need when making a request
19+
*/
20+
protected static $_domain = '';
21+
22+
/*
23+
* The API token you need when making a request
24+
*/
25+
protected static $_token = '';
26+
27+
/*
28+
* The API url we're hitting. {{ DOMAIN }} will get replaced with $domain
29+
* when you set FreshBooksRequest::init($domain, $token)
30+
*/
31+
protected $_api_url = 'https://{{ DOMAIN }}.freshbooks.com/api/2.1/xml-in';
32+
33+
/*
34+
* Stores the current method we're using. Example:
35+
* new FreshBooksRequest('client.create'), 'client.create' would be the method
36+
*/
37+
protected $_method = '';
38+
39+
/*
40+
* Any arguments to pass to the request
41+
*/
42+
protected $_args = array();
43+
44+
/*
45+
* Determines whether or not the request was successful
46+
*/
47+
protected $_success = false;
48+
49+
/*
50+
* Holds the error returned from our request
51+
*/
52+
protected $_error = '';
53+
54+
/*
55+
* Holds the response after our request
56+
*/
57+
protected $_response = array();
58+
59+
/*
60+
* Initialize the and store the domain/token for making requests
61+
*
62+
* @param string $domain The subdomain like 'yoursite'.freshbooks.com
63+
* @param string $token The token found in your account settings area
64+
* @return null
65+
*/
66+
public static function init($domain, $token)
67+
{
68+
self::$_domain = $domain;
69+
self::$_token = $token;
70+
}
71+
72+
/*
73+
* Set up the request object and assign a method name
74+
*
75+
* @param array $method The method name from the API, like 'client.update' etc
76+
* @return null
77+
*/
78+
public function __construct($method)
79+
{
80+
$this->_method = $method;
81+
}
82+
83+
/*
84+
* Set the data/arguments we're about to request with
85+
*
86+
* @return null
87+
*/
88+
public function post($data)
89+
{
90+
$this->_args = $data;
91+
}
92+
93+
/*
94+
* Determine whether or not it was successful
95+
*
96+
* @return bool
97+
*/
98+
public function success()
99+
{
100+
return $this->_success;
101+
}
102+
103+
/*
104+
* Get the error (if there was one returned from the request)
105+
*
106+
* @return string
107+
*/
108+
public function getError()
109+
{
110+
return $this->_error;
111+
}
112+
113+
/*
114+
* Get the response from the request we made
115+
*
116+
* @return array
117+
*/
118+
public function getResponse()
119+
{
120+
return $this->_response;
121+
}
122+
123+
/*
124+
* Get the generated XML to view. This is useful for debugging
125+
* to see what you're actually sending over the wire. Call this
126+
* after $fb->post() but before your make your $fb->request()
127+
*
128+
* @return array
129+
*/
130+
public function getGeneratedXML()
131+
{
132+
133+
$dom = new XmlDomConstruct('1.0', 'utf-8');
134+
$dom->fromMixed(array(
135+
'request' => $this->_args
136+
));
137+
$post_data = $dom->saveXML();
138+
$post_data = str_replace('<request/>', '<request method="' . $this->_method . '" />', $post_data);
139+
$post_data = str_replace('<request>', '<request method="' . $this->_method . '">', $post_data);
140+
141+
return $post_data;
142+
143+
}
144+
145+
/*
146+
* Send the request over the wire
147+
*
148+
* @return array
149+
*/
150+
public function request()
151+
{
152+
153+
if(!self::$_domain || !self::$_token)
154+
{
155+
$this->_error = 'You need to call FreshBooks::init($domain, $token) with your domain and token.';
156+
return;
157+
}
158+
159+
$post_data = $this->getGeneratedXML();
160+
$url = str_replace('{{ DOMAIN }}', self::$_domain, $this->_api_url);
161+
$ch = curl_init(); // initialize curl handle
162+
curl_setopt($ch, CURLOPT_URL, $url); // set url to post to
163+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return into a variable
164+
curl_setopt($ch, CURLOPT_TIMEOUT, 40); // times out after 40s
165+
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); // add POST fields
166+
curl_setopt($ch, CURLOPT_USERPWD, self::$_token . ':X');
167+
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
168+
169+
$result = curl_exec($ch);
170+
171+
if(curl_errno($ch))
172+
{
173+
$this->_error = 'A cURL error occured: ' . curl_error($ch);
174+
return;
175+
}
176+
else
177+
{
178+
curl_close($ch);
179+
}
180+
181+
$response = json_decode(json_encode(simplexml_load_string($result)), true);
182+
183+
$this->_response = $response;
184+
$this->_success = ($response['@attributes']['status'] == 'ok');
185+
if(isset($response['error']))
186+
{
187+
$this->_error = $response['error'];
188+
}
189+
190+
}
191+
192+
}

0 commit comments

Comments
 (0)