2017-02-21 1 views
0

다음 안내는 다음과 같습니다 : File upload tutorialCollection form type guide. 모든 것은 괜찮 았지만 "편집"작업이었습니다. 이미지 수집은 "편집"작업에서 올바르게 표시되지만 양식을 제출할 때 (새 이미지를 추가하지 않고) 오류가 발생합니다. 대신 UploadedFile 컬렉션에 이미지가 NULL 값을 가지고 있다는 것을 의미 널Symfony3, 이미지 수집을위한 양식 편집

의 멤버 함수 guessExtension()에

전화.

나는 교리로 이미지 모음을 다루는 것에 관한 많은 의문점을 읽었지만 아직 단서는 없다. 같은

질문 :

그래서 질문은 u는 편집 영상을 처리 할 수있는 방법인가? 제거도 필요합니다.

컨트롤러 편집 작업을

public function editAction(Request $request, Stamp $stamp) 
{ 
    if (!$stamp) { 
     throw $this->createNotFoundException('No stamp found'); 
    } 
    $form = $this->createForm(AdminStampForm::class, $stamp); 

    $form->handleRequest($request); 
    if ($form->isSubmitted() && $form->isValid()) { 
     /** @var Stamp $stamp */ 
     $stamp = $form->getData(); 
     foreach ($stamp->getImages() as $image) { 
      $fileName = md5(uniqid()) . '.' . $image->getName()->guessExtension(); 
      /** @var $image StampImage */ 
      $image->getName()->move(
       $this->getParameter('stamps_images_directory'), 
       $fileName 
      ); 
      $image->setName($fileName)->setFileName($fileName); 
     } 
     $em = $this->getDoctrine()->getManager(); 
     $em->persist($stamp); 
     $em->flush(); 

     $this->addFlash('success', 'Successfully edited a stamp!'); 

     return $this->redirectToRoute('admin_stamps_list'); 
    } 

    return [ 
     'form' => $form->createView(), 
    ]; 
} 

법인

<?php 

namespace AppBundle\Entity; 

use Doctrine\Common\Collections\ArrayCollection; 
use Doctrine\ORM\Mapping as ORM; 
use Doctrine\ORM\Mapping\JoinColumn; 
use Doctrine\ORM\Mapping\JoinTable; 
use Doctrine\ORM\Mapping\ManyToMany; 

/** 
* Class Stamp 
* @package AppBundle\Entity 
* 
* 
* @ORM\Entity(repositoryClass="AppBundle\Repository\StampRepository") 
* @ORM\Table(name="stamp") 
* @ORM\HasLifecycleCallbacks() 
*/ 
class Stamp 
{ 
    /** 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    * @ORM\Column(type="integer") 
    */ 
    private $id; 

    //  * @ORM\OneToMany(targetEntity="AppBundle\Entity\StampImage", mappedBy="id", cascade={"persist", "remove"}) 

    /** 
    * @ManyToMany(targetEntity="AppBundle\Entity\StampImage", cascade={"persist"}) 
    * @JoinTable(name="stamps_images", 
    *  joinColumns={@JoinColumn(name="stamp_id", referencedColumnName="id")}, 
    *  inverseJoinColumns={@JoinColumn(name="image_id", referencedColumnName="id", unique=true)} 
    *  )  */ 
    private $images; 

    /** 
    * @ORM\Column(type="datetime") 
    */ 
    private $createdAt; 

    /** 
    * @ORM\Column(type="datetime") 
    */ 
    private $updatedAt; 

    public function __construct() 
    { 
     $this->images = new ArrayCollection(); 
    } 

    /** 
    * @return mixed 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    public function addImage(StampImage $image) 
    { 
     $this->images->add($image); 
    } 

    public function removeImage(StampImage $image) 
    { 
     $this->images->removeElement($image); 
    } 

    /** 
    * @return mixed 
    */ 
    public function getImages() 
    { 
     return $this->images; 
    } 

    /** 
    * @param mixed $images 
    * 
    * @return $this 
    */ 
    public function setImages($images) 
    { 
     $this->images = $images; 

     return $this; 
    } 

    /** 
    * @return mixed 
    */ 
    public function getCreatedAt() 
    { 
     return $this->createdAt; 
    } 

    /** 
    * @param mixed $createdAt 
    * 
    * @return Stamp 
    */ 
    public function setCreatedAt($createdAt) 
    { 
     $this->createdAt = $createdAt; 

     return $this; 
    } 

    /** 
    * @return mixed 
    */ 
    public function getUpdatedAt() 
    { 
     return $this->updatedAt; 
    } 

