Completed
Push — master ( a84236...a47bd8 )
by Tobias
9s
created

LinkedIn::setHttpMessageFactory()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
namespace Happyr\LinkedIn;
4
5
use Happyr\LinkedIn\Exception\LoginError;
6
use Happyr\LinkedIn\Http\GlobalVariableGetter;
7
use Happyr\LinkedIn\Http\RequestManager;
8
use Happyr\LinkedIn\Http\ResponseConverter;
9
use Happyr\LinkedIn\Http\UrlGenerator;
10
use Happyr\LinkedIn\Http\UrlGeneratorInterface;
11
use Happyr\LinkedIn\Storage\DataStorageInterface;
12
use Http\Client\HttpClient;
13
use Http\Message\MessageFactory;
14
use Psr\Http\Message\ResponseInterface;
15
16
/**
17
 * Class LinkedIn lets you talk to LinkedIn api.
18
 *
19
 * When a new user arrives and want to authenticate here is whats happens:
20
 * 1. You redirect him to whatever url getLoginUrl() returns.
21
 * 2. The user logs in on www.linkedin.com and authorize your application.
22
 * 3. The user returns to your site with a *code* in the the $_REQUEST.
23
 * 4. You call isAuthenticated() or getAccessToken()
24
 * 5. We don't got an access token (only a *code*). So getAccessToken() calls fetchNewAccessToken()
25
 * 6. fetchNewAccessToken() gets the *code* from the $_REQUEST and calls getAccessTokenFromCode()
26
 * 7. getAccessTokenFromCode() makes a request to www.linkedin.com and exchanges the *code* for an access token
27
 * 8. When you have the access token you should store it in a database and/or query the API.
28
 * 9. When you make a second request to the API we have the access token in memory, so we don't go through all these
29
 *    authentication steps again.
30
 *
31
 * @author Tobias Nyholm <[email protected]>
32
 */
