Completed
Push — master ( d2e951...b1f2c8 )
by Haridarshan
02:18
created

InstagramRequest::isRateLimitReached()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 6
rs 9.4285
cc 2
eloc 3
nc 2
nop 0
1
<?php
2
namespace Haridarshan\Instagram;
3
4
use Haridarshan\Instagram\HelperFactory;
5
use Haridarshan\Instagram\Constants;
6
use Haridarshan\Instagram\Instagram;
7
use Haridarshan\Instagram\InstagramResponse;
8
use Haridarshan\Instagram\Exceptions\InstagramResponseException;
9
10
class InstagramRequest
11
{
12
    /** @var string $path */
13
    private $path;
14
    
15
    /** @var array $params */
16
    private $params;
17
    
18
    /** @var string $method */
19
    private $method;
20
21
    /*
22
    * Remaining Rate Limit
23
    * Sandbox = 500
24
    * Live = 5000
25
    * @var array $x_rate_limit_remaining
26
    */
27
    private $xRateLimitRemaining = 500;
28
    
29
    /** @var InstagramResponse $response */
30
    protected $response;
31
    
32
    /** @var Instagram $instagram */
33
    protected $instagram;
34
    
35
    /*
36
     * Create the request and execute it to get the response
37
     * @param Instagram $instagram
38
     * @param string $path
39
     * @param array $params
40
     * @param string $method
41
     *
42
     * @return InstagramResponse
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
43
     */
44
    public function __construct(Instagram $instagram, $path, array $params = array(), $method = 'GET')
45
    {
46
        $this->instagram = $instagram;
47
        $this->path = $path;
48
        $this->params = $params;
49
        $this->method = $method;
50
    }
51
    
52
    /*
53
     * Execute the Instagram Request
54
     * @param void
55
     * @return InstagramResponse
56
     */
57
    protected function execute()
58
    {
59
        $this->isRateLimitReached();
60
        $this->isAccessTokenPresent();
61
        $oauth = $this->instagram->getOAuth();
62
        if (!$oauth->isAccessTokenSet()) {
63
            $oauth->setAccessToken($this->params['access_token']);
64
        }
65
        $authentication_method = '?access_token='.$this->params['access_token'];
66
        $endpoint = Constants::API_VERSION.$this->path.(('GET' === $this->method) ? '?'.http_build_query($this->params) : $authentication_method);
67
        $endpoint .= (strstr($endpoint, '?') ? '&' : '?').'sig='.static::generateSignature($this->instagram->getClientSecret(), $this->path, $this->params);
68
        
69
        $this->response = new InstagramResponse(HelperFactory::request($this->instagram->getHttpClient(), $endpoint, $this->params, $this->method));
70
        $this->xRateLimitRemaining = $this->response->getHeader('X-Ratelimit-Remaining');
71
    }
72
    
73
    /*
74
     * Check Access Token is present. If not throw InstagramRequestException
75
     * @throws InstagramRequestException
76
     */
77
    protected function isAccessTokenPresent()
78
    {
79
        if (!isset($this->params['access_token'])) {
80
            throw new InstagramRequestException("{$this->path} - api requires an authenticated users access token.", 400);
81
        }
82
    }
83
    
84
    /*
85
     * Get Response
86
     * @return InstagramResponse
87
     */
88
    public function getResponse()
89
    {
90
        $this->execute();
91
        return $this->response;
92
    }
93
    
94
    /*
95
     * Check whether api rate limit is reached or not
96
     * @throws InstagramThrottleException
97
     */
98
    private function isRateLimitReached()
99
    {
100
        if (!$this->getRateLimit()) {
101
            throw new InstagramThrottleException("400 Bad Request : You have reached Instagram API Rate Limit", 400);
102
        }
103
    }
104
    
105
    /*
106
     * Secure API Request by using endpoint, paramters and API secret
107
     * copy from Instagram API Documentation: https://www.instagram.com/developer/secure-api-requests/
108
     *
109
     * @param string $secret
110
     * @param string $endpoint
111
     * @param array $params
112
     *
113
     * @return string (Signature)
114
     */
115
    public static function generateSignature($secret, $endpoint, $params)
116
    {
117
        $signature = $endpoint;
118
        ksort($params);
119
        foreach ($params as $key => $value) {
120
            $signature .= "|$key=$value";
121
        }
122
        return hash_hmac('sha256', $signature, $secret, false);
123
    }
124
    
125
    /*
126
     * @return int
127
     */
128
    public function getRateLimit()
129
    {
130
        return $this->xRateLimitRemaining;
131
    }
132
}
133