    /** 
    * @param mixed $updatedAt 
    * 
    * @return Stamp 
    */ 
    public function setUpdatedAt($updatedAt) 
    { 
     $this->updatedAt = $updatedAt; 

     return $this; 
    } 

    /** 
    * @ORM\PrePersist 
    * @ORM\PreUpdate 
    */ 
    public function updateTimestamps() 
    { 
     $this->setUpdatedAt(new \DateTime('now')); 

     if (null == $this->getCreatedAt()) { 
      $this->setCreatedAt(new \DateTime()); 
     } 
    } 
} 

StampImage 엔티티

<?php 

namespace AppBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity as UniqueEntity; 
use Symfony\Component\Validator\Constraints as Assert; 

/** 
* Class StampImage 
* @package AppBundle\Entity 
* 
* @ORM\Entity() 
* @ORM\Table(name="stamp_image") 
* @UniqueEntity(fields={"name"}, message="This file name is already used.") 
*/ 
class StampImage 
{ 
    /** 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    * @ORM\Column(type="integer") 
    */ 
    private $id; 

    /** 
    * @return mixed 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    private $name; 

    /** 
    * @ORM\Column(type="string") 
    */ 
    private $fileName; 

    /** 
    * @return mixed 
    */ 
    public function getFileName() 
    { 
     return $this->fileName; 
    } 

    /** 
    * @param mixed $fileName 
    * 
    * @return StampImage 
    */ 
    public function setFileName($fileName) 
    { 
     $this->fileName = $fileName; 

     return $this; 
    } 

    /** 
    * @return mixed 
    */ 
    public function getName() 
    { 
     return $this->name; 
    } 

    /** 
    * @param mixed $name 
    * 
    * @return StampImage 
    */ 
    public function setName($name) 
    { 
     $this->name = $name; 

     return $this; 
    } 

} 
(210) 홈페이지 엔티티 양식

<?php 

namespace AppBundle\Form; 

use AppBundle\Entity\Stamp; 
use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\Extension\Core\Type\CollectionType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolver; 

class AdminStampForm extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('images', CollectionType::class, [ 
       'entry_type' => AdminStampImageForm::class, 
       'allow_add' => true, 
       'allow_delete' => true, 
       'by_reference' => false, 
      ]) 
     ; 

    } 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults([ 
      'data_class' => Stamp::class, 
     ]); 
    } 

    public function getName() 
    { 
     return 'app_bundle_admin_stamp_form'; 
    } 
} 

이미지 양식 유형

<?php 

namespace AppBundle\Form; 

use AppBundle\Entity\StampImage; 
use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\Extension\Core\Type\FileType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolver; 

class AdminStampImageForm extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('name', FileType::class, [ 
       'image_name' => 'fileName', 
       'label' => false, 
       'attr' => [ 
       ], 
      ]); 
    } 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults([ 
      'data_class' => StampImage::class, 
      'required' => false 
     ]); 
    } 

    public function getBlockPrefix() 
    { 
     return 'app_bundle_admin_stamp_image_form'; 
    } 
} 

파일 유형 확장

- extends 'form_div_layout.html.twig' 

- block file_widget 
    - spaceless 
    - if image_url is not null 
     %img{:src => "#{image_url}"} 
     %div{:style => "display: none;"} 
     #{block('form_widget')} 
    - else 
     #{block('form_widget')} 
+0

'StampImage' 엔티티를 추가 하시겠습니까? – sakhunzai

+0

문제는 없습니다. –

+0

정확한 오류를 재현 할 수 없으므로'$ fileName = md5 (uniqid()) '줄을 바꾸는 것이 좋습니다. '.' . $ image-> getName() -> guessExtension();'과 같은 빠른 디버그 라인으로'var_dump ($ image, $ image-> getName()); 'foreach' 블록 후 – sakhunzai

답변

1

1) Multiupload (그러나 OneToMany하지 않음)

$fileName = md5(uniqid()) . '.' . $image->getName()->guessExtension(); 

를 교체합니다.업로드 된 이미지를 편집하기위한

2) :

# AppBundle/Entity/Stamp 
/** 
* @ORM\Column(type="string", length=255) 
*/ 
private $image; 

# AppBundle/Form/StampForm 
->add('imageFile', FileType::class, [ //the $image property of Stamp entity class will store the path to the file, and this imageFile field will get the uploaded file 
    'data_class' => null, //important! 
]) 

