symfony2 : unable to save parent id in embedded object - doctrine-orm

I'm trying tu use my first embedded form (SF2.1 + Doctrine2)
the entities :
<?php
namespace Chris\BabelBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
*/
class Needs
{
/**
* #ORM\GeneratedValue
* #ORM\Id
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Projects")
* #Assert\NotBlank()
*/
private $relatedproject;
/**
* #ORM\ManyToOne(targetEntity="Activities")
* #Assert\NotBlank()
*/
private $relatedactivity;
/**
* #ORM\ManyToOne(targetEntity="Jobs")
* #Assert\NotBlank()
*/
private $relatedjob;
/**
* #ORM\Column(type="string", length=255)
* #Assert\NotBlank()
*/
private $firstname;
/**
* #ORM\Column(type="string", length=255)
* #Assert\NotBlank()
*/
private $lastname;
/**
* #ORM\ManyToOne(targetEntity="Experiences")
* #Assert\NotBlank()
*/
private $relatedexperience;
/**
* #ORM\ManyToOne(targetEntity="Plants")
* #Assert\NotBlank()
*/
private $maintrainingplant;
/**
* #ORM\Column(type="date")
* #Assert\NotBlank()
*/
private $trainingneedstart;
/**
* #ORM\Column(type="date")
* #Assert\NotBlank()
*/
private $readytowork;
/**
* #var ArrayCollection $trainings
*
* #ORM\OneToMany(targetEntity="Trainings", mappedBy="training", cascade={"persist", "remove", "merge"})
*/
private $trainings;
/**
* Constructor
*/
public function __construct()
{
$this->trainings = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set firstname
*
* #param string $firstname
* #return Needs
*/
public function setFirstname($firstname)
{
$this->firstname = $firstname;
return $this;
}
/**
* Get firstname
*
* #return string
*/
public function getFirstname()
{
return $this->firstname;
}
/**
* Set lastname
*
* #param string $lastname
* #return Needs
*/
public function setLastname($lastname)
{
$this->lastname = $lastname;
return $this;
}
/**
* Get lastname
*
* #return string
*/
public function getLastname()
{
return $this->lastname;
}
/**
* Set trainingneedstart
*
* #param \DateTime $trainingneedstart
* #return Needs
*/
public function setTrainingneedstart($trainingneedstart)
{
$this->trainingneedstart = $trainingneedstart;
return $this;
}
/**
* Get trainingneedstart
*
* #return \DateTime
*/
public function getTrainingneedstart()
{
return $this->trainingneedstart;
}
/**
* Set readytowork
*
* #param \DateTime $readytowork
* #return Needs
*/
public function setReadytowork($readytowork)
{
$this->readytowork = $readytowork;
return $this;
}
/**
* Get readytowork
*
* #return \DateTime
*/
public function getReadytowork()
{
return $this->readytowork;
}
/**
* Set relatedproject
*
* #param \Chris\BabelBundle\Entity\Projects $relatedproject
* #return Needs
*/
public function setRelatedproject(\Chris\BabelBundle\Entity\Projects $relatedproject = null)
{
$this->relatedproject = $relatedproject;
return $this;
}
/**
* Get relatedproject
*
* #return \Chris\BabelBundle\Entity\Projects
*/
public function getRelatedproject()
{
return $this->relatedproject;
}
/**
* Set relatedactivity
*
* #param \Chris\BabelBundle\Entity\Activities $relatedactivity
* #return Needs
*/
public function setRelatedactivity(\Chris\BabelBundle\Entity\Activities $relatedactivity = null)
{
$this->relatedactivity = $relatedactivity;
return $this;
}
/**
* Get relatedactivity
*
* #return \Chris\BabelBundle\Entity\Activities
*/
public function getRelatedactivity()
{
return $this->relatedactivity;
}
/**
* Set relatedjob
*
* #param \Chris\BabelBundle\Entity\Jobs $relatedjob
* #return Needs
*/
public function setRelatedjob(\Chris\BabelBundle\Entity\Jobs $relatedjob = null)
{
$this->relatedjob = $relatedjob;
return $this;
}
/**
* Get relatedjob
*
* #return \Chris\BabelBundle\Entity\Jobs
*/
public function getRelatedjob()
{
return $this->relatedjob;
}
/**
* Set relatedexperience
*
* #param \Chris\BabelBundle\Entity\Experiences $relatedexperience
* #return Needs
*/
public function setRelatedexperience(\Chris\BabelBundle\Entity\Experiences $relatedexperience = null)
{
$this->relatedexperience = $relatedexperience;
return $this;
}
/**
* Get relatedexperience
*
* #return \Chris\BabelBundle\Entity\Experiences
*/
public function getRelatedexperience()
{
return $this->relatedexperience;
}
/**
* Set maintrainingplant
*
* #param \Chris\BabelBundle\Entity\Plants $maintrainingplant
* #return Needs
*/
public function setMaintrainingplant(\Chris\BabelBundle\Entity\Plants $maintrainingplant = null)
{
$this->maintrainingplant = $maintrainingplant;
return $this;
}
/**
* Get maintrainingplant
*
* #return \Chris\BabelBundle\Entity\Plants
*/
public function getMaintrainingplant()
{
return $this->maintrainingplant;
}
/**
* Add trainings
*
* #param \Chris\BabelBundle\Entity\Trainings $trainings
* #return Needs
*/
public function addTraining(\Chris\BabelBundle\Entity\Trainings $trainings)
{
$this->trainings[] = $trainings;
return $this;
}
/**
* Remove trainings
*
* #param \Chris\BabelBundle\Entity\Trainings $trainings
*/
public function removeTraining(\Chris\BabelBundle\Entity\Trainings $trainings)
{
$this->trainings->removeElement($trainings);
}
/**
* Get trainings
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getTrainings()
{
return $this->trainings;
}
public function __toString() {return $this->getFirstname();}
}
<?php
namespace Chris\BabelBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
*/
class Trainings
{
/**
* #ORM\GeneratedValue
* #ORM\Id
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Plants")
* #Assert\NotBlank()
*/
private $trainingplant;
/**
* #ORM\Column(type="date")
* #Assert\NotBlank()
*/
private $trainingstart;
/**
* #ORM\Column(type="date")
* #Assert\NotBlank()
*/
private $trainingend;
/**
* #var Needs $trainings
*
* #ORM\ManyToOne(targetEntity="Needs", inversedBy="trainings", cascade={"persist", "remove", "merge"})
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="Needs_id", referencedColumnName="id")
* })
*/
private $training;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set trainingstart
*
* #param \DateTime $trainingstart
* #return Trainings
*/
public function setTrainingstart($trainingstart)
{
$this->trainingstart = $trainingstart;
return $this;
}
/**
* Get trainingstart
*
* #return \DateTime
*/
public function getTrainingstart()
{
return $this->trainingstart;
}
/**
* Set trainingend
*
* #param \DateTime $trainingend
* #return Trainings
*/
public function setTrainingend($trainingend)
{
$this->trainingend = $trainingend;
return $this;
}
/**
* Get trainingend
*
* #return \DateTime
*/
public function getTrainingend()
{
return $this->trainingend;
}
/**
* Set trainingplant
*
* #param \Chris\BabelBundle\Entity\Plants $trainingplant
* #return Trainings
*/
public function setTrainingplant(\Chris\BabelBundle\Entity\Plants $trainingplant = null)
{
$this->trainingplant = $trainingplant;
return $this;
}
/**
* Get trainingplant
*
* #return \Chris\BabelBundle\Entity\Plants
*/
public function getTrainingplant()
{
return $this->trainingplant;
}
/**
* Set training
*
* #param \Chris\BabelBundle\Entity\Needs $training
* #return Trainings
*/
public function setTraining(\Chris\BabelBundle\Entity\Needs $training = null)
{
$this->training = $training;
return $this;
}
/**
* Get training
*
* #return \Chris\BabelBundle\Entity\Needs
*/
public function getTraining()
{
return $this->training;
}
}
The 2 Controllers :
<?php
namespace Chris\BabelBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Chris\BabelBundle\Entity\Needs;
use Chris\BabelBundle\Form\NeedsType;
/**
* Needs controller.
*
*/
class NeedsController extends Controller
{
/**
* Lists all Needs entities.
*
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('ChrisBabelBundle:Needs')->findAll();
return $this->render('ChrisBabelBundle:Needs:index.html.twig', array(
'entities' => $entities,
));
}
/**
* Finds and displays a Needs entity.
*
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ChrisBabelBundle:Needs')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Needs entity.');
}
return $this->render('ChrisBabelBundle:Needs:show.html.twig', array(
'entity' => $entity, ));
}
/**
* Displays a form to create a new Needs entity.
*
*/
public function newAction()
{
$entity = new Needs();
$form = $this->createForm(new NeedsType(), $entity);
return $this->render('ChrisBabelBundle:Needs:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
/**
* Creates a new Needs entity.
*
*/
public function createAction(Request $request)
{
$entity = new Needs();
$form = $this->createForm(new NeedsType(), $entity);
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('needs_show', array('id' => $entity->getId())));
}
return $this->render('ChrisBabelBundle:Needs:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
/**
* Displays a form to edit an existing Needs entity.
*
*/
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ChrisBabelBundle:Needs')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Needs entity.');
}
$editForm = $this->createForm(new NeedsType(), $entity);
return $this->render('ChrisBabelBundle:Needs:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
));
}
/**
* Edits an existing Needs entity.
*
*/
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ChrisBabelBundle:Needs')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Needs entity.');
}
$editForm = $this->createForm(new NeedsType(), $entity);
$editForm->bind($request);
if ($editForm->isValid()) {
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('needs_edit', array('id' => $id)));
}
return $this->render('ChrisBabelBundle:Needs:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
));
}
/**
* Deletes a Needs entity.
*
*/
public function deleteAction($id)
{
$em = $this->container->get('doctrine')->getEntityManager();
$metier = $em->find('ChrisBabelBundle:Needs', $id);
if (!$metier)
{
throw new NotFoundHttpException("Need not found");
}
$em->remove($metier); $em->flush();
return $this->redirect($this->generateUrl('needs'));
}
}
<?php
namespace Chris\BabelBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Chris\BabelBundle\Entity\Trainings;
use Chris\BabelBundle\Form\TrainingsType;
/**
* Trainings controller.
*
*/
class TrainingsController extends Controller
{
/**
* Lists all Trainings entities.
*
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('ChrisBabelBundle:Trainings')->findAll();
return $this->render('ChrisBabelBundle:Trainings:index.html.twig', array(
'entities' => $entities,
));
}
/**
* Finds and displays a Trainings entity.
*
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ChrisBabelBundle:Trainings')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Trainings entity.');
}
$deleteForm = $this->createDeleteForm($id);
return $this->render('ChrisBabelBundle:Trainings:show.html.twig', array(
'entity' => $entity,
'delete_form' => $deleteForm->createView(), ));
}
/**
* Displays a form to create a new Trainings entity.
*
*/
public function newAction()
{
$entity = new Trainings();
$form = $this->createForm(new TrainingsType(), $entity);
return $this->render('ChrisBabelBundle:Trainings:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
/**
* Creates a new Trainings entity.
*
*/
public function createAction(Request $request)
{
$entity = new Trainings();
$form = $this->createForm(new TrainingsType(), $entity);
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('trainings_show', array('id' => $entity->getId())));
}
return $this->render('ChrisBabelBundle:Trainings:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
/**
* Displays a form to edit an existing Trainings entity.
*
*/
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ChrisBabelBundle:Trainings')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Trainings entity.');
}
$editForm = $this->createForm(new TrainingsType(), $entity);
$deleteForm = $this->createDeleteForm($id);
return $this->render('ChrisBabelBundle:Trainings:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Edits an existing Trainings entity.
*
*/
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ChrisBabelBundle:Trainings')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Trainings entity.');
}
$deleteForm = $this->createDeleteForm($id);
$editForm = $this->createForm(new TrainingsType(), $entity);
$editForm->bind($request);
if ($editForm->isValid()) {
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('trainings_edit', array('id' => $id)));
}
return $this->render('ChrisBabelBundle:Trainings:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Deletes a Trainings entity.
*
*/
public function deleteAction(Request $request, $id)
{
$form = $this->createDeleteForm($id);
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ChrisBabelBundle:Trainings')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Trainings entity.');
}
$em->remove($entity);
$em->flush();
}
return $this->redirect($this->generateUrl('trainings'));
}
private function createDeleteForm($id)
{
return $this->createFormBuilder(array('id' => $id))
->add('id', 'hidden')
->getForm()
;
}
}
and finally the forms :
<?php
namespace Chris\BabelBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class NeedsType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('firstname')
->add('lastname')
->add('trainingneedstart')
->add('readytowork')
->add('relatedproject')
->add('relatedactivity')
->add('relatedjob')
->add('relatedexperience')
->add('maintrainingplant')
// Ajout du formulaire imbriqué des trainings en collection
->add('trainings', 'collection', array('type' => new TrainingsType(),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
))
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Chris\BabelBundle\Entity\Needs'
));
}
public function getName()
{
return 'chris_babelbundle_needstype';
}
}
<?php
namespace Chris\BabelBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class TrainingsType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('trainingstart')
->add('trainingend')
->add('trainingplant')
->add('training')
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Chris\BabelBundle\Entity\Trainings'
));
}
public function getName()
{
return 'chris_babelbundle_trainingstype';
}
}
most of this is working except that the trainings saved do not contain the needs ID in the DB so, when editing a need I cant retrieve the several trainings.

