-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
FoursquareAPI.Class.php
326 lines (294 loc) · 11.5 KB
/
FoursquareAPI.Class.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
<?php
/**
* FoursquareApi
* A PHP-based Foursquare client library with a focus on simplicity and ease of integration
*
* @package php-foursquare
* @author Stephen Young <[email protected]>, @stephenyoungdev
* @version 1.0.0
* @license GPLv3 <http://www.gnu.org/licenses/gpl.txt>
*/
// ???
DEFINE("HTTP_GET","GET");
DEFINE("HTTP_POST","POST");
/**
* FoursquareApi
* Provides a wrapper for making both public and authenticated requests to the
* Foursquare API, as well as the necessary functionality for acquiring an
* access token for a user via Foursquare web authentication
*/
class FoursquareApiException extends Exception {}
class FoursquareApi {
/** @var String $BaseUrl The base url for the foursquare API */
private $BaseUrl = "https://api.foursquare.com/";
/** @var String $AuthUrl The url for obtaining the auth access code */
private $AuthUrl = "https://foursquare.com/oauth2/authenticate";
/** @var String $AuthorizeUrl The url for obtaining an auth token, reprompting even if logged in */
private $AuthorizeUrl = "https://foursquare.com/oauth2/authorize";
/** @var String $TokenUrl The url for obtaining an auth token */
private $TokenUrl = "https://foursquare.com/oauth2/access_token";
// Edited Petr Babicka ([email protected]) https://developer.foursquare.com/overview/versioning
/** @var String $Version YYYYMMDD */
private $Version;
/** @var String $ClientID */
private $ClientID;
/** @var String $ClientSecret */
private $ClientSecret;
/** @var String $RedirectUri */
protected $RedirectUri;
/** @var String $AuthToken */
private $AuthToken;
/** @var String $ClientLanguage */
private $ClientLanguage;
/**
* Constructor for the API
* Prepares the request URL and client api params
* @param bool|String $client_id
* @param bool|String $client_secret
* @param string $redirect_uri
* @param String $version Defaults to v2, appends into the API url
* @param string $language
* @param string $api_version https://developer.foursquare.com/overview/versioning
*/
public function __construct($client_id = false,$client_secret = false, $redirect_uri='', $version='v2', $language='pt', $api_version='20140825'){
$this->BaseUrl = "{$this->BaseUrl}$version/";
$this->ClientID = $client_id;
$this->ClientSecret = $client_secret;
$this->ClientLanguage = $language;
$this->RedirectUri = $redirect_uri;
$this->Version = $api_version;
}
public function setRedirectUri( $uri ) {
$this->RedirectUri = $uri;
}
// Request functions
/**
* GetPublic
* Performs a request for a public resource
* @param String $endpoint A particular endpoint of the Foursquare API
* @param Array $params A set of parameters to be appended to the request, defaults to false (none)
*/
public function GetPublic($endpoint,$params=false){
// Build the endpoint URL
$url = $this->BaseUrl . trim($endpoint,"/");
// Append the client details
$params['client_id'] = $this->ClientID;
$params['client_secret'] = $this->ClientSecret;
$params['v'] = $this->Version;
$params['locale'] = $this->ClientLanguage;
// Return the result;
return $this->GET($url,$params);
}
/**
* GetPrivate
* Performs a request for a private resource
* @param String $endpoint A particular endpoint of the Foursquare API
* @param Array $params A set of parameters to be appended to the request, defaults to false (none)
* @param bool $POST whether or not to use a POST request
*/
public function GetPrivate($endpoint,$params=false,$POST=false){
$url = $this->BaseUrl . trim($endpoint,"/");
$params['oauth_token'] = $this->AuthToken;
$params['v'] = $this->Version;
$params['locale'] = $this->ClientLanguage;
if(!$POST) return $this->GET($url,$params);
else return $this->POST($url,$params);
}
/**
* GetMulti
* Performs a request for up to 5 private or public resources
* @param Array $requests An array of arrays containing the endpoint and a set of parameters
* to be appended to the request, defaults to false (none)
* @param bool $POST whether or not to use a POST request, e.g. for large request bodies.
* It does not allow you to call endpoints that mutate data.
*/
public function GetMulti($requests=false,$POST=false){
$url = $this->BaseUrl . "multi";
$params = array();
$params['oauth_token'] = $this->AuthToken;
$params['v'] = $this->Version;
if (is_array($requests)){
$request_queries = array();
foreach($requests as $request) {
$endpoint = $request['endpoint'];
unset($request['endpoint']);
$query = '/' . $endpoint;
// Edited Elio Gavlinski ([email protected])
if (!empty($request)) $query .= '?' . htmlentities(urlencode(http_build_query($request)));
$request_queries[] = $query;
}
$params['requests'] = implode(',', $request_queries);
}
if(!$POST) return $this->GET($url,$params);
else return $this->POST($url,$params);
}
public function getResponseFromJsonString($json) {
$json = json_decode( $json );
if ( !isset( $json->response ) ) {
throw new FoursquareApiException( 'Invalid response' );
}
// Better to check status code and fail gracefully, but not worried about it
// ... REALLY, we should be checking the HTTP status code as well, not
// just what the API gives us in it's microformat
/*
if ( !isset( $json->meta->code ) || 200 !== $json->meta->code ) {
throw new FoursquareApiException( 'Invalid response' );
}
*/
return $json->response;
}
/**
* Request
* Performs a cUrl request with a url generated by MakeUrl. The useragent of the request is hardcoded
* as the Google Chrome Browser agent
* @param String $url The base url to query
* @param Array $params The parameters to pass to the request
*/
private function Request($url,$params=false,$type=HTTP_GET){
// Populate data for the GET request
if($type == HTTP_GET) $url = $this->MakeUrl($url,$params);
// borrowed from Andy Langton: http://andylangton.co.uk/
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
if ( isset($_SERVER['HTTP_USER_AGENT']) ) {
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT'] );
} else {
// Handle the useragent like we are Google Chrome
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.X.Y.Z Safari/525.13.');
}
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$acceptLanguage[] = "Accept-Language:" . $this->ClientLanguage;
curl_setopt($ch, CURLOPT_HTTPHEADER, $acceptLanguage);
// Populate the data for POST
if($type == HTTP_POST) {
curl_setopt($ch, CURLOPT_POST, 1);
if($params) curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
}
$result=curl_exec($ch);
$info=curl_getinfo($ch);
curl_close($ch);
return $result;
}
/**
* GET
* Abstraction of the GET request
*/
private function GET($url,$params=false){
return $this->Request($url,$params,HTTP_GET);
}
/**
* POST
* Abstraction of a POST request
*/
private function POST($url,$params=false){
return $this->Request($url,$params,HTTP_POST);
}
// Helper Functions
/**
* GeoLocate
* Leverages the google maps api to generate a lat/lng pair for a given address
* packaged with FoursquareApi to facilitate locality searches.
* @param String $addr An address string accepted by the google maps api
* @return array(lat, lng) || NULL
*/
public function GeoLocate($addr){
$addr = str_replace(" ", "+", $addr);
$geoapi = "https://maps.googleapis.com/maps/api/geocode/json";
$params = array("address"=>$addr,"key"=>"AIzaSyD9ZfpJz_ZlwOo7crLhiYhxcpJdBPpBVi8","sensor"=>"false");
$response = $this->GET($geoapi,$params);
if (empty($response)) {
$json = new stdClass();
$json->status = "";
} else {
$json = json_decode($response);
}
// If Status Code is ZERO_RESULTS, OVER_QUERY_LIMIT, REQUEST_DENIED or INVALID_REQUEST
if ($json->status != "OK") {
return NULL;
} else {
// Edited Elio Gavlinski ([email protected])
return array('latitude' => $json->results[0]->geometry->location->lat,
'longitude' => $json->results[0]->geometry->location->lng,
'southwest' => $json->results[0]->geometry->viewport->southwest->lat . "," . $json->results[0]->geometry->viewport->southwest->lng,
'northeast' => $json->results[0]->geometry->viewport->northeast->lat . "," . $json->results[0]->geometry->viewport->northeast->lng,
'southeast' => $json->results[0]->geometry->viewport->southwest->lat . "," . $json->results[0]->geometry->viewport->northeast->lng,
'northwest' => $json->results[0]->geometry->viewport->northeast->lat . "," . $json->results[0]->geometry->viewport->southwest->lng);
}
}
/**
* MakeUrl
* Takes a base url and an array of parameters and sanitizes the data, then creates a complete
* url with each parameter as a GET parameter in the URL
* @param String $url The base URL to append the query string to (without any query data)
* @param Array $params The parameters to pass to the URL
*/
private function MakeUrl($url,$params){
return trim($url) . '?' . http_build_query($params);
}
// Access token functions
/**
* SetAccessToken
* Basic setter function, provides an authentication token to GetPrivate requests
* @param String $token A Foursquare user auth_token
*/
public function SetAccessToken($token){
$this->AuthToken = $token;
}
/**
* AuthenticationLink
* Returns a link to the Foursquare web authentication page.
* @param String $redirect The configured redirect_uri for the provided client credentials
*/
public function AuthenticationLink($redirect=''){
if ( 0 === strlen( $redirect ) ) {
$redirect = $this->RedirectUri;
}
$params = array("client_id"=>$this->ClientID,"response_type"=>"code","redirect_uri"=>$redirect);
return $this->MakeUrl($this->AuthUrl,$params);
}
/**
* AuthorizeLink
* Returns a link to the Foursquare web authentication page. Using /authorize will ask the user to
* re-authenticate their identity and reauthorize your app while giving the user the option to
* login under a different account.
* @param String $redirect The configured redirect_uri for the provided client credentials
*/
public function AuthorizeLink($redirect=''){
if ( 0 === strlen( $redirect ) ) {
$redirect = $this->RedirectUri;
}
$params = array("client_id"=>$this->ClientID,"response_type"=>"code","redirect_uri"=>$redirect);
return $this->MakeUrl($this->AuthorizeUrl,$params);
}
/**
* GetToken
* Performs a request to Foursquare for a user token, and returns the token, while also storing it
* locally for use in private requests
* @param $code The 'code' parameter provided by the Foursquare webauth callback redirect
* @param $redirect The configured redirect_uri for the provided client credentials
*/
public function GetToken($code,$redirect=''){
if ( 0 === strlen( $redirect ) ) {
// If we have to use the same URI to request a token as we did for
// the authorization link, why are we not storing it internally?
$redirect = $this->RedirectUri;
}
$params = array("client_id"=>$this->ClientID,
"client_secret"=>$this->ClientSecret,
"grant_type"=>"authorization_code",
"redirect_uri"=>$redirect,
"code"=>$code);
$result = $this->GET($this->TokenUrl,$params);
$json = json_decode($result);
// Petr Babicka Check if we get token
if (property_exists($json, 'access_token')) {
$this->SetAccessToken($json->access_token);
return $json->access_token;
}
else {
return 0;
}
}
}