Completed
Push — master ( 7113c4...8875d3 )
by Yassine
14s
created

Client   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 201
Duplicated Lines 0 %

Test Coverage

Coverage 94.23%

Importance

Changes 0
Metric Value
dl 0
loc 201
ccs 49
cts 52
cp 0.9423
rs 10
c 0
b 0
f 0
wmc 16

8 Methods

Rating   Name   Duplication   Size   Complexity  
A enableBetaMode() 0 3 1
A __construct() 0 4 2
A setHttpClient() 0 3 1
A prepareRequestMessage() 0 23 2
A getBaseGraphUrl() 0 7 4
B sendRequest() 0 32 4
A getHttpClient() 0 3 1
A sendBatchRequest() 0 6 1
1
<?php
2
/**
3
 * Copyright 2017 Facebook, Inc.
4
 *
5
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
6
 * use, copy, modify, and distribute this software in source code or binary
7
 * form for use in connection with the web services and APIs provided by
8
 * Facebook.
9
 *
10
 * As with any software that integrates with the Facebook platform, your use
11
 * of this software is subject to the Facebook Developer Principles and
12
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
13
 * shall be included in all copies or substantial portions of the software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
 * DEALINGS IN THE SOFTWARE.
22
 */
23
namespace Facebook;
24
25
use Facebook\Exception\SDKException;
26
use Http\Client\HttpClient;
27
use Http\Discovery\HttpClientDiscovery;
28
use Http\Discovery\MessageFactoryDiscovery;
29
30
/**
31
 * @package Facebook
32
 */
