Symfony VichUploaderBundle не загружает файл и не записывает в базу данных

Я пытался 4 раза безуспешно, прежде чем опубликовать эту проблему.

Я внимательно прочитал документацию и после установки VichUploaderBundle создал свой код для загрузки песни следующим образом:

Сущность / модель

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Vich\UploaderBundle\Mapping\Annotation as Vich;

/**
 * @ORM\Entity
 * @Vich\Uploadable
 */
class Song
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    // ..... other fields

    /**
     * NOTE: This is not a mapped field of entity metadata, just a simple property.
     * 
     * @Vich\UploadableField(mapping="song_track", fileNameProperty="trackName")
     * 
     * @var File
     */
    private $trackFile;

    /**
     * @ORM\Column(type="string", length=255)
     *
     * @var string
     */
    private $trackName;

    /**
     * @ORM\Column(type="datetime")
     *
     * @var \DateTime
     */
    private $updatedAt;

    /**
     * If manually uploading a file (i.e. not using Symfony Form) ensure an instance
     * of 'UploadedFile' is injected into this setter to trigger the  update. If this
     * bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
     * must be able to accept an instance of 'File' as the bundle will inject one here
     * during Doctrine hydration.
     *
     * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $trackName
     */
    public function setTrackFile(File $trackName = null)
    { 
        $this->$trackName = $trackName;
        if ($trackName) {
          var_dump($trackName);
            // It is required that at least one field changes if you are using doctrine
            // otherwise the event listeners won't be called and the file is lost
            $this->updatedAt = new \DateTime('now');
        }
    }

    /**
     * @return File
     */
    public function getTrackFile()
    {
        return $this->trackFile;
    }

    /**
     * @param string $imageName
     */
    public function setTrackName($trackName)
    {
        $this->trackName = $trackName;
    }

    /**
     * @return string
     */
    public function getTrackName()
    {
        return $this->trackName;
    }

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set updatedAt
     *
     * @param \DateTime $updatedAt
     *
     * @return Track
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }

    /**
     * Get updatedAt
     *
     * @return \DateTime
     */
    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }
}

Контроллер

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use AppBundle\Entity\Song;

class UploadTrackController extends Controller
{
    /**
     * @Route("/uploadtrack", name="uploadtrackform")
     */
    public function indexAction(Request $request)
    {
      $track = new Song();
      $form = $this->createFormBuilder($track)
          ->add('trackFile', 'file')
          ->add('save', 'submit', array('label' => 'Upload File'))
          ->getForm();
        $form->handleRequest($request);

        return $this->render('default/uploadtrack.html.twig', 
          array(
            'form' => $form->createView(),
          )
        );
    }
}

Просмотр

<body>
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
</body>

Я вижу форму, загружаю файл, и контроллер запускается правильно. Я не получаю никаких ошибок, но ни файл не копируется в папку, ни данные не сохраняются в базе данных.

Вы можете видеть в моем Entity, что у меня есть var_dump, который на самом деле содержит свойство error. После отправки формы я получаю от этого var_dump:

объект (Symfony \ Component \ HttpFoundation \ File \ UploadedFile) # 13 (7) {["test": "Symfony \ Component \ HttpFoundation \ File \ UploadedFile": private] => bool (false) ["originalName": "Symfony \ Component \ HttpFoundation \ File \ UploadedFile ": private] => строка (24)" file.pdf "[" mimeType ":" Symfony \ Component \ HttpFoundation \ File \ UploadedFile ": private] => строка (15)" приложение / pdf "[" size ":" Symfony \ Component \ HttpFoundation \ File \ UploadedFile ": private] => int (186992) [" error ":" Symfony \ Component \ HttpFoundation \ File \ UploadedFile ": private] => int (0) ["pathName": "SplFileInfo": private] => строка (66) "/ private / var / folder / 1g / 4t5n9rhj0_s_9tnstpjj6w_w5wl8pn / T / phpptwjZH" ["fileName": "SplFileInfo": private] => строка (9) "phpptwjZH"}

Мне кажется, что файл где-то временно хранится, но никогда не копируется в папку, и поэтому никакие данные не сохраняются в базе данных доктриной.

Извините, если я не нашел способа быть более кратким, но этот вопрос в основном для тех, кто имеет опыт работы с Symfony и VichUploaderBundle.

заранее спасибо

На всякий случай, если вам интересно, какова конфигурация для пакета, мы идем:

#VichUpload config
vich_uploader:
    db_driver: orm # or mongodb or propel or phpcr
    mappings:
        song_track:
            uri_prefix:         /upload/tracks
            upload_destination: %kernel.root_dir%/../web/upload/tracks

ОБНОВЛЕНИЕ

модифицированный сеттер в сущности Song, такой как K-Phoen, предложенный ниже, все та же проблема: / PS: Я запускаю проект, используя внутренний сервер Symfony php app / console server: запустить

public function setTrackFile(File $trackFile = null)
{
    $this->trackFile = $trackFile;
    if($trackFile){
      var_dump($trackFile);
        // It is required that at least one field changes if you are using doctrine
        // otherwise the event listeners won't be called and the file is lost
        $this->updatedAt = new \DateTime('now');
    }
}

ОБНОВЛЕНИЕ 2

Добавление этого к моему контроллеру заставило все это работать, файлы скопированы, база данных записана ...

 if ($form->isValid()) {
    $em = $this->getDoctrine()->getManager();
    $em->persist($track);
    $em->flush();
}

... Кстати, я запутался на этом этапе, так как читая документацию VichUploaderBundle, я понял, что это сохранение вызывается автоматически без необходимости указывать что-либо еще, кроме $ form-> handleRequest ($ request); в контроллере.


person Meeku    schedule 29.10.2015    source источник


Ответы (1)


Установщик setTrackFile(…) неверен: он должен обновить атрибут trackFile вместо trackName.

public function setTrackFile(File $trackFile = null)
{
    $this->trackFile = $trackFile;

    // …
}
person K-Phoen    schedule 29.10.2015
comment
Спасибо (действительно, также за комплект), я пробовал использовать ваш метод setTrack, но файл не копируется, и в базе данных ничего не сохраняется: /, хотя никаких ошибок не возникает, даже в консоли Symfony ничего не видно. единственная ошибка, которую я вижу, находится в выводе var_dump (снова), [ошибка: Symfony \ Component \ HttpFoundation \ File \ UploadedFile: private] = ›int (1) - person Meeku; 30.10.2015