feat: allow users to delete/create own profile
This commit is contained in:
parent
85962de188
commit
dcbff0f52e
10
app/Exceptions/ProfileAlreadyExistsException.php
Normal file
10
app/Exceptions/ProfileAlreadyExistsException.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class ProfileAlreadyExistsException extends Exception
|
||||
{
|
||||
//
|
||||
}
|
10
app/Exceptions/ProfileCreationFailedException.php
Normal file
10
app/Exceptions/ProfileCreationFailedException.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class ProfileCreationFailedException extends Exception
|
||||
{
|
||||
//
|
||||
}
|
@ -21,6 +21,9 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Exceptions\ProfileAlreadyExistsException;
|
||||
use App\Exceptions\ProfileCreationFailedException;
|
||||
use App\Exceptions\ProfileNotFoundException;
|
||||
use App\Facades\IP;
|
||||
use App\Http\Requests\ProfileSave;
|
||||
use App\Services\ProfileService;
|
||||
@ -123,4 +126,44 @@ class ProfileController extends Controller
|
||||
->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.'));
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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,18 +41,25 @@ 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()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the user "updated" event.
|
||||
|
@ -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!'));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -35,6 +35,33 @@
|
||||
@section('content')
|
||||
|
||||
|
||||
@if (!is_null($profile))
|
||||
|
||||
<x-modal id="deleteProfileConfirmationModal" modal-label="deleteProfileConfirmationModal" modal-title="{{ __('Please confirm') }}" include-close-button="true">
|
||||
|
||||
<p>{{ __('Deleting your profile is an irreversible operation. You will not be able to recover any previously entered information.') }}</p>
|
||||
<p>{{ __('After you delete your profile, the following will happen:') }}</p>
|
||||
|
||||
<ul>
|
||||
<li>{{ __('Your account will no longer be listed on the public Directory page.') }}</li>
|
||||
<li>{{ __('Your profile page will become inaccesible to everyone with an error message.') }}</li>
|
||||
<li>{{ __('Your profile configuration page will become inaccessible with an error message.') }}</li>
|
||||
<li>{{ __('In a future update, the public Directory page might become inaccessible to users without a profile.') }}</li>
|
||||
</ul>
|
||||
|
||||
<p>{{ __('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.') }}</p>
|
||||
<p>{{ __('Are you sure you want to delete your profile?') }}</p>
|
||||
|
||||
<x-slot name="modalFooter">
|
||||
<form name="deleteProfileConfirmation" method="post" action="{{ route('deleteProfile') }}">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<x-button type="submit" color="danger" icon="fas fa-trash" id="deleteProfileConfirmationBtn">{{ __('Yes, delete my profile') }}</x-button>
|
||||
</form>
|
||||
</x-slot>
|
||||
|
||||
</x-modal>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col">
|
||||
@ -202,18 +229,47 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row mt-3">
|
||||
<div class="row mt-3 mb-5">
|
||||
|
||||
<div class="col text-center">
|
||||
|
||||
<button type="button" class="btn btn-success" onclick="document.getElementById('saveProfileSettings').submit()">{{__('Update Profile')}}</button>
|
||||
<div class="col text-right">
|
||||
<button type="button" class="btn btn-success" onclick="document.getElementById('saveProfileSettings').submit()"><i class="fas fa-save"></i> {{__('Update Profile')}}</button>
|
||||
</div>
|
||||
|
||||
<div class="col text-left">
|
||||
<button type="button" class="btn btn-warning" onclick="$('#deleteProfileConfirmationModal').modal('show')"><i class="fas fa-exclamation-triangle"></i> {{ __('Delete Profile') }}</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
@else
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col">
|
||||
<x-card id="noProfile" card-title="{{ __('Create a profile') }}" footer-style="">
|
||||
|
||||
<x-slot name="cardHeader"></x-slot>
|
||||
|
||||
<x-alert alert-type="danger" title="{{ __('No profile found!') }}" icon="fa-user-alt-slash">
|
||||
<p>{{ __("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.") }}</p>
|
||||
<p>{{ __("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.") }}</p>
|
||||
</x-alert>
|
||||
|
||||
<x-slot name="cardFooter">
|
||||
<form name="createProfile" method="post" action="{{ route('createProfile') }}">
|
||||
@csrf
|
||||
<x-button type="submit" color="success" icon="fas fa-plus" size="sm" id="createProfile" link="#" target="_blank">{{ __('Create profile') }}</x-button>
|
||||
</form>
|
||||
</x-slot>
|
||||
</x-card>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@endif
|
||||
|
||||
@stop
|
||||
@section('footer')
|
||||
@include('breadcrumbs.dashboard.footer')
|
||||
|
@ -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'])
|
||||
|
Loading…
x
Reference in New Issue
Block a user