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()): ?> + makePartial('hint_trashed') ?> + +
@@ -38,13 +42,23 @@ - + 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