Passed
Push — master ( ef8807...c1ca83 )
by Mihail
05:17
created

Apps/ActiveRecord/User.php (4 issues)

1
<?php
2
3
namespace Apps\ActiveRecord;
4
5
use Ffcms\Core\App as MainApp;
6
use Ffcms\Core\Arch\ActiveModel;
7
use Ffcms\Core\Helper\Type\Any;
8
use Ffcms\Core\Helper\Type\Obj;
9
use Ffcms\Core\Helper\Type\Str;
10
use Ffcms\Core\Interfaces\iUser;
11
12
/**
13
 * Class User. Active record model for user auth data
14
 * @package Apps\ActiveRecord
15
 * @property int $id
16
 * @property string $login
17
 * @property string $email
18
 * @property string $password
19
 * @property int $role_id
20
 * @property string $approve_token
21
 * @property string $created_at
22
 * @property string $updated_at
23
 * @property WallPost $wall
24
 * @property Profile|null $profile
25
 * @property Role $role
26
 * @property UserLog $log
27
 * @property UserProvider $provider
28
 */
29
class User extends ActiveModel implements iUser
30
{
31
    protected $casts = [
32
        'id' => 'integer',
33
        'login' => 'string',
34
        'email' => 'string',
35
        'role_id' => 'integer',
36
        'approve_token' => 'string'
37
    ];
38
39
    private $openidProvider;
40
41
    /**
42
     * Get user object relation. If $user_id is null - get current session user
43
     * @param string|int|null $id
44
     * @return self|null
45
     */
46
    public static function identity(?string $id = null): ?self
47
    {
48
        if (!$id) {
49
            $id = MainApp::$Session->get('ff_user_id');
50
        }
51
52
        // check if id is looks like integer
53
        if (!Any::isInt($id) || (int)$id < 1) {
54
            return null;
55
        }
56
57
        // check in memory cache object
58
        if (MainApp::$Memory->get('user.object.cache.' . $id)) {
59
            return MainApp::$Memory->get('user.object.cache.' . $id);
60
        }
61
62
        // not founded in memory? lets make query
63
        $user = self::with(['profile', 'role'])
64
            ->find($id);
65
66
        // store cache and return object
67
        MainApp::$Memory->set('user.object.cache.' . $user->id, $user);
68
        return $user;
69
    }
70
71
    /**
72
     * Get current user id if auth
73
     * @return int|null
74
     */
75
    public function getId(): ?int
76
    {
77
        return (int)$this->id;
78
    }
79
80
    /**
81
     * Get user param
82
     * @param string $param
83
     * @param null|string $defaultValue
84
     * @return string|int|null
85
     */
86
    public function getParam(string $param, ?string $defaultValue = null): ?string
87
    {
88
        return $this->{$param} ?? $defaultValue;
89
    }
90
91
    /**
92
     * Check if current user session is auth
93
     * @return bool
94
     */
95
    public static function isAuth(): bool
96
    {
97
        // get data from session
98
        $sessionUserId = (int)MainApp::$Session->get('ff_user_id', 0);
99
100
        // check if session contains user id data
101
        if ($sessionUserId < 1) {
102
            return false;
103
        }
104
105
        // find user identity
106
        $identity = self::identity($sessionUserId);
107
        if (!$identity) { // check if this $id exist
0 ignored issues
show
$identity is of type Apps\ActiveRecord\User, thus it always evaluated to true.
Loading history...
108
            MainApp::$Session->invalidate(); // destory session data - it's not valid!
109
            return false;
110
        }
111
112
        // check if user is approved. Default value: 0, can be null, '' or the same.
113
        if ($identity->approve_token) {
114
            return false;
115
        }
116
117
        return ($identity->id > 0 && $identity->id === $sessionUserId);
118
    }
119
120
    /**
121
     * Check if user with $id exist
122
     * @param string|int|null $id
123
     * @return bool
124
     */
125
    public static function isExist(?string $id = null): bool
126
    {
127
        if (!$id || !Any::isInt($id)) {
128
            return false;
129
        }
130
131
        $find = MainApp::$Memory->get('user.counter.cache.' . $id);
132
        if (!$find) {
133
            $find = self::where('id', $id)->count();
134
            MainApp::$Memory->set('user.counter.cache.' . $id, $find);
135
        }
136
137
        return (int)$find === 1;
138
    }
139
140
    /**
141
     * Check if use with $email is exist
142
     * @param string $email
143
     * @return bool
144
     */
145
    public static function isMailExist(?string $email = null): bool
146
    {
147
        if (!Any::isStr($email) || !Str::isEmail($email)) {
0 ignored issues
show
It seems like $email can also be of type null; however, parameter $string of Ffcms\Core\Helper\Type\Str::isEmail() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

147
        if (!Any::isStr($email) || !Str::isEmail(/** @scrutinizer ignore-type */ $email)) {
Loading history...
148
            return false;
149
        }
150
151
        return self::where('email', $email)->count() > 0;
152
    }
153
154
    /**
155
     * Check if user with $login is exist
156
     * @param string $login
157
     * @return bool
158
     */
159
    public static function isLoginExist(?string $login = null): bool
160
    {
161
        if (!Any::isStr($login) || Any::isEmpty($login) || Str::length($login) < 2) {
162
            return false;
163
        }
164
165
        return self::where('login', $login)->count() > 0;
166
    }
167
168
    /**
169
     * Get user person like a object via email
170
     * @param string|null $email
171
     * @return null|self
172
     */
173
    public static function getIdentityViaEmail(?string $email = null)
174
    {
175
        if (!self::isMailExist($email)) {
176
            return null;
177
        }
178
179
        return self::where('email', $email)->first();
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::where('email', $email)->first() also could return the type Ffcms\Core\Arch\ActiveModel which is incompatible with the return type mandated by Ffcms\Core\Interfaces\iUser::getIdentityViaEmail() of Ffcms\Core\Interfaces\iUser|null.
Loading history...
180
    }
181
182
    /**
183
     * Get user wall post relation
184
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
185
     */
186
    public function wall()
187
    {
188
        return $this->hasMany(WallPost::class, 'target_id');
189
    }
190
191
    /**
192
     * Get user role relation object.
193
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
194
     */
195
    public function role()
196
    {
197
        return $this->hasOne(Role::class, 'id', 'role_id');
198
    }
199
200
    /**
201
     * Get user profile relation object.
202
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
203
     */
204
    public function profile()
205
    {
206
        return $this->hasOne(Profile::class, 'user_id', 'id');
207
    }
208
209
    /**
210
     * Get user logs relation object
211
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
212
     */
213
    public function log()
214
    {
215
        return $this->hasMany(UserLog::class, 'user_id');
216
    }
217
218
    /**
219
     * Get user social providers data
220
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
221
     */
222
    public function provider()
223
    {
224
        return $this->hasMany(UserProvider::class, 'user_id');
225
    }
226
227
    /**
228
     * Check if target user in blacklist
229
     * @param string|int|null $target
230
     * @return bool
231
     */
232
    public function inBlacklist(?string $target = null): bool
233
    {
234
        if (!$target || (int)$target < 1) {
235
            return false;
236
        }
237
238
        return Blacklist::have($this->getId(), $target);
0 ignored issues
show
$target of type string is incompatible with the type integer expected by parameter $targetId of Apps\ActiveRecord\Blacklist::have(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

238
        return Blacklist::have($this->getId(), /** @scrutinizer ignore-type */ $target);
Loading history...
239
    }
240
241
    /**
242
     * Set openID library dependence object. Do not use this function, if you have no idia how it work
243
     * @param $provider
244
     */
245
    public function setOpenidInstance($provider): void
246
    {
247
        $this->openidProvider = $provider;
248
    }
249
250
    /**
251
     * Get openid provider library. Default - hybridauth
252
     * @return \Hybrid_Auth
253
     */
254
    public function getOpenidInstance()
255
    {
256
        return $this->openidProvider;
257
    }
258
}
259