我有一家公司,其中有一个徽标字段。我在编辑页面中的想法是,如果在编辑表单中,该字段为空,则保留我们以前在数据库上拥有的徽标,因为这是必填字段。
我的想法是获取以前要提交的表单数据,并检查该字段是否为空以从数据库中获取数据以对其进行更新。我使用了eventListener,但是在提交数据时,获取null不会改变。对于这个symfony版本,我几乎是新手,但我无法做到这一点。你可以帮帮我吗。谢谢
/**
* @Route("/admin/companies/edit/{id}", name="edit_company")
* Method({"GET", "POST"})
*/
public function editCompany(Request $request, $id){
$company = new Company();
$company = $this->getDoctrine()->getRepository(Company::class)->find($id);
$form = $this->createFormBuilder($company)
->add('name', TextType::class, array('attr' => array('class' => 'form-control')))
->add('description', TextAreaType::class, array('attr' => array('class' => 'form-control summernote')))
->add('telephone', TextType::class, array('attr' => array('class' => 'form-control')))
->add('city', TextType::class, array('attr' => array('class' => 'form-control')))
->add('web', UrlType::class, array('attr' => array('class' => 'form-control')))
->add('image', FileType::class, array('data_class' => null, 'label' => false, 'required' => false, 'attr' => array('class' => 'form-control d-none')))
->add('save', SubmitType::class, ['label' => 'Edit Company', 'attr' => array('class' => 'btn btn-success p-2 mt-5')])`enter code here`
->addEventListener(FormEvents::PRE_SUBMIT, function(FormEvent $event) {
$data = $event->getData();
$form = $event->getForm();
$image = $data['image'];
if ($image == null){
$company_tmp = $this->getDoctrine()->getRepository(Company::class)->find($form->getData()->getId());
$data['image'] = $company_tmp->getImage();
$event->setData($data);
}
})
->getForm();
$form->handleRequest($request);
if ( ($form->isSubmitted()) && ( $form->isValid() ) ){
$company = $form->getData();
$file = $form->get('image')->getData();
if ($file !== null){
$fileName = 'company-'.$this->generateUniqueFileName().'.'.$file->guessExtension();
// Move the file to the directory where brochures are stored
try {
$moved = $file->move( $this->get('kernel')->getProjectDir() . '/public/uploads', $fileName );
} catch (FileException $e) {
throw new HttpNotFoundException("Page not found");
}
$company->setImage($fileName);
}
$entityManager= $this->getDoctrine()->getManager();
$entityManager->flush();
$flashbag = $this->get('session')->getFlashBag();
$flashbag->add("success", "Company Edited Correctly");
return $this->redirectToRoute('companies_list');
}
return $this->render('admin/edit_company.html.twig',
array(
'form' => $form->createView(),
'company' => $company,
)
);
}
例如,如果先前要保存的图像名称为company122121.jpg,而数据的编辑表单为空,则将company122121.jpg保留在数据库中。但是结果始终为空。我已经在侦听器上检查了$ event-> getData(),数据是正确的,但是当我在isSubmitted()之后获取数据时,该数据为空。
答案 0 :(得分:0)
根据官方文档: https://symfony.com/doc/current/controller/upload_file.html
创建表单以编辑已保留的项目时,文件表单 类型仍然需要File实例。现在作为永久实体 仅包含相对文件路径,您首先必须串联 配置的上传路径和存储的文件名并创建一个新的 文件类别:
std::vector<int> my_vector {1,3,3,7};
for(auto [i, my_element] : en::enumerate(my_vector))
{
// do stuff
}
所以我认为您应该添加
use Symfony\Component\HttpFoundation\File\File;
// ...
$product->setBrochure(
new File($this->getParameter('brochures_directory').'/'.$product->getBrochure())
);
之后
$company->setImage(new File($pathToYourImage));
答案 1 :(得分:0)
我还建议通过“事件事件订阅者”中包含的服务来处理图像上传。
我还将图像作为媒体对象保存到数据库,其中包含上载图像的文件名,可以通过postLoad侦听器正确解析。
参考: Doctrine Event Subscriber File Upload Service
class UploadHandler
{
/** @var string */
private $fileDirectory;
/**
* FileUploader constructor.
*
* @param string $fileDirectory
*/
public function __construct(
string $fileDirectory
) {
$this->fileDirectory = $fileDirectory;
}
/**
* Move the file to the upload directory.
*
* @param UploadedFile $file
*
* @return string
*/
public function upload(UploadedFile $file) {
$fileName = md5(uniqid() . '.' . $file->guessExtension());
$file->move($this->getFileDirectory(), $fileName);
return $fileName;
}
/**
* @return string
*/
public function getFileDirectory(): string {
return $this->fileDirectory;
}
}
class UploadEventSubscriber
{
/**
* @var FileUploader
*/
private $uploader;
/**
* UploadEventSubscriber constructor.
* @param FileUploader $uploader
*/
public function __construct(
FileUploader $uploader
)
{
$this->uploader = $uploader;
}
/**
* Returns an array of events this subscriber wants to listen to.
*
* @return string[]
*/
public function getSubscribedEvents()
{
return [
'prePersist',
'preUpdate',
'postLoad'
];
}
/**
* Pre-Persist method for Media.
*
* @param LifecycleEventArgs $args
*/
public function prePersist(LifecycleEventArgs $args) {
/** @var Media $entity */
$entity = $args->getEntity();
if (!$this->validInstance($entity)) {
return;
}
$this->uploadFile($entity);
}
/**
* Pre-Update method for Media.
*
* @param LifecycleEventArgs $args
*/
public function preUpdate(LifecycleEventArgs $args) {
/** @var Media $entity */
$entity = $args->getEntity();
if (!$this->validInstance($entity)) {
return;
}
$this->uploadFile($entity);
}
/**
* Post-Load method for Media
*
* @param LifecycleEventArgs $args
*/
public function postLoad(LifecycleEventArgs $args) {
/** @var Media $entity */
$entity = $args->getEntity();
if (!$this->validInstance($entity)) {
return;
}
$fileName = $entity->getImage();
if($fileName) {
$entity->setImage(new File($this->uploader->getFileDirectory() . '/' . $fileName));
}
}
/**
* Check if a valid entity is given.
*
* @param object $entity
* @return bool
*/
private function validInstance($entity)
{
return $entity instanceof Media;
}
/**
* Upload the file
* @param Media $entity
*/
private function uploadFile(Media $entity)
{
$file = $entity->getImage();
if($file instanceof UploadedFile) {
$fileName = $this->uploader->upload($file);
$entity->setImage($fileName);
}
}
}