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 :)
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'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.
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>
I'm making an app mobile and I need to upload a photo from my camera via my API. But when doctrine try to INSERT INTO, he isn't happy because my name field is null. So the name generate by my entity is missing.
I don't understand where the code block. My web app uses already the same entity photo and everything works fine.
My Api controller:
<?php
/**
* #throws AccessDeniedException
* #return array
* #FOSRest\View()
*/
public function apiUploadAction()
{
$photo = new Photo;
$photo->setUser($this->getUser());
$photo->setFile = new UploadedFile(
$_FILES["file"]["tmp_name"],
$_FILES["file"]["name"],
$_FILES["file"]["type"],
$_FILES["file"]["size"],
$_FILES["file"]["error"],
$test = false
);
$em = $this->getDoctrine()->getManager();
$em->persist($photo);
$em->flush();
$apiResponse = array(
"code" => true,
"style" => "success",
/*********** SCREENSHOT COMES FROM HERE ***********/
"message" => $_FILES["file"]["tmp_name"]." ".$_FILES["file"]["name"]." ".$_FILES["file"]["type"]." ".$_FILES["file"]["size"]." ".$_FILES["file"]["error"],
);
$view = View::create();
$view->setFormat('json');
$view->setData($apiResponse);
return $this->get('fos_rest.view_handler')->handle($view);
}
The $apiResponse.message (screenshot):
As you can see symfony has the image so the problem don't come from my app mobile. new UploadedFile(); is the right way ? To upload without form.
Here is the solution :
Replace :
$photo->setFile = new UploadedFile(
$_FILES["file"]["tmp_name"],
$_FILES["file"]["name"],
$_FILES["file"]["type"],
$_FILES["file"]["size"],
$_FILES["file"]["error"],
$test = false
);
by
$photo->setFile($this->getRequest()->files->get('file'));
I have this code that creates a new Image based on a new file added to the filesystem but not yet in the DB:
$image = Image::create();
$image->Filename = 'assets/Art/e3434cc7-d348-491a-9dc8-325af3d9086d.jpg';
$image->write();
$images = Image::get();
$image = $images->last();
$vd = new ViewableData();
$ad = new ArrayData(array(
'Image' => $image
));
$strHTML = $vd->customise($ad)->renderWith('Art');
Art.ss contains only $Image.SetWidth(100)
Ignoring the fact the query doesn't look up by ID or whatever... why is the image only rendered into $strHTML if I retrieve the image from the DB after creating? If I delete the code below, $strHTML is empty:
$images = Image::get();
$image = $images->last();
There is a setter available so using that alone may help, but you also may need to assign the ID of the parent folder to the object:
$pFolder = Folder::find_or_make('Art');
if ($pFolder) {
$image->setParentID($pFolder->ID);
$image->setFilename('assets/Art/e3434cc7-d348-491a-9dc8-325af3d9086d.jpg');
}