Passed
Push — master ( 28a360...d194a0 )
by Mihail
11:20
created

User::setOpenidInstance()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 1
eloc 2
c 1
b 1
f 0
nc 1
nop 1
dl 0
loc 4
rs 10
1
<?php
2
3
namespace Apps\ActiveRecord;
4
5
use Ffcms\Core\Arch\ActiveModel;
6
use Ffcms\Core\Interfaces\iUser;
7
use Ffcms\Core\App as MainApp;
8
use Ffcms\Core\Helper\Type\Obj;
9
use Ffcms\Core\Helper\Type\Str;
10
11
/**
12
 * Class User. Active record model for user auth data
13
 * @package Apps\ActiveRecord
14
 * @property int $id
15
 * @property string $login
16
 * @property string $email
17
 * @property string $password
18
 * @property int $role_id
19
 * @property string $approve_token
20
 * @property string $created_at
21
 * @property string $updated_at
22
 */
23
class User extends ActiveModel implements iUser
24
{
25
    private $openidProvider;
26
27
    /**
28
     * Get user object relation. If $user_id is null - get current session user
29
     * @param int|null $user_id
30
     * @return self|null
31
     */
32
    public static function identity($user_id = null)
33
    {
34
        if ($user_id === null) {
35
            $user_id = MainApp::$Session->get('ff_user_id');
36
        }
37
38
        // convert id to real integer
39
        $user_id = (int)$user_id;
40
41
        if (!Obj::isInt($user_id) || $user_id < 1) {
42
            return null;
43
        }
44
45
        // check in memory cache object
46
        if (MainApp::$Memory->get('user.object.cache.' . $user_id) !== null) {
47
            return MainApp::$Memory->get('user.object.cache.' . $user_id);
48
        }
49
        // not founded in memory? lets make query
50
        $user = self::find($user_id);
51
        // no rows? lets end this shit ;)
52
        if ($user === null || $user->id < 1) {
53
            return null;
54
        }
55
56
        // store cache and return object
57
        MainApp::$Memory->set('user.object.cache.' . $user->id, $user);
58
        return $user;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $user; (Ffcms\Core\Arch\ActiveModel) is incompatible with the return type declared by the interface Ffcms\Core\Interfaces\iUser::identity of type null|Ffcms\Core\Interfaces\iUser.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
59
    }
60
61
    /**
62
     * Get current user id if auth
63
     * @return int
64
     */
65
    public function getId()
66
    {
67
        return (int)$this->id;
68
    }
69
70
    /**
71
     * Get user param
72
     * @param string $param
73
     * @param null|string $defaultValue
74
     * @return string|int|null
75
     */
76
    public function getParam($param, $defaultValue = null)
77
    {
78
        return $this->{$param} === null ? $defaultValue : $this->{$param};
79
    }
80
81
    /**
82
     * Check if current user session is auth
83
     * @return bool
84
     */
85
    public static function isAuth()
86
    {
87
        // get data from session
88
        $sessionUserId = (int)MainApp::$Session->get('ff_user_id', 0);
89
90
        // check if session contains user id data
91
        if ($sessionUserId < 1) {
92
            return false;
93
        }
94
95
        // find user identity
96
        $identity = self::identity($sessionUserId);
97
        if ($identity === null) { // check if this $id exist
98
            MainApp::$Session->invalidate(); // destory session data - it's not valid!
99
            return false;
100
        }
101
102
        // check if user is approved. Default value: 0, can be null, '' or the same.
103
        if ($identity->approve_token !== '0' && Str::length($identity->approve_token) > 0) {
104
            return false;
105
        }
106
107
        return ((int)$identity->id > 0 && (int)$identity->id === $sessionUserId);
108
    }
109
110
    /**
111
     * Check if user with $id exist
112
     * @param int $id
113
     * @return bool
114
     */
115
    public static function isExist($id)
116
    {
117
        if (!Obj::isLikeInt($id) || $id < 1) {
118
            return false;
119
        }
120
121
        // convert id to real integer
122
        $id = (int)$id;
123
124
        $find = MainApp::$Memory->get('user.counter.cache.' . $id);
125
        if ($find === null) {
126
            $find = self::where('id', '=', $id)->count();
127
            MainApp::$Memory->set('user.counter.cache.' . $id, $find);
128
        }
129
130
        return $find === 1;
131
    }
132
133
    /**
134
     * Check if use with $email is exist
135
     * @param string $email
136
     * @return bool
137
     */
138 View Code Duplication
    public static function isMailExist($email)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
139
    {
140
        if (!Obj::isString($email) || !Str::isEmail($email)) {
141
            return false;
142
        }
143
144
        return self::where('email', '=', $email)->count() > 0;
145
    }
146
147
    /**
148
     * Check if user with $login is exist
149
     * @param string $login
150
     * @return bool
151
     */
152 View Code Duplication
    public static function isLoginExist($login)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
153
    {
154
        if (!Obj::isString($login) || Str::length($login) < 1) {
155
            return false;
156
        }
157
158
        return self::where('login', '=', $login)->count() > 0;
159
    }
160
161
    /**
162
     * Get user person like a object via email
163
     * @param string $email
164
     * @return null|static
165
     */
166
    public static function getIdentityViaEmail($email)
167
    {
168
        if (!self::isMailExist($email)) {
169
            return null;
170
        }
171
172
        return self::where('email', '=', $email)->first();
0 ignored issues
show
Bug Compatibility introduced by
The expression self::where('email', '=', $email)->first(); of type Ffcms\Core\Arch\ActiveModel|null adds the type Ffcms\Core\Arch\ActiveModel to the return on line 172 which is incompatible with the return type declared by the interface Ffcms\Core\Interfaces\iUser::getIdentityViaEmail of type Ffcms\Core\Interfaces\iUser|null.
Loading history...
173
    }
174
175
    /**
176
     * Get relation one-to-many for user wall posts. Ex: User::find(1)->getWall()->offset()
177
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
178
     */
179
    public function getWall()
180
    {
181
        return $this->hasMany('Apps\\ActiveRecord\\WallPost', 'target_id');
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->hasMany('A...allPost', 'target_id'); (Illuminate\Database\Eloquent\Relations\HasMany) is incompatible with the return type declared by the interface Ffcms\Core\Interfaces\iUser::getWall of type Apps\ActiveRecord\WallPost.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
182
    }
183
184
    /**
185
     * Get user role object
186
     * @return \Apps\ActiveRecord\Role|null
187
     */
188
    public function getRole()
189
    {
190
        return Role::get($this->role_id);
191
    }
192
193
    /**
194
     * Get user profile data as relation of user table. Ex: User::find(1)->getProfile()->nick
195
     * @return \Apps\ActiveRecord\Profile
196
     */
197
    public function getProfile()
198
    {
199
        // lets find profile identity via current user id
200
        $object = Profile::identity($this->getId());
201
        // is not exist? Hmmm, lets create it!
202
        if ($object === null && $this->getId() > 0) {
203
            $object = new Profile();
204
            $object->user_id = $this->getId();
205
            $object->save();
206
        }
207
        // return result ;)
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
208
        return $object;
209
    }
210
211
    /**
212
     * Get user logs
213
     * @return \Apps\ActiveRecord\UserLog
214
     */
215
    public function getLogs()
216
    {
217
        return $this->hasMany('Apps\\ActiveRecord\\UserLog', 'user_id');
218
    }
219
220
    /**
221
     * Get user social providers data
222
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
223
     */
224
    public function getProviders()
225
    {
226
        return $this->hasMany('Apps\ActiveRecord\UserProvider', 'user_id');
227
    }
228
229
    /**
230
     * Check if target user in blacklist
231
     * @param int $target_id
232
     * @return bool
233
     */
234
    public function inBlacklist($target_id)
235
    {
236
        return Blacklist::have($this->getId(), $target_id);
237
    }
238
239
    /**
240
     * Set openID library dependence object. Do not use this function, if you have no idia how it work
241
     * @param $provider
242
     */
243
    public function setOpenidInstance($provider)
244
    {
245
        $this->openidProvider = $provider;
246
    }
247
248
    /**
249
     * Get openid provider library. Default - hybridauth
250
     * @return \Hybrid_Auth
251
     */
252
    public function getOpenidInstance()
253
    {
254
        return $this->openidProvider;
255
    }
256
}