mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-05-09 02:20:09 +00:00
Added user ownership migrate to delete screen.
This commit is contained in:
parent
99b14621f9
commit
5e686bb624
6 changed files with 50 additions and 8 deletions
app
resources
|
@ -1,6 +1,7 @@
|
||||||
<?php namespace BookStack\Auth;
|
<?php namespace BookStack\Auth;
|
||||||
|
|
||||||
use Activity;
|
use Activity;
|
||||||
|
use BookStack\Entities\EntityProvider;
|
||||||
use BookStack\Entities\Models\Book;
|
use BookStack\Entities\Models\Book;
|
||||||
use BookStack\Entities\Models\Bookshelf;
|
use BookStack\Entities\Models\Bookshelf;
|
||||||
use BookStack\Entities\Models\Chapter;
|
use BookStack\Entities\Models\Chapter;
|
||||||
|
@ -169,7 +170,7 @@ class UserRepo
|
||||||
* Remove the given user from storage, Delete all related content.
|
* Remove the given user from storage, Delete all related content.
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function destroy(User $user)
|
public function destroy(User $user, ?int $newOwnerId = null)
|
||||||
{
|
{
|
||||||
$user->socialAccounts()->delete();
|
$user->socialAccounts()->delete();
|
||||||
$user->apiTokens()->delete();
|
$user->apiTokens()->delete();
|
||||||
|
@ -183,6 +184,25 @@ class UserRepo
|
||||||
foreach ($profileImages as $image) {
|
foreach ($profileImages as $image) {
|
||||||
Images::destroy($image);
|
Images::destroy($image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!empty($newOwnerId)) {
|
||||||
|
$newOwner = User::query()->find($newOwnerId);
|
||||||
|
if (!is_null($newOwner)) {
|
||||||
|
$this->migrateOwnership($user, $newOwner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrate ownership of items in the system from one user to another.
|
||||||
|
*/
|
||||||
|
protected function migrateOwnership(User $fromUser, User $toUser)
|
||||||
|
{
|
||||||
|
$entities = (new EntityProvider)->all();
|
||||||
|
foreach ($entities as $instance) {
|
||||||
|
$instance->newQuery()->where('owned_by', '=', $fromUser->id)
|
||||||
|
->update(['owned_by' => $toUser->id]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -55,7 +55,7 @@ class EntityProvider
|
||||||
/**
|
/**
|
||||||
* Fetch all core entity types as an associated array
|
* Fetch all core entity types as an associated array
|
||||||
* with their basic names as the keys.
|
* with their basic names as the keys.
|
||||||
* @return [string => Entity]
|
* @return array<Entity>
|
||||||
*/
|
*/
|
||||||
public function all(): array
|
public function all(): array
|
||||||
{
|
{
|
||||||
|
|
|
@ -217,12 +217,13 @@ class UserController extends Controller
|
||||||
* Remove the specified user from storage.
|
* Remove the specified user from storage.
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function destroy(int $id)
|
public function destroy(Request $request, int $id)
|
||||||
{
|
{
|
||||||
$this->preventAccessInDemoMode();
|
$this->preventAccessInDemoMode();
|
||||||
$this->checkPermissionOrCurrentUser('users-manage', $id);
|
$this->checkPermissionOrCurrentUser('users-manage', $id);
|
||||||
|
|
||||||
$user = $this->userRepo->getById($id);
|
$user = $this->userRepo->getById($id);
|
||||||
|
$newOwnerId = $request->get('new_owner_id', null);
|
||||||
|
|
||||||
if ($this->userRepo->isOnlyAdmin($user)) {
|
if ($this->userRepo->isOnlyAdmin($user)) {
|
||||||
$this->showErrorNotification(trans('errors.users_cannot_delete_only_admin'));
|
$this->showErrorNotification(trans('errors.users_cannot_delete_only_admin'));
|
||||||
|
@ -234,7 +235,7 @@ class UserController extends Controller
|
||||||
return redirect($user->getEditUrl());
|
return redirect($user->getEditUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->userRepo->destroy($user);
|
$this->userRepo->destroy($user, $newOwnerId);
|
||||||
$this->showSuccessNotification(trans('settings.users_delete_success'));
|
$this->showSuccessNotification(trans('settings.users_delete_success'));
|
||||||
$this->logActivity(ActivityType::USER_DELETE, $user);
|
$this->logActivity(ActivityType::USER_DELETE, $user);
|
||||||
|
|
||||||
|
|
|
@ -175,7 +175,10 @@ return [
|
||||||
'users_delete_named' => 'Delete user :userName',
|
'users_delete_named' => 'Delete user :userName',
|
||||||
'users_delete_warning' => 'This will fully delete this user with the name \':userName\' from the system.',
|
'users_delete_warning' => 'This will fully delete this user with the name \':userName\' from the system.',
|
||||||
'users_delete_confirm' => 'Are you sure you want to delete this user?',
|
'users_delete_confirm' => 'Are you sure you want to delete this user?',
|
||||||
'users_delete_success' => 'Users successfully removed',
|
'users_migrate_ownership' => 'Migrate Ownership',
|
||||||
|
'users_migrate_ownership_desc' => 'Select a user here if you want another user to become the owner of all items currently owned by this user.',
|
||||||
|
'users_none_selected' => 'No user selected',
|
||||||
|
'users_delete_success' => 'User successfully removed',
|
||||||
'users_edit' => 'Edit User',
|
'users_edit' => 'Edit User',
|
||||||
'users_edit_profile' => 'Edit Profile',
|
'users_edit_profile' => 'Edit Profile',
|
||||||
'users_edit_success' => 'User successfully updated',
|
'users_edit_success' => 'User successfully updated',
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
<div class="dropdown-search custom-select-input" components="dropdown dropdown-search user-select"
|
<div class="dropdown-search custom-select-input" components="dropdown dropdown-search user-select"
|
||||||
option:dropdown-search:url="/search/users/select"
|
option:dropdown-search:url="/search/users/select"
|
||||||
>
|
>
|
||||||
<input refs="user-select@input" type="hidden" name="{{ $name }}" value="{{ $user->id }}">
|
<input refs="user-select@input" type="hidden" name="{{ $name }}" value="{{ $user->id ?? '' }}">
|
||||||
<div refs="dropdown@toggle"
|
<div refs="dropdown@toggle"
|
||||||
class="dropdown-search-toggle flex-container-row items-center"
|
class="dropdown-search-toggle flex-container-row items-center"
|
||||||
aria-haspopup="true" aria-expanded="false" tabindex="0">
|
aria-haspopup="true" aria-expanded="false" tabindex="0">
|
||||||
<div refs="user-select@user-info" class="flex-container-row items-center px-s">
|
<div refs="user-select@user-info" class="flex-container-row items-center px-s">
|
||||||
<img class="avatar mr-m" src="{{ $user->getAvatar(30) }}" alt="{{ $user->name }}">
|
@if($user)
|
||||||
<span>{{ $user->name }}</span>
|
<img class="avatar mr-m" src="{{ $user->getAvatar(30) }}" alt="{{ $user->name }}">
|
||||||
|
<span>{{ $user->name }}</span>
|
||||||
|
@else
|
||||||
|
<span>{{ trans('settings.users_none_selected') }}</span>
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<span style="font-size: 1.5rem; margin-left: auto;">
|
<span style="font-size: 1.5rem; margin-left: auto;">
|
||||||
@icon('caret-down')
|
@icon('caret-down')
|
||||||
|
|
|
@ -12,6 +12,20 @@
|
||||||
|
|
||||||
<p>{{ trans('settings.users_delete_warning', ['userName' => $user->name]) }}</p>
|
<p>{{ trans('settings.users_delete_warning', ['userName' => $user->name]) }}</p>
|
||||||
|
|
||||||
|
<hr class="my-l">
|
||||||
|
|
||||||
|
<div class="grid half gap-xl v-center">
|
||||||
|
<div>
|
||||||
|
<label class="setting-list-label">{{ trans('settings.users_migrate_ownership') }}</label>
|
||||||
|
<p class="small">{{ trans('settings.users_migrate_ownership_desc') }}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
@include('components.user-select', ['name' => 'new_owner_id', 'user' => null])
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="my-l">
|
||||||
|
|
||||||
<div class="grid half">
|
<div class="grid half">
|
||||||
<p class="text-neg"><strong>{{ trans('settings.users_delete_confirm') }}</strong></p>
|
<p class="text-neg"><strong>{{ trans('settings.users_delete_confirm') }}</strong></p>
|
||||||
<div>
|
<div>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue