diff --git a/modules/backend/controllers/Users.php b/modules/backend/controllers/Users.php
index 6aba91696..a2501aec7 100644
--- a/modules/backend/controllers/Users.php
+++ b/modules/backend/controllers/Users.php
@@ -1,6 +1,9 @@
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
*/
diff --git a/modules/backend/controllers/users/_hint_trashed.htm b/modules/backend/controllers/users/_hint_trashed.htm
new file mode 100644
index 000000000..7c15ebd2a
--- /dev/null
+++ b/modules/backend/controllers/users/_hint_trashed.htm
@@ -0,0 +1,9 @@
+
\ No newline at end of file
diff --git a/modules/backend/controllers/users/config_filter.yaml b/modules/backend/controllers/users/config_filter.yaml
index 7d6bc797a..08ebb3f56 100644
--- a/modules/backend/controllers/users/config_filter.yaml
+++ b/modules/backend/controllers/users/config_filter.yaml
@@ -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
diff --git a/modules/backend/controllers/users/update.htm b/modules/backend/controllers/users/update.htm
index 88ef81feb..cf6902392 100644
--- a/modules/backend/controllers/users/update.htm
+++ b/modules/backend/controllers/users/update.htm
@@ -8,6 +8,10 @@
fatalError): ?>
+ trashed()): ?>
+ = $this->makePartial('hint_trashed') ?>
+
+
diff --git a/modules/backend/database/migrations/2018_12_16_000011_Db_Backend_Add_Deleted_At.php b/modules/backend/database/migrations/2018_12_16_000011_Db_Backend_Add_Deleted_At.php
new file mode 100644
index 000000000..6266f648e
--- /dev/null
+++ b/modules/backend/database/migrations/2018_12_16_000011_Db_Backend_Add_Deleted_At.php
@@ -0,0 +1,25 @@
+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');
+ });
+ }
+ }
+}
diff --git a/modules/backend/lang/en/lang.php b/modules/backend/lang/en/lang.php
index 0e17c1bcb..1d3e6a879 100644
--- a/modules/backend/lang/en/lang.php
+++ b/modules/backend/lang/en/lang.php
@@ -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',
diff --git a/modules/backend/models/User.php b/modules/backend/models/User.php
index 1ac926a03..f527f58ca 100644
--- a/modules/backend/models/User.php
+++ b/modules/backend/models/User.php
@@ -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
*/
diff --git a/modules/backend/models/user/columns.yaml b/modules/backend/models/user/columns.yaml
index 4c3e137aa..6ce6f0dfd 100644
--- a/modules/backend/models/user/columns.yaml
+++ b/modules/backend/models/user/columns.yaml
@@ -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