Subversion Repositories instagram

[/] [classes/] [Instagram.php] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ffruehstueck
<?php
2
/**
3
 * Instagram PHP implementation API
4
 * URLs: http://www.mauriciocuenca.com/
5
 *
6
 * This program is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18
 */
19
// require_once 'Zend/Http/Client.php';
20
require_once 'CurlHttpClient.php';
21
 
22
class Instagram {
23
 
24
    /**
25
     * The name of the GET param that holds the authentication code
26
     * @var string
27
     */
28
    const RESPONSE_CODE_PARAM = 'code';
29
 
30
    /**
31
     * Format for endpoint URL requests
32
     * @var string
33
     */
34
    protected $_endpointUrls = array(
35
        'authorize' => 'https://api.instagram.com/oauth/authorize/?client_id=%s&redirect_uri=%s&response_type=%s&scope=likes+comments',
36
        'access_token' => 'https://api.instagram.com/oauth/access_token',
37
        'user' => 'https://api.instagram.com/v1/users/%d/?access_token=%s',
38
        'user_feed' => 'https://api.instagram.com/v1/users/self/feed?access_token=%s&max_id=%d&min_id=%d',
39
        'user_recent' => 'https://api.instagram.com/v1/users/%d/media/recent/?access_token=%s&max_id=%s&min_id=%s&max_timestamp=%s&min_timestamp=%s',
40
        'user_search' => 'https://api.instagram.com/v1/users/search?q=%s&access_token=%s',
41
        'user_follows' => 'https://api.instagram.com/v1/users/%d/follows?access_token=%s',
42
        'user_followed_by' => 'https://api.instagram.com/v1/users/%d/followed-by?access_token=%s',
43
        'user_requested_by' => 'https://api.instagram.com/v1/users/self/requested-by?access_token=%s',
44
        'user_relationship' => 'https://api.instagram.com/v1/users/%d/relationship?access_token=%s',
45
        'modify_user_relationship' => 'https://api.instagram.com/v1/users/%d/relationship?action=%s&access_token=%s',
46
        'media' => 'https://api.instagram.com/v1/media/%d?access_token=%s',
47
        'media_search' => 'https://api.instagram.com/v1/media/search?lat=%s&lng=%s&max_timestamp=%d&min_timestamp=%d&distance=%d&access_token=%s',
48
        'media_popular' => 'https://api.instagram.com/v1/media/popular?access_token=%s',
49
        'media_comments' => 'https://api.instagram.com/v1/media/%d/comments?access_token=%s',
50
        'post_media_comment' => 'https://api.instagram.com/v1/media/%s/comments?access_token=%s',
51
        'delete_media_comment' => 'https://api.instagram.com/v1/media/%d/comments?comment_id=%d&access_token=%s',
52
        'likes' => 'https://api.instagram.com/v1/media/%d/likes?access_token=%s',
53
        'post_like' => 'https://api.instagram.com/v1/media/%d/likes',
54
        'remove_like' => 'https://api.instagram.com/v1/media/%d/likes?access_token=%s',
55
        'tags' => 'https://api.instagram.com/v1/tags/%s?access_token=%s',
56
        'tags_recent' => 'https://api.instagram.com/v1/tags/%s/media/recent?max_id=%d&min_id=%d&access_token=%s',
57
        'tags_search' => 'https://api.instagram.com/v1/tags/search?q=%s&access_token=%s',
58
        'locations' => 'https://api.instagram.com/v1/locations/%d?access_token=%s',
59
        'locations_recent' => 'https://api.instagram.com/v1/locations/%d/media/recent/?max_id=%d&min_id=%d&max_timestamp=%d&min_timestamp=%d&access_token=%s',
60
        'locations_search' => 'https://api.instagram.com/v1/locations/search?lat=%s&lng=%s&foursquare_id=%d&distance=%d&access_token=%s',
61
    );
62
 
63
    /**
64
    * Configuration parameter
65
    */
66
    protected $_config = array();
67
 
68
    /**
69
     * Whether all response are sent as JSON or decoded
70
     */
71
    protected $_arrayResponses = false;
72
 
73
    /**
74
     * OAuth token
75
     * @var string
76
     */
77
    protected $_oauthToken = null;
78
 
79
    /**
80
     * OAuth token
81
     * @var string
82
     */
83
    protected $_accessToken = null;
84
 
85
    /**
86
     * OAuth user object
87
     * @var object
88
     */
89
    protected $_currentUser = null;
90
 
91
    /**
92
     * Holds the HTTP client instance
93
     * @param Zend_Http_Client $httpClient
94
     */
95
    protected $_httpClient = null;
96
 
97
    /**
98
     * Constructor needs to receive the config as an array
99
     * @param mixed $config
100
     */
101
    public function __construct($config = null, $arrayResponses = false) {
102
        $this->_config = $config;
103
        $this->_arrayResponses = $arrayResponses;
104
        if (empty($config)) {
105
            throw new InstagramException('Configuration params are empty or not an array.');
106
        }
107
    }
108
 
109
    /**
110
     * Instantiates the internal HTTP client
111
     * @param string $uri
112
     * @param string $method
113
     */
114
    protected function _initHttpClient($uri, $method = CurlHttpClient::GET, $params = false) {
115
        if ($this->_httpClient == null) {
116
            $this->_httpClient = new CurlHttpClient($uri);
117
        } else {
118
            $this->_httpClient->setUri($uri);
119
        }
120
        $this->_httpClient->setMethod($method);
121
        if( is_array( $params ) )
122
        {
123
                foreach( $params as $key => $value )
124
                {
125
                        $this->_httpClient->setPostParam($key,$value);
126
                }
127
 
128
        }
129
    }
130
 
131
    /**
132
     * Returns the body of the HTTP client response
133
     * @return string
134
     */
135
    protected function _getHttpClientResponse() {
136
        return $this->_httpClient->getResponse();
137
    }
138
 
139
    /**
140
     * Retrieves the authorization code to be used in every request
141
     * @return string. The JSON encoded OAuth token
142
     */
143
    protected function _setOauthToken() {
144
        $this->_initHttpClient($this->_endpointUrls['access_token'], CurlHttpClient::POST);
145
        $this->_httpClient->setPostParam('client_id', $this->_config['client_id']);
146
        $this->_httpClient->setPostParam('client_secret', $this->_config['client_secret']);
147
        $this->_httpClient->setPostParam('grant_type', $this->_config['grant_type']);
148
        $this->_httpClient->setPostParam('redirect_uri', $this->_config['redirect_uri']);
149
        $this->_httpClient->setPostParam('code', $this->getAccessCode());
150
 
151
        $this->_oauthToken = $this->_getHttpClientResponse();
152
    }
153
 
154
    /**
155
     * Return the decoded plain access token value
156
     * from the OAuth JSON encoded token.
157
     * @return string
158
     */
159
    public function getAccessToken() {
160
        if ($this->_accessToken == null) {
161
 
162
            if ($this->_oauthToken == null) {
163
                $this->_setOauthToken();
164
            }
165
 
166
            $this->_accessToken = json_decode($this->_oauthToken)->access_token;
167
        }
168
 
169
        return $this->_accessToken;
170
    }
171
 
172
    /**
173
     * Return the decoded user object
174
     * from the OAuth JSON encoded token
175
     * @return object
176
     */
177
    public function getCurrentUser() {
178
        if ($this->_currentUser == null) {
179
 
180
            if ($this->_oauthToken == null) {
181
                $this->_setOauthToken();
182
            }
183
 
184
            $this->_currentUser = json_decode($this->_oauthToken)->user;
185
        }
186
 
187
        return $this->_currentUser;
188
    }
189
 
190
    /**
191
     * Gets the code param received during the authorization step
192
     */
193
    protected function getAccessCode() {
194
        return $_GET[self::RESPONSE_CODE_PARAM];
195
    }
196
 
197
    /**
198
     * Sets the access token response from OAuth
199
     * @param string $accessToken
200
     */
201
    public function setAccessToken($accessToken) {
202
        $this->_accessToken = $accessToken;
203
    }
204
 
205
    /**
206
     * Surf to Instagram credentials verification page.
207
     * If the user is already authenticated, redirects to
208
     * the URI set in the redirect_uri config param.
209
     * @return string
210
     */
211
    public function openAuthorizationUrl() {
212
        $authorizationUrl = sprintf($this->_endpointUrls['authorize'],
213
            $this->_config['client_id'],
214
            $this->_config['redirect_uri'],
215
            self::RESPONSE_CODE_PARAM);
216
 
217
        header('Location: ' . $authorizationUrl);
218
        eZExecution::cleanExit();
219
    }
220
 
221
    /**
222
      * Get basic information about a user.
223
      * @param $id
224
      */
225
    public function getUser($id) {
226
        $endpointUrl = sprintf($this->_endpointUrls['user'], $id, $this->getAccessToken());
227
        $this->_initHttpClient($endpointUrl);
228
        return $this->_getHttpClientResponse();
229
    }
230
 
231
    /**
232
     * See the authenticated user's feed.
233
     * @param integer $maxId. Return media after this maxId.
234
     * @param integer $minId. Return media before this minId.
235
     */
236
    public function getUserFeed($maxId = null, $minId = null) {
237
        $endpointUrl = sprintf($this->_endpointUrls['user_feed'], $this->getAccessToken(), $maxId, $minId);
238
        $this->_initHttpClient($endpointUrl);
239
        return $this->_getHttpClientResponse();
240
    }
241
 
242
    /**
243
     * Get the most recent media published by a user.
244
     * @param $id. User id
245
     * @param $maxId. Return media after this maxId
246
     * @param $minId. Return media before this minId
247
     * @param $maxTimestamp. Return media before this UNIX timestamp
248
     * @param $minTimestamp. Return media after this UNIX timestamp
249
     */
250
    public function getUserRecent($id, $maxId = '', $minId = '', $maxTimestamp = '', $minTimestamp = '') {
251
        $endpointUrl = sprintf($this->_endpointUrls['user_recent'], $id, $this->getAccessToken(), $maxId, $minId, $maxTimestamp, $minTimestamp);
252
                echo $endpointUrl ."\n";
253
 
254
        $this->_initHttpClient($endpointUrl);
255
        return $this->_getHttpClientResponse();
256
    }
257
 
258
    /**
259
     * Search for a user by name.
260
     * @param string $name. A query string
261
     */
262
    public function searchUser($name) {
263
        $endpointUrl = sprintf($this->_endpointUrls['user_search'], $name, $this->getAccessToken());
264
        $this->_initHttpClient($endpointUrl);
265
        return $this->_getHttpClientResponse();
266
    }
267
 
268
    /**
269
     * Get the list of users this user follows.
270
     * @param integer $id. The user id
271
     */
272
    public function getUserFollows($id) {
273
        $endpointUrl = sprintf($this->_endpointUrls['user_follows'], $id, $this->getAccessToken());
274
        $this->_initHttpClient($endpointUrl);
275
        return $this->_getHttpClientResponse();
276
    }
277
 
278
    /**
279
     * Get the list of users this user is followed by.
280
     * @param integer $id
281
     */
282
    public function getUserFollowedBy($id) {
283
        $endpointUrl = sprintf($this->_endpointUrls['user_followed_by'], $id, $this->getAccessToken());
284
        $this->_initHttpClient($endpointUrl);
285
        return $this->_getHttpClientResponse();
286
    }
287
 
288
    /**
289
     * List the users who have requested this user's permission to follow
290
     */
291
    public function getUserRequestedBy() {
292
        $endpointUrl = sprintf($this->_endpointUrls['user_requested_by'], $this->getAccessToken());
293
        $this->_initHttpClient($endpointUrl);
294
        return $this->_getHttpClientResponse();
295
    }
296
 
297
    /**
298
     * Get information about the current user's relationship (follow/following/etc) to another user.
299
     * @param integer $id
300
     */
301
    public function getUserRelationship($id) {
302
        $endpointUrl = sprintf($this->_endpointUrls['user_relationship'], $id, $this->getAccessToken());
303
        $this->_initHttpClient($endpointUrl);
304
        return $this->_getHttpClientResponse();
305
    }
306
 
307
    /**
308
     * Modify the relationship between the current user and the target user
309
     * In order to perform this action the scope must be set to 'relationships'
310
     * @param integer $id
311
     * @param string $action. One of follow/unfollow/block/unblock/approve/deny
312
     */
313
    public function modifyUserRelationship($id, $action) {
314
        $endpointUrl = sprintf($this->_endpointUrls['modify_user_relationship'], $id, $action, $this->getAccessToken());
315
        $this->_initHttpClient($endpointUrl, Zend_Http_Client::POST);
316
        return $this->_getHttpClientResponse();
317
    }
318
 
319
    /**
320
     * Get information about a media object.
321
     * @param integer $mediaId
322
     */
323
    public function getMedia($id) {
324
        $endpointUrl = sprintf($this->_endpointUrls['media'], $id, $this->getAccessToken());
325
        $this->_initHttpClient($endpointUrl);
326
        return $this->_getHttpClientResponse();
327
    }
328
 
329
    /**
330
     * Search for media in a given area.
331
     * @param float $lat
332
     * @param float $lng
333
     * @param integer $maxTimestamp
334
     * @param integer $minTimestamp
335
     * @param integer $distance
336
     */
337
    public function mediaSearch($lat, $lng, $maxTimestamp = '', $minTimestamp = '', $distance = '') {
338
        $endpointUrl = sprintf($this->_endpointUrls['media_search'], $lat, $lng, $maxTimestamp, $minTimestamp, $distance, $this->getAccessToken());
339
        $this->_initHttpClient($endpointUrl);
340
        return $this->_getHttpClientResponse();
341
    }
342
 
343
    /**
344
     * Get a list of what media is most popular at the moment.
345
     */
346
    public function getPopularMedia() {
347
        $endpointUrl = sprintf($this->_endpointUrls['media_popular'], $this->getAccessToken());
348
        $this->_initHttpClient($endpointUrl);
349
        return $this->_getHttpClientResponse();
350
    }
351
 
352
    /**
353
     * Get a full list of comments on a media.
354
     * @param integer $id
355
     */
356
    public function getMediaComments($id) {
357
        $endpointUrl = sprintf($this->_endpointUrls['media_comments'], $id, $this->getAccessToken());
358
        $this->_initHttpClient($endpointUrl);
359
        return $this->_getHttpClientResponse();
360
    }
361
 
362
    /**
363
     * Create a comment on a media.
364
     * @param integer $id
365
     * @param string $text
366
     */
367
    public function postMediaComment($id, $text) {
368
        $endpointUrl = sprintf($this->_endpointUrls['post_media_comment'], $id, $this->getAccessToken());
369
                echo $endpointUrl."\n";
370
        $this->_initHttpClient($endpointUrl, CurlHttpClient::POST, array( 'text'=>$text ));
371
        return $this->_getHttpClientResponse();
372
    }
373
 
374
    /**
375
     * Remove a comment either on the authenticated user's media or authored by the authenticated user.
376
     * @param integer $mediaId
377
     * @param integer $commentId
378
     */
379
    public function deleteComment($mediaId, $commentId) {
380
        $endpointUrl = sprintf($this->_endpointUrls['delete_media_comment'], $mediaId, $commentId, $this->getAccessToken());
381
        $this->_initHttpClient($endpointUrl, CurlHttpClient::DELETE);
382
        return $this->_getHttpClientResponse();
383
    }
384
 
385
    /**
386
     * Get a list of users who have liked this media.
387
     * @param integer $mediaId
388
     */
389
    public function getLikes($mediaId) {
390
        $endpointUrl = sprintf($this->_endpointUrls['likes'], $mediaId, $this->getAccessToken());
391
        $this->_initHttpClient($endpointUrl);
392
        return $this->_getHttpClientResponse();
393
    }
394
 
395
    /**
396
     * Set a like on this media by the currently authenticated user.
397
     * @param integer $mediaId
398
     */
399
    public function postLike($mediaId) {
400
        $endpointUrl = sprintf($this->_endpointUrls['post_like'], $mediaId);
401
        echo $endpointUrl."<hr>";
402
        $this->_initHttpClient($endpointUrl, CurlHttpClient::POST);
403
        $this->_httpClient->setPostParam('access_token', $this->getAccessToken());
404
        return $this->_getHttpClientResponse();
405
    }
406
 
407
    /**
408
     * Remove a like on this media by the currently authenticated user.
409
     * @param integer $mediaId
410
     */
411
    public function removeLike($mediaId) {
412
        $endpointUrl = sprintf($this->_endpointUrls['remove_like'], $mediaId, $this->getAccessToken());
413
        $this->_initHttpClient($endpointUrl, CurlHttpClient::DELETE);
414
        return $this->_getHttpClientResponse();
415
    }
416
 
417
    /**
418
     * Get information about a tag object.
419
     * @param string $tagName
420
     */
421
    public function getTags($tagName) {
422
        $endpointUrl = sprintf($this->_endpointUrls['tags'], $tagName, $this->getAccessToken());
423
        $this->_initHttpClient($endpointUrl);
424
        return $this->_getHttpClientResponse();
425
    }
426
 
427
    /**
428
     * Get a list of recently tagged media.
429
     * @param string $tagName
430
     * @param integer $maxId
431
     * @param integer $minId
432
     */
433
    public function getRecentTags($tagName, $maxId = '', $minId = '') {
434
        $endpointUrl = sprintf($this->_endpointUrls['tags_recent'], $tagName, $maxId, $minId, $this->getAccessToken());
435
        $this->_initHttpClient($endpointUrl);
436
        return $this->_getHttpClientResponse();
437
    }
438
 
439
    /**
440
     * Search for tags by name - results are ordered first as an exact match, then by popularity.
441
     * @param string $tagName
442
     */
443
    public function searchTags($tagName) {
444
        $endpointUrl = sprintf($this->_endpointUrls['tags_search'], urlencode($tagName), $this->getAccessToken());
445
        $this->_initHttpClient($endpointUrl);
446
        return $this->_getHttpClientResponse();
447
    }
448
 
449
    /**
450
     * Get information about a location.
451
     * @param integer $id
452
     */
453
    public function getLocation($id) {
454
        $endpointUrl = sprintf($this->_endpointUrls['locations'], $id, $this->getAccessToken());
455
        $this->_initHttpClient($endpointUrl);
456
        return $this->_getHttpClientResponse();
457
    }
458
 
459
    /**
460
     * Get a list of recent media objects from a given location.
461
     * @param integer $locationId
462
     */
463
    public function getLocationRecentMedia($id, $maxId = '', $minId = '', $maxTimestamp = '', $minTimestamp = '') {
464
        $endpointUrl = sprintf($this->_endpointUrls['locations_recent'], $id, $maxId, $minId, $maxTimestamp, $minTimestamp, $this->getAccessToken());
465
        $this->_initHttpClient($endpointUrl);
466
        return $this->_getHttpClientResponse();
467
    }
468
 
469
    /**
470
     * Search for a location by name and geographic coordinate.
471
     * @see http://instagr.am/developer/endpoints/locations/#get_locations_search
472
     * @param float $lat
473
     * @param float $lng
474
     * @param integer $foursquareId
475
     * @param integer $distance
476
     */
477
    public function searchLocation($lat, $lng, $foursquareId = '', $distance = '') {
478
        $endpointUrl = sprintf($this->_endpointUrls['locations_search'], $lat, $lng, $foursquareId, $distance, $this->getAccessToken());
479
        $this->_initHttpClient($endpointUrl);
480
        return $this->_getHttpClientResponse();
481
    }
482
}
483
 
484
class InstagramException extends Exception {
485
}