├── .gitignore ├── LICENSE.txt ├── README.md ├── composer.json ├── examples ├── README.md ├── authenticated.php ├── public.php ├── screenshots │ └── public.php.png └── tokenrequest.php ├── src └── FoursquareApi.php └── tests └── FoursquareApiTest.php /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | .idea/ 3 | .DS_Store 4 | .creds.php -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Why another Foursquare library? 2 | 3 | I couldn't find a php library for the Foursquare API that encapsulated all the functionality of the API while still remaining easy to plug in to an application quickly. This library seeks to fill that need. 4 | 5 | ### Installation 6 | 7 | The best way to install Foursquare library is to use [Composer](https://getcomposer.org/): 8 | 9 | ``` 10 | composer require hownowstephen/php-foursquare:'1.2.*' 11 | ``` 12 | 13 | If you are not using an autoloader, you need to require_once the autoload file: 14 | 15 | ``` 16 | require_once 'vendor/autoload.php'; 17 | ``` 18 | 19 | Another way to install is to download the latest version directly from this repository. 20 | 21 | ### Usage 22 | 23 | This library wrappers for php applications to make requests to both public and authenticated-only resources on Foursquare. As well it provides functions that encapsulate the main methods needed to retrieve an auth_token for a user from Foursquare. Instead of having explicit functions for calling API endpoints, you can call individual endpoints directly by their path (eg. [venues/40a55d80f964a52020f31ee3/tips](https://api.foursquare.com/v2/venues/40a55d80f964a52020f31ee3/tips)) 24 | 25 | #### Querying the API 26 | 27 | ```php 28 | $foursquare = new FoursquareApi("", ""); 29 | 30 | // Searching for venues nearby Montreal, Quebec 31 | $endpoint = "venues/search"; 32 | 33 | // Prepare parameters 34 | $params = array("near"=>"Montreal, Quebec"); 35 | 36 | // Perform a request to a public resource 37 | $response = $foursquare->GetPublic($endpoint,$params); 38 | 39 | // Returns a list of Venues 40 | // $POST defaults to false 41 | $venues = $foursquare->GetPublic($endpoint [,$params], $POST=false); 42 | 43 | // Note: You don't need to add client_id, client_secret, or version to $params 44 | 45 | // Setting the access token to enable private requests 46 | // See examples/tokenrequest.php for how to retrieve this 47 | $auth_token = ""; 48 | $foursquare->SetAccessToken($auth_token); 49 | 50 | // Request a private endpoint (Requires Acting User) 51 | $endpoint_private = "users/self"; 52 | 53 | // Returns a single user object 54 | $me = $foursquare->GetPrivate($endpoint_private); 55 | // Note: You don't need to add oauth_token to $params 56 | ``` 57 | 58 | #### Authenticating the user (see [examples/tokenrequest.php](examples/tokenrequest.php)) 59 | 60 | ```php 61 | $foursquare = new FoursquareApi("", ""); 62 | 63 | // Some real url that accepts a foursquare code (see examples/tokenrequest.php) 64 | // This URL should match exactly the URL given in your foursquare developer account settings 65 | $redirect_url = "http://localhost/foursquare_code_handler"; 66 | 67 | // Generates an authentication link for you to display to your users 68 | // (https://foursquare.com/oauth2/authenticate?...) 69 | $auth_link = $foursquare->AuthenticationLink($redirect_url); 70 | 71 | // Converts an authentication code (sent from foursquare to your $redirect_url) into an access token 72 | // Use this on your $redirect_url page (see examples/tokenrequest.php for more) 73 | $code = $_GET['code']; 74 | 75 | $token = $foursquare->GetToken($code, $redirect_url); 76 | 77 | // again, redirect_url must match the one you set in your account exactly 78 | // and here is where you would store the token for future usage 79 | ``` 80 | 81 | ### Adding features & testing 82 | 83 | If you want to commit features, please also update the [tests/FoursquareApiTest.php](tests/FoursquareApiTest.php) file with a proper unit test - this will ensure changes can be accepted more quickly. 84 | 85 | Running tests requires phpunit, and can be run as the following: 86 | 87 | ``` 88 | export FOURSQUARE_CLIENT_ID= 89 | export FOURSQUARE_CLIENT_SECRET= 90 | export FOURSQUARE_TOKEN= 91 | phpunit --bootstrap src/FoursquareApi.php tests/FoursquareApiTest.php 92 | ``` 93 | 94 | **PROTIP**: The easiest way to get an access token to test with is to [look yourself up in the api explorer](https://developer.foursquare.com/docs/explore#req=users/self) and pull it directly from the grayed-out url information (OAuth token automatically added. https://api.foursquare.com/v2/users/self?oauth_token=...) underneath the input box. 95 | 96 | ### What else do I need? 97 | 98 | This library does not deal with the management of your tokens - only the interaction between your code and the Foursquare API. If you are using it in an application that needs to use user data via an auth_token, you will need to store the token across sessions separately from the library. 99 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hownowstephen/php-foursquare", 3 | "description": "A simple PHP library for accessing the foursquare API (see: https://developer.foursquare.com)", 4 | "require": { 5 | "php": ">=5.2.0" 6 | }, 7 | "autoload": { 8 | "psr-0": { "FoursquareApi": "src/" } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | ## Using public.php 2 | 3 | 1. Edit `$client_key` and `$client_secret` in public.php to your app CLIENT_KEY and CLIENT_SECRET (see: https://foursquare.com/developers/apps) 4 | 2. From the `examples` directory run `php -S localhost:8888` 5 | 3. Navigate your browser to http://localhost:8888/public.php 6 | 4. You should see a page like: 7 | 8 | ![Screenshot of public.php success](screenshots/public.php.png) -------------------------------------------------------------------------------- /examples/authenticated.php: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | PHP-Foursquare :: Authenticated Request Example 9 | 10 | 11 |

