Passed
Push — master ( 5478c9...c05c9e )
by Jeremy
06:14
created

ProfilesController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace App\Http\Controllers;
4
5
use App\Models\Profile;
6
use App\Models\Theme;
7
use App\Models\User;
8
use App\Notifications\SendGoodbyeEmail;
9
use App\Traits\CaptureIpTrait;
10
use File;
11
use Illuminate\Database\Eloquent\ModelNotFoundException;
12
use Illuminate\Http\Request;
13
use Illuminate\Support\Facades\Input;
14
use Illuminate\Support\Facades\Session;
15
use Image;
16
use jeremykenedy\Uuid\Uuid;
17
use Validator;
18
use View;
19
20
class ProfilesController extends Controller
21
{
22
    protected $idMultiKey = '618423'; //int
23
    protected $seperationKey = '****';
24
25
    /**
26
     * Create a new controller instance.
27
     *
28
     * @return void
29
     */
30
    public function __construct()
31
    {
32
        $this->middleware('auth');
33
    }
34
35
    /**
36
     * Get a validator for an incoming registration request.
37
     *
38
     * @param array $data
39
     *
40
     * @return \Illuminate\Contracts\Validation\Validator
41
     */
42
    public function profile_validator(array $data)
43
    {
44
        return Validator::make($data, [
45
            'theme_id'         => '',
46
            'location'         => '',
47
            'bio'              => 'max:500',
48
            'twitter_username' => 'max:50',
49
            'github_username'  => 'max:50',
50
            'avatar'           => '',
51
            'avatar_status'    => '',
52
        ]);
53
    }
54
55
    /**
56
     * Fetch user
57
     * (You can extract this to repository method).
58
     *
59
     * @param $username
60
     *
61
     * @return mixed
62
     */
63
    public function getUserByUsername($username)
64
    {
65
        return User::with('profile')->wherename($username)->firstOrFail();
66
    }
67
68
    /**
69
     * Display the specified resource.
70
     *
71
     * @param string $username
72
     *
73
     * @return Response
0 ignored issues
show
Bug introduced by
The type App\Http\Controllers\Response was not found. Did you mean Response? If so, make sure to prefix the type with \.
Loading history...
74
     */
75
    public function show($username)
76
    {
77
        try {
78
            $user = $this->getUserByUsername($username);
79
        } catch (ModelNotFoundException $exception) {
80
            abort(404);
81
        }
82
83
        $currentTheme = Theme::find($user->profile->theme_id);
84
85
        $data = [
86
            'user'         => $user,
87
            'currentTheme' => $currentTheme,
88
        ];
89
90
        return view('profiles.show')->with($data);
0 ignored issues
show
Bug Best Practice introduced by
The expression return view('profiles.show')->with($data) returns the type Illuminate\View\View which is incompatible with the documented return type App\Http\Controllers\Response.
Loading history...
91
    }
92
93
    /**
94
     * /profiles/username/edit.
95
     *
96
     * @param $username
97
     *
98
     * @return mixed
99
     */
100
    public function edit($username)
101
    {
102
        try {
103
            $user = $this->getUserByUsername($username);
104
        } catch (ModelNotFoundException $exception) {
105
            return view('pages.status')
106
                ->with('error', trans('profile.notYourProfile'))
107
                ->with('error_title', trans('profile.notYourProfileTitle'));
108
        }
109
110
        $themes = Theme::where('status', 1)
111
                        ->orderBy('name', 'asc')
112
                        ->get();
113
114
        $currentTheme = Theme::find($user->profile->theme_id);
115
116
        $data = [
117
            'user'         => $user,
118
            'themes'       => $themes,
119
            'currentTheme' => $currentTheme,
120
121
        ];
122
123
        return view('profiles.edit')->with($data);
124
    }
125
126
    /**
127
     * Update a user's profile.
128
     *
129
     * @param $username
130
     *
131
     * @throws Laracasts\Validation\FormValidationException
132
     *
133
     * @return mixed
134
     */
135
    public function update($username, Request $request)
136
    {
137
        $user = $this->getUserByUsername($username);
138
139
        $input = Input::only('theme_id', 'location', 'bio', 'twitter_username', 'github_username', 'avatar_status');
140
141
        $ipAddress = new CaptureIpTrait();
142
143
        $profile_validator = $this->profile_validator($request->all());
144
145
        if ($profile_validator->fails()) {
146
            return back()->withErrors($profile_validator)->withInput();
147
        }
148
149
        if ($user->profile == null) {
150
            $profile = new Profile();
151
            $profile->fill($input);
152
            $user->profile()->save($profile);
153
        } else {
154
            $user->profile->fill($input)->save();
155
        }
156
157
        $user->updated_ip_address = $ipAddress->getClientIp();
158
159
        $user->save();
160
161
        return redirect('profile/'.$user->name.'/edit')->with('success', trans('profile.updateSuccess'));
162
    }
163
164
    /**
165
     * Update the specified resource in storage.
166
     *
167
     * @param \Illuminate\Http\Request $request
168
     * @param int                      $id
169
     *
170
     * @return \Illuminate\Http\Response
171
     */
172
    public function updateUserAccount(Request $request, $id)
173
    {
174
        $currentUser = \Auth::user();
0 ignored issues
show
Unused Code introduced by
The assignment to $currentUser is dead and can be removed.
Loading history...
175
        $user = User::findOrFail($id);
176
        $emailCheck = ($request->input('email') != '') && ($request->input('email') != $user->email);
177
        $ipAddress = new CaptureIpTrait();
178
        $rules = [];
1 ignored issue
show
Unused Code introduced by
The assignment to $rules is dead and can be removed.
Loading history...
179
180
        if ($user->name != $request->input('name')) {
181
            $usernameRules = [
182
                'name' => 'required|max:255|unique:users',
183
            ];
184
        } else {
185
            $usernameRules = [
186
                'name' => 'required|max:255',
187
            ];
188
        }
189
        if ($emailCheck) {
190
            $emailRules = [
191
                'email' => 'email|max:255|unique:users',
192
            ];
193
        } else {
194
            $emailRules = [
195
                'email' => 'email|max:255',
196
            ];
197
        }
198
        $additionalRules = [
199
            'first_name' => 'nullable|string|max:255',
200
            'last_name'  => 'nullable|string|max:255',
201
        ];
202
203
        $rules = array_merge($usernameRules, $emailRules, $additionalRules);
204
        $validator = Validator::make($request->all(), $rules);
205
206
        if ($validator->fails()) {
207
            return back()->withErrors($validator)->withInput();
0 ignored issues
show
Bug Best Practice introduced by
The expression return back()->withError...validator)->withInput() returns the type Illuminate\Http\RedirectResponse which is incompatible with the documented return type Illuminate\Http\Response.
Loading history...
208
        }
209
210
        $user->name = $request->input('name');
211
        $user->first_name = $request->input('first_name');
212
        $user->last_name = $request->input('last_name');
213
214
        if ($emailCheck) {
215
            $user->email = $request->input('email');
216
        }
217
218
        $user->updated_ip_address = $ipAddress->getClientIp();
219
220
        $user->save();
221
222
        return redirect('profile/'.$user->name.'/edit')->with('success', trans('profile.updateAccountSuccess'));
0 ignored issues
show
Bug Best Practice introduced by
The expression return redirect('profile...updateAccountSuccess')) returns the type Illuminate\Http\RedirectResponse which is incompatible with the documented return type Illuminate\Http\Response.
Loading history...
223
    }
