1

My question seems pretty complicated to me (maybe not to you guys) so I will try to explain as best as I can. I am building an "app" (not a native app, an HTML based app) to run on iPad kiosks at various venues to allow people to check in on Foursquare. This means the lat/long is already known (fixed locations coming from a list). I already have this working with Facebook, but Foursquare is being a pain.

I've tried a ton of different solutions, tutorials, and libraries (including the Epi-async library) and the best one I have found is this: http://blog.jambura.com/2011/07/23/implementing-foursquare-api-with-ease/. This is what my code is based off of.

With that said, my apps flow goes like this:

  1. User starts at index.php
  2. User touches button to "Check in to Foursquare!"
  3. User is routed to login screen, and then to the Allow screen to allow access to the app.
  4. User is checked in using information coming from the included file.
  5. User is directed back to the app, where a secret word is displayed that they can tell the cashier for a discount (obviously I understand that both Facebook and Foursquare offer check in deals that are "built-in", but for the sake of this question just pretend that this makes sense to you. :P)
  6. After the word is displayed, user is automatically logged out, the session is destroyed, and the app moves back to index.php to let the next person check in. (I have no clue how to log out of Foursquare via the API yet, I figured I would cross that bridge when I got to it. I'm hoping that session_destroy(); is enough!)

Now, it's important to note here that with Facebook, you can do everything via PHP and don't need to use CURL at all. This allows me to pass a GET variable called $loc_id so that I have a persistent means to remember which location the person is at, and this allows me to pull any "check in text" (for Foursquare it's the "shout") as well as any lat/long I might need, etc.

With Foursquare, I am trying to set the $loc_id to a session variable, since I have to use POST and can't carry any URL-based variables between my app and Foursquare (like I can with Facebook).

Unfortunately, I can only get Foursquare check ins to work halfway. Let me show you the code I am using (please excuse my formatting, still trying to get the hang of this crazy system):

  1. index.php: <a href="checkin-foursquare.php?loc_id=<?php echo $loc_id; ?>"> <-- This is what starts the process

  2. fs_conn.php:

    <?PHP
    
    // $_SESSION["loc_id"] = $_GET["loc_id"]; I removed this because I wasn't sure if it was unsetting itself all the time
    
    $callback_url="https://www.mydomain.com/path/to/app/callback-foursquare.php";
    
    $client_id="xxx";
    $client_secret="yyy";
    
    $authorize_url="https://foursquare.com/oauth2/authorize?client_id={$client_id}&response_type=code&redirect_uri={$callback_url}";
    
    $access_token_url="https://foursquare.com/oauth2/access_token?post_checkins=post_checkins&client_id={$client_id}&client_secret={$client_secret}&grant_type=authorization_code&redirect_uri={$callback_url}&code=";
    
    ?>
    
  3. checkin-foursquare.php:

    <?php 
    
    include_once 'inc/locations.php'; // this is where my location info is stored
    include_once 'inc/fs_conn.php'; // these are the keys/urls
    
    session_start();
    
    $_SESSION["loc_id"] = $_GET["loc_id"];
    
     $code = $_REQUEST["code"];
    
    if(empty($code)) {
        $_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection
        $dialog_url = "https://foursquare.com/oauth2/authenticate?client_id=" . $client_id . "&redirect_uri=" . urlencode($authorize_url) . "&display=touch&response_type=code";
        echo("<script> top.location.href='" . $dialog_url . "'</script>");
    } else {
    
        if($_GET['post_checkins']=='post_checkins')
        {
        $url = 'https://api.foursquare.com/v2/checkins/add';
        $fields = array(
                'venueId'=> $venue_id,
                'venue'=> $venue_name,
                'shout'=> $shout,
                'broadcast'=>'public',
                'll'=> $loc_lat . "," . $loc_long,
                'oauth_token'=> $_SESSION['access_token']
            );
        foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
        rtrim($fields_string,'&');
    
        $ch = curl_init();
        curl_setopt($ch,CURLOPT_URL,$url);
        curl_setopt($ch,CURLOPT_POST,count($fields));
        curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);    
        curl_exec($ch);
        curl_close($ch);
        header('Location: word-foursquare.php?loc_id=' . $_SESSION["$loc_id"] ); // this displays the secret word
        exit;
        }
        }
          ?>
    
  4. callback-foursquare.php:

    <?php // this is what gets redirected from Foursquare and is listed in the "callback" field
    
    include('inc/fs_conn.php'); // keys/urls again
    
    $access_token_url=$access_token_url.$_GET['code'];
    $access_token=json_decode(file_get_contents("{$access_token_url}"),true);   
    $_SESSION['access_token']=$access_token['access_token'];
    header('Location: checkin-foursquare.php?loc_id=' . $_SESSION["loc_id"] . '&post_checkins=post_checkins');
    exit;
    ?>
    

So basically it goes index.php -> checkin-foursquare.php -> foursquare.com -> callback-foursquare.php -> back to checkin-foursquare.php to actually do the checkin -> word-foursquare.php

Does this look correct?

If I go to 'https://www.mydomain.com/path/to/app/checkin-foursquare.php?loc_id=SOME-CITY-HERE' it correctly loads the login page. When I log in, it correctly brings up the "Connect your foursquare account with:" screen. However, once I get to this point, clicking the "Allow" button points me back to foursquare-checkin.php and then brings up the same "Connect your foursquare account with:" screen up, over and over. I feel like I am missing some token or something, like Foursquare isn't authorizing correctly (like I'm not supplying it with the correct token?), but I have no clue what's wrong. :(

I do notice that at the end of the looped URL there has been 'error=redirect_uri_mismatch' appended. However the callback URL in my Foursquare settings is the same as the $callback_url in fs_conn.php... so I'm not sure what's wrong with the redirect URI..?

I tried looking at this but it didn't help much, it looks like what I am doing but with the code split up differently (e.g. I don't need popup windows): Connecting with FourSquare API V2 using PHP

I do know that I only have half of the CSRF protection in there, but I'm not sure how to properly implement it with Foursquare. Is this what's causing me to get stuck in a loop? :(

Anyways, I'm sorry this is so long, and I'm forever grateful to anyone who has read this far. I've read so many pages here on SO that's it's all starting to blur together. I've been using this site for years and this is the first time I've never been able to figure something out on my own. Failure. :(

Community
  • 1
  • 1
Kane Ford
  • 426
  • 6
  • 12
  • Also, I know I don't have it set to advance to word-foursquare.php... trying to get this login/checkin stuff sorted out first. Facebook was so easy! Foursquare... not so much. :\ – Kane Ford Feb 25 '12 at 13:08

1 Answers1

2

While not officially supported, there are a number of community contributed libraries for the foursquare API. If you're using PHP to access the API, you should consider using one of the listed PHP libraries: https://developer.foursquare.com/resources/libraries

akdotcom
  • 4,627
  • 2
  • 17
  • 16