Vichuploaderbundle: Upload does not perform if manually injecting file into the entity

Created on 9 Mar 2015  路  6Comments  路  Source: dustin10/VichUploaderBundle

I'm injecting file in the form event listener:

        $builder->addEventListener(
            FormEvents::PRE_SUBMIT,
            function (FormEvent $event) use ($container) {

                $form = $event->getForm();
                $data = $event->getData();

                $uploadsDir = $container->getParameter('uploads_dir');
                if (isset($data['file'])) {
                    $filename = sprintf('%s.%s', uniqid('tmp_'), $data['file']->getClientOriginalExtension());
                    copy($data['file']->getRealPath(), $uploadsDir . '/tmp/' . $filename);
                    $form->add('file_hidden', 'hidden', array(
                        'mapped' => false,
                        'required' => false,
                        'empty_data' => $filename,
                    ));
                } else if (!isset($data['file']) && isset($data['file_hidden'])) {
                    $fileInfo = new \SplFileInfo($uploadsDir . '/tmp/' . $data['file_hidden']);

                    $uploadedFile = new File($fileInfo->getRealPath());

                    $form->add('file_hidden', 'hidden', array(
                        'mapped' => false,
                        'required' => false,
                        'empty_data' => $data['file_hidden'],
                    ));

                    $form->get('file')->setData($uploadedFile);
                    $data['file'] = $uploadedFile;
                    $event->setData($data);
                }
            }
        );

Here are File object created:
php $uploadedFile = new File($fileInfo->getRealPath());

and is set as the submitted data:

                    $form->get('file')->setData($uploadedFile);
                    $data['file'] = $uploadedFile;
                    $event->setData($data);

But if the insance is File type (not UploadedFile because it wouldn't work - validation will fail), the file wouldn't be uploaded.

Support

Most helpful comment

Hey! I've just solved issue by setting up parameter "test" (the last parameter in the constructor) to "true" in UploadedFile instance! This means:

Local files are used in test mode hence the code should not enforce HTTP uploads.

                    $fileInfo = new \SplFileInfo($uploadsDir . '/tmp/' . $data['file_hidden']);

                    $mimeTypeGuesser = MimeTypeGuesser::getInstance();
                    $uploadedFile = new UploadedFile(
                        $fileInfo->getRealPath(),
                        $fileInfo->getBasename(),
                        $mimeTypeGuesser->guess($fileInfo->getRealPath()),
                        $fileInfo->getSize(),
                        null,
                        true
                    );

@K-Phoen Could you please add information about "test" parameter to the manual?

All 6 comments

This is a known issue.

@K-Phoen but if create UploadedFile manually, any validation will fail. Take a look into isValid method of UploadedFile:

    public function isValid()
    {
        $isOk = $this->error === UPLOAD_ERR_OK;

        return $this->test ? $isOk : $isOk && is_uploaded_file($this->getPathname());
    }

This bundle is meant to be used in conjunction with forms and uploaded files. If you don't use them, you defeat its purpose and I can not really help you.

@K-Phoen there is such case: when user upload files and form is invalid, the files are lost. I am trying to manually re-populate files using tricks with hidden field. So, when hidden field with the file name is present, I am picking up file in event listener and adding it to the form field as data. If VichUploader would trigger if the File instance is set, that would help me so much!

Hey! I've just solved issue by setting up parameter "test" (the last parameter in the constructor) to "true" in UploadedFile instance! This means:

Local files are used in test mode hence the code should not enforce HTTP uploads.

                    $fileInfo = new \SplFileInfo($uploadsDir . '/tmp/' . $data['file_hidden']);

                    $mimeTypeGuesser = MimeTypeGuesser::getInstance();
                    $uploadedFile = new UploadedFile(
                        $fileInfo->getRealPath(),
                        $fileInfo->getBasename(),
                        $mimeTypeGuesser->guess($fileInfo->getRealPath()),
                        $fileInfo->getSize(),
                        null,
                        true
                    );

@K-Phoen Could you please add information about "test" parameter to the manual?

Done, thanks! :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

manguecreative picture manguecreative  路  4Comments

Propscode picture Propscode  路  4Comments

benIT picture benIT  路  3Comments

webkmua picture webkmua  路  4Comments

eved42 picture eved42  路  7Comments