224
225
    /**
226
     * Update the specified resource in storage.
227
     *
228
     * @param \Illuminate\Http\Request $request
229
     * @param int                      $id
230
     *
231
     * @return \Illuminate\Http\Response
232
     */
233
    public function updateUserPassword(Request $request, $id)
234
    {
235
        $currentUser = \Auth::user();
0 ignored issues
show
Unused Code introduced by
The assignment to $currentUser is dead and can be removed.
Loading history...
236
        $user = User::findOrFail($id);
237
        $ipAddress = new CaptureIpTrait();
238
239
        $validator = Validator::make($request->all(),
240
            [
241
                'password'              => 'required|min:6|max:20|confirmed',
242
                'password_confirmation' => 'required|same:password',
243
            ],
244
            [
245
                'password.required' => trans('auth.passwordRequired'),
246
                'password.min'      => trans('auth.PasswordMin'),
247
                'password.max'      => trans('auth.PasswordMax'),
248
            ]
249
        );
250
251
        if ($validator->fails()) {
252
            return back()->withErrors($validator)->withInput();
0 ignored issues
show
Bug Best Practice introduced by
The expression return back()->withError...validator)->withInput() returns the type Illuminate\Http\RedirectResponse which is incompatible with the documented return type Illuminate\Http\Response.
Loading history...
253
        }
254
255
        if ($request->input('password') != null) {
256
            $user->password = bcrypt($request->input('password'));
257
        }
258
259
        $user->updated_ip_address = $ipAddress->getClientIp();
260
261
        $user->save();
262
263
        return redirect('profile/'.$user->name.'/edit')->with('success', trans('profile.updatePWSuccess'));
0 ignored issues
show
Bug Best Practice introduced by
The expression return redirect('profile...file.updatePWSuccess')) returns the type Illuminate\Http\RedirectResponse which is incompatible with the documented return type Illuminate\Http\Response.
Loading history...
264
    }
265
266
    /**
267
     * Upload and Update user avatar.
268
     *
269
     * @param $file
270
     *
271
     * @return mixed
272
     */
273
    public function upload()