Finally I found the solution with the help of French IRC :)
I only had to modify the Needs entity like this :
/**
* Add trainings
*
* #param \Chris\BabelBundle\Entity\Trainings $trainings
* #return Needs
*/
public function addTraining(\Chris\BabelBundle\Entity\Trainings $trainings)
{
$this->trainings[] = $trainings;
$trainings->setTraining($this);
return $this;
}

Related

upload not running with VichUploaderBundle

I would like to use a VichUploaderBundle for upload files in my symfony 3.2.3 project (PHP 5.6). I try lot of thing but nothing upload run. But the persistance layer run perfeclty with my database.
config.yml
knp_gaufrette:
stream_wrapper: ~
adapters:
fileupload_adapter:
local:
directory: %kernel.root_dir%/../web/
create: true
filesystems:
fileupload_fs:
adapter: fileupload_adapter
# VichUploaderBundle Configuration
vich_uploader:
db_driver: orm
twig: true
storage: gaufrette
mappings:
tgmedia_file:
uri_prefix: web
upload_destination: fileupload_fs
namer: vich_uploader.namer_origname
Entity
namespace MediaBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use TweedeGolf\MediaBundle\Model\AbstractFile;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* #ORM\Entity
* #Vich\Uploadable
* #ORM\HasLifecycleCallbacks
* #ORM\Table
*/
class FileUpload
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* #Vich\UploadableField(mapping="tgmedia_file", fileNameProperty="imageName")
*
* #var File
*/
protected $imageFile;
/**
* #ORM\Column(type="string", length=255)
*
* #var string
*/
private $imageName;
/**
* #ORM\Column(type="datetime")
*
* #var \DateTime
*/
protected $updatedAt;
/**
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* #return File|null
*/
public function getImageFile()
{
return $this->imageFile;
}
/**
* 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 $image
*
* #return Product
*/
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 \DateTimeImmutable();
}
return $this;
}
/**
* #param string $imageName
*
* #return FileUpload
*/
public function setImageName($imageName)
{
$this->imageName = $imageName;
return $this;
}
/**
* #return string|null
*/
public function getImageName()
{
return $this->imageName;
}
/**
* Set updatedAt
*
* #param \DateTime $updatedAt
*
* #return FileUpload
*/
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* Get updatedAt
*
* #return \DateTime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
}
The formType
<?php
namespace MediaBundle\Form;
use MediaBundle\Entity\File;
use MediaBundle\Entity\FileUpload;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Vich\UploaderBundle\Form\Type\VichFileType;
use Vich\UploaderBundle\Form\Type\VichImageType;
class FileUploadType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('imageName')
->add('imageFile', VichImageType::class, [
'required' => false,
'allow_delete' => true,
'download_link' => true,
'mapped' => false,
'data_class' => null
])
->add('submit', SubmitType::class);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => FileUpload::class,
'csrf_protection' => false,
));
}
}
Controller
<?php
namespace MediaBundle\Controller;
use MediaBundle\Entity\File;
use MediaBundle\Entity\FileUpload;
use MediaBundle\Entity\Product;
use MediaBundle\Form\FileType;
use MediaBundle\Form\FileUploadType;
use MediaBundle\Form\ProductType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class MainController extends Controller
{
public function indexAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$fileUploaded = new FileUpload();
$form = $this->createForm(FileUploadType::class, $fileUploaded, array(
'action' => $this->generateUrl('media_main')
));
$form->handleRequest($request);
if ($form->isSubmitted())
{
$fileUploaded->setUpdatedAt(new \DateTime());
$fileUploaded->setImageFile($form->get('imageFile')->getData());
$em->persist($fileUploaded);
$em->flush();
}
return $this->render('MediaBundle:main:index.html.twig', array(
'form' => $form->createView()
));
}
}
Where is my error ? What wrong ?
uri_prefix: /project/web/fileupload_fs
upload_destination: '%kernel.root_dir%/../web/fileupload_fs'
uri_prefix begins from www folder.
and change controller like that
if ($form->isSubmitted() && $form->isValid())
{
$em->persist($fileUploaded);
$em->flush();
}

