2015-02-10 15 views
6

Đây là loại hình thức của tôi:Symfony2 trường mẫu không cập nhật khi xác nhận lỗi xảy ra

class TestFormType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 

     $builder->add('thumbnail', 'hidden', array(
      'label' => 'Thumbnail', 
      'label_attr' => array(
       'class' => 'col-xs-2 control-label' 
      ), 
      'required' => false, 
      'error_bubbling' => true, 
      'required' => false 
     )); 

     $builder->add('thumbnail_data', 'file', array(
      'error_bubbling' => true, 
      'required' => false 
     )); 
    } 

    public function setDefaultOptions(\Symfony\Component\OptionsResolver\OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'X\LibraryBundle\Entity\Test', 
      'cascade_validation' => true, 
      'error_bubbling' => true, 
     )); 

    } 

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

Đây là thực thể, một phần quan trọng là setThumbnailData ($ file) phương pháp, mà các cửa hàng các tập tin hình ảnh thu nhỏ và đặt thumbnail đường dẫn thông qua phương thức setThumbnail (string).

<?php 

namespace X\LibraryBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 

/** 
* Test 
* 
* @ORM\Table(name="test") 
* @ORM\Entity(repositoryClass="X\LibraryBundle\Repository\TestRepository") 
*/ 
class Test 
{ 
    /** 
    * @ORM\Column(name="id", type="integer", nullable=false) 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    /** 
    * @ORM\Column(type="text", nullable=true) 
    */ 
    protected $thumbnail; 

    /** 
    * Set thumbnail 
    * 
    * @param string $thumbnail 
    * @return Test 
    */ 
    public function setThumbnail($thumbnail) 
    { 
     $this->thumbnail = $thumbnail; 

     return $this; 
    } 

    /** 
    * Get thumbnail 
    * 
    * @return string 
    */ 
    public function getThumbnail() 
    { 
     return $this->thumbnail; 
    } 

    /** 
    * This will save file to disk 
    * @param $file 
    */ 
    public function setThumbnailData($file) { 
     if($file !== null && $file !== false) 
     { 
      $fileName = $file->getClientOriginalName(); 
      $baseDir = __DIR__ . '/../../../../../../../web/uploads/promotional_material/'; 
      $dir = sha1(microtime()); 
      while (is_dir($baseDir . $dir)) { 
       $dir = sha1(microtime()); 
      } 
      mkdir($baseDir . $dir); 
      $this->setThumbnail('/uploads/promotional_material/' . $dir . '/' . $fileName); 
      $file->move($baseDir . $dir, $fileName); 
     } 
    } 

    public function getThumbnailData() { 
     return ''; 
    } 
} 

Bây giờ vấn đề là, nếu các hình thức chạy vào một lỗi xác nhận, các đường cành lá sau sản xuất sản lượng khác nhau, giá trị đúng outputted từ dòng thứ hai, người kia tạo ra con đường thumbnail gốc. Vì vậy, nếu tôi xuất đầu vào hình thu nhỏ bằng cách sử dụng {{form_widget (form.thumbnail)}}, tôi nhận được đường dẫn hình thu nhỏ ban đầu, không phải là đường dẫn đã thay đổi thông qua phương thức setThumbnailData().

{{ dump(form.thumbnail.vars.data) }} 
{{ dump(form.vars.data.thumbnail) }} 

Sự cố có gây ra bằng cách đặt hình thu nhỏ bằng phương thức setThumbnailData() không? Bạn không chắc chắn làm thế nào để sửa lỗi này không phải là cứng mã hóa các đầu vào trong cành lá như vậy:

<input type="hidden" name="test[thumbnail]" value="{{ form.vars.value.thumbnail }}"/> 

Trả lời

5

Tôi không thể chính xác giải quyết vấn đề của bạn, bởi vì trong quan điểm của tôi bạn đang làm nó một cách sai lầm. Một lớp dữ liệu là thực sự chỉ có trách nhiệm để giữ cho dữ liệu của bạn, vì vậy phương pháp của bạn set/getThumbnailData sẽ trông như thế này

<?php 
// ... 
private $thumbnailData; 

public function setThumbnailData(UploadedFile $thumbnailData) { 
    $this->thumbnailData = $thumbnailData; 
} 

public function getThumbnailData() { 
    return $this->thumbnailData; 
} 

Trong điều khiển của bạn, bạn có một cái gì đó như thế này:

<?php 
// ... 
public function formAction() { 

    $form = // ... 
    $form->handleRequest($request); 
    if($form->isValid()) { 
     $test = $form->getData(); 
     /* @var $test Test */ 
     $thumbnailUploader = $this->get('thumbnail_uploader'); 
     /* @var $thumbnailUploader ThumbnailUploadService */ 

     $file = $test->getThumbnailData(); 
     $filename = $file->getClientOriginalName(); 
     $thumbnailUploader->upload($filename, $file); 

     // ... 
    } 
} 

Tôi khuyên bạn nên di chuyển tất cả các logic mà không liên quan gì đến các biểu mẫu hoặc yêu cầu vào dịch vụ. Dịch vụ của bạn trong trường hợp này có thể được xử lý chung hơn bất kỳ tệp symfony nào với một tên tệp đã cho.

