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

LinkedIn::fetchPrimaryEmail()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 10
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 16
ccs 0
cts 9
cp 0
crap 30
rs 9.6111
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