Я пытался 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); в контроллере.