<?php 
class ThumbnailUploadService { 
    /** 
    * @param $file Symfony\Component\HttpFoundation\File\File 
    * 
    */ 
    public function upload($filename, File $file) { 
     // ... 
    } 
} 
+0

Tôi cũng muốn lưu tệp vào đĩa ngay cả khi nó không xác thực, do đó người dùng không phải tải lên lại hình ảnh nếu xảy ra lỗi xác thực. – Trololololol

+0

Sau đó, tạo một 'Type' và' Validator' mới làm cho nó liền mạch với khuôn khổ của symfony, có thể với trường 'file' và' hidden' là kiểu con. Nếu bạn chỉ lưu tệp của mình vào đĩa, điều gì sẽ xảy ra nếu người dùng không bao giờ nhập dữ liệu hợp lệ? – Aitch

0

Cũng có một cách khác sử dụng callbacks. Ở đây tôi cung cấp cho bạn một lớp chung để tải lên hình ảnh và tạo hình thu nhỏ. Tôi hy vọng công việc này cho bạn. Lớp này quản lý các tệp được tạo tự động khi bạn tạo bản cập nhật o xóa thực thể.

use Doctrine\ORM\Mapping as ORM; 
use Symfony\Bridge\Doctrine\Validator\Constraints as DoctrineAssert; 
use Symfony\Component\HttpFoundation\File\UploadedFile; 
use Symfony\Component\Validator\Constraints as Assert; 
use App\MyBundleBundle\Util\Util; 

/** 
* Image 
* 
* @ORM\Table(name="image") 
* @ORM\Entity() 
* @ORM\HasLifecycleCallbacks 
*/ 
class Image 
{ 

    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    * 
    */ 
    private $id; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="name", type="string") 
    * @Assert\NotBlank() 
    */ 
    private $name; 


    private $temp; 

    /** 
    * @ORM\Column(type="string", length=255) 
    */ 
    protected $path; 

    /** 
    * @Assert\Image(maxSize="5M") 
    */ 
    private $file; 

    /** 
    * Sets file. 
    * 
    * @param UploadedFile $file 
    */ 
    public function setFile(UploadedFile $file = null) 
    { 
     $this->file= $file; 

     if (isset($this->path)) { 
      $this->temp = $this->path; 
      $this->path= null; 
     } else { 
      $this->path= 'initial'; 
     } 
    } 

    /** 
    * Get file. 
    * 
    * @return UploadedFile 
    */ 
    public function getFile() 
    { 
     return $this->file; 
    } 

    /** 
    * @ORM\PrePersist() 
    * @ORM\PreUpdate() 
    */ 
    public function preUpload() 
    { 
     if (null !== $this->getFile()) { 
      // do whatever you want to generate a unique name 
      $filename = Util::getSlug($this->name) . uniqid() . '.' . $this->file->guessExtension(); 
      $this->path = $filename; 
     } 
    } 

    /** 
    * @ORM\PostPersist() 
    * @ORM\PostUpdate() 
    */ 
    public function upload() 
    { 
     if (null === $this->getFile()) { 
      return; 
     } 

     $this->getFile()->move($this->getUploadRootDir(), $this->path); 
     if (isset($this->temp)) { 
      if (file_exists($this->getUploadRootDir() .'/'. $this->temp)) { 
       unlink($this->getUploadRootDir() . '/' . $this->temp); 
      } 
      $this->temp = null; 
     } 
     $this->file= null; 
     //create a dir to save de thumbnails 
     if (!file_exists($this->getUploadRootDir() . '/thumbnails')) { 
      mkdir($this->getUploadRootDir() . '/thumbnails'); 
     } 

     //call a method in util class to generate the thumbnails 
     Util::redim($this->getUploadRootDir() . '/' . $this->path, $this->getUploadRootDir() . '/thumbnails/' . $this->path, 128, 128); 
    } 

    /** 
    * @ORM\PostRemove() 
    */ 
    public function removeUpload() 
    { 
     //This is to remove the files when the entity is delete 
     if ($file = $this->getAbsolutePath()) { 
      if (file_exists($file)) { 
       unlink($file); 
       $thumb = $this->getUploadRootDir() . '/thumbnails/' . $this->getPath(); 
       if (file_exists($thumb)) { 
        unlink($thumb); 
       } 
      } 
     } 
    } 

    public function getAbsolutePath() 
    { 
     return null === $this->path ? null : $this->getUploadRootDir() . '/' . $this->path; 
    } 

    public function getWebPath() 
    { 
     return null === $this->path? null : 
      $this->getUploadDir() . '/' . $this->path; 
    } 

    protected function getUploadRootDir() 
    { 
     return $this->getUploadDir(); 
    } 

    protected function getUploadDir() 
    { 
     return 'uploads/image/'; 
    } 

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

    /** 
    * Set nombre 
    * 
    * @param string $name 
    * @return Image 
    */ 
    public function setName($name) 
    { 
     $this->name= $name; 

     return $this; 
    } 

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


    /** 
    * Set path 
    * 
    * @param string $path 
    * @return Imagen 
    */ 
    public function setPath($path) 
    { 
     $this->path= $path; 

     return $this; 
    } 

    /** 
    * Get path 
    * 
    * @return string 
    */ 
    public function getPath() 
    { 
     return $this->path; 
    } 

    public function __toString() 
    { 
     return $this->getName(); 
    } 
} 
Các vấn đề liên quan