Completed
Pull Request — dev (#235)
by Alies
07:06
created

UserRepository::create()   B

Complexity

Conditions 9
Paths 1

Size

Total Lines 25
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 15
nc 1
nop 1
dl 0
loc 25
rs 8.0555
c 0
b 0
f 0
1
<?php
2
3
namespace App\Repositories\Backend\Auth;
4
5
use App\Models\Auth\User;
6
use Illuminate\Support\Facades\DB;
7
use App\Exceptions\GeneralException;
8
use App\Repositories\BaseRepository;
9
use App\Events\Backend\Auth\User\UserCreated;
10
use App\Events\Backend\Auth\User\UserUpdated;
11
use App\Events\Backend\Auth\User\UserRestored;
12
use App\Events\Backend\Auth\User\UserConfirmed;
13
use Illuminate\Pagination\LengthAwarePaginator;
14
use App\Events\Backend\Auth\User\UserDeactivated;
15
use App\Events\Backend\Auth\User\UserReactivated;
16
use App\Events\Backend\Auth\User\UserUnconfirmed;
17
use App\Events\Backend\Auth\User\UserPasswordChanged;
18
use App\Notifications\Backend\Auth\UserAccountActive;
19
use App\Events\Backend\Auth\User\UserPermanentlyDeleted;
20
use App\Notifications\Frontend\Auth\UserNeedsConfirmation;
21
22
/**
23
 * Class UserRepository.
24
 */
25
class UserRepository extends BaseRepository
26
{
27
    /**
28
     * @return string
29
     */
30
    public function model()
31
    {
32
        return User::class;
33
    }
34
35
    /**
36
     * @return mixed
37
     */
38
    public function getUnconfirmedCount() : int
39
    {
40
        return $this->model
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->model->whe...confirmed', 0)->count() could return the type Illuminate\Database\Eloquent\Builder which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
41
            ->where('confirmed', 0)
42
            ->count();
43
    }
44
45
    /**
46
     * @param int    $paged
47
     * @param string $orderBy
48
     * @param string $sort
49
     *
50
     * @return mixed
51
     */
52
    public function getActivePaginated($paged = 25, $orderBy = 'created_at', $sort = 'desc') : LengthAwarePaginator
53
    {
54
        return $this->model
55
            ->with('providers')
56
            ->active()
57
            ->orderBy($orderBy, $sort)
58
            ->paginate($paged);
59
    }
60
61
    /**
62
     * @param int    $paged
63
     * @param string $orderBy
64
     * @param string $sort
65
     *
66
     * @return LengthAwarePaginator
67
     */
68
    public function getInactivePaginated($paged = 25, $orderBy = 'created_at', $sort = 'desc') : LengthAwarePaginator
69
    {
70
        return $this->model
71
            ->with('providers')
72
            ->active(false)
73
            ->orderBy($orderBy, $sort)
74
            ->paginate($paged);
75
    }
76
77
    /**
78
     * @param int    $paged
79
     * @param string $orderBy
80
     * @param string $sort
81
     *
82
     * @return LengthAwarePaginator
83
     */
84
    public function getDeletedPaginated($paged = 25, $orderBy = 'created_at', $sort = 'desc') : LengthAwarePaginator
85
    {
86
        return $this->model
87
            ->with('providers')
88
            ->onlyTrashed()
89
            ->orderBy($orderBy, $sort)
90
            ->paginate($paged);
91
    }
92
93
    /**
94
     * @param array $data
95
     *
96
     * @return User
97
     * @throws \Exception
98
     * @throws \Throwable
99
     */
100
    public function create(array $data) : User
101
    {
102
        return DB::transaction(function () use ($data) {
103
            $user = parent::create([
104
                'first_name' => $data['first_name'],
105
                'last_name' => $data['last_name'],
106
                'email' => $data['email'],
107
                'password' => $data['password'],
108
                'active' => isset($data['active']) && $data['active'] == '1' ? 1 : 0,
109
                'confirmation_code' => md5(uniqid(mt_rand(), true)),
110
                'confirmed' => isset($data['confirmed']) && $data['confirmed'] == '1' ? 1 : 0,
111
            ]);
112
113
            if ($user) {
0 ignored issues
show
introduced by
$user is of type Illuminate\Database\Eloquent\Model, thus it always evaluated to true.
Loading history...
114
                //Send confirmation email if requested and account approval is off
115
                if (isset($data['confirmation_email']) && $user->confirmed == 0 && ! config('access.users.requires_approval')) {
116
                    $user->notify(new UserNeedsConfirmation($user->confirmation_code));
117
                }
118
119
                event(new UserCreated($user));
120
121
                return $user;
122
            }
123
124
            throw new GeneralException(__('exceptions.backend.access.users.create_error'));
125
        });
126
    }
127
128
    /**
129
     * @param User  $user
130
     * @param array $data
131
     *
132
     * @return User
133
     * @throws GeneralException
134
     * @throws \Exception
135
     * @throws \Throwable
136
     */
137
    public function update(User $user, array $data) : User
138
    {
139
        $this->checkUserByEmail($user, $data['email']);
140
141
        // See if adding any additional permissions
142
        if (! isset($data['permissions']) || ! count($data['permissions'])) {
143
            $data['permissions'] = [];
144
        }
145
146
        return DB::transaction(function () use ($user, $data) {
147
            if ($user->update([
148
                'first_name' => $data['first_name'],
149
                'last_name' => $data['last_name'],
150
                'email' => $data['email'],
151
            ])) {
152
                event(new UserUpdated($user));
153
154
                return $user;
155
            }
156
157
            throw new GeneralException(__('exceptions.backend.access.users.update_error'));
158
        });
159
    }
160
161
    /**
162
     * @param User $user
163
     * @param      $input
164
     *
165
     * @return User
166
     * @throws GeneralException
167
     */
168
    public function updatePassword(User $user, $input) : User
169
    {
170
        if ($user->update(['password' => $input['password']])) {
171
            event(new UserPasswordChanged($user));
172
173
            return $user;
174
        }
175
176
        throw new GeneralException(__('exceptions.backend.access.users.update_password_error'));
177
    }
178
179
    /**
180
     * @param User $user
181
     * @param      $status
182
     *
183
     * @return User
184
     * @throws GeneralException
185
     */
186
    public function mark(User $user, $status) : User
187
    {
188
        if (auth()->id() == $user->id && $status == 0) {
189
            throw new GeneralException(__('exceptions.backend.access.users.cant_deactivate_self'));
190
        }
191
192
        $user->active = $status;
0 ignored issues
show
Bug Best Practice introduced by
The property active does not exist on App\Models\Auth\User. Since you implemented __set, consider adding a @property annotation.
Loading history...
193
194
        switch ($status) {
195
            case 0:
196
                event(new UserDeactivated($user));
197
            break;
198
199
            case 1:
200
                event(new UserReactivated($user));
201
            break;
202
        }
203
204
        if ($user->save()) {
205
            return $user;
206
        }
207
208
        throw new GeneralException(__('exceptions.backend.access.users.mark_error'));
209
    }
210
211
    /**
212
     * @param User $user
213
     *
214
     * @return User
215
     * @throws GeneralException
216
     */
217
    public function confirm(User $user) : User
218
    {
219
        if ($user->confirmed) {
0 ignored issues
show
Bug Best Practice introduced by
The property confirmed does not exist on App\Models\Auth\User. Since you implemented __get, consider adding a @property annotation.
Loading history...
220
            throw new GeneralException(__('exceptions.backend.access.users.already_confirmed'));
221
        }
222
223
        $user->confirmed = 1;
0 ignored issues
show
Bug Best Practice introduced by
The property confirmed does not exist on App\Models\Auth\User. Since you implemented __set, consider adding a @property annotation.
Loading history...
224
        $confirmed = $user->save();
225
226
        if ($confirmed) {
227
            event(new UserConfirmed($user));
228
229
            // Let user know their account was approved
230
            if (config('access.users.requires_approval')) {
231
                $user->notify(new UserAccountActive);
232
            }
233
234
            return $user;
235
        }
236
237
        throw new GeneralException(__('exceptions.backend.access.users.cant_confirm'));
238
    }
239
240
    /**
241
     * @param User $user
242
     *
243
     * @return User
244
     * @throws GeneralException
245
     */
246
    public function unconfirm(User $user) : User
247
    {
248
        if (! $user->confirmed) {
0 ignored issues
show
Bug Best Practice introduced by
The property confirmed does not exist on App\Models\Auth\User. Since you implemented __get, consider adding a @property annotation.
Loading history...
249
            throw new GeneralException(__('exceptions.backend.access.users.not_confirmed'));
250
        }
251
252
        if ($user->id == 1) {
253
            // Cant un-confirm admin
254
            throw new GeneralException(__('exceptions.backend.access.users.cant_unconfirm_admin'));
255
        }
256
257
        if ($user->id == auth()->id()) {
258
            // Cant un-confirm self
259
            throw new GeneralException(__('exceptions.backend.access.users.cant_unconfirm_self'));
260
        }
261
262
        $user->confirmed = 0;
0 ignored issues
show
Bug Best Practice introduced by
The property confirmed does not exist on App\Models\Auth\User. Since you implemented __set, consider adding a @property annotation.
Loading history...
263
        $unconfirmed = $user->save();
264
265
        if ($unconfirmed) {
266
            event(new UserUnconfirmed($user));
267
268
            return $user;
269
        }
270
271
        throw new GeneralException(__('exceptions.backend.access.users.cant_unconfirm'));
272
    }
273
274
    /**
275
     * @param User $user
276
     *
277
     * @return User
278
     * @throws GeneralException
279
     * @throws \Exception
280
     * @throws \Throwable
281
     */
282
    public function forceDelete(User $user) : User
283
    {
284
        if (is_null($user->deleted_at)) {
0 ignored issues
show
Bug Best Practice introduced by
The property deleted_at does not exist on App\Models\Auth\User. Since you implemented __get, consider adding a @property annotation.
Loading history...
285
            throw new GeneralException(__('exceptions.backend.access.users.delete_first'));
286
        }
287
288
        return DB::transaction(function () use ($user) {
289
            // Delete associated relationships
290
            $user->passwordHistories()->delete();
291
            $user->providers()->delete();
292
            $user->sessions()->delete();
293
294
            if ($user->forceDelete()) {
295
                event(new UserPermanentlyDeleted($user));
296
297
                return $user;
298
            }
299
300
            throw new GeneralException(__('exceptions.backend.access.users.delete_error'));
301
        });
302
    }
303
304
    /**
305
     * @param User $user
306
     *
307
     * @return User
308
     * @throws GeneralException
309
     */
310
    public function restore(User $user) : User
311
    {
312
        if (is_null($user->deleted_at)) {
0 ignored issues
show
Bug Best Practice introduced by
The property deleted_at does not exist on App\Models\Auth\User. Since you implemented __get, consider adding a @property annotation.
Loading history...
313
            throw new GeneralException(__('exceptions.backend.access.users.cant_restore'));
314
        }
315
316
        if ($user->restore()) {
317
            event(new UserRestored($user));
318
319
            return $user;
320
        }
321
322
        throw new GeneralException(__('exceptions.backend.access.users.restore_error'));
323
    }
324
325
    /**
326
     * @param User $user
327
     * @param      $email
328
     *
329
     * @throws GeneralException
330
     */
331
    protected function checkUserByEmail(User $user, $email)
332
    {
333
        //Figure out if email is not the same
334
        if ($user->email != $email) {
0 ignored issues
show
Bug Best Practice introduced by
The property email does not exist on App\Models\Auth\User. Since you implemented __get, consider adding a @property annotation.
Loading history...
335
            //Check to see if email exists
336
            if ($this->model->where('email', '=', $email)->first()) {
337
                throw new GeneralException(trans('exceptions.backend.access.users.email_error'));
338
            }
339
        }
340
    }
341
}
342