Authenticated Request Example

12 |

13 | Search for users by name... 14 |

15 | 16 | 17 |
18 |

Searching for users with name similar to

19 |
20 | "; 23 | $client_secret = ""; 24 | // Set your auth token, loaded using the workflow described in tokenrequest.php 25 | $auth_token = ""; 26 | // Load the Foursquare API library 27 | $foursquare = new FoursquareApi($client_key,$client_secret); 28 | $foursquare->SetAccessToken($auth_token); 29 | 30 | // Prepare parameters 31 | $params = array("name"=>$name); 32 | 33 | // Perform a request to a authenticated-only resource 34 | $response = $foursquare->GetPrivate("users/search",$params); 35 | $users = json_decode($response); 36 | 37 | // NOTE: 38 | // Foursquare only allows for 500 api requests/hr for a given client (meaning the below code would be 39 | // a very inefficient use of your api calls on a production application). It would be a better idea in 40 | // this scenario to have a caching layer for user details and only request the details of users that 41 | // you have not yet seen. Alternatively, several client keys could be tried in a round-robin pattern 42 | // to increase your allowed requests. 43 | 44 | ?> 45 |
    46 | response->results as $user): ?> 47 |
  • 48 | firstName . " "; 50 | if(property_exists($user,"lastName")) echo $user->lastName; 51 | 52 | // Grab user twitter details 53 | $request = $foursquare->GetPrivate("users/{$user->id}"); 54 | $details = json_decode($request); 55 | $u = $details->response->user; 56 | if(property_exists($u->contact,"twitter")){ 57 | echo " -- follow this user contact->twitter}\">@{$u->contact->twitter}"; 58 | } 59 | 60 | ?> 61 | 62 |
  • 63 | 64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /examples/public.php: -------------------------------------------------------------------------------- 1 | foursquare'; 13 | exit; 14 | } 15 | 16 | $foursquare = new FoursquareApi($client_key,$client_secret); 17 | $location = array_key_exists("location",$_GET) ? $_GET['location'] : "Montreal, QC"; 18 | ?> 19 | 20 | 21 | 22 | PHP-Foursquare :: Unauthenticated Request Example 23 | 48 | 49 | 50 |

