Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony3 wont convert file to UploadedFile

Tags:

php

symfony

I'm following this tutorial http://symfony.com/doc/current/controller/upload_file.html but the $file isn't being converted to an UploadedFile, it stays as a string:

var_dump($file);
/home/owner/Desktop/Workspace/Documentary/src/DW/DocumentaryBundle/Controller/Admin/DocumentaryController.php:103:string '/tmp/phpmmv1LP' (length=14)

Type error: Argument 1 passed to DW\DocumentaryBundle\Uploader\PosterUploader::upload() must be an instance of Symfony\Component\HttpFoundation\File\UploadedFile, string given, called in /home/owner/Desktop/Workspace/DocumentaryWIRE/src/DW/DocumentaryBundle/Controller/Admin/DocumentaryController.php on line 106

Create Action:

     /**
     * @param Request $request
     * @return Response
     */
    public function createAction(Request $request)
    {
        $documentary = new Documentary();

        $form = $this->createForm(DocumentaryType::class, $documentary);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $file = $documentary->getPoster();

            $posterUploader = $this->getPosterUploader();
            $fileName = $posterUploader->upload($file);

            $documentary->setPoster($fileName);

            $documentaryService = $this->getDocumentaryService();
            $documentaryService->save($documentary);
        }

        return $this->render('DocumentaryBundle:Admin:create.html.twig', array(
            'form' => $form->createView(),
        ));
    }

View

{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}

Form:

<?php

namespace DW\DocumentaryBundle\Form;

use DW\DocumentaryBundle\Entity\Documentary;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class DocumentaryType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title', TextType::class)
            ->add('storyline', TextareaType::class)
            ->add('summary', TextareaType::class)
            ->add('year', IntegerType::class)
            ->add('length', IntegerType::class)
            ->add('status', TextType::class)
            ->add('views', IntegerType::class)
            ->add('shortUrl', TextType::class)
            ->add('videoId', TextType::class)
            ->add('videoSource', TextType::class)
            ->add('poster', FileType::class, [
                'label' => 'Poster'])
            ->add('category', EntityType::class, [
                'class' => 'CategoryBundle:Category',
                'choice_label' => 'name',
            ])
            ->add('submit', SubmitType::class);
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => Documentary::class,
        ));
    }

    /**
     * @return string
     */
    public function getName()
    {
        return "documentary";
    }
}

Controller:

<?php

namespace DW\DocumentaryBundle\Uploader;

use Symfony\Component\HttpFoundation\File\UploadedFile;

class PosterUploader
{
    /**
     * @var string
     */
    private $targetDir;

    /**
     * @param string $targetDir
     */
    public function __construct(string $targetDir)
    {
        $this->targetDir = $targetDir;
    }

    /**
     * @param UploadedFile $file
     * @return string
     */
    public function upload(UploadedFile $file)
    {
        $fileName = md5(uniqid()).'.'.$file->guessExtension();

        $file->move($this->targetDir, $fileName);

        return $fileName;
    }
}
like image 888
Jonathan Avatar asked Feb 05 '23 03:02

Jonathan


1 Answers

The documentation is NOT wrong! They don't use type hinting in their example:

// src/AppBundle/Entity/Product.php
public function setBrochure($brochure)
{
    $this->brochure = $brochure;

    return $this;
}

When you use string type hinting then UploadedFile::__toString() will be invoked! So check your entity. It should be something like this:

public function setPoster($poster)
{
   // ...
}
like image 169
Andrey Nikonov Avatar answered Feb 07 '23 17:02

Andrey Nikonov