Completed
Push — 3.x ( 957ed2...aeddc7 )
by Дмитрий
03:25
created

LinkedIn::getIdentity()   B

Complexity

Conditions 9
Paths 4

Size

Total Lines 59
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 12.994

Importance

Changes 5
Bugs 0 Features 0
Metric Value
cc 9
eloc 34
c 5
b 0
f 0
nc 4
nop 1
dl 0
loc 59
ccs 19
cts 30
cp 0.6333
crap 12.994
rs 8.0555

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * SocialConnect project
4
 * @author: Patsura Dmitry https://github.com/ovr <[email protected]>
5
 * @author: Bogdan Popa https://github.com/icex <[email protected]>
6
 */
7
declare(strict_types=1);
8
9
namespace SocialConnect\OAuth2\Provider;
10
11
use SocialConnect\Common\ArrayHydrator;
12
use SocialConnect\Provider\AccessTokenInterface;
13
use SocialConnect\Common\Entity\User;
14
15
class LinkedIn extends \SocialConnect\OAuth2\AbstractProvider
16
{
17
    const NAME = 'linkedin';
18
19
    /**
20
     * @var array
21
     */
22
    protected $options = [
23
        /**
24
         * It's needed additional API call to fetch email, by default it's disabled
25
         */
26
        'fetch_emails' => false
27
    ];
28
29
    /**
30
     * {@inheritdoc}
31
     */
32 4
    public function getBaseUri()
33
    {
34 4
        return 'https://api.linkedin.com/v2/';
35
    }
36
37
    /**
38
     * {@inheritdoc}
39
     */
40 2
    public function getAuthorizeUri()
41
    {
42 2
        return 'https://www.linkedin.com/oauth/v2/authorization';
43
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48 2
    public function getRequestTokenUri()
49
    {
50 2
        return 'https://www.linkedin.com/oauth/v2/accessToken';
51
    }
52
53
    /**
54
     * {@inheritdoc}
55
     */
56 3
    public function getName()
57
    {
58 3
        return self::NAME;
59
    }
60
61
    /**
62
     * {@inheritDoc}
63
     */
64 3
    public function prepareRequest(string $method, string $uri, array &$headers, array &$query, AccessTokenInterface $accessToken = null): void
65
    {
66 3
        $headers['Content-Type'] = 'application/json';
67
68 3
        if ($accessToken) {
69 3
            $headers['Authorization'] = "Bearer {$accessToken->getToken()}";
70
        }
71 3
    }
72
73
    protected function fetchPrimaryEmail(AccessTokenInterface $accessToken, User $user)
74
    {
75
        $response = $this->request(
76
            'GET',
77
            'emailAddress',
78
            [
79
                'q' => 'members',
80
                'projection' => '(elements*(primary,type,handle~))'
81
            ],
82
            $accessToken
83
        );
84
85
        if (isset($response['elements'])) {
86
            $element = array_shift($response['elements']);
87
            if ($element && isset($element['handle~']) && isset($element['handle~']['emailAddress'])) {
88
                $user->email = $element['handle~']['emailAddress'];
89
            }
90
        }
91
    }
92
93
    /**
94
     * {@inheritdoc}
95
     */
96 3
    public function getIdentity(AccessTokenInterface $accessToken)
97
    {
98 3
        $query = [];
99
100
        // @link https://docs.microsoft.com/en-us/linkedin/shared/integrations/people/profile-api?context=linkedin/consumer/context
101 3
        $fields = $this->getArrayOption(
102 3
            'identity.fields',
103
            [
104 3
                'id',
105
                'firstName',
106
                'lastName',
107
                'profilePicture(displayImage~:playableStreams)',
108
            ]
109
        );
110 3
        if ($fields) {
111 3
            $query['projection'] = '(' . implode(',', $fields) . ')';
112
        }
113
114 3
        $response = $this->request(
115 3
            'GET',
116 3
            'me',
117
            $query,
118
            $accessToken
119
        );
120
121 1
        $hydrator = new ArrayHydrator([
122 1
            'id'           => 'id',
123 1
            'emailAddress' => 'email',
124
            'firstName'    => static function ($value, User $user) {
125
                if ($value['localized']) {
126
                    $user->firstname = array_pop($value['localized']);
127
                }
128 1
            },
129
            'lastName'     => static function ($value, User $user) {
130
                if ($value['localized']) {
131
                    $user->lastname = array_pop($value['localized']);
132
                }
133 1
            },
134
            'profilePicture'     => static function ($value, User $user) {
135
                if (isset($value['displayImage~']) && isset($value['displayImage~']['elements'])) {
136
                    $biggestElement = array_shift($value['displayImage~']['elements']);
137
                    if (isset($biggestElement['identifiers'])) {
138
                        $biggestElementIdentifier = array_pop($biggestElement['identifiers']);
139
                        if (isset($biggestElementIdentifier['identifier'])) {
140
                            $user->pictureURL = $biggestElementIdentifier['identifier'];
141
                        }
142
                    }
143
                }
144 1
            },
145
        ]);
146
147
        /** @var User $identity */
148 1
        $identity = $hydrator->hydrate(new User(), $response);
149
150 1
        if ($this->getBoolOption('fetch_emails', false)) {
151
            $this->fetchPrimaryEmail($accessToken, $identity);
152
        }
153
154 1
        return $identity;
155
    }
156
}
157