Skip to content

Commit

Permalink
Merge pull request #582 from getformwork/feature/delete-user-image
Browse files Browse the repository at this point in the history
Add the possibility to delete user images
  • Loading branch information
giuscris authored Oct 6, 2024
2 parents bd3310b + cd8b833 commit 8d68f83
Show file tree
Hide file tree
Showing 15 changed files with 138 additions and 19 deletions.
61 changes: 49 additions & 12 deletions formwork/src/Panel/Controllers/UsersController.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
use Formwork\Utils\Arr;
use Formwork\Utils\Exceptions\FileNotFoundException;
use Formwork\Utils\FileSystem;
use RuntimeException;

class UsersController extends AbstractController
{
Expand Down Expand Up @@ -101,7 +100,10 @@ public function delete(RouteParams $routeParams): RedirectResponse
);
}
FileSystem::delete(FileSystem::joinPaths($this->config->get('system.users.paths.accounts'), $user->username() . '.yaml'));
$this->deleteImage($user);

if (!$user->hasDefaultImage()) {
$this->deleteUserImage($user);
}
} catch (TranslatedException $e) {
$this->panel()->notify($e->getTranslatedMessage(), 'error');
return $this->redirectToReferer(default: '/users/');
Expand All @@ -116,6 +118,37 @@ public function delete(RouteParams $routeParams): RedirectResponse
return $this->redirect($this->generateRoute('panel.users'));
}

/**
* Users@deleteImage action
*/
public function deleteImage(RouteParams $routeParams): RedirectResponse
{
$user = $this->site->users()->get($routeParams->get('user'));

if ($user === null) {
$this->panel()->notify($this->translate('panel.users.user.notFound'), 'error');
return $this->redirectToReferer(default: '/users/');
}

if ($this->user()->canChangeOptionsOf($user)) {
try {
$this->deleteUserImage($user);

$userData = $user->data();
Arr::remove($userData, 'image');
Yaml::encodeToFile($userData, FileSystem::joinPaths($this->config->get('system.users.paths.accounts'), $user->username() . '.yaml'));

$this->panel()->notify($this->translate('panel.user.image.deleted'), 'success');
} catch (TranslatedException $e) {
$this->panel()->notify($e->getTranslatedMessage(), 'error');
}
} else {
$this->panel()->notify($this->translate('panel.users.user.cannotEdit', $user->username()), 'error');
}

return $this->redirect($this->generateRoute('panel.users.profile', ['user' => $user->username()]));
}

/**
* Users@profile action
*/
Expand Down Expand Up @@ -162,6 +195,8 @@ public function profile(RouteParams $routeParams): Response

$this->modal('deleteUser');

$this->modal('deleteUserImage');