#AppBundle/Controller/StampController 
/** 
* @Route("/{id}/edit", name="stamp_edit") 
* @Method({"GET", "POST"}) 
*/ 
public function editAction(Request $request, Stamp $stamp) { 
    $editForm = $this->createForm(StampType::class, $stamp, [ 
     'action'=>$this->generateUrl('stamp_edit',['id'=>$stamp->getId()]), 
     'method'=>'POST' 
    ]); 
    $editForm->handleRequest($request); 
    if($editForm->isSubmitted() && $form->isValid()) { 
     $imageFile = $editForm->get('imageFile')->getData(); 
     if (null != $imageFile) { //this means that for the current record that needs to be edited, the user has chosen a different image 
      //1. remove the old image 
      $oldImg = $this->getDoctrine()->getRepository('AppBundle:Stamp')->find($stamp); 
      $this->get('app.file_remove')->removeFile($oldImg->getImage()); 

      //2. upload the new image 
      $img = $this->get('app.file_upload')->upload($imageFile); 

      //3. update the db, replacing the path to the old file with the path to the new uploaded file 
      $stamp->setImage($img); 
      $this->getDoctrine()->getManager()->flush(); 

      //4. add a success flash, and anything else you need, and redirect to a route 
     } else { //if the user has chosen to edit a different field (but not the image one) 
      $this->getDoctrine()->getManager()->flush(); 
      //add flash message, and redirect to a route 
     } 
    } 

    return $this->render(...); 
} 

#AppBundle/Services/FileRemove 
use Symfony\Component\Filesystem\Filesystem; 
use Symfony\Component\Filesystem\Exception\IOExceptionInterface; 
class FileRemove { 
    private $targetDir; 
    public function __construct($targetDir) { 
     $this->targetDir = $targetDir; 
    } 
    public function removeFile($path) { 
     $fs = new Filesystem(); 
     $file = $this->targetDir . '/' . $path; 
     try{ 
      if($fs->exists($file)){ 
       $fs->remove($file); 
       return true; 
      } 
      return false; 
     } catch(IOExceptionInterface $e){ 
      //log error for $e->getPath(); 
     } 
    } 
} 

#app/config/services.yml 
app.file_remove: 
    class: AppBundle/Services/FileRemove 
    arguments: ['%stamp_dir%'] 

#app/config/config.yml 
parameters: 
    stamp_dir: '%kernel.root_dir%/../web/uploads/stamps' //assuming this is how you've set up the upload directory 

#AppBundle/Services/FileUpload 
use Symfony\Component\HttpFoundation\File\UploadedFile; 
class FileUpload{ 
    private $targetDir; 
    public function __construct($targetDir) { 
     $this->targetDir = $targetDir; 
    } 
    public function upload(UploadedFile $file) { 
     $file_name = empty($file->getClientOriginalName()) ? md5(uniqid()).'.'.$file->guessExtension() : $file->getClientOriginalName(); 
     $file->move($this->targetDir, $file_name); 
     return $file_name; 
    } 
} 

#app/config/services.yml 
app.file_upload: 
    class: AppBundle\Services\FileUpload 
    arguments: ['%stamp_dir%'] 

오타 죄송합니다,이 귀하의 경우에 작동하는 경우에 나는 당신에 내 경우를 적응으로 나를, 알려 주시기 바랍니다.

+0

좋은 접근 방법 인 것 같습니다. 그러나 이미지를 어떻게 제거합니까? –

+0

@AlexeyVasiljev'FileRemove' 서비스에서'removeFile()'메소드를 호출하고 db에서 파일 경로를 삭제하면됩니다. 그게 다야! –

0

는 이미지 형태 여부 foreach 전에를 경쟁 업로드 확인합니다.

if ($form->isSubmitted() && $form->isValid()) { 
    /** @var Stamp $stamp */ 
    $stamp = $form->getData(); 

    if(!empty($stamp->getImages()) && count($stamp->getImages()) > 0){ // Check uploaded image 
     foreach ($stamp->getImages() as $image) { 
      $fileName = md5(uniqid()) . '.' . $image->guessExtension(); 
      /** @var $image StampImage */ 
      $image->getName()->move(
       $this->getParameter('stamps_images_directory'), 
       $fileName 
      ); 
      $image->setName($fileName)->setFileName($fileName); 
     } 
    } 
    $em = $this->getDoctrine()->getManager(); 
    $em->persist($stamp); 
    $em->flush(); 

    $this->addFlash('success', 'Successfully edited a stamp!'); 

    return $this->redirectToRoute('admin_stamps_list'); 
} 

업데이트 #

1

$fileName = md5(uniqid()) . '.' . $image->guessExtension(); 
+0

같은 이야기입니다. count ($ stamp-> getImages())는 "3"을 실제 이미지 양으로 반환합니다. –

+0

나는 대답을 업데이트했습니다. 사용해보기 –

+0

아니요, 맞습니다. –