Reputation: 127
FileType on edit stays empty even when setting new file at the beginning.
I've tried to put the value in the form, to set the name of the file before creating form, but still empty. I use Symfony4 and bootstrap 4.
public function edit(Request $request, ObjectManager $manager, SkillRepository $skillRepo, SkillWantRepository $skillWantRepo)
{
$skilles = $skillRepo->findAll();
$skillesWant = $skillWantRepo->findAll();
//getUser appartient à Symfony, il récupère l'utilisateur connecté
$user = $this->getUser();
$skill = new Skill();
$skillWant = new SkillWant();
$fileName = $user->getAvatar();
$user->setAvatar(
new File($this->getParameter('avatars_directory') . '/' . $user->getAvatar())
);
$form = $this->createForm(AccountType::class, $user);
$test =$user->getAvatar();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$file = $form->get('avatar')->getData();
/** @var Symfony\Component\HttpFoundation\File\UploadedFile $file*/
$fileName = $this->generateUniqueFileName() . '.' . $file->guessExtension();
try {
$file->move(
$this->getParameter('avatars_directory'),
$fileName
);
} catch (FileException $e) {
// ... handle exception if something happens during file upload
}
//on stocke le nom du fichier dans la db
// instead of its contents
$user->setAvatar($fileName);
The form
->add('description', TextareaType:: class, ['required' => false])
->add('avatar', FileType:: class ,['data_class'=>null,'required'=>false, 'label'=>'votre image de profil'])`
I'd like to get the file in my download field but I get This error : Expected argument of type "string", "NULL" given at property path "avatar
Upvotes: 1
Views: 514
Reputation: 505
You are close. It is difficult because the 'avatar' property holds either a string filename or an UploadedFile. The property type is checked by the client browser, the form validator, and the database. Also https://symfony.com/doc/current/controller/upload_file.html has some omissions and does not have example Controller code for editing an entity. Try this.
/**
* @ORM\Column(type="string", length=255, nullable=true)
*
* @Assert\Type(
* type="File",
* message="The value {{ value }} is not a valid {{ type }}.")
* @Assert\Image()
*/
private $avatar;
If 'avatar' were holding a non-image file such as a PDF file, the annotations would be: (See https://symfony.com/doc/current/reference/constraints/File.html)
/**
* @ORM\Column(type="string", length=255, nullable=true)
*
* @Assert\Type(
* type="File",
* message="The value {{ value }} is not a valid {{ type }}.")
* @Assert\File(mimeTypes={ "application/pdf" })
*/
private $avatar;
php bin/console make:entity
public function getAvatar(): ?string
{
return $this->avatar;
}
should be changed to:
public function getAvatar()
{
return $this->avatar;
}
and
public function setAvatar(?string $avatar): self
{
$this->avatar = $avatar;
return $this;
}
should be changed to:
public function setAvatar($avatar): self
{
$this->avatar = $avatar;
return $this;
}
public function new(Request $request): Response
{
$user2 = new User2();
$form = $this->createForm(User2Type::class, $user2);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// $file stores the uploaded picture file.
/** @var Symfony\Component\HttpFoundation\File\UploadedFile $file */
$file = $user2->getAvatar();
$filename = null;
if ($file != null) {
$filename = $this->generateUniqueFileName().'.'.$file->guessExtension();
// Move the file to the directory where pictures are stored
try {
$file->move(
$this->getParameter('avatars_directory'),
$filename
);
} catch (FileException $e) {
// ... handle exception if something happens during file upload
}
}
// Updates the avatar property to store the picture file name
// instead of its contents.
$user2->setAvatar($filename);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user2);
$entityManager->flush();
return $this->redirectToRoute('user2_index');
}
return $this->render('user2/new.html.twig', [
'user2' => $user2,
'form' => $form->createView(),
]);
}
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
...
public function edit(Request $request, User2 $user2): Response
{
$fileName = $user2->getAvatar();
$oldFileName = $fileName;
$form = $this->createForm(User2Type::class, $user2);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var Symfony\Component\HttpFoundation\File\UploadedFile $file*/
$file = $form->get('avatar')->getData();
if ($file != null) {
// The user changed the avatar.
$fileName = $this->generateUniqueFileName() . '.' . $file->guessExtension();
try {
$file->move(
$this->getParameter('avatars_directory'),
$fileName
);
// Delete the old file, if any.
if ($oldFileName != null) {
try {
$filesystem = new Filesystem();
$filesystem->remove([$this->getParameter('avatars_directory') . '/' . $oldFileName]);
} catch (IOExceptionInterface $ioe) {
// ... handle exception if something happens during old file removal
}
}
} catch (FileException $e) {
// ... handle exception if something happens during moving uploaded file to avatars directory.
$fileName = $oldFileName;
}
}
$user2->setAvatar($fileName);
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('user2_index', [
'id' => $user2->getId(),
]);
}
return $this->render('user2/edit.html.twig', [
'user2' => $user2,
'form' => $form->createView(),
]);
}
Since you are using the Bootstrap theme, also see this question Symfony 4 Form file upload field does not show selected filename with Bootstrap 4 theme
Upvotes: 1