Implemented soft deleting for backend users

This commit is contained in:
Luke Towers 2018-12-17 23:09:17 -06:00
parent 14c4d1392e
commit 54a67ca556
8 changed files with 119 additions and 9 deletions

View File

@ -1,6 +1,9 @@
<?php namespace Backend\Controllers;
use Lang;
use Flash;
use Backend;
use Redirect;
use BackendMenu;
use BackendAuth;
use Backend\Models\UserGroup;
@ -68,7 +71,7 @@ class Users extends Controller
$query->where('is_superuser', false);
}
}
/**
* Prevents non-superusers from even seeing the is_superuser filter
*/
@ -79,6 +82,16 @@ class Users extends Controller
}
}
/**
* Strike out deleted records
*/
public function listInjectRowClass($record, $definition = null)
{
if ($record->trashed()) {
return 'strike';
}
}
/**
* Extends the form query to prevent non-superusers from accessing superusers at all
*/
@ -87,6 +100,9 @@ class Users extends Controller
if (!$this->user->isSuperUser()) {
$query->where('is_superuser', false);
}
// Ensure soft-deleted records can still be managed
$query->withTrashed();
}
/**
@ -102,6 +118,18 @@ class Users extends Controller
return $this->asExtension('FormController')->update($recordId, $context);
}
/**
* Handle restoring users
*/
public function update_onRestore($recordId)
{
$this->formFindModelObject($recordId)->restore();
Flash::success(Lang::get('backend::lang.form.restore_success', ['name' => Lang::get('backend::lang.user.name')]));
return Redirect::refresh();
}
/**
* My Settings controller
*/

View File

@ -0,0 +1,9 @@
<div class="layout-row min-size">
<div class="callout callout-danger">
<div class="header">
<i class="icon-trash"></i>
<h3><?= e(trans('backend::lang.user.trashed_hint_title')) ?></h3>
<p><?= e(trans('backend::lang.user.trashed_hint_desc')) ?></p>
</div>
</div>
</div>

View File

@ -21,3 +21,10 @@ scopes:
modelClass: Backend\Models\UserRole
conditions: role_id in (:filtered)
nameFrom: name
show_deleted:
label: backend::lang.user.show_deleted
type: checkbox
modelClass: Backend\Models\User
scope: withTrashed
default: 0

View File

@ -8,6 +8,10 @@
<?php if (!$this->fatalError): ?>
<?php Block::put('form-contents') ?>
<?php if ($formModel->trashed()): ?>
<?= $this->makePartial('hint_trashed') ?>
<?php endif; ?>
<div class="layout">
<div class="layout-row">
@ -38,13 +42,23 @@
<span class="btn-text">
<?= e(trans('backend::lang.form.or')) ?> <a href="<?= Backend::url('backend/users') ?>"><?= e(trans('backend::lang.form.cancel')) ?></a>
</span>
<button
type="button"
class="oc-icon-trash-o btn-icon danger pull-right"
data-request="onDelete"
data-load-indicator="<?= e(trans('backend::lang.form.deleting')) ?>"
data-request-confirm="<?= e(trans('backend::lang.user.delete_confirm')) ?>">
</button>
<?php if ($formModel->trashed()) : ?>
<button
type="button"
class="oc-icon-user-plus btn-icon info pull-right"
data-request="onRestore"
data-load-indicator="<?= e(trans('backend::lang.form.restoring')) ?>"
data-request-confirm="<?= e(trans('backend::lang.form.confirm_restore')) ?>">
</button>
<?php else: ?>
<button
type="button"
class="oc-icon-trash-o btn-icon danger pull-right"
data-request="onDelete"
data-load-indicator="<?= e(trans('backend::lang.form.deleting')) ?>"
data-request-confirm="<?= e(trans('backend::lang.user.delete_confirm')) ?>">
</button>
<?php endif; ?>
</div>
</div>

View File

@ -0,0 +1,25 @@
<?php
use October\Rain\Database\Schema\Blueprint;
use October\Rain\Database\Updates\Migration;
class DbBackendAddDeletedAt extends Migration
{
public function up()
{
if (!Schema::hasColumn('backend_users', 'deleted_at')) {
Schema::table('backend_users', function (Blueprint $table) {
$table->timestamp('deleted_at')->nullable()->after('updated_at');
});
}
}
public function down()
{
if (Schema::hasColumn('backend_users', 'deleted_at')) {
Schema::table('backend_users', function (Blueprint $table) {
$table->dropColumn('deleted_at');
});
}
}
}

View File

@ -141,6 +141,8 @@ return [
'last_login' => 'Last login',
'created_at' => 'Created at',
'updated_at' => 'Updated at',
'deleted_at' => 'Deleted at',
'show_deleted' => 'Show deleted',
'group' => [
'name' => 'Group',
'name_field' => 'Name',
@ -173,7 +175,9 @@ return [
],
'preferences' => [
'not_authenticated' => 'There is no an authenticated user to load or save preferences for.'
]
],
'trashed_hint_title' => 'This account has been deleted',
'trashed_hint_desc' => 'This account has been deleted and will be unable to be signed in under. To restore it, click the restore user icon in the bottom right',
],
'list' => [
'default_title' => 'List',
@ -229,6 +233,7 @@ return [
'create_success' => ':name created',
'update_success' => ':name updated',
'delete_success' => ':name deleted',
'restore_success' => ':name restored',
'reset_success' => 'Reset complete',
'missing_id' => 'Form record ID has not been specified.',
'missing_model' => 'Form behavior used in :class does not have a model defined.',
@ -248,6 +253,9 @@ return [
'confirm_delete' => 'Delete record?',
'confirm_delete_multiple' => 'Delete selected records?',
'deleting_name' => 'Deleting :name...',
'restore' => 'Restore',
'restoring' => 'Restoring',
'confirm_restore' => 'Are you sure you want to restore this record?',
'reset_default' => 'Reset to default',
'resetting' => 'Resetting',
'resetting_name' => 'Resetting :name',

View File

@ -13,6 +13,8 @@ use October\Rain\Auth\Models\User as UserBase;
*/
class User extends UserBase
{
use \October\Rain\Database\Traits\SoftDelete;
/**
* @var string The database table used by the model.
*/
@ -28,6 +30,17 @@ class User extends UserBase
'password_confirmation' => 'required_with:password|between:4,255'
];
/**
* @var array Attributes that should be cast to dates
*/
protected $dates = [
'activated_at',
'last_login',
'created_at',
'updated_at',
'deleted_at',
];
/**
* Relations
*/

View File

@ -59,6 +59,12 @@ columns:
invisible: true
type: datetime
deleted_at:
label: backend::lang.user.deleted_at
searchable: true
invisible: true
type: datetime
is_activated:
label: backend::lang.user.activated
invisible: true