Completed
Push — master ( 077592...2f74ab )
by Haridarshan
02:17
created

InstagramRequest::execute()   B

Complexity

Conditions 5
Paths 16

Size

Total Lines 20
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 2 Features 0
Metric Value
c 2
b 2
f 0
dl 0
loc 20
rs 8.8571
cc 5
eloc 15
nc 16
nop 0
1
<?php
2
namespace Haridarshan\Instagram;
3
4
use Haridarshan\Instagram\Constants;
5
use Haridarshan\Instagram\Exceptions\InstagramRequestException;
6
use Haridarshan\Instagram\Exceptions\InstagramResponseException;
7
use Haridarshan\Instagram\Exceptions\InstagramThrottleException;
8
use Haridarshan\Instagram\HelperFactory;
9
use Haridarshan\Instagram\Instagram;
10
use Haridarshan\Instagram\InstagramResponse;
11
12
class InstagramRequest
13
{
14
    /** @var string $path */
15
    private $path;
16
    
17
    /** @var array $params */
18
    private $params;
19
    
20
    /** @var string $method */
21
    private $method;
22
23
    /*
24
    * Remaining Rate Limit
25
    * Sandbox = 500
26
    * Live = 5000
27
    * @var array $x_rate_limit_remaining
28
    */
29
    private $xRateLimitRemaining = 500;
30
    
31
    /** @var InstagramResponse $response */
32
    protected $response;
33
    
34
    /** @var Instagram $instagram */
35
    protected $instagram;
36
    
37
    /*
38
     * Create the request and execute it to get the response
39
     * @param Instagram $instagram
40
     * @param string $path
41
     * @param array $params
42
     * @param string $method
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
		$request = HelperFactory::request($this->instagram->getHttpClient(), $endpoint, $this->params, $this->method);
70
		if ($request != null) {
71
        	$this->response = new InstagramResponse($request);
72
        	$this->xRateLimitRemaining = $this->response->getHeader('X-Ratelimit-Remaining');
73
		} else {
74
			throw new InstagramResponseException("400 Bad Request: instanceof InstagramResponse cannot be null", 400);
75
		}
76
    }
77
    
78
    /*
79
     * Check Access Token is present. If not throw InstagramRequestException
80
     * @throws InstagramRequestException
81
     */
82
    protected function isAccessTokenPresent()
83
    {
84
        if (!isset($this->params['access_token'])) {
85
            throw new InstagramRequestException("{$this->path} - api requires an authenticated users access token.", 400);
86
        }
87
    }
88
    
89
    /*
90
     * Get Response
91
     * @return InstagramResponse
92
     */
93
    public function getResponse()
94
    {
95
        $this->execute();
96
        return $this->response;
97
    }
98
    
99
    /*
100
     * Check whether api rate limit is reached or not
101
     * @throws InstagramThrottleException
102
     */
103
    private function isRateLimitReached()
104
    {
105
        if (!$this->getRateLimit()) {
106
            throw new InstagramThrottleException("400 Bad Request : You have reached Instagram API Rate Limit", 400);
107
        }
108
    }
109
    
110
    /*
111
     * Secure API Request by using endpoint, paramters and API secret
112
     * copy from Instagram API Documentation: https://www.instagram.com/developer/secure-api-requests/
113
     *
114
     * @param string $secret
115
     * @param string $endpoint
116
     * @param array $params
117
     *
118
     * @return string (Signature)
119
     */
120
    public static function generateSignature($secret, $endpoint, $params)
121
    {
122
        $signature = $endpoint;
123
        ksort($params);
124
        foreach ($params as $key => $value) {
125
            $signature .= "|$key=$value";
126
        }
127
        return hash_hmac('sha256', $signature, $secret, false);
128
    }
129
    
130
    /*
131
     * @return int
132
     */
133
    public function getRateLimit()
134
    {
135
        return $this->xRateLimitRemaining;
136
    }
137
}
138