From dcbff0f52ea5aff31b5bfeedf28a2c0e06b5a374 Mon Sep 17 00:00:00 2001 From: miguel456 Date: Fri, 8 Apr 2022 19:40:35 +0100 Subject: [PATCH] feat: allow users to delete/create own profile --- .../ProfileAlreadyExistsException.php | 10 + .../ProfileCreationFailedException.php | 10 + app/Http/Controllers/ProfileController.php | 43 +++ app/Observers/UserObserver.php | 30 +- app/Services/ProfileService.php | 63 ++++ .../user/profile/userprofile.blade.php | 320 ++++++++++-------- routes/web.php | 8 + 7 files changed, 342 insertions(+), 142 deletions(-) create mode 100644 app/Exceptions/ProfileAlreadyExistsException.php create mode 100644 app/Exceptions/ProfileCreationFailedException.php diff --git a/app/Exceptions/ProfileAlreadyExistsException.php b/app/Exceptions/ProfileAlreadyExistsException.php new file mode 100644 index 0000000..dfb4975 --- /dev/null +++ b/app/Exceptions/ProfileAlreadyExistsException.php @@ -0,0 +1,10 @@ +back() ->with('success', __('Profile updated.')); } + + + public function createProfile(Request $request) + { + + try { + $this->profileService->createProfile($request->user()); + } catch (\Exception $e) { + + return redirect() + ->back() + ->with('error', $e->getMessage()); + + } + + return redirect() + ->back() + ->with('success', __('Your profile has been created.')); + } + + + + public function deleteProfile(Request $request) + { + + try { + $this->profileService->deleteProfile($request->user()); + } catch (ProfileNotFoundException $e) { + + return redirect() + ->back() + ->with('error', $e->getMessage()); + + } + + return redirect() + ->back() + ->with('success', __('Profile deleted successfully.')); + + } } diff --git a/app/Observers/UserObserver.php b/app/Observers/UserObserver.php index 3f4130d..99c8676 100755 --- a/app/Observers/UserObserver.php +++ b/app/Observers/UserObserver.php @@ -21,7 +21,10 @@ namespace App\Observers; +use App\Exceptions\ProfileAlreadyExistsException; +use App\Exceptions\ProfileCreationFailedException; use App\Profile; +use App\Services\ProfileService; use App\User; use Illuminate\Support\Facades\Log; @@ -38,17 +41,24 @@ class UserObserver * @param \App\User $user * @return void */ - public function created(User $user) + public function created(ProfileService $profileService, User $user) { - // TODO: Make sure that the profile is created, throw an exception if otherwise, or try to recreate the profile. - Profile::create([ - - 'profileShortBio' => 'Write a one-liner about you here!', - 'profileAboutMe' => 'Tell us a bit about you.', - 'socialLinks' => '{}', - 'userID' => $user->id, - - ]); + try + { + $profileService->createProfile($user); + } + catch (ProfileAlreadyExistsException $exception) + { + Log::error('Attempting to create profile that already exists!', [ + 'trace' => $exception->getTrace() + ]); + } + catch (ProfileCreationFailedException $e) + { + Log::error('Failed creating a new profile!', [ + 'trace' => $e->getTrace() + ]); + } } /** diff --git a/app/Services/ProfileService.php b/app/Services/ProfileService.php index 438527b..3aa4b97 100755 --- a/app/Services/ProfileService.php +++ b/app/Services/ProfileService.php @@ -4,15 +4,56 @@ namespace App\Services; +use App\Exceptions\ProfileAlreadyExistsException; +use App\Exceptions\ProfileCreationFailedException; use App\Exceptions\ProfileNotFoundException; +use App\Profile; use App\User; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Log; class ProfileService { /** + * Creates a new profile for the specified $targetUser. + * + * @param User $targetUser The user to create the profile for. + * @return bool + * @throws ProfileAlreadyExistsException + * @throws ProfileCreationFailedException + */ + public function createProfile(User $targetUser): Profile { + + if (is_null($targetUser->profile)) { + + $profile = Profile::create([ + + 'profileShortBio' => 'Write a one-liner about you here!', + 'profileAboutMe' => 'Tell us a bit about you.', + 'socialLinks' => '{}', + 'userID' => $targetUser->id, + + ]); + + if (is_null($profile)) { + throw new ProfileCreationFailedException(__('Could not create profile! Please try again later.')); + } + + Log::info('Created profile for new user', [ + 'userid' => $targetUser->id + ]); + + return $profile; + } + + throw new ProfileAlreadyExistsException(__('Profile already exists!')); + } + + /** + * Updates the user's profile. + * * @throws ProfileNotFoundException */ public function updateProfile($userID, Request $request) { @@ -47,4 +88,26 @@ class ProfileService throw new ProfileNotFoundException("This profile does not exist."); } + /** + * Delete specified user's profile + * + * @param User $targetUser + * @return bool + * @throws ProfileNotFoundException + */ + public function deleteProfile(User $targetUser): bool + { + + if (!is_null($targetUser->profile)) { + + Log::alert('Deleted user profile', [ + 'userid' => $targetUser->id + ]); + + return $targetUser->profile->delete(); + } + + throw new ProfileNotFoundException(__('Attempting to delete non-existant profile!')); + } + } diff --git a/resources/views/dashboard/user/profile/userprofile.blade.php b/resources/views/dashboard/user/profile/userprofile.blade.php index d9f1652..591805e 100755 --- a/resources/views/dashboard/user/profile/userprofile.blade.php +++ b/resources/views/dashboard/user/profile/userprofile.blade.php @@ -35,184 +35,240 @@ @section('content') -
+ @if (!is_null($profile)) -
+ -
+

{{ __('Deleting your profile is an irreversible operation. You will not be able to recover any previously entered information.') }}

+

{{ __('After you delete your profile, the following will happen:') }}

-
+
    +
  • {{ __('Your account will no longer be listed on the public Directory page.') }}
  • +
  • {{ __('Your profile page will become inaccesible to everyone with an error message.') }}
  • +
  • {{ __('Your profile configuration page will become inaccessible with an error message.') }}
  • +
  • {{ __('In a future update, the public Directory page might become inaccessible to users without a profile.') }}
  • +
-
-
-
- @if($profile->avatarPreference == 'gravatar') - {{ __('User profile picture') }} - @else - {{ __('User profile picture') }} - @endif +

{{ __('If you change your mind and want your profile back, you will be able to create a new blank profile from your profile configuration page, restoring access to the features mentioned above.') }}

+

{{ __('Are you sure you want to delete your profile?') }}

+ + +
+ @csrf + @method('DELETE') + {{ __('Yes, delete my profile') }} +
+
+ + + +
+ +
+ +
+ +
+ +
+
+
+ @if($profile->avatarPreference == 'gravatar') + {{ __('User profile picture') }} + @else + {{ __('User profile picture') }} + @endif +
+ +

{{Auth::user()->name}}

+ +

{{$profile->profileShortBio}}

+ +
+ + + +
-

{{Auth::user()->name}}

+ - - - - - -
+
+ -
-
+
+ @method('PATCH') + @csrf -
+
-
+
+
- +
- @method('PATCH') - @csrf - -
- -
- -
- -
- -

{{__('Basic Information')}}

- -
- -
- -
- -
- - - - -
- -
- -
- - - - -
- -
- - - -

{{__('Markdown supported')}}

- -
- -
- -
- -
- -
- -
- -
-

{{__('Preferences & Media')}}

-
- -
- - - -
- - - - +

{{__('Basic Information')}}

- +
-
-
- -
- -
+
-
-
- -
- -
+
-
-
- -
- -
+ + + +
-
-
-
- + +
+ + + + +
+ +
+ + + +

{{__('Markdown supported')}}

+ +
+
-
+
-
+
-
+
+

{{__('Preferences & Media')}}

+
-
+
- + -
+
-
+ - + + +
+ + + +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ + + + @else + +
+ +
+ + + + + +

{{ __("Your account currently has no profile on file. This means that your account will not be visibile in the public profile Directory, and you will not be able to access your profile until you create one.") }}

+

{{ __("There are many benefits to creating a profile! For instance, you'll be able to set a profile picture, as well as sharing your social media and anything else you'd like. Creating a profile is instant and you can begin configuring it right away. If you later change your mind, you may also delete your profile at any time.") }}

+
+ + +
+ @csrf + {{ __('Create profile') }} +
+
+
+
+ +
+ + @endif @stop @section('footer') diff --git a/routes/web.php b/routes/web.php index cfa8703..89a6a17 100755 --- a/routes/web.php +++ b/routes/web.php @@ -192,6 +192,7 @@ Route::group(['prefix' => LaravelLocalization::setLocale(), 'middleware' => ['lo // Further locking down the profile section by adding the middleware to everything but the required routes Route::group(['prefix' => '/profile'], function () { + Route::get('/settings', [ProfileController::class, 'showProfile']) ->name('showProfileSettings') ->middleware('passwordredirect'); @@ -204,6 +205,13 @@ Route::group(['prefix' => LaravelLocalization::setLocale(), 'middleware' => ['lo ->name('showSingleProfile') ->middleware('passwordredirect'); + Route::post('user/profile', [ProfileController::class, 'createProfile']) + ->name('createProfile') + ->middleware('passwordredirect'); + + Route::delete('user/profile', [ProfileController::class, 'deleteProfile']) + ->name('deleteProfile') + ->middleware('passwordredirect'); Route::get('/settings/account', [UserController::class, 'showAccount'])