From d06701fa87af85f59a040cadd2cdc9ccc8c6e636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Tue, 24 Jan 2023 00:57:41 +0100 Subject: [PATCH] Started to work on avatar upload from user settings page. --- src/Controller/UserSettingsController.php | 10 +++- src/Form/UserSettingsType.php | 15 ++++++ src/Services/UserSystem/UserAvatarHelper.php | 53 +++++++++++++++++++- 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/Controller/UserSettingsController.php b/src/Controller/UserSettingsController.php index 2aaa62d1..133dce62 100644 --- a/src/Controller/UserSettingsController.php +++ b/src/Controller/UserSettingsController.php @@ -30,6 +30,7 @@ use App\Events\SecurityEvents; use App\Form\TFAGoogleSettingsType; use App\Form\UserSettingsType; use App\Services\UserSystem\TFA\BackupCodeManager; +use App\Services\UserSystem\UserAvatarHelper; use Doctrine\ORM\EntityManagerInterface; use RuntimeException; use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Google\GoogleAuthenticator; @@ -209,7 +210,7 @@ class UserSettingsController extends AbstractController * * @return RedirectResponse|Response */ - public function userSettings(Request $request, EntityManagerInterface $em, UserPasswordHasherInterface $passwordEncoder, GoogleAuthenticator $googleAuthenticator, BackupCodeManager $backupCodeManager, FormFactoryInterface $formFactory) + public function userSettings(Request $request, EntityManagerInterface $em, UserPasswordHasherInterface $passwordEncoder, GoogleAuthenticator $googleAuthenticator, BackupCodeManager $backupCodeManager, FormFactoryInterface $formFactory, UserAvatarHelper $avatarHelper) { /** @var User */ $user = $this->getUser(); @@ -239,6 +240,13 @@ class UserSettingsController extends AbstractController $page_need_reload = true; } + if ($form['avatar_file']->getData() !== null) { + $attachment = $avatarHelper->handleAvatarUpload($user, $form['avatar_file']->getData()); + //$em->flush(); + //For some reason the avatar is not set as master picture attachment, so we do it again here + $user->setMasterPictureAttachment($attachment); + } + $em->flush(); $this->addFlash('success', 'user.settings.saved_flash'); } diff --git a/src/Form/UserSettingsType.php b/src/Form/UserSettingsType.php index 551912d1..98ce57fa 100644 --- a/src/Form/UserSettingsType.php +++ b/src/Form/UserSettingsType.php @@ -27,6 +27,7 @@ use App\Form\Type\CurrencyEntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\EmailType; +use Symfony\Component\Form\Extension\Core\Type\FileType; use Symfony\Component\Form\Extension\Core\Type\LanguageType; use Symfony\Component\Form\Extension\Core\Type\ResetType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; @@ -35,6 +36,7 @@ use Symfony\Component\Form\Extension\Core\Type\TimezoneType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Security\Core\Security; +use Symfony\Component\Validator\Constraints\File; class UserSettingsType extends AbstractType { @@ -74,6 +76,19 @@ class UserSettingsType extends AbstractType 'label' => 'user.email.label', 'disabled' => !$this->security->isGranted('edit_infos', $options['data']) || $this->demo_mode, ]) + ->add('avatar_file', FileType::class, [ + 'label' => 'user.change_avatar.label', + 'mapped' => false, + 'required' => false, + 'attr' => [ + 'accept' => 'image/*', + ], + 'constraints' => [ + new File([ + 'maxSize' => '2M', + ]), + ], + ]) ->add('language', LanguageType::class, [ 'disabled' => $this->demo_mode, 'required' => false, diff --git a/src/Services/UserSystem/UserAvatarHelper.php b/src/Services/UserSystem/UserAvatarHelper.php index 64fd10c2..80ad5d00 100644 --- a/src/Services/UserSystem/UserAvatarHelper.php +++ b/src/Services/UserSystem/UserAvatarHelper.php @@ -20,10 +20,16 @@ namespace App\Services\UserSystem; +use App\Entity\Attachments\Attachment; +use App\Entity\Attachments\AttachmentType; +use App\Entity\Attachments\UserAttachment; use App\Entity\UserSystem\User; +use App\Services\Attachments\AttachmentSubmitHandler; use App\Services\Attachments\AttachmentURLGenerator; +use Doctrine\ORM\EntityManagerInterface; use Liip\ImagineBundle\Service\FilterService; use Symfony\Component\Asset\Packages; +use Symfony\Component\HttpFoundation\File\UploadedFile; class UserAvatarHelper { @@ -31,13 +37,18 @@ class UserAvatarHelper private Packages $packages; private AttachmentURLGenerator $attachmentURLGenerator; private FilterService $filterService; + private EntityManagerInterface $entityManager; + private AttachmentSubmitHandler $submitHandler; - public function __construct(bool $use_gravatar, Packages $packages, AttachmentURLGenerator $attachmentURLGenerator, FilterService $filterService) + public function __construct(bool $use_gravatar, Packages $packages, AttachmentURLGenerator $attachmentURLGenerator, + FilterService $filterService, EntityManagerInterface $entityManager, AttachmentSubmitHandler $attachmentSubmitHandler) { $this->use_gravatar = $use_gravatar; $this->packages = $packages; $this->attachmentURLGenerator = $attachmentURLGenerator; $this->filterService = $filterService; + $this->entityManager = $entityManager; + $this->submitHandler = $attachmentSubmitHandler; } @@ -108,4 +119,44 @@ class UserAvatarHelper return $url; } + + /** + * Handles the upload of the user avatar. + * @param User $user + * @param UploadedFile $file + * @return Attachment + */ + public function handleAvatarUpload(User $user, UploadedFile $file): Attachment + { + //Determine which attachment to user + //If the user already has a master attachment, we use this one + if ($user->getMasterPictureAttachment()) { + $attachment = $user->getMasterPictureAttachment(); + } else { //Otherwise we have to create one + $attachment = new UserAttachment(); + $user->addAttachment($attachment); + $user->setMasterPictureAttachment($attachment); + $attachment->setName('Avatar'); + + //Retrieve or create the avatar attachment type + $attachment_type = $this->entityManager->getRepository(AttachmentType::class)->findOneBy(['name' => 'Avatars']); + if ($attachment_type === null) { + $attachment_type = new AttachmentType(); + $attachment_type->setName('Avatars'); + $attachment_type->setFiletypeFilter('image/*'); + $this->entityManager->persist($attachment_type); + } + + $attachment->setAttachmentType($attachment_type); + //$user->setMasterPictureAttachment($attachment); + } + + //Handle the upload + $this->submitHandler->handleFormSubmit($attachment, $file); + + //Set attachment as master picture + $user->setMasterPictureAttachment($attachment); + + return $attachment; + } } \ No newline at end of file