Completed
Push — master ( 069494...c512ba )
by Haridarshan
02:24
created

InstagramRequest::execute()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 2 Features 0
Metric Value
c 3
b 2
f 0
dl 0
loc 14
rs 9.2
cc 4
eloc 10
nc 8
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
        $authentication_method = '?access_token='.$this->params['access_token'];
60
        $endpoint = Constants::API_VERSION.$this->path.(('GET' === $this->method) ? '?'.http_build_query($this->params) : $authentication_method);
61
        $endpoint .= (strstr($endpoint, '?') ? '&' : '?').'sig='.static::generateSignature($this->instagram->getClientSecret(), $this->path, $this->params);
62
        
63
		$request = HelperFactory::request($this->instagram->getHttpClient(), $endpoint, $this->params, $this->method);
64
		if ($request !== null) {
65
        	$this->response = new InstagramResponse($request);
66
        	$this->xRateLimitRemaining = $this->response->getHeader('X-Ratelimit-Remaining');
67
		} else {
68
			throw new InstagramResponseException("400 Bad Request: instanceof InstagramResponse cannot be null", 400);
69
		}
70
    }
71
    
72
    /*
73
     * Check Access Token is present. If not throw InstagramRequestException
74
     * @throws InstagramRequestException
75
     */
76
    protected function isAccessTokenPresent()
77
    {
78
        if (!isset($this->params['access_token'])) {
79
            throw new InstagramRequestException("{$this->path} - api requires an authenticated users access token.", 400);
80
        }
81
    }
82
    
83
    /*
84
     * Get Response
85
     * @return InstagramResponse
86
     */
87
    public function getResponse()
88
    {
89
		$this->isRateLimitReached();
90
        $this->isAccessTokenPresent();
91
        $oauth = $this->instagram->getOAuth();
92
        if (!$oauth->isAccessTokenSet()) {
93
            $oauth->setAccessToken($this->params['access_token']);
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