Is there an easy way to handle user profile image?
I tried with VichUploaderBundle without success.
Save them in your folder with a unique name and store names in the database.
To upload an image you can use a FileType field in your form, documented here. You can use ImageType for form validation as I remember and here is some code which will save the file in a folder and save the filename in the database:
$user = new User();
$form = $this->createForm(UserForm::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$img = $user->getPhoto();
$fileName = md5(uniqid()).'.'.$img->guessExtension();
$user->setPhoto($fileName);
// Move the file to the directory where brochures are stored
$img->move(
$this->getParameter('user_image_directory'),
$fileName
);
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
}
And when you want to display the img you display it in twig in a similar fashion, first you read the filename with $user->getPhoto() and send it to your template, i had some bug when I called user.getPhoto() from the template, maybe it was just me:
img src="{{ asset('media/users/') }}{{ filename }}"></div>
Related
im trying to upload diffrent types of files in symfony
$uploadedFile = $request->files->get('image');
Works good for handling with images, However i cannot use it with diffrent files than
$uploadedFile = $request->files->get('file');
dd($uploadedFile);
Whatever i send using this, dd method shows me null.
How can I upload files for example pdfs, docx etc. (diffrent than images)
I use vue on the frontend.
You should use createForm.
https://symfony.com/doc/current/controller/upload_file.html
$form = $this->createForm(ProductType::class, $product);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** #var UploadedFile $brochureFile */
$brochureFile = $form->get('brochure')->getData();
// this condition is needed because the 'brochure' field is not required
// so the PDF file must be processed only when a file is uploaded
if ($brochureFile) {
$originalFilename = pathinfo($brochureFile->getClientOriginalName(), PATHINFO_FILENAME);
// this is needed to safely include the file name as part of the URL
$safeFilename = transliterator_transliterate('Any-Latin; Latin-ASCII; [^A-Za-z0-9_] remove; Lower()', $originalFilename);
$newFilename = $safeFilename.'-'.uniqid().'.'.$brochureFile->guessExtension();
// Move the file to the directory where brochures are stored
try {
$brochureFile->move(
$this->getParameter('brochures_directory'),
$newFilename
);
} catch (FileException $e) {
// ... handle exception if something happens during file upload
}
// updates the 'brochureFilename' property to store the PDF file name
// instead of its contents
$product->setBrochureFilename($newFilename);
}
I have a form that I use both for registration and edition of the user informations. This form contains a profile picture property on which I put #Assert\Image.
I succeed in creating a new user through my registration form but when I try to edit the user informations (with a PATCH method, just to update what need to be updated) I encounter an error with a 'File could not be found' message.
I suppose it's because the path stored in the database is a string and my #Assert\Image want an image.
I'm not sure about how I should manage this kind of update.
When I dd() the $user right after the submission, I see that the profilePicture property still contains the path saved in the database.
Here is my function regarding the form handling:
public function myProfile(Request $request)
{
$user = $this->getUser();
$form = $this->createForm(UserFormType::class, $user, ['method' => 'PATCH']);
if ($request->isMethod('PATCH')){
$form->submit($request->request->get($form->getName()), false);
if ($form->isSubmitted() && $form->isValid()) {
//...
}
}
//if no request just display the page
return $this->render('connected/myProfile.html.twig', [
'user' => $user,
'userProfileForm' => $form->createView()
]);
}
The Validator will check if your object contains a image and that seems not the case when you’re updating your object.
A workaround is to use group validation you define a specific group to the property that have the assert Image and in the method getGroupSequence you return the group if you’re in creation (id == null) or if the property is setted.
I'm learning Symfony 4 right now and I came across this documentation about file upload in the controller page that I got confused.
public function new(Request $request)
{
$product = new Product();
$form = $this->createForm(ProductType::class, $product);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// $file stores the uploaded PDF file
/** #var Symfony\Component\HttpFoundation\File\UploadedFile $file */
$file = $product->getBrochure();
On form submission, $file was used to store the content of the uploaded file as specified by the annotation. But what's the point of this $product->getBrochure()? $product should held nothing inside since it was newly created from the Product entity.
In your controller you generate a form with an underlying object to store the data which is the Product Entity. The controller can be accessed on two ways.
first in the GET method without any form data and second in the POST method with data from the form fields. In Symfony the data from the form fields will be placed in your entity automatically and even validated automatically. It all happens with the line
$form->handleRequest($request);
So the uploaded file data is stored in the entity too and if you want to access it you will have to get it out of the entity by a public method like $product->getBrochure();
It seems the documentation in the Symfony 4 File Upload page is incorrect. This might be a little late for you, but the problem still exists.
Instead of using:
$file = $product->getBrochure();
use:
$file = $form['brochure']->getData();
The first will return the file name which is a string while the second will get the actual file.
I am implementing a logical erase for my Symfony 3 entities.
On my entities, I added a $deleted field, and I created some delete-controllers with this code:
$entity->setDeleted(true);
$em->persist($entity);
$em->flush();
Then, I modified also my queries to avoid select 'deleted' entities. And works great.
The problem:
I have some entities with Unique Constraint (for example, email field on user table), so when I delete an user, and then try to add the same user with the same email, symfony shows a validation form error due to 'duplicated email'.
I tried to control this on controller in the following way:
$user = new User();
$em = $this->getDoctrine()->getManager();
if ($request->getMethod() == 'POST') {
$form->handleRequest($request);
//Check for deleted duplication:
$duplicatedUser = $em->getRepository('AppBundle:User')
->getDuplicatedAndDeletedUser($user);
if($duplicatedUser != null){
$em->remove($duplicatedUser);
$em->flush();
}
if ($form->isValid()) {
$em->persist($user);
$em->flush();
}
}
But this code doesn't avoid the form validation error. First time when I try to create, Stymfony shows an error, and then, if I resubmit the form, it works because of the duplicated entity was removed from db.
How can I solve this issue?
Note: I know this: http://atlantic18.github.io/DoctrineExtensions/doc/softdeleteable.html but, I have already developed all the logic described, so I prefer go in my way with this.
Finally I find the sollution.
As you can see here http://symfony.com/doc/current/forms.html#handling-form-submissions handleRequest() method validate the form, so delete the entity after that don't solve the problem at all.
I do that to get form data:
$userName = $request->request->get('user')['email'];
And then check if this $userName is already used. If so, I delete the user before handleRequest() call.
Hope this help others.
Something strange in your code, I can see a user getting created but it doesn't get injected in the form so it can be used to store data in it and I also don't see the form anywhere, was it created in the controller or is it pure html, if so, you would need to fill in the user with the data from the form with $formName->getData() function or if you so wish, fill in only individual fields with the $formName['fieldname']->getData(). Try this code:
$user = new User();
$form = $this->createForm(UserType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid())
{
$em = $this->getDoctrine()->getManager();
//Check for deleted duplication:
$duplicatedUser = $em->getRepository('AppBundle:User')
->getDuplicatedAndDeletedUser($user);
if($duplicatedUser != null){
$em->remove($duplicatedUser);
$em->flush();
}
$em->persist($user);
$em->flush();
}
I have an entity called Image. It contains a file attribute. I have also a form to create new Image entities with a FileType field which admits multiple uploads (multiple => true).
In case the user uploads multiple files, I would like to create the corresponding Image entities. What/where is the smartest way/place to do that?
We can do this inside controller,
$request = Request::createFromGlobals();
$em = $this->getDoctrine()->getManager();
if($request->isMethod('POST')){
foreach($request->files as $uploadedFile) {
$name = 'yourname.jpg';
$file = $uploadedFile->move($directory, $name);
$image->setFile('yourname.jpg');
$image = new Image();
$em->persist($image);
$em->flush();
}
}
* Remember images will be saved in the table according to the order you put them in view :)