I have two entities: Product
and Image
and many Products can have many
Images so this generates a third table ProductHasImages
. Entities are right
as doctrine:schema:validate
command outputs:
Symfony > doctrine:schema:validate
[Mapping] OK - The mapping files are correct.
[Database] FAIL - The database schema is not in sync with the current
mapping file.
The command terminated with an error status (2)
I've added this lines to my config.yml
:
services:
tan.common.admin.image:
class: Tan\CommonBundle\Admin\ImageAdmin
tags:
- { name: sonata.admin, manager_type: orm, label: "Imagenes",
show_in_dashboard: false }
arguments: [null, Tan\CommonBundle\Entity\Image, null]
I've have the file Tan\CommonBundle\Admin\ImageAdmin.php
created with the
following content:
<?php
namespace Tan\CommonBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Form\FormMapper;
class ImageAdmin extends Admin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper->add('file', 'file', array('required' => false));
}
public function prePersist($image)
{
$this->manageFileUpload($image);
}
public function preUpdate($image)
{
$this->manageFileUpload($image);
}
private function manageFileUpload($image)
{
if ($image->getFile()) {
$image->refreshUpdated();
}
}
}
Now I'm trying to add the image
field to ProductAdmin.php
as follow:
protected function configureFormFields(FormMapper $form)
{
$form
->add('product_name', null, array('label' => 'Nombre'))
->add('product_description', null, array('label' => 'Descripción'))
->add('image', 'sonata_type_admin', array('delete' => false));
}
But any time I try to add a new product I get this error:
The current field
image
is not linked to an admin. Please create one for the target entity : ``
Why? What I'm doing wrong?
For files the best in sonata admin use Sonata Media Bundle
to handle uploads and you can reuse them in your different admin once you have configured then your mapping will be
Now Products
entity will have a mapping for ProductHasImages
which can point many images (Media files from sonata media bundle) similar to
/**
* @Assert\NotBlank()
* @ORM\OneToMany(targetEntity="Namespace\YourBundle\Entity\ProductHasImages", mappedBy="productImages",cascade={"persist","remove"} )
*/
protected $images;
other fields ...
Generate its getter and setter methods
removeImages()
getImages()
setImages()
addImages()
And now your junction entity i.e (ProductHasImages
) will have a 2 mappings to point back Products
and other one will point to Sonata Media
/**
* @var \Application\Sonata\MediaBundle\Entity\Media
* @Assert\NotBlank()
* @ORM\ManyToOne(targetEntity="Application\Sonata\MediaBundle\Entity\Media", cascade={"persist"}, fetch="LAZY")
* @ORM\JoinColumn(name="media_id", referencedColumnName="id")
*/
protected $media;
/**
* @var \Namespace\YourBundle\Entity\Products
* @Assert\NotBlank()
* @ORM\ManyToOne(targetEntity="Namespace\YourBundle\Entity\Products", cascade={"persist","remove"} ,inversedBy="images", fetch="LAZY" )
* @ORM\JoinColumn(name="product_id", referencedColumnName="id",nullable=true)
*/
protected $productImages;
Generate their getters and setters
Now create Admin class for ProductHasImages
which has a field in configureFormFields
function
$formMapper->add('media', 'sonata_type_model_list', array('required' => false), array(
'link_parameters' => $link_parameters
)); //other fields too if you want to show in collection
And in your Product Admin class add this field
->add('images', 'sonata_type_collection', array(
'cascade_validation' => false,
'type_options' => array('delete' => false),
), array(
'edit' => 'inline',
'inline' => 'table',
'sortable' => 'position',
'link_parameters' => array('context' => 'default'),
'admin_code' => 'sonata.admin.product_has_images'
/*here provide service name for junction admin
like service code for admin defined for ProductHasImages */
)
)
You can find full code demo here Git Hub