return new Response($this->view('users.profile', [
'title' => $this->translate('panel.users.userProfile', $user->username()),
'user' => $user,
Expand Down Expand Up @@ -214,7 +249,7 @@ protected function updateUser(User $user, FieldCollection $fieldCollection): voi
if ($field->name() === 'image') {
$file = $field->value();
// Handle incoming files
if ($file && ($image = $this->uploadImage($user, $file, $field->acceptMimeTypes())) !== null) {
if ($file && ($image = $this->uploadUserImage($user, $file, $field->acceptMimeTypes())) !== null) {
Arr::set($userData, 'image', $image);
}
continue;
Expand All @@ -231,7 +266,7 @@ protected function updateUser(User $user, FieldCollection $fieldCollection): voi
*
* @param array<string> $mimeTypes
*/
protected function uploadImage(User $user, UploadedFile $file, array $mimeTypes): ?string
protected function uploadUserImage(User $user, UploadedFile $file, array $mimeTypes): ?string
{
$imagesPath = FileSystem::joinPaths($this->config->get('system.users.paths.images'));

Expand All @@ -247,7 +282,9 @@ protected function uploadImage(User $user, UploadedFile $file, array $mimeTypes)
$image->square($userImageSize)->save();

// Delete old image
$this->deleteImage($user);
if (!$user->hasDefaultImage()) {
$this->deleteUserImage($user);
}

$this->panel()->notify($this->translate('panel.user.image.uploaded'), 'success');
return $uploadedFile->name();
Expand All @@ -259,16 +296,16 @@ protected function uploadImage(User $user, UploadedFile $file, array $mimeTypes)
/**
* Delete the image of a given user
*/
protected function deleteImage(User $user): void
protected function deleteUserImage(User $user): void
{
$image = $user->image()->path();

if ($image === $this->panel->realUri('/assets/images/user-image.svg')) {
throw new RuntimeException('Cannot delete default user image');
if ($user->hasDefaultImage()) {
throw new TranslatedException('Cannot delete default user image', 'panel.user.image.cannotDelete.defaultImage');
}

if (FileSystem::isFile($image, assertExists: false)) {
FileSystem::delete($image);
$path = $user->image()->path();

if (FileSystem::isFile($path, assertExists: false)) {
FileSystem::delete($path);
}
}
}
5 changes: 5 additions & 0 deletions formwork/src/Users/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ public function image(): Image
return $this->image = $file;
}

public function hasDefaultImage(): bool
{
return $this->image()->path() === FileSystem::joinPaths($this->config->get('system.panel.paths.assets'), 'images/user-image.svg');
}

public function role(): Role
{
return $this->role;
Expand Down
1 change: 1 addition & 0 deletions panel/assets/icons/svg/user-image-slash.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions panel/assets/icons/svg/user-image.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions panel/modals/deleteUserImage.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: '{{panel.user.image.delete}}'

message: '{{panel.user.image.delete.prompt}}'

buttons:
dismiss:
action: dismiss
icon: times-circle
label: '{{panel.modal.action.cancel}}'
variant: secondary

delete:
action: submit
icon: trash
label: '{{panel.modal.action.delete}}'
align: right
variant: danger
10 changes: 8 additions & 2 deletions panel/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,13 +209,19 @@
],

'panel.users.delete' => [
'path' => '/users/{user}/delete/',
'path' => '/users/{user:[a-z0-9_-]+}/delete/',
'action' => 'Formwork\Panel\Controllers\UsersController@delete',
'methods' => ['POST'],
],

'panel.users.deleteImage' => [
'path' => '/users/{user:[a-z0-9_-]+}/image/delete/',
'action' => 'Formwork\Panel\Controllers\UsersController@deleteImage',
'methods' => ['POST'],
],

'panel.users.profile' => [
'path' => '/users/{user}/profile/',
'path' => '/users/{user:[a-z0-9_-]+}/profile/',
'action' => 'Formwork\Panel\Controllers\UsersController@profile',
'methods' => ['GET', 'POST'],
],
Expand Down
17 changes: 14 additions & 3 deletions panel/src/scss/components/_users.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
}

.user-summary-image {
overflow: hidden;
position: relative;
width: 12rem;
height: 12rem;
border-radius: $border-radius-round;
Expand All @@ -13,9 +13,20 @@
box-shadow: $box-shadow-sm;
}

.user-summary-image .dropdown {
position: absolute;
top: 0;
right: -1.5rem;
}

.user-summary-image .dropdown-button {
background-color: var(--color-tooltip-light);
}

.user-summary-image img {
width: 100%;
height: 100%;
width: 12rem;
height: 12rem;
border-radius: $border-radius-round;
}

.users-list {
Expand Down
5 changes: 5 additions & 0 deletions panel/translations/de.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,11 @@ panel.user.colorScheme.light: Hell
panel.user.email: E-Mail
panel.user.fullname: Vollständiger Name
panel.user.image: Bild
panel.user.image.actions: Aktionen
panel.user.image.cannotDelete.defaultImage: Das Standard-Benutzerbild kann nicht gelöscht werden
panel.user.image.delete: Benutzerbild löschen
panel.user.image.delete.prompt: Sind Sie sicher, dass Sie das Benutzerbild löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.
panel.user.image.deleted: Benutzerbild gelöscht
panel.user.image.uploaded: Benutzerbild hochgeladen
panel.user.language: Sprache
panel.user.lastAccess: Letzter Zugriff
Expand Down
5 changes: 5 additions & 0 deletions panel/translations/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,11 @@ panel.user.colorScheme.light: Light
panel.user.email: Email
panel.user.fullname: Full name
panel.user.image: Image
panel.user.image.actions: Actions
panel.user.image.cannotDelete.defaultImage: Cannot delete the default user image
panel.user.image.delete: Delete user image
panel.user.image.delete.prompt: Are you sure you want to delete the user image? This action can’t be undone.
panel.user.image.deleted: User image deleted
panel.user.image.uploaded: User image uploaded
panel.user.language: Language
panel.user.lastAccess: Last access
Expand Down
5 changes: 5 additions & 0 deletions panel/translations/es.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,11 @@ panel.user.colorScheme.light: Claro
panel.user.email: Correo electrónico
panel.user.fullname: Nombre completo
panel.user.image: Imagen
panel.user.image.actions: Acciones
panel.user.image.cannotDelete.defaultImage: No se puede eliminar la imagen predeterminada del usuario
panel.user.image.delete: Eliminar imagen del usuario
panel.user.image.delete.prompt: ¿Está seguro de que desea eliminar la imagen del usuario? Esta acción no se puede deshacer.
panel.user.image.deleted: Imagen del usuario eliminada
panel.user.image.uploaded: Imagen de usuario cargada
panel.user.language: Idioma
panel.user.lastAccess: Último acceso
Expand Down
5 changes: 5 additions & 0 deletions panel/translations/fr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,11 @@ panel.user.colorScheme.light: Clair
panel.user.email: Adresse de messagerie
panel.user.fullname: Nom complet
panel.user.image: Photo de profil
panel.user.image.actions: Actions
panel.user.image.cannotDelete.defaultImage: Impossible de supprimer l’image par défaut de l’utilisateur
panel.user.image.delete: Supprimer l'image de l’utilisateur
panel.user.image.delete.prompt: Êtes-vous sûr de vouloir supprimer l’image de l’utilisateur ? Cette action ne peut pas être annulée.
panel.user.image.deleted: Image de l’utilisateur supprimée
panel.user.image.uploaded: Photo de profil téléversée avec succès.
panel.user.language: Langue
panel.user.lastAccess: Dernier accès
Expand Down
5 changes: 5 additions & 0 deletions panel/translations/it.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,11 @@ panel.user.colorScheme.light: Chiara
panel.user.email: E-mail
panel.user.fullname: Nome completo
panel.user.image: Immagine
panel.user.image.actions: Azioni
panel.user.image.cannotDelete.defaultImage: Impossibile eliminare l’immagine utente predefinita
panel.user.image.delete: Elimina immagine utente
panel.user.image.delete.prompt: Sei sicuro di voler eliminare l’immagine utente? Questa azione non può essere annullata.
panel.user.image.deleted: Immagine utente eliminata
panel.user.image.uploaded: Immagine caricata
panel.user.language: Lingua
panel.user.lastAccess: Ultimo accesso
Expand Down
5 changes: 5 additions & 0 deletions panel/translations/pt.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,11 @@ panel.user.colorScheme.light: Claro
panel.user.email: E'mail
panel.user.fullname: Nome completo
panel.user.image: Imagem
panel.user.image.actions: Ações
panel.user.image.cannotDelete.defaultImage: Não é possível eliminar a imagem padrão do utilizador
panel.user.image.delete: Eliminar imagem do utilizador
panel.user.image.delete.prompt: Tem a certeza de que quer eliminar a imagem do utilizador? Esta ação não pode ser desfeita.
panel.user.image.deleted: Imagem do utilizador eliminada
panel.user.image.uploaded: Imagem do utilizador enviada
panel.user.language: Idioma
panel.user.lastAccess: Último acesso
Expand Down
5 changes: 5 additions & 0 deletions panel/translations/ru.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,11 @@ panel.user.colorScheme.light: Светлая
panel.user.email: Email
panel.user.fullname: Полное имя
panel.user.image: Аватар
panel.user.image.actions: Действия
panel.user.image.cannotDelete.defaultImage: Невозможно удалить изображение пользователя по умолчанию
panel.user.image.delete: Удалить изображение пользователя
panel.user.image.delete.prompt: Вы уверены, что хотите удалить изображение пользователя? Это действие нельзя отменить.
panel.user.image.deleted: Изображение пользователя удалено
panel.user.image.uploaded: Аватар закачанный
panel.user.language: Язык
panel.user.lastAccess: Последний доступ
Expand Down
10 changes: 8 additions & 2 deletions panel/views/users/profile.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?php $this->layout('panel') ?>
<form method="post" enctype="multipart/form-data" data-form="user-profile-form">

<div class="header">
<div class="header-title"><?= $this->translate('panel.users.user') ?></div>
<?php if ($panel->user()->canChangeOptionsOf($user)) : ?>
Expand All @@ -10,10 +9,17 @@
</div>
<?php endif ?>
</div>

<section class="section user-summary">
<div class="user-summary-image">
<img src="<?= $user->image()->uri() ?>" alt="<?= $panel->user()->username() ?>">
<?php if ($panel->user()->canChangeOptionsOf($user) && !$user->hasDefaultImage()) : ?>
<div class="dropdown">
<button type="button" class="button button-link dropdown-button" title="<?= $this->translate('panel.user.image.actions') ?>" data-dropdown="dropdown-user-image"><?= $this->icon('ellipsis-v') ?></button>
<div class="dropdown-menu" id="dropdown-user-image">
<a class="dropdown-item" data-modal="deleteUserImageModal" data-modal-action="<?= $panel->uri('/users/' . $user->username() . '/image/delete/') ?>"><?= $this->icon('user-image-slash') ?> <?= $this->translate('panel.user.image.delete') ?></a>
</div>
</div>
<?php endif ?>
</div>
<div class="user-summary-data">
<div class="h3 mb-0"><?= $this->escape($user->fullname()) ?></div>
Expand Down

0 comments on commit 8d68f83

Please sign in to comment.