InstagramClient::sendRequest()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 30
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 14
nc 4
nop 2
dl 0
loc 30
rs 9.7998
c 0
b 0
f 0
1
<?php
2
3
namespace Maztech;
4
5
use Maztech\HttpClients\InstagramCurlHttpClient;
6
use Maztech\HttpClients\InstagramHttpClientInterface;
7
use Maztech\HttpClients\InstagramStreamHttpClient;
8
use Maztech\Exceptions\InstagramSDKException;
9
10
/**
11
 * Class InstagramClient
12
 *
13
 * @package Instagram
14
 */
15
class InstagramClient
16
{
17
    /**
18
     * @const string Production Graph API URL.
19
     */
20
    const BASE_GRAPH_URL = 'https://graph.instagram.com';
21
22
    /**
23
     * @const string The base authorization URL.
24
     */
25
    const BASE_AUTHORIZATION_URL = 'https://api.instagram.com';
26
27
    /**
28
     * @const int The timeout in seconds for a normal request.
29
     */
30
    const DEFAULT_REQUEST_TIMEOUT = 60;
31
32
    /**
33
     * @const int The timeout in seconds for a request that contains file uploads.
34
     */
35
    const DEFAULT_FILE_UPLOAD_REQUEST_TIMEOUT = 3600;
36
37
    /**
38
     * @const int The timeout in seconds for a request that contains video uploads.
39
     */
40
    const DEFAULT_VIDEO_UPLOAD_REQUEST_TIMEOUT = 7200;
41
42
    /**
43
     * @var InstagramHttpClientInterface HTTP client handler.
44
     */
45
    protected $httpClientHandler;
46
47
    /**
48
     * @var int The number of calls that have been made to Graph.
49
     */
50
    public static $requestCount = 0;
51
52
    /**
53
     * Instantiates a new InstagramClient object.
54
     *
55
     * @param InstagramHttpClientInterface|null $httpClientHandler
56
     * @param boolean                          $enableBeta
57
     */
58
    public function __construct(InstagramHttpClientInterface $httpClientHandler = null)
59
    {
60
        $this->httpClientHandler = $httpClientHandler ?: $this->detectHttpClientHandler();
61
    }
62
63
    /**
64
     * Sets the HTTP client handler.
65
     *
66
     * @param InstagramHttpClientInterface $httpClientHandler
67
     */
68
    public function setHttpClientHandler(InstagramHttpClientInterface $httpClientHandler)
69
    {
70
        $this->httpClientHandler = $httpClientHandler;
71
    }
72
73
    /**
74
     * Returns the HTTP client handler.
75
     *
76
     * @return InstagramHttpClientInterface
77
     */
78
    public function getHttpClientHandler()
79
    {
80
        return $this->httpClientHandler;
81
    }
82
83
    /**
84
     * Detects which HTTP client handler to use.
85
     *
86
     * @return InstagramHttpClientInterface
87
     */
88
    public function detectHttpClientHandler()
89
    {
90
        return extension_loaded('curl') ? new InstagramCurlHttpClient() : new InstagramStreamHttpClient();
91
    }
92
93
    /**
94
     * Returns the base Graph URL.
95
     *
96
     * @return string
97
     */
98
    public function getBaseGraphUrl()
99
    {
100
        return static::BASE_GRAPH_URL;
101
    }
102
103
    /**
104
     * Returns the base Authorization URL.
105
     *
106
     * @return string
107
     */
108
    public function getBaseAuthorizationUrl()
109
    {
110
        return static::BASE_AUTHORIZATION_URL;
111
    }
112
113
    /**
114
     * Prepares the request for sending to the client handler.
115
     *
116
     * @param InstagramRequest $request
117
     * @param string $baseUrl value=graph|authorization
118
     *
119
     * @return array
120
     */
121
    public function prepareRequestMessage(InstagramRequest $request, $baseUrl = 'graph')
122
    {
123
        if($baseUrl == 'authorization') {
124
            $url = $this->getBaseAuthorizationUrl();
125
        } else {
126
            $url = $this->getBaseGraphUrl();
127
        } 
128
        
129
        $url .=  $request->getUrl();
130
131
        $requestBody = $request->getUrlEncodedBody();
132
        $request->setHeaders([
133
            'Content-Type' => 'application/x-www-form-urlencoded',
134
        ]);
135
136
        return [
137
            $url,
138
            $request->getMethod(),
139
            $request->getHeaders(),
140
            $requestBody->getBody(),
141
        ];
142
    }
143
144
    /**
145
     * Makes the request to Graph and returns the result.
146
     *
147
     * @param InstagramRequest $request
148
     * @param string $baseUrl value=graph|authorization
149
     *
150
     * @return InstagramResponse
151
     *
152
     * @throws InstagramSDKException
153
     */
154
    public function sendRequest(InstagramRequest $request, $baseUrl = 'graph')
155
    {
156
        if (get_class($request) === 'Instagram\InstagramRequest') {
157
            $request->validateAccessToken();
158
        }
159
160
        list($url, $method, $headers, $body) = $this->prepareRequestMessage($request, $baseUrl);
161
162
        // dd($request, $url, $method, $headers, $body);
163
        // Since file uploads can take a while, we need to give more time for uploads
164
        $timeOut = static::DEFAULT_REQUEST_TIMEOUT;
165
166
        // Should throw `InstagramSDKException` exception on HTTP client error.
167
        // Don't catch to allow it to bubble up.
168
        $rawResponse = $this->httpClientHandler->send($url, $method, $body, $headers, $timeOut);
169
        
170
        static::$requestCount++;
171
172
        $returnResponse = new InstagramResponse(
173
            $request,
174
            $rawResponse->getBody(),
175
            $rawResponse->getHttpResponseCode(),
176
            $rawResponse->getHeaders()
177
        );
178
179
        if ($returnResponse->isError()) {
180
            throw $returnResponse->getThrownException();
181
        }
182
183
        return $returnResponse;
184
    }
185
186
    /**
187
     * Makes a batched request to Graph and returns the result.
188
     *
189
     * @param InstagramBatchRequest $request
190
     *
191
     * @return InstagramBatchResponse
192
     *
193
     * @throws InstagramSDKException
194
     */
195
    public function sendBatchRequest(InstagramBatchRequest $request)
196
    {
197
        $request->prepareRequestsForBatch();
198
        $response = $this->sendRequest($request);
199
200
        return new InstagramBatchResponse($request, $response);
201
    }
202
}
203