问题
Hello (excuse my English, not too confident with it)
I'm actually working on a Symfony website that display some spectacles' information. For now, I need to add an image when I create one of them. I managed to do so with the help of this tutorial.
It basically works like this: I upload an image into site's directory and then send file's name to the entity (Store in a MySQL database). I can then display the image in spectacle's details.
The issue appeared when I want to edit a spectacle. I can't update the image's name. I have two only possibilities are to 1/not edit the entity, or to 2/change the image name and then get a random one that I can't display anymore (these names are usually like /tmp/phpWb8kwV)
My image is instantiate like this in the entity (in Spectacle.php):
/**
* @var string
*
* @ORM\Column(name="image", type="string", length=255)
* @Assert\NotBlank(message="Veuillez ajouter une image à votre spectacle.")
* @Assert\File(mimeTypes={ "image/png" })
*/
private $image;
And the FormType for the spectacle's form is made like this (in SpectacleType.php):
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('nom')
->add('lieu')
->add('dateSpectacle', null, array(
'label' => 'Date du spectacle',
))
->add('annee')
->add('image',FileType::class, array(
'label' => 'Image du spectacle',
'required' => false, //(Still need to provide a file to finalize the creation/edit)
));
}
And the controller to acces this page is made like this (in SpectacleController.php):
/**
* Creates a new spectacle entity.
*
* @Route("/new", name="admin_spectacle_new")
* @Method({"GET", "POST"})
*/
public function newAction(Request $request)
{
$spectacle = new Spectacle();
$form = $this->createForm('FabopBundle\Form\SpectacleType', $spectacle);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
//--------------------------------------------------------------------
$file = $spectacle->getImage();
$fileName = (md5(uniqid())).'.'.$file->guessExtension();
// moves the file to the directory where image are stored
$file->move(
$this->getParameter('img_directory'), //(Define in the service.yml)
$fileName
);
$spectacle->setImage($fileName); //(Don't know how to handle file names without this line)
//---------------------------------------------------------------------
$em->persist($spectacle);
$em->flush();
return $this->redirectToRoute('admin_spectacle_show', array('id' => $spectacle->getId()));
}
return $this->render('spectacle/new.html.twig', array(
'spectacle' => $spectacle,
'form' => $form->createView(),
));
}
The function that is routed to the edit view is approximatively the same, but i can't use
$spectacle->setImage($fileName);
There is two possibilities to solve this: I would like being able to update the new filename in the entity (with the other information) or being able to update the entity without changing filename.
I hope I was clear enough to explain my problem... Thanks in advance for your responses.
回答1:
I had this problem when trying to upload a PDF/TEXT.. file. But for managing images, I advice you to use ComurImageBundle, it helps you a lot and your problem will be resolved. It's very simple, you download the bundle like it's explained in this link. Then you modify your code like this : 1/ Instantiation of your image in Spectacle.php (your image is stored in the DB like string)
/**
* @ORM\Column(type="string", nullable=true)
*/
private $image;
2/ Update your base ( php bin/console doctrine:schema:update --force)
3/ Add these functions to your Spectacle.php after updating your DB schema, these functions let you upload and stock your images under specific directory (web/uploads/spectacles) and don't forget to add this two libraries
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @Assert\File()
*/
private $file;
/**
* Sets file.
*
* @param UploadedFile $file
*/
public function setFile(UploadedFile $file = null)
{
$this->file = $file;
}
/**
* Get file.
*
* @return UploadedFile
*/
public function getFile()
{
return $this->file;
}
/**
* @ORM\PrePersist
*/
public function preUpload()
{
if (null !== $this->file) {
$this->image = uniqid() . '.' . $this->file->guessExtension();
}
}
/**
* @ORM\PostPersist
*/
public function upload()
{
if (null === $this->file) {
return;
}
// If there is an error when moving the file, an exception will
// be automatically thrown by move(). This will properly prevent
// the entity from being persisted to the database on error
$this->file->move($this->getUploadRootDir(), $this->image);
}
public function getUploadDir()
{
return 'uploads/spectacles';
}
public function getBaseUrl()
{
$currentPath = $_SERVER['PHP_SELF'];
$pathInfo = pathinfo($currentPath);
return substr($pathInfo['dirname']."/", 1);
}
public function getUploadRootDir()
{
return $this->getBaseUrl() . $this->getUploadDir();
}
public function getWebPath()
{
return null === $this->image ? null : $this->getUploadDir() . '/' . $this->image;
}
public function getAbsolutePath()
{
return null === $this->image ? null : $this->getUploadRootDir() . '/' . $this->image;
}
4/ Modify the FormType (SpectacleType.php)like this
use Comur\ImageBundle\Form\Type\CroppableImageType;
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('nom')
->add('lieu')
->add('dateSpectacle', null, array(
'label' => 'Date du spectacle',
))
->add('annee')
->add('image', CroppableImageType::class, array('label' => 'Image', 'required' => true,
'uploadConfig' => array(
'uploadUrl' => $myEntity->getUploadDir(), // required - see explanation below (you can also put just a dir path)
'webDir' => $myEntity->getUploadRootDir(), // required - see explanation below (you can also put just a dir path)
'fileExt' => '*.png', // required - see explanation below (you can also put just a dir path)
'showLibrary' => false,
),
'cropConfig' => array(
'minWidth' => 128,
'minHeight' => 128,
'aspectRatio' => true,
)
));
}
5/ Remove all these lines from your controller you won't need them
//--------------------------------------------------------------------
$file = $spectacle->getImage();
$fileName = (md5(uniqid())).'.'.$file->guessExtension();
// moves the file to the directory where image are stored
$file->move(
$this->getParameter('img_directory'), //(Define in the service.yml)
$fileName
);
$spectacle->setImage($fileName); //(Don't know how to handle file names without this line)
//---------------------------------------------------------------------
6/ That's it you can call the form of your image in new.html.twig and edit.html.twig, all will get well, try it please and notify me if there is any problem.
回答2:
The solution was stupid ...
In fact, the controller to access the edit route didn't have those lines:
$em = $this->getDoctrine()->getManager();
...
$em->persist($spectacle);
$em->flush();
I need to finish this quickly. If i have more time later, i'll try to make it work with the ComurImageBundle.
Thank you for your help, i'll be more carefull next time ...
来源:https://stackoverflow.com/questions/49506670/edit-file-name-in-entity-with-symfony