问题描述:

I'm currently trying to make Symfony CMF and Sonata allow the admin user to add multiple images to a product through the same view panel. I have my Product and Image entities setup and working individually with their ORM relationships too.

Product:

class Product extends AbstractEntity

{

/**

* @ORM\OneToMany(targetEntity="Image", mappedBy="product", cascade={"persist"})

*/

protected $images;

// ...

Image:

class Image extends AbstractEntity

{

/**

* @ManyToOne(targetEntity="Product", inversedBy="image", cascade={"persist"})

* @JoinColumn(name="product_id", referencedColumnName="id")

**/

private $product;

// ...

Rather than having the user add all the images first and then link to them, I want it to be achievable from the same view. So in my ProductAdmin class I have added the following:

protected function configureFormFields(FormMapper $formMapper)

{

$formMapper

->with('Product')

->add('name', 'text', array('required' => true))

// everything else ...

->add('images', 'sonata_type_collection', array(

'type_options' => array('delete' => false),

), array(

'edit' => 'inline',

'inline' => 'table',

))

->end();

}

Currently this allows me to upload images from the product management page. However it does not create a link between the product and image and I'm not sure what I need to do to get it to do that.

UPDATE

Having read countless articles across StackOverflow and the wider web the common response I seem to be seeing is that the relation is only stored when the sonata_type_collection is used for the Admin page of the Entity which holds the relationship (in my case that would be the image). I can understand why it is that way, but it would be much better from a user perspective to work the other way round also (as I'd expect to add images to a product, and not add images and then add a product to them).

I'll leave this question open in case anyone has/does figure out a workaround.

WORKING

I've managed to get it working. Firstly I have changed my relationship to a Many-to-Many (so that images can be re-used for other products as my system contains versions), however I do not believe this is the fix itself, but worth noting none the less.

What I think has made it work is the inclusion of the by_reference attribute:

protected function configureFormFields(FormMapper $formMapper)

{

$formMapper

->with('Product')

->add('name', 'text', array('required' => true))

// everything else ...

->add('images', 'sonata_type_collection', array(

'by_reference' => false,

'type_options' => array('delete' => false),

), array(

'edit' => 'inline',

'inline' => 'table',

))

->end();

}

网友答案:

So my issue was because I was missing 'by_reference' => false: http://symfony.com/doc/current/reference/forms/types/collection.html#by-reference

Similarly, if you're using the collection form type where your underlying collection data is an object (like with Doctrine's ArrayCollection), then by_reference must be set to false if you need the adder and remover (e.g. addAuthor() and removeAuthor()) to be called.

Or in my case addImage() and removeImage().

相关阅读:
Top