33
class LinkedIn implements LinkedInInterface
34
{
35
    /**
36
     * The OAuth access token received in exchange for a valid authorization
37
     * code.  null means the access token has yet to be determined.
38
     *
39
     * @var AccessToken
40
     */
41
    protected $accessToken = null;
42
43
    /**
44
     * @var string format
45
     */
46
    private $format;
47
48
    /**
49
     * @var string responseFormat
50
     */
51
    private $responseDataType;
52
53
    /**
54
     * @var ResponseInterface
55
     */
56
    private $lastResponse;
57
58
    /**
59
     * @var RequestManager
60
     */
61
    private $requestManager;
62
63
    /**
64
     * @var Authenticator
65
     */
66
    private $authenticator;
67
68
    /**
69
     * @var UrlGeneratorInterface
70
     */
71
    private $urlGenerator;
72
73
    /**
74
     * Constructor.
75
     *
76
     * @param string $appId
77
     * @param string $appSecret
78
     * @param string $format           'json', 'xml'
79
     * @param string $responseDataType 'array', 'string', 'simple_xml' 'psr7', 'stream'
80
     */
81
    public function __construct($appId, $appSecret, $format = 'json', $responseDataType = 'array')
82
    {
83
        $this->format = $format;
84
        $this->responseDataType = $responseDataType;
85
86
        $this->requestManager = new RequestManager();
87
        $this->authenticator = new Authenticator($this->requestManager, $appId, $appSecret);
88
    }
89
90
    /**
91
     * {@inheritdoc}
92
     */
93
    public function isAuthenticated()
94
    {
95
        $accessToken = $this->getAccessToken();
96
        if ($accessToken === null) {
97
            return false;
98
        }
99
100
        $user = $this->api('GET', '/v1/people/~:(id,firstName,lastName)', array('format' => 'json', 'response_data_type' => 'array'));
101
102
        return !empty($user['id']);
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     */
108
    public function api($method, $resource, array $options = array())
109
    {
110
        // Add access token to the headers
111
        $options['headers']['Authorization'] = sprintf('Bearer %s', (string) $this->getAccessToken());
112
113
        // Do logic and adjustments to the options
114
        $requestFormat = $this->filterRequestOption($options);
115
116
        // Generate an url
117
        $url = $this->getUrlGenerator()->getUrl(
118
            'api',
119
            $resource,
120
            isset($options['query']) ? $options['query'] : array()
121
        );
122
123
        $body = isset($options['body']) ? $options['body'] : null;
124
        $this->lastResponse = $this->getRequestManager()->sendRequest($method, $url, $options['headers'], $body);
125
126
        //Get the response data format
127
        if (isset($options['response_data_type'])) {
128
            $responseDataType = $options['response_data_type'];
129
        } else {
130
            $responseDataType = $this->getResponseDataType();
131
        }
132
133
        return ResponseConverter::convert($this->lastResponse, $requestFormat, $responseDataType);
134
    }
135
136
    /**
137
     * Modify and filter the request options. Make sure we use the correct query parameters and headers.
138
     *
139
     * @param array &$options
140
     *
141
     * @return string the request format to use
142
     */
143
    protected function filterRequestOption(array &$options)
144
    {
145
        if (isset($options['json'])) {
146
            $options['format'] = 'json';
147
            $options['body'] = json_encode($options['json']);
148
        } elseif (!isset($options['format'])) {
149
            // Make sure we always have a format
150
            $options['format'] = $this->getFormat();
151
        }
152
153
        // Set correct headers for this format
154
        switch ($options['format']) {
155
            case 'xml':
156
                $options['headers']['Content-Type'] = 'text/xml';
157
                break;
158
            case 'json':
159
                $options['headers']['Content-Type'] = 'application/json';
160
                $options['headers']['x-li-format'] = 'json';
161
                $options['query']['format'] = 'json';
162
                break;
163
            default:
164
                // Do nothing
165
        }
166
167
        return $options['format'];
168
    }
169
170
    /**
171
     * {@inheritdoc}
172
     */
173
    public function getLoginUrl($options = array())
174
    {
175
        $urlGenerator = $this->getUrlGenerator();
176
177
        // Set redirect_uri to current URL if not defined
178
        if (!isset($options['redirect_uri'])) {
179
            $options['redirect_uri'] = $urlGenerator->getCurrentUrl();
180
        }
181
182
        return $this->getAuthenticator()->getLoginUrl($urlGenerator, $options);
183
    }
184
185
    /**
186
     * See docs for LinkedIn::api().
187
     *
188
     * @param string $resource
189
     * @param array  $options
190
     *
191
     * @return mixed
192
     */
193
    public function get($resource, array $options = array())
194
    {
195
        return $this->api('GET', $resource, $options);
196
    }
197
198
    /**
199
     * See docs for LinkedIn::api().
200
     *
201
     * @param string $resource
202
     * @param array  $options
203
     *
204
     * @return mixed
205
     */
206
    public function post($resource, array $options = array())
207
    {
208
        return $this->api('POST', $resource, $options);
209
    }
210
211
    /**
212
     * {@inheritdoc}
213
     */
214
    public function clearStorage()
215
    {
216
        $this->getAuthenticator()->clearStorage();
217
218
        return $this;
219
    }
220
221
    /**
222
     * {@inheritdoc}
223
     */
224
    public function hasError()
225
    {
226
        return GlobalVariableGetter::has('error');
227
    }
228
229
    /**
230
     * {@inheritdoc}
231
     */
232
    public function getError()
233
    {
234
        if ($this->hasError()) {
235
            return new LoginError(GlobalVariableGetter::get('error'), GlobalVariableGetter::get('error_description'));
236
        }
237
    }
238
239
    /**
240
     * Get the default format to use when sending requests.
241
     *
242
     * @return string
243
     */
244
    protected function getFormat()
245
    {
246
        return $this->format;
247
    }
248
249
    /**
250
     * {@inheritdoc}
251
     */
252
    public function setFormat($format)
253
    {
254
        $this->format = $format;
255
256
        return $this;
257
    }
258
259
    /**
260
     * Get the default data type to be returned as a response.
261
     *
262
     * @return string
263
     */
264
    protected function getResponseDataType()
265
    {
266
        return $this->responseDataType;
267
    }
268
269
    /**
270
     * {@inheritdoc}
271
     */
272
    public function setResponseDataType($responseDataType)
273
    {
274
        $this->responseDataType = $responseDataType;
275
276
        return $this;
277
    }
278
279
    /**
280
     * {@inheritdoc}
281
     */
282
    public function getLastResponse()
283
    {
284
        return $this->lastResponse;
285
    }
286
287
    /**
288
     * {@inheritdoc}
289
     */
290
    public function getAccessToken()
291
    {
292
        if ($this->accessToken === null) {
293
            if (null !== $newAccessToken = $this->getAuthenticator()->fetchNewAccessToken($this->getUrlGenerator())) {
294
                $this->setAccessToken($newAccessToken);
295
            }
296
        }
297
298
        // return the new access token or null if none found
299
        return $this->accessToken;
300
    }
301
302
    /**
303
     * {@inheritdoc}
304
     */
305
    public function setAccessToken($accessToken)
306
    {
307
        if (!($accessToken instanceof AccessToken)) {
308
            $accessToken = new AccessToken($accessToken);
309
        }
310
311
        $this->accessToken = $accessToken;
312
313
        return $this;
314
    }
315
316
    /**
317
     * {@inheritdoc}
318
     */
319
    public function setUrlGenerator(UrlGeneratorInterface $urlGenerator)
320
    {
321
        $this->urlGenerator = $urlGenerator;
322
323
        return $this;
324
    }
325
326
    /**
327
     * @return UrlGeneratorInterface
328
     */
329
    protected function getUrlGenerator()
330
    {
331
        if ($this->urlGenerator === null) {
332
            $this->urlGenerator = new UrlGenerator();
333
        }
334
335
        return $this->urlGenerator;
336
    }
337
338
    /**
339
     * {@inheritdoc}
340
     */
341
    public function setStorage(DataStorageInterface $storage)
342
    {
343
        $this->getAuthenticator()->setStorage($storage);
344
345
        return $this;
346
    }
347
348
    /**
349
     * {@inheritdoc}
350
     */
351
    public function setHttpClient(HttpClient $client)
352
    {
353
        $this->getRequestManager()->setHttpClient($client);
354
355
        return $this;
356
    }
357
358
    /**
359
     * {@inheritdoc}
360
     */
361
    public function setHttpMessageFactory(MessageFactory $factory)
362
    {
363
        $this->getRequestManager()->setMessageFactory($factory);
364
365
        return $this;
366
    }
367
368
    /**
369
     * @return RequestManager
370
     */
371
    protected function getRequestManager()
372
    {
373
        return $this->requestManager;
374
    }
375
376
    /**
377
     * @return Authenticator
378
     */
379
    protected function getAuthenticator()
380
    {
381
        return $this->authenticator;
382
    }
383
}
384