Basic Request Example

51 |

52 | Search for venues near... 53 |

54 | 55 | 56 |
57 |

Searching for venues near

58 |
59 | GeoLocate($location); 64 | 65 | 66 | // Prepare parameters 67 | $params = array("ll"=>"$lat,$lng"); 68 | 69 | // Perform a request to a public resource 70 | $response = $foursquare->GetPublic("venues/search",$params); 71 | $venues = json_decode($response); 72 | ?> 73 | 74 | meta->code != 200){ ?> 75 |
Couldn't find any venues, got meta->errorType . ": " . $venues->meta->errorDetail; ?>
76 | 80 | 81 | 82 | response->venues as $venue): ?> 83 |
84 | categories['0'])) 88 | { 89 | echo ''; 90 | } 91 | else 92 | echo ''; 93 | echo ''; 94 | echo $venue->name; 95 | echo "
"; 96 | 97 | 98 | 99 | if(isset($venue->categories['0'])) 100 | { 101 | if(property_exists($venue->categories['0'],"name")) 102 | { 103 | echo ' '.$venue->categories['0']->name.'
'; 104 | } 105 | } 106 | 107 | if(property_exists($venue->hereNow,"count")) 108 | { 109 | echo ''.$venue->hereNow->count ." people currently here
"; 110 | } 111 | 112 | echo 'History :'.$venue->stats->usersCount." visitors , ".$venue->stats->checkinsCount." visits "; 113 | 114 | ?> 115 | 116 |
117 | 118 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /examples/screenshots/public.php.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hownowstephen/php-foursquare/6b215c93da7834d4ff5138748dd114abb145394a/examples/screenshots/public.php.png -------------------------------------------------------------------------------- /examples/tokenrequest.php: -------------------------------------------------------------------------------- 1 | "; 8 | $client_secret = ""; 9 | $redirect_uri = ""; 10 | 11 | // Load the Foursquare API library 12 | $foursquare = new FoursquareApi($client_key,$client_secret); 13 | 14 | // If the link has been clicked, and we have a supplied code, use it to request a token 15 | if(array_key_exists("code",$_GET)){ 16 | $token = $foursquare->GetToken($_GET['code'],$redirect_uri); 17 | } 18 | 19 | ?> 20 | 21 | 22 | 23 | PHP-Foursquare :: Token Request Example 24 | 25 | 26 |

Token Request Example

27 |

28 | AuthenticationLink($redirect_uri)."'>Connect to this app via Foursquare"; 32 | // Otherwise display the token 33 | }else{ 34 | echo "Your auth token: $token"; 35 | } 36 | 37 | ?> 38 | 39 |

