Completed
Pull Request — master (#150)
by
unknown
04:41 queued 01:31
created

LinkedIn::getError()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 0
crap 2
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. If we don't have an access token (only a *code*), getAccessToken() will call 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 RequestManager
55
     */
56
    private $requestManager;
57
58
    /**
59
     * @var Authenticator
60
     */
61
    private $authenticator;
62
63
    /**
64
     * @var UrlGeneratorInterface
65
     */
66
    private $urlGenerator;
67
68
    /**
69
     * Constructor.
70
     *
71
     * @param string $appId
72
     * @param string $appSecret
73
     * @param string $format           'json', 'xml'
74
     * @param string $responseDataType 'array', 'string', 'simple_xml' 'psr7', 'stream'
75
     */
76 7
    public function __construct($appId, $appSecret, $format = 'json', $responseDataType = 'array')
77
    {
78 7
        $this->format = $format;
79 7
        $this->responseDataType = $responseDataType;
80
81 7
        $this->requestManager = new RequestManager();
82 7
        $this->authenticator = new Authenticator($this->requestManager, $appId, $appSecret);
83 7
    }
84
85
    /**
86
     * {@inheritdoc}
87
     */
88 1
    public function isAuthenticated()
89
    {
90 1
        $accessToken = $this->getAccessToken();
91 1
        if ($accessToken === null) {
92 1
            return false;
93
        }
94
95 1
        $user = $this->api('GET', '/v1/people/~:(id,firstName,lastName)', ['format' => 'json', 'response_data_type' => 'array']);
96
97 1
        return !empty($user['id']);
98
    }
99
100
    /**
101
     * {@inheritdoc}
102
     */
103 1
    public function api($method, $resource, array $options = [])
104
    {
105
        // Add access token to the headers
106 1
        $options['headers']['Authorization'] = sprintf('Bearer %s', (string) $this->getAccessToken());
107
108
        // Do logic and adjustments to the options
109 1
        $requestFormat = $this->filterRequestOption($options);
110
111
        // Generate an url
112 1
        $url = $this->getUrlGenerator()->getUrl(
113 1
            'api',
114 1
            $resource,
115 1
            isset($options['query']) ? $options['query'] : []
116 1
        );
117
118 1
        $body = isset($options['body']) ? $options['body'] : null;
119 1
        $this->lastResponse = $this->getRequestManager()->sendRequest($method, $url, $options['headers'], $body);
0 ignored issues
show
Bug introduced by
The property lastResponse does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
120
121
        //Get the response data format
122 1
        if (isset($options['response_data_type'])) {
123
            $responseDataType = $options['response_data_type'];
124
        } else {
125 1
            $responseDataType = $this->getResponseDataType();
126
        }
127
128 1
        return ResponseConverter::convert($this->lastResponse, $requestFormat, $responseDataType);
129
    }
130
131
    /**
132
     * Modify and filter the request options. Make sure we use the correct query parameters and headers.
133
     *
134
     * @param array &$options
135
     *
136
     * @return string the request format to use
137
     */
138 1
    protected function filterRequestOption(array &$options)
139
    {
140 1
        if (isset($options['json'])) {
141 1
            $options['format'] = 'json';
142 1
            $options['body'] = json_encode($options['json']);
143 1
        } elseif (!isset($options['format'])) {
144
            // Make sure we always have a format
145
            $options['format'] = $this->getFormat();
146
        }
147
148
        // Set correct headers for this format
149 1
        switch ($options['format']) {
150 1
            case 'xml':
151
                $options['headers']['Content-Type'] = 'text/xml';
152
                break;
153 1
            case 'json':
154 1
                $options['headers']['Content-Type'] = 'application/json';
155 1
                $options['headers']['x-li-format'] = 'json';
156 1
                $options['query']['format'] = 'json';
157 1
                break;
158
            default:
159
                // Do nothing
160 1
        }
161
162 1
        return $options['format'];
163
    }
164
165
    /**
166
     * {@inheritdoc}
167
     */
168 2
    public function getLoginUrl($options = [])
169
    {
170 2
        $urlGenerator = $this->getUrlGenerator();
171
172
        // Set redirect_uri to current URL if not defined
173 2
        if (!isset($options['redirect_uri'])) {
174 1
            $options['redirect_uri'] = $urlGenerator->getCurrentUrl();
175 1
        }
176
177 2
        return $this->getAuthenticator()->getLoginUrl($urlGenerator, $options);
178
    }
179
180
    /**
181
     * See docs for LinkedIn::api().
182
     *
183
     * @param string $resource
184
     * @param array  $options
185
     *
186
     * @return mixed
187
     */
188
    public function get($resource, array $options = [])
189
    {
190
        return $this->api('GET', $resource, $options);
191
    }
192
193
    /**
194
     * See docs for LinkedIn::api().
195
     *
196
     * @param string $resource
197
     * @param array  $options
198
     *
199
     * @return mixed
200
     */
201
    public function post($resource, array $options = [])
202
    {
203
        return $this->api('POST', $resource, $options);
204
    }
205
206
    /**
207
     * {@inheritdoc}
208
     */
209
    public function clearStorage()
210
    {
211
        $this->getAuthenticator()->clearStorage();
212
213
        return $this;
214
    }
215
216
    /**
217
     * {@inheritdoc}
218
     */
219 3
    public function hasError()
220
    {
221 3
        return GlobalVariableGetter::has('error');
222
    }
223
224
    /**
225
     * {@inheritdoc}
226
     */
227 2
    public function getError()
228
    {
229 2
        if ($this->hasError()) {
230 2
            return new LoginError(GlobalVariableGetter::get('error'), GlobalVariableGetter::get('error_description'));
231
        }
232 1
    }
233
234
    /**
235
     * Get the default format to use when sending requests.
236
     *
237
     * @return string
238
     */
239 1
    protected function getFormat()
240
    {
241 1
        return $this->format;
242
    }
243
244
    /**
245
     * {@inheritdoc}
246
     */
247 1
    public function setFormat($format)
248
    {
249 1
        $this->format = $format;
250
251 1
        return $this;
252
    }
253
254
    /**
255
     * Get the default data type to be returned as a response.
256
     *
257
     * @return string
258
     */
259 1
    protected function getResponseDataType()
260
    {
261 1
        return $this->responseDataType;
262
    }
263
264
    /**
265
     * {@inheritdoc}
266
     */
267
    public function setResponseDataType($responseDataType)
268
    {
269
        $this->responseDataType = $responseDataType;
270
271
        return $this;
272
    }
273
274
    /**
275
     * {@inheritdoc}
276
     */
277 1
    public function getAccessToken()
278
    {
279 1
        if ($this->accessToken === null) {
280 1
            if (null !== $newAccessToken = $this->getAuthenticator()->fetchNewAccessToken($this->getUrlGenerator())) {
281 1
                $this->setAccessToken($newAccessToken);
282 1
            }
283 1
        }
284
285
        // return the new access token or null if none found
286 1
        return $this->accessToken;
287
    }
288
289
    /**
290
     * {@inheritdoc}
291
     */
292 1
    public function setAccessToken($accessToken)
293
    {
294 1
        if (!($accessToken instanceof AccessToken)) {
295 1
            $accessToken = new AccessToken($accessToken);
296 1
        }
297
298 1
        $this->accessToken = $accessToken;
299
300 1
        return $this;
301
    }
302
303
    /**
304
     * {@inheritdoc}
305
     */
306 1
    public function setUrlGenerator(UrlGeneratorInterface $urlGenerator)
307
    {
308 1
        $this->urlGenerator = $urlGenerator;
309
310 1
        return $this;
311
    }
312
313
    /**
314
     * @return UrlGeneratorInterface
315
     */
316 2
    protected function getUrlGenerator()
317
    {
318 2
        if ($this->urlGenerator === null) {
319 2
            $this->urlGenerator = new UrlGenerator();
320 2
        }
321
322 2
        return $this->urlGenerator;
323
    }
324
325
    /**
326
     * {@inheritdoc}
327
     */
328
    public function setStorage(DataStorageInterface $storage)
329
    {
330
        $this->getAuthenticator()->setStorage($storage);
331
332
        return $this;
333
    }
334
335
    /**
336
     * {@inheritdoc}
337
     */
338
    public function setHttpClient(HttpClient $client)
339
    {
340
        $this->getRequestManager()->setHttpClient($client);
341
342
        return $this;
343
    }
344
345
    /**
346
     * {@inheritdoc}
347
     */
348
    public function setHttpMessageFactory(MessageFactory $factory)
349
    {
350
        $this->getRequestManager()->setMessageFactory($factory);
351
352
        return $this;
353
    }
354
355
    /**
356
     * @return RequestManager
357
     */
358
    protected function getRequestManager()
359
    {
360
        return $this->requestManager;
361
    }
362
363
    /**
364
     * @return Authenticator
365
     */
366
    protected function getAuthenticator()
367
    {
368
        return $this->authenticator;
369
    }
370
371
372
    /**
373
     * @return \Psr\Http\Message\ResponseInterface
374
     */
375
    public function getLastResponse()
376
    {
377
        return $this->getRequestManager()->getLastResponse();
378
    }
379
380
    /**
381
     * @return \Psr\Http\Message\RequestInterface
382
     */
383
    public function getLastRequest()
384
    {
385
        return $this->getRequestManager()->getLastRequest();
386
    }
387
}
388