Error sonata classificiation bundle - php

I have a problem. I installed sonata classification bundle.
But when I want to create a new post I have an error:
Neither the property "collection" nor one of the methods "getCollection()", "collection()", "isCollection()", "hasCollection()", "__get()" exist and have public access in class "DN\SiteBundle\Entity\Post".*
This is my code in PostAdmin.php (src/DN/SiteBundle/Admin/PostAdmin.php)
namespace DN\SiteBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Sonata\CoreBundle\Validator\ErrorElement;
use Knp\Menu\ItemInterface as MenuItemInterface;
class PostAdmin extends Admin
{
// Fields to be shown on create/edit forms
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('title', 'text', array('label' => 'Post Title'))
->add('content')
->add('publication')
->add('author')
->add('collection', 'sonata_type_model_list', array('required' => false));
}
//...
}
?>
This is my code in Post.php (src/DN/SiteBundle/Entity/Post.php)
namespace DN\SiteBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use DoctrineExtensions\Taggable\Taggable;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
*/
class Post implements Taggable
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* #var string
*
* #ORM\Column(name="author", type="string", length=255)
*/
private $author;
/**
* #var string
*
* #ORM\Column(name="content", type="text")
*/
private $content;
/**
* #var \DateTime
*
* #ORM\Column(name="created_at", type="datetime")
*/
private $created_at;
/**
* #var boolean
*
* #ORM\Column(name="publication", type="boolean")
*/
private $publication;
/**
* #var string
* #Gedmo\Slug(fields={"title"})
* #ORM\Column(name="slug", type="string", length=255)
*/
private $slug;
private $tags;
public function getTags()
{
$this->tags = $this->tags ?: new ArrayCollection();
return $this->tags;
}
public function getTaggableType()
{
return 'DN_tag';
}
public function getTaggableId()
{
return $this->getId();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set title
*
* #param string $title
* #return Post
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set author
*
* #param string $author
* #return Post
*/
public function setAuthor($author)
{
$this->author = $author;
return $this;
}
/**
* Get author
*
* #return string
*/
public function getAuthor()
{
return $this->author;
}
/**
* Set content
*
* #param string $content
* #return Post
*/
public function setContent($content)
{
$this->content = $content;
return $this;
}
/**
* Get content
*
* #return string
*/
public function getContent()
{
return $this->content;
}
/**
* Set publication
*
* #param boolean $publication
* #return Post
*/
public function setPublication($publication)
{
$this->publication = $publication;
return $this;
}
/**
* Get publication
*
* #return boolean
*/
public function getPublication()
{
return $this->publication;
}
/**
* Set slug
*
* #param string $slug
* #return Post
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Get slug
*
* #return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* Set created_at
*
* #param \DateTime $createdAt
* #return Post
*/
public function setCreatedAt($createdAt)
{
$this->created_at = $createdAt;
return $this;
}
/**
* Get created_at
*
* #return \DateTime
*/
public function getCreatedAt()
{
return $this->created_at;
}
public function __construct()
{
$this->created_at = new \DateTime("now");
}
public function __toString()
{
return $this->getTitle();
}
}

The name of your field should be "tags" instead of "collection" I guess.
I don't see a property "collection" in your Entity.
The first parameter of the add method should be the name of your property defined in your Entity.
namespace DN\SiteBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Sonata\CoreBundle\Validator\ErrorElement;
use Knp\Menu\ItemInterface as MenuItemInterface;
class PostAdmin extends Admin
{
// Fields to be shown on create/edit forms
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('title', 'text', array('label' => 'Post Title'))
->add('content')
->add('publication')
->add('author')
->add('collection', 'sonata_type_model_list', array('required' => false));
}
//...
}
?>
Documentation on forms : https://sonata-project.org/bundles/doctrine-orm-admin/master/doc/reference/form_field_definition.html

Related

Symfony 3 form pre-populate collection field type

