function api_privatesquare_venues_checkin()
{
    $venue_id = post_str("venue_id");
    $status_id = post_int32("status_id");
    if (!$venue_id) {
        api_output_error(999, "Missing venue ID");
    }
    if (!isset($status_id)) {
        api_output_error(999, "Missing status ID");
    }
    $fsq_user = foursquare_users_get_by_user_id($GLOBALS['cfg']['user']['id']);
    $checkin = array('user_id' => $GLOBALS['cfg']['user']['id'], 'venue_id' => $venue_id, 'status_id' => $status_id);
    # where am I?
    $venue = foursquare_venues_get_by_venue_id($venue_id);
    if (!$venue) {
        $rsp = foursquare_venues_archive_venue($venue_id);
        if ($rsp['ok']) {
            $venue = $rsp['venue'];
        }
    }
    if ($venue) {
        $checkin['locality'] = $venue['locality'];
        $checkin['latitude'] = $venue['latitude'];
        $checkin['longitude'] = $venue['longitude'];
    }
    # check to see if we're checking in to 4sq too
    if ($broadcast = post_str("broadcast")) {
        $method = 'checkins/add';
        $args = array('oauth_token' => $fsq_user['oauth_token'], 'venueId' => $venue_id, 'broadcast' => $broadcast);
        $more = array('method' => 'POST');
        $rsp = foursquare_api_call($method, $args, $more);
        if ($rsp['ok']) {
            $checkin['checkin_id'] = $rsp['rsp']['checkin']['id'];
        }
        # on error, then what?
    }
    if ($GLOBALS['cfg']['enable_feature_weather_tracking']) {
        loadlib("weather_google");
        $rsp = weather_google_conditions($checkin['latitude'], $checkin['longitude']);
        if ($rsp['ok']) {
            $conditions = $rsp['conditions'];
            $conditions['source'] = $rsp['source'];
            $checkin['weather'] = json_encode($conditions);
        }
    }
    $rsp = privatesquare_checkins_create($checkin);
    if (!$rsp['ok']) {
        api_output_error(999, "Check in failed");
    }
    $out = array('checkin' => $rsp['checkin']);
    api_output_ok($out);
}
function foursquare_venues_archive_venue($venue_id)
{
    loadlib("foursquare_users");
    loadlib("foursquare_api");
    loadlib("reverse_geoplanet");
    $fsq_user = foursquare_users_random_user();
    $method = "venues/{$venue_id}";
    $args = array('oauth_token' => $fsq_user['oauth_token']);
    $rsp = foursquare_api_call($method, $args);
    if (!$rsp['ok']) {
        return $rsp;
    }
    $data = $rsp['rsp']['venue'];
    $lat = $data['location']['lat'];
    $lon = $data['location']['lng'];
    $venue = array('venue_id' => $data['id'], 'name' => $data['name'], 'latitude' => $lat, 'longitude' => $lon, 'data' => json_encode($data));
    # might be better/easier to geocode string place names (20120121/straup)
    $geo_rsp = reverse_geoplanet($lat, $lon, $GLOBALS['cfg']['reverse_geoplanet_remote_endpoint']);
    if ($geo_rsp['ok']) {
        $venue['locality'] = $geo_rsp['data']['locality'];
    }
    return foursquare_venues_add_venue($venue);
}
if (!$rsp['ok']) {
    $GLOBALS['error']['oauth_access_token'] = 1;
    $GLOBALS['smarty']->display("page_auth_callback_foursquare_oauth.txt");
    exit;
}
$oauth_token = $rsp['oauth_token'];
$foursquare_user = foursquare_users_get_by_oauth_token($oauth_token);
if ($foursquare_user && ($user_id = $foursquare_user['user_id'])) {
    $user = users_get_by_id($user_id);
} else {
    if (!$GLOBALS['cfg']['enable_feature_signup']) {
        $GLOBALS['smarty']->display("page_signup_disabled.txt");
        exit;
    } else {
        $args = array('oauth_token' => $oauth_token);
        $rsp = foursquare_api_call('users/self', $args);
        if (!$rsp['ok']) {
            $GLOBALS['error']['foursquare_userinfo'] = 1;
            $GLOBALS['smarty']->display("page_auth_callback_foursquare_oauth.txt");
            exit;
        }
        $foursquare_id = $rsp['rsp']['user']['id'];
        $username = $rsp['rsp']['user']['firstName'];
        $email = $rsp['rsp']['user']['contact']['email'];
        if (!$email) {
            $email = "{$foursquare_id}@donotsend-foursquare.com";
        }
        if (isset($rsp['rsp']['user']['lastName'])) {
            $username .= " {$rsp['rsp']['user']['lastName']}";
        }
        $password = random_string(32);
function api_foursquare_venues_search()
{
    $lat = request_float('latitude');
    $lon = request_float('longitude');
    $alt = request_float('altitude');
    $query = request_str('query');
    # See this? It's a quick and dirty shim until I can figure
    # out how to pass 'sort' flags via the UI (20120201/straup)
    # $sort = request_float('sort');
    $sort = $GLOBALS['cfg']['foursquare_venues_sort'];
    $sort_func = "_api_foursquare_venues_sort_by_name";
    if ($sort == 'distance') {
        $sort_func = "_api_foursquare_venues_sort_by_distance";
    }
    if (!$lat || !geo_utils_is_valid_latitude($lat)) {
        api_output_error(999, "Missing or invalid latitude");
    }
    if (!$lat || !geo_utils_is_valid_longitude($lon)) {
        api_output_error(999, "Missing or invalid longitude");
    }
    $checkin_crumb = crumb_generate("api", "privatesquare.venues.checkin");
    $fsq_user = foursquare_users_get_by_user_id($GLOBALS['cfg']['user']['id']);
    $method = 'venues/search';
    if ($query) {
        $args = array('oauth_token' => $fsq_user['oauth_token'], 'll' => "{$lat},{$lon}", 'radius' => 1200, 'limit' => 30, 'intent' => 'match', 'query' => $query);
        $rsp = foursquare_api_call($method, $args);
        if (!$rsp['ok']) {
            _api_foursquare_error($rsp);
        }
        $venues = $rsp['rsp']['venues'];
        usort($venues, $sort_func);
        $out = array('venues' => $venues, 'query' => $query, 'latitude' => $lat, 'longitude' => $lon, 'crumb' => $checkin_crumb);
        api_output_ok($out);
    }
    $random_user = foursquare_users_random_user();
    if (!$random_user) {
        $random_user = $fsq_user;
    }
    # https://developer.foursquare.com/docs/venues/search
    # TO DO: api_call_multi
    # first get stuff scoped to the current user
    $args = array('oauth_token' => $fsq_user['oauth_token'], 'll' => "{$lat},{$lon}", 'limit' => 30, 'intent' => 'checkin');
    $rsp = foursquare_api_call($method, $args);
    if (!$rsp['ok']) {
        _api_foursquare_error($rsp);
    }
    $venues = array();
    $seen = array();
    foreach ($rsp['rsp']['venues'] as $v) {
        $venues[] = $v;
        $seen[] = $v['id'];
    }
    # now just get whatever
    $args = array('oauth_token' => $random_user['oauth_token'], 'll' => "{$lat},{$lon}", 'limit' => 30, 'radius' => 800, 'intent' => 'browse');
    $rsp = foursquare_api_call($method, $args);
    if (!$rsp['ok']) {
        _api_foursquare_error($rsp);
    }
    foreach ($rsp['rsp']['venues'] as $v) {
        if (!in_array($v['id'], $seen)) {
            $venues[] = $v;
        }
    }
    usort($venues, $sort_func);
    # go!
    $out = array('venues' => $venues, 'latitude' => $lat, 'longitude' => $lon, 'crumb' => $checkin_crumb);
    api_output_ok($out);
}
function sync_user($fsq_user, $more = array())
{
    $user = users_get_by_id($fsq_user['user_id']);
    if (!$user['sync_foursquare']) {
        echo "'{$user['username']}' has not opted in to foursquare syncing, skipping...\n";
        return;
    }
    echo "sync checkins for '{$user['username']}' : {$user['sync_foursquare']}\n";
    $status_map = privatesquare_checkins_status_map("string keys");
    $method = 'users/self/checkins';
    $count = null;
    $offset = 0;
    $limit = 250;
    while (!isset($count) || $offset < $count) {
        $args = array('oauth_token' => $fsq_user['oauth_token'], 'limit' => $limit, 'offset' => $offset);
        # only sync updates since the user signed up for privatesquare
        # > 1 (or "2") would mean pull in all a users' checkins.
        # see also: account_foursquare_sync.php
        if ($user['sync_foursquare'] == 1) {
            $args['afterTimestamp'] = $user['created'];
        }
        $rsp = foursquare_api_call($method, $args);
        if (!isset($count)) {
            $count = $rsp['rsp']['checkins']['count'];
        }
        $count_items = count($rsp['rsp']['checkins']['items']);
        # As of 20120218 if you pass a date filter to the API it
        # still returns the count for the total number of checkins
        # without the date filter. I love that... (20120218/straup)
        if (!$count_items) {
            break;
        }
        foreach ($rsp['rsp']['checkins']['items'] as $fsq_checkin) {
            if (privatesquare_checkins_get_by_foursquare_id($user, $fsq_checkin['id'])) {
                continue;
            }
            $checkin = array('user_id' => $user['id'], 'checkin_id' => $fsq_checkin['id'], 'venue_id' => $fsq_checkin['venue']['id'], 'created' => $fsq_checkin['createdAt'], 'status_id' => $status_map['i am here'], 'latitude' => $fsq_checkin['location']['lat'], 'longitude' => $fsq_checkin['location']['lng']);
            $venue = foursquare_venues_get_by_venue_id($checkin['venue_id']);
            if (!$venue) {
                $rsp = foursquare_venues_archive_venue($checkin['venue_id']);
                if (!$rsp['ok']) {
                    echo "failed to archive venue '{$checkin['venue_id']}' : {$rsp['error']}\n";
                    echo "skipping...\n";
                    continue;
                }
                $venue = $rsp['venue'];
            }
            if ($venue) {
                $checkin['locality'] = $venue['locality'];
                $checkin['latitude'] = $venue['latitude'];
                $checkin['longitude'] = $venue['longitude'];
            }
            $rsp = privatesquare_checkins_create($checkin);
            if (!$rsp['ok']) {
                echo "failed to archive checkin: {$rsp['error']}\n";
                continue;
            }
            echo "archived 4sq checkin {$checkin['checkin_id']} with privatesquare ID: {$rsp['checkin']['id']}\n";
        }
        # do stuff here...
        $offset += $limit;
    }
}