Completed
Pull Request — master (#23)
by
unknown
12:53
created

LinkedIn::getResourceOwnerEmailUrl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace League\OAuth2\Client\Provider;
4
5
use InvalidArgumentException;
6
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
7
use League\OAuth2\Client\Token\AccessToken;
8
use League\OAuth2\Client\Tool\BearerAuthorizationTrait;
9
use Psr\Http\Message\ResponseInterface;
10
11
class LinkedIn extends AbstractProvider
12
{
13
    use BearerAuthorizationTrait;
14
15
    /**
16
     * Default scopes
17
     *
18
     * @var array
19
     */
20
    public $defaultScopes = ['r_liteprofile', 'r_emailaddress'];
21
22
    /**
23
     * Requested fields in scope, seeded with default values
24
     *
25
     * @var array
26
     * @see https://docs.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/sign-in-with-linkedin?context=linkedin/consumer/context#response-body-schema
27
     */
28
    protected $fields = [
29
        'id',
30
        'firstName',
31
        'lastName',
32
        'localizedFirstName',
33
        'localizedLastName',
34
        'profilePicture(displayImage~:playableStreams)',
35
    ];
36
37
    /**
38
     * Try getting ResourceOwner email in a separate request.
39
     *
40
     * @var bool
41
     */
42
    protected $getEmail = true;
43
44
    /**
45
     * Constructs an OAuth 2.0 service provider.
46
     *
47
     * @param array $options An array of options to set on this provider.
48
     *     Options include `clientId`, `clientSecret`, `redirectUri`, and `state`.
49
     *     Individual providers may introduce more options, as needed.
50
     * @param array $collaborators An array of collaborators that may be used to
51
     *     override this provider's default behavior. Collaborators include
52
     *     `grantFactory`, `requestFactory`, and `httpClient`.
53
     *     Individual providers may introduce more collaborators, as needed.
54 36
     */
55
    public function __construct(array $options = [], array $collaborators = [])
56 36
    {
57 3
        if (isset($options['fields']) && !is_array($options['fields'])) {
58
            throw new InvalidArgumentException('The fields option must be an array');
59
        }
60 36
61 36
        parent::__construct($options, $collaborators);
62
    }
63
64
    /**
65
     * Get the string used to separate scopes.
66
     *
67
     * @return string
68 9
     */
69
    protected function getScopeSeparator()
70 9
    {
71
        return ' ';
72
    }
73
74
    /**
75
     * Get authorization url to begin OAuth flow
76
     *
77
     * @return string
78 9
     */
79
    public function getBaseAuthorizationUrl()
80 9
    {
81
        return 'https://www.linkedin.com/oauth/v2/authorization';
82
    }
83
84
    /**
85
     * Get access token url to retrieve token
86
     *
87
     * @return string
88 15
     */
89
    public function getBaseAccessTokenUrl(array $params)
90 15
    {
91
        return 'https://www.linkedin.com/oauth/v2/accessToken';
92
    }
93
94
    /**
95
     * Get provider url to fetch user details
96
     *
97
     * @param  AccessToken $token
98
     *
99
     * @return string
100 12
     */
101
    public function getResourceOwnerEmailUrl(AccessToken $token)
0 ignored issues
show
Unused Code introduced by
The parameter $token is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
102 12
    {
103
        $projection = '(elements*(state,primary,type,handle~))';
104 12
105 12
        return 'https://api.linkedin.com/v2/clientAwareMemberHandles?q=members&projection='.$projection;
106 12
    }
107 3
108 1
    /**
109 3
     * Get provider url to fetch user details
110
     *
111 1
     * @param  AccessToken $token
112
     *
113
     * @return string
114
     */
115
    public function getResourceOwnerDetailsUrl(AccessToken $token)
116
    {
117
        return 'https://api.linkedin.com/v2/me?projection=(' . implode(',', $this->fields).')';
118
    }
119
120
    /**
121 6
     * Get the default scopes used by this provider.
122
     *
123 6
     * This should not be a complete list of all scopes, but the minimum
124
     * required for the provider user interface!
125
     *
126
     * @return array
127
     */
128
    protected function getDefaultScopes()
129
    {
130
        return $this->defaultScopes;
131
    }
132
133
    /**
134 12
     * Check a provider response for errors.
135
     *
136 12
     * @throws IdentityProviderException
137 3
     * @param  ResponseInterface $response
138 3
     * @param  string $data Parsed response data
139 3
     * @return void
140 2
     */
141 1
    protected function checkResponse(ResponseInterface $response, $data)
142
    {
143 9
        if (isset($data['error'])) {
144
            throw new IdentityProviderException(
145
                $data['error_description'] ?: $response->getReasonPhrase(),
146
                $response->getStatusCode(),
147
                $response
0 ignored issues
show
Documentation introduced by
$response is of type object<Psr\Http\Message\ResponseInterface>, but the function expects a array|string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
148
            );
149
        }
150
    }
151
152 6
    /**
153
     * Generate a user object from a successful user details request.
154 6
     *
155
     * @param array $response
156
     * @param AccessToken $token
157
     * @return LinkedInResourceOwner
158
     */
159
    protected function createResourceOwner(array $response, AccessToken $token)
160
    {
161
        return new LinkedInResourceOwner($response);
162 9
    }
163
164 9
    /**
165
     * @param AccessToken $token
166
     *
167
     * @return array|mixed
168
     * @throws IdentityProviderException
169
     */
170
    protected function fetchResourceOwnerDetails(AccessToken $token)
171
    {
172 3
        $profile = parent::fetchResourceOwnerDetails($token);
173
        $emailResponse = null;
174 3
175
        if ($this->getEmail) {
176
            $emailUrl = $this->getResourceOwnerEmailUrl($token);
177
            $emailRequest = $this->getAuthenticatedRequest(self::METHOD_GET, $emailUrl, $token);
178
            $emailResponse = $this->getParsedResponse($emailRequest);
179
        }
180
181
        return [
182
            'profile' => $profile,
183
            'email' => $emailResponse,
184 3
        ];
185
    }
186 3
187
    /**
188 3
     * Returns the requested fields in scope.
189
     *
190
     * @return array
191
     */
192
    public function getFields()
193
    {
194
        return $this->fields;
195
    }
196
197
    /**
198 3
     * Updates the requested fields in scope.
199
     *
200 3
     * @param  array   $fields
201
     *
202 3
     * @return LinkedIn
203 3
     */
204 1
    public function withFields(array $fields)
205
    {
206 3
        $this->fields = $fields;
207
208
        return $this;
209
    }
210
}
211