Is it possible to populate collection with some default items
Say you have collection of prices, but each price can be of different type. And what I want is that collection always has some predefined (generated somehow) items?
Main entity
<?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\Column(type="string", length=512, nullable=true)
*/
private $title;
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Price", cascade={"persist", "remove"})
* #ORM\JoinTable(name="stamps_prices",
* joinColumns={#ORM\JoinColumn(name="stamp_id", referencedColumnName="id", onDelete="CASCADE")},
* inverseJoinColumns={#ORM\JoinColumn(name="price_id", referencedColumnName="id", onDelete="CASCADE")}
* )
*/
private $prices;
/**
* #ORM\Column(type="datetime")
*/
private $createdAt;
/**
* #ORM\Column(type="datetime")
*/
private $updatedAt;
public function __construct()
{
$this->prices = new ArrayCollection();
}
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #return mixed
*/
public function getTitle()
{
return $this->title;
}
/**
* #param mixed $title
*
* #return Stamp
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* #return mixed
*/
public function getPrices()
{
return $this->prices;
}
public function addPrice(Price $price)
{
$this->prices->add($price);
}
/**
* #param mixed $prices
*
* #return Stamp
*/
public function setPrices(ArrayCollection $prices)
{
$this->prices = $prices;
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());
}
}
}
Main entity form
<?php
namespace AppBundle\Form;
use AppBundle\Entity\Stamp;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\CallbackTransformer;
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('title', null, [
'label' => false,
'attr' => [
'id' => 'stamp-title',
'class' => 'form-control input-md',
'placeholder' => 'Enter title',
'autocomplete' => 'off'
]
])
->add('prices', CollectionType::class, [
'label' => false,
'entry_type' => AdminStampPriceForm::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';
}
}
Price entity
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Class Price
* #package AppBundle\Entity
*
* #ORM\Entity(repositoryClass="AppBundle\Repository\PriceRepository")
* #ORM\Table(name="price")
*/
class Price
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\PriceType")
* #ORM\JoinColumn(name="type_id", nullable=false, referencedColumnName="id")
*/
private $type;
/**
* #ORM\Column(type="string")
*/
private $value;
/**
* #ORM\Column(type="string", nullable=true)
*/
private $city;
/**
* #ORM\Column(type="string", nullable=true)
*/
private $issueDate;
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #return mixed
*/
public function getType()
{
return $this->type;
}
/**
* #param mixed $type
* #return Price
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* #return mixed
*/
public function getValue()
{
return $this->value;
}
/**
* #param mixed $value
*
* #return Price
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* #return mixed
*/
public function getCity()
{
return $this->city;
}
/**
* #param mixed $city
*
* #return Price
*/
public function setCity($city)
{
$this->city = $city;
return $this;
}
/**
* #return mixed
*/
public function getIssueDate()
{
return $this->issueDate;
}
/**
* #param mixed $issueDate
*
* #return Price
*/
public function setIssueDate($issueDate)
{
$this->issueDate = $issueDate;
return $this;
}
}
PriceType Entity
<?php
namespace AppBundle\Entity;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Doctrine\ORM\Mapping as ORM;
/**
* Class PriceType
* #package AppBundle\Entity
*
* #ORM\Entity(repositoryClass="AppBundle\Repository\PriceTypeRepository")
* #ORM\Table(name="price_type")
* #ORM\HasLifecycleCallbacks()
*/
class PriceType
{
const SECTION_UNUSED = 1;
const SECTION_USED = 2;
const SECTION_FDC = 3;
const SECTION_CUSTOM = 4;
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="integer")
*/
private $section;
/**
* #ORM\Column(type="string")
*/
private $name;
/**
* #ORM\Column(type="boolean")
*/
private $hasCityName = false;
/**
* #ORM\Column(type="boolean")
*/
private $hasIssueDate = false;
/**
* #ORM\Column(type="boolean")
*/
private $isPredefined = false;
/**
* #ORM\Column(type="datetime")
*/
private $createdAt;
/**
* #ORM\Column(type="datetime")
*/
private $updatedAt;
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #return mixed
*/
public function getSection()
{
return $this->section;
}
/**
* #param mixed $section
*
* #return PriceType
*/
public function setSection($section)
{
$this->section = $section;
return $this;
}
/**
* #return mixed
*/
public function getName()
{
return $this->name;
}
/**
* #param mixed $name
*
* #return PriceType
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* #return mixed
*/
public function getHasCityName()
{
return $this->hasCityName;
}
/**
* #param mixed $hasCityName
*
* #return PriceType
*/
public function setHasCityName($hasCityName)
{
$this->hasCityName = $hasCityName;
return $this;
}
/**
* #return mixed
*/
public function getHasIssueDate()
{
return $this->hasIssueDate;
}
/**
* #param mixed $hasIssueDate
*
* #return PriceType
*/
public function setHasIssueDate($hasIssueDate)
{
$this->hasIssueDate = $hasIssueDate;
return $this;
}
/**
* #return mixed
*/
public function getIsPredefined()
{
return $this->isPredefined;
}
/**
* #param mixed $isPredefined
*
* #return PriceType
*/
public function setIsPredefined($isPredefined)
{
$this->isPredefined = $isPredefined;
return $this;
}
/**
* #return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* #param \DateTime $createdAt
*
* #return PriceType
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* #return \DateTime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
/**
* #param \DateTime $updatedAt
*
* #return PriceType
*/
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());
}
}
}
PriceType repository
<?php
namespace AppBundle\Repository;
use Doctrine\ORM\EntityRepository;
/**
* Class PriceTypeRepository
* #package AppBundle\Entity
*/
class PriceTypeRepository extends EntityRepository
{
public function getPredefinedPriceTypes($section)
{
return $this
->createQueryBuilder('pt')
->andWhere('pt.section = :section')
->setParameter('section', $section)
->andWhere('pt.isPredefined = :isPredefined')
->setParameter('isPredefined', true)
->getQuery()
->getResult()
;
}
}
Priec form
<?php
namespace AppBundle\Form;
use AppBundle\Entity\Price;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class AdminStampPriceForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('value', null, [
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Price::class,
]);
}
public function getBlockPrefix()
{
return 'app_bundle_admin_stamp_price_form';
}
}
Main entity controller newAction
/**
* #Route("/new", name="admin_stamps_new")
* #Template(engine="haml")
*/
public function newAction(Request $request)
{
$stamp = new Stamp();
$priceTypeRepo = $this->getDoctrine()->getManager()->getRepository('AppBundle:PriceType');
$priceTypes = $priceTypeRepo->getPredefinedPriceTypes(PriceType::SECTION_UNUSED);
/** #var PriceType $priceType */
foreach ($priceTypes as $priceType) {
$price = new Price();
$price->setType($priceType->getId());
$stamp->addPrice($price);
}
$form = $this->createForm(AdminStampForm::class, $stamp);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** #var Stamp $stamp */
$stamp = $form->getData();
$user = $this->getUser();
$stamp->setUser($user);
$stamp->setCountry($user->getAdminConfig()->getCountry());
$em = $this->getDoctrine()->getManager();
$em->persist($stamp);
$em->flush();
$this->addFlash('success', 'Successfully added a new stamp!');
return $this->redirectToRoute('admin_stamps_list');
}
return [
'form' => $form->createView(),
];
}
So I tried to populate Stamp entity itself. But what I actually need is to have 4 separate field sets of prices (each field set for a price type). And (and) to have some predefined $priceType->isPredefined() prices to be there. I'm not sure if you understand correctly what I'm trying to say. So I will answer all upcoming questions.

