From 256362b444e8d6e9cfff981297016d5e05970061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my?= Date: Sat, 6 Jul 2024 13:21:49 +0200 Subject: [PATCH] fix: user can now update their profite picture --- .../Settings/Picture/FormChangePicture.vue | 4 +- config/packages/api_platform.yaml | 2 +- .../User/CreateUserProfilePictureAction.php | 45 ------------------- src/Entity/Image/UserProfilePicture.php | 23 +++++----- .../Denormalizer/UploadedFileDenormalizer.php | 27 +++++++++++ src/Serializer/Encoder/MultipartDecoder.php | 35 +++++++++++++++ .../User/UserProfilePictureProcessor.php | 42 +++++++++++++++++ 7 files changed, 119 insertions(+), 59 deletions(-) delete mode 100644 src/Controller/Api/Media/User/CreateUserProfilePictureAction.php create mode 100644 src/Serializer/Denormalizer/UploadedFileDenormalizer.php create mode 100644 src/Serializer/Encoder/MultipartDecoder.php create mode 100644 src/State/Processor/User/UserProfilePictureProcessor.php diff --git a/assets/js/views/user/Settings/Picture/FormChangePicture.vue b/assets/js/views/user/Settings/Picture/FormChangePicture.vue index 04591616..3b32e088 100644 --- a/assets/js/views/user/Settings/Picture/FormChangePicture.vue +++ b/assets/js/views/user/Settings/Picture/FormChangePicture.vue @@ -77,7 +77,7 @@ export default { if (canvas) { const form = new FormData(); canvas.toBlob(async blob => { - form.append('file', blob); + form.append('imageFile', blob); try { await userApi.changePicture(form); this.$root.$emit(EVENT_PROFILE_PICTURE_SUCCESS) @@ -85,7 +85,7 @@ export default { this.$root.$emit(EVENT_PROFILE_PICTURE_MODAL_CLOSE); this.$emit('close'); } catch (e) { - this.errors = e.response.data.map(error => error.message); + this.errors = e.response.data.violations.map(error => error.message); } }, 'image/jpeg'); } diff --git a/config/packages/api_platform.yaml b/config/packages/api_platform.yaml index 17cc0e42..846f69f9 100644 --- a/config/packages/api_platform.yaml +++ b/config/packages/api_platform.yaml @@ -27,7 +27,7 @@ api_platform: extra_properties: standard_put: true rfc_7807_compliant_errors: true - event_listeners_backward_compatibility_layer: false + use_symfony_listeners: false keep_legacy_inflector: false exception_to_status: # Symfony diff --git a/src/Controller/Api/Media/User/CreateUserProfilePictureAction.php b/src/Controller/Api/Media/User/CreateUserProfilePictureAction.php deleted file mode 100644 index 9c1549c8..00000000 --- a/src/Controller/Api/Media/User/CreateUserProfilePictureAction.php +++ /dev/null @@ -1,45 +0,0 @@ -files->get('file'); - if (!$uploadedFile) { - throw new BadRequestHttpException('"file" is required'); - } - /** @var User $user */ - $user = $this->security->getUser(); - $previousProfilePicture = $user->getProfilePicture() ?: null; - if ($previousProfilePicture) { - $user->setProfilePicture(null); - $this->entityManager->flush(); - $this->entityManager->remove($previousProfilePicture); - $this->entityManager->flush(); - } - $userProfilePicture = new UserProfilePicture(); - $userProfilePicture->setImageFile($uploadedFile); - $userProfilePicture->setUser($user); - $user->setProfilePicture($userProfilePicture); - - return $userProfilePicture; - } -} \ No newline at end of file diff --git a/src/Entity/Image/UserProfilePicture.php b/src/Entity/Image/UserProfilePicture.php index da8e0716..48bb888d 100644 --- a/src/Entity/Image/UserProfilePicture.php +++ b/src/Entity/Image/UserProfilePicture.php @@ -5,11 +5,12 @@ use ApiPlatform\Metadata\ApiResource; use ApiPlatform\Metadata\Post; use App\ApiResource\Search\MusicianSearchResult; -use App\Controller\Api\Media\User\CreateUserProfilePictureAction; +use ApiPlatform\OpenApi\Model; use App\Entity\Comment\Comment; use App\Entity\Forum\ForumPost; use App\Entity\Message\MessageThreadMeta; use App\Entity\User; +use App\State\Processor\User\UserProfilePictureProcessor; use DateTimeImmutable; use DateTimeInterface; use Doctrine\DBAL\Types\Types; @@ -25,27 +26,27 @@ #[ApiResource( operations: [ new Post( - controller: CreateUserProfilePictureAction::class, - openapiContext: [ - 'requestBody' => [ - 'content' => [ + inputFormats: ['multipart' => ['multipart/form-data']], + openapi: new Model\Operation( + requestBody: new Model\RequestBody( + content: new \ArrayObject([ 'multipart/form-data' => [ 'schema' => [ 'type' => 'object', 'properties' => [ - 'file' => [ + 'imageFile' => [ 'type' => 'string', 'format' => 'binary' ] ] ] ] - ] - ] - ], + ]) + ) + ), security: "is_granted('IS_AUTHENTICATED_REMEMBERED')", - deserialize: false, - name: 'api_user_profile_picture_post' + name: 'api_user_profile_picture_post', + processor: UserProfilePictureProcessor::class ) ], )] diff --git a/src/Serializer/Denormalizer/UploadedFileDenormalizer.php b/src/Serializer/Denormalizer/UploadedFileDenormalizer.php new file mode 100644 index 00000000..5990b75d --- /dev/null +++ b/src/Serializer/Denormalizer/UploadedFileDenormalizer.php @@ -0,0 +1,27 @@ + null, + '*' => false, + File::class => true, + ]; + } +} \ No newline at end of file diff --git a/src/Serializer/Encoder/MultipartDecoder.php b/src/Serializer/Encoder/MultipartDecoder.php new file mode 100644 index 00000000..ec3440c1 --- /dev/null +++ b/src/Serializer/Encoder/MultipartDecoder.php @@ -0,0 +1,35 @@ +requestStack->getCurrentRequest(); + if (!$request) { + return null; + } + + return array_map(static function (string $element) { + // Multipart form values will be encoded in JSON. + $decoded = json_decode($element, true); + + return \is_array($decoded) ? $decoded : $element; + }, $request->request->all()) + $request->files->all(); + } + + public function supportsDecoding(string $format): bool + { + return self::FORMAT === $format; + } +} diff --git a/src/State/Processor/User/UserProfilePictureProcessor.php b/src/State/Processor/User/UserProfilePictureProcessor.php new file mode 100644 index 00000000..cbe896b9 --- /dev/null +++ b/src/State/Processor/User/UserProfilePictureProcessor.php @@ -0,0 +1,42 @@ +security->getUser(); + $previousProfilePicture = $user->getProfilePicture() ?: null; + if ($previousProfilePicture) { + $user->setProfilePicture(null); + $this->entityManager->flush(); + $this->entityManager->remove($previousProfilePicture); + $this->entityManager->flush(); + } + + $data->setUser($user); + $user->setProfilePicture($data); + $this->entityManager->flush(); + + return $data; + } +} \ No newline at end of file