2013-08-22 57 views
1

我有两个实体Kitchen和KitchenImage。厨房的子图像存储在KitchenImage实体中。Symfony2 - 不显示嵌入式表格

我遇到的问题是没有显示Kitc​​henImage的文件输入框,但是它的标签是?

嫩枝文件:

<div class="row"> 
    <div class="col-md-12"> 
     {{ form_start(form, {'attr': {'role': 'form'}}) }} 
      <div class="form-group"> 
       {{ form_label(form.name, 'Title') }} 
       {{ form_errors(form.name) }} 
       {{ form_widget(form.name, {'attr': {'class': 'form-control', 'placeholder': 'Enter title' }}) }} 
      </div> 
      <div class="row"> 
       <div class="form-group col-md-3"> 
        {{ form_label(form.image, 'Main Image') }} 
        {{ form_errors(form.image) }} 
        {{ form_widget(form.image) }} 
        <p class="help-block">Main Image</p> 
       </div> 
       <div class="form-group col-md-3"> 
        {{ form_label(form.images, 'Sub Images') }} 
        {{ form_errors(form.images) }} 
        {{ form_widget(form.images) }} 
        <p class="help-block">Sub Images</p> 
       </div> 
      </div> 
      <div class="form-group"> 
       {{ form_label(form.description) }} 
       {{ form_errors(form.description) }} 
       {{ form_widget(form.description, {'attr': {'class': 'form-control' }}) }} 
      </div> 
      <button type="submit" class="btn btn-default">Submit</button> 
     {{ form_end(form) }} 
    </div> 
</div> 

控制器

<?php 

namespace PWD\AdminBundle\Controller; 

use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\HttpFoundation\Response; 

use PWD\AdminBundle\Form\Type\KitchenType; 
use PWD\AdminBundle\Form\Type\KitchenImageType; 
use PWD\WebsiteBundle\Entity\Kitchen; 
use PWD\WebsiteBundle\Entity\KitchenImage; 

class KitchenController extends Controller 
{ 

    public function addAction(Request $request) 
    { 
     $kitchen = new Kitchen(); 
     $form = $this->createForm(new KitchenType(), $kitchen); 
     $form->handleRequest($request); 

     if ($form->isValid()) 
     { 
      return "Yeah!"; 
     } 

     return $this->render('PWDAdminBundle:Pages:add-kitchen.html.twig', array(
      'form' => $form->createView(), 
     )); 
    } 
} 

KitchenType

<?php 

namespace PWD\AdminBundle\Form\Type; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 

class KitchenType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
       ->add('name', 'text') 
       ->add('description', 'textarea') 
       ->add('image', 'file') 
       ->add('images', 'collection', array(
        'type' => new KitchenImageType(), 
        'cascade_validation' => true, 
        )); 
    } 

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

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'PWD\WebsiteBundle\Entity\Kitchen', 
      'cascade_validation' => true, 
     )); 
    } 
} 

KitchenImageType

<?php 

namespace PWD\AdminBundle\Form\Type; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 

class KitchenImageType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('image', 'file'); 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'PWD\WebsiteBundle\Entity\KitchenImage', 
      'cascade_validation' => true, 
      'allow_add' => true, 
     )); 
    } 

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

KitchenImage实体

<?php 

namespace PWD\WebsiteBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 

use Symfony\Component\Validator\Constraints as Assert; 
use Symfony\Component\HttpFoundation\File\UploadedFile; 