Cannot get related entity field to save in Symfony Admin Form

I'm working my way through Symfony trying to learn how it all fits together and I'm working on the admin section.
Right now I'm putting together an admin form for a Show Entity which will reference a section entity (so this show belongs in that section, etc). Every other field in the form saves EXCEPT for the related entity choice field.
This is the ShowAdmin class
<?php
namespace AppBundle\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Nelmio\ApiDocBundle\Tests\Fixtures\Form\EntityType;
class ShowAdmin extends AbstractAdmin {
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper->add('title', 'text')
->add('shortname', 'text')
->add('section_id', EntityType::class, array(
'class' => 'AppBundle:SectionEntity',
'choice_label' => 'section_title',
))
->add('logo', 'text')
->add('description', 'textarea')
->add('status', 'integer');
}
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper->add('title');
$datagridMapper->add('shortname');
}
protected function configureListFields(ListMapper $listMapper)
{
$listMapper->addIdentifier('title');
$listMapper->add('shortname', 'text');
}
}
This is the ShowEntity
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="shows")
*/
class ShowEntity {
function __construct() {
$this->children = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=100)
*/
private $title;
/**
* #ORM\Column(type="string", length=100)
*/
private $shortname;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\SectionEntity")
*/
private $section;
/**
* #ORM\Column(type="string", length=255)
*/
private $logo;
/**
* #ORM\Column(type="text")
*/
private $description;
/**
* #ORM\Column(type="integer")
*/
private $status;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set title
*
* #param string $title
*
* #return ShowEntity
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set sectionId
*
* #param integer $sectionId
*
* #return ShowEntity
*/
public function setSectionId($sectionId)
{
$this->section_id = $sectionId;
return $this;
}
/**
* Get sectionId
*
* #return integer
*/
public function getSectionId()
{
return $this->section_id;
}
/**
* Set logo
*
* #param string $logo
*
* #return ShowEntity
*/
public function setLogo($logo)
{
$this->logo = $logo;
return $this;
}
/**
* Get logo
*
* #return string
*/
public function getLogo()
{
return $this->logo;
}
/**
* Set description
*
* #param string $description
*
* #return ShowEntity
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set status
*
* #param integer $status
*
* #return ShowEntity
*/
public function setStatus($status)
{
$this->status = $status;
return $this;
}
/**
* Get status
*
* #return integer
*/
public function getStatus()
{
return $this->status;
}
/**
* Set shortname
*
* #param string $shortname
*
* #return ShowEntity
*/
public function setShortname($shortname)
{
$this->shortname = $shortname;
return $this;
}
/**
* Get shortname
*
* #return string
*/
public function getShortname()
{
return $this->shortname;
}
}
And this is the SectionEntity
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* SectionEntity
*
* #ORM\Table(name="section_entity")
* #ORM\Entity(repositoryClass="AppBundle\Repository\SectionEntityRepository")
*/
class SectionEntity
{
protected $section_id;
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="text")
*/
private $section_title;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set sectionTitle
*
* #param string $sectionTitle
*
* #return SectionEntity
*/
public function setSectionTitle($sectionTitle)
{
$this->section_title = $sectionTitle;
return $this;
}
/**
* Get sectionTitle
*
* #return string
*/
public function getSectionTitle()
{
return $this->section_title;
}
/**
* Get string
*/
public function __toString() {
return $this->section_title;
}
function __construct() {
$this->section_id = new \Doctrine\Common\Collections\ArrayCollection();
}
}
Any help would be greatly appreciated, I know it's probably something super simple that I'm just not seeing.
Thanks.
(optional) Rename ShowEntity::$section into ShowEntity::$sections to highlight sections is a collection but not a single entity.
Set ShowEntity __construct method body to:
$this->sections = new \Doctrine\Common\Collections\ArrayCollection();
At ShowAdmin::configureFormFields rename
->add('section_id', EntityType::class, array(
into
->add('section', EntityType::class, array(
You should use direct reference to the relation instead of id.
Remove SectionEntity::__construct method, it has no sense.
Remove protected $section_id; from SectionEntity.
Change public function setSectionId($sectionId) into public function setSection(Section $section).
Perhaps you also need to rename section_title into sectionTitle or simply title, not sure about that.

Symfony [2.8.9] EntityType within embedded form not selecting value

I have an Organisation entity referencing an embedded form containing a Country entity. The form saves without issue, but the Country EntityType field does not correctly pick up the value upon editing, and as such the first option in the dropdown is always selected rather than the correct option.
The OrganisationType form:
<?php
namespace AppBundle\Form\Type\Meta;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;
class OrganisationType extends AbstractType
{
public function __construct()
{
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', new TitleType(),
array('required' => true, 'label' => false))
->add('country', new CountryType(), array('label' => false))
->add('location', 'text',
array('required' => false, 'label' => 'City'));
}
public function getName()
{
return 'organisation';
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Organisation',
'csrf_protection' => true,
'csrf_field_name' => '_token',
// a unique key to help generate the secret token
'intention' => 'organisation',
'cascade_validation' => true
));
}
}
The CountryType form:
<?php
namespace AppBundle\Form\Type\Meta;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;
class CountryType extends AbstractType
{
public function __construct()
{
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('id', EntityType::class, array(
'label' => 'Country',
'class' => 'AppBundle:Country',
'choice_label' => 'name',
'placeholder' => 'Choose an option...',
'query_builder' => function (EntityRepository $repository) {
return $repository->createQueryBuilder('c')->orderBy('c.name', 'ASC');
}
));
}
public function getName()
{
return 'country';
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Country'
));
}
}
Organisation Entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Gedmo\Mapping\Annotation as Gedmo;
use AppBundle\Model\OrganisationModel;
/**
* Organisation
*
* #ORM\Table(name="organisation", indexes={#ORM\Index(name="fk_meta_org_country_idx", columns={"country_id"}), #ORM\Index(name="fk_meta_org_subdivision_idx", columns={"country_subdivision_id"}), #ORM\Index(name="fk_meta_org_user_entered_idx", columns={"entered_by_user_id"}), #ORM\Index(name="fk_meta_org_user_updated_idx", columns={"updated_by_user_id"}), #ORM\Index(name="fk_meta_org_title_idx", columns={"title_id"})})
* #ORM\Entity(repositoryClass="AppBundle\Entity\OrganisationRepository")
*/
class Organisation extends OrganisationModel
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="location", type="string", length=45, nullable=false)
*/
private $location;
/**
* #var boolean
*
* #ORM\Column(name="hidden", type="boolean", nullable=false)
*/
private $hidden;
/**
* #var \DateTime
*
* #ORM\Column(name="date_entered", type="datetime", nullable=false)
* #Gedmo\Timestampable(on="create")
*/
private $dateEntered;
/**
* #var \DateTime
*
* #ORM\Column(name="date_updated", type="datetime", nullable=false)
* #Gedmo\Timestampable(on="update")
*/
private $dateUpdated;
/**
* #var \AppBundle\Entity\Country
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Country")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="country_id", referencedColumnName="id")
* })
*/
private $country;
/**
* #var \AppBundle\Entity\CountrySubdivision
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\CountrySubdivision")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="country_subdivision_id", referencedColumnName="id")
* })
*/
private $countrySubdivision;
/**
* #var \AppBundle\Entity\Title
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Title", cascade="persist")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="title_id", referencedColumnName="id")
* })
* #Assert\Type(type="AppBundle\Entity\Title")
* #Assert\Valid()
*/
private $title;
/**
* #var \AppBundle\Entity\User
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="entered_by_user_id", referencedColumnName="id")
* })
*/
private $enteredByUser;
/**
* #var \AppBundle\Entity\User
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="updated_by_user_id", referencedColumnName="id")
* })
*/
private $updatedByUser;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set location
*
* #param string $location
* #return Organisation
*/
public function setLocation($location)
{
$this->location = $location;
return $this;
}
/**
* Get location
*
* #return string
*/
public function getLocation()
{
return $this->location;
}
/**
* Set hidden
*
* #param boolean $hidden
* #return Organisation
*/
public function setHidden($hidden)
{
$this->hidden = $hidden;
return $this;
}
/**
* Get hidden
*
* #return boolean
*/
public function getHidden()
{
return $this->hidden;
}
/**
* Set dateEntered
*
* #param \DateTime $dateEntered
* #return Organisation
*/
public function setDateEntered($dateEntered)
{
$this->dateEntered = $dateEntered;
return $this;
}
/**
* Get dateEntered
*
* #return \DateTime
*/
public function getDateEntered()
{
return $this->dateEntered;
}
/**
* Set dateUpdated
*
* #param \DateTime $dateUpdated
* #return Organisation
*/
public function setDateUpdated($dateUpdated)
{
$this->dateUpdated = $dateUpdated;
return $this;
}
/**
* Get dateUpdated
*
* #return \DateTime
*/
public function getDateUpdated()
{
return $this->dateUpdated;
}
/**
* Set country
*
* #param \AppBundle\Entity\Country $country
* #return Organisation
*/
public function setCountry(\AppBundle\Entity\Country $country = null)
{
$this->country = $country;
return $this;
}
/**
* Get country
*
* #return \AppBundle\Entity\Country
*/
public function getCountry()
{
return $this->country;
}
/**
* Set countrySubdivision
*
* #param \AppBundle\Entity\CountrySubdivision $countrySubdivision
* #return Organisation
*/
public function setCountrySubdivision(\AppBundle\Entity\CountrySubdivision $countrySubdivision = null)
{
$this->countrySubdivision = $countrySubdivision;
return $this;
}
/**
* Get countrySubdivision
*
* #return \AppBundle\Entity\CountrySubdivision
*/
public function getCountrySubdivision()
{
return $this->countrySubdivision;
}
/**
* Set title
*
* #param \AppBundle\Entity\Title $title
* #return Organisation
*/
public function setTitle(\AppBundle\Entity\Title $title = null)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return \AppBundle\Entity\Title
*/
public function getTitle()
{
return $this->title;
}
/**
* Set enteredByUser
*
* #param \AppBundle\Entity\User $enteredByUser
* #return Organisation
*/
public function setEnteredByUser(\AppBundle\Entity\User $enteredByUser = null)
{
$this->enteredByUser = $enteredByUser;
return $this;
}
/**
* Get enteredByUser
*
* #return \AppBundle\Entity\User
*/
public function getEnteredByUser()
{
return $this->enteredByUser;
}
/**
* Set updatedByUser
*
* #param \AppBundle\Entity\User $updatedByUser
* #return Organisation
*/
public function setUpdatedByUser(\AppBundle\Entity\User $updatedByUser = null)
{
$this->updatedByUser = $updatedByUser;
return $this;
}
/**
* Get updatedByUser
*
* #return \AppBundle\Entity\User
*/
public function getUpdatedByUser()
{
return $this->updatedByUser;
}
}
Country Entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Criteria;
/**
* Country
*
* #ORM\Table(name="country", uniqueConstraints={#ORM\UniqueConstraint(name="unique", columns={"code"})})
* #ORM\Entity(repositoryClass="AppBundle\Entity\CountryRepository")
*/
class Country
{
/**
* #var string
*
* #ORM\Column(name="code", type="string", length=2, nullable=false)
*/
private $code;
/**
* #var string
*
* #ORM\Column(name="code_iso_3", type="string", length=3, nullable=true)
*/
private $codeIso3;
/**
* #var string
*
* #ORM\Column(name="code_iso_numeric", type="string", length=4, nullable=true)
*/
private $codeIsoNumeric;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=45, nullable=false)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="capital", type="string", length=30, nullable=true)
*/
private $capital;
/**
* #var string
*
* #ORM\Column(name="continent_name", type="string", length=15, nullable=true)
*/
private $continentName;
/**
* #var string
*
* #ORM\Column(name="continent_code", type="string", length=2, nullable=true)
*/
private $continentCode;
/**
* #var boolean
*
* #ORM\Column(name="hidden", type="boolean", nullable=false)
*/
private $hidden;
/**
* #var \DateTime
*
* #ORM\Column(name="date_entered", type="datetime", nullable=false)
*/
private $dateEntered;
/**
* #var \DateTime
*
* #ORM\Column(name="date_updated", type="datetime", nullable=false)
*/
private $dateUpdated;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var Doctrine\Common\Collections\ArrayCollection
*
* #ORM\OneToMany(targetEntity="CountrySubdivision", mappedBy="country")
*/
private $subdivisions;
/*
* #var AppBundle\Entity\CountrySubdivision
* Stored purely for the purposes of form capture
*/
private $subdivision;
/**
* #var Doctrine\Common\Collections\ArrayCollection
*
* #ORM\OneToMany(targetEntity="CountrySubdivisionType", mappedBy="country")
*/
private $subdivisionTypes;
public function __construct()
{
$this->subdivisions = new ArrayCollection();
$this->subdivisionTypes = new ArrayCollection();
}
public function getSubdivisions()
{
return $this->subdivisions->toArray();
}
public function getSubdivisionsOfParentId($parentId)
{
$criteria = Criteria::create()
->where(Criteria::expr()->eq("parentId", $parentId))
->orderBy(array("name" => Criteria::ASC));
return $this->subdivisions->matching($criteria)->toArray();
}
public function setSubdivisions($subdivisions)
{
}
public function getSubdivision()
{
return $this->subdivision;
}
public function setSubdivision($subdivision)
{
$this->subdivision = $subdivision;
}
public function setId($id)
{
$this->id = $id;
}
public function getSubdivisionTypeOfParentId($parentId)
{
$criteria = Criteria::create()
->where(Criteria::expr()->eq("subdivisionId", $parentId))
->orderBy(array("name" => Criteria::ASC));
return $this->subdivisionTypes->matching($criteria)[0];
}
/**
* Set code
*
* #param string $code
* #return Country
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* Get code
*
* #return string
*/
public function getCode()
{
return $this->code;
}
/**
* Set codeIso3
*
* #param string $codeIso3
* #return Country
*/
public function setCodeIso3($codeIso3)
{
$this->codeIso3 = $codeIso3;
return $this;
}
/**
* Get codeIso3
*
* #return string
*/
public function getCodeIso3()
{
return $this->codeIso3;
}
/**
* Set codeIsoNumeric
*
* #param string $codeIsoNumeric
* #return Country
*/
public function setCodeIsoNumeric($codeIsoNumeric)
{
$this->codeIsoNumeric = $codeIsoNumeric;
return $this;
}
/**
* Get codeIsoNumeric
*
* #return string
*/
public function getCodeIsoNumeric()
{
return $this->codeIsoNumeric;
}
/**
* Set name
*
* #param string $name
* #return Country
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set capital
*
* #param string $capital
* #return Country
*/
public function setCapital($capital)
{
$this->capital = $capital;
return $this;
}
/**
* Get capital
*
* #return string
*/
public function getCapital()
{
return $this->capital;
}
/**
* Set continentName
*
* #param string $continentName
* #return Country
*/
public function setContinentName($continentName)
{
$this->continentName = $continentName;
return $this;
}
/**
* Get continentName
*
* #return string
*/
public function getContinentName()
{
return $this->continentName;
}
/**
* Set continentCode
*
* #param string $continentCode
* #return Country
*/
public function setContinentCode($continentCode)
{
$this->continentCode = $continentCode;
return $this;
}
/**
* Get continentCode
*
* #return string
*/
public function getContinentCode()
{
return $this->continentCode;
}
/**
* Set hidden
*
* #param boolean $hidden
* #return Country
*/
public function setHidden($hidden)
{
$this->hidden = $hidden;
return $this;
}
/**
* Get hidden
*
* #return boolean
*/
public function getHidden()
{
return $this->hidden;
}
/**
* Set dateEntered
*
* #param \DateTime $dateEntered
* #return Country
*/
public function setDateEntered($dateEntered)
{
$this->dateEntered = $dateEntered;
return $this;
}
/**
* Get dateEntered
*
* #return \DateTime
*/
public function getDateEntered()
{
return $this->dateEntered;
}
/**
* Set dateUpdated
*
* #param \DateTime $dateUpdated
* #return Country
*/
public function setDateUpdated($dateUpdated)
{
$this->dateUpdated = $dateUpdated;
return $this;
}
/**
* Get dateUpdated
*
* #return \DateTime
*/
public function getDateUpdated()
{
return $this->dateUpdated;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
If I replace, in the CountryType form...
->add('id', EntityType::class, ...
With...
->add('name')
...then I see the country name displayed without any issue. Where am I going wrong with the EntityType?
I think you're not using custom FormType correctly. You're not supposed to add anything to the builder in a custom FormType. Try this :
<?php
namespace AppBundle\Form\Type\Meta;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;
class OrganisationType extends AbstractType
{
public function __construct()
{
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', new TitleType(),
array('required' => true, 'label' => false))
->add('country', new CountryType(), array(
'label' => 'Country',
'choice_label' => 'name',
'placeholder' => 'Choose an option...',
'query_builder' => function (EntityRepository $repository) {
return $repository->createQueryBuilder('c')->orderBy('c.name', 'ASC');
}
))
->add('location', 'text',
array('required' => false, 'label' => 'City'));
}
public function getName()
{
return 'organisation';
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Organisation',
'csrf_protection' => true,
'csrf_field_name' => '_token',
// a unique key to help generate the secret token
'intention' => 'organisation',
'cascade_validation' => true
));
}
}
with
<?php
namespace AppBundle\Form\Type\Meta;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;
class CountryType extends AbstractType
{
public function getName()
{
return 'country';
}
public function getParent()
{
return EntityType::class;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Country'
));
}
}