274
    {
275
        if (Input::hasFile('file')) {
276
            $currentUser = \Auth::user();
277
            $avatar = Input::file('file');
278
            $filename = 'avatar.'.$avatar->getClientOriginalExtension();
279
            $save_path = storage_path().'/users/id/'.$currentUser->id.'/uploads/images/avatar/';
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
280
            $path = $save_path.$filename;
281
            $public_path = '/images/profile/'.$currentUser->id.'/avatar/'.$filename;
282
283
            // Make the user a folder and set permissions
284
            File::makeDirectory($save_path, $mode = 0755, true, true);
285
286
            // Save the file to the server
287
            Image::make($avatar)->resize(300, 300)->save($save_path.$filename);
288
289
            // Save the public image path
290
            $currentUser->profile->avatar = $public_path;
0 ignored issues
show
Bug introduced by
Accessing profile on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
291
            $currentUser->profile->save();
292
293
            return response()->json(['path' => $path], 200);
294
        } else {
295
            return response()->json(false, 200);
296
        }
297
    }
298
299
    /**
300
     * Show user avatar.
301
     *
302
     * @param $id
303
     * @param $image
304
     *
305
     * @return string
306
     */
307
    public function userProfileAvatar($id, $image)
308
    {
309
        return Image::make(storage_path().'/users/id/'.$id.'/uploads/images/avatar/'.$image)->response();
310
    }
311
312
    /**
313
     * Update the specified resource in storage.
314
     *
315
     * @param \Illuminate\Http\Request $request
316
     * @param int                      $id
317
     *
318
     * @return \Illuminate\Http\Response
319
     */
320
    public function deleteUserAccount(Request $request, $id)
321
    {
322
        $currentUser = \Auth::user();
323
        $user = User::findOrFail($id);
324
        $ipAddress = new CaptureIpTrait();
325
326
        $validator = Validator::make($request->all(),
327
            [
328
                'checkConfirmDelete' => 'required',
329
            ],
330
            [
331
                'checkConfirmDelete.required' => trans('profile.confirmDeleteRequired'),
332
            ]
333
        );
334
335
        if ($user->id != $currentUser->id) {
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
336
            return redirect('profile/'.$user->name.'/edit')->with('error', trans('profile.errorDeleteNotYour'));
0 ignored issues
show
Bug Best Practice introduced by
The expression return redirect('profile...e.errorDeleteNotYour')) returns the type Illuminate\Http\RedirectResponse which is incompatible with the documented return type Illuminate\Http\Response.
Loading history...
337
        }
338
339
        if ($validator->fails()) {
340
            return back()->withErrors($validator)->withInput();
0 ignored issues
show
Bug Best Practice introduced by
The expression return back()->withError...validator)->withInput() returns the type Illuminate\Http\RedirectResponse which is incompatible with the documented return type Illuminate\Http\Response.
Loading history...
341
        }
342
343
        // Create and encrypt user account restore token
344
        $sepKey = $this->getSeperationKey();
345
        $userIdKey = $this->getIdMultiKey();
346
        $restoreKey = config('settings.restoreKey');
347
        $encrypter = config('settings.restoreUserEncType');
348
        $level1 = $user->id * $userIdKey;
349
        $level2 = urlencode(Uuid::generate(4).$sepKey.$level1);
350
        $level3 = base64_encode($level2);
351
        $level4 = openssl_encrypt($level3, $encrypter, $restoreKey);
352
        $level5 = base64_encode($level4);
353
354
        // Save Restore Token and Ip Address
355
        $user->token = $level5;
356
        $user->deleted_ip_address = $ipAddress->getClientIp();
357
        $user->save();
358
359
        // Send Goodbye email notification
360
        $this->sendGoodbyEmail($user, $user->token);
361
362
        // Soft Delete User
363
        $user->delete();
364
365
        // Clear out the session
366
        $request->session()->flush();
367
        $request->session()->regenerate();
368
369
        return redirect('/login/')->with('success', trans('profile.successUserAccountDeleted'));
0 ignored issues
show
Bug Best Practice introduced by
The expression return redirect('/login/...ssUserAccountDeleted')) returns the type Illuminate\Http\RedirectResponse which is incompatible with the documented return type Illuminate\Http\Response.
Loading history...
370
    }
371
372
    /**
373
     * Send GoodBye Email Function via Notify.
374
     *
375
     * @param array  $user
376
     * @param string $token
377
     *
378
     * @return void
379
     */
380
    public static function sendGoodbyEmail(User $user, $token)
381
    {
382
        $user->notify(new SendGoodbyeEmail($token));
383
    }
384
385
    /**
386
     * Get User Restore ID Multiplication Key.
387
     *
388
     * @return string
389
     */
390
    public function getIdMultiKey()
391
    {
392
        return $this->idMultiKey;
393
    }
394
395
    /**
396
     * Get User Restore Seperation Key.
397
     *
398
     * @return string
399
     */
400
    public function getSeperationKey()
401
    {
402
        return $this->seperationKey;
403
    }
404
}
405