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