Constraints like #Assert\NotBlank() annotation for entities does not work in unit test which gives semantical or auto loaded error

When I run the Unit test it gives the following error for the constraints
[Semantical Error] The annotation "#Symfony\Component\Validator\Constraints\NotBlank" in property AppBundle\Entity\User::$username does not exist, or could not be auto-loaded.
Here is my entity
User.class
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
/**
* Class User
* #package AppBundle\Entity
*
* #ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
* #ORM\Table(name="user")
* #ORM\HasLifecycleCallbacks()
*
*/
class User implements AdvancedUserInterface, \Serializable
{
/** #var double
* #ORM\Column(type="bigint", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
* #ORM\Column(type="string", length=60, unique=true)
* #Assert\NotBlank()
* #Assert\Email()
*/
private $username;
/**
* #ORM\Column(type="string", length=64)
*/
private $password;
/**
* #Assert\NotBlank()
* #Assert\Length(max=4096)
*/
private $plainPassword;
/**
* #var string
* #ORM\Column(name="fullname", type="string", length=100, nullable=false)
* #Assert\NotBlank()
*/
protected $fullname;
/**
* #var \DateTime
* #ORM\Column(name="createdat", type="datetime", nullable=true)
*/
protected $createdat;
/**
* #var \DateTime
* #ORM\Column(name="modifiedat", type="datetime", nullable=true)
*/
protected $modifiedat;
/**
* #ORM\Column(type="boolean", options={"default" = 1}, nullable=false)
*/
private $isactive = true;
public function __construct()
{
$this->updatedTimestamps();
}
/**
* Now we tell doctrine that before we persist or update we call the updatedTimestamps() function.
*
* #ORM\PrePersist
* #ORM\PreUpdate
*/
public function updatedTimestamps()
{
$this->setModifiedat(new \DateTime(date('Y-m-d H:i:s')));
if($this->getCreatedat() == null)
{
$this->setCreatedat(new \DateTime(date('Y-m-d H:i:s')));
}
}
public function getUsername()
{
return $this->username;
}
public function getSalt()
{
// you *may* need a real salt depending on your encoder
// see section on salt below
return '';
}
public function getPassword()
{
return $this->password;
}
public function getRoles()
{
return array('ROLE_USER');
}
public function eraseCredentials()
{
}
public function isAccountNonExpired()
{
return true;
}
public function isAccountNonLocked()
{
return true;
}
public function isCredentialsNonExpired()
{
return true;
}
public function isEnabled()
{
return $this->isactive;
}
/** #see \Serializable::serialize() */
public function serialize()
{
return serialize(array(
$this->id,
$this->username,
$this->password,
$this->isactive
));
}
/** #see \Serializable::unserialize() */
public function unserialize($serialized)
{
list (
$this->id,
$this->username,
$this->password,
$this->isactive
) = unserialize($serialized);
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set username
*
* #param string $username
*
* #return User
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Set password
*
* #param string $password
*
* #return User
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Set isactive
*
* #param boolean $isactive
*
* #return User
*/
public function setIsactive($isactive)
{
$this->isactive = $isactive;
return $this;
}
/**
* Get isactive
*
* #return boolean
*/
public function getIsactive()
{
return $this->isactive;
}
/**
* #return mixed
*/
public function getPlainPassword()
{
return $this->plainPassword;
}
/**
* #param mixed $plainPassword
*/
public function setPlainPassword($plainPassword)
{
$this->plainPassword = $plainPassword;
}
/**
* Set fullname
*
* #param string $fullname
*
* #return User
*/
public function setFullname($fullname)
{
$this->fullname = $fullname;
return $this;
}
/**
* Get fullname
*
* #return string
*/
public function getFullname()
{
return $this->fullname;
}
/**
* Set createdat
*
* #param \DateTime $createdat
*
* #return User
*/
public function setCreatedat($createdat)
{
$this->createdat = $createdat;
return $this;
}
/**
* Get createdat
*
* #return \DateTime
*/
public function getCreatedat()
{
return $this->createdat;
}
/**
* Set modifiedat
*
* #param \DateTime $modifiedat
*
* #return User
*/
public function setModifiedat($modifiedat)
{
$this->modifiedat = $modifiedat;
return $this;
}
/**
* Get modifiedat
*
* #return \DateTime
*/
public function getModifiedat()
{
return $this->modifiedat;
}
/**
* The __toString method allows a class to decide how it will react when it is converted to a string.
*
* #return string
* #link http://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.tostring
*/
function __toString()
{
return "id: ". $this->id ." email: ". $this->username . " fullname: ". $this->fullname . " isactive: ". $this->isactive .
" createdat: ". $this->createdat->format('Y-m-d H:i:s') ." updatedat: ". $this->modifiedat->format('Y-m-d H:i:s');
}
}
This is my Unit Test classes:
TestBase.class
namespace tests\AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\DependencyInjection\Container;
use Doctrine\Common\Annotations\AnnotationRegistry;
use AppKernel;
AnnotationRegistry::registerFile("../../../vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php");
require_once __DIR__ . "/../../../vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php";
class TestBase extends \PHPUnit_Framework_TestCase
{
/**
* #var Application
*/
protected $application;
/**
* #var \Doctrine\ORM\EntityManager
*/
protected $entityManager;
/**
* #var \AppKernel
*/
protected $kernel;
/**
* #var Container
*/
protected $container;
protected function setUp()
{
$this->kernel = new AppKernel("test", true);
$this->kernel->boot();
$this->application = new Application($this->kernel);
$this->application->setAutoExit(false);
// Store the container and the entity manager in test case properties
$this->container = $this->kernel->getContainer();
$this->entityManager = $this->container->get("doctrine")->getManager();
if(is_null($this->entityManager)){
print("upssss entitiy manager is null :(");
}
parent::setUp();
}
public function tearDown()
{
// Shutdown the kernel.
$this->kernel->shutdown();
parent::tearDown();
}
}
And here I test my User class just printing the database..
UserTest.class
namespace tests\AppBundle\Controller;
require_once ("TestBase.php");
class UserTest extends TestBase
{
protected function setUp()
{
parent::setUp();
}
public function tearDown()
{
parent::tearDown();
}
//generic method to list the users
public function listUsers($users ){
echo EOL, EOL;
foreach($users as $user){
echo $user, EOL;
}
echo EOL, EOL;
}
public function testListUsers(){
$users = $this->entityManager->getRepository('AppBundle:User')->findAll();
$this->assertGreaterThan(1, count($users));
$this->listUsers($users);
}
}
By the way it works when I don't use #Assert\NotBlank()
So from code-wise there is no problem at all... I guess it is just about autoloading when unit testing..
I really got stuck for 2 weeks with that..
Ok I found the answer..
When I changed test to dev in AppKernel it worked
old one was this:
$this->kernel = new AppKernel("test", true);
solution
$this->kernel = new AppKernel("dev", true);
I didn't change my AppKernel.php though
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;
define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');
class AppKernel extends Kernel
{
public function registerBundles()
{
$bundles = [
new Liuggio\ExcelBundle\LiuggioExcelBundle(),
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new Symfony\Bundle\SecurityBundle\SecurityBundle(),
new Symfony\Bundle\TwigBundle\TwigBundle(),
new Symfony\Bundle\MonologBundle\MonologBundle(),
new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
new AppBundle\AppBundle(),
];
if (in_array($this->getEnvironment(), ['dev', 'test'], true)) {
$bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle();
$bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
$bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle();
$bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle();
}
return $bundles;
}
public function getRootDir()
{
return __DIR__;
}
public function getCacheDir()
{
return dirname(__DIR__).'/var/cache/'.$this->getEnvironment();
}
public function getLogDir()
{
return dirname(__DIR__).'/var/logs';
}
public function registerContainerConfiguration(LoaderInterface $loader)
{
$loader->load($this->getRootDir().'/config/config_'.$this->getEnvironment().'.yml');
}
}

Doctrine: one to many relationship and cascade persistance

I mean I have these two classes (one to many relationship). As you can appreciate in both I have included cascade={"persist"}.
namespace Project\FrontendBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="task")
*/
class Task
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=255, name="description", nullable=true)
*/
protected $description;
/**
* #ORM\OneToMany(targetEntity="Tag", mappedBy="task", cascade={"persist"})
**/
protected $tags;
/*************************************/
public function __toString()
{
return $this->description;
}
/**
* Constructor
*/
public function __construct()
{
$this->tags = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set description
*
* #param string $description
* #return Task
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Add tags
*
* #param \Project\FrontendBundle\Entity\Tag $tags
* #return Task
*/
public function addTag(\Project\FrontendBundle\Entity\Tag $tags)
{
$this->tags[] = $tags;
return $this;
}
/**
* Remove tags
*
* #param \Project\FrontendBundle\Entity\Tag $tags
*/
public function removeTag(\Project\FrontendBundle\Entity\Tag $tags)
{
$this->tags->removeElement($tags);
}
/**
* Get tags
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getTags()
{
return $this->tags;
}
}
namespace Project\FrontendBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="tag")
*/
class Tag
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=255, name="name", nullable=true)
*/
protected $name;
/**
* #ORM\ManyToOne(targetEntity="Task", inversedBy="tags", cascade={"persist"})
* #ORM\JoinColumn(name="task_id", referencedColumnName="id")
**/
private $task;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Tag
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set task
*
* #param \Project\FrontendBundle\Entity\Task $task
* #return Tag
*/
public function setTask(\Project\FrontendBundle\Entity\Task $task = null)
{
$this->task = $task;
return $this;
}
/**
* Get task
*
* #return \Project\FrontendBundle\Entity\Task
*/
public function getTask()
{
return $this->task;
}
}
In my controller I have this:
$task = new Task();
$tag = new Tag();
$task->addTag($tag);
$em = $this->getDoctrine()->getManager();
$em->persist($item);
$em->flush();
but the foreign key is always NULL, why?
I think in the Task class, the addTag and removeTag should look like this:
public function addTag($tag)
{
$tag->setTask($this);
$this->tags->add($tag);
}
public function removeTag($tag)
{
$tag->setTask(null);
$this->tags->removeElement($tag);
}
Or if you want to add and remove many tags in one function call use these:
public function addTags(Collection $tags)
{
foreach ($tags as $tag) {
$tag->setTask($this);
$this->tags->add($tag);
}
}
public function removeTags(Collection $tags)
{
foreach ($tags as $tag) {
$tag->setTask(null);
$this->tags->removeElement($tag);
}
}

Doctrine 2 one-to-many relationship

I have the following:
User have one group, group can have many users
User
<?php namespace Application\Model;
use Doctrine\Common\Collections;
use Doctrine\ORM\Mapping as ORM;
/**
* User model
* Read-only entity
* #ORM\Table(name="VLOGGER_WEBCALENDAR_USR")
* #ORM\Entity
* #package Application\Model
*/
class User
{
/**
* #var int
* #ORM\Id
* #ORM\Column(name="USR_ID", type="integer")
*/
protected $id;
/**
* #var string
* #ORM\Column(name="USR_LOGIN", type="string")
*/
protected $login;
/**
* #var string
* #ORM\Column(name="USR_CODE", type="string")
*/
protected $code;
/**
* #var int
* #ORM\Column(name="GRP_ID", type="integer")
*/
protected $groupId;
/**
* #var string
* #ORM\Column(name="GRP_CODE", type="string")
*/
protected $groupCode;
/**
* #var User\Group
* #ORM\ManyToOne(targetEntity="Application\Model\User\Group",fetch="EAGER")
* #ORM\JoinColumn(name="GRP_ID", referencedColumnName="GRP_ID")
*/
protected $group;
/**
* #var Event
* #ORM\OneToMany(targetEntity="Application\Model\Event", mappedBy="user")
* #ORM\JoinColumn(name="USR_ID", referencedColumnName="USR_ID")
*/
protected $events;
/**
* Constructor
*/
public function __construct()
{
$this->events = new Collections\ArrayCollection();
}
/**
* #return string
*/
public function getCode()
{
return $this->code;
}
/**
* #param string $code
* #return User
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* #return Event
*/
public function getEvents()
{
return $this->events;
}
/**
* #param Event $events
* #return User
*/
public function setEvents($events)
{
$this->events = $events;
return $this;
}
/**
* #return User\Group
*/
public function getGroup()
{
return $this->group;
}
/**
* #param User\Group $group
* #return User
*/
public function setGroup($group)
{
$this->group = $group;
return $this;
}
/**
* #return string
*/
public function getGroupCode()
{
return $this->groupCode;
}
/**
* #param string $groupCode
* #return User
*/
public function setGroupCode($groupCode)
{
$this->groupCode = $groupCode;
return $this;
}
/**
* #return int
*/
public function getGroupId()
{
return $this->groupId;
}
/**
* #param int $groupId
* #return User
*/
public function setGroupId($groupId)
{
$this->groupId = $groupId;
return $this;
}
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #param mixed $id
* #return User
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* #return string
*/
public function getLogin()
{
return $this->login;
}
/**
* #param string $login
* #return User
*/
public function setLogin($login)
{
$this->login = $login;
return $this;
}
}
Group
<?php namespace Application\Model\User;
use Application\Model;
use Doctrine\Common\Collections;
use Doctrine\ORM\Mapping as ORM;
/**
* User group model
* Read-only entity
* #ORM\Table(name="VLOGGER_WEBCALENDAR_GRP")
* #ORM\Entity
* #package Application\Model
*/
class Group
{
/**
* #var int
* #ORM\Id
* #ORM\Column(name="GRP_ID", type="integer")
*/
protected $id;
/**
* #var string
* #ORM\Column(name="GRP_CODE", type="string")
*/
protected $code;
/**
* #var Collections\ArrayCollection
* #ORM\OneToMany(targetEntity="Application\Model\User", mappedBy="group")
* #ORM\JoinColumn(name="GRP_ID", referencedColumnName="GRP_ID")
*/
protected $users;
/**
* Constructor
*/
public function __construct()
{
$this->users = new Collections\ArrayCollection();
}
/**
* #return mixed
*/
public function getCode()
{
return $this->code;
}
/**
* #param mixed $code
* #return Group
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* #param int $id
* #return Group
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* #return mixed
*/
public function getUsers()
{
return $this->users;
}
/**
* #param mixed $users
* #return Group
*/
public function setUsers($users)
{
$this->users = $users;
return $this;
}
}
When I try to retrieve the relation from the groups, it works great, but when I slect the users and try to get their group, Doctrine create some proxy objects and the result is an empty object with only the relationship key filled.
Can someone point me to the good direction ?
Here my code:
$query = $em->createQueryBuilder()
->select('u')
->from('Application\Model\User', 'u');
$data = $query->getQuery()->getResult();
$data = reset($data);
var_dump($data->getGroup()); // proxy
###########################
$query = $em->createQueryBuilder()
->select('g')
->from('Application\Model\User\Group', 'g');
$data = $query->getQuery()->getResult();
$data = reset($data);
var_dump($data->getUsers()); // ok
you don't need the $GRP_ID in the User Entity - it's already mapped with the $group relation. Doctrine handles the IDs automatically.
Also your naming-convention looks a bit weird. Normally you should use lowe-camel-case (to save you from strange errors)
Example:
$USR_CODE should be $usrCode -> to match your getter/setter: setUsrCode(), getUsrCode().
just noticed: you don't have any setters. You have to define setters for your attributes, with the naming-convention (look at my example above)
Edit:
you can map the column with the doctrine orm notation:
/**
*
* #ORM\Column(name="USR_CODE", type="string")
*/
private $usrCode;
And yes, you need setters otherwise doctrine won't be able to set the values.
You also need addUser() and removeUser() functions (since user is a Collection):
public function addUsers(Collection $users)
{
foreach($users as $user)
{
if( ! $this->users->contains($user))
{
$this->users->add($user);
$user->setGroup($this);
}
}
}
public function removeUsers(Collection $users)
{
foreach($users as $user)
{
if($this->users->contains($user)){
$this->users->remove($user);
$user->setGroup(null);
}
}
}

Updating Doctrine Collection

I'm working on a survey project and I got 3 Entities, survey(umfrage), surveyQuestion(umfrageFrage) and surveyAnswer(umfrageAntwort).
Here are the entities(removed all unnecessary fields):
namespace Umfrage\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* Umfrage
*
* #ORM\Table(name="umfrage")
* #ORM\Entity
*/
class Umfrage
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var Fragen
*
* #ORM\OneToMany(targetEntity="Umfrage\Entity\UmfrageFrage", mappedBy="umfrage", cascade={"persist","remove"})
*/
private $fragen;
public function __construct() {
$this->fragen = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set fragen
*
* #param \Umfrage\Entity\UmfrageFrage $fragen
*
* #return UmfrageFrage
*/
public function setFragen($fragen)
{
$this->fragen = $fragen;
return $this;
}
/** Get fragen
*
* #param \Umfrage\Entity\UmfrageFrage $fragen
*
* #return UmfrageFrage
*/
public function getFragen() {
return $this->fragen;
}
public function addFragen(Collection $fragen)
{
foreach ($fragen as $frage) {
$frage->setUmfrage($this);
$this->fragen->add($frage);
}
}
public function removeFragen(Collection $fragen)
{
foreach ($fragen as $frage) {
$frage->setUmfrage(null);
$this->fragen->removeElement($frage);
}
}
}
The Questions:
namespace Umfrage\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* UmfrageFrage
*
* #ORM\Table(name="umfrage_frage")
* #ORM\Entity
*/
class UmfrageFrage
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \Umfrage\Entity\Umfrage
*
* #ORM\ManyToOne(targetEntity="Umfrage\Entity\Umfrage", inversedBy="fragen")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="umfrage_id", referencedColumnName="id")
* })
*/
private $umfrage;
/**
* #var Antworten
*
* #ORM\OneToMany(targetEntity="Umfrage\Entity\UmfrageAntwort", mappedBy="umfrageFrage", cascade={"all"})
*/
private $antworten;
public function __construct() {
$this->antworten = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set umfrage
*
* #param \Umfrage\Entity\Umfrage $umfrage
*
* #return UmfrageFrage
*/
public function setUmfrage(\Umfrage\Entity\Umfrage $umfrage = null)
{
$this->umfrage = $umfrage;
return $this;
}
/**
* Get umfrage
*
* #return \Umfrage\Entity\Umfrage
*/
public function getUmfrage()
{
return $this->umfrage;
}
/**
* Set antworten
*
* #param \Umfrage\Entity\UmfrageAntwort $antworten
*
* #return UmfrageAntwort
*/
public function setAntworten($antworten)
{
$this->antworten = $antworten;
return $this;
}
/** Get antworten
*
* #param \Umfrage\Entity\UmfrageAntwort $antworten
*
* #return UmfrageAntwort
*/
public function getAntworten() {
return $this->antworten;
}
public function addAntworten(Collection $antworten)
{
foreach ($antworten as $antwort) {
$antwort->setUmfrageFrage($this);
$this->antworten->add($antwort);
}
}
public function removeAntworten(Collection $antworten)
{
foreach ($antworten as $antwort) {
$this->antworten->removeElement($antwort);
}
}
}
The Answers:
namespace Umfrage\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* UmfrageAntwort
*
* #ORM\Table(name="umfrage_antwort")
* #ORM\Entity
*/
class UmfrageAntwort
{
/**
* #var integer
*
* #ORM\Column(name="id", type="bigint", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \Umfrage\Entity\UmfrageFrage
*
* #ORM\ManyToOne(targetEntity="Umfrage\Entity\UmfrageFrage", inversedBy="antworten")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="umfrage_frage_id", referencedColumnName="id")
* })
*/
private $umfrageFrage;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set umfrageFrage
*
* #param \Umfrage\Entity\UmfrageFrage $umfrageFrage
*
* #return UmfrageFrage
*/
public function setUmfrageFrage($umfrageFrage)
{
$this->umfrageFrage = $umfrageFrage;
return $this;
}
/**
* Get umfrageFrage
*
* #return \Umfrage\Entity\UmfrageFrage
*/
public function getUmfrageFrage()
{
return $this->umfrageFrage;
}
}
The Controller action:
public function editAction()
{
$id = (int) $this->params()->fromRoute('id', 0);
if (!$id) {
return $this->redirect()->toRoute('umfrage', array('action'=>'add'));
}
$umfrage = $this->getEntityManager()->find('Umfrage\Entity\Umfrage', $id);
$form = new UmfrageForm($this->getEntityManager());
$form->setHydrator(new DoctrineEntity($this->getEntityManager(),'Umfrage\Entity\Umfrage'));
$form->bind($umfrage);
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
$this->getEntityManager()->persist($umfrage);
$this->getEntityManager()->flush();
// Redirect to overview
return $this->redirect()->toRoute('umfrage');
}
}
$this->layout('layout/umfrage_backend');
return new ViewModel(array(
'id' => $id,
'form' => $form
));
}
And the view:
<?php
// module/Umfrage/view/umfrage/umfrage/edit.phtml:
use Doctrine\Common\Util\Debug;
$title = 'Umfrage bearbeiten';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
$form = $this->form;
$form->setAttribute('action', $this->url(
'umfrage',
array(
'action' => 'edit',
'id' => $this->id,
)
));
echo $this->ztbForm($form);
?>
Adding a Survey works fine, Deleting also, the Survey and its related Questions/Answers are removed from the DB. Only the Update actions doesn't work as expected. Survey and Questions are updated, but for the Answers I receive an Insert, instead of an Update, which results in duplicate entries in the DB. What's wrong with the Mapping(Code)?
Thanks in advance for your help!