Multiple file upload with VlabsMediaBundle in Symfony2

i'm trying to make a multiple upload file on an entity with the vlabsmediaBundle.
So i have an advert who can have many images but each can be linked with only one advert.
I followed the tutorial(tuto) of the bundle but get an error.
Here:
Entity Image.php
namespace MDB\PlatformBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Vlabs\MediaBundle\Entity\BaseFile as VlabsFile;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Image
*
* #ORM\Table()
* #ORM\Entity
*/
class Image extends VlabsFile {
/**
* #var string
*
* #ORM\Column(name="url", type="string", length=255)
*/
private $url;
/**
* #var string
*
* #ORM\Column(name="alt", type="string", length=255)
*/
private $alt;
/**
* #ORM\ManyToOne(targetEntity="MDB\AnnonceBundle\Entity\Annonce", inversedBy="images")
* #ORM\JoinColumn(nullable=true)
*/
private $annonce;
/**
* Get id
*
* #return integer
*/
public function getId() {
return $this->id;
}
/**
* Set url
*
* #param string $url
* #return Image
*/
public function setUrl($url) {
$this->url = $url;
return $this;
}
/**
* Get url
*
* #return string
*/
public function getUrl() {
return $this->url;
}
/**
* Set alt
*
* #param string $alt
* #return Image
*/
public function setAlt($alt) {
$this->alt = $alt;
return $this;
}
/**
* Get alt
*
* #return string
*/
public function getAlt() {
return $this->alt;
}
public function getAnnonce() {
return $this->annonce;
}
public function setAnnonce($annonce) {
$this->annonce = $annonce;
}
/**
* #var string $path
*
* #ORM\Column(name="path", type="string", length=255)
* #Assert\Image()
*/
private $path;
/**
* Set path
*
* #param string $path
* #return Image
*/
public function setPath($path) {
$this->path = $path;
return $this;
}
/**
/**
* Get path
*
* #return string
*/
public function getPath() {
return $this->path;
}
}
Annonce.php (advert enity)
<?php
namespace MDB\AnnonceBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Vlabs\MediaBundle\Annotation\Vlabs;
/**
* Annonce
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="MDB\AnnonceBundle\Entity\AnnonceRepository")
*/
class Annonce {
public function __construct() {
$this->date = new \Datetime();
$this->categories = new ArrayCollection();
$this->images = new ArrayCollection();
}
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="titre", type="string", length=255)
*/
private $titre;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=255)
*/
private $description;
/**
* #ORM\Column(name="date", type="date")
*/
private $date;
/**
* #var float
*
* #ORM\Column(name="prix", type="float")
*/
private $prix;
/**
* #ORM\ManyToOne(targetEntity="MDB\AdresseBundle\Entity\Ville", inversedBy="annonces")
*/
private $ville;
/**
* #ORM\ManyToMany(targetEntity="MDB\AnnonceBundle\Entity\Category", cascade={"persist"})
*/
private $categories;
/**
* #ORM\ManyToMany(targetEntity="MDB\UserBundle\Entity\User")
*
*/
private $wishlist;
/**
* #var boolean
*
* #ORM\Column(name="telAppear", type="boolean")
*/
private $telAppear;
/**
* #ORM\ManyToOne(targetEntity="MDB\UserBundle\Entity\User", inversedBy="annonces")
* #ORM\JoinColumn(nullable=false)
*/
private $user;
/**
* #var VlabsFile
* #ORM\OneToMany(targetEntity="MDB\PlatformBundle\Entity\Image", mappedBy="annonce")
* #Vlabs\Media(identifier="image_entity", upload_dir="files/images")
* #Assert\Valid()
*/
private $images;
/**
* Get id
*
* #return integer
*/
public function getId() {
return $this->id;
}
/**
* Set titre
*
* #param string $titre
* #return Annonce
*/
public function setTitre($titre) {
$this->titre = $titre;
return $this;
}
/**
* Get titre
*
* #return string
*/
public function getTitre() {
return $this->titre;
}
/**
* Set description
*
* #param string $description
* #return Annonce
*/
public function setDescription($description) {
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription() {
return $this->description;
}
/**
* Set prix
*
* #param float $prix
* #return Annonce
*/
public function setPrix($prix) {
$this->prix = $prix;
return $this;
}
/**
* Get prix
*
* #return float
*/
public function getPrix() {
return $this->prix;
}
public function addCategory(Category $category) {
// Ici, on utilise l'ArrayCollection vraiment comme un tableau
$this->categories[] = $category;
return $this;
}
public function removeCategory(Category $category) {
$this->categories->removeElement($category);
}
public function getCategories() {
return $this->categories;
}
public function getDate() {
return $this->date;
}
public function setDate($date) {
$this->date = $date;
}
public function getWishlist() {
return $this->wishlist;
}
public function setWishlist($wishlist) {
$this->wishlist = $wishlist;
}
public function getVille() {
return $this->ville;
}
public function setVille($ville) {
$this->ville = $ville;
}
public function getTelAppear() {
return $this->telAppear;
}
public function setTelAppear($telAppear) {
$this->telAppear = $telAppear;
}
public function getUser() {
return $this->user;
}
public function setUser($user) {
$this->user = $user;
}
public function addImage(Image $image) {
$this->images[] = $image;
$image->setUser($this);
return $this;
}
public function removeImage(Image $image) {
$this->images->removeElement($image);
}
public function getImages() {
return $this->images;
}
}
config.yml
vlabs_media:
image_cache:
cache_dir: files/c
mapping:
image_entity:
class: MDB\PlatformBundle\Entity\Image
AnnonceSellType.php
<?php
namespace MDB\AnnonceBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use MDB\PlatformBundle\Form\ImageType;
class AnnonceSellType extends AbstractType {
private $arrayListCat;
public function __construct( $arrayListCat)
{
$this->arrayListCat = $arrayListCat;
}
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->remove('wishlist')
->remove('date')
->remove('images')
->add('titre')
->add('description', 'textarea')
->add('prix')
->add('categories', 'choice', array(
'choices' => $this->arrayListCat,
'multiple' => true,
'mapped'=>false,
))
//->add('images', 'collection', array('type' => new ImageType()))
->add('image', 'vlabs_file', array(
'required' => false
))
;
}
/**
* #return string
*/
public function getName() {
return 'mdb_annoncebundle_annonce_sell';
}
public function getParent() {
return new AnnonceType();
}
}
And i have the following error : Catchable Fatal Error: Argument 1 passed to Vlabs\MediaBundle\EventListener\BaseFileListener::preSetData() must be an instance of Symfony\Component\Form\Event\DataEvent, instance of Symfony\Component\Form\FormEvent given in C:\wamp\www\Mdb\vendor\vlabs\media-bundle\Vlabs\MediaBundle\EventListener\BaseFileListener.php line 59
i tried to change this line :
->add('image', 'vlabs_file', array(
'required' => false
))
with :
->add('images', 'collection', array('type' => 'vlabs_file'))
but i just have the image label who appear in this case
if someone have an idea ?
I was a little bit investigating about your problem and Vlabs Media Bundle seems to be unmaintained. There is form listener on PRE_SET_DATA event (Vlabs\MediaBundle\EventListener\BaseFileListener::preSetData()) that is not compatible with new version of Symfony (it expects DataEvent as parametr instead FormEvent). They fixed it but after 1.1.1 release (you can compare dates from links). If really wanna give a try, change composer.json and run composer update. I can't guarantee there will not be another possible issues.
composer.json
"vlabs/media-bundle": "dev-master"
Library update
composer update vlabs/media-bundle

Symfony2: One To Many Relationship

Experiencing some serious problems in getting a OneToMany relationship to work. The error happens when trying to add "Children" to Beauties in Sonata Admin.
Using:
Symfony2
Doctrine
Sonata Admin
Been trying to follow the guide at: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#one-to-many-bidirectional
and
http://sonata-project.org/bundles/doctrine-orm-admin/2-2/doc/reference/form_field_definition.html
Error:
"CRITICAL - Uncaught PHP Exception
Doctrine\ORM\ORMInvalidArgumentException: "A new entity was found
through the relationship
'Beautify\BeautiesBundle\Entity\Beauty#children' that was not
configured to cascade persist operations for entity:
Beautify\BeautiesBundle\Entity\Children#000000000eff91d5000000017f8ca53b.
To solve this issue: Either explicitly call EntityManager#persist() on
this unknown entity or configure cascade persist this association in
the mapping for example #ManyToOne(..,cascade={"persist"}). If you
cannot find out which entity causes the problem implement
'Beautify\BeautiesBundle\Entity\Children#__toString()' to get a clue."
at
/Users/gmf/symfony/vendor/doctrine/orm/lib/Doctrine/ORM/ORMInvalidArgumentException.php
line 91 "
.
.
BeautyAdmin.php
<?php
// src/Beautify/BeautiesBundle/Admin/BeautyAdmin.php
namespace Beautify\BeautiesBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Knp\Menu\ItemInterface as MenuItemInterface;
use Beautify\CategoryBundle\Entity\Category;
use Beautify\CategoryBundle\Entity\Children;
class BeautyAdmin extends Admin
{
// Fields to be shown on create/edit forms
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->with('General')
->add('name', 'text', array('label' => 'Name'))
->add('content', 'textarea', array('label' => 'Content'))
->add('imageFile', 'file', array('label' => 'Image file', 'required' => false))
->end()
->with('Category')
->add('category', 'sonata_type_model', array('expanded' => true))
->end()
->with('Children')
->add('children', 'sonata_type_collection', array(), array(
'edit' => 'inline',
'inline' => 'table',
'sortable' => 'position'
))
->end()
;
}
// Fields to be shown on filter forms
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
->add('name')
->add('content')
->add('category')
;
}
// Fields to be shown on lists
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('name')
->add('content')
->add('category')
->add('imageName')
->add('_action', 'actions', array(
'actions' => array(
'show' => array(),
'edit' => array(),
'delete' => array(),
)
))
;
}
}
Beauty.php Entity
<?php
// src/Beautify/BeautiesBundle/Entity/Beauty.php
namespace Beautify\BeautiesBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="beauties")
* #ORM\HasLifecycleCallbacks
* #Vich\Uploadable
*/
class Beauty
{
/**
* #ORM\OneToMany(targetEntity="Children", mappedBy="beauties")
**/
private $children;
public function __construct()
{
$this->children = new ArrayCollection();
}
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=100)
*/
protected $name;
/**
* #ORM\Column(type="text")
*/
protected $content;
/**
* #Vich\UploadableField(mapping="beauty_image", fileNameProperty="imageName")
* #var File $imageFile
*/
protected $imageFile;
/**
* #ORM\Column(type="string", length=255, nullable=true, name="image_name")
* #var string $imageName
*/
protected $imageName;
/**
* #ORM\ManyToOne(targetEntity="Category", inversedBy="beauties")
* #ORM\JoinColumn(name="category_id", referencedColumnName="id")
*/
protected $category;
/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
* of 'UploadedFile' is injected into this setter to trigger the update. If this
* bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
* must be able to accept an instance of 'File' as the bundle will inject one here
* during Doctrine hydration.
*
* #param File|\Symfony\Component\HttpFoundation\File\UploadedFile
*/
public function setImageFile(File $image = null)
{
$this->imageFile = $image;
if ($image) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->updatedAt = new \DateTime('now');
}
}
/**
* #return File
*/
public function getImageFile()
{
return $this->imageFile;
}
/**
* #param string $imageName
*/
public function setImageName($imageName)
{
$this->imageName = $imageName;
}
/**
* #return string
*/
public function getImageName()
{
return $this->imageName;
}
public function __toString()
{
return ($this->getName()) ? : '';
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Beauty
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set content
*
* #param string $content
* #return Beauty
*/
public function setContent($content)
{
$this->content = $content;
return $this;
}
/**
* Get content
*
* #return string
*/
public function getContent()
{
return $this->content;
}
/**
* Set category
*
* #param \Beautify\BeautiesBundle\Entity\Category $category
* #return Beauty
*/
public function setCategory(\Beautify\BeautiesBundle\Entity\Category $category = null)
{
$this->category = $category;
return $this;
}
/**
* Get category
*
* #return \Beautify\BeautiesBundle\Entity\Category
*/
public function getCategory()
{
return $this->category;
}
/**
* Set children
*
* #param \Beautify\BeautiesBundle\Entity\Children $children
* #return Beauty
*/
public function setChildren(\Beautify\BeautiesBundle\Entity\Children $children = null)
{
$this->children = $children;
return $this;
}
/**
* Get children
*
* #return \Beautify\BeautiesBundle\Entity\Children
*/
public function getChildren()
{
return $this->children;
}
/**
* Add children
*
* #param \Beautify\BeautiesBundle\Entity\Children $children
* #return Beauty
*/
public function addChild(\Beautify\BeautiesBundle\Entity\Children $children)
{
$this->children[] = $children;
return $this;
}
/**
* Remove children
*
* #param \Beautify\BeautiesBundle\Entity\Children $children
*/
public function removeChild(\Beautify\BeautiesBundle\Entity\Children $children)
{
$this->children->removeElement($children);
}
}
Children.php Entity
<?php
namespace Beautify\BeautiesBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Children
*
* #ORM\Table(name="children")
* #ORM\Entity
*/
class Children
{
/**
* #ORM\ManyToOne(targetEntity="Beauty", inversedBy="children")
* #ORM\JoinColumn(name="beauty_id", referencedColumnName="id")
**/
private $beauties;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="image", type="string", length=255)
*/
private $image;
/**
* #var string
*
* #ORM\Column(name="content", type="text")
*/
private $content;
/**
* #var integer
*
* #ORM\Column(name="priority", type="integer")
*/
private $priority;
/**
* #var integer
*
* #ORM\Column(name="parent_id", type="integer")
*/
private $parentId;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set image
*
* #param string $image
* #return Children
*/
public function setImage($image)
{
$this->image = $image;
return $this;
}
/**
* Get image
*
* #return string
*/
public function getImage()
{
return $this->image;
}
/**
* Set content
*
* #param string $content
* #return Children
*/
public function setContent($content)
{
$this->content = $content;
return $this;
}
/**
* Get content
*
* #return string
*/
public function getContent()
{
return $this->content;
}
/**
* Set priority
*
* #param integer $priority
* #return Children
*/
public function setPriority($priority)
{
$this->priority = $priority;
return $this;
}
/**
* Get priority
*
* #return integer
*/
public function getPriority()
{
return $this->priority;
}
/**
* Set parentId
*
* #param integer $parentId
* #return Children
*/
public function setParentId($parentId)
{
$this->parentId = $parentId;
return $this;
}
/**
* Get parentId
*
* #return integer
*/
public function getParentId()
{
return $this->parentId;
}
/**
* Set beauties
*
* #param \Beautify\BeautiesBundle\Entity\Beauty $beauties
* #return Children
*/
public function setBeauties(\Beautify\BeautiesBundle\Entity\Beauty $beauties = null)
{
$this->beauties = $beauties;
return $this;
}
/**
* Get beauties
*
* #return \Beautify\BeautiesBundle\Entity\Beauty
*/
public function getBeauties()
{
return $this->beauties;
}
}
Very thankful for any help...
The error says it all. You need to add cascade="persist" to the children property.
/**
* #ORM\OneToMany(targetEntity="Children", mappedBy="beauties", cascade={"persist"})
**/
private $children;
See http://doctrine-orm.readthedocs.org/en/latest/reference/working-with-associations.html#transitive-persistence-cascade-operations

Categories