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 Validator; |
||||||
17 | use View; |
||||||
18 | use Webpatser\Uuid\Uuid; |
||||||
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 | 'first_name' => 'nullable|alpha', |
||||||
46 | 'last_name' => 'nullable|alpha', |
||||||
47 | 'theme_id' => 'required', |
||||||
48 | 'location' => 'nullable', |
||||||
49 | 'bio' => 'nullable|max:500', |
||||||
50 | 'twitter_username' => 'nullable|max:50', |
||||||
51 | 'github_username' => 'nullable|max:50', |
||||||
52 | 'avatar' => '', |
||||||
53 | 'avatar_status' => '', |
||||||
54 | ]); |
||||||
55 | } |
||||||
56 | |||||||
57 | /** |
||||||
58 | * Get a validator for an incoming update user request. |
||||||
59 | * |
||||||
60 | * @param array $data |
||||||
61 | * |
||||||
62 | * @return \Illuminate\Contracts\Validation\Validator |
||||||
63 | */ |
||||||
64 | public function validator(array $data) |
||||||
65 | { |
||||||
66 | return Validator::make($data, [ |
||||||
67 | 'name' => 'required|max:255', |
||||||
68 | ]); |
||||||
69 | } |
||||||
70 | |||||||
71 | /** |
||||||
72 | * Fetch user |
||||||
73 | * (You can extract this to repository method). |
||||||
74 | * |
||||||
75 | * @param $username |
||||||
76 | * |
||||||
77 | * @return mixed |
||||||
78 | */ |
||||||
79 | public function getUserByUsername($username) |
||||||
80 | { |
||||||
81 | return User::with('profile')->wherename($username)->firstOrFail(); |
||||||
82 | } |
||||||
83 | |||||||
84 | /** |
||||||
85 | * Display the specified resource. |
||||||
86 | * |
||||||
87 | * @param string $username |
||||||
88 | * |
||||||
89 | * @return Response |
||||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||||
90 | */ |
||||||
91 | public function show($username) |
||||||
92 | { |
||||||
93 | try { |
||||||
94 | $user = $this->getUserByUsername($username); |
||||||
95 | } catch (ModelNotFoundException $exception) { |
||||||
96 | abort(404); |
||||||
97 | } |
||||||
98 | |||||||
99 | $currentTheme = Theme::find($user->profile->theme_id); |
||||||
100 | |||||||
101 | $data = [ |
||||||
102 | 'user' => $user, |
||||||
103 | 'currentTheme' => $currentTheme, |
||||||
104 | ]; |
||||||
105 | |||||||
106 | return view('profiles.show')->with($data); |
||||||
0 ignored issues
–
show
|
|||||||
107 | } |
||||||
108 | |||||||
109 | /** |
||||||
110 | * /profiles/username/edit. |
||||||
111 | * |
||||||
112 | * @param $username |
||||||
113 | * |
||||||
114 | * @return mixed |
||||||
115 | */ |
||||||
116 | public function edit($username) |
||||||
117 | { |
||||||
118 | try { |
||||||
119 | $user = $this->getUserByUsername($username); |
||||||
120 | } catch (ModelNotFoundException $exception) { |
||||||
121 | return view('pages.status') |
||||||
122 | ->with('error', trans('profile.notYourProfile')) |
||||||
123 | ->with('error_title', trans('profile.notYourProfileTitle')); |
||||||
124 | } |
||||||
125 | |||||||
126 | $themes = Theme::where('status', 1) |
||||||
127 | ->orderBy('name', 'asc') |
||||||
128 | ->get(); |
||||||
129 | |||||||
130 | $currentTheme = Theme::find($user->profile->theme_id); |
||||||
131 | |||||||
132 | $data = [ |
||||||
133 | 'user' => $user, |
||||||
134 | 'themes' => $themes, |
||||||
135 | 'currentTheme' => $currentTheme, |
||||||
136 | |||||||
137 | ]; |
||||||
138 | |||||||
139 | return view('profiles.edit')->with($data); |
||||||
140 | } |
||||||
141 | |||||||
142 | /** |
||||||
143 | * Update a user's profile. |
||||||
144 | * |
||||||
145 | * @param $username |
||||||
146 | * |
||||||
147 | * @throws Laracasts\Validation\FormValidationException |
||||||
148 | * |
||||||
149 | * @return mixed |
||||||
150 | */ |
||||||
151 | public function update($username, Request $request) |
||||||
152 | { |
||||||
153 | $data = $request->formData; |
||||||
154 | $info = []; |
||||||
155 | foreach ($data as $key => $value) { |
||||||
156 | $info[] = [ |
||||||
157 | $value['name'] => $value['value'], |
||||||
158 | ]; |
||||||
159 | } |
||||||
160 | $convertedData = call_user_func_array('array_merge', $info); |
||||||
161 | |||||||
162 | $user = $this->getUserByUsername($username); |
||||||
163 | $ipAddress = new CaptureIpTrait(); |
||||||
164 | |||||||
165 | if ($request->ajax()) { |
||||||
166 | $profile_validator = $this->profile_validator($convertedData); |
||||||
167 | } else { |
||||||
168 | $profile_validator = $this->profile_validator($request->all()); |
||||||
169 | $input = $request->all(); |
||||||
170 | } |
||||||
171 | |||||||
172 | if ($profile_validator->fails()) { |
||||||
173 | $this->throwValidationException( |
||||||
0 ignored issues
–
show
The method
throwValidationException() does not exist on App\Http\Controllers\ProfilesController . Since you implemented __call , consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
174 | $request, |
||||||
175 | $profile_validator |
||||||
176 | ); |
||||||
177 | |||||||
178 | return redirect('profile/'.$user->name.'/edit')->withErrors($validator)->withInput(); |
||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||||
179 | } |
||||||
180 | |||||||
181 | if ($user->profile == null) { |
||||||
182 | $profile = new Profile(); |
||||||
183 | $profile->fill($input); |
||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||||
184 | $user->profile()->save($profile); |
||||||
185 | } else { |
||||||
186 | if ($request->ajax()) { |
||||||
187 | $user->profile->fill($convertedData)->save(); |
||||||
188 | $user->fill($convertedData); |
||||||
189 | } else { |
||||||
190 | $user->profile->fill($input)->save(); |
||||||
191 | $user->fill($input); |
||||||
192 | } |
||||||
193 | } |
||||||
194 | |||||||
195 | $user->updated_ip_address = $ipAddress->getClientIp(); |
||||||
196 | $user->save(); |
||||||
197 | |||||||
198 | if ($request->ajax()) { |
||||||
199 | $theme = Theme::find($user->profile->theme_id); |
||||||
200 | |||||||
201 | $returnData = [ |
||||||
202 | 'title' => trans('auth.success'), |
||||||
203 | 'message' => trans('profile.updateSuccess'), |
||||||
204 | 'themeLink' => $theme->link, |
||||||
205 | ]; |
||||||
206 | |||||||
207 | return response()->json($returnData, 200); |
||||||
208 | } |
||||||
209 | |||||||
210 | return redirect('profile/'.$user->name.'/edit')->with('success', trans('profile.updateSuccess')); |
||||||
211 | } |
||||||
212 | |||||||
213 | /** |
||||||
214 | * User account admin page. |
||||||
215 | * |
||||||
216 | * @return \Illuminate\Http\Response |
||||||
217 | */ |
||||||
218 | public function account() |
||||||
219 | { |
||||||
220 | $user = \Auth::user(); |
||||||
221 | $username = $user->name; |
||||||
0 ignored issues
–
show
|
|||||||
222 | |||||||
223 | $data = [ |
||||||
224 | 'user' => $user, |
||||||
225 | ]; |
||||||
226 | |||||||
227 | return view('profiles.account')->with($data); |
||||||
0 ignored issues
–
show
|
|||||||
228 | } |
||||||
229 | |||||||
230 | /** |
||||||
231 | * Update the specified resource in storage. |
||||||
232 | * |
||||||
233 | * @param \Illuminate\Http\Request $request |
||||||
234 | * @param int $id |
||||||
235 | * |
||||||
236 | * @return \Illuminate\Http\Response |
||||||
237 | */ |
||||||
238 | public function updateUserAccount(Request $request, $id) |
||||||
239 | { |
||||||
240 | $currentUser = \Auth::user(); |
||||||
0 ignored issues
–
show
|
|||||||
241 | $user = User::findOrFail($id); |
||||||
242 | $emailCheck = ($request->input('email') != '') && ($request->input('email') != $user->email); |
||||||
243 | $ipAddress = new CaptureIpTrait(); |
||||||
244 | |||||||
245 | $validator = Validator::make($request->all(), [ |
||||||
0 ignored issues
–
show
|
|||||||
246 | 'name' => 'required|max:255', |
||||||
247 | ]); |
||||||
248 | |||||||
249 | $rules = []; |
||||||
250 | |||||||
251 | if ($emailCheck) { |
||||||
252 | $rules = [ |
||||||
253 | 'email' => 'email|max:255|unique:users', |
||||||
254 | ]; |
||||||
255 | } |
||||||
256 | |||||||
257 | $validator = $this->validator($request->all(), $rules); |
||||||
0 ignored issues
–
show
The call to
App\Http\Controllers\Pro...Controller::validator() has too many arguments starting with $rules .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above. ![]() |
|||||||
258 | |||||||
259 | if ($validator->fails()) { |
||||||
260 | $this->throwValidationException( |
||||||
261 | $request, |
||||||
262 | $validator |
||||||
263 | ); |
||||||
264 | } |
||||||
265 | |||||||
266 | $user->name = $request->input('name'); |
||||||
267 | $user->first_name = $request->input('first_name'); |
||||||
268 | $user->last_name = $request->input('last_name'); |
||||||
269 | |||||||
270 | if ($emailCheck) { |
||||||
271 | $user->email = $request->input('email'); |
||||||
272 | } |
||||||
273 | |||||||
274 | $user->updated_ip_address = $ipAddress->getClientIp(); |
||||||
275 | |||||||
276 | $user->save(); |
||||||
277 | |||||||
278 | return redirect('profile/'.$user->name.'/edit')->with('success', trans('profile.updateAccountSuccess')); |
||||||
0 ignored issues
–
show
|
|||||||
279 | } |
||||||
280 | |||||||
281 | /** |
||||||
282 | * Update the specified resource in storage. |
||||||
283 | * |
||||||
284 | * @param \Illuminate\Http\Request $request |
||||||
285 | * @param int $id |
||||||
286 | * |
||||||
287 | * @return \Illuminate\Http\Response |
||||||
288 | */ |
||||||
289 | public function updateUserPassword(Request $request, $id) |
||||||
290 | { |
||||||
291 | $currentUser = \Auth::user(); |
||||||
0 ignored issues
–
show
|
|||||||
292 | $user = User::findOrFail($id); |
||||||
293 | $ipAddress = new CaptureIpTrait(); |
||||||
294 | |||||||
295 | $validator = Validator::make( |
||||||
296 | $request->all(), |
||||||
297 | [ |
||||||
298 | 'password' => 'required|min:6|max:20|confirmed', |
||||||
299 | 'password_confirmation' => 'required|same:password', |
||||||
300 | ], |
||||||
301 | [ |
||||||
302 | 'password.required' => trans('auth.passwordRequired'), |
||||||
303 | 'password.min' => trans('auth.PasswordMin'), |
||||||
304 | 'password.max' => trans('auth.PasswordMax'), |
||||||
305 | ] |
||||||
306 | ); |
||||||
307 | |||||||
308 | if ($validator->fails()) { |
||||||
309 | $this->throwValidationException( |
||||||
310 | $request, |
||||||
311 | $validator |
||||||
312 | ); |
||||||
313 | } |
||||||
314 | |||||||
315 | if ($request->input('password') != null) { |
||||||
316 | $user->password = bcrypt($request->input('password')); |
||||||
317 | } |
||||||
318 | |||||||
319 | $user->updated_ip_address = $ipAddress->getClientIp(); |
||||||
320 | |||||||
321 | $user->save(); |
||||||
322 | |||||||
323 | return redirect('profile/'.$user->name.'/edit')->with('success', trans('profile.updatePWSuccess')); |
||||||
0 ignored issues
–
show
|
|||||||
324 | } |
||||||
325 | |||||||
326 | /** |
||||||
327 | * Upload and Update user avatar. |
||||||
328 | * |
||||||
329 | * @param $file |
||||||
330 | * |
||||||
331 | * @return mixed |
||||||
332 | */ |
||||||
333 | public function upload() |
||||||
334 | { |
||||||
335 | if (Input::hasFile('file')) { |
||||||
336 | $currentUser = \Auth::user(); |
||||||
337 | $avatar = Input::file('file'); |
||||||
338 | $filename = 'avatar.'.$avatar->getClientOriginalExtension(); |
||||||
339 | $save_path = storage_path().'/users/id/'.$currentUser->id.'/uploads/images/avatar/'; |
||||||
0 ignored issues
–
show
|
|||||||
340 | $path = $save_path.$filename; |
||||||
341 | $public_path = '/images/profile/'.$currentUser->id.'/avatar/'.$filename; |
||||||
342 | |||||||
343 | // Make the user a folder and set permissions |
||||||
344 | File::makeDirectory($save_path, $mode = 0755, true, true); |
||||||
345 | |||||||
346 | // Save the file to the server |
||||||
347 | Image::make($avatar)->resize(300, 300)->save($save_path.$filename); |
||||||
348 | |||||||
349 | // Save the public image path |
||||||
350 | $currentUser->profile->avatar = $public_path; |
||||||
0 ignored issues
–
show
|
|||||||
351 | $currentUser->profile->save(); |
||||||
352 | |||||||
353 | return response()->json(['path'=> $path], 200); |
||||||
354 | } else { |
||||||
355 | return response()->json(false, 200); |
||||||
356 | } |
||||||
357 | } |
||||||
358 | |||||||
359 | /** |
||||||
360 | * Upload and update the user profile background. |
||||||
361 | * |
||||||
362 | * @param $file |
||||||
363 | * |
||||||
364 | * @return mixed |
||||||
365 | */ |
||||||
366 | public function uploadBackground() |
||||||
367 | { |
||||||
368 | if (Input::hasFile('file')) { |
||||||
369 | $currentUser = \Auth::user(); |
||||||
370 | $user_profile_bg = Input::file('file'); |
||||||
371 | $filename = 'background.'.$user_profile_bg->getClientOriginalExtension(); |
||||||
372 | $save_path = storage_path().'/users/id/'.$currentUser->id.'/uploads/images/background/'; |
||||||
0 ignored issues
–
show
|
|||||||
373 | $path = $save_path.$filename; |
||||||
374 | $public_path = '/images/profile/'.$currentUser->id.'/background/'.$filename; |
||||||
375 | |||||||
376 | // Make the user a folder and set permissions |
||||||
377 | File::makeDirectory($save_path, $mode = 0755, true, true); |
||||||
378 | |||||||
379 | // Save the file to the server |
||||||
380 | // Image::make($user_profile_bg)->resize(300, 300)->save($save_path . $filename); |
||||||
381 | Image::make($user_profile_bg)->save($save_path.$filename); |
||||||
382 | |||||||
383 | // Save the public image path |
||||||
384 | $currentUser->profile->user_profile_bg = $public_path; |
||||||
0 ignored issues
–
show
|
|||||||
385 | $currentUser->profile->save(); |
||||||
386 | |||||||
387 | return response()->json(['path'=> $path], 200); |
||||||
388 | } else { |
||||||
389 | return response()->json(false, 200); |
||||||
390 | } |
||||||
391 | } |
||||||
392 | |||||||
393 | /** |
||||||
394 | * Show user avatar. |
||||||
395 | * |
||||||
396 | * @param $id |
||||||
397 | * @param $image |
||||||
398 | * |
||||||
399 | * @return string |
||||||
400 | */ |
||||||
401 | public function userProfileAvatar($id, $image) |
||||||
402 | { |
||||||
403 | return Image::make(storage_path().'/users/id/'.$id.'/uploads/images/avatar/'.$image)->response(); |
||||||
404 | } |
||||||
405 | |||||||
406 | /** |
||||||
407 | * Show user background image. |
||||||
408 | * |
||||||
409 | * @param $id |
||||||
410 | * @param $image |
||||||
411 | * |
||||||
412 | * @return string |
||||||
413 | */ |
||||||
414 | public function userProfileBackgroundImage($id, $image) |
||||||
415 | { |
||||||
416 | return Image::make(storage_path().'/users/id/'.$id.'/uploads/images/background/'.$image)->response(); |
||||||
417 | } |
||||||
418 | |||||||
419 | /** |
||||||
420 | * Update the specified resource in storage. |
||||||
421 | * |
||||||
422 | * @param \Illuminate\Http\Request $request |
||||||
423 | * @param int $id |
||||||
424 | * |
||||||
425 | * @return \Illuminate\Http\Response |
||||||
426 | */ |
||||||
427 | public function deleteUserAccount(Request $request, $id) |
||||||
428 | { |
||||||
429 | $currentUser = \Auth::user(); |
||||||
430 | $user = User::findOrFail($id); |
||||||
431 | $ipAddress = new CaptureIpTrait(); |
||||||
432 | |||||||
433 | $validator = Validator::make( |
||||||
434 | $request->all(), |
||||||
435 | [ |
||||||
436 | 'checkConfirmDelete' => 'required', |
||||||
437 | ], |
||||||
438 | [ |
||||||
439 | 'checkConfirmDelete.required' => trans('profile.confirmDeleteRequired'), |
||||||
440 | ] |
||||||
441 | ); |
||||||
442 | |||||||
443 | if ($validator->fails()) { |
||||||
444 | $this->throwValidationException( |
||||||
445 | $request, |
||||||
446 | $validator |
||||||
447 | ); |
||||||
448 | } |
||||||
449 | |||||||
450 | if ($user->id != $currentUser->id) { |
||||||
0 ignored issues
–
show
|
|||||||
451 | return redirect('profile/'.$user->name.'/edit')->with('error', trans('profile.errorDeleteNotYour')); |
||||||
0 ignored issues
–
show
|
|||||||
452 | } |
||||||
453 | |||||||
454 | // Create and encrypt user account restore token |
||||||
455 | $sepKey = $this->getSeperationKey(); |
||||||
456 | $userIdKey = $this->getIdMultiKey(); |
||||||
457 | $restoreKey = config('settings.restoreKey'); |
||||||
458 | $encrypter = config('settings.restoreUserEncType'); |
||||||
459 | $level1 = $user->id * $userIdKey; |
||||||
460 | $level2 = urlencode(Uuid::generate(4).$sepKey.$level1); |
||||||
461 | $level3 = base64_encode($level2); |
||||||
462 | $level4 = openssl_encrypt($level3, $encrypter, $restoreKey); |
||||||
463 | $level5 = base64_encode($level4); |
||||||
464 | |||||||
465 | // Save Restore Token and Ip Address |
||||||
466 | $user->token = $level5; |
||||||
467 | $user->deleted_ip_address = $ipAddress->getClientIp(); |
||||||
468 | $user->save(); |
||||||
469 | |||||||
470 | // Send Goodbye email notification |
||||||
471 | $this->sendGoodbyEmail($user, $user->token); |
||||||
472 | |||||||
473 | // Soft Delete User |
||||||
474 | $user->delete(); |
||||||
475 | |||||||
476 | // Clear out the session |
||||||
477 | $request->session()->flush(); |
||||||
478 | $request->session()->regenerate(); |
||||||
479 | |||||||
480 | return redirect('/login/')->with('success', trans('profile.successUserAccountDeleted')); |
||||||
0 ignored issues
–
show
|
|||||||
481 | } |
||||||
482 | |||||||
483 | /** |
||||||
484 | * Send GoodBye Email Function via Notify. |
||||||
485 | * |
||||||
486 | * @param array $user |
||||||
487 | * @param string $token |
||||||
488 | * |
||||||
489 | * @return void |
||||||
490 | */ |
||||||
491 | public static function sendGoodbyEmail(User $user, $token) |
||||||
492 | { |
||||||
493 | $user->notify(new SendGoodbyeEmail($token)); |
||||||
494 | } |
||||||
495 | |||||||
496 | /** |
||||||
497 | * Get User Restore ID Multiplication Key. |
||||||
498 | * |
||||||
499 | * @return string |
||||||
500 | */ |
||||||
501 | public function getIdMultiKey() |
||||||
502 | { |
||||||
503 | return $this->idMultiKey; |
||||||
504 | } |
||||||
505 | |||||||
506 | /** |
||||||
507 | * Get User Restore Seperation Key. |
||||||
508 | * |
||||||
509 | * @return string |
||||||
510 | */ |
||||||
511 | public function getSeperationKey() |
||||||
512 | { |
||||||
513 | return $this->seperationKey; |
||||||
514 | } |
||||||
515 | } |
||||||
516 |