40 |
41 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/FoursquareApi.php: -------------------------------------------------------------------------------- 1 | , @hownowstephen 8 | * @version 1.2.0 9 | * @license GPLv3 10 | */ 11 | 12 | // Set the default version 13 | // @TODO: Warning when the version becomes too out of date 14 | define("DEFAULT_VERSION", "20140201"); 15 | 16 | // I have no explanation as to why this is necessary 17 | define("HTTP_GET","GET"); 18 | define("HTTP_POST","POST"); 19 | 20 | /** 21 | * FoursquareApi 22 | * Provides a wrapper for making both public and authenticated requests to the 23 | * Foursquare API, as well as the necessary functionality for acquiring an 24 | * access token for a user via Foursquare web authentication 25 | */ 26 | 27 | class FoursquareApiException extends Exception {} 28 | 29 | class FoursquareApi { 30 | 31 | /** @var String $BaseUrl The base url for the foursquare API */ 32 | private $BaseUrl = "https://api.foursquare.com/"; 33 | /** @var String $AuthUrl The url for obtaining the auth access code */ 34 | private $AuthUrl = "https://foursquare.com/oauth2/authenticate"; 35 | /** @var String $AuthorizeUrl The url for obtaining an auth token, reprompting even if logged in */ 36 | private $AuthorizeUrl = "https://foursquare.com/oauth2/authorize"; 37 | /** @var String $TokenUrl The url for obtaining an auth token */ 38 | private $TokenUrl = "https://foursquare.com/oauth2/access_token"; 39 | 40 | // Edited Petr Babicka (babcca@gmail.com) https://developer.foursquare.com/overview/versioning 41 | /** @var String $Version YYYYMMDD */ 42 | private $Version; 43 | 44 | /** @var String $ClientID */ 45 | private $ClientID; 46 | /** @var String $ClientSecret */ 47 | private $ClientSecret; 48 | /** @var String $RedirectUri */ 49 | protected $RedirectUri; 50 | /** @var String $AuthToken */ 51 | private $AuthToken; 52 | /** @var String $ClientLanguage */ 53 | private $ClientLanguage; 54 | /** @var String[] $ResponseHeaders */ 55 | public $ResponseHeaders = array(); 56 | /** @var String last url sent */ 57 | public $LastUrl; 58 | 59 | /** 60 | * Constructor for the API 61 | * Prepares the request URL and client api params 62 | * @param bool|String $client_id 63 | * @param bool|String $client_secret 64 | * @param string $redirect_uri 65 | * @param String $version Defaults to v2, appends into the API url 66 | * @param string $language 67 | * @param string $api_version https://developer.foursquare.com/overview/versioning 68 | */ 69 | public function __construct($client_id = false,$client_secret = false, $redirect_uri='', $version='v2', $language='en', $api_version=DEFAULT_VERSION){ 70 | $this->BaseUrl = "{$this->BaseUrl}$version/"; 71 | $this->ClientID = $client_id; 72 | $this->ClientSecret = $client_secret; 73 | $this->ClientLanguage = $language; 74 | $this->RedirectUri = $redirect_uri; 75 | $this->Version = $api_version; 76 | } 77 | 78 | public function setRedirectUri( $uri ) { 79 | $this->RedirectUri = $uri; 80 | } 81 | 82 | // Request functions 83 | 84 | /** 85 | * GetPublic 86 | * Performs a request for a public resource 87 | * @param String $endpoint A particular endpoint of the Foursquare API 88 | * @param Array $params A set of parameters to be appended to the request, defaults to false (none) 89 | */ 90 | public function GetPublic($endpoint,$params=false){ 91 | // Build the endpoint URL 92 | $url = $this->BaseUrl . trim($endpoint,"/"); 93 | // Append the client details 94 | $params['client_id'] = $this->ClientID; 95 | $params['client_secret'] = $this->ClientSecret; 96 | $params['v'] = $this->Version; 97 | $params['locale'] = $this->ClientLanguage; 98 | // Return the result; 99 | return $this->GET($url,$params); 100 | } 101 | 102 | /** 103 | * GetPrivate 104 | * Performs a request for a private resource 105 | * @param String $endpoint A particular endpoint of the Foursquare API 106 | * @param Array $params A set of parameters to be appended to the request, defaults to false (none) 107 | * @param bool $POST whether or not to use a POST request 108 | */ 109 | public function GetPrivate($endpoint,$params=false,$POST=false){ 110 | $url = $this->BaseUrl . trim($endpoint,"/"); 111 | $params['oauth_token'] = $this->AuthToken; 112 | $params['v'] = $this->Version; 113 | $params['locale'] = $this->ClientLanguage; 114 | if(!$POST) return $this->GET($url,$params); 115 | else return $this->POST($url,$params); 116 | } 117 | 118 | /** 119 | * GetMulti 120 | * Performs a request for up to 5 private or public resources 121 | * @param Array $requests An array of arrays containing the endpoint and a set of parameters 122 | * to be appended to the request, defaults to false (none) 123 | * @param bool $POST whether or not to use a POST request, e.g. for large request bodies. 124 | * It does not allow you to call endpoints that mutate data. 125 | */ 126 | public function GetMulti($requests=false,$POST=false){ 127 | $url = $this->BaseUrl . "multi"; 128 | $params = array(); 129 | $params['oauth_token'] = $this->AuthToken; 130 | $params['v'] = $this->Version; 131 | if (is_array($requests)){ 132 | $request_queries = array(); 133 | foreach($requests as $request) { 134 | $endpoint = $request['endpoint']; 135 | unset($request['endpoint']); 136 | $query = '/' . $endpoint; 137 | if (!empty($request)) $query .= '?' . http_build_query($request); 138 | $request_queries[] = $query; 139 | } 140 | $params['requests'] = implode(',', $request_queries); 141 | } 142 | if(!$POST) return $this->GET($url,$params); 143 | else return $this->POST($url,$params); 144 | } 145 | 146 | public function getResponseFromJsonString($json) { 147 | $json = json_decode( $json ); 148 | if ( !isset( $json->response ) ) { 149 | throw new FoursquareApiException( 'Invalid response' ); 150 | } 151 | 152 | // Better to check status code and fail gracefully, but not worried about it 153 | // ... REALLY, we should be checking the HTTP status code as well, not 154 | // just what the API gives us in it's microformat 155 | /* 156 | if ( !isset( $json->meta->code ) || 200 !== $json->meta->code ) { 157 | throw new FoursquareApiException( 'Invalid response' ); 158 | } 159 | */ 160 | return $json->response; 161 | } 162 | 163 | /** 164 | * Request 165 | * Performs a cUrl request with a url generated by MakeUrl. The useragent of the request is hardcoded 166 | * as the Google Chrome Browser agent 167 | * @param String $url The base url to query 168 | * @param Array $params The parameters to pass to the request 169 | */ 170 | private function Request($url, $params=false, $type=HTTP_GET){ 171 | 172 | // Populate data for the GET request 173 | if($type == HTTP_GET) $url = $this->MakeUrl($url,$params); 174 | 175 | $this->LastUrl = $url; 176 | 177 | // Reset the headers every time we initiate a new request 178 | $this->ResponseHeaders = array(); 179 | 180 | // borrowed from Andy Langton: http://andylangton.co.uk/ 181 | $ch = curl_init(); 182 | curl_setopt($ch, CURLOPT_URL,$url); 183 | curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); 184 | if ( isset($_SERVER['HTTP_USER_AGENT']) ) { 185 | curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT'] ); 186 | } else { 187 | // Handle the useragent like we are Google Chrome 188 | 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.'); 189 | } 190 | curl_setopt($ch, CURLOPT_TIMEOUT, 30); 191 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); 192 | $acceptLanguage[] = "Accept-Language:" . $this->ClientLanguage; 193 | curl_setopt($ch, CURLOPT_HTTPHEADER, $acceptLanguage); 194 | // Set the header callback 195 | curl_setopt($ch, CURLOPT_HEADERFUNCTION, array($this, 'ParseHeaders')); 196 | // Populate the data for POST 197 | if($type == HTTP_POST) { 198 | curl_setopt($ch, CURLOPT_POST, 1); 199 | if($params) curl_setopt($ch, CURLOPT_POSTFIELDS, $params); 200 | } 201 | 202 | $result=curl_exec($ch); 203 | $info=curl_getinfo($ch); 204 | curl_close($ch); 205 | 206 | return $result; 207 | } 208 | 209 | /** 210 | * Callback function to handle header strings as they are returned by cUrl in the $this->Request() function 211 | * Parses header strings into key/value pairs and stores them in $ResponseHeaders array 212 | * 213 | * @param $ch 214 | * @param $header 215 | * @return int 216 | */ 217 | private function ParseHeaders($ch, $header) { 218 | if (strpos($header, ':') !== false) { 219 | $header_split = explode(':', $header); 220 | $this->ResponseHeaders[strtolower(trim($header_split[0]))] = trim($header_split[1]); 221 | } 222 | return strlen($header); 223 | } 224 | 225 | /** 226 | * GET 227 | * Abstraction of the GET request 228 | */ 229 | private function GET($url,$params=false){ 230 | return $this->Request($url,$params,HTTP_GET); 231 | } 232 | 233 | /** 234 | * POST 235 | * Abstraction of a POST request 236 | */ 237 | private function POST($url,$params=false){ 238 | return $this->Request($url,$params,HTTP_POST); 239 | } 240 | 241 | 242 | // Helper Functions 243 | 244 | /** 245 | * GeoLocate 246 | * Leverages the google maps api to generate a lat/lng pair for a given address 247 | * packaged with FoursquareApi to facilitate locality searches. 248 | * @param String $addr An address string accepted by the google maps api 249 | * @return array(lat, lng) || NULL 250 | */ 251 | public function GeoLocate($addr, $geoapi_key){ 252 | $geoapi = "https://maps.googleapis.com/maps/api/geocode/json"; 253 | $params = array("address"=>$addr,"sensor"=>"false","key"=>$geoapi_key); 254 | $response = $this->GET($geoapi,$params); 255 | $json = json_decode($response); 256 | if ($json->status === "ZERO_RESULTS") { 257 | return null; 258 | } else { 259 | return array($json->results[0]->geometry->location->lat,$json->results[0]->geometry->location->lng); 260 | } 261 | } 262 | 263 | /** 264 | * MakeUrl 265 | * Takes a base url and an array of parameters and sanitizes the data, then creates a complete 266 | * url with each parameter as a GET parameter in the URL 267 | * @param String $url The base URL to append the query string to (without any query data) 268 | * @param Array $params The parameters to pass to the URL 269 | */ 270 | private function MakeUrl($url,$params){ 271 | return trim($url) . '?' . http_build_query($params); 272 | } 273 | 274 | // Access token functions 275 | 276 | /** 277 | * SetAccessToken 278 | * Basic setter function, provides an authentication token to GetPrivate requests 279 | * @param String $token A Foursquare user auth_token 280 | */ 281 | public function SetAccessToken($token){ 282 | $this->AuthToken = $token; 283 | } 284 | 285 | /** 286 | * AuthenticationLink 287 | * Returns a link to the Foursquare web authentication page. 288 | * @param String $redirect The configured redirect_uri for the provided client credentials 289 | */ 290 | public function AuthenticationLink($redirect=''){ 291 | if ( 0 === strlen( $redirect ) ) { 292 | $redirect = $this->RedirectUri; 293 | } 294 | $params = array("client_id"=>$this->ClientID,"response_type"=>"code","redirect_uri"=>$redirect); 295 | return $this->MakeUrl($this->AuthUrl,$params); 296 | } 297 | 298 | /** 299 | * AuthorizeLink 300 | * Returns a link to the Foursquare web authentication page. Using /authorize will ask the user to 301 | * re-authenticate their identity and reauthorize your app while giving the user the option to 302 | * login under a different account. 303 | * @param String $redirect The configured redirect_uri for the provided client credentials 304 | */ 305 | public function AuthorizeLink($redirect=''){ 306 | if ( 0 === strlen( $redirect ) ) { 307 | $redirect = $this->RedirectUri; 308 | } 309 | $params = array("client_id"=>$this->ClientID,"response_type"=>"code","redirect_uri"=>$redirect); 310 | return $this->MakeUrl($this->AuthorizeUrl,$params); 311 | } 312 | 313 | /** 314 | * GetToken 315 | * Performs a request to Foursquare for a user token, and returns the token, while also storing it 316 | * locally for use in private requests 317 | * @param $code The 'code' parameter provided by the Foursquare webauth callback redirect 318 | * @param $redirect The configured redirect_uri for the provided client credentials 319 | */ 320 | public function GetToken($code,$redirect=''){ 321 | if ( 0 === strlen( $redirect ) ) { 322 | // If we have to use the same URI to request a token as we did for 323 | // the authorization link, why are we not storing it internally? 324 | $redirect = $this->RedirectUri; 325 | } 326 | $params = array("client_id"=>$this->ClientID, 327 | "client_secret"=>$this->ClientSecret, 328 | "grant_type"=>"authorization_code", 329 | "redirect_uri"=>$redirect, 330 | "code"=>$code); 331 | $result = $this->GET($this->TokenUrl,$params); 332 | $json = json_decode($result); 333 | 334 | // Petr Babicka Check if we get token 335 | if (property_exists($json, 'access_token')) { 336 | $this->SetAccessToken($json->access_token); 337 | return $json->access_token; 338 | } 339 | else { 340 | return 0; 341 | } 342 | } 343 | } 344 | -------------------------------------------------------------------------------- /tests/FoursquareApiTest.php: -------------------------------------------------------------------------------- 1 | assertFalse(CLIENT_ID == false, "Must set the FOURSQUARE_CLIENT_ID environment variable to run public tests"); 11 | $this->assertFalse(CLIENT_SECRET == false, "Must set the FOURSQUARE_CLIENT_SECRET environment variable to run public tests"); 12 | } 13 | 14 | public function testPrivateEnvironment(){ 15 | $this->assertFalse(TOKEN == false, "Must set the FOURSQUARE_TOKEN environment variable to run private tests"); 16 | } 17 | 18 | public function testPublicEndpoint(){ 19 | $foursquare = new FoursquareAPI(CLIENT_ID, CLIENT_SECRET); 20 | $venues = json_decode($foursquare->GetPublic('venues/search', array('near'=>'Montreal, QC'))); 21 | 22 | // Ensure we get a success response 23 | $this->assertLessThan(400, $venues->meta->code, $venues->meta->errorDetail); 24 | } 25 | 26 | public function testLanguageSupport(){ 27 | $foursquare = new FoursquareAPI(CLIENT_ID, CLIENT_SECRET, '', 'v2', 'fr'); 28 | $categories = json_decode($foursquare->GetPublic('venues/categories')); 29 | 30 | foreach($categories->response->categories as $category){ 31 | if($category->id == '4d4b7104d754a06370d81259'){ 32 | $this->assertEquals($category->name, 'Culture et loisirs', "Locale failed or \"{$category->name}\" is a new translation"); 33 | $run = true; 34 | break; 35 | } 36 | } 37 | 38 | $this->assertEquals($run, true, 'Test category no longer exists in fr locale, update test.'); 39 | // Ensure we get a success response 40 | $this->assertLessThan(400, $venues->meta->code, $venues->meta->errorDetail); 41 | } 42 | 43 | public function testPrivateEndpoint(){ 44 | 45 | // Load the API and set the token 46 | $foursquare = new FoursquareAPI(CLIENT_ID, CLIENT_SECRET); 47 | $foursquare->SetAccessToken(TOKEN); 48 | 49 | // Load response & convert to Stdclass object 50 | $venues = json_decode($foursquare->GetPrivate('users/self')); 51 | 52 | // Ensure we get a success response 53 | $this->assertLessThan(400, $venues->meta->code, $venues->meta->errorDetail); 54 | } 55 | 56 | public function testCheckin(){ 57 | 58 | $foursquare = new FoursquareAPI(CLIENT_ID, CLIENT_SECRET); 59 | $foursquare->SetAccessToken(TOKEN); 60 | 61 | // Checks the acting user in at Aux Vivres in Montreal, Canada 62 | $response = json_decode($foursquare->GetPrivate("checkins/add", array("venueId"=>"4ad4c06bf964a5207ff920e3"), $POST=true)); 63 | 64 | $this->assertLessThan(400, $response->meta->code, $response->meta->errorDetail); 65 | } 66 | } 67 | --------------------------------------------------------------------------------