Completed
Push — master ( e3ab92...3aa844 )
by Travis
02:51
created

SocialAuthController::getProviderDetails()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 16
rs 9.2
cc 4
eloc 9
nc 5
nop 1
1
<?php
2
3
namespace NukaCode\Users\Http\Controllers;
4
5
use App\Http\Controllers\BaseController;
6
use App\Models\User;
7
use Laravel\Socialite\Facades\Socialite;
8
use NukaCode\Users\Events\UserLoggedIn;
9
use NukaCode\Users\Events\UserRegistered;
10
use NukaCode\Users\Models\User\Social;
11
12
class SocialAuthController extends BaseController
13
{
14
    /**
15
     * @var array
16
     */
17
    protected $providers;
18
19
    /**
20
     * @var string
21
     */
22
    protected $driver;
23
24
    /**
25
     * @var array
26
     */
27
    protected $scopes;
28
29
    /**
30
     * @var array
31
     */
32
    protected $extras;
33
34
    public function __construct()
35
    {
36
        $this->providers = collect(config('users.providers'))->keyBy('driver');
0 ignored issues
show
Documentation Bug introduced by
It seems like collect(config('users.pr...ers'))->keyBy('driver') of type object<Illuminate\Support\Collection> is incompatible with the declared type array of property $providers.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
37
    }
38
39
    /**
40
     * Redirect the user to the social providers auth page.
41
     *
42
     * @param null|string $provider
43
     *
44
     * @return mixed
45
     */
46
    public function login($provider = null)
47
    {
48
        $this->getProviderDetails($provider);
49
50
        return Socialite::driver($this->driver)
51
                        ->scopes($this->scopes)
52
                        ->with($this->extras)
53
                        ->redirect();
54
    }
55
56
    /**
57
     * Use the returned user to register (if needed) and login.
58
     *
59
     * @param null|string $provider
60
     *
61
     * @return mixed
62
     */
63
    public function callback($provider = null)
64
    {
65
        $this->getProviderDetails($provider);
66
67
        $socialUser = Socialite::driver($this->driver)->user();
68
        $user       = User::where('email', $socialUser->getEmail())
69
                          ->orWhereHas('socials', function ($query) use ($socialUser) {
70
                              $query->where('email', $socialUser->getEmail())->where('provider', $this->driver);
71
                          })->first();
72
73
        if (is_null($user)) {
74
            $user = $this->register($socialUser);
75
        }
76
77
        if (! $user->hasProvider($this->driver)) {
78
            $user->addSocial($socialUser, $this->driver);
79
        } else {
80
            $user->getProvider($this->driver)->updateFromProvider($socialUser, $this->driver);
81
        }
82
83
        auth()->login($user, request('remember', false));
84
        event(new UserLoggedIn($user, $socialUser));
0 ignored issues
show
Documentation introduced by
new \NukaCode\Users\Even...dIn($user, $socialUser) is of type object<NukaCode\Users\Events\UserLoggedIn>, but the function expects a 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...
85
86
        return redirect()
87
            ->intended(route('home'))
88
            ->with('message', 'You have been logged in.');
89
    }
90
91
    /**
92
     * Create a new user from a social user.
93
     *
94
     * @param $socialUser
95
     *
96
     * @return mixed
97
     */
98
    private function register($socialUser)
99
    {
100
        $names    = explode(' ', $socialUser->getName());
101
        $username = is_null($socialUser->getNickname()) ? $socialUser->getEmail() : $socialUser->getNickname();
102
103
        $userDetails = [
104
            'username'     => $username,
105
            'email'        => $socialUser->getEmail(),
106
            'first_name'   => isset($names[0]) ? $names[0] : null,
107
            'last_name'    => isset($names[1]) ? $names[1] : null,
108
            'display_name' => $username,
109
        ];
110
111
        $user = User::create($userDetails);
112
        $user->assignRole(config('users.default'));
113
        $user->addSocial($socialUser, $this->driver);
114
115
        event(new UserRegistered($user));
0 ignored issues
show
Documentation introduced by
new \NukaCode\Users\Events\UserRegistered($user) is of type object<NukaCode\Users\Events\UserRegistered>, but the function expects a 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...
116
117
        return $user;
118
    }
119
120
    /**
121
     * Log the user out.
122
     *
123
     * @return mixed
124
     */
125
    public function logout()
126
    {
127
        auth()->logout();
128
129
        return redirect(route('home'))
130
            ->with('message', 'You have been logged out.');
131
    }
132
133
    /**
134
     * Find the provider's driver, scopes and extras based on a given provider name.
135
     *
136
     * @param $provider
137
     *
138
     * @throws \Exception
139
     */
140
    private function getProviderDetails($provider)
141
    {
142
        if (empty($this->providers)) {
143
            throw new \Exception('No Providers have been set in users config.');
144
        }
145
146
        $provider = is_null($provider) ? $this->providers->first() : $this->providers->get($provider);
147
148
        if (is_null($provider['driver'])) {
149
            throw new \InvalidArgumentException('You must set a social driver to use the social authenticating features.');
150
        }
151
152
        $this->driver = $provider['driver'];
153
        $this->scopes = $provider['scopes'];
154
        $this->extras = $provider['extras'];
155
    }
156
}
157