Hello,
je suis entrain de faire une API avec symfony 5.2.8. Et j'en suis à l'étape de l'upload des fichiers.
Pour tester ca, je voulais ajouter un avatar sur l'utilisateur.
Mais je ne comprend pas trop l'erreur que j'ai :
Mapping not found for field "avatarFile"
Voici le code que j'utilise :
/**
* @ORM\Entity(repositoryClass=UserRepository::class)
* @ORM\Table(name="`users`")
* @ORM\HasLifecycleCallbacks
* @Vich\Uploadable
*
* @OA\Schema
*/
class User implements UserInterface, JWTUserInterface
{
/**
* @Vich\UploadableField(mapping="avatars", fileNameProperty="avatar")
* @var File|null
*/
private ?File $avatarFile = null;
/**
* @ORM\Column(type="string", length=255, nullable=false)
*
* @Groups({"user:read"})
*/
private string $avatar = "";
public function getAvatarFile(): ?File
{
return $this->avatarFile;
}
public function setAvatarFile(?File $file): self
{
$this->avatarFile = $file;
if($this->avatarFile instanceof UploadedFile){
$this->updateTimestamps();
}
return $this;
}
public function getAvatar(): ?string
{
return $this->avatar;
}
public function setAvatar(string $avatar): self
{
$this->avatar = $avatar;
return $this;
}
}
class UserForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('username', TextType::class)
->add('email', EmailType::class)
->add('password', PasswordType::class)
->add('avatarFile', VichFileType::class, [
'required' => false,
]);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => UserData::class,
'csrf_protection' => false
]);
}
}
public function create(UserPasswordEncoderInterface $encoder): JsonResponse
{
$data = new UserData();
$data->encoder = $encoder;
$data->entity = new User();
$data->avatarFile = $this->getCurrentRequest()->files->get('avatar');
return $this->crudCreate($data);
}
$form = $this->createForm($data->getFormClass(), $data);
//$form->handleRequest($request); // ne fonctionne pas, remplacé par submit()
$form->submit($request->request->all(), ($request->getMethod() != 'PATCH'));
if( $form->isSubmitted() && $form->isValid() ){
$entity = $data->getEntity();
$data->hydrate();
$this->em->persist($entity);
}
Si vous avez une piste,
Merci.
bon je ne sais pas trop pourquoi mais is je retire le
->add('avatarFile', VichFileType::class, [
'required' => false,
]);
cela fonctionne.
Merci pour votre aide.
Hello Amstramgram, Vich s'attend à ce que tu crée une configuration dans le fichier config/packages/vich_uploader.yaml
avec un truc qui ressemble à ça :
vich_uploader:
db_driver: orm
mappings:
file_mapping: # Le nom du mapping
uri_prefix: '%upload_path%'
upload_destination: '%kernel.project_dir%/public/%upload_path%'
namer: vich_uploader.namer_uniqid
Je t'invite à lire la doc du Bundle.
Hello, désolé j'ai oublié de mettre la config de mapping mais je l'ai bien dans config/packages/vich_uploader.yaml
avec la mapping avatars que j'utilise dans l'entity.
vich_uploader:
db_driver: orm
mappings:
avatars:
uri_prefix: /uploads/avatars
upload_destination: '%kernel.project_dir%/public/uploads/avatars'
namer:
service: Vich\UploaderBundle\Naming\PropertyNamer
options: { property: 'id' }
directory_namer:
service: App\Utils\Uploader\PropertyUserDirectoryNamer
inject_on_load: false
delete_on_update: true
delete_on_remove: true
Vide le cache et ça ne fixe pas le pb essaie de faire une erreur dans le yaml pour voir si il est bien pris en compte.
J'ai vidé le cache même erreur.
Et si je fais une erreur dans le fichier yaml, j'ai une erreur avec le FileLoader.php, YamlFileLoader.php et Parser.php.
Et mon UserData
<?php
namespace App\Component\User\Data;
use App\Component\User\Entity\User;
use App\Component\User\Form\UserForm;
use App\Utils\Base\BaseCrudDataInterface;
use App\Utils\Validator\Unique;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Validator\Constraints as Assert;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* @Unique(field="email")
* @Unique(field="username")
* @Vich\Uploadable
*/
class UserData implements BaseCrudDataInterface
{
private EntityManagerInterface $em;
private bool $isUpdate = false;
private array $required = ['username', 'email', 'password'];
public User $entity;
public UserPasswordEncoderInterface $encoder;
/**
* @Assert\NotBlank()
* @Assert\Email()
*/
public string $email = "";
/**
* @Assert\NotBlank()
* @Assert\Type(type="alnum", message="This value should contain only letter or number.")
*/
public string $username = "";
/**
* @Assert\NotBlank()
* @Assert\Length(min=8, max=128)
* @Assert\NotCompromisedPassword()
*/
public string $password = "";
/**
* @Assert\NotBlank()
* @Assert\Image(mimeTypes={"image/jpeg", "image/jpg", "image/png"}, minWidth=120, maxHeight=1400, maxWidth=1400, minHeight=120)
*/
public ?UploadedFile $avatarFile = null;
//public string $avatar = "";
public static function clone(User $user): self
{
$data = new self();
$data->username = $user->getUsername();
$data->email = $user->getEmail();
$data->password = $user->getPassword();
$data->avatarFile = $user->getAvatarFile();
//$data->avatar = $user->getAvatar();
$data->entity = $user;
$data->isUpdate = true;
return $data;
}
public function hydrate(): void
{
$this->entity->setEmail($this->email);
$this->entity->setUsername($this->username);
$this->entity->setAvatarFile($this->avatarFile);
$this->entity->setAvatar($this->avatar);
if( !$this->isUpdate ){
$this->entity->setPassword($this->encoder->encodePassword($this->entity, $this->password));
}
}
public function getEntity(): User
{
return $this->entity;
}
public function getFormClass(): string
{
return UserForm::class;
}
public function setEntityManager(EntityManagerInterface $em): self
{
$this->em = $em;
return $this;
}
public function getId(): string
{
return $this->getEntity()->getId();
}
public function getRequiredFields(): array
{
return $this->required;
}
}