/** 
* KitchenImage 
* 
* @ORM\Table(name="kitchen_image") 
* @ORM\Entity 
*/ 
class KitchenImage 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    /** 
    * @Assert\File(maxSize="6000000") 
    * @Assert\Image(
    *  minWidth = 800, 
    *  maxWidth = 800, 
    *  minHeight = 467, 
    *  maxHeight = 467 
    *) 
    */ 
    public $image; 

    /** 
    * @ORM\ManyToOne(targetEntity="Kitchen", inversedBy="image") 
    * @ORM\JoinColumn(name="kitchen_id", referencedColumnName="id") 
    */ 
    protected $kitchen; 

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

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

    /** 
    * Set image 
    * 
    * @param UploadedFile $file 
    */ 
    public function setImage(UploadedFile $image = null) 
    { 
     $this->image = $image; 
    } 

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

    /** 
    * Set kitchen 
    * 
    * @param \PWD\WebsiteBundle\Entity\Kitchen $kitchen 
    * @return KitchenImage 
    */ 
    public function setKitchen(\PWD\WebsiteBundle\Entity\Kitchen $kitchen = null) 
    { 
     $this->kitchen = $kitchen; 

     return $this; 
    } 

    /** 
    * Get kitchen 
    * 
    * @return \PWD\WebsiteBundle\Entity\Kitchen 
    */ 
    public function getKitchen() 
    { 
     return $this->kitchen; 
    } 

    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() 
    { 
     // the absolute directory path where uploaded 
     // documents should be saved 
     return __DIR__.'/../../../../web/'.$this->getUploadDir(); 
    } 

    protected function getUploadDir() 
    { 
     // get rid of the __DIR__ so it doesn't screw up 
     // when displaying uploaded doc/image in the view. 
     return 'uploads/our-work'; 
    } 

    public function upload() 
    { 
    // the file property can be empty if the field is not required 
    if (null === $this->getImage()) { 
     return; 
    } 

    // use the original file name here but you should 
    // sanitize it at least to avoid any security issues 

    // move takes the target directory and then the 
    // target filename to move to 
    $this->getImage()->move(
     $this->getUploadRootDir(), 
     $this->getImage()->getClientOriginalName() 
    ); 

    // set the path property to the filename where you've saved the file 
    $this->path = $this->getImage()->getClientOriginalName(); 

    // clean up the file property as you won't need it anymore 
    $this->image = null; 
    } 

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

     return $this; 
    } 

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

厨房实体

<?php 

namespace PWD\WebsiteBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Doctrine\Common\Collections\ArrayCollection; 

use Symfony\Component\Validator\Constraints as Assert; 
use Symfony\Component\HttpFoundation\File\UploadedFile; 

/** 
* @ORM\Entity 
* @ORM\Table(name="kitchen") 
*/ 
class Kitchen 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    /** 
    * @ORM\Column(type="string", length=100) 
    * @Assert\NotBlank() 
    */ 
    protected $name; 

    /** 
    * @ORM\Column(type="text") 
    * @Assert\NotBlank() 
    */ 
    protected $description; 

    /** 
    * @Assert\File(maxSize="6000000") 
    * @Assert\NotNull() 
    * @Assert\Image(
    *  minWidth = 800, 
    *  maxWidth = 800, 
    *  minHeight = 467, 
    *  maxHeight = 467 
    *) 
    */ 
    protected $image; 

    /** 
    * @ORM\OneToMany(targetEntity="KitchenImage", mappedBy="kitchen") 
    * @Assert\Type(type="PWD\WebsiteBundle\Entity\KitchenImage") 
    */ 
    protected $images; 

    /** 
    * @ORM\Column(type="string", length=255, nullable=true) 
    */ 
    public $imagePath; 

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

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

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

     return $this; 
    } 

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

    /** 
    * Set description 
    * 
    * @param string $description 
    * @return Kitchen 
    */ 
    public function setDescription($description) 
    { 
     $this->description = $description; 

     return $this; 
    } 

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

    /** 
    * Set image 
    * 
    * @param UploadedFile $image 
    * @return Kitchen 
    */ 
    public function setImage(UploadedFile $image = null) 
    { 
     $this->image = $image; 
    } 

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

    /** 
    * Add images 
    * 
    * @param \PWD\WebsiteBundle\Entity\KitchenImage $images 
    * @return Kitchen 
    */ 
    public function addImage(\PWD\WebsiteBundle\Entity\KitchenImage $images) 
    { 
     $this->images[] = $images; 

     return $this; 
    } 

    /** 
    * Remove images 
    * 
    * @param \PWD\WebsiteBundle\Entity\KitchenImage $images 
    */ 
    public function removeImage(\PWD\WebsiteBundle\Entity\KitchenImage $images) 
    { 
     $this->images->removeElement($images); 
    } 

    /** 
    * Get images 
    * 
    * @return \Doctrine\Common\Collections\Collection 
    */ 
    public function getImages() 
    { 
     return $this->images; 
    } 

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

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

    /** 
    * Get upload root directory 
    */ 
    protected function getUploadRootDir() 
    { 
     return __DIR__.'/../../../../web/'.$this->getUploadDir(); 
    } 

    /** 
    * Get upload directory 
    */ 
    protected function getUploadDir() 
    { 
     return 'uploads/our-work'; 
    } 

    /** 
    * Upload image 
    */ 
    public function upload() 
    { 
    // The file property can be empty if the field is not required 
    if (null === $this->getImage()) { 
     return; 
    } 

    // move takes the target directory and then the 
    // target filename to move to 
    $this->getImage()->move(
     $this->getUploadRootDir(), 
     $this->getImage()->getClientOriginalName() 
    ); 

    // set the path property to the filename where you've saved the file 
    $this->imagePath = $this->getImage()->getClientOriginalName(); 

    // clean up the file property as you won't need it anymore 
    $this->image = null; 
    } 

    /** 
    * Set imagePath 
    * 
    * @param string $imagePath 
    * @return Kitchen 
    */ 
    public function setImagePath($imagePath) 
    { 
     $this->imagePath = $imagePath; 

     return $this; 
    } 

    /** 
    * Get imagePath 
    * 
    * @return string 
    */ 
    public function getImagePath() 
    { 
     return $this->imagePath; 
    } 
} 
+0

