Completed
Push — master ( 51b8e0...0f94ca )
by ARCANEDEV
06:17
created

FacebookProvider   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 177
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 3

Test Coverage

Coverage 41.18%

Importance

Changes 0
Metric Value
wmc 13
lcom 2
cbo 3
dl 0
loc 177
ccs 21
cts 51
cp 0.4118
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getAuthUrl() 0 4 1
A getTokenUrl() 0 4 1
A getAccessTokenResponse() 0 12 2
A getUserByToken() 0 16 2
A mapUserToObject() 0 14 1
A getCodeFields() 0 14 3
A fields() 0 6 1
A asPopup() 0 6 1
A reRequest() 0 5 1
1
<?php namespace Arcanedev\Socialite\OAuth\Two;
2
3
use GuzzleHttp\ClientInterface;
4
use Illuminate\Support\Arr;
5
6
/**
7
 * Class     FacebookProvider
8
 *
9
 * @package  Arcanedev\Socialite\OAuth\Two
10
 * @author   ARCANEDEV <[email protected]>
11
 */
12
class FacebookProvider extends AbstractProvider
13
{
14
    /* ------------------------------------------------------------------------------------------------
15
     |  Properties
16
     | ------------------------------------------------------------------------------------------------
17
     */
18
    /**
19
     * The base Facebook Graph URL.
20
     *
21
     * @var string
22
     */
23
    protected $graphUrl = 'https://graph.facebook.com';
24
25
    /**
26
     * The Graph API version for the request.
27
     *
28
     * @var string
29
     */
30
    protected $version = 'v2.8';
31
32
    /**
33
     * The user fields being requested.
34
     *
35
     * @var array
36
     */
37
    protected $fields = ['name', 'email', 'gender', 'verified', 'link'];
38
39
    /**
40
     * The scopes being requested.
41
     *
42
     * @var array
43
     */
44
    protected $scopes = ['email'];
45
46
    /**
47
     * Display the dialog in a popup view.
48
     *
49
     * @var bool
50
     */
51
    protected $popup = false;
52
53
    /**
54
     * Re-request a declined permission.
55
     *
56
     * @var bool
57
     */
58
    protected $reRequest = false;
59
60
    /* ------------------------------------------------------------------------------------------------
61
     |  Main Functions
62
     | ------------------------------------------------------------------------------------------------
63
     */
64
    /**
65
     * {@inheritdoc}
66
     */
67
    protected function getAuthUrl($state)
68
    {
69
        return $this->buildAuthUrlFromBase("https://www.facebook.com/{$this->version}/dialog/oauth", $state);
70
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75 6
    protected function getTokenUrl()
76
    {
77 6
        return "{$this->graphUrl}/oauth/access_token";
78
    }
79
80
    /**
81
     * {@inheritdoc}
82
     */
83 6
    public function getAccessTokenResponse($code)
84
    {
85 6
        $postKey  = (version_compare(ClientInterface::VERSION, '6') === 1) ? 'form_params' : 'body';
86 6
        $response = $this->getHttpClient()->post($this->getTokenUrl(), [
87 6
            $postKey => $this->getTokenFields($code),
88 3
        ]);
89
90 6
        $data = [];
91 6
        parse_str($response->getBody(), $data);
92
93 6
        return Arr::add($data, 'expires_in', Arr::pull($data, 'expires'));
0 ignored issues
show
Bug introduced by
It seems like $data can also be of type null; however, Illuminate\Support\Arr::pull() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Bug introduced by
It seems like $data can also be of type null; however, Illuminate\Support\Arr::add() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
94
    }
95
96
    /**
97
     * {@inheritdoc}
98
     */
99
    protected function getUserByToken($token)
100
    {
101
        $meUrl = "{$this->graphUrl}/{$this->version}/me?access_token={$token}&fields=".implode(',', $this->fields);
102
103
        if ( ! empty($this->clientSecret)) {
104
            $meUrl .= '&appsecret_proof='.hash_hmac('sha256', $token, $this->clientSecret);
105
        }
106
107
        $response = $this->getHttpClient()->get($meUrl, [
108
            'headers' => [
109
                'Accept' => 'application/json',
110
            ],
111
        ]);
112
113
        return json_decode($response->getBody(), true);
114
    }
115
116
    /**
117
     * {@inheritdoc}
118
     */
119 6
    protected function mapUserToObject(array $user)
120
    {
121 6
        $avatarUrl = "{$this->graphUrl}/{$this->version}/".$user['id'].'/picture';
122
123 6
        return (new User)->setRaw($user)->map([
124 6
            'id'              => $user['id'],
125 3
            'nickname'        => null,
126 6
            'name'            => Arr::get($user, 'name'),
127 6
            'email'           => Arr::get($user, 'email'),
128 6
            'avatar'          => "{$avatarUrl}?type=normal",
129 6
            'avatar_original' => "{$avatarUrl}?width=1920",
130 6
            'profileUrl'      => Arr::get($user, 'link'),
131 3
        ]);
132
    }
133
134
    /**
135
     * {@inheritdoc}
136
     */
137
    protected function getCodeFields($state = null)
138
    {
139
        $fields = parent::getCodeFields($state);
140
141
        if ($this->popup) {
142
            $fields['display'] = 'popup';
143
        }
144
145
        if ($this->reRequest) {
146
            $fields['auth_type'] = 'rerequest';
147
        }
148
149
        return $fields;
150
    }
151
152
    /**
153
     * Set the user fields to request from Facebook.
154
     *
155
     * @param  array  $fields
156
     *
157
     * @return self
158
     */
159
    public function fields(array $fields)
160
    {
161
        $this->fields = $fields;
162
163
        return $this;
164
    }
165
166
    /**
167
     * Set the dialog to be displayed as a popup.
168
     *
169
     * @return self
170
     */
171
    public function asPopup()
172
    {
173
        $this->popup = true;
174
175
        return $this;
176
    }
177
178
    /**
179
     * Re-request permissions which were previously declined.
180
     *
181
     * @return self
182
     */
183
    public function reRequest()
184
    {
185
        $this->reRequest = true;
186
        return $this;
187
    }
188
}
189