-
Notifications
You must be signed in to change notification settings - Fork 0
/
apinearby.php
156 lines (135 loc) · 5.75 KB
/
apinearby.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
<?php
# https://github.com/jakesankey/PHP-RestServer-Class/blob/master/RestServer.php
require_once('RestServer.php');
class WFS_Nearby
{
/**
* method to return $how_many venues with the highest number of foursquare checkins
*
* grabs json from foursquare and performs aggregations on the results in mongodb
* presents nicely sorted (by foursquare checkins) json array to the calling application
* and only includes a few important details of the original response
*
* creates a temporary aggregation table with temp_id = date('U')
*
* table is erased immediately after aggregation is performed
* if $KEEP_NEARBY_QUERY is set to false
*
* @param $lat
* @param $lng
* @param $howmany
* @param $restrict boolean restricts foursquare categories to businesses excluding landmarks
* @param $radius int in metres
*
* @return array
*
*/
public function nearby($lat, $lng, $howmany, $restrict, $radius)
{
# setup & initialize foursquare api and mongodb connections
$foursquare = $venues_db = $nearby_venues = $wfs = null;
require_once('mongo_setup_venues.php');
require_once('foursquare_setup.php');
# for demonstration purposes we will keep these queries in the database
$KEEP_NEARBY_QUERY = true;
# access collection for temporary documents
# TODO leverage to save foursquare api calls
$nearby_venues = $wfs->selectCollection('nearby');
# add or omit category restrictions to shopping type locations
if (strcasecmp($restrict, 'true') == 0)
{
# prepare foursquare categories
$category_array = array(
/* food */ '4d4b7105d754a06374d81259',
/* arts */ '4d4b7104d754a06370d81259',
/* bars */ '4d4b7105d754a06376d81259',
/* shopping */ '4d4b7105d754a06378d81259',
/* travel */ '4d4b7105d754a06379d81259');
#create a csv string as per the foursquare api requirements
$categories = implode(',', $category_array);
#prepare default params with categories selected
$params = array('ll' => "$lat, $lng",
'radius' => $radius,
'categories' => $categories);
}
else
{
# prepare default params without categories selected
$params = array('ll' => "$lat, $lng", 'radius' => $radius);
}
# Perform a request to a public resource
$response = $foursquare->GetPublic("venues/search",$params);
$venues = json_decode($response);
# unique timestamp to label temporary document or 'table' so it can be erased
$temp_id = date('U');
# prep mongo db document
$nearby_venues->insert(array('temp_id' => $temp_id, 'venues' => array() ));
# push relevant venue details to temporary document
foreach ($venues->response->venues as $v)
{
$insert_array =array();
$insert_array['id'] = $v->id;
$insert_array['name'] = $v->name;
$insert_array['distance'] = $v->location->distance;
$insert_array['checkins'] = $v->stats->checkinsCount;
$insert_array['lat'] = $v->location->lat;
$insert_array['lng'] = $v->location->lng;
try
{
$nearby_venues->update(array('temp_id' => $temp_id),
array('$push' => array('venues' => $insert_array )));
}
catch (MongoCursorException $e)
{
return array('response' => 'fail', 'reason' => $e->getMessage());
}
catch (MongoException $e)
{
return array('response' => 'fail', 'reason' => 'other database error');
}
}
try
{
/*
AGGREGATION PIPELINE
$unwind: used to access nested array 'venues'
$match: restrict to the current temp_id just in case more exist
$sort: -1 used for descending order sort of venues[checkins]
$limit: returns only however many the function is asked for ($how_many)
$project: create projection of 'columns' to exclude (0) mongodb _id
and include (1) the venues array
*/
$agg_array = array( array('$unwind' => '$venues'),
array('$match' => array('temp_id' => $temp_id)),
array('$sort' => array('venues.checkins' =>-1 )),
array('$limit' => (int) $howmany),
array('$project' =>
array('_id' => 0,
'venues' => 1)));
# perform the aggregation
$aggregate = $nearby_venues->aggregate( $agg_array );
# attempt to delete the temporary document (no big deal if it fails)
if (!$KEEP_NEARBY_QUERY)
{
try
{
$nearby_venues->remove(array('temp_id' => $temp_id));
}
catch (MongoCursorException $e)
{
# nop
}
}
# return the aggregation as the value for key 'top_venues'
return array('response' => 'ok', 'top_venues' => $aggregate);
}
catch(MongoCursorException $e)
{
return array('response' => 'fail', 'reason' => 'aggregation');
}
}
}
######################MAIN
$rest = new RestServer();
$rest->addServiceClass('WFS_Nearby');
$rest->handle();