首先创建一个新的树枝模板,其中只有{{form(form)}}。看起来不漂亮,但看看是否显示输入框。这会将问题与代码或模板隔离开来。 – Cerad

+0

@Cerad嗨 - 同样的问题发生 - 不显示图像的文件输入。 – ritch

+0

好的。我假设厨房图像输入框显示?你有没有把厨房图像贴在厨房里?无论如何,你的控制器只需制作一个KitchenImageFormType并将其提供给{{form(form)}}模板。确保模板中没有其他东西。只想看看表格。这会将问题隔离到KitcheImage本身或某种收集问题。 KitchenImage具有公共属性并且其中一些未映射到数据库有点奇怪。 – Cerad

回答

0

我敢肯定,问题是,你在你的KitchenImageType有allow_add当它应该在你的工具包中收集陈式

class KitchenType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
    $builder 
      ->add('name', 'text') 
      ->add('description', 'textarea') 
      ->add('image', 'file') 
      ->add('images', 'collection', array(
       'type' => new KitchenImageType(), 
       'cascade_validation' => true, 
       'allow_add' => true, // *** Need this here, remove it from KitchenImageType 
       )); 
} 

可能还有其他问题,但我认为就是这样。您可能要仔细阅读本书中的示例:http://symfony.com/doc/current/cookbook/form/form_collections.html。有很多事情需要让新的东西工作。

==================================

并做出反应的的有关添加评论用于测试的厨房图像,只是

public function addAction(Request $request) 
{ 
    $kitchen = new Kitchen(); 
    $kitchen->addImage(new KitchenImage()); 
    $form = $this->createForm(new KitchenType(), $kitchen); 

这是有点混淆图像和图像属性。稍后,您可能需要将图像重命名为像subImages和图像到mainImage的图像,只是为了清晰起见。但它仍然应该工作。

==================================

它您的厨房的实体,您将需要这样的事情坚持不懈:

// Note that your are only passing one image at a time to argument is $image not $images 
public function addImage(\PWD\WebsiteBundle\Entity\KitchenImage $kitchenImage) 
{ 
    $this->images[] = $kitchenImage; 
    $kitchenImage->setKitchen($this); // *** Need this for persisting 
    return $this; 
} 

===================================== ====

当你通过故障排除过程才发现基本问题是完全不同的东西时总是很有趣。您需要了解文件上传的工作方式,不仅仅是在Symfony/Doctrine中,而是在网络上。

有了一个新的项目,请仔细阅读并实现这一点:

http://symfony.com/doc/current/cookbook/doctrine/file_uploads.html

http://symfony.com/doc/current/reference/forms/types/file.html

一旦你了解如何上传文件(即图像)以及如何存储他们(在数据库路径,该文件本身在Web服务器上的某个地方),那么你可以回到你的厨房的东西,并正确处理图像。一旦你这样做,只要让你的主厨房图像工作,然后添加一组子图像。

+0

感谢您迄今为止的帮助。我做了修改建议,但没有区别。 – ritch

+0

添加额外的代码位。我得到一个奇怪的结果 - 输入框出现,但有两个标签和一个0打印 - http://i.imgur.com/YpO4szi.png – ritch

+0

我是否设置了错误的关系?这是令人困惑的,因为这是我第一次使用教义 - 由于两个文件输入而变得更加困难。重新开始会更好吗? – ritch