Mettre à jour un attribut fichier d’une entité depuis un fichier distant

Habituellement, les entités contenant des attributs de types fichiers sont mis à jour depuis des formulaires. Mais parfois, il peut être utile de les mettre à jour à partir de fichiers distants. Vous pouvez par exemple proposer à vos utilisateurs de modifier leur photo de profil à partir d’une URL existante sur un site externe.

Pour permettre cela, rien de plus simple, il suffit de créer une nouvelle méthode dans votre contrôleur qui va créer un fichier temporaire à partir de l’URL distante, et qui va ensuite l’associer à votre entité.

<?php

    /**
     * Creates a new Picture entity from a remote URL.
     *
     * @Route("/{id}/remote/picture/upload", name="user_remote_picture_upload")
     * @Method({"GET", "POST"})
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function uploadRemotePictureAction(Request $request)
    {
        // Retrieve remote image URL from query parameters
        $remoteImageUrl = $request->query->get('remote_image_url', null);

        // Make sure we have a parameter
        if (null !== $remoteImageUrl) {
            $em = $this->getDoctrine()->getManager();

            // Create the picture object
            $picture = new Picture();
            $picture->setUser($this->getUser());

            // Upload the file to a temporary directory
            $newFile = $this->get('kernel')->getRootDir() . '/../web/uploads/temp-' . $this->getUser()->getId() . '.jpg';
            copy($remoteImageUrl, $newFile);
            
            // Retrieve file parameters
            $mimeType = mime_content_type($newFile);
            $size = filesize ($newFile);
            $finalName = md5(uniqid(rand(), true)) . '.jpg';
            $uploadedFile = new UploadedFile($newFile, $finalName, $mimeType, $size, null, true);
            
            // Associate the file to our entity
            $picture->setImageFile($uploadedFile);
            $this->get('vich_uploader.upload_handler')->upload($picture, 'imageFile');

            // Persist the entity
            $em->persist($picture);
            $em->flush();

            // Remove the temporary file
            unlink($newFile);

            // Get picture full URL
            /** @var UploaderHelper $uploaderHelper */
            $uploaderHelper = $this->container->get('vich_uploader.templating.helper.uploader_helper');
            $imageUrl = $uploaderHelper->asset($picture, 'imageFile');

            return new JsonResponse(array(
                'success' => true,
                'picture' => array(
                    'id' => $picture->getId(),
                    'url' => $imageUrl,
                ),
            ));
        }

        return new JsonResponse(array(
            'success' => false,
        ));
    }

Pour simplifier l’exemple, j’ai volontairement passé outre de la vérification du format de l’URL fournie et de la récupération de l’extension de l’image. J’ai donc assumé que c’était un fichier JPEG mais libre à vous de développer à votre guise l’exemple présenté.

En cas de doute sur la configuration de votre entité, vous pouvez vous référer à la documentation du bundle VichUploader qui est plutôt complète.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *