Completed
Push — master ( 392340...6e5734 )
by Sherif
07:20
created

UserRepository   B

Complexity

Total Complexity 46

Size/Duplication

Total Lines 361
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 46
c 1
b 0
f 0
lcom 2
cbo 1
dl 0
loc 361
rs 8.3999

How to fix   Complexity   

Complex Class

Complex classes like UserRepository often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use UserRepository, and based on these observations, apply Extract Interface, too.

1
<?php namespace App\Modules\V1\Acl\Repositories;
2
3
use App\Modules\V1\Core\AbstractRepositories\AbstractRepository;
4
5
class UserRepository extends AbstractRepository
6
{
7
    /**
8
     * Return the model full namespace.
9
     * 
10
     * @return string
11
     */
12
    protected function getModel()
13
    {
14
        return 'App\Modules\V1\Acl\AclUser';
15
    }
16
17
    /**
18
     * Return the logged in user account.
19
     *
20
     * @param  array   $relations
21
     * @return boolean
22
     */
23
    public function account($relations = [])
24
    {
25
        $permissions = [];
26
        $user        = \Core::users()->find(\JWTAuth::parseToken()->authenticate()->id, $relations);
27
        foreach ($user->groups()->get() as $group)
28
        {
29
            $group->permissions->each(function ($permission) use (&$permissions){
30
                $permissions[$permission->model][$permission->id] = $permission->name;
31
            });
32
        }
33
        $user->permissions = $permissions;
34
35
       return $user;
36
    }
37
38
    /**
39
     * Check if the logged in user or the given user 
40
     * has the given permissions on the given model.
41
     * 
42
     * @param  string  $nameOfPermission
43
     * @param  string  $model            
44
     * @param  boolean $user
45
     * @return boolean
46
     */
47
    public function can($nameOfPermission, $model, $user = false )
48
    {      
49
        $user        = $user ?: \JWTAuth::parseToken()->authenticate();
50
        $permissions = [];
51
52
        if ( ! $user = $this->find($user->id, ['groups.permissions'])) 
53
        {
54
            \ErrorHandler::tokenExpired();
55
        }
56
57
        $user->groups->pluck('permissions')->each(function ($permission) use (&$permissions, $model){
58
            $permissions = array_merge($permissions, $permission->where('model', $model)->pluck('name')->toArray()); 
59
        });
60
        
61
        return in_array($nameOfPermission, $permissions);
62
    }
63
64
    /**
65
     * Check if the logged in user has the given group.
66
     * 
67
     * @param  string  $groupName
68
     * @param  integer $userId
69
     * @return boolean
70
     */
71
    public function hasGroup($groupName, $userId = fa;se)
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected ';', expecting ')'
Loading history...
72
    {
73
        $userId = $userId ?: \JWTAuth::parseToken()->authenticate()->id;
74
        $groups = $this->find($userId)->groups;
75
        return $groups->pluck('name')->search($groupName, true) === false ? false : true;
76
    }
77
78
    /**
79
     * Assign the given group ids to the given user.
80
     * 
81
     * @param  integer $user_id    
82
     * @param  array   $group_ids
83
     * @return object
84
     */
85
    public function assignGroups($user_id, $group_ids)
86
    {
87
        \DB::transaction(function () use ($user_id, $group_ids) {
88
            $user = $this->find($user_id);
89
            $user->groups()->detach();
90
            $user->groups()->attach($group_ids);
91
        });
92
93
        return $this->find($user_id);
94
    }
95
96
    /**
97
     * Handle a login request to the application.
98
     * 
99
     * @param  array   $credentials    
100
     * @param  boolean $adminLogin
101
     * @return array
102
     */
103
    public function login($credentials, $adminLogin = false)
104
    {
105
        if ( ! $user = $this->first(['email' => $credentials['email']])) 
106
        {
107
            \ErrorHandler::loginFailed();
108
        }
109
        else if ($adminLogin && $user->groups->pluck('name')->search('Admin', true) === false) 
110
        {
111
            \ErrorHandler::loginFailed();
112
        }
113
        else if ( ! $adminLogin && $user->groups->pluck('name')->search('Admin', true) !== false) 
114
        {
115
            \ErrorHandler::loginFailed();
116
        }
117
        else if ($user->blocked)
118
        {
119
            \ErrorHandler::userIsBlocked();
120
        }
121
        else if ($token = \JWTAuth::attempt($credentials))
122
        {
123
            return ['token' => $token];
124
        }
125
        else
126
        {
127
            \ErrorHandler::loginFailed();
128
        }
129
    }
130
131
    /**
132
     * Handle a social login request of the none admin to the application.
133
     * 
134
     * @param  array   $credentials
135
     * @return array
136
     */
137
    public function loginSocial($credentials)
138
    {
139
        $access_token = $credentials['auth_code'] ? \Socialite::driver($credentials['type'])->getAccessToken($credentials['auth_code']) : $credentials['access_token'];
140
        $user         = \Socialite::driver($credentials['type'])->userFromToken($access_token);
141
142
        if ( ! $user->email)
143
        {
144
            \ErrorHandler::noSocialEmail();
145
        }
146
147
        if ( ! $registeredUser = $this->model->where('email', $user->email)->first()) 
148
        {
149
            $data = ['email' => $user->email, 'password' => ''];
150
            return $this->register($data);
151
        }
152
        else
153
        {
154
            if ( ! \Auth::attempt(['email' => $registeredUser->email, 'password' => '']))
155
            {
156
                \ErrorHandler::userAlreadyRegistered();
157
            }
158
            return $this->login(['email' => $registeredUser->email, 'password' => ''], false);
159
        }
160
    }
161
    
162
    /**
163
     * Handle a registration request.
164
     * 
165
     * @param  array $credentials
166
     * @return array
167
     */
168
    public function register($credentials)
169
    {
170
        return ['token' => \JWTAuth::fromUser($this->model->create($credentials))];
171
    }
172
173
    /**
174
     * Logout the user.
175
     * 
176
     * @return boolean
177
     */
178
    public function logout()
179
    {
180
        return \JWTAuth::invalidate(\JWTAuth::getToken());
181
    }
182
183
    /**
184
     * Block the user.
185
     *
186
     * @param  integer $user_id
187
     * @return object
188
     */
189
    public function block($user_id)
190
    {
191
        if ( ! $user = $this->find($user_id)) 
192
        {
193
            \ErrorHandler::notFound('user');
194
        }
195
        if ( ! $this->hasGroup('Admin'))
196
        {
197
            \ErrorHandler::noPermissions();
198
        }
199
        else if (\JWTAuth::parseToken()->authenticate()->id == $user_id)
200
        {
201
            \ErrorHandler::noPermissions();
202
        }
203
        else if ($user->groups->pluck('name')->search('Admin', true) !== false) 
204
        {
205
            \ErrorHandler::noPermissions();
206
        }
207
208
        $user->blocked = 1;
209
        $user->save();
210
        
211
        return $user;
212
    }
213
214
    /**
215
     * Unblock the user.
216
     *
217
     * @param  integer $user_id
218
     * @return object
219
     */
220
    public function unblock($user_id)
221
    {
222
        if ( ! $this->hasGroup('Admin'))
223
        {
224
            \ErrorHandler::noPermissions();
225
        }
226
227
        $user          = $this->find($user_id);
228
        $user->blocked = 0;
229
        $user->save();
230
231
        return $user;
232
    }
233
234
    /**
235
     * Send a reset link to the given user.
236
     *
237
     * @param  string  $email
238
     * @return void
239
     */
240
    public function sendReset($email)
241
    {
242
        if ( ! $user = $this->model->where('email', $email)->first())
243
        {
244
            \ErrorHandler::notFound('email');
245
        }
246
247
        $url   = $this->config['resetLink'];
248
        $token = \Password::getRepository()->create($user);
249
        
250
        \Mail::send('Acl:resetpassword', ['user' => $user, 'url' => $url, 'token' => $token], function ($m) use ($user) {
251
            $m->to($user->email, $user->name)->subject('Your Password Reset Link');
252
        });
253
    }
254
255
    /**
256
     * Reset the given user's password.
257
     *
258
     * @param  array  $credentials
259
     * @return array
260
     */
261
    public function resetPassword($credentials)
262
    {
263
        $token    = false;
264
        $response = \Password::reset($credentials, function ($user, $password) use (&$token) {
265
            $user->password = bcrypt($password);
266
            $user->save();
267
268
            $token = \JWTAuth::fromUser($user);
269
        });
270
271
        switch ($response) {
272
            case \Password::PASSWORD_RESET:
273
                return ['token' => $token];
274
                
275
            case \Password::INVALID_TOKEN:
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
276
                \ErrorHandler::invalidResetToken('token');
277
278
            case \Password::INVALID_PASSWORD:
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
279
                \ErrorHandler::invalidResetPassword('email');
280
281
            case \Password::INVALID_USER:
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
282
                \ErrorHandler::notFound('user');
283
284
            default:
285
                \ErrorHandler::generalError();
286
        }
287
    }
288
289
    /**
290
     * Change the logged in user password.
291
     *
292
     * @param  array  $credentials
293
     * @return void
294
     */
295
    public function changePassword($credentials)
296
    {
297
        $user = \JWTAuth::parseToken()->authenticate();
298
        if ( ! \Hash::check($credentials['old_password'], $user->password)) 
299
        {
300
            \ErrorHandler::invalidOldPassword();
301
        }
302
303
        $user->password = $credentials['password'];
304
        $user->save();
305
    }
306
307
    /**
308
     * Refresh the expired login token.
309
     *
310
     * @return array
311
     */
312
    public function refreshtoken()
313
    {
314
        $token = \JWTAuth::parseToken()->refresh();
315
316
        return ['token' => $token];
317
    }
318
319
    /**
320
     * Paginate all users in the given group based on the given conditions.
321
     * 
322
     * @param  string  $groupName
323
     * @param  array   $relations
324
     * @param  integer $perPage
325
     * @param  string  $sortBy
326
     * @param  boolean $desc
327
     * @return \Illuminate\Http\Response
328
     */
329
    public function group($conditions, $groupName, $relations, $perPage, $sortBy, $desc)
330
    {   
331
        unset($conditions['page']);
332
        $conditions = $this->constructConditions($conditions, $this->model);
333
        $sort       = $desc ? 'desc' : 'asc';
334
        $model      = call_user_func_array("{$this->getModel()}::with", array($relations));
335
336
        $model->whereHas('groups', function($q) use ($groupName){
337
            $q->where('name', $groupName);
338
        });
339
340
        
341
        if (count($conditions['conditionValues']))
342
        {
343
            $model->whereRaw($conditions['conditionString'], $conditions['conditionValues']);
344
        }
345
346
        if ($perPage) 
347
        {
348
            return $model->orderBy($sortBy, $sort)->paginate($perPage);
349
        }
350
351
        return $model->orderBy($sortBy, $sort)->get();
352
    }
353
354
    /**
355
     * Save the given data to the logged in user.
356
     *
357
     * @param  array $credentials
358
     * @return object
359
     */
360
    public function saveProfile($credentials) 
361
    {
362
        $user = \JWTAuth::parseToken()->authenticate();
363
        $user->save($credentials);
364
365
        return $user;
366
    }
367
}
368