Completed
Push — master ( a53bf3...ad40b1 )
by Igor
01:39
created

SocialAuth::getUser()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 26
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 26
rs 8.8571
c 0
b 0
f 0
cc 3
eloc 15
nc 4
nop 0
1
<?php
2
3
namespace app\modules\auth\services;
4
5
use yii\authclient\ClientInterface;
6
use app\modules\auth\oauth\ParserInterface;
7
use app\models\entity\{User, UserProvider};
8
9
/**
10
 * SocialAuth handles successful authentication
11
 */
12
class SocialAuth
13
{
14
    /**
15
     * @var ParserInterface
16
     */
17
    private $parser;
18
    /**
19
     * @var ClientInterface
20
     */
21
    private $provider;
22
    /**
23
     * @var int
24
     */
25
    private $providerType;
26
27
    /**
28
     * @param ParserInterface $parser
29
     * @param ClientInterface $provider
30
     * @return User
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
31
     */
32
    public function __construct(ParserInterface $parser, ClientInterface $provider)
33
    {
34
        $this->parser = $parser;
35
        $this->provider = $provider;
36
        $this->providerType = UserProvider::getTypeByName($provider->id);
0 ignored issues
show
Bug introduced by
Accessing id on the interface yii\authclient\ClientInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
37
    }
38
39
    public function getUser(): User
40
    {
41
        $user = null;
42
43
        $existUserProvider = UserProvider::find()
44
            ->provider($this->providerType, $this->parser->profileId())
45
            ->one();
46
47
        if ($existUserProvider) {
48
            $user = $existUserProvider->user;
49
50
            // if exist then update access tokens
51
            $existUserProvider->setAttributes($this->providerAttributes(), false);
52
            $existUserProvider->save();
53
        }
54
55
        if (!is_object($user)) {
56
            $user = new User();
57
58
            $user->email = $this->parser->email();
59
            $user->setProfile($this->profileAttributes());
60
            $user->setProviders($this->providerAttributes());
61
        }
62
63
        return $user;
64
    }
65
66
    private function profileAttributes()
67
    {
68
        return [
69
            'full_name' => $this->parser->fullName(),
70
            'photo' => $this->parser->photo(),
71
        ];
72
    }
73
74
    private function providerAttributes()
75
    {
76
        return [
77
            'type' => $this->providerType,
78
            'profile_id' => $this->parser->profileId(),
79
            'profile_url' => $this->parser->profileUrl(),
80
            'access_token' => $this->parser->accessToken(),
81
            'access_token_secret' => $this->parser->accessTokenSecret(),
82
        ];
83
    }
84
}
85