33
class Client
34
{
35
    /**
36
     * @const string Production Graph API URL.
37
     */
38
    const BASE_GRAPH_URL = 'https://graph.facebook.com';
39
40
    /**
41
     * @const string Graph API URL for video uploads.
42
     */
43
    const BASE_GRAPH_VIDEO_URL = 'https://graph-video.facebook.com';
44
45
    /**
46
     * @const string Beta Graph API URL.
47
     */
48
    const BASE_GRAPH_URL_BETA = 'https://graph.beta.facebook.com';
49
50
    /**
51
     * @const string Beta Graph API URL for video uploads.
52
     */
53
    const BASE_GRAPH_VIDEO_URL_BETA = 'https://graph-video.beta.facebook.com';
54
55
    /**
56
     * @const int The timeout in seconds for a normal request.
57
     */
58
    const DEFAULT_REQUEST_TIMEOUT = 60;
59
60
    /**
61
     * @const int The timeout in seconds for a request that contains file uploads.
62
     */
63
    const DEFAULT_FILE_UPLOAD_REQUEST_TIMEOUT = 3600;
64
65
    /**
66
     * @const int The timeout in seconds for a request that contains video uploads.
67
     */
68
    const DEFAULT_VIDEO_UPLOAD_REQUEST_TIMEOUT = 7200;
69
70
    /**
71
     * @var bool toggle to use Graph beta url
72
     */
73
    protected $enableBetaMode = false;
74
75
    /**
76
     * @var httpClient HTTP client handler
77
     */
78
    protected $httpClient;
79
80
    /**
81
     * @var int the number of calls that have been made to Graph
82
     */
83
    public static $requestCount = 0;
84
85
    /**
86
     * Instantiates a new Client object.
87
     *
88
     * @param null|HttpClient $httpClient
89
     * @param bool            $enableBeta
90
     */
91 43
    public function __construct(HttpClient $httpClient = null, $enableBeta = false)
92
    {
93 43
        $this->httpClient = $httpClient ?: HttpClientDiscovery::find();
94 43
        $this->enableBetaMode = $enableBeta;
95 43
    }
96
97
    /**
98
     * Sets the HTTP client handler.
99
     *
100
     * @param HttpClient $httpClient
101
     */
102
    public function setHttpClient(HttpClient $httpClient)
103
    {
104
        $this->httpClient = $httpClient;
105
    }
106
107
    /**
108
     * Returns the HTTP client handler.
109
     *
110
     * @return HttpClient
111
     */
112 3
    public function getHttpClient()
113
    {
114 3
        return $this->httpClient;
115
    }
116
117
    /**
118
     * Toggle beta mode.
119
     *
120
     * @param bool $betaMode
121
     */
122 2
    public function enableBetaMode($betaMode = true)
123
    {
124 2
        $this->enableBetaMode = $betaMode;
125 2
    }
126
127
    /**
128
     * Returns the base Graph URL.
129
     *
130
     * @param bool $postToVideoUrl post to the video API if videos are being uploaded
131
     *
132
     * @return string
133
     */
134 16
    public function getBaseGraphUrl($postToVideoUrl = false)
135
    {
136 16
        if ($postToVideoUrl) {
137 2
            return $this->enableBetaMode ? static::BASE_GRAPH_VIDEO_URL_BETA : static::BASE_GRAPH_VIDEO_URL;
138
        }
139
140 14
        return $this->enableBetaMode ? static::BASE_GRAPH_URL_BETA : static::BASE_GRAPH_URL;
141
    }
142
143
    /**
144
     * Prepares the request for sending to the client handler.
145
     *
146
     * @param Request $request
147
     *
148
     * @return array
149
     */
150 11
    public function prepareRequestMessage(Request $request)
151
    {
152 11
        $postToVideoUrl = $request->containsVideoUploads();
153 11
        $url = $this->getBaseGraphUrl($postToVideoUrl) . $request->getUrl();
154
155
        // If we're sending files they should be sent as multipart/form-data
156 11
        if ($request->containsFileUploads()) {
157 6
            $requestBody = $request->getMultipartBody();
158 6
            $request->setHeaders([
159 6
                'Content-Type' => 'multipart/form-data; boundary=' . $requestBody->getBoundary(),
160
            ]);
161
        } else {
162 8
            $requestBody = $request->getUrlEncodedBody();
163 8
            $request->setHeaders([
164 8
                'Content-Type' => 'application/x-www-form-urlencoded',
165
            ]);
166
        }
167
168
        return [
169 11
            $url,
170 11
            $request->getMethod(),
171 11
            $request->getHeaders(),
172 11
            $requestBody->getBody(),
173
        ];
174
    }
175
176
    /**
177
     * Makes the request to Graph and returns the result.
178
     *
179
     * @param Request $request
180
     *
181
     * @throws SDKException
182
     *
183
     * @return Response
184
     */
185 11
    public function sendRequest(Request $request)
186
    {
187 11
        if (get_class($request) === 'Facebook\Request') {
188 10
            $request->validateAccessToken();
189
        }
190
191 10
        list($url, $method, $headers, $body) = $this->prepareRequestMessage($request);
192
193 10
        $psr7Response = $this->httpClient->sendRequest(
194 10
            MessageFactoryDiscovery::find()->createRequest($method, $url, $headers, $body)
195
        );
196
197 10
        static::$requestCount++;
198
199
        // Prepare headers from associative array to a single string for each header.
200 10
        $responseHeaders = [];
201 10
        foreach ($psr7Response->getHeaders() as $name => $values) {
202 10
            $responseHeaders[] = sprintf('%s: %s', $name, implode(", ", $values));
203
        }
204
205 10
        $Response = new Response(
206 10
            $request,
207 10
            $psr7Response->getBody(),
208 10
            $psr7Response->getStatusCode(),
209 10
            $responseHeaders
210
        );
211
212 10
        if ($Response->isError()) {
213 3
            throw $Response->getThrownException();
214
        }
215
216 8
        return $Response;
217
    }
218
219
    /**
220
     * Makes a batched request to Graph and returns the result.
221
     *
222
     * @param BatchRequest $request
223
     *
224
     * @throws SDKException
225
     *
226
     * @return BatchResponse
227
     */
228 1
    public function sendBatchRequest(BatchRequest $request)
229
    {
230 1
        $request->prepareRequestsForBatch();
231 1
        $Response = $this->sendRequest($request);
232
233 1
        return new BatchResponse($request, $